1use runas_with_inherited_cmd as runas;
2
3pub fn admin() -> anyhow::Result<()> {
4 let mut binding = runas::Command::new(std::env::current_exe()?);
5 let mut cmd = binding
6 .args(std::env::args().skip(1).collect::<Vec<_>>().as_slice());
7
8
9
10 #[cfg(target_os = "windows")]
11 let show_flag = true;
12 #[cfg(not(target_os = "windows"))]
13 let show_flag = false;
14 cmd = cmd.show(show_flag);
15
16 match cmd.status()
17 {
18 Ok(_) => Ok(()),
19 Err(_) => anyhow::bail!("failed"),
20 }
21}
22
23#[cfg(windows)]
24pub fn is_elevated() -> bool {
25 use winapi::shared::minwindef::DWORD;
26 use winapi::um::handleapi::CloseHandle;
27 use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcessToken};
28 use winapi::um::securitybaseapi::GetTokenInformation;
29 use winapi::um::winnt::{TOKEN_ELEVATION, TOKEN_QUERY, TokenElevation};
30
31 unsafe {
32 let process = GetCurrentProcess();
33 let mut token = std::ptr::null_mut();
34 if OpenProcessToken(process, TOKEN_QUERY, &mut token) == 0 {
35 return false;
36 }
37 let mut elev: TOKEN_ELEVATION = std::mem::zeroed();
38 let mut ret_len: DWORD = 0;
39 let ok = GetTokenInformation(
40 token,
41 TokenElevation,
42 &mut elev as *mut _ as *mut _,
43 std::mem::size_of::<TOKEN_ELEVATION>() as DWORD,
44 &mut ret_len,
45 );
46 CloseHandle(token);
47 if ok == 0 {
48 return false;
49 }
50 elev.TokenIsElevated != 0
51 }
52}
53
54#[cfg(unix)]
55pub fn is_elevated() -> bool {
56 nix::unistd::geteuid().is_root()
57}