From e8199ec88c7ca8107c4fb9238e383a4a9eb981ee Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 12 Sep 2015 10:35:52 -0600 Subject: Derp, channels and goroutines are enumerators --- src/nshd/hackers_git/db_config.go | 32 ++++------ src/nshd/hackers_git/db_group.go | 129 +++++++++++++++++--------------------- src/nshd/hackers_git/db_pam.go | 104 ++++++++++++++++-------------- src/nshd/hackers_git/db_passwd.go | 108 +++++++++++++------------------ src/nshd/hackers_git/db_shadow.go | 111 ++++++++++++-------------------- 5 files changed, 211 insertions(+), 273 deletions(-) (limited to 'src/nshd/hackers_git') diff --git a/src/nshd/hackers_git/db_config.go b/src/nshd/hackers_git/db_config.go index fde16b3..7e96059 100644 --- a/src/nshd/hackers_git/db_config.go +++ b/src/nshd/hackers_git/db_config.go @@ -1,26 +1,20 @@ package hackers_git -import ( - p "nslcd_proto" - "nslcd_proto/util" -) +import p "nslcd_proto" -func (o *Hackers) Config_Get(cred p.Ucred, req p.Request_Config_Get) p.Config_Enumerator { +func (o *Hackers) Config_Get(cred p.Ucred, req p.Request_Config_Get) <-chan p.Config { o.lock.RLock() - defer o.lock.RUnlock() + ret := make(chan p.Config) + go func() { + defer o.lock.RUnlock() + defer close(ret) - var val *string = nil - - switch req.Key { - case p.NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE: - if o.Cfg.Pam_password_prohibit_message != "" { - val = &o.Cfg.Pam_password_prohibit_message + switch req.Key { + case p.NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE: + if o.Cfg.Pam_password_prohibit_message != "" { + ret <- p.Config{Value: o.Cfg.Pam_password_prohibit_message} + } } - } - - if val != nil { - return util.New_Config_List([]p.Config{p.Config{Value: *val}}) - } else { - return util.Config_Ø{} - } + }() + return ret } diff --git a/src/nshd/hackers_git/db_group.go b/src/nshd/hackers_git/db_group.go index 63a9fe4..3122bd2 100644 --- a/src/nshd/hackers_git/db_group.go +++ b/src/nshd/hackers_git/db_group.go @@ -1,9 +1,6 @@ package hackers_git -import ( - p "nslcd_proto" - "nslcd_proto/util" -) +import p "nslcd_proto" func (o *Hackers) groupByName(name string, users bool) p.Group { members_set, found := o.groups[name] @@ -51,85 +48,73 @@ func (o *Hackers) groupByGid(gid int32, users bool) p.Group { } } -func (o *Hackers) Group_ByName(cred p.Ucred, req p.Request_Group_ByName) p.Group_Enumerator { +func (o *Hackers) Group_ByName(cred p.Ucred, req p.Request_Group_ByName) <-chan p.Group { o.lock.RLock() - defer o.lock.RUnlock() - group := o.groupByName(req.Name, true) - if group.ID < 0 { - return util.Group_Ø{} - } - return util.New_Group_List([]p.Group{group}) -} + ret := make(chan p.Group) + go func() { + defer o.lock.RUnlock() + defer close(ret) -func (o *Hackers) Group_ByGid(cred p.Ucred, req p.Request_Group_ByGid) p.Group_Enumerator { - o.lock.RLock() - defer o.lock.RUnlock() - group := o.groupByGid(req.Gid, true) - if group.ID < 0 { - return util.Group_Ø{} - } - return util.New_Group_List([]p.Group{group}) + group := o.groupByName(req.Name, true) + if group.ID < 0 { + return + } + ret <- group + }() + return ret } -type groupEnumerator struct { - groups []string - users bool - backend *Hackers - done bool -} +func (o *Hackers) Group_ByGid(cred p.Ucred, req p.Request_Group_ByGid) <-chan p.Group { + o.lock.RLock() + ret := make(chan p.Group) + go func() { + defer o.lock.RUnlock() + defer close(ret) -func (e *groupEnumerator) GetNext() (*p.Group, error) { - for len(e.groups) > 0 { - name := e.groups[0] - group := e.backend.groupByName(name, e.users) - e.groups = e.groups[1:] - if group.ID >= 0 { - return &group, nil + group := o.groupByGid(req.Gid, true) + if group.ID < 0 { + return } - } - if !e.done { - e.done = true - e.backend.lock.RUnlock() - } - return nil, nil -} - -func (o *groupEnumerator) GenericGetNext() (n *interface{}, err error) { - a, err := o.GetNext() - if a != nil { - b := (interface{})(*a) - n = &b - } - return + ret <- group + }() + return ret } // note that the BYMEMBER call returns an empty members list -func (o *Hackers) Group_ByMember(cred p.Ucred, req p.Request_Group_ByMember) p.Group_Enumerator { +func (o *Hackers) Group_ByMember(cred p.Ucred, req p.Request_Group_ByMember) <-chan p.Group { o.lock.RLock() - uid := o.name2uid(req.Member) - if uid < 0 { - return util.Group_Ø{} - } - return &groupEnumerator{ - groups: o.users[uid].groups, - users: false, - backend: o, - done: false, - } + ret := make(chan p.Group) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + uid := o.name2uid(req.Member) + if uid < 0 { + return + } + for _, name := range o.users[uid].groups { + group := o.groupByName(name, false) + if group.ID >= 0 { + ret <- group + } + } + }() + return ret } -func (o *Hackers) Group_All(cred p.Ucred, req p.Request_Group_All) p.Group_Enumerator { +func (o *Hackers) Group_All(cred p.Ucred, req p.Request_Group_All) <-chan p.Group { o.lock.RLock() - e := groupEnumerator{ - groups: make([]string, len(o.groups)), - users: true, - backend: o, - done: false, - } - i := uint(0) - for group, _ := range o.groups { - e.groups[i] = group - i++ - } - return &e + ret := make(chan p.Group) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + for name, _ := range o.groups { + group := o.groupByName(name, false) + if group.ID >= 0 { + ret <- group + } + } + }() + return ret } diff --git a/src/nshd/hackers_git/db_pam.go b/src/nshd/hackers_git/db_pam.go index d4df99a..126c403 100644 --- a/src/nshd/hackers_git/db_pam.go +++ b/src/nshd/hackers_git/db_pam.go @@ -4,70 +4,80 @@ import ( "crypto/rand" "math/big" p "nslcd_proto" - "nslcd_proto/util" ) -func (o *Hackers) PAM_Authentication(cred p.Ucred, req p.Request_PAM_Authentication) p.PAM_Authentication_Enumerator { +func (o *Hackers) PAM_Authentication(cred p.Ucred, req p.Request_PAM_Authentication) <-chan p.PAM_Authentication { o.lock.RLock() - defer o.lock.RUnlock() + ret := make(chan p.PAM_Authentication) + go func() { + defer o.lock.RUnlock() + defer close(ret) - uid := o.name2uid(req.UserName) - if uid < 0 { - return util.PAM_Authentication_Ø{} - } - - user := o.users[uid] - ret := p.PAM_Authentication{ - AuthenticationResult: p.NSLCD_PAM_AUTH_ERR, - UserName: "", - AuthorizationResult: p.NSLCD_PAM_AUTH_ERR, - AuthorizationError: "", - } - if check_password(req.Password, user.passwd.PwHash) { - ret.AuthenticationResult = p.NSLCD_PAM_SUCCESS - ret.AuthorizationResult = ret.AuthenticationResult - ret.UserName = user.passwd.Name - } + uid := o.name2uid(req.UserName) + if uid < 0 { + return + } - return util.New_PAM_Authentication_List([]p.PAM_Authentication{ret}) + user := o.users[uid] + obj := p.PAM_Authentication{ + AuthenticationResult: p.NSLCD_PAM_AUTH_ERR, + UserName: "", + AuthorizationResult: p.NSLCD_PAM_AUTH_ERR, + AuthorizationError: "", + } + if check_password(req.Password, user.passwd.PwHash) { + obj.AuthenticationResult = p.NSLCD_PAM_SUCCESS + obj.AuthorizationResult = obj.AuthenticationResult + obj.UserName = user.passwd.Name + } + ret <- obj + }() + return ret } -func (o *Hackers) PAM_Authorization(cred p.Ucred, req p.Request_PAM_Authorization) p.PAM_Authorization_Enumerator { +func (o *Hackers) PAM_Authorization(cred p.Ucred, req p.Request_PAM_Authorization) <-chan p.PAM_Authorization { o.lock.RLock() - defer o.lock.RUnlock() - - uid := o.name2uid(req.UserName) - if uid < 0 { - return util.PAM_Authorization_Ø{} - } - ret := p.PAM_Authorization{ - Result: p.NSLCD_PAM_SUCCESS, - Error: "", - } + ret := make(chan p.PAM_Authorization) + go func() { + defer o.lock.RUnlock() + defer close(ret) - return util.New_PAM_Authorization_List([]p.PAM_Authorization{ret}) + uid := o.name2uid(req.UserName) + if uid < 0 { + return + } + ret <- p.PAM_Authorization{ + Result: p.NSLCD_PAM_SUCCESS, + Error: "", + } + }() + return ret } const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890" var alphabet_len = big.NewInt(int64(len(alphabet))) -func (o *Hackers) PAM_SessionOpen(cred p.Ucred, req p.Request_PAM_SessionOpen) p.PAM_SessionOpen_Enumerator { - var sessionid [24]byte +func (o *Hackers) PAM_SessionOpen(cred p.Ucred, req p.Request_PAM_SessionOpen) <-chan p.PAM_SessionOpen { + ret := make(chan p.PAM_SessionOpen) + go func() { + defer close(ret) - for i := 0; i < len(sessionid); i++ { - bigint, err := rand.Int(rand.Reader, alphabet_len) - if err != nil { - return util.PAM_SessionOpen_Ø{} + var sessionid [24]byte + for i := 0; i < len(sessionid); i++ { + bigint, err := rand.Int(rand.Reader, alphabet_len) + if err != nil { + return + } + sessionid[i] = alphabet[bigint.Int64()] } - sessionid[i] = alphabet[bigint.Int64()] - } - - ret := p.PAM_SessionOpen{SessionID: string(sessionid[:])} - - return util.New_PAM_SessionOpen_List([]p.PAM_SessionOpen{ret}) + ret <- p.PAM_SessionOpen{SessionID: string(sessionid[:])} + }() + return ret } -func (o *Hackers) PAM_SessionClose(cred p.Ucred, req p.Request_PAM_SessionClose) p.PAM_SessionClose_Enumerator { - return util.PAM_SessionClose_Ø{} +func (o *Hackers) PAM_SessionClose(cred p.Ucred, req p.Request_PAM_SessionClose) <-chan p.PAM_SessionClose { + ret := make(chan p.PAM_SessionClose) + go close(ret) + return ret } diff --git a/src/nshd/hackers_git/db_passwd.go b/src/nshd/hackers_git/db_passwd.go index 32570fb..cc8c711 100644 --- a/src/nshd/hackers_git/db_passwd.go +++ b/src/nshd/hackers_git/db_passwd.go @@ -1,9 +1,6 @@ package hackers_git -import ( - p "nslcd_proto" - "nslcd_proto/util" -) +import p "nslcd_proto" /* Note that the output password hash value should be one of: - no password set, allow login without password @@ -12,73 +9,54 @@ import ( often used to indicate that the password is defined elsewhere other - encrypted password, in crypt(3) format */ -func (o *Hackers) Passwd_ByName(cred p.Ucred, req p.Request_Passwd_ByName) p.Passwd_Enumerator { +func (o *Hackers) Passwd_ByName(cred p.Ucred, req p.Request_Passwd_ByName) <-chan p.Passwd { o.lock.RLock() - defer o.lock.RUnlock() - - uid := o.name2uid(req.Name) - if uid < 0 { - return util.Passwd_Ø{} - } - passwd := o.users[uid].passwd - passwd.PwHash = "x" // only put actual hashes in the Shadow DB - - return util.New_Passwd_List([]p.Passwd{passwd}) + ret := make(chan p.Passwd) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + uid := o.name2uid(req.Name) + if uid < 0 { + return + } + passwd := o.users[uid].passwd + passwd.PwHash = "x" // only put actual hashes in the Shadow DB + ret <- passwd + }() + return ret } -func (o *Hackers) Passwd_ByUID(cred p.Ucred, req p.Request_Passwd_ByUID) p.Passwd_Enumerator { +func (o *Hackers) Passwd_ByUID(cred p.Ucred, req p.Request_Passwd_ByUID) <-chan p.Passwd { o.lock.RLock() - defer o.lock.RUnlock() - - user, found := o.users[req.UID] - if !found { - return util.Passwd_Ø{} - } - passwd := user.passwd - passwd.PwHash = "x" // only put actual hashes in the Shadow DB - - return util.New_Passwd_List([]p.Passwd{passwd}) -} - -type allPasswdEnumerator struct { - uids []int32 - backend *Hackers - done bool -} - -func (e *allPasswdEnumerator) GetNext() (*p.Passwd, error) { - if len(e.uids) > 0 { - passwd := e.backend.users[e.uids[0]].passwd + ret := make(chan p.Passwd) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + user, found := o.users[req.UID] + if !found { + return + } + passwd := user.passwd passwd.PwHash = "x" // only put actual hashes in the Shadow DB - e.uids = e.uids[1:] - return &passwd, nil - } else if !e.done { - e.done = true - e.backend.lock.RUnlock() - } - return nil, nil -} - -func (o *allPasswdEnumerator) GenericGetNext() (n *interface{}, err error) { - a, err := o.GetNext() - if a != nil { - b := (interface{})(*a) - n = &b - } - return + ret <- passwd + }() + return ret } -func (o *Hackers) Passwd_All(cred p.Ucred, req p.Request_Passwd_All) p.Passwd_Enumerator { +func (o *Hackers) Passwd_All(cred p.Ucred, req p.Request_Passwd_All) <-chan p.Passwd { o.lock.RLock() - e := allPasswdEnumerator{ - uids: make([]int32, len(o.users)), - backend: o, - done: false, - } - i := uint(0) - for uid, _ := range o.users { - e.uids[i] = uid - i++ - } - return &e + ret := make(chan p.Passwd) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + for _, user := range o.users { + passwd := user.passwd + passwd.PwHash = "x" // only put actual hashes in the Shadow DB + ret <- passwd + } + }() + return ret } diff --git a/src/nshd/hackers_git/db_shadow.go b/src/nshd/hackers_git/db_shadow.go index fecb9f8..594e7a1 100644 --- a/src/nshd/hackers_git/db_shadow.go +++ b/src/nshd/hackers_git/db_shadow.go @@ -1,46 +1,22 @@ package hackers_git -import ( - p "nslcd_proto" - "nslcd_proto/util" -) +import p "nslcd_proto" -func (o *Hackers) Shadow_ByName(cred p.Ucred, req p.Request_Shadow_ByName) p.Shadow_Enumerator { +func (o *Hackers) Shadow_ByName(cred p.Ucred, req p.Request_Shadow_ByName) <-chan p.Shadow { o.lock.RLock() - defer o.lock.RUnlock() + ret := make(chan p.Shadow) + go func() { + defer o.lock.RUnlock() + defer close(ret) - if cred.Uid != 0 { - return util.Shadow_Ø{} - } - uid := o.name2uid(req.Name) - passwd := o.users[uid].passwd - shadow := p.Shadow{ - Name: passwd.Name, - PwHash: passwd.PwHash, - LastChangeDate: -1, - MinDays: -1, - MaxDays: -1, - WarnDays: -1, - InactDays: -1, - ExpireDate: -1, - Flag: -1, - } - - return util.New_Shadow_List([]p.Shadow{shadow}) -} - -type allShadowEnumerator struct { - uids []int32 - backend *Hackers - done bool -} - -func (e *allShadowEnumerator) GetNext() (*p.Shadow, error) { - if len(e.uids) > 0 { - passwd := e.backend.users[e.uids[0]].passwd - shadow := p.Shadow{ - Name: passwd.Name, - PwHash: passwd.PwHash, + if cred.Uid != 0 { + return + } + uid := o.name2uid(req.Name) + user := o.users[uid] + ret <- p.Shadow{ + Name: user.passwd.Name, + PwHash: user.passwd.PwHash, LastChangeDate: -1, MinDays: -1, MaxDays: -1, @@ -49,39 +25,34 @@ func (e *allShadowEnumerator) GetNext() (*p.Shadow, error) { ExpireDate: -1, Flag: -1, } - e.uids = e.uids[1:] - return &shadow, nil - } - if len(e.uids) == 0 && !e.done { - e.done = true - e.backend.lock.RUnlock() - } - return nil, nil + }() + return ret } -func (o *allShadowEnumerator) GenericGetNext() (n *interface{}, err error) { - a, err := o.GetNext() - if a != nil { - b := (interface{})(*a) - n = &b - } - return -} - -func (o *Hackers) Shadow_All(cred p.Ucred, req p.Request_Shadow_All) p.Shadow_Enumerator { - if cred.Uid != 0 { - return util.Shadow_Ø{} - } +func (o *Hackers) Shadow_All(cred p.Ucred, req p.Request_Shadow_All) <-chan p.Shadow { o.lock.RLock() - e := allShadowEnumerator{ - uids: make([]int32, len(o.users)), - backend: o, - done: false, - } - i := uint(0) - for uid, _ := range o.users { - e.uids[i] = uid - i++ - } - return &e + ret := make(chan p.Shadow) + go func() { + defer o.lock.RUnlock() + defer close(ret) + + if cred.Uid != 0 { + return + } + + for _, user := range o.users { + ret <- p.Shadow{ + Name: user.passwd.Name, + PwHash: user.passwd.PwHash, + LastChangeDate: -1, + MinDays: -1, + MaxDays: -1, + WarnDays: -1, + InactDays: -1, + ExpireDate: -1, + Flag: -1, + } + } + }() + return ret } -- cgit v1.2.3-54-g00ecf