kanidm_utils_users/
unix.rs
1use libc::passwd as c_passwd;
2use libc::{gid_t, uid_t};
3use std::ffi::{CStr, OsStr, OsString};
4use std::os::unix::ffi::OsStrExt;
5use std::{mem, ptr};
6
7pub fn get_current_uid() -> uid_t {
8 unsafe { libc::getuid() }
9}
10
11pub fn get_effective_uid() -> uid_t {
12 unsafe { libc::geteuid() }
13}
14
15pub fn get_current_gid() -> gid_t {
16 unsafe { libc::getgid() }
17}
18
19pub fn get_effective_gid() -> gid_t {
20 unsafe { libc::getegid() }
21}
22
23pub fn get_user_name_by_uid(uid: uid_t) -> Option<OsString> {
24 let mut passwd = unsafe { mem::zeroed::<c_passwd>() };
25 let mut buf = vec![0; 2048];
26 let mut result = ptr::null_mut::<c_passwd>();
27
28 loop {
29 let r =
30 unsafe { libc::getpwuid_r(uid, &mut passwd, buf.as_mut_ptr(), buf.len(), &mut result) };
31
32 if r != libc::ERANGE {
33 break;
34 }
35
36 let newsize = buf.len().checked_mul(2)?;
37 buf.resize(newsize, 0);
38 }
39
40 if result.is_null() {
41 return None;
44 }
45
46 if result != &mut passwd {
47 return None;
49 }
50
51 let name = unsafe {
52 OsStr::from_bytes(CStr::from_ptr(result.read().pw_name).to_bytes()).to_os_string()
53 };
54
55 Some(name)
56}
57
58#[test]
59fn test_get_effective_uid() {
61 let euid = get_effective_uid();
62 assert!(euid > 0);
63 let egid = get_effective_gid();
64 assert!(egid > 0);
65
66 let username = get_user_name_by_uid(get_current_uid());
67 assert!(username.is_some());
68}