mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
//go:build (!cgo || osusergo) && !windows
|
|
|
|
package server
|
|
|
|
import (
|
|
"os"
|
|
"os/user"
|
|
"strconv"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// lookupWithGetent looks up a user by name, falling back to getent if os/user fails.
|
|
// Without CGO, os/user only reads /etc/passwd and misses NSS-provided users.
|
|
// getent goes through the host's NSS stack.
|
|
func lookupWithGetent(username string) (*user.User, error) {
|
|
u, err := user.Lookup(username)
|
|
if err == nil {
|
|
return u, nil
|
|
}
|
|
|
|
stdErr := err
|
|
log.Debugf("os/user.Lookup(%q) failed, trying getent: %v", username, err)
|
|
|
|
u, _, getentErr := runGetent(username)
|
|
if getentErr != nil {
|
|
log.Debugf("getent fallback for %q also failed: %v", username, getentErr)
|
|
return nil, stdErr
|
|
}
|
|
|
|
return u, nil
|
|
}
|
|
|
|
// currentUserWithGetent gets the current user, falling back to getent if os/user fails.
|
|
func currentUserWithGetent() (*user.User, error) {
|
|
u, err := user.Current()
|
|
if err == nil {
|
|
return u, nil
|
|
}
|
|
|
|
stdErr := err
|
|
uid := strconv.Itoa(os.Getuid())
|
|
log.Debugf("os/user.Current() failed, trying getent with UID %s: %v", uid, err)
|
|
|
|
u, _, getentErr := runGetent(uid)
|
|
if getentErr != nil {
|
|
return nil, stdErr
|
|
}
|
|
|
|
return u, nil
|
|
}
|
|
|
|
// groupIdsWithFallback gets group IDs for a user via the id command first,
|
|
// falling back to user.GroupIds().
|
|
// NOTE: unlike lookupWithGetent/currentUserWithGetent which try stdlib first,
|
|
// this intentionally tries `id -G` first because without CGO, user.GroupIds()
|
|
// only reads /etc/group and silently returns incomplete results for NSS users
|
|
// (no error, just missing groups). The id command goes through NSS and returns
|
|
// the full set.
|
|
func groupIdsWithFallback(u *user.User) ([]string, error) {
|
|
ids, err := runIdGroups(u.Username)
|
|
if err == nil {
|
|
return ids, nil
|
|
}
|
|
|
|
log.Debugf("id -G %q failed, falling back to user.GroupIds(): %v", u.Username, err)
|
|
|
|
ids, stdErr := u.GroupIds()
|
|
if stdErr != nil {
|
|
return nil, stdErr
|
|
}
|
|
|
|
return ids, nil
|
|
}
|