in lib/ec2macosinit/util.go [82:150]
func getUIDandGID(username string) (uid int, gid int, err error) {
var uidstr, gidstr string
// Preference is user.Lookup(), if it works
u, lookuperr := user.Lookup(username)
if lookuperr != nil {
// user.Lookup() has failed, second try by checking the DS cache
out, cmderr := executeCommand([]string{"dscacheutil", "-q", "user", "-a", "name", username}, "", []string{})
if cmderr != nil {
// dscacheutil has failed with an error
return 0, 0, fmt.Errorf("ec2macosinit: error while looking up user %s: \n"+
"user.Lookup() error: %s \ndscacheutil error: %s\ndscacheutil stderr: %s\n",
username, lookuperr, cmderr, out.stderr)
}
// Check length of stdout - dscacheutil returns nothing if user is not found
if len(out.stdout) > 0 { // dscacheutil has returned something
// Command output from dscacheutil should look like:
// name: ec2-user
// password: ********
// uid: 501
// gid: 20
// dir: /Users/ec2-user
// shell: /bin/bash
// gecos: ec2-user
dsSplit := strings.Split(out.stdout, "\n") // split on newline to separate uid and gid
for _, e := range dsSplit {
eSplit := strings.Fields(e) // split into fields to separate tag with id
// Find UID and GID and set them
if strings.HasPrefix(e, "uid") {
if len(eSplit) != 2 {
// dscacheutil has returned some sort of weird output that can't be split
return 0, 0, fmt.Errorf("ec2macosinit: error while splitting dscacheutil uid output for user %s: %s\n"+
"user.Lookup() error: %s \ndscacheutil error: %s\ndscacheutil stderr: %s\n",
username, out.stdout, lookuperr, cmderr, out.stderr)
}
uidstr = eSplit[1]
} else if strings.HasPrefix(e, "gid") {
if len(eSplit) != 2 {
// dscacheutil has returned some sort of weird output that can't be split
return 0, 0, fmt.Errorf("ec2macosinit: error while splitting dscacheutil gid output for user %s: %s\n"+
"user.Lookup() error: %s \ndscacheutil error: %s\ndscacheutil stderr: %s\n",
username, out.stdout, lookuperr, cmderr, out.stderr)
}
gidstr = eSplit[1]
}
}
} else {
// dscacheutil has returned nothing, user is not found
return 0, 0, fmt.Errorf("ec2macosinit: user %s not found: \n"+
"user.Lookup() error: %s \ndscacheutil error: %s\ndscacheutil stderr: %s\n",
username, lookuperr, cmderr, out.stderr)
}
} else {
// user.Lookup() was successful, use the returned UID/GID
uidstr = u.Uid
gidstr = u.Gid
}
// Convert UID and GID to int
uid, err = strconv.Atoi(uidstr)
if err != nil {
return 0, 0, fmt.Errorf("ec2macosinit: error while converting UID to int: %s\n", err)
}
gid, err = strconv.Atoi(gidstr)
if err != nil {
return 0, 0, fmt.Errorf("ec2macosinit: error while converting GID to int: %s\n", err)
}
return uid, gid, nil
}