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 users::switch::{set_current_gid, set_current_uid};
use users::{get_current_uid, get_group_by_name, get_user_by_name};

fn is_root() -> bool {
	get_current_uid() == 0
}

pub fn switch_user(user: &str) -> Result<bool, String> {
	if !is_root() {
		return Err(format!(
			"Cannot switch to user {}, run as root to support user switching",
			user
		));
	}

	let user_id = match get_user_by_name(&user) {
		Some(user) => user.uid(),
		None => return Err(format!("User {} unknown", user)),
	};

	match set_current_uid(user_id) {
		Ok(_) => Ok(true),
		Err(e) => Err(format!("Cannot switch to user {}: {}", user, e)),
	}
}

pub fn switch_group(group: &str) -> Result<bool, String> {
	if !is_root() {
		return Err(format!(
			"Cannot switch to group {}, run as root to support group switching",
			group
		));
	}

	let group_id = match get_group_by_name(&group) {
		Some(group) => group.gid(),
		None => return Err(format!("Group {} unknown", group)),
	};

	match set_current_gid(group_id) {
		Ok(_) => Ok(true),
		Err(e) => Err(format!("Cannot switch to group {}: {}", group, e)),
	}
}