diff --git a/README.md b/README.md index 282f951..da61591 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![easy-ldap-admin](https://socialify.git.ci/47oo/easy-ldap-admin/image?description=1&font=KoHo&language=1&name=1&pattern=Floating%20Cogs&theme=Light) +# Easy LDAP Admin ## How to make @@ -35,7 +35,7 @@ Available Commands: teammod modify a team useradd create a new user or update default new user information userdel delete a user account and related files - usermod modify user account + usermod Flags: --config string config file (default is $HOME/.ela.ini) diff --git a/cmd/groupadd.go b/cmd/groupadd.go index 37429ad..662ce24 100644 --- a/cmd/groupadd.go +++ b/cmd/groupadd.go @@ -18,6 +18,7 @@ package cmd import ( "ela/eldap" "log" + "strconv" "github.com/spf13/cobra" ) @@ -32,6 +33,14 @@ func groupaddRun(cmd *cobra.Command, args []string) { g := eldap.NewGroupEntry() g.Name = args g.Description = append(g.Description, groupaddDesc) + if groupaddGidNumber == "" { + g, err := eldap.NewGidNumber(eldap.MinNumber, eldap.MaxNumber) + if err != nil { + log.Fatalln(err) + return + } + groupaddGidNumber = strconv.Itoa(g) + } g.GidNumber = append(g.GidNumber, groupaddGidNumber) if err := o.GroupAdd(groupaddTeamName, g); err != nil { log.Fatalln(err) @@ -54,6 +63,5 @@ func init() { groupaddCmd.Flags().StringVarP(&groupaddGidNumber, "gid", "g", "", "use GID for the new group") groupaddCmd.Flags().StringVarP(&groupaddDesc, "desc", "d", "", "Group Description") groupaddCmd.Flags().StringVarP(&groupaddTeamName, "teamname", "t", "", "You want the group in which team, or default team") - groupaddCmd.MarkFlagRequired("gid") } diff --git a/cmd/root.go b/cmd/root.go index 2db23bd..6a2b030 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,7 +17,6 @@ package cmd import ( "fmt" - "log" "os" "github.com/spf13/cobra" @@ -90,6 +89,6 @@ func initConfig() { // If a config file is found, read it in. if err := viper.ReadInConfig(); err != nil { // fmt.Println("Using config file:", viper.ConfigFileUsed()) - log.Fatalln("Using config file Error:", viper.ConfigFileUsed()) + fmt.Println("you must have ela config ,please check or create .ela.ini") } } diff --git a/cmd/useradd.go b/cmd/useradd.go index b501baf..b1d9077 100644 --- a/cmd/useradd.go +++ b/cmd/useradd.go @@ -19,6 +19,7 @@ import ( "ela/eldap" "fmt" "log" + "strconv" "github.com/spf13/cobra" ) @@ -44,6 +45,30 @@ func useraddRun(cmd *cobra.Command, args []string) { u := eldap.NewUserEntry() u.CN = args u.Name = args + if useraddUidNumber == "" { + un, err := eldap.NewUidNumber(eldap.MinNumber, eldap.MaxNumber) + if err != nil { + log.Fatalln(err) + return + } + useraddUidNumber = strconv.Itoa(un) + } + if useraddGidNumber == "" { + un, _ := strconv.Atoi(useraddUidNumber) + gn, err := eldap.NewPrivateGidNumber(eldap.MinNumber, eldap.MaxNumber, un) + if err != nil { + log.Fatalln(err) + } + useraddGidNumber = strconv.Itoa(gn) + ge := eldap.NewGroupEntry() + ge.Name = args + ge.GidNumber = append(ge.GidNumber, useraddGidNumber) + if err := o.GroupAdd(useraddTeamName, ge); err != nil { + log.Fatalln(err) + return + } + } + u.GidNumber = append(u.GidNumber, useraddGidNumber) u.UidNumber = append(u.UidNumber, useraddUidNumber) u.HomeDirectory = append(u.HomeDirectory, useraddHomeDirectory) @@ -52,7 +77,9 @@ func useraddRun(cmd *cobra.Command, args []string) { if err := o.UserAdd(useraddTeamName, u); err != nil { log.Fatalln(err) + return } + } // useraddCmd represents the useradd command @@ -73,8 +100,4 @@ func init() { useraddCmd.Flags().StringVarP(&useraddUserPassword, "password", "p", "", "encrypted password of the new account") useraddCmd.Flags().StringVarP(&useraddLoginShell, "shell", "s", "", "login shell of the new account") useraddCmd.Flags().StringVarP(&useraddTeamName, "team", "t", "", "teamname for this user") - - useraddCmd.MarkFlagRequired("gid") - useraddCmd.MarkFlagRequired("uid") - } diff --git a/eldap/base.go b/eldap/base.go index e55b878..749b09b 100644 --- a/eldap/base.go +++ b/eldap/base.go @@ -172,7 +172,6 @@ func (o Option) SearchAllEntryByKindDN(DN string, Kind int) ([]model.EntryBase, if err != nil { return nil, err } - res.Print() EBIArr := make([]model.EntryBase, 0) for _, entry := range res.Entries { ebi := model.EntryBase{} diff --git a/eldap/egroup.go b/eldap/egroup.go index 4ac0c53..697b74b 100644 --- a/eldap/egroup.go +++ b/eldap/egroup.go @@ -34,7 +34,7 @@ func (o Option) GroupAdd(teamName string, g model.GroupEntry) error { return err } if len(arr) != 1 { - return fmt.Errorf("[FAIL] %d num of this team", len(arr)) + return ErrGroupAdd } dn, _ = combineDN(Group, arr[0], g.Name[0]) } @@ -56,7 +56,7 @@ func (o Option) GroupDel(groupName string) error { return err } if len(arr) != 1 { - return fmt.Errorf("bad dn number %d", len(arr)) + return ErrGroupDel } return o.DeleteEntry(arr[0]) } @@ -88,7 +88,7 @@ func (o Option) GroupMod(groupName string, gidNumber string) error { return err } if len(arr) != 1 { - return fmt.Errorf("bad dn number %d", len(arr)) + return ErrGroupMod } dn := arr[0] return o.ModifyEntryAttr(dn, []model.AttrVal{ diff --git a/eldap/errors.go b/eldap/errors.go new file mode 100644 index 0000000..5cd5ec0 --- /dev/null +++ b/eldap/errors.go @@ -0,0 +1,17 @@ +package eldap + +import ( + "errors" +) + +var ErrGroupAdd = errors.New("[FAIL] group name exist") +var ErrGroupDel = errors.New("[FAIL] group name not found or more than one same name") +var ErrGroupMod = errors.New("[FAIL] modify attr for group fail") + +var ErrTeamAdd = errors.New("[FAIL] team name exist") +var ErrTeamDel = errors.New("[FAIL] team name not found or more than one same name") +var ErrTeamMod = errors.New("[FAIL] modify attr for team fail") + +var ErrUserAdd = errors.New("[FAIL] user name exist") +var ErrUserDel = errors.New("[FAIL] user name not dount or more than one same name") +var ErrUserMod = errors.New("[FAIL] modify attr for user fail") diff --git a/eldap/eteam.go b/eldap/eteam.go index 8743b5a..f5bda7d 100644 --- a/eldap/eteam.go +++ b/eldap/eteam.go @@ -17,7 +17,6 @@ package eldap import ( "ela/model" - "fmt" ) /* @@ -29,7 +28,7 @@ func (o Option) TeamAdd(t model.TeamEntry) error { return err } if len(arr) != 0 { - return fmt.Errorf("[FAIL] we find num %d name team,this version only support one from whole tree", len(arr)) + return ErrTeamAdd } t.AssociatedDomain = append(t.AssociatedDomain, o.LAI.TopDN) attrs, err := Map(t) @@ -49,7 +48,7 @@ func (o Option) TeamDescUpdate(t model.TeamEntry) error { return err } if len(arr) != 1 { - return fmt.Errorf("[FAIL] we find num %d name team,this version only support one", len(arr)) + return ErrTeamMod } DN := arr[0] return o.ModifyEntryAttr(DN, []model.AttrVal{ @@ -67,7 +66,7 @@ func (o Option) TeamDelete(teamName string) error { return err } if len(arr) != 1 { - return fmt.Errorf("[FAIL] we find num %d name team,this version only support one", len(arr)) + return ErrTeamDel } dn := arr[0] return o.DeleteEntry(dn) diff --git a/eldap/euser.go b/eldap/euser.go index 1d6e691..01dac62 100644 --- a/eldap/euser.go +++ b/eldap/euser.go @@ -17,7 +17,6 @@ package eldap import ( "ela/model" - "fmt" ) /** @@ -33,7 +32,7 @@ func (o Option) UserAdd(teamName string, u model.UserEntry) error { return err } if len(arr) != 1 { - return fmt.Errorf("bad dn number %d", len(arr)) + return ErrUserAdd } dn, _ = combineDN(User, arr[0], u.Name[0]) } @@ -53,7 +52,7 @@ func (o Option) UserDel(userName string) error { return err } if len(arr) != 1 { - return fmt.Errorf("bad dn number %d", len(arr)) + return ErrUserDel } dn := arr[0] return o.DeleteEntry(dn) @@ -65,7 +64,7 @@ func (o Option) UserMod(u model.UserEntry) error { return err } if len(arr) != 1 { - return fmt.Errorf("bad dn number %d", len(arr)) + return ErrUserMod } dn := arr[0] um, err := Map(u) diff --git a/eldap/number.go b/eldap/number.go new file mode 100644 index 0000000..6aff851 --- /dev/null +++ b/eldap/number.go @@ -0,0 +1,53 @@ +package eldap + +import ( + "fmt" + "strconv" +) + +var MinNumber = 10000 +var MaxNumber = 100000 + +func NewGidNumber(min int, max int) (int, error) { + o := NewOption() + for i := min; i < max; i++ { + arr, err := o.SearchAllEntryDNByAttr(Group, "gidNumber", strconv.Itoa(i)) + if err != nil { + return -1, err + } + if len(arr) != 0 { + continue + } + return i, nil + } + return -1, fmt.Errorf("not found unique gidNumber in %d and %d", min, max) + +} + +func NewPrivateGidNumber(min int, max int, gidNumber int) (int, error) { + o := NewOption() + arr, err := o.SearchAllEntryDNByAttr(Group, "gidNumber", strconv.Itoa(gidNumber)) + if err != nil { + return -1, err + } + if len(arr) != 0 { + return NewGidNumber(min, max) + } + return gidNumber, nil +} + +func NewUidNumber(min int, max int) (int, error) { + o := NewOption() + for i := min; i < max; i++ { + arr, err := o.SearchAllEntryDNByAttr(User, "uidNumber", strconv.Itoa(i)) + if err != nil { + return -1, err + } + if len(arr) != 0 { + continue + } + return i, nil + } + return -1, fmt.Errorf("not found unique uidNumber in %d and %d", min, max) + +} diff --git a/script/init-ldapserver.sh b/script/init-ldapserver.sh new file mode 100644 index 0000000..b5dadc6 --- /dev/null +++ b/script/init-ldapserver.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# Author: Han Hao +# Email: 136698493@qq.com +# Only Run Once When You First Install OpenLDAP + + +function usage(){ + cat < -u -s +Example: $0 -D home.org -u admin -s 111111 +EOF +} + + +while getopts "D:s:u:" opt;do + case $opt in + D) domain=$OPTARG + ;; + s) rootpw=$OPTARG + ;; + u) cn=$OPTARG + ;; + *) echo "Invalid option: " $OPTARG + ;; + esac +done + +# check args +[ -z $domain ] && usage && exit 1 +[ -z $rootpw ] && usage && exit 1 +[ -z $cn ] && usage && exit 1 + +# domain is home.org ==> olcSuffix is dc=home,dc=org +olcSuffix=`echo $domain |awk -F '.' '{print "dc="$1",dc="$2}'` +# olcRootDN cn=admin,dc=home,dc=org +olcRootDN="cn=$cn,$olcSuffix" +# get password to sha password +shaRootPW=`slappasswd -h {SHA} -s $rootpw` + +cat < /dev/null +fi +# modify olcSuffix olcRootDN +cat <