package group import ( "fmt" "log" "os" "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 groupAddMemberCmd.Flags().StringP("base_ou", "o", "", "LDAP OU to search for the group entry under") groupAddMemberCmd.Flags().StringP("id_attribute", "a", "cn", "LDAP DN attribute for groups") groupAddMemberCmd.Flags().StringVarP(&flagGroupName, "group_name", "n", "", "Name for the group") groupAddMemberCmd.Flags().StringVarP(&flagGroupType, "group_type", "t", "unix", "Type of the group") groupAddMemberCmd.Flags().StringVarP(&flagGroupMembers, "group_members", "m", "", "Members to add to the group (comma-separated list)") // bind config file values to group add flags viper.BindPFlag("group.base_ou", groupAddMemberCmd.Flags().Lookup("base_ou")) viper.BindPFlag("group.id_attr", groupAddMemberCmd.Flags().Lookup("id_attribute")) } // define group add subcommand var groupAddMemberCmd = &cobra.Command{ Use: "addMember", Short: "Add a member to an LDAP group", Long: `Adds an LDAP user as a member of an LDAP group.`, 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) } // check if users were supplied if flagGroupMembers == "" { log.Fatal(fmt.Errorf("you didn't supply any members to add to the group")) 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 dn 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")) // create new LDAP modify request groupMod := ldap.NewModifyRequest(groupDn, nil) // split list of group members groupMembers := strings.Split(flagGroupMembers, ",") // add attributes based on group type if flagGroupType == "unix" { // add new member attribute groupMod.Add("memberUid", groupMembers) } else if flagGroupType == "app" { // loop through app group members to create their full DNs for i, member := range groupMembers { groupMembers[i] = fmt.Sprintf("%s=%s,%s", viper.GetString("user.uid_attr"), member, viper.GetString("user.base_ou")) } // add new member attribute groupMod.Add("member", groupMembers) } // perform the add operation err = l.Modify(groupMod) 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 { userMod := ldap.NewModifyRequest(fmt.Sprintf("%s=%s,%s", viper.GetString("user.uid_attr"), member, viper.GetString("user.base_ou")), nil) userMod.Replace(viper.GetString("user.uid_attr"), []string{member}) err = l.Modify(userMod) if err != nil { log.Fatal(err) } } } }, }