drop_root/
user.rs

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
17/// Set user ID.
18pub 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}