diff --git a/components/engine/container_test.go b/components/engine/container_test.go index e7f6818eb6..6a09f567d4 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -849,6 +849,23 @@ func TestUser(t *testing.T) { if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") { t.Error(string(output)) } + + // Test an wrong username + container, err = builder.Create(&Config{ + Image: GetTestImage(runtime).ID, + Cmd: []string{"id"}, + + User: "unkownuser", + }, + ) + if err != nil { + t.Fatal(err) + } + defer runtime.Destroy(container) + output, err = container.Output() + if container.State.ExitCode == 0 { + t.Fatal("Starting container with wrong uid should fail but it passed.") + } } func TestMultipleContainers(t *testing.T) { diff --git a/components/engine/sysinit.go b/components/engine/sysinit.go index 622dbdf095..fb36cd2543 100644 --- a/components/engine/sysinit.go +++ b/components/engine/sysinit.go @@ -3,10 +3,10 @@ package docker import ( "flag" "fmt" + "github.com/dotcloud/docker/utils" "log" "os" "os/exec" - "os/user" "strconv" "strings" "syscall" @@ -27,10 +27,7 @@ func changeUser(u string) { if u == "" { return } - userent, err := user.LookupId(u) - if err != nil { - userent, err = user.Lookup(u) - } + userent, err := utils.UserLookup(u) if err != nil { log.Fatalf("Unable to find user %v: %v", u, err) } diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index 153b1b910c..c85731a2ad 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -14,6 +14,7 @@ import ( "net/http" "os" "os/exec" + "os/user" "path/filepath" "runtime" "strconv" @@ -700,3 +701,26 @@ func ParseRepositoryTag(repos string) (string, string) { } return repos, "" } + +// UserLookup check if the given username or uid is present in /etc/passwd +// and returns the user struct. +// If the username is not found, an error is returned. +func UserLookup(uid string) (*user.User, error) { + file, err := ioutil.ReadFile("/etc/passwd") + if err != nil { + return nil, err + } + for _, line := range strings.Split(string(file), "\n") { + data := strings.Split(line, ":") + if len(data) > 5 && (data[0] == uid || data[2] == uid) { + return &user.User{ + Uid: data[2], + Gid: data[3], + Username: data[0], + Name: data[4], + HomeDir: data[5], + }, nil + } + } + return nil, fmt.Errorf("User not found in /etc/passwd") +}