blob: ee0507c76c1400964e4b80ecccb0dc3fd49a768a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
use std::{fs::File, io::Result, os::unix::prelude::AsRawFd, path::Path};
use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode, 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<SetEUID> {
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<SetEGID> {
let old_gid = unistd::getegid();
unistd::setegid(gid).to_io_result()?;
Ok(SetEGID(old_gid))
}
pub fn create_as<P: AsRef<Path>>(
path: P,
uid: Option<unistd::Uid>,
gid: Option<unistd::Gid>,
) -> Result<File> {
let _setegid = gid.map(setegid).transpose()?;
let _seteuid = uid.map(seteuid).transpose()?;
File::create(path)
}
pub struct Chdir(Dir);
impl Drop for Chdir {
fn drop(&mut self) {
unistd::fchdir(self.0.as_raw_fd()).expect("failed to revert directory change");
}
}
pub fn chdir<P: AsRef<Path>>(path: P) -> Result<Chdir> {
let dir = Dir::open(
".",
OFlag::O_PATH | OFlag::O_CLOEXEC | OFlag::O_NOFOLLOW,
Mode::empty(),
)
.to_io_result()?;
unistd::chdir(path.as_ref()).to_io_result()?;
Ok(Chdir(dir))
}
|