Skip to content

Commit

Permalink
logName(): lazily lookup userName instead of on init()
Browse files Browse the repository at this point in the history
Commit c46b9e1 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 <github@gone.nl>
  • Loading branch information
thaJeztah committed May 10, 2020
1 parent ea583d2 commit 134f148
Showing 1 changed file with 35 additions and 29 deletions.
64 changes: 35 additions & 29 deletions klog_file.go
Expand Up @@ -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.
Expand All @@ -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(),
Expand Down

0 comments on commit 134f148

Please sign in to comment.