diff --git a/client/allocdir/alloc_dir_posix.go b/client/allocdir/alloc_dir_posix.go index d5e4a9296..e6205b220 100644 --- a/client/allocdir/alloc_dir_posix.go +++ b/client/allocdir/alloc_dir_posix.go @@ -5,6 +5,7 @@ package allocdir import ( "fmt" + "github.com/hashicorp/nomad/helper/user-lookup" "os" "os/user" "strconv" @@ -26,7 +27,7 @@ func (d *AllocDir) dropDirPermissions(path string) error { return nil } - u, err := user.Lookup("nobody") + u, err := userlookup.Lookup("nobody") if err != nil { return err } diff --git a/client/driver/executor/exec_linux.go b/client/driver/executor/exec_linux.go index a5b33e06b..26d2d7145 100644 --- a/client/driver/executor/exec_linux.go +++ b/client/driver/executor/exec_linux.go @@ -14,18 +14,18 @@ import ( "syscall" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/nomad/client/allocdir" - "github.com/hashicorp/nomad/client/driver/environment" - "github.com/hashicorp/nomad/client/driver/spawn" - "github.com/hashicorp/nomad/helper/args" - "github.com/hashicorp/nomad/nomad/structs" - "github.com/opencontainers/runc/libcontainer/cgroups" cgroupFs "github.com/opencontainers/runc/libcontainer/cgroups/fs" "github.com/opencontainers/runc/libcontainer/cgroups/systemd" cgroupConfig "github.com/opencontainers/runc/libcontainer/configs" + "github.com/hashicorp/nomad/client/allocdir" + "github.com/hashicorp/nomad/client/driver/environment" + "github.com/hashicorp/nomad/client/driver/spawn" cstructs "github.com/hashicorp/nomad/client/driver/structs" + "github.com/hashicorp/nomad/helper/args" + "github.com/hashicorp/nomad/helper/user-lookup" + "github.com/hashicorp/nomad/nomad/structs" ) var ( @@ -124,7 +124,7 @@ func (e *LinuxExecutor) ID() (string, error) { // runAs takes a user id as a string and looks up the user, and sets the command // to execute as that user. func (e *LinuxExecutor) runAs(userid string) error { - u, err := user.Lookup(userid) + u, err := userlookup.Lookup(userid) if err != nil { return fmt.Errorf("Failed to identify user %v: %v", userid, err) } diff --git a/helper/user-lookup/user-lookup.go b/helper/user-lookup/user-lookup.go new file mode 100644 index 000000000..439449787 --- /dev/null +++ b/helper/user-lookup/user-lookup.go @@ -0,0 +1,33 @@ +package userlookup + +import ( + "fmt" + "io/ioutil" + "os/user" + "strings" +) + +// Lookup checks 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. +// Credit to @creak, https://github.com/docker/docker/pull/1096 +func Lookup(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") +}