aboutsummaryrefslogtreecommitdiff
path: root/pkg/chrootuser/user.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/chrootuser/user.go')
-rw-r--r--pkg/chrootuser/user.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/pkg/chrootuser/user.go b/pkg/chrootuser/user.go
new file mode 100644
index 000000000..a024877a5
--- /dev/null
+++ b/pkg/chrootuser/user.go
@@ -0,0 +1,71 @@
+package chrootuser
+
+import (
+ "os/user"
+ "strconv"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+// GetUser will return the uid, gid of the user specified in the userspec
+// it will use the /etc/password and /etc/shadow files inside of the rootdir
+// to return this information.
+// userspace format [user | user:group | uid | uid:gid | user:gid | uid:group ]
+func GetUser(rootdir, userspec string) (uint32, uint32, error) {
+ var gid64 uint64
+ var gerr error = user.UnknownGroupError("error looking up group")
+
+ spec := strings.SplitN(userspec, ":", 2)
+ userspec = spec[0]
+ groupspec := ""
+ if userspec == "" {
+ return 0, 0, nil
+ }
+ if len(spec) > 1 {
+ groupspec = spec[1]
+ }
+
+ uid64, uerr := strconv.ParseUint(userspec, 10, 32)
+ if uerr == nil && groupspec == "" {
+ // We parsed the user name as a number, and there's no group
+ // component, so try to look up the primary GID of the user who
+ // has this UID.
+ var name string
+ name, gid64, gerr = lookupGroupForUIDInContainer(rootdir, uid64)
+ if gerr == nil {
+ userspec = name
+ } else {
+ // Leave userspec alone, but swallow the error and just
+ // use GID 0.
+ gid64 = 0
+ gerr = nil
+ }
+ }
+ if uerr != nil {
+ // The user ID couldn't be parsed as a number, so try to look
+ // up the user's UID and primary GID.
+ uid64, gid64, uerr = lookupUserInContainer(rootdir, userspec)
+ gerr = uerr
+ }
+
+ if groupspec != "" {
+ // We have a group name or number, so parse it.
+ gid64, gerr = strconv.ParseUint(groupspec, 10, 32)
+ if gerr != nil {
+ // The group couldn't be parsed as a number, so look up
+ // the group's GID.
+ gid64, gerr = lookupGroupInContainer(rootdir, groupspec)
+ }
+ }
+
+ if uerr == nil && gerr == nil {
+ return uint32(uid64), uint32(gid64), nil
+ }
+
+ err := errors.Wrapf(uerr, "error determining run uid")
+ if uerr == nil {
+ err = errors.Wrapf(gerr, "error determining run gid")
+ }
+ return 0, 0, err
+}