From 2206136023f3e548c3f02e393a85c6e911b61ef3 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 29 Aug 2015 23:20:53 -0600 Subject: roll sleeves up, do actual yaml the hard way --- src/nshd/hackers_git/hackers.go | 9 +++- src/nshd/hackers_git/hackers_parse.go | 89 +++++++++++++++++++++++++++-------- src/nshd/hackers_git/hackers_watch.go | 29 ++++++------ 3 files changed, 91 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/nshd/hackers_git/hackers.go b/src/nshd/hackers_git/hackers.go index 230f08b..a155f83 100644 --- a/src/nshd/hackers_git/hackers.go +++ b/src/nshd/hackers_git/hackers.go @@ -9,6 +9,13 @@ import ( "sync" ) +type user struct { + passwd nslcd_proto.Passwd + pwhash string + groups []string +} + + type Config struct { Pam_password_prohibit_message string Yamldir string @@ -18,7 +25,7 @@ type Hackers struct { util.NullBackend cfg Config lock sync.RWMutex - users map[int32]nslcd_proto.Passwd + users map[int32]user passwords map[int32]string in_fd *inotify.Inotify diff --git a/src/nshd/hackers_git/hackers_parse.go b/src/nshd/hackers_git/hackers_parse.go index 5152b55..8f93432 100644 --- a/src/nshd/hackers_git/hackers_parse.go +++ b/src/nshd/hackers_git/hackers_parse.go @@ -4,25 +4,20 @@ import ( "fmt" yaml "gopkg.in/yaml.v2" "io/ioutil" - "nslcd_proto" "os" ) -type yaml_user struct { - username string - fullname string - shell string - groups []string -} - func filename2uid(filename string) int32 { // TODO return 0 } -func load_user_yaml(filename string) (ret nslcd_proto.Passwd, err error) { - ret.UID = filename2uid(filename) - if ret.UID < 0 { +var usersGid = name2gid("users") + +func load_user_yaml(filename string) (ret user, err error) { + ret.passwd.UID = filename2uid(filename) + + if ret.passwd.UID < 0 { err = fmt.Errorf("Invalid user filename: %q", filename) return } @@ -34,15 +29,69 @@ func load_user_yaml(filename string) (ret nslcd_proto.Passwd, err error) { if err != nil { return } - var user yaml_user - err = yaml.Unmarshal(contents, &user) - - ret.Name = user.username - ret.Password = "x" - ret.GID = name2gid("users") - ret.GECOS = user.fullname - ret.HomeDir = "/home/" + ret.Name - ret.Shell = user.shell + 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 { + 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 { + errs = append(errs, "\"groups\" is not set") + } else if ary, isTyp := iface.([]interface{}); !isTyp { + errs = append(errs, "\"groups\" is not an array") + } else { + groups := make([]string, len(ary)) + e := false + for i, iface := range ary { + if str, isTyp := iface.(string); !isTyp { + errs = append(errs, "\"group\" item is not an array") + e = true + break + } else { + groups[i] = str + } + } + if !e { + ret.groups = groups + } + } + } + if len(errs) > 0 { + err = &yaml.TypeError{errs} + } + + ret.passwd.Password = "x" + ret.passwd.GID = usersGid + ret.pwhash = "!" return } diff --git a/src/nshd/hackers_git/hackers_watch.go b/src/nshd/hackers_git/hackers_watch.go index aec1f65..be4af40 100644 --- a/src/nshd/hackers_git/hackers_watch.go +++ b/src/nshd/hackers_git/hackers_watch.go @@ -2,7 +2,6 @@ package hackers_git import ( "inotify" - p "nslcd_proto" "os" "path/filepath" "sd_daemon/logger" @@ -19,7 +18,7 @@ const ( ) func (o *Hackers) watchHomedir(uid int32) { - wd, err := o.in_fd.AddWatch(o.users[uid].HomeDir, in_DIR|in_CHILD_ANY) + wd, err := o.in_fd.AddWatch(o.users[uid].passwd.HomeDir, in_DIR|in_CHILD_ANY) if err == nil { oldwd, found := o.in_uid2wd[uid] if found && oldwd != wd { @@ -29,7 +28,7 @@ func (o *Hackers) watchHomedir(uid int32) { o.in_wd2uid[wd] = uid } else { delete(o.in_uid2wd, uid) - logger.Info("could not watch: %s", o.users[uid].HomeDir) + logger.Info("could not watch: %s", o.users[uid].passwd.HomeDir) } } func (o *Hackers) unwatchHomedir(wd inotify.Cint) { @@ -62,7 +61,7 @@ func (o *Hackers) close() { } o.in_wd_home = -1 o.in_wd_yaml = -1 - o.users = make(map[int32]p.Passwd, 0) + o.users = make(map[int32]user, 0) o.in_uid2wd = make(map[int32]inotify.Cint, 0) o.in_wd2uid = make(map[inotify.Cint]int32, 0) } @@ -74,17 +73,17 @@ func (o *Hackers) reload() (err error) { o.in_wd_yaml, err = o.in_fd.AddWatch(o.cfg.Yamldir, in_DIR|in_CHILD_ANY); if err != nil { return } files, err := filepath.Glob(o.cfg.Yamldir + "/*.yml") - o.users = make(map[int32]p.Passwd, len(files)) + o.users = make(map[int32]user, len(files)) o.in_uid2wd = make(map[int32]inotify.Cint, len(files)) o.in_wd2uid = make(map[inotify.Cint]int32, len(files)) for _, file := range files { logger.Debug("Loading yaml file: %s", file) user, err := load_user_yaml(file) if err == nil { - o.users[user.UID] = user + o.users[user.passwd.UID] = user logger.Debug("... success") - o.watchHomedir(user.UID) - o.passwords[user.UID] = load_user_password(user.HomeDir + "/.password") + o.watchHomedir(user.passwd.UID) + o.passwords[user.passwd.UID] = load_user_password(user.passwd.HomeDir + "/.password") } else { logger.Debug("... error") } @@ -94,13 +93,13 @@ func (o *Hackers) reload() (err error) { return } -func (o *Hackers) worker_handle_user_add(user p.Passwd) { +func (o *Hackers) worker_handle_user_add(user user) { o.lock.Lock() defer o.lock.Unlock() - o.users[user.UID] = user - o.watchHomedir(user.UID) - o.passwords[user.UID] = load_user_password(user.HomeDir + "/.password") + o.users[user.passwd.UID] = user + o.watchHomedir(user.passwd.UID) + o.passwords[user.passwd.UID] = load_user_password(user.passwd.HomeDir + "/.password") } func (o *Hackers) worker_handle_user_del(uid int32) { @@ -124,7 +123,7 @@ func (o *Hackers) worker_handle_passwd(uid int32) { o.lock.Lock() defer o.lock.Unlock() - o.passwords[uid] = load_user_password(o.users[uid].HomeDir + "/.password") + o.passwords[uid] = load_user_password(o.users[uid].passwd.HomeDir + "/.password") } func worker_error(format string, a ...interface{}) { @@ -156,9 +155,9 @@ func (o *Hackers) worker() { if err == nil { // User added/updated o.worker_handle_user_add(user) - } else if user.UID >= 0 { + } else if user.passwd.UID >= 0 { // User became invalid - o.worker_handle_user_del(user.UID) + o.worker_handle_user_del(user.passwd.UID) } } else { panic("recieved non-subscribed inotify event from kernel") -- cgit v1.2.3-54-g00ecf