diff --git a/src/sudo.rs b/src/sudo.rs index b51a283a..ae4d66fa 100644 --- a/src/sudo.rs +++ b/src/sudo.rs @@ -22,11 +22,25 @@ pub struct Sudo { } impl Sudo { + /// Get the `sudo` binary or the `gsudo` binary in the case of `gsudo` + /// masquerading as the `sudo` binary. + fn determine_sudo_variant(sudo_p: PathBuf) -> (PathBuf, SudoKind) { + match which("gsudo") { + Some(gsudo_p) => { + match std::fs::canonicalize(&gsudo_p).unwrap() == std::fs::canonicalize(&sudo_p).unwrap() { + true => (gsudo_p, SudoKind::Gsudo), + false => (sudo_p, SudoKind::Sudo), + } + } + None => (sudo_p, SudoKind::Sudo), + } + } + /// Get the `sudo` binary for this platform. pub fn detect() -> Option { which("doas") .map(|p| (p, SudoKind::Doas)) - .or_else(|| which("sudo").map(|p| (p, SudoKind::Sudo))) + .or_else(|| which("sudo").map(Self::determine_sudo_variant)) .or_else(|| which("gsudo").map(|p| (p, SudoKind::Gsudo))) .or_else(|| which("pkexec").map(|p| (p, SudoKind::Pkexec))) .or_else(|| which("please").map(|p| (p, SudoKind::Please))) @@ -65,9 +79,11 @@ impl Sudo { cmd.arg("-v"); } SudoKind::Gsudo => { - // Shows current user, cache and console status. + // `gsudo` doesn't have anything like `sudo -v` to cache credentials, + // so we just execute a dummy `echo` command so we have something + // unobtrusive to run. // See: https://gerardog.github.io/gsudo/docs/usage - cmd.arg("status"); + cmd.arg("echo"); } SudoKind::Pkexec => { // I don't think this does anything; `pkexec` usually asks for