}
// TODO: move somewhere we can reuse it from (namespace has its own copy atm.)
-fn get_ns_privs(store: &str, ns: &BackupNamespace, auth_id: &Authid) -> Result<u64, Error> {
+fn get_ns_privs(store_with_ns: &DatastoreWithNamespace, auth_id: &Authid) -> Result<u64, Error> {
let user_info = CachedUserInfo::new()?;
- Ok(if ns.is_root() {
- user_info.lookup_privs(auth_id, &["datastore", store])
- } else {
- user_info.lookup_privs(auth_id, &["datastore", store, &ns.to_string()])
- })
+ Ok(user_info.lookup_privs(auth_id, &store_with_ns.acl_path()))
}
// asserts that either either `full_access_privs` or `partial_access_privs` are fulfilled,
full_access_privs: u64,
partial_access_privs: u64,
) -> Result<bool, Error> {
- let privs = get_ns_privs(store, ns, auth_id)?;
+ let store_with_ns = DatastoreWithNamespace {
+ store: store.to_string(),
+ ns: ns.clone(),
+ };
+ let privs = get_ns_privs(&store_with_ns, auth_id)?;
if full_access_privs != 0 && (privs & full_access_privs) != 0 {
return Ok(false);
PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_READ | PRIV_DATASTORE_BACKUP;
let name = store.name();
iter.any(|ns| -> bool {
- let user_privs = user_info.lookup_privs(&auth_id, &["datastore", name, &ns.to_string()]);
+ let store_with_ns = DatastoreWithNamespace {
+ store: name.to_string(),
+ ns: ns,
+ };
+ let user_privs = user_info.lookup_privs(&auth_id, &store_with_ns.acl_path());
user_privs & wanted != 0
})
}
use proxmox_schema::*;
use pbs_api_types::{
- Authid, BackupNamespace, NamespaceListItem, Operation, DATASTORE_SCHEMA, NS_MAX_DEPTH_SCHEMA,
- PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_MODIFY, PROXMOX_SAFE_ID_FORMAT,
+ Authid, BackupNamespace, DatastoreWithNamespace, NamespaceListItem, Operation,
+ DATASTORE_SCHEMA, NS_MAX_DEPTH_SCHEMA, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
+ PRIV_DATASTORE_MODIFY, PROXMOX_SAFE_ID_FORMAT,
};
use pbs_datastore::DataStore;
// TODO: move somewhere we can reuse it from (datastore has its own copy atm.)
-fn get_ns_privs(store: &str, ns: &BackupNamespace, auth_id: &Authid) -> Result<u64, Error> {
+fn get_ns_privs(store_with_ns: &DatastoreWithNamespace, auth_id: &Authid) -> Result<u64, Error> {
let user_info = CachedUserInfo::new()?;
- Ok(if ns.is_root() {
- user_info.lookup_privs(auth_id, &["datastore", store])
- } else {
- user_info.lookup_privs(auth_id, &["datastore", store, &ns.to_string()])
- })
+ Ok(user_info.lookup_privs(auth_id, &store_with_ns.acl_path()))
}
#[api(
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let parent = parent.unwrap_or_default();
- if get_ns_privs(&store, &parent, &auth_id)? & PRIV_DATASTORE_MODIFY == 0 {
+ let store_with_parent = DatastoreWithNamespace {
+ store: store.clone(),
+ ns: parent.clone(),
+ };
+
+ if get_ns_privs(&store_with_parent, &auth_id)? & PRIV_DATASTORE_MODIFY == 0 {
proxmox_router::http_bail!(FORBIDDEN, "permission check failed");
}
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
const PRIVS_OK: u64 = PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_BACKUP | PRIV_DATASTORE_AUDIT;
// first do a base check to avoid leaking if a NS exists or not
- if get_ns_privs(&store, &parent, &auth_id)? & PRIVS_OK == 0 {
+ let store_with_parent = DatastoreWithNamespace {
+ store: store.clone(),
+ ns: parent.clone(),
+ };
+
+ if get_ns_privs(&store_with_parent, &auth_id)? & PRIVS_OK == 0 {
proxmox_router::http_bail!(FORBIDDEN, "permission check failed");
}
let user_info = CachedUserInfo::new()?;
};
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
let parent = ns.parent(); // must have MODIFY permission on parent to allow deletion
- if get_ns_privs(&store, &parent, &auth_id)? & PRIV_DATASTORE_MODIFY == 0 {
+ let store_with_parent = DatastoreWithNamespace {
+ store: store.clone(),
+ ns: parent.clone(),
+ };
+ if get_ns_privs(&store_with_parent, &auth_id)? & PRIV_DATASTORE_MODIFY == 0 {
http_bail!(FORBIDDEN, "permission check failed");
}
use proxmox_sys::sortable;
use pbs_api_types::{
- Authid, BackupNamespace, BackupType, Operation, SnapshotVerifyState, VerifyState,
- BACKUP_ARCHIVE_NAME_SCHEMA, BACKUP_ID_SCHEMA, BACKUP_NAMESPACE_SCHEMA, BACKUP_TIME_SCHEMA,
- BACKUP_TYPE_SCHEMA, CHUNK_DIGEST_SCHEMA, DATASTORE_SCHEMA, PRIV_DATASTORE_BACKUP,
+ Authid, BackupNamespace, BackupType, DatastoreWithNamespace, Operation, SnapshotVerifyState,
+ VerifyState, BACKUP_ARCHIVE_NAME_SCHEMA, BACKUP_ID_SCHEMA, BACKUP_NAMESPACE_SCHEMA,
+ BACKUP_TIME_SCHEMA, BACKUP_TYPE_SCHEMA, CHUNK_DIGEST_SCHEMA, DATASTORE_SCHEMA,
+ PRIV_DATASTORE_BACKUP,
};
use pbs_config::CachedUserInfo;
use pbs_datastore::index::IndexFile;
let store = required_string_param(¶m, "store")?.to_owned();
let backup_ns = optional_ns_param(¶m)?;
+ let store_with_ns = DatastoreWithNamespace {
+ store: store.clone(),
+ ns: backup_ns.clone(),
+ };
let backup_dir_arg = pbs_api_types::BackupDir::deserialize(¶m)?;
let user_info = CachedUserInfo::new()?;
- 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()])
- };
+ let privs = user_info.lookup_privs(&auth_id, &store_with_ns.acl_path());
if privs & PRIV_DATASTORE_BACKUP == 0 {
proxmox_router::http_bail!(FORBIDDEN, "permission check failed");
}
use anyhow::Error;
use pbs_api_types::{
- Authid, BackupNamespace, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_MODIFY,
- PRIV_DATASTORE_READ,
+ Authid, BackupNamespace, DatastoreWithNamespace, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
+ PRIV_DATASTORE_MODIFY, PRIV_DATASTORE_READ,
};
use pbs_config::CachedUserInfo;
use pbs_datastore::{backup_info::BackupGroup, DataStore, ListGroups, ListNamespacesRecursive};
let mut override_owner = false;
if let Some(auth_id) = &self.auth_id {
let info = &self.user_info;
- let privs = if ns.is_root() {
- info.lookup_privs(&auth_id, &["datastore", self.store.name()])
- } else {
- info.lookup_privs(
- &auth_id,
- &["datastore", self.store.name(), &ns.to_string()],
- )
+ let store_with_ns = DatastoreWithNamespace {
+ store: self.store.name().to_string(),
+ ns: ns.clone(),
};
+ let privs = info.lookup_privs(&auth_id, &store_with_ns.acl_path());
+
if privs & NS_PRIVS_OK == 0 {
continue;
}