diff --git a/Cargo.lock b/Cargo.lock index dc2e1c6..616744f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1406,6 +1406,7 @@ dependencies = [ "whitespace-conf", "xdg", "zbus", + "zbus_systemd", ] [[package]] @@ -8787,6 +8788,16 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zbus_systemd" +version = "0.26000.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c8310483ff4a77492d04a90bef30f40938059b4a4b4f7e456dda335d816cb6" +dependencies = [ + "serde", + "zbus", +] + [[package]] name = "zbus_xml" version = "5.2.1" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index a229b05..44daa5f 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -28,6 +28,7 @@ whitespace-conf = "1" #TODO: reduce features tokio = { workspace = true, features = ["full"] } xdg = "3.0" +zbus_systemd = { version = "0.26000.0", features = ["home1"] } [features] default = ["systemd"] diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 842aebe..45f184c 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -1,11 +1,13 @@ use cosmic_comp_config::output::randr; use cosmic_config::CosmicConfigEntry; use kdl::KdlDocument; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::fs; use std::io::Read; use std::os::unix::fs::OpenOptionsExt; use std::path::{Path, PathBuf}; +use zbus::Connection; +use zbus_systemd::home1::ManagerProxy; pub use cosmic_applets_config::time::TimeAppletConfig; pub use cosmic_bg_config::state::State as BgState; @@ -16,13 +18,25 @@ pub use cosmic_theme::{Theme, ThemeBuilder}; pub struct UserFilter { uid_min: u32, uid_max: u32, + homed_uids: BTreeSet, } -impl Default for UserFilter { - fn default() -> Self { +impl UserFilter { + pub async fn new() -> Result { let login_defs_data = fs::read_to_string("/etc/login.defs").unwrap_or_default(); let login_defs = whitespace_conf::parse(&login_defs_data); - Self { + + let connection = Connection::system().await?; + let homed = ManagerProxy::new(&connection).await?; + + let homed_uids = homed + .list_homes() + .await? + .iter() + .map(|(_, uid, ..)| *uid) + .collect(); + + Ok(Self { uid_min: login_defs .get("UID_MIN") .and_then(|x| x.parse::().ok()) @@ -31,17 +45,14 @@ impl Default for UserFilter { .get("UID_MAX") .and_then(|x| x.parse::().ok()) .unwrap_or(65000), - } - } -} - -impl UserFilter { - pub fn new() -> Self { - Self::default() + homed_uids, + }) } pub fn filter(&self, user: &pwd::Passwd) -> bool { - if user.uid < self.uid_min || user.uid > self.uid_max { + if (user.uid < self.uid_min || user.uid > self.uid_max) + && !self.homed_uids.contains(&user.uid) + { // Skip system accounts return false; } diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 427070a..a9d35b9 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -70,8 +70,8 @@ struct GreeterProxy; #[zbus::interface(name = "com.system76.CosmicGreeter")] impl GreeterProxy { - fn get_user_data(&mut self) -> Result { - let user_filter = UserFilter::new(); + async fn get_user_data(&mut self) -> Result { + let user_filter = UserFilter::new().await?; // The pwd::Passwd method is unsafe (but not labelled as such) due to using global state (libc pwent functions). // To prevent issues, this should only be called once in the entire process space at a time