]> git.proxmox.com Git - proxmox-backup.git/commitdiff
src/config/cached_user_info.rs: new helper class
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 16 Apr 2020 07:18:56 +0000 (09:18 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 16 Apr 2020 08:05:16 +0000 (10:05 +0200)
src/config.rs
src/config/acl.rs
src/config/cached_user_info.rs [new file with mode: 0644]

index 94ac81856950e5b70a2662b09e45f96d65e5d198..f7d904fa9e4dcaa174837a86fe4461c2e854bfce 100644 (file)
@@ -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
 ///
index cb7286dff88a99ac91b2afdc4647f7592e30681c..54181c911d72400eaba0ca35be58050f297c13f0 100644 (file)
@@ -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 (file)
index 0000000..65378b4
--- /dev/null
@@ -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<SectionConfigData>,
+    acl_tree: Arc<AclTree>,
+}
+
+impl CachedUserInfo {
+
+    /// Creates a new instance.
+    pub fn new() -> Result<Self, Error> {
+        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>("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
+    }
+}