Simplify getUser() to use libcontainer built-in functionality

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2020-07-29 14:26:05 +02:00
parent f50a40e889
commit 65a33d02f6
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
2 changed files with 25 additions and 57 deletions

View File

@ -12,15 +12,11 @@ import (
func (daemon *Daemon) execSetPlatformOpt(c *container.Container, ec *exec.Config, p *specs.Process) error { func (daemon *Daemon) execSetPlatformOpt(c *container.Container, ec *exec.Config, p *specs.Process) error {
if len(ec.User) > 0 { if len(ec.User) > 0 {
uid, gid, additionalGids, err := getUser(c, ec.User) var err error
p.User, err = getUser(c, ec.User)
if err != nil { if err != nil {
return err return err
} }
p.User = specs.User{
UID: uid,
GID: gid,
AdditionalGids: additionalGids,
}
} }
if ec.Privileged { if ec.Privileged {
if p.Capabilities == nil { if p.Capabilities == nil {

View File

@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/daemon"
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
@ -171,64 +170,42 @@ func WithCapabilities(c *container.Container) coci.SpecOpts {
} }
} }
func readUserFile(c *container.Container, p string) (io.ReadCloser, error) { func resourcePath(c *container.Container, getPath func() (string, error)) (string, error) {
fp, err := c.GetResourcePath(p) p, err := getPath()
if err != nil { if err != nil {
return nil, err return "", err
} }
fh, err := os.Open(fp) return c.GetResourcePath(p)
if err != nil {
// This is needed because a nil *os.File is different to a nil
// io.ReadCloser and this causes GetExecUser to not detect that the
// container file is missing.
return nil, err
}
return fh, nil
} }
func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) { func getUser(c *container.Container, username string) (specs.User, error) {
passwdPath, err := user.GetPasswdPath() var usr specs.User
passwdPath, err := resourcePath(c, user.GetPasswdPath)
if err != nil { if err != nil {
return 0, 0, nil, err return usr, err
} }
groupPath, err := user.GetGroupPath() groupPath, err := resourcePath(c, user.GetGroupPath)
if err != nil { if err != nil {
return 0, 0, nil, err return usr, err
} }
passwdFile, err := readUserFile(c, passwdPath) execUser, err := user.GetExecUserPath(username, nil, passwdPath, groupPath)
if err == nil { if err != nil {
defer passwdFile.Close() return usr, err
}
groupFile, err := readUserFile(c, groupPath)
if err == nil {
defer groupFile.Close()
} }
usr.UID = uint32(execUser.Uid)
usr.GID = uint32(execUser.Gid)
execUser, err := user.GetExecUser(username, nil, passwdFile, groupFile)
if err != nil {
return 0, 0, nil, err
}
// todo: fix this double read by a change to libcontainer/user pkg
groupFile, err = readUserFile(c, groupPath)
if err == nil {
defer groupFile.Close()
}
var addGroups []int var addGroups []int
if len(c.HostConfig.GroupAdd) > 0 { if len(c.HostConfig.GroupAdd) > 0 {
addGroups, err = user.GetAdditionalGroups(c.HostConfig.GroupAdd, groupFile) addGroups, err = user.GetAdditionalGroupsPath(c.HostConfig.GroupAdd, groupPath)
if err != nil { if err != nil {
return 0, 0, nil, err return usr, err
} }
} }
uid := uint32(execUser.Uid) for _, g := range append(execUser.Sgids, addGroups...) {
gid := uint32(execUser.Gid) usr.AdditionalGids = append(usr.AdditionalGids, uint32(g))
sgids := append(execUser.Sgids, addGroups...)
var additionalGids []uint32
for _, g := range sgids {
additionalGids = append(additionalGids, uint32(g))
} }
return uid, gid, additionalGids, nil return usr, nil
} }
func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) { func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) {
@ -1023,15 +1000,10 @@ func WithSysctls(c *container.Container) coci.SpecOpts {
// WithUser sets the container's user // WithUser sets the container's user
func WithUser(c *container.Container) coci.SpecOpts { func WithUser(c *container.Container) coci.SpecOpts {
return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error { return func(ctx context.Context, _ coci.Client, _ *containers.Container, s *coci.Spec) error {
uid, gid, additionalGids, err := getUser(c, c.Config.User) var err error
if err != nil { s.Process.User, err = getUser(c, c.Config.User)
return err return err
} }
s.Process.User.UID = uid
s.Process.User.GID = gid
s.Process.User.AdditionalGids = additionalGids
return nil
}
} }
func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, err error) { func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, err error) {