1use std::ffi::CString;
2use crate::DropRootError;
3
4fn get_user_id_of(user_name: &str) -> Result<libc::uid_t, DropRootError> {
5 let passwd_record = unsafe { libc::getpwnam(CString::new(user_name)?.as_ptr()) };
6
7 if passwd_record.is_null() {
8 #[cfg(feature = "logging")]
9 log::error!("Unable to getpwnam of the user {user_name}");
10 return Err(DropRootError::last_os_error());
11 }
12
13 let user_id = unsafe { (*passwd_record).pw_uid };
14 Ok(user_id)
15}
16
17pub fn set_user<T: AsRef<str>>(user_name: T) -> Result<(), DropRootError> {
19 let user_name = user_name.as_ref();
20 let user_id = get_user_id_of(user_name)?;
21
22 if unsafe { libc::setuid(user_id) } != 0 {
23 #[cfg(feature = "logging")]
24 log::error!("Unable to setuid of user {user_name}");
25 return Err(DropRootError::last_os_error());
26 }
27
28 #[cfg(feature = "logging")]
29 log::info!("Set process effective user to {user_name}");
30 Ok(())
31}