From cabda57f0a57ae49ecd1da2f994d450b146cbd9b Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Thu, 5 May 2022 19:26:04 +0200 Subject: [PATCH] api: backup create: make permission check namespace aware Signed-off-by: Thomas Lamprecht --- src/api2/backup/mod.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/api2/backup/mod.rs b/src/api2/backup/mod.rs index 230e4cdb..8fb52321 100644 --- a/src/api2/backup/mod.rs +++ b/src/api2/backup/mod.rs @@ -54,7 +54,7 @@ pub const API_METHOD_UPGRADE_BACKUP: ApiMethod = ApiMethod::new( ) ).access( // Note: parameter 'store' is no uri parameter, so we need to test inside function body - Some("The user needs Datastore.Backup privilege on /datastore/{store} and needs to own the backup group."), + Some("Requires on /datastore/{store}[/{namespace}] DATASTORE_BACKUP and being the owner of the group"), &Permission::Anybody ); @@ -72,19 +72,22 @@ fn upgrade_to_backup_protocol( let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; let store = required_string_param(¶m, "store")?.to_owned(); + let backup_dir_arg = pbs_api_types::BackupDir::deserialize(¶m)?; + let backup_ns = &backup_dir_arg.group.ns; let user_info = CachedUserInfo::new()?; - user_info.check_privs( - &auth_id, - &["datastore", &store], - PRIV_DATASTORE_BACKUP, - false, - )?; + + let privs = if backup_ns.is_root() { + user_info.lookup_privs(&auth_id, &["datastore", &store]) + } else { + user_info.lookup_privs(&auth_id, &["datastore", &store, &backup_ns.to_string()]) + }; + if privs & PRIV_DATASTORE_BACKUP == 0 { + proxmox_router::http_bail!(FORBIDDEN, "permission check failed"); + } let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?; - let backup_dir_arg = pbs_api_types::BackupDir::deserialize(¶m)?; - let protocols = parts .headers .get("UPGRADE")