diff --git a/client/ssh/lookup.go b/client/ssh/lookup.go new file mode 100644 index 000000000..7acef8f0b --- /dev/null +++ b/client/ssh/lookup.go @@ -0,0 +1,10 @@ +//go:build !darwin +// +build !darwin + +package ssh + +import "os/user" + +func userNameLookup(username string) (*user.User, error) { + return user.Lookup(username) +} diff --git a/client/ssh/lookup_darwin.go b/client/ssh/lookup_darwin.go new file mode 100644 index 000000000..e6f3c3b93 --- /dev/null +++ b/client/ssh/lookup_darwin.go @@ -0,0 +1,47 @@ +//go:build darwin +// +build darwin + +package ssh + +import ( + "bytes" + "fmt" + "os/exec" + "os/user" + "strings" +) + +func userNameLookup(username string) (*user.User, error) { + var userObject *user.User + userObject, err := user.Lookup(username) + if err != nil && err.Error() == user.UnknownUserError(username).Error() { + return idUserNameLookup(username) + } else if err != nil { + return nil, err + } + + return userObject, nil +} + +func idUserNameLookup(username string) (*user.User, error) { + cmd := exec.Command("id", "-P", username) + out, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("error while retrieving user with id -P command, error: %v", err) + } + colon := ":" + + if !bytes.Contains(out, []byte(username+colon)) { + return nil, fmt.Errorf("unable to find user in returned string") + } + // netbird:********:501:20::0:0:netbird:/Users/netbird:/bin/zsh + parts := strings.SplitN(string(out), colon, 10) + userObject := &user.User{ + Username: parts[0], + Uid: parts[2], + Gid: parts[3], + Name: parts[7], + HomeDir: parts[8], + } + return userObject, nil +} diff --git a/client/ssh/server.go b/client/ssh/server.go index 70f13e7c4..5d63362b9 100644 --- a/client/ssh/server.go +++ b/client/ssh/server.go @@ -137,7 +137,7 @@ func (srv *DefaultServer) sessionHandler(session ssh.Session) { } }() - localUser, err := user.Lookup(session.User()) + localUser, err := userNameLookup(session.User()) if err != nil { _, err = fmt.Fprintf(session, "remote SSH server couldn't find local user %s\n", session.User()) //nolint err = session.Exit(1)