ipn/ipnserver: work around os/user.LookupId failure on Windows

If we can't find the mapping from SID ("user ID") -> username, don't
treat that as a fatal. Apparently that happens in the wild for Reasons.
Ignore it for now. It's just a nice-to-have for error messages in the
rare multi-user case.

Updates #869

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
bradfitz/win_firewall_async
Brad Fitzpatrick 4 years ago committed by Brad Fitzpatrick
parent 09721fede8
commit c64718e9a0

@ -119,7 +119,7 @@ type connIdentity struct {
// (pid, userid, user). If it's not Windows (for now), it returns a nil error // (pid, userid, user). If it's not Windows (for now), it returns a nil error
// and a ConnIdentity with Unknown set true. It's only an error if we expected // and a ConnIdentity with Unknown set true. It's only an error if we expected
// to be able to map it and couldn't. // to be able to map it and couldn't.
func getConnIdentity(c net.Conn) (ci connIdentity, err error) { func (s *server) getConnIdentity(c net.Conn) (ci connIdentity, err error) {
if runtime.GOOS != "windows" { // for now; TODO: expand to other OSes if runtime.GOOS != "windows" { // for now; TODO: expand to other OSes
return connIdentity{Unknown: true}, nil return connIdentity{Unknown: true}, nil
} }
@ -152,7 +152,7 @@ func getConnIdentity(c net.Conn) (ci connIdentity, err error) {
return ci, fmt.Errorf("failed to map connection's pid to a user%s: %w", hint, err) return ci, fmt.Errorf("failed to map connection's pid to a user%s: %w", hint, err)
} }
ci.UserID = uid ci.UserID = uid
u, err := user.LookupId(uid) u, err := s.lookupUserFromID(uid)
if err != nil { if err != nil {
return ci, fmt.Errorf("failed to look up user from userid: %w", err) return ci, fmt.Errorf("failed to look up user from userid: %w", err)
} }
@ -160,6 +160,22 @@ func getConnIdentity(c net.Conn) (ci connIdentity, err error) {
return ci, nil return ci, nil
} }
func (s *server) lookupUserFromID(uid string) (*user.User, error) {
u, err := user.LookupId(uid)
if err != nil && runtime.GOOS == "windows" && errors.Is(err, syscall.Errno(0x534)) {
s.logf("[warning] issue 869: os/user.LookupId failed; ignoring")
// Work around https://github.com/tailscale/tailscale/issues/869 for
// now. We don't strictly need the username. It's just a nice-to-have.
// So make up a *user.User if their machine is broken in this way.
return &user.User{
Uid: uid,
Username: "unknown-user-" + uid,
Name: "unknown user " + uid,
}, nil
}
return u, err
}
func (s *server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) { func (s *server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) {
// First see if it's an HTTP request. // First see if it's an HTTP request.
br := bufio.NewReader(c) br := bufio.NewReader(c)
@ -227,7 +243,7 @@ func (s *server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) {
} }
func (s *server) addConn(c net.Conn, isHTTP bool) (ci connIdentity, err error) { func (s *server) addConn(c net.Conn, isHTTP bool) (ci connIdentity, err error) {
ci, err = getConnIdentity(c) ci, err = s.getConnIdentity(c)
if err != nil { if err != nil {
return return
} }

Loading…
Cancel
Save