func lookupPasswd(uid int, username string, lookupByName bool) (*user.User, error) { f, err := os.Open(UserDatabase) if err != nil { return nil, err } defer f.Close() exist := false p := &PasswdRecord{} scanner := bufio.NewScanner(f) for scanner.Scan() { fields := strings.SplitN(scanner.Text(), ":", 7) if strings.HasPrefix(fields[0], "#") { continue } if len(fields) < 7 { return nil, InvalidUserDatabaseError } p = &PasswdRecord{fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6]} if lookupByName { if username == p.Name { exist = true break } } else { if strconv.Itoa(uid) == p.Uid { exist = true break } } } if !exist { if lookupByName { return nil, user.UnknownUserError(username) } else { return nil, user.UnknownUserIdError(uid) } } u := &user.User{ Username: p.Name, Uid: p.Uid, Gid: p.Gid, Name: p.Gecos, HomeDir: p.Directory, } // The gecos field isn't quite standardized. Some docs // say: "It is expected to be a comma separated list of // personal data where the first item is the full name of the // user." if i := strings.Index(u.Name, ","); i >= 0 { u.Name = u.Name[:i] } return u, nil }
func LookupId(uid string, users []*User) (*User, error) { uidInt, err := strconv.Atoi(uid) if err != nil { return nil, err } if users == nil { var err error users, err = AllUsers() if err != nil { return nil, err } } for _, user := range users { if user.Uid == uid { return user, nil } } return nil, osuser.UnknownUserIdError(uidInt) }
func lookupDscl(uid int, username string, lookupByName bool) (*user.User, error) { dscl := exec.Command("/usr/bin/dscl", ".", "-list", "users", "uid") dsclbuf, err := dscl.StdoutPipe() if err != nil { return nil, err } if err = dscl.Start(); err != nil { return nil, err } name := "" id := "" exist := false scanner := bufio.NewScanner(dsclbuf) for scanner.Scan() { scannerWord := bufio.NewScanner(bytes.NewReader(scanner.Bytes())) scannerWord.Split(bufio.ScanWords) scannerWord.Scan() name = scannerWord.Text() scannerWord.Scan() id = scannerWord.Text() if lookupByName { if username != name && "_"+username != name { continue } } else { if strconv.Itoa(uid) != id { continue } } dscl = exec.Command("/usr/bin/dscl", "-plist", ".", "-read", "users/"+name) dsclbuf, err = dscl.StdoutPipe() if err != nil { return nil, err } if err = dscl.Start(); err != nil { return nil, err } var uplist userplist buf, err := ioutil.ReadAll(dsclbuf) if err != nil { return nil, err } _, err = plist.Unmarshal(buf, &uplist) if err != nil { return nil, err } exist = true if name[0] == '_' { name = name[1:] } u := &user.User{ Username: name, Uid: id, Gid: uplist.Gid[0], Name: uplist.Name[0], HomeDir: uplist.HomeDir[0], } return u, nil } if !exist { if lookupByName { return nil, user.UnknownUserError(username) } else { return nil, user.UnknownUserIdError(uid) } } return nil, InvalidUserDatabaseError }