elevator_lib/
unix.rs

1//! Module for running programs with elevated privileges on Unix-like systems.
2//!
3//! # Examples
4//!
5//! ```
6//! use elevator_lib::run_elevated;
7//!
8//! // Run a program with elevated privileges
9//! if let Err(err) = run_elevated("/usr/bin/some_program", &["arg1", "arg2"]) {
10//!     eprintln!("Error: {}", err);
11//! }
12//! ```
13
14use std::ffi::OsStr;
15use std::process::{Command, ExitStatus};
16
17/// Run a program with elevated privileges.
18///
19/// This function attempts to elevate the program's privileges by setting the effective user ID to root
20/// using the `setuid` system call, and then spawns a new process to execute the specified program
21/// with the given arguments.
22///
23/// # Arguments
24///
25/// * `program_path` - The path to the program to execute.
26/// * `args` - A single str of arguments to pass to the program.
27///
28/// # Errors
29///
30/// Returns an `io::Error` if setting the effective user ID to root fails, or if spawning the process fails.
31///
32/// # Examples
33///
34/// ```
35/// use elevator_lib::run_elevated;
36///
37/// // Run a program with elevated privileges
38/// if let Err(err) = run_elevated("/usr/bin/some_program", "arg1 arg2") {
39///     eprintln!("Error: {}", err);
40/// }
41/// ```
42#[inline]
43pub fn run_elevated<S: AsRef<OsStr>>(program_path: S, args: &str) -> std::io::Result<ExitStatus> {
44    // Check if the process is running with elevated privileges
45    if !is_running_as_sudo() {
46        return Err(std::io::Error::new(
47            std::io::ErrorKind::Other,
48            "Error: This program must be run with elevated privileges (sudo).",
49        ));
50    }
51
52    // Split the arguments string at spaces
53    let args_split: Vec<&str> = args.split_whitespace().collect();
54
55    // Start the specified program with the provided arguments
56    let mut child = Command::new(program_path).args(args_split).spawn()?;
57
58    // Wait for the process to finish and capture the exit status
59    let exit_status = child.wait()?;
60
61    Ok(exit_status)
62}
63
64// Function to check if the process is running with elevated privileges (sudo)
65pub fn is_running_as_sudo() -> bool {
66    // Check if the environment variable "SUDO_USER" is set
67    std::env::var("SUDO_USER").is_ok()
68}