package group import ( "fmt" "log" "os" "strconv" "strings" "github.com/spf13/cobra" "github.com/spf13/viper" ldap "github.com/go-ldap/ldap/v3" util "git.metaunix.net/metaunix.net/muldap/lib/util" ) func init() { // define group add subcommand flags groupAddCmd.Flags().StringP("base_ou", "o", "", "LDAP OU to create the new group entry under") groupAddCmd.Flags().StringP("id_attribute", "a", "cn", "LDAP DN attribute for groups") groupAddCmd.Flags().StringVarP(&flagGroupName, "group_name", "n", "", "Name for the new group") groupAddCmd.Flags().StringVarP(&flagGroupType, "group_type", "t", "unix", "Type of the new group") groupAddCmd.Flags().IntVarP(&flagGroupIDNumber, "group_id", "i", -1, "ID number of the new group (Unix/Posix groups only)") groupAddCmd.Flags().StringVarP(&flagGroupMembers, "group_members", "m", "", "Members to add to the newly created group") // bind config file values to group add flags viper.BindPFlag("group.base_ou", groupAddCmd.Flags().Lookup("base_ou")) viper.BindPFlag("group.id_attr", groupAddCmd.Flags().Lookup("id_attribute")) } // define group add subcommand var groupAddCmd = &cobra.Command{ Use: "add", Short: "Add an LDAP group to the directory", Long: `Create and add an LDAP group resource to your directory.`, Run: func(cmd *cobra.Command, args []string) { // check the type given if !util.ContainsString(validTypes, flagGroupType) { log.Fatal(fmt.Errorf("%s is not a valid group type; valid types are: %v", flagGroupType, validTypes)) os.Exit(1) } // create new LDAP connection l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", viper.GetString("host"), viper.GetInt("port"))) if err != nil { log.Fatal(err) } defer l.Close() // bind as the admin group err = l.Bind(viper.GetString("bind_dn"), viper.GetString("bind_pw")) if err != nil { log.Fatal(err) } // set up group attributes groupDn := fmt.Sprintf("%s=%s,%s", viper.GetString("group.id_attr"), flagGroupName, viper.GetString("group.base_ou")) groupOClasses := viper.GetStringSlice("group.object_class") // create a new add request object addRequest := ldap.NewAddRequest(groupDn, nil) // add group attributes to the request addRequest.Attribute(viper.GetString("group.id_attr"), []string{flagGroupName}) // add attributes based on group type if flagGroupType == "unix" { // add unix group type to objectClasses groupOClasses = append(groupOClasses, "posixGroup") // finish adding attributes to the request addRequest.Attribute("objectClass", groupOClasses) addRequest.Attribute("gidNumber", []string{strconv.Itoa(flagGroupIDNumber)}) if flagGroupMembers != "" { addRequest.Attribute("memberUid", strings.Split(flagGroupMembers, ",")) } else { addRequest.Attribute("memberUid", []string{"noname"}) } } else if flagGroupType == "app" { // add unix group type to objectClasses groupOClasses = append(groupOClasses, "groupOfNames") // finish adding attributes to the request addRequest.Attribute("objectClass", groupOClasses) if flagGroupMembers != "" { groupMembers := strings.Split(flagGroupMembers, ",") for i, member := range groupMembers { groupMembers[i] = fmt.Sprintf("%s=%s,%s", viper.GetString("user.uid_attr"), member, viper.GetString("user.base_ou")) } addRequest.Attribute("member", groupMembers) } else { addRequest.Attribute("member", []string{fmt.Sprintf("%s=noname,%s", viper.GetString("user.uid_attr"), viper.GetString("user.base_ou"))}) } } // perform the add operation err = l.Add(addRequest) if err != nil { log.Fatal(err) } // create and send a modify request for each user to update modification times for replication if flagGroupMembers != "" && flagGroupType == "app" { groupMembers := strings.Split(flagGroupMembers, ",") for _, member := range groupMembers { modify := ldap.NewModifyRequest(fmt.Sprintf("%s=%s,%s", viper.GetString("user.uid_attr"), member, viper.GetString("user.base_ou")), nil) modify.Replace(viper.GetString("user.uid_attr"), []string{member}) err = l.Modify(modify) if err != nil { log.Fatal(err) } } } }, }