diff --git a/oci/spec_opts.go b/oci/spec_opts.go index 973ac7e15..d7fe4a29f 100644 --- a/oci/spec_opts.go +++ b/oci/spec_opts.go @@ -478,12 +478,13 @@ func WithUser(userstr string) SpecOpts { } f := func(root string) error { if username != "" { - uid, _, err = getUIDGIDFromPath(root, func(u user.User) bool { + user, err := getUserFromPath(root, func(u user.User) bool { return u.Name == username }) if err != nil { return err } + uid = uint32(user.Uid) } if groupname != "" { gid, err = getGIDFromPath(root, func(g user.Group) bool { @@ -541,7 +542,7 @@ func WithUserID(uid uint32) SpecOpts { if !isRootfsAbs(s.Root.Path) { return errors.Errorf("rootfs absolute path is required") } - uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { + user, err := getUserFromPath(s.Root.Path, func(u user.User) bool { return u.Uid == int(uid) }) if err != nil { @@ -551,7 +552,7 @@ func WithUserID(uid uint32) SpecOpts { } return err } - s.Process.User.UID, s.Process.User.GID = uuid, ugid + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) return nil } @@ -567,7 +568,7 @@ func WithUserID(uid uint32) SpecOpts { return err } return mount.WithTempMount(ctx, mounts, func(root string) error { - uuid, ugid, err := getUIDGIDFromPath(root, func(u user.User) bool { + user, err := getUserFromPath(root, func(u user.User) bool { return u.Uid == int(uid) }) if err != nil { @@ -577,7 +578,7 @@ func WithUserID(uid uint32) SpecOpts { } return err } - s.Process.User.UID, s.Process.User.GID = uuid, ugid + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) return nil }) } @@ -595,13 +596,13 @@ func WithUsername(username string) SpecOpts { if !isRootfsAbs(s.Root.Path) { return errors.Errorf("rootfs absolute path is required") } - uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { + user, err := getUserFromPath(s.Root.Path, func(u user.User) bool { return u.Name == username }) if err != nil { return err } - s.Process.User.UID, s.Process.User.GID = uid, gid + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) return nil } if c.Snapshotter == "" { @@ -616,13 +617,13 @@ func WithUsername(username string) SpecOpts { return err } return mount.WithTempMount(ctx, mounts, func(root string) error { - uid, gid, err := getUIDGIDFromPath(root, func(u user.User) bool { + user, err := getUserFromPath(root, func(u user.User) bool { return u.Name == username }) if err != nil { return err } - s.Process.User.UID, s.Process.User.GID = uid, gid + s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid) return nil }) } else if s.Windows != nil { @@ -636,43 +637,27 @@ func WithUsername(username string) SpecOpts { // WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed // for a particular user in the /etc/groups file of the image's root filesystem -func WithAdditionalGIDs(username string) SpecOpts { +// The passed in user can be either a uid or a username. +func WithAdditionalGIDs(userstr string) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { setProcess(s) - if c.Snapshotter == "" && c.SnapshotKey == "" { - if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") - } - gids, err := getSupplementalGroupsFromPath(s.Root.Path, func(g user.Group) bool { - // we only want supplemental groups - if g.Name == username { - return false - } - for _, entry := range g.List { - if entry == username { - return true + setAdditionalGids := func(root string) error { + var username string + uid, err := strconv.Atoi(userstr) + if err == nil { + user, err := getUserFromPath(root, func(u user.User) bool { + return u.Uid == uid + }) + if err != nil { + if os.IsNotExist(err) || err == errNoUsersFound { + return nil } + return err } - return false - }) - if err != nil { - return err + username = user.Name + } else { + username = userstr } - s.Process.User.AdditionalGids = gids - return nil - } - if c.Snapshotter == "" { - return errors.Errorf("no snapshotter set for container") - } - if c.SnapshotKey == "" { - return errors.Errorf("rootfs snapshot not created for container") - } - snapshotter := client.SnapshotService(c.Snapshotter) - mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) - if err != nil { - return err - } - return mount.WithTempMount(ctx, mounts, func(root string) error { gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool { // we only want supplemental groups if g.Name == username { @@ -686,11 +671,32 @@ func WithAdditionalGIDs(username string) SpecOpts { return false }) if err != nil { + if os.IsNotExist(err) { + return nil + } return err } s.Process.User.AdditionalGids = gids return nil - }) + } + if c.Snapshotter == "" && c.SnapshotKey == "" { + if !isRootfsAbs(s.Root.Path) { + return errors.Errorf("rootfs absolute path is required") + } + return setAdditionalGids(s.Root.Path) + } + if c.Snapshotter == "" { + return errors.Errorf("no snapshotter set for container") + } + if c.SnapshotKey == "" { + return errors.Errorf("rootfs snapshot not created for container") + } + snapshotter := client.SnapshotService(c.Snapshotter) + mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) + if err != nil { + return err + } + return mount.WithTempMount(ctx, mounts, setAdditionalGids) } } @@ -741,20 +747,19 @@ func WithAmbientCapabilities(caps []string) SpecOpts { var errNoUsersFound = errors.New("no users found") -func getUIDGIDFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) { +func getUserFromPath(root string, filter func(user.User) bool) (user.User, error) { ppath, err := fs.RootPath(root, "/etc/passwd") if err != nil { - return 0, 0, err + return user.User{}, err } users, err := user.ParsePasswdFileFilter(ppath, filter) if err != nil { - return 0, 0, err + return user.User{}, err } if len(users) == 0 { - return 0, 0, errNoUsersFound + return user.User{}, errNoUsersFound } - u := users[0] - return uint32(u.Uid), uint32(u.Gid), nil + return users[0], nil } var errNoGroupsFound = errors.New("no groups found")