#[cfg(unix)]
use nix::unistd::{setgid, setgroups, setuid, Uid, User};
#[cfg(unix)]
#[cfg_attr(docsrs, doc(cfg(unix)))]
pub fn drop_privileges(user: &str) -> anyhow::Result<()> {
if !Uid::effective().is_root() {
return Ok(()); }
let user = User::from_name(user)?
.ok_or_else(|| anyhow::anyhow!("User '{}' not found", user))?;
setgroups(&[user.gid])?;
setgid(user.gid)?;
setuid(user.uid)?;
if user.uid.as_raw() != 0 && setuid(Uid::from_raw(0)).is_ok() {
anyhow::bail!("privilege drop failed: process can still regain root");
}
tracing::info!("Dropped privileges to uid={} gid={}", user.uid, user.gid);
Ok(())
}
#[cfg(not(unix))]
pub fn drop_privileges(_user: &str) -> anyhow::Result<()> {
Ok(()) }