use tor_error::error_report;
use tor_persist::StateMgr;
pub(crate) struct StateMgrUnlockGuard<'a, T: StateMgr + 'a> {
mgr: &'a T,
}
impl<'a, T: StateMgr + 'a> Drop for StateMgrUnlockGuard<'a, T> {
fn drop(&mut self) {
if let Err(e) = self.mgr.unlock() {
error_report!(e, "Failed to unlock state manager");
}
}
}
impl<'a, T: StateMgr + 'a> StateMgrUnlockGuard<'a, T> {
pub(crate) fn new(mgr: &'a T) -> Self {
Self { mgr }
}
pub(crate) fn disarm(self) {
std::mem::forget(self);
}
}
pub(crate) fn running_as_setuid() -> bool {
cfg_if::cfg_if! {
if #[cfg(any(target_os = "fuchsia",
target_os = "linux",
target_os = "l4re",
target_os = "android",
target_os = "emscripten",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd",
))] {
let mut resuid = [0, 0, 0];
let mut resgid = [0, 0, 0];
unsafe {
let _ = libc::getresuid(&mut resuid[0], &mut resuid[1], &mut resuid[2]);
let _ = libc::getresgid(&mut resgid[0], &mut resgid[1], &mut resgid[2]);
}
let same_resuid = resuid.iter().all(|uid| uid == &resuid[0]);
let same_resgid = resgid.iter().all(|gid| gid == &resgid[0]);
!(same_resuid && same_resgid)
} else if #[cfg(any(target_family = "unix", target_os = "vxworks"))] {
let same_reuid = unsafe { libc::geteuid() == libc::getuid() };
let same_regid = unsafe { libc::getegid() == libc::getgid() };
!(same_reuid && same_regid)
} else {
false
}
}
}