drop_root/
group.rs

1use std::ffi::CString;
2use crate::DropRootError;
3
4fn get_group_id_of(group_name: &str) -> Result<libc::gid_t, DropRootError> {
5    let group_record = unsafe { libc::getgrnam(CString::new(group_name)?.as_ptr()) };
6
7    if group_record.is_null() {
8        #[cfg(feature = "logging")]
9        log::error!("Unable to getgrnam of the group {group_name}");
10        return Err(DropRootError::last_os_error());
11    }
12
13    let group_id = unsafe { (*group_record).gr_gid };
14    Ok(group_id)
15}
16
17/// Set group ID and supplementary group list.
18pub fn set_group<T: AsRef<str>>(group_name: T) -> Result<(), DropRootError> {
19    let group_name = group_name.as_ref();
20    let group_id = get_group_id_of(group_name)?;
21
22    if unsafe { libc::setgid(group_id) } != 0 {
23        #[cfg(feature = "logging")]
24        log::error!("Unable to setgid of group {group_name}");
25        return Err(DropRootError::last_os_error());
26    }
27
28    if unsafe { libc::setgroups(1, &group_id) } != 0 {
29        #[cfg(feature = "logging")]
30        log::error!("Unable to setgroups for group {group_name}");
31        return Err(DropRootError::last_os_error());
32    }
33
34    #[cfg(feature = "logging")]
35    log::info!("Set process effective group to {group_name}");
36    Ok(())
37}