From 270b9f8ef2c0a7f2cc0fa3141dab379020703e0a Mon Sep 17 00:00:00 2001 From: Firstyear Date: Tue, 1 Aug 2023 19:08:21 +1000 Subject: [PATCH] Resolve build failiures when selinux is enabled (#1927) --- Cargo.lock | 34 +++++++++++----------- libs/users/src/lib.rs | 42 ++++++++++++++++++++++++++++ unix_integration/src/selinux_util.rs | 6 ++-- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e0f2e29b..72607d914 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -973,7 +973,7 @@ dependencies = [ [[package]] name = "daemon" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "clap", "clap_complete", @@ -2087,7 +2087,7 @@ dependencies = [ [[package]] name = "kanidm-ipa-sync" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "base64urlsafedata", "chrono", @@ -2111,7 +2111,7 @@ dependencies = [ [[package]] name = "kanidm-ldap-sync" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "base64urlsafedata", "chrono", @@ -2135,7 +2135,7 @@ dependencies = [ [[package]] name = "kanidm_build_profiles" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "base64 0.21.2", "git2", @@ -2145,7 +2145,7 @@ dependencies = [ [[package]] name = "kanidm_client" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "kanidm_proto", "reqwest", @@ -2188,7 +2188,7 @@ dependencies = [ [[package]] name = "kanidm_proto" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "base32", "base64urlsafedata", @@ -2206,7 +2206,7 @@ dependencies = [ [[package]] name = "kanidm_tools" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "async-recursion", "clap", @@ -2235,7 +2235,7 @@ dependencies = [ [[package]] name = "kanidm_unix_int" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "async-trait", "base64urlsafedata", @@ -2273,14 +2273,14 @@ dependencies = [ [[package]] name = "kanidm_utils_users" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "libc", ] [[package]] name = "kanidmd_core" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "async-trait", "axum", @@ -2323,7 +2323,7 @@ dependencies = [ [[package]] name = "kanidmd_lib" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "base64 0.21.2", "base64urlsafedata", @@ -2386,7 +2386,7 @@ dependencies = [ [[package]] name = "kanidmd_testkit" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "compact_jwt", "fantoccini", @@ -2411,7 +2411,7 @@ dependencies = [ [[package]] name = "kanidmd_web_ui" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "gloo", "js-sys", @@ -2825,7 +2825,7 @@ dependencies = [ [[package]] name = "nss_kanidm" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "kanidm_unix_int", "lazy_static", @@ -3057,7 +3057,7 @@ dependencies = [ [[package]] name = "orca" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "clap", "crossbeam", @@ -3092,7 +3092,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pam_kanidm" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "kanidm_unix_int", "libc", @@ -4035,7 +4035,7 @@ dependencies = [ [[package]] name = "sketching" -version = "1.1.0-rc.14" +version = "1.1.0-rc.14-dev" dependencies = [ "num_enum", "tracing", diff --git a/libs/users/src/lib.rs b/libs/users/src/lib.rs index 0b3962ef5..695474ea6 100644 --- a/libs/users/src/lib.rs +++ b/libs/users/src/lib.rs @@ -1,4 +1,8 @@ +use libc::passwd as c_passwd; use libc::{gid_t, uid_t}; +use std::ffi::{CStr, OsStr, OsString}; +use std::os::unix::ffi::OsStrExt; +use std::{mem, ptr}; pub fn get_current_uid() -> uid_t { unsafe { libc::getuid() } @@ -15,3 +19,41 @@ pub fn get_current_gid() -> gid_t { pub fn get_effective_gid() -> gid_t { unsafe { libc::getegid() } } + +pub fn get_user_name_by_uid(uid: uid_t) -> Option { + let mut passwd = unsafe { mem::zeroed::() }; + let mut buf = vec![0; 2048]; + let mut result = ptr::null_mut::(); + + #[cfg(feature = "logging")] + trace!("Running getpwuid_r for user #{}", uid); + + loop { + let r = + unsafe { libc::getpwuid_r(uid, &mut passwd, buf.as_mut_ptr(), buf.len(), &mut result) }; + + if r != libc::ERANGE { + break; + } + + let newsize = buf.len().checked_mul(2)?; + buf.resize(newsize, 0); + } + + if result.is_null() { + // There is no such user, or an error has occurred. + // errno gets set if there’s an error. + return None; + } + + if result != &mut passwd { + // The result of getpwuid_r should be its input passwd. + return None; + } + + let name = unsafe { + OsStr::from_bytes(CStr::from_ptr(result.read().pw_name).to_bytes()).to_os_string() + }; + + Some(name) +} diff --git a/unix_integration/src/selinux_util.rs b/unix_integration/src/selinux_util.rs index c56c3b71c..742069503 100644 --- a/unix_integration/src/selinux_util.rs +++ b/unix_integration/src/selinux_util.rs @@ -1,7 +1,7 @@ +use kanidm_utils_users::get_user_name_by_uid; use std::ffi::CString; use std::path::Path; use std::process::Command; -use users::get_user_by_uid; use selinux::{ current_mode, kernel_support, label::back_end::File, label::Labeler, KernelSupport, @@ -63,8 +63,8 @@ impl SelinuxLabeler { // so that relabels in the future do not break it. #[cfg(all(target_family = "unix", feature = "selinux"))] // Yes, gid, because we use the GID number for both the user's UID and primary GID - let sel_lookup_path_raw = match get_user_by_uid(gid) { - Some(v) => format!("{}{}", home_prefix, v.name().to_str().unwrap()), + let sel_lookup_path_raw = match get_user_name_by_uid(gid) { + Some(v) => format!("{}{}", home_prefix, v.to_str().unwrap()), None => { return Err("Failed looking up username by uid for SELinux relabeling".to_string()); }