mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-06 22:27:36 +02:00
drive/driveimpl: use sudo or su to run file server
Some systems have `sudo`, some have `su`. This tries both, increasing the chance that we can run the file server as an unprivileged user. Updates #14629 Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:
parent
3d1e4f147a
commit
aa6a2d1e56
@ -333,8 +333,14 @@ func (s *userServer) run() error {
|
||||
args = append(args, s.Name, s.Path)
|
||||
}
|
||||
var cmd *exec.Cmd
|
||||
if su := s.canSU(); su != "" {
|
||||
s.logf("starting taildrive file server as user %q", s.username)
|
||||
|
||||
if s.canSudo() {
|
||||
s.logf("starting taildrive file server with sudo as user %q", s.username)
|
||||
allArgs := []string{"-n", "-u", s.username, s.executable}
|
||||
allArgs = append(allArgs, args...)
|
||||
cmd = exec.Command("sudo", allArgs...)
|
||||
} else if su := s.canSU(); su != "" {
|
||||
s.logf("starting taildrive file server with su as user %q", s.username)
|
||||
// Quote and escape arguments. Use single quotes to prevent shell substitutions.
|
||||
for i, arg := range args {
|
||||
args[i] = "'" + strings.ReplaceAll(arg, "'", "'\"'\"'") + "'"
|
||||
@ -343,7 +349,7 @@ func (s *userServer) run() error {
|
||||
allArgs := []string{s.username, "-c", cmdString}
|
||||
cmd = exec.Command(su, allArgs...)
|
||||
} else {
|
||||
// If we were root, we should have been able to sudo as a specific
|
||||
// If we were root, we should have been able to sudo or su as a specific
|
||||
// user, but let's check just to make sure, since we never want to
|
||||
// access shared folders as root.
|
||||
err := s.assertNotRoot()
|
||||
@ -409,6 +415,18 @@ func (s *userServer) run() error {
|
||||
"DELETE": true,
|
||||
}
|
||||
|
||||
// canSudo checks wether we can sudo -u the configured executable as the
|
||||
// configured user by attempting to call the executable with the '-h' flag to
|
||||
// print help.
|
||||
func (s *userServer) canSudo() bool {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
if err := exec.CommandContext(ctx, "sudo", "-n", "-u", s.username, s.executable, "-h").Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// canSU checks whether the current process can run su with the right username.
|
||||
// If su can be run, this returns the path to the su command.
|
||||
// If not, this returns the empty string "".
|
||||
|
Loading…
Reference in New Issue
Block a user