summaryrefslogtreecommitdiffstats
path: root/src/util/uid.rs
blob: ee1e16b30d9503d529b30480cf1b7a3ae56ee8a2 (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
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<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)
}