diff --git a/client/allocdir/fs_unix.go b/client/allocdir/fs_unix.go index 72ec9a1ea..6f58b20d3 100644 --- a/client/allocdir/fs_unix.go +++ b/client/allocdir/fs_unix.go @@ -40,14 +40,17 @@ func dropDirPermissions(path string, desired os.FileMode) error { return nil } - nobody := users.Nobody() - - uid, err := getUid(&nobody) + nobody, err := users.Nobody() if err != nil { return err } - gid, err := getGid(&nobody) + uid, err := getUid(nobody) + if err != nil { + return err + } + + gid, err := getGid(nobody) if err != nil { return err } diff --git a/helper/users/lookup.go b/helper/users/lookup.go index bac6a6155..87b7817e8 100644 --- a/helper/users/lookup.go +++ b/helper/users/lookup.go @@ -1,33 +1,29 @@ package users import ( - "fmt" "os/user" "sync" ) // lock is used to serialize all user lookup at the process level, because // some NSS implementations are not concurrency safe -var lock *sync.Mutex +var lock sync.Mutex // nobody is a cached copy of the nobody user, which is going to be looked-up // frequently and is unlikely to be modified on the underlying system. -var nobody user.User +var nobody *user.User // Nobody returns User data for the "nobody" user on the system, bypassing the // locking / file read / NSS lookup. -func Nobody() user.User { - // original is immutable via copy by value - return nobody -} - -func init() { - lock = new(sync.Mutex) - u, err := Lookup("nobody") - if err != nil { - panic(fmt.Sprintf("unable to lookup the nobody user: %v", err)) +func Nobody() (*user.User, error) { + lock.Lock() + defer lock.Unlock() + if nobody != nil { + return nobody, nil } - nobody = *u + u, err := user.Lookup("nobody") + nobody = u + return u, err } // Lookup username while holding a global process lock.