package hackers_git import ( "fmt" yaml "gopkg.in/yaml.v2" "io/ioutil" "os" "path" "sd_daemon/logger" "strconv" "strings" ) func filename2uid(filename string) int32 { basename := path.Base(filename) parts := strings.SplitN(basename, ".", 2) if len(parts) != 2 || parts[1] != "yml" { return -1 } uid, err := strconv.ParseInt(parts[0], 10, 32) if err != nil { return -1 } return int32(uid) } var usersGid = name2gid("users") func parse_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 } file, err := os.Open(filename) if err != nil { return } contents, err := ioutil.ReadAll(file) 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 { 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(map[string]bool, 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 = groups } } } if len(errs) > 0 { err = &yaml.TypeError{Errors: errs} } ret.passwd.PwHash = "!" ret.passwd.GID = usersGid return } func parse_user_password(filename string) (hash string) { hash = "!" file, err := os.Open(filename) if err != nil { logger.Debug("hackers.git: %v", err) return } contents, err := ioutil.ReadAll(file) if err != nil { logger.Debug("hackers.git: Error while reading: %q: %v", filename, err) return } lines := strings.Split(string(contents), "\n") switch len(lines) { case 1: hash = lines[0] case 2: if lines[1] == "" { hash = lines[0] } else { logger.Debug("hackers.git: Invalid password format in file: %q", filename) } default: logger.Debug("hackers.git: Invalid password format in file: %q", filename) } return }