From 8c9c6c075566f45fc7dde5431ff48c4a1736fe69 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Sat, 4 Jun 2022 14:57:30 +0200 Subject: [PATCH] api: list datastore: avoid iterating over NS for priv check, use AclTree Make the assumption that if a user has any privilege that would make an NS and (parts) of its content visible they also should be able to know about the datastore and very basic errors on lookup (path existence and maintenance mode) even if that NS doesn't even exists (yet), as they could, e.g., make or view a backup and find out anyway. This avoids iterating over parts of the whole datastore folder tree on disk, doing a priv check on each, swapping IO to virtual in memory checks on info we got available already anyway, is always a good idea after all Signed-off-by: Thomas Lamprecht --- src/api2/admin/datastore.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index ca2dc8dba..ca958988f 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -64,7 +64,7 @@ use crate::api2::backup::optional_ns_param; use crate::api2::node::rrd::create_value_from_rrd; use crate::backup::{ can_access_any_namespace, check_ns_privs_full, verify_all_backups, verify_backup_dir, - verify_backup_group, verify_filter, ListAccessibleBackupGroups, + verify_backup_group, verify_filter, ListAccessibleBackupGroups, NS_PRIVS_OK, }; use crate::server::jobstate::Job; @@ -1188,16 +1188,15 @@ pub fn get_datastore_list( let mut list = Vec::new(); for (store, (_, data)) in &config.sections { - let user_privs = user_info.lookup_privs(&auth_id, &["datastore", store]); + let acl_path = &["datastore", store]; + let user_privs = user_info.lookup_privs(&auth_id, acl_path); let allowed = (user_privs & (PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_BACKUP)) != 0; let mut allow_id = false; if !allowed { - if let Ok(datastore) = DataStore::lookup_datastore(store, Some(Operation::Read)) { - allow_id = can_access_any_namespace(datastore, &auth_id, &user_info); + if let Ok(any_privs) = user_info.any_privs_below(&auth_id, acl_path, NS_PRIVS_OK) { + allow_id = any_privs; } - // FIXME: check for any ACL on the datastore below in the error case, otherwise offline - // datastore will disappear for users that can only access a specific namespace } if allowed || allow_id {