960f03269c
documentation - Rename crate from workshop-executor to workshop-baker - Add MDBook documentation infrastructure with Chinese docs (Vol1/2/3) - Implement engine module with cgroups resource management - Add package manager support (apt, pacman) - Add daemon module with Unix socket IPC and heartbeat - Add privdrop dependency for privilege dropping - Implement prebake stages (bootstrap, depssystem, depsuser, environment, hooks) - Add new bake.sh.tmpl pipeline template for osu! project - Add pipeline implicit parameter documentation (PIPELINE_BAREMETAL_*, PIPELINE_CONTAINER_*, PIPELINE_UNCOVER_SECRET)
80 lines
2.6 KiB
Rust
80 lines
2.6 KiB
Rust
fn lookup_user(
|
|
user: &OsStr,
|
|
fallback_to_ids_if_names_are_numeric: bool,
|
|
) -> Result<UserIds, PrivDropError> {
|
|
let username = CString::new(user.as_bytes())
|
|
.map_err(|_| PrivDropError::from((ErrorKind::SysError, "Invalid username")))?;
|
|
|
|
let mut pwd = MaybeUninit::<libc::passwd>::uninit();
|
|
let mut pwent = std::ptr::null_mut::<libc::passwd>();
|
|
|
|
// Start with the initial buffer size and increase if needed
|
|
let mut bufsize = INITIAL_BUFFER_SIZE;
|
|
let mut pwbuf = vec![0; bufsize];
|
|
|
|
let mut ret;
|
|
loop {
|
|
ret = unsafe {
|
|
libc::getpwnam_r(
|
|
username.as_ptr(),
|
|
pwd.as_mut_ptr(),
|
|
pwbuf.as_mut_ptr(),
|
|
pwbuf.len(),
|
|
&mut pwent,
|
|
)
|
|
};
|
|
|
|
// If we get ERANGE, the buffer was too small, double it and try again
|
|
if ret == libc::ERANGE {
|
|
bufsize *= 2;
|
|
pwbuf.resize(bufsize, 0);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ret != 0 || pwent.is_null() {
|
|
if !fallback_to_ids_if_names_are_numeric {
|
|
if ret != 0 && ret == libc::ENOENT {
|
|
return Err(PrivDropError::from((ErrorKind::SysError, "User not found")));
|
|
} else if ret != 0 {
|
|
return Err(PrivDropError::from((
|
|
ErrorKind::SysError,
|
|
"Failed to look up user",
|
|
)));
|
|
} else {
|
|
return Err(PrivDropError::from((ErrorKind::SysError, "User not found")));
|
|
}
|
|
}
|
|
|
|
// Try to parse the username as a numeric UID
|
|
let user_str = user.to_str().ok_or_else(|| {
|
|
PrivDropError::from((
|
|
ErrorKind::SysError,
|
|
"User not found and username is not valid UTF-8",
|
|
))
|
|
})?;
|
|
|
|
let uid = user_str.parse().map_err(|_| {
|
|
PrivDropError::from((
|
|
ErrorKind::SysError,
|
|
"User not found and username is not a valid numeric ID",
|
|
))
|
|
})?;
|
|
|
|
return Ok(UserIds {
|
|
uid: Some(uid),
|
|
gid: None,
|
|
group_list: None,
|
|
});
|
|
}
|
|
|
|
let uid = unsafe { *pwent }.pw_uid;
|
|
let gid = unsafe { *pwent }.pw_gid;
|
|
|
|
Ok(UserIds {
|
|
uid: Some(uid),
|
|
gid: Some(gid),
|
|
group_list: None,
|
|
})
|
|
} |