From de72a1f9fc636fbf1e1427d27fa38a717243a09b Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 19 Feb 2022 15:45:59 -0800 Subject: [PATCH] ipn/ipnserver: let TS_PERMIT_CERT_UID contain a username too, not just uid Don't make users map their system's "caddy" (or whatever) system user to its userid. We can do that. Support either a uid or a username. RELNOTE=TS_PERMIT_CERT_UID can contain a uid or username Change-Id: I7451b537a5e118b818addf1353882291d5f0d07f Signed-off-by: Brad Fitzpatrick --- ipn/ipnserver/server.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/ipn/ipnserver/server.go b/ipn/ipnserver/server.go index 6c1a30dbc..522fead66 100644 --- a/ipn/ipnserver/server.go +++ b/ipn/ipnserver/server.go @@ -458,6 +458,29 @@ func (s *Server) localAPIPermissions(ci connIdentity) (read, write bool) { return false, false } +// userIDFromString maps from either a numeric user id in string form +// ("998") or username ("caddy") to its string userid ("998"). +// It returns the empty string on error. +func userIDFromString(v string) string { + if v == "" || isAllDigit(v) { + return v + } + u, err := user.Lookup(v) + if err != nil { + return "" + } + return u.Uid +} + +func isAllDigit(s string) bool { + for i := 0; i < len(s); i++ { + if b := s[i]; b < '0' || b > '9' { + return false + } + } + return true +} + // connCanFetchCerts reports whether ci is allowed to fetch HTTPS // certs from this server when it wouldn't otherwise be able to. // @@ -471,7 +494,7 @@ func (s *Server) localAPIPermissions(ci connIdentity) (read, write bool) { func (s *Server) connCanFetchCerts(ci connIdentity) bool { if ci.IsUnixSock && ci.Creds != nil { connUID, ok := ci.Creds.UserID() - if ok && connUID == envknob.String("TS_PERMIT_CERT_UID") { + if ok && connUID == userIDFromString(envknob.String("TS_PERMIT_CERT_UID")) { return true } }