From 4d12729aa4026229e4e118b924cc3b1c75ca214b Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 17 Jun 2016 20:09:33 -0400 Subject: write setuid, move things around --- src/parabola_hackers/.gitignore | 2 - src/parabola_hackers/nslcd_backend/db_config.go | 40 ------ src/parabola_hackers/nslcd_backend/db_group.go | 141 -------------------- src/parabola_hackers/nslcd_backend/db_pam.go | 167 ------------------------ src/parabola_hackers/nslcd_backend/db_passwd.go | 82 ------------ src/parabola_hackers/nslcd_backend/db_shadow.go | 78 ----------- src/parabola_hackers/nslcd_backend/hackers.go | 122 ----------------- src/parabola_hackers/nslcd_backend/util.go | 58 -------- src/parabola_hackers/passwords.go.in | 94 ------------- src/parabola_hackers/users.go.in | 141 -------------------- src/parabola_hackers/util.go | 47 ------- 11 files changed, 972 deletions(-) delete mode 100644 src/parabola_hackers/.gitignore delete mode 100644 src/parabola_hackers/nslcd_backend/db_config.go delete mode 100644 src/parabola_hackers/nslcd_backend/db_group.go delete mode 100644 src/parabola_hackers/nslcd_backend/db_pam.go delete mode 100644 src/parabola_hackers/nslcd_backend/db_passwd.go delete mode 100644 src/parabola_hackers/nslcd_backend/db_shadow.go delete mode 100644 src/parabola_hackers/nslcd_backend/hackers.go delete mode 100644 src/parabola_hackers/nslcd_backend/util.go delete mode 100644 src/parabola_hackers/passwords.go.in delete mode 100644 src/parabola_hackers/users.go.in delete mode 100644 src/parabola_hackers/util.go (limited to 'src/parabola_hackers') diff --git a/src/parabola_hackers/.gitignore b/src/parabola_hackers/.gitignore deleted file mode 100644 index 3be3f08..0000000 --- a/src/parabola_hackers/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/users.go -/passwords.go diff --git a/src/parabola_hackers/nslcd_backend/db_config.go b/src/parabola_hackers/nslcd_backend/db_config.go deleted file mode 100644 index e78643b..0000000 --- a/src/parabola_hackers/nslcd_backend/db_config.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - s "syscall" - - p "lukeshu.com/git/go/libnslcd.git/proto" -) - -func (o *Hackers) Config_Get(cred s.Ucred, req p.Request_Config_Get) <-chan p.Config { - o.lock.RLock() - ret := make(chan p.Config) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - 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} - } - } - }() - return ret -} diff --git a/src/parabola_hackers/nslcd_backend/db_group.go b/src/parabola_hackers/nslcd_backend/db_group.go deleted file mode 100644 index 18e54b1..0000000 --- a/src/parabola_hackers/nslcd_backend/db_group.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - "parabola_hackers" - s "syscall" - - p "lukeshu.com/git/go/libnslcd.git/proto" -) - -func (o *Hackers) groupByName(name string, users bool) p.Group { - members_set, found := o.groups[name] - if !found { - return p.Group{ID: -1} - } - gid := name2gid(name) - if gid < 0 { - return p.Group{ID: -1} - } - var members_list []string - if users { - members_list = parabola_hackers.Set2list(members_set) - } else { - members_list = make([]string, 0) - } - return p.Group{ - Name: name, - PwHash: "x", - ID: gid, - Members: members_list, - } -} - -func (o *Hackers) groupByGid(gid int32, users bool) p.Group { - name, found := gid2name(gid) - if !found { - return p.Group{ID: -1} - } - members_set, found := o.groups[name] - if !found { - return p.Group{ID: -1} - } - var members_list []string - if users { - members_list = parabola_hackers.Set2list(members_set) - } else { - members_list = make([]string, 0) - } - return p.Group{ - Name: name, - PwHash: "x", - ID: gid, - Members: members_list, - } -} - -func (o *Hackers) Group_ByName(cred s.Ucred, req p.Request_Group_ByName) <-chan p.Group { - o.lock.RLock() - ret := make(chan p.Group) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - group := o.groupByName(req.Name, true) - if group.ID < 0 { - return - } - ret <- group - }() - return ret -} - -func (o *Hackers) Group_ByGid(cred s.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) - - group := o.groupByGid(req.Gid, true) - if group.ID < 0 { - return - } - ret <- group - }() - return ret -} - -// note that the BYMEMBER call returns an empty members list -func (o *Hackers) Group_ByMember(cred s.Ucred, req p.Request_Group_ByMember) <-chan p.Group { - o.lock.RLock() - 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 s.Ucred, req p.Request_Group_All) <-chan p.Group { - o.lock.RLock() - ret := make(chan p.Group) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - for name, _ := range o.groups { - group := o.groupByName(name, true) - if group.ID >= 0 { - ret <- group - } - } - }() - return ret -} diff --git a/src/parabola_hackers/nslcd_backend/db_pam.go b/src/parabola_hackers/nslcd_backend/db_pam.go deleted file mode 100644 index 3374170..0000000 --- a/src/parabola_hackers/nslcd_backend/db_pam.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - "fmt" - "parabola_hackers" - s "syscall" - - "lukeshu.com/git/go/libgnulinux.git/crypt" - p "lukeshu.com/git/go/libnslcd.git/proto" - "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" -) - -func checkPassword(password string, hash string) bool { - return crypt.Crypt(password, hash) == hash -} - -func hashPassword(newPassword string, oldHash string) string { - salt := oldHash - if salt == "!" { - str, err := parabola_hackers.RandomString(crypt.SaltAlphabet, 8) - if err != nil { - logger.Err("Could not generate a random string") - str = "" - } - salt = "$6$" + str + "$" - } - return crypt.Crypt(newPassword, salt) -} - -func (o *Hackers) PAM_Authentication(cred s.Ucred, req p.Request_PAM_Authentication) <-chan p.PAM_Authentication { - o.lock.RLock() - ret := make(chan p.PAM_Authentication) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - uid := o.name2uid(req.UserName) - if uid < 0 { - return - } - - user := o.users[uid] - obj := p.PAM_Authentication{ - AuthenticationResult: p.NSLCD_PAM_AUTH_ERR, - UserName: "", - AuthorizationResult: p.NSLCD_PAM_AUTH_ERR, - AuthorizationError: "", - } - if checkPassword(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 s.Ucred, req p.Request_PAM_Authorization) <-chan p.PAM_Authorization { - o.lock.RLock() - ret := make(chan p.PAM_Authorization) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - uid := o.name2uid(req.UserName) - if uid < 0 { - return - } - ret <- p.PAM_Authorization{ - Result: p.NSLCD_PAM_SUCCESS, - Error: "", - } - }() - return ret -} - -const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - -func (o *Hackers) PAM_SessionOpen(cred s.Ucred, req p.Request_PAM_SessionOpen) <-chan p.PAM_SessionOpen { - ret := make(chan p.PAM_SessionOpen) - go func() { - defer close(ret) - - sessionid, err := parabola_hackers.RandomString(alphabet, 24) - if err != nil { - return - } - ret <- p.PAM_SessionOpen{SessionID: sessionid} - }() - return ret -} - -func (o *Hackers) PAM_SessionClose(cred s.Ucred, req p.Request_PAM_SessionClose) <-chan p.PAM_SessionClose { - ret := make(chan p.PAM_SessionClose) - go close(ret) - return ret -} - -func (o *Hackers) PAM_PwMod(cred s.Ucred, req p.Request_PAM_PwMod) <-chan p.PAM_PwMod { - ret := make(chan p.PAM_PwMod) - o.lock.Lock() - go func() { - defer close(ret) - defer o.lock.Unlock() - - uid := o.name2uid(req.UserName) - if uid < 0 { - return - } - user := o.users[uid] - - // Check the OldPassword - if req.AsRoot == 1 { - if !checkPassword(req.OldPassword, user.Passwd.PwHash) { - ret <- p.PAM_PwMod{ - Result: p.NSLCD_PAM_PERM_DENIED, - Error: fmt.Sprintf("password change failed: %s", "Old password did not match"), - } - return - } - } - - // Update the PwHash in memory - user.Passwd.PwHash = hashPassword(req.NewPassword, user.Passwd.PwHash) - if user.Passwd.PwHash == "" { - logger.Err("Password hashing failed") - return - } - - // Update the PwHash on disk - passwords := make(map[string]string, len(o.users)) - for _, ouser := range o.users { - passwords[ouser.Passwd.Name] = ouser.Passwd.PwHash - } - passwords[user.Passwd.Name] = user.Passwd.PwHash - err := parabola_hackers.SaveAllPasswords(passwords) - if err != nil { - logger.Err("Writing passwords to disk: %v", err) - return - } - - // Ok, we're done, commit the changes - o.users[uid] = user - ret <- p.PAM_PwMod{ - Result: p.NSLCD_PAM_SUCCESS, - Error: "", - } - }() - return ret -} diff --git a/src/parabola_hackers/nslcd_backend/db_passwd.go b/src/parabola_hackers/nslcd_backend/db_passwd.go deleted file mode 100644 index 3f32ddd..0000000 --- a/src/parabola_hackers/nslcd_backend/db_passwd.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - s "syscall" - - p "lukeshu.com/git/go/libnslcd.git/proto" -) - -/* Note that the output password hash value should be one of: - - no password set, allow login without password - ! - used to prevent logins - x - "valid" encrypted password that does not match any valid password - often used to indicate that the password is defined elsewhere - other - encrypted password, in crypt(3) format */ - -func (o *Hackers) Passwd_ByName(cred s.Ucred, req p.Request_Passwd_ByName) <-chan p.Passwd { - o.lock.RLock() - 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 s.Ucred, req p.Request_Passwd_ByUID) <-chan p.Passwd { - o.lock.RLock() - 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 - ret <- passwd - }() - return ret -} - -func (o *Hackers) Passwd_All(cred s.Ucred, req p.Request_Passwd_All) <-chan p.Passwd { - o.lock.RLock() - 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/parabola_hackers/nslcd_backend/db_shadow.go b/src/parabola_hackers/nslcd_backend/db_shadow.go deleted file mode 100644 index abfff28..0000000 --- a/src/parabola_hackers/nslcd_backend/db_shadow.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - s "syscall" - - p "lukeshu.com/git/go/libnslcd.git/proto" -) - -func (o *Hackers) Shadow_ByName(cred s.Ucred, req p.Request_Shadow_ByName) <-chan p.Shadow { - o.lock.RLock() - ret := make(chan p.Shadow) - go func() { - defer o.lock.RUnlock() - defer close(ret) - - 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, - WarnDays: -1, - InactDays: -1, - ExpireDate: -1, - Flag: -1, - } - }() - return ret -} - -func (o *Hackers) Shadow_All(cred s.Ucred, req p.Request_Shadow_All) <-chan p.Shadow { - o.lock.RLock() - 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 -} diff --git a/src/parabola_hackers/nslcd_backend/hackers.go b/src/parabola_hackers/nslcd_backend/hackers.go deleted file mode 100644 index bb03862..0000000 --- a/src/parabola_hackers/nslcd_backend/hackers.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -// Package hackers_nslcd_backend is an nslcd_server Backend that -// speaks to hackers.git. -package hackers_nslcd_backend - -import ( - "parabola_hackers" - "sync" - - nslcd_server "lukeshu.com/git/go/libnslcd.git/proto/server" - nslcd_systemd "lukeshu.com/git/go/libnslcd.git/systemd" - "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" -) - -type config struct { - Pam_password_prohibit_message string -} - -type Hackers struct { - nslcd_server.NilBackend - lock sync.RWMutex - - CfgFilename string - - cfg config - users map[int32]parabola_hackers.User - groups map[string]map[string]bool -} - -var _ nslcd_systemd.Backend = &Hackers{} -var _ nslcd_server.Backend = &Hackers{} - -func (o *Hackers) Init() error { - logger.Debug("hackers.git: CfgFilename = %v", o.CfgFilename) - err := o.Reload() - if err != nil { - logger.Err("hackers.git: Could not initialize: %v", err) - return err - } - return nil -} - -func (o *Hackers) Close() { - logger.Info("hackers.git: Closing session") - o.lock.Lock() - defer o.lock.Unlock() - - o.users = make(map[int32]parabola_hackers.User, 0) - o.groups = make(map[string]map[string]bool) -} - -func (o *Hackers) Reload() error { - logger.Info("hackers.git: Loading session") - o.lock.Lock() - defer o.lock.Unlock() - - var err error - o.cfg, err = parse_config(o.CfgFilename) - if err != nil { - return err - } - logger.Info("hackers.git: pam_password_prohibit_message: %#v", o.cfg.Pam_password_prohibit_message) - - logger.Debug("hackers.git: Parsing user data") - o.users, err = parabola_hackers.LoadAllUsers() - if err != nil { - return err - } - - passwords, err := parabola_hackers.LoadAllPasswords() - if err != nil { - return err - } - - o.groups = make(map[string]map[string]bool) - for uid, user := range o.users { - user.Passwd.GID = usersGid - hash, hasHash := passwords[user.Passwd.Name] - if !hasHash { - hash = "!" - } - user.Passwd.PwHash = hash - o.users[uid] = user - for _, groupname := range user.Groups { - o.add_user_to_group(user.Passwd.Name, groupname) - } - } - return nil -} - -func (o *Hackers) name2uid(name string) int32 { - for uid, data := range o.users { - if data.Passwd.Name == name { - return uid - } - } - return -1 -} - -func (o *Hackers) add_user_to_group(username string, groupname string) { - group, found := o.groups[groupname] - if !found { - group = make(map[string]bool) - o.groups[groupname] = group - } - group[username] = true -} diff --git a/src/parabola_hackers/nslcd_backend/util.go b/src/parabola_hackers/nslcd_backend/util.go deleted file mode 100644 index 4fb28f3..0000000 --- a/src/parabola_hackers/nslcd_backend/util.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package hackers_nslcd_backend - -import ( - "io/ioutil" - "os" - - yaml "gopkg.in/yaml.v2" - "lukeshu.com/git/go/libgnulinux.git/getgr" -) - -func name2gid(name string) int32 { - gr, err := getgr.ByName(name) - if gr == nil || err != nil { - return -1 - } else { - return int32(gr.Gid) - } -} - -func gid2name(gid int32) (string, bool) { - gr, err := getgr.ByGid(gid) - if gr == nil || err != nil { - return "", false - } else { - return gr.Name, true - } -} - -var usersGid = name2gid("users") - -func parse_config(filename string) (cfg config, err error) { - file, err := os.Open(filename) - if err != nil { - return - } - contents, err := ioutil.ReadAll(file) - if err != nil { - return - } - err = yaml.Unmarshal(contents, &cfg) - return -} diff --git a/src/parabola_hackers/passwords.go.in b/src/parabola_hackers/passwords.go.in deleted file mode 100644 index 0d763b9..0000000 --- a/src/parabola_hackers/passwords.go.in +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package parabola_hackers - -import ( - "fmt" - "io/ioutil" - "os" - "sort" - "strings" - - "lukeshu.com/git/go/libgnulinux.git/crypt" - "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" -) - -/* Note that the password hash value should be one of: - - no password set, allow login without password - ! - used to prevent logins - x - "valid" encrypted password that does not match any valid password - often used to indicate that the password is defined elsewhere - other - encrypted password, in crypt(3) format */ - -const shadow_file = "@shadow_file@" - -func LoadAllPasswords() (map[string]string, error) { - file, err := os.Open(shadow_file) - if err != nil { - return nil, err - } - contents, err := ioutil.ReadAll(file) - if err != nil { - return nil, err - } - lines := strings.Split(string(contents), "\n") - passwords := make(map[string]string, len(lines)) - for i, line := range lines { - cols := strings.SplitN(line, ":", 2) - if len(cols) != 2 { - logger.Err("hackers.git %s:%d: malformed line", shadow_file, i+1) - continue - } - username := cols[0] - hash := cols[1] - if hash != "!" && !crypt.SaltOk(hash) { - hash = "!" - logger.Err("%s:%d: malformed hash for user: %s", shadow_file, i+1, username) - } - passwords[username] = hash - } - return passwords, nil -} - -func SaveAllPasswords(passwords map[string]string) error { - usernames := make([]string, len(passwords)) - i := 0 - for username, _ := range passwords { - usernames[i] = username - i++ - } - sort.Strings(usernames) - - file, err := os.OpenFile(shadow_file+"-", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) - if err != nil { - return err - } - - for _, username := range usernames { - fmt.Fprintf(file, "%s:%s\n", username, passwords[username]) - } - err = file.Sync() - if err != nil { - return err - } - err = file.Close() - if err != nil { - return err - } - - return os.Rename(shadow_file+"-", shadow_file) -} diff --git a/src/parabola_hackers/users.go.in b/src/parabola_hackers/users.go.in deleted file mode 100644 index aeda069..0000000 --- a/src/parabola_hackers/users.go.in +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package parabola_hackers - -import ( - "fmt" - "os/exec" - - yaml "gopkg.in/yaml.v2" - nslcd_proto "lukeshu.com/git/go/libnslcd.git/proto" - "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" -) - -/* Note that the password hash value should be one of: - - no password set, allow login without password - ! - used to prevent logins - x - "valid" encrypted password that does not match any valid password - often used to indicate that the password is defined elsewhere - other - encrypted password, in crypt(3) format */ - -type User struct { - Passwd nslcd_proto.Passwd - Groups []string -} - -func LoadAllUsers() (users map[int32]User, err error) { - contents, err := exec.Command("@bindir@/meta-cat").Output() - if err != nil { - return - } - - var _data interface{} - err = yaml.Unmarshal(contents, &_data) - if err != nil { - return - } - - data, isMap := _data.(map[interface{}]interface{}) - errs := []string{} - if !isMap { - errs = append(errs, "root node is not a map") - } else { - users = make(map[int32]User, len(data)) - for _uid, _user := range data { - uid, isInt := _uid.(int) - if !isInt { - errs = append(errs, fmt.Sprintf("UID is not an int: %T ( %#v )", _uid, _uid)) - continue - } - user, _err := parseUser(_user) - if _err != nil { - errs = append(errs, fmt.Sprintf("Could not parse data for UID %d: %v", uid, _err)) - continue - } - user.Passwd.UID = int32(uid) - logger.Debug("hackers.git: -> User %d(%s) parsed", user.Passwd.UID, user.Passwd.Name) - users[user.Passwd.UID] = user - } - } - if len(errs) > 0 { - users = nil - err = &yaml.TypeError{Errors: errs} - } - return -} - -func parseUser(_data interface{}) (ret User, err error) { - data, isMap := _data.(map[interface{}]interface{}) - errs := []string{} - if !isMap { - errs = append(errs, "root node is not a map") - } else { - if iface, isSet := data["username"]; !isSet { - errs = append(errs, "\"username\" is not set") - } else if str, isTyp := iface.(string); !isTyp { - errs = append(errs, "\"username\" is not a string") - } else { - ret.Passwd.Name = str - ret.Passwd.HomeDir = "/home/" + str - } - - if iface, isSet := data["fullname"]; !isSet { - errs = append(errs, "\"fullname\" is not set") - } else if str, isTyp := iface.(string); !isTyp { - errs = append(errs, "\"fullname\" is not a string") - } else { - ret.Passwd.GECOS = str - } - - if iface, isSet := data["shell"]; !isSet { - errs = append(errs, "\"shell\" is not set") - } else if str, isTyp := iface.(string); !isTyp { - errs = append(errs, "\"shell\" is not a string") - } else { - ret.Passwd.Shell = str - } - - if iface, isSet := data["groups"]; !isSet { - ret.Groups = make([]string, 0) - } else if ary, isTyp := iface.([]interface{}); !isTyp { - errs = append(errs, "\"groups\" is not an array") - } else { - groups := make(map[string]bool, len(ary)) - e := false - for _, iface := range ary { - if str, isTyp := iface.(string); !isTyp { - errs = append(errs, "\"group\" item is not an array") - e = true - break - } else { - groups[str] = true - } - } - if !e { - ret.Groups = Set2list(groups) - } - } - } - if len(errs) > 0 { - err = &yaml.TypeError{Errors: errs} - } - - ret.Passwd.PwHash = "x" // look in shadow for the password hash - ret.Passwd.GID = -1 - - return -} diff --git a/src/parabola_hackers/util.go b/src/parabola_hackers/util.go deleted file mode 100644 index 9a241db..0000000 --- a/src/parabola_hackers/util.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015-2016 Luke Shumaker . -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// . - -package parabola_hackers - -import ( - "crypto/rand" - "math/big" -) - -func RandomString(alphabet string, n uint) (str string, err error) { - var alphabet_len = big.NewInt(int64(len(alphabet))) - var bigint *big.Int - _str := make([]byte, n) - for i := 0; i < len(_str); i++ { - bigint, err = rand.Int(rand.Reader, alphabet_len) - if err != nil { - return - } - _str[i] = alphabet[bigint.Int64()] - } - str = string(_str[:]) - return -} - -func Set2list(set map[string]bool) []string { - list := make([]string, len(set)) - i := uint(0) - for item, _ := range set { - list[i] = item - i++ - } - return list -} -- cgit v1.2.3-54-g00ecf