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}