From 423e6561638d5cffd46dc59d9d76ccec5e41475f Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 16 Apr 2020 09:18:56 +0200 Subject: [PATCH] src/config/cached_user_info.rs: new helper class --- src/config.rs | 1 + src/config/acl.rs | 2 +- src/config/cached_user_info.rs | 69 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/config/cached_user_info.rs diff --git a/src/config.rs b/src/config.rs index 94ac8185..f7d904fa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,6 +19,7 @@ pub mod datastore; pub mod remote; pub mod user; pub mod acl; +pub mod cached_user_info; /// Check configuration directory permissions /// diff --git a/src/config/acl.rs b/src/config/acl.rs index cb7286df..54181c91 100644 --- a/src/config/acl.rs +++ b/src/config/acl.rs @@ -39,7 +39,7 @@ pub const ROLE_DATASTORE_AUDIT: u64 = PRIV_DATASTORE_AUDIT; pub const ROLE_NAME_NO_ACCESS: &str ="NoAccess"; lazy_static! { - static ref ROLE_NAMES: HashMap<&'static str, u64> = { + pub static ref ROLE_NAMES: HashMap<&'static str, u64> = { let mut map = HashMap::new(); map.insert("Admin", ROLE_ADMIN); diff --git a/src/config/cached_user_info.rs b/src/config/cached_user_info.rs new file mode 100644 index 00000000..65378b44 --- /dev/null +++ b/src/config/cached_user_info.rs @@ -0,0 +1,69 @@ +//! Cached user info for fast ACL permission checks + +use std::sync::Arc; + +use failure::*; + +use proxmox::api::section_config::SectionConfigData; +use proxmox::api::UserInformation; + +use super::acl::{AclTree, ROLE_NAMES}; +use super::user::User; + +/// Cache User/Group/Acl configuration data for fast permission tests +pub struct CachedUserInfo { + user_cfg: Arc, + acl_tree: Arc, +} + +impl CachedUserInfo { + + /// Creates a new instance. + pub fn new() -> Result { + Ok(CachedUserInfo { + user_cfg: super::user::cached_config()?, + acl_tree: super::acl::cached_config()?, + }) + } + + /// Test if a user account is enabled and not expired + pub fn is_active_user(&self, userid: &str) -> bool { + if let Ok(info) = self.user_cfg.lookup::("user", &userid) { + if !info.enable.unwrap_or(true) { + return false; + } + if let Some(expire) = info.expire { + if expire > 0 { + let now = unsafe { libc::time(std::ptr::null_mut()) }; + if expire <= now { + return false; + } + } + } + return true; + } else { + return false; + } + } +} + +impl UserInformation for CachedUserInfo { + fn is_superuser(&self, userid: &str) -> bool { + userid == "root@pam" + } + + fn is_group_member(&self, _userid: &str, _group: &str) -> bool { + false + } + + fn lookup_privs(&self, userid: &str, path: &[&str]) -> u64 { + let roles = self.acl_tree.roles(userid, path); + let mut privs: u64 = 0; + for role in roles { + if let Some(role_privs) = ROLE_NAMES.get(role.as_str()) { + privs |= role_privs; + } + } + privs + } +}