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
17pub 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}