use std::sync::OnceLock;
const TEST_SEAM_ENV: &str = "OPENLATCH_TEST_OS_USER";
static OS_USER: OnceLock<Option<String>> = OnceLock::new();
pub fn os_user() -> Option<String> {
OS_USER.get_or_init(resolve).clone()
}
fn resolve() -> Option<String> {
if let Some(seam) = env_non_empty(TEST_SEAM_ENV) {
return Some(seam);
}
resolve_platform()
}
#[cfg(unix)]
fn resolve_platform() -> Option<String> {
env_non_empty("SUDO_USER")
.or_else(passwd_name)
.or_else(|| env_non_empty("USER"))
.or_else(|| env_non_empty("LOGNAME"))
}
#[cfg(unix)]
fn passwd_name() -> Option<String> {
const MAX_BUF: usize = 64 * 1024;
let uid = unsafe { libc::getuid() };
let mut bufsize = match unsafe { libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) } {
n if n > 0 => n as usize,
_ => 1024,
};
loop {
let mut buf = vec![0 as libc::c_char; bufsize];
let mut passwd: libc::passwd = unsafe { std::mem::zeroed() };
let mut result: *mut libc::passwd = std::ptr::null_mut();
let rc =
unsafe { libc::getpwuid_r(uid, &mut passwd, buf.as_mut_ptr(), bufsize, &mut result) };
if rc == 0 && !result.is_null() {
let name = unsafe { std::ffi::CStr::from_ptr(passwd.pw_name) };
return name
.to_str()
.ok()
.filter(|s| !s.is_empty())
.map(str::to_owned);
}
if rc != libc::ERANGE || bufsize >= MAX_BUF {
return None;
}
bufsize = (bufsize * 2).min(MAX_BUF);
}
}
#[cfg(windows)]
fn resolve_platform() -> Option<String> {
windows_user_name().or_else(|| env_non_empty("USERNAME"))
}
#[cfg(windows)]
fn windows_user_name() -> Option<String> {
use windows_sys::Win32::System::WindowsProgramming::GetUserNameW;
const UNLEN_NUL: usize = 257;
let mut size = UNLEN_NUL as u32;
let mut buf = vec![0u16; UNLEN_NUL];
if unsafe { GetUserNameW(buf.as_mut_ptr(), &mut size) } == 0 {
return None;
}
let len = (size as usize).saturating_sub(1).min(buf.len());
let name = String::from_utf16_lossy(&buf[..len]);
if name.is_empty() {
None
} else {
Some(name)
}
}
fn env_non_empty(key: &str) -> Option<String> {
std::env::var(key).ok().filter(|v| !v.is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::daemon::identity::test_support::EnvGuard;
#[test]
fn resolution_order_is_seam_then_platform() {
let _lock = crate::daemon::identity::ENV_LOCK.blocking_lock();
let env = EnvGuard::clear();
env.set(TEST_SEAM_ENV, "seam-user");
assert_eq!(resolve().as_deref(), Some("seam-user"));
env.set(TEST_SEAM_ENV, "");
assert_ne!(
resolve().as_deref(),
Some(""),
"an empty seam must be treated as unset, never stamped"
);
env.unset(TEST_SEAM_ENV);
#[cfg(unix)]
unix_ladder(&env);
#[cfg(windows)]
windows_ladder();
}
#[cfg(unix)]
fn unix_ladder(env: &EnvGuard) {
let from_syscall = resolve();
assert!(
from_syscall.as_deref().is_none_or(|s| !s.is_empty()),
"getpwuid_r must return a real name or nothing, never an empty string"
);
env.set("SUDO_USER", "ol-sudo-user-fixture");
assert_eq!(resolve().as_deref(), Some("ol-sudo-user-fixture"));
assert_ne!(
resolve(),
from_syscall,
"under sudo the syscall answers root; SUDO_USER must win"
);
env.set("SUDO_USER", "");
assert_eq!(resolve(), from_syscall);
env.unset("SUDO_USER");
env.set("USER", "env-user");
env.set("LOGNAME", "env-logname");
if from_syscall.is_some() {
assert_eq!(resolve(), from_syscall, "the syscall outranks $USER");
}
}
#[cfg(windows)]
fn windows_ladder() {
let name = super::windows_user_name();
assert!(
name.as_deref().is_none_or(|s| !s.is_empty()),
"GetUserNameW must return a real name or nothing"
);
if name.is_some() {
assert_eq!(resolve(), name, "the syscall outranks %USERNAME%");
}
}
}