From 014efc77a70a015bc6b143f09cebac882c8c3d95 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Mon, 1 Jul 2013 16:48:59 -0700 Subject: [PATCH 1/2] Remove the os.user dependency and manually lookup /etc/passwd instead Upstream-commit: eb38750d99d4f9706cb2abcb861c84e1d309bd40 Component: engine --- components/engine/sysinit.go | 7 ++----- components/engine/utils/utils.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) 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 df615844a7..ea5c08e60e 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,23 @@ func ParseRepositoryTag(repos string) (string, string) { } return repos, "" } + +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") +} From 08204dd54e889b398b1f2b15a18f2f3cdf39ee4b Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Mon, 1 Jul 2013 17:08:42 -0700 Subject: [PATCH 2/2] Add unit test to check wrong uid case Upstream-commit: e41507bde2d87cb9bbb0c328e414a39354dae10e Component: engine --- components/engine/container_test.go | 17 +++++++++++++++++ components/engine/utils/utils.go | 3 +++ 2 files changed, 20 insertions(+) diff --git a/components/engine/container_test.go b/components/engine/container_test.go index 7646bb3793..b4e6551a34 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/utils/utils.go b/components/engine/utils/utils.go index ea5c08e60e..c1f5f6a00c 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -702,6 +702,9 @@ 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 {