From 125f4eecf51548d136853213481a327cd20afbff Mon Sep 17 00:00:00 2001 From: Ben Segall Date: Thu, 4 Jul 2024 20:33:59 +0000 Subject: [PATCH] Avoid calling user.Current() on windows Use the current process token to look up the user's name on Windows. This is more reliable than using the USER or USERNAME environment variables, which are not always set, or might be overridden by the user accidentally or maliciously. cl/649607112 (google-internal) --- glog_file.go | 6 ++---- glog_file_nonwindows.go | 12 ++++++++++++ glog_file_windows.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 glog_file_nonwindows.go create mode 100644 glog_file_windows.go diff --git a/glog_file.go b/glog_file.go index a1551dbc..8eb8b08c 100644 --- a/glog_file.go +++ b/glog_file.go @@ -26,7 +26,6 @@ import ( "fmt" "io" "os" - "os/user" "path/filepath" "runtime" "strings" @@ -68,9 +67,8 @@ func init() { host = shortHostname(h) } - current, err := user.Current() - if err == nil { - userName = current.Username + if u := lookupUser(); u != "" { + userName = u } // Sanitize userName since it is used to construct file paths. userName = strings.Map(func(r rune) rune { diff --git a/glog_file_nonwindows.go b/glog_file_nonwindows.go new file mode 100644 index 00000000..d5cdb793 --- /dev/null +++ b/glog_file_nonwindows.go @@ -0,0 +1,12 @@ +//go:build !windows + +package glog + +import "os/user" + +func lookupUser() string { + if current, err := user.Current(); err == nil { + return current.Username + } + return "" +} diff --git a/glog_file_windows.go b/glog_file_windows.go new file mode 100644 index 00000000..a9e4f609 --- /dev/null +++ b/glog_file_windows.go @@ -0,0 +1,30 @@ +//go:build windows + +package glog + +import ( + "syscall" +) + +// This follows the logic in the standard library's user.Current() function, except +// that it leaves out the potentially expensive calls required to look up the user's +// display name in Active Directory. +func lookupUser() string { + token, err := syscall.OpenCurrentProcessToken() + if err != nil { + return "" + } + defer token.Close() + tokenUser, err := token.GetTokenUser() + if err != nil { + return "" + } + username, _, accountType, err := tokenUser.User.Sid.LookupAccount("") + if err != nil { + return "" + } + if accountType != syscall.SidTypeUser { + return "" + } + return username +}