|
7 | 7 | "fmt" |
8 | 8 | "os" |
9 | 9 | "os/exec" //nolint:depguard // We want no logging and no soft-context signal handling |
| 10 | + "slices" |
| 11 | + "strings" |
10 | 12 |
|
11 | 13 | "golang.org/x/sys/unix" |
12 | 14 |
|
@@ -41,18 +43,26 @@ func startInBackground(includeEnv bool, args ...string) error { |
41 | 43 | return nil |
42 | 44 | } |
43 | 45 |
|
44 | | -func startInBackgroundAsRoot(_ context.Context, args ...string) error { |
| 46 | +func startInBackgroundAsRoot(ctx context.Context, args ...string) error { |
45 | 47 | if isAdmin() { |
46 | 48 | return startInBackground(false, args...) |
47 | 49 | } |
48 | 50 | // Run sudo with a prompt explaining why root credentials are needed. |
49 | | - cmd := exec.Command("sudo", append([]string{ |
50 | | - "-b", "-p", |
51 | | - fmt.Sprintf( |
52 | | - "Need root privileges to run: %s\nPassword:", |
53 | | - shellquote.ShellString(args[0], args[1:])), |
54 | | - }, args...)...) |
55 | | - return cmd.Run() |
| 51 | + const promptContext = "telepresence network daemon" |
| 52 | + err := exec.Command("sudo", append([]string{"-b", "-p", fmt.Sprintf("[sudo: %s] Password: ", promptContext)}, args...)...).Run() |
| 53 | + if err == nil { |
| 54 | + return nil |
| 55 | + } |
| 56 | + // Are we using sudo-rs? |
| 57 | + out, err2 := exec.Command("sudo", "--version").CombinedOutput() |
| 58 | + if err2 != nil || !strings.Contains(string(out), "sudo-rs") { |
| 59 | + // return the original error |
| 60 | + return err |
| 61 | + } |
| 62 | + // sudo-rs does not support the "-b" (background) option. We need it to start a shell command that backgrounds the executable |
| 63 | + // once the user has entered their password. |
| 64 | + cmdString := shellquote.ShellArgsString(slices.Insert(args, 0, "setsid")) + "</dev/null >/dev/null 2>&1 &" |
| 65 | + return exec.Command("sudo", "-p", promptContext, "sh", "-c", cmdString).Run() |
56 | 66 | } |
57 | 67 |
|
58 | 68 | func terminate(p *os.Process) error { |
|
0 commit comments