From 3a18f0ecb5748488501c565e995ec12a29e66966 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Sat, 8 Sep 2018 12:35:03 -0700 Subject: [PATCH] os/user: retrieve Current username from /etc/passwd, not $USER Per golang/go#27524 there are situations where the username for the uid does not match the value in the $USER environment variable and it seems sensible to choose the value in /etc/passwd when they disagree. This may make the Current() call slightly more expensive, since we read /etc/passwd with cgo disabled instead of just checking the environment. However, we cache the result of Current() calls, so we only invoke this cost once in the lifetime of the process. Fixes #14626. Fixes #27524. Updates #24884. Change-Id: I0dcd224cf7f61dd5292f3fcc363aa2e9656a2cb1 Reviewed-on: https://go-review.googlesource.com/134218 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- src/os/user/lookup_stubs.go | 11 +++++++++-- src/os/user/user_test.go | 18 ++---------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/os/user/lookup_stubs.go b/src/os/user/lookup_stubs.go index f7d138ff46..9fc03c65d9 100644 --- a/src/os/user/lookup_stubs.go +++ b/src/os/user/lookup_stubs.go @@ -19,8 +19,15 @@ func init() { } func current() (*User, error) { - u := &User{ - Uid: currentUID(), + uid := currentUID() + // $USER and /etc/passwd may disagree; prefer the latter if we can get it. + // See issue 27524 for more information. + u, err := lookupUserId(uid) + if err == nil { + return u, nil + } + u = &User{ + Uid: uid, Gid: currentGID(), Username: os.Getenv("USER"), Name: "", // ignored diff --git a/src/os/user/user_test.go b/src/os/user/user_test.go index 8fd760e649..2563077eb2 100644 --- a/src/os/user/user_test.go +++ b/src/os/user/user_test.go @@ -5,33 +5,18 @@ package user import ( - "internal/testenv" - "os" "runtime" "testing" ) func checkUser(t *testing.T) { + t.Helper() if !userImplemented { t.Skip("user: not implemented; skipping tests") } } func TestCurrent(t *testing.T) { - // The Go builders (in particular the ones using containers) - // often have minimal environments without $HOME or $USER set, - // which breaks Current which relies on those working as a - // fallback. - // TODO: we should fix that (Issue 24884) and remove these - // workarounds. - if testenv.Builder() != "" && runtime.GOOS != "windows" && runtime.GOOS != "plan9" { - if os.Getenv("HOME") == "" { - os.Setenv("HOME", "/tmp") - } - if os.Getenv("USER") == "" { - os.Setenv("USER", "gobuilder") - } - } u, err := Current() if err != nil { t.Fatalf("Current: %v (got %#v)", err, u) @@ -108,6 +93,7 @@ func TestLookupId(t *testing.T) { } func checkGroup(t *testing.T) { + t.Helper() if !groupImplemented { t.Skip("user: group not implemented; skipping test") } -- 2.48.1