From 134f14871df1b41690e120832e64d127877a6537 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 10 May 2020 13:39:23 +0200 Subject: [PATCH] logName(): lazily lookup userName instead of on init() Commit c46b9e13e600dbe96a19e86a8eb5dbf9ebe00ffa implemented a workaround for situations on Windows where `user.Current()` was not available. On Linux/Unix ennvironments, `user.Current()` may be calling (among others) `getgrnam_r` (https://linux.die.net/man/3/getgrgid_r), which: > Returns a pointer to a structure containing the broken-out fields of > the record in the group database (e.g., the local group file /etc/group, > NIS, and LDAP) that matches the group name name. This means that the `init()` function might be making network connections, which is not desirable. This patch changes the lookup to be performed lazily. A `sync.Once` was added so that lookup is only performed once (to keep the behavior that was previously provided by using `init()`. Signed-off-by: Sebastiaan van Stijn --- klog_file.go | 64 ++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/klog_file.go b/klog_file.go index 458456a4..de830d92 100644 --- a/klog_file.go +++ b/klog_file.go @@ -44,43 +44,49 @@ func createLogDirs() { } var ( - pid = os.Getpid() - program = filepath.Base(os.Args[0]) - host = "unknownhost" - userName = "unknownuser" + pid = os.Getpid() + program = filepath.Base(os.Args[0]) + host = "unknownhost" + userName = "unknownuser" + userNameOnce sync.Once ) func init() { - h, err := os.Hostname() - if err == nil { + if h, err := os.Hostname(); err == nil { host = shortHostname(h) } +} - // On Windows, the Go 'user' package requires netapi32.dll. - // This affects Windows Nano Server: - // https://github.com/golang/go/issues/21867 - // Fallback to using environment variables. - if runtime.GOOS == "windows" { - u := os.Getenv("USERNAME") - if len(u) == 0 { - return - } - // Sanitize the USERNAME since it may contain filepath separators. - u = strings.Replace(u, `\`, "_", -1) +func getUserName() string { + userNameOnce.Do(func() { + // On Windows, the Go 'user' package requires netapi32.dll. + // This affects Windows Nano Server: + // https://github.com/golang/go/issues/21867 + // Fallback to using environment variables. + if runtime.GOOS == "windows" { + u := os.Getenv("USERNAME") + if len(u) == 0 { + return + } + // Sanitize the USERNAME since it may contain filepath separators. + u = strings.Replace(u, `\`, "_", -1) - // user.Current().Username normally produces something like 'USERDOMAIN\USERNAME' - d := os.Getenv("USERDOMAIN") - if len(d) != 0 { - userName = d + "_" + u + // user.Current().Username normally produces something like 'USERDOMAIN\USERNAME' + d := os.Getenv("USERDOMAIN") + if len(d) != 0 { + userName = d + "_" + u + } else { + userName = u + } } else { - userName = u - } - } else { - current, err := user.Current() - if err == nil { - userName = current.Username + current, err := user.Current() + if err == nil { + userName = current.Username + } } - } + }) + + return userName } // shortHostname returns its argument, truncating at the first period. @@ -98,7 +104,7 @@ func logName(tag string, t time.Time) (name, link string) { name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d", program, host, - userName, + getUserName(), tag, t.Year(), t.Month(),