use std::{fs::File, io::Result, path::Path}; use nix::unistd; use super::ToIOResult; pub struct SetEUID(unistd::Uid); impl Drop for SetEUID { fn drop(&mut self) { unistd::seteuid(self.0).expect("failed to reset effective UID"); } } pub fn seteuid(uid: unistd::Uid) -> Result { let old_uid = unistd::geteuid(); unistd::seteuid(uid).to_io_result()?; Ok(SetEUID(old_uid)) } pub struct SetEGID(unistd::Gid); impl Drop for SetEGID { fn drop(&mut self) { unistd::setegid(self.0).expect("failed to reset effective GID"); } } pub fn setegid(gid: unistd::Gid) -> Result { let old_gid = unistd::getegid(); unistd::setegid(gid).to_io_result()?; Ok(SetEGID(old_gid)) } pub fn create_as>( path: P, uid: Option, gid: Option, ) -> Result { let _setegid = gid.map(setegid).transpose()?; let _seteuid = uid.map(seteuid).transpose()?; File::create(path) }