diff --git a/ssh/tailssh/incubator.go b/ssh/tailssh/incubator.go index c3e865630..40bc2eaf1 100644 --- a/ssh/tailssh/incubator.go +++ b/ssh/tailssh/incubator.go @@ -693,3 +693,39 @@ func acceptEnvPair(kv string) bool { } return k == "TERM" || k == "LANG" || strings.HasPrefix(k, "LC_") } + +func fileExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} + +func (ia *incubatorArgs) loginArgs() []string { + switch runtime.GOOS { + case "linux": + if distro.Get() == distro.Arch && !fileExists("/etc/pam.d/remote") { + // See https://github.com/tailscale/tailscale/issues/4924 + // + // Arch uses a different login binary that makes the -h flag set the PAM + // service to "remote". So if they don't have that configured, don't + // pass -h. + return []string{ia.loginCmdPath, "-f", ia.localUser, "-p"} + } + return []string{ia.loginCmdPath, "-f", ia.localUser, "-h", ia.remoteIP, "-p"} + case "darwin", "freebsd": + return []string{ia.loginCmdPath, "-fp", "-h", ia.remoteIP, ia.localUser} + } + panic("unimplemented") +} + +func setGroups(groupIDs []int) error { + if runtime.GOOS == "darwin" && len(groupIDs) > 16 { + // darwin returns "invalid argument" if more than 16 groups are passed to syscall.Setgroups + // some info can be found here: + // https://opensource.apple.com/source/samba/samba-187.8/patches/support-darwin-initgroups-syscall.auto.html + // this fix isn't great, as anyone reading this has probably just wasted hours figuring out why + // some permissions thing isn't working, due to some arbitrary group ordering, but it at least allows + // this to work for more things than it previously did. + groupIDs = groupIDs[:16] + } + return syscall.Setgroups(groupIDs) +} diff --git a/ssh/tailssh/incubator_darwin.go b/ssh/tailssh/incubator_darwin.go deleted file mode 100644 index 960a8b08b..000000000 --- a/ssh/tailssh/incubator_darwin.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tailssh - -import "syscall" - -func (ia *incubatorArgs) loginArgs() []string { - return []string{ia.loginCmdPath, "-fp", "-h", ia.remoteIP, ia.localUser} -} - -func setGroups(groupIDs []int) error { - // darwin returns "invalid argument" if more than 16 groups are passed to syscall.Setgroups - // some info can be found here: - // https://opensource.apple.com/source/samba/samba-187.8/patches/support-darwin-initgroups-syscall.auto.html - // this fix isn't great, as anyone reading this has probably just wasted hours figuring out why - // some permissions thing isn't working, due to some arbitrary group ordering, but it at least allows - // this to work for more things than it previously did. - return syscall.Setgroups(groupIDs[:16]) -} diff --git a/ssh/tailssh/incubator_freebsd.go b/ssh/tailssh/incubator_freebsd.go deleted file mode 100644 index 3dfbfec2b..000000000 --- a/ssh/tailssh/incubator_freebsd.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tailssh - -import "syscall" - -func (ia *incubatorArgs) loginArgs() []string { - return []string{ia.loginCmdPath, "-fp", "-h", ia.remoteIP, ia.localUser} -} - -func setGroups(groupIDs []int) error { - return syscall.Setgroups(groupIDs) -} diff --git a/ssh/tailssh/incubator_linux.go b/ssh/tailssh/incubator_linux.go index 2a1c342e6..205a071bb 100644 --- a/ssh/tailssh/incubator_linux.go +++ b/ssh/tailssh/incubator_linux.go @@ -16,7 +16,6 @@ import ( "github.com/godbus/dbus/v5" "tailscale.com/types/logger" - "tailscale.com/version/distro" ) func init() { @@ -173,24 +172,3 @@ func maybeStartLoginSessionLinux(logf logger.Logf, ia incubatorArgs) (func() err } return nil, nil } - -func fileExists(path string) bool { - _, err := os.Stat(path) - return err == nil -} - -func (ia *incubatorArgs) loginArgs() []string { - if distro.Get() == distro.Arch && !fileExists("/etc/pam.d/remote") { - // See https://github.com/tailscale/tailscale/issues/4924 - // - // Arch uses a different login binary that makes the -h flag set the PAM - // service to "remote". So if they don't have that configured, don't - // pass -h. - return []string{ia.loginCmdPath, "-f", ia.localUser, "-p"} - } - return []string{ia.loginCmdPath, "-f", ia.localUser, "-h", ia.remoteIP, "-p"} -} - -func setGroups(groupIDs []int) error { - return syscall.Setgroups(groupIDs) -}