api: datastore: further unify check helpers
this is the most common sequence of checks we have in this file, so let's have a single place where we implement it. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
c939698414
commit
7a404dc53d
|
@ -109,17 +109,24 @@ fn check_ns_privs(
|
||||||
proxmox_router::http_bail!(FORBIDDEN, "permission check failed");
|
proxmox_router::http_bail!(FORBIDDEN, "permission check failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_owner_load_store(
|
// helper to unify common sequence of checks:
|
||||||
|
// 1. check privs on NS (full or limited access)
|
||||||
|
// 2. load datastore
|
||||||
|
// 3. if needed (only limited access), check owner of group
|
||||||
|
fn check_privs_and_load_store(
|
||||||
store: &str,
|
store: &str,
|
||||||
ns: &BackupNamespace,
|
ns: &BackupNamespace,
|
||||||
auth_id: &Authid,
|
auth_id: &Authid,
|
||||||
|
full_access_privs: u64,
|
||||||
|
partial_access_privs: u64,
|
||||||
operation: Option<Operation>,
|
operation: Option<Operation>,
|
||||||
owner_check_required: bool,
|
|
||||||
backup_group: &pbs_api_types::BackupGroup,
|
backup_group: &pbs_api_types::BackupGroup,
|
||||||
) -> Result<Arc<DataStore>, Error> {
|
) -> Result<Arc<DataStore>, Error> {
|
||||||
|
let limited = check_ns_privs(store, ns, auth_id, full_access_privs, partial_access_privs)?;
|
||||||
|
|
||||||
let datastore = DataStore::lookup_datastore(&store, operation)?;
|
let datastore = DataStore::lookup_datastore(&store, operation)?;
|
||||||
|
|
||||||
if owner_check_required {
|
if limited {
|
||||||
let owner = datastore.get_owner(&ns, backup_group)?;
|
let owner = datastore.get_owner(&ns, backup_group)?;
|
||||||
check_backup_owner(&owner, &auth_id)?;
|
check_backup_owner(&owner, &auth_id)?;
|
||||||
}
|
}
|
||||||
|
@ -302,20 +309,13 @@ pub fn delete_group(
|
||||||
|
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
|
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_PRUNE,
|
PRIV_DATASTORE_PRUNE,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&group,
|
&group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -359,20 +359,13 @@ pub fn list_snapshot_files(
|
||||||
|
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
|
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_READ,
|
PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_READ,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -416,21 +409,13 @@ pub fn delete_snapshot(
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
|
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
|
let datastore = check_privs_and_load_store(
|
||||||
let owner_check_required = check_ns_privs(
|
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_PRUNE,
|
PRIV_DATASTORE_PRUNE,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -936,23 +921,14 @@ pub fn prune(
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
rpcenv: &mut dyn RpcEnvironment,
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
|
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
|
let datastore = check_privs_and_load_store(
|
||||||
let owner_check_required = check_ns_privs(
|
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_PRUNE,
|
PRIV_DATASTORE_PRUNE,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&group,
|
&group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1287,20 +1263,13 @@ pub fn download_file(
|
||||||
let store = required_string_param(¶m, "store")?;
|
let store = required_string_param(¶m, "store")?;
|
||||||
let backup_ns = optional_ns_param(¶m)?;
|
let backup_ns = optional_ns_param(¶m)?;
|
||||||
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_READ,
|
PRIV_DATASTORE_READ,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1375,19 +1344,13 @@ pub fn download_file_decoded(
|
||||||
let store = required_string_param(¶m, "store")?;
|
let store = required_string_param(¶m, "store")?;
|
||||||
let backup_ns = optional_ns_param(¶m)?;
|
let backup_ns = optional_ns_param(¶m)?;
|
||||||
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_READ,
|
PRIV_DATASTORE_READ,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1508,30 +1471,20 @@ pub fn upload_backup_log(
|
||||||
let store = required_string_param(¶m, "store")?;
|
let store = required_string_param(¶m, "store")?;
|
||||||
let backup_ns = optional_ns_param(¶m)?;
|
let backup_ns = optional_ns_param(¶m)?;
|
||||||
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
||||||
check_ns_privs(&store, &backup_ns, &auth_id, PRIV_DATASTORE_BACKUP, 0).map_err(|_| {
|
|
||||||
http_err!(
|
|
||||||
UNAUTHORIZED,
|
|
||||||
"{} does not have permission to upload log for backup snapshot '{}'",
|
|
||||||
auth_id,
|
|
||||||
backup_dir,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
let datastore = check_privs_and_load_store(
|
||||||
store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
|
0,
|
||||||
|
PRIV_DATASTORE_BACKUP,
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
true,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
let backup_dir = datastore.backup_dir(backup_ns, backup_dir)?;
|
let backup_dir = datastore.backup_dir(backup_ns, backup_dir)?;
|
||||||
|
|
||||||
let file_name = CLIENT_LOG_BLOB_NAME;
|
let file_name = CLIENT_LOG_BLOB_NAME;
|
||||||
|
|
||||||
let owner = backup_dir.get_owner()?;
|
|
||||||
check_backup_owner(&owner, &auth_id)?;
|
|
||||||
|
|
||||||
let mut path = backup_dir.full_path();
|
let mut path = backup_dir.full_path();
|
||||||
path.push(&file_name);
|
path.push(&file_name);
|
||||||
|
|
||||||
|
@ -1594,20 +1547,13 @@ pub fn catalog(
|
||||||
) -> Result<Vec<ArchiveEntry>, Error> {
|
) -> Result<Vec<ArchiveEntry>, Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_READ,
|
PRIV_DATASTORE_READ,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1681,19 +1627,13 @@ pub fn pxar_file_download(
|
||||||
let store = required_string_param(¶m, "store")?;
|
let store = required_string_param(¶m, "store")?;
|
||||||
let backup_ns = optional_ns_param(¶m)?;
|
let backup_ns = optional_ns_param(¶m)?;
|
||||||
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
let backup_dir: pbs_api_types::BackupDir = Deserialize::deserialize(¶m)?;
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_READ,
|
PRIV_DATASTORE_READ,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1893,19 +1833,13 @@ pub fn get_group_notes(
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_AUDIT,
|
PRIV_DATASTORE_AUDIT,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_group,
|
&backup_group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1946,19 +1880,13 @@ pub fn set_group_notes(
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&backup_group,
|
&backup_group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1997,19 +1925,13 @@ pub fn get_notes(
|
||||||
) -> Result<String, Error> {
|
) -> Result<String, Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_AUDIT,
|
PRIV_DATASTORE_AUDIT,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2055,19 +1977,13 @@ pub fn set_notes(
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2111,19 +2027,13 @@ pub fn get_protection(
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_AUDIT,
|
PRIV_DATASTORE_AUDIT,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Read),
|
Some(Operation::Read),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2165,19 +2075,13 @@ pub fn set_protection(
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
|
||||||
let backup_ns = backup_ns.unwrap_or_default();
|
let backup_ns = backup_ns.unwrap_or_default();
|
||||||
let owner_check_required = check_ns_privs(
|
let datastore = check_privs_and_load_store(
|
||||||
&store,
|
&store,
|
||||||
&backup_ns,
|
&backup_ns,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
PRIV_DATASTORE_MODIFY,
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
)?;
|
|
||||||
let datastore = check_owner_load_store(
|
|
||||||
&store,
|
|
||||||
&backup_ns,
|
|
||||||
&auth_id,
|
|
||||||
Some(Operation::Write),
|
Some(Operation::Write),
|
||||||
owner_check_required,
|
|
||||||
&backup_dir.group,
|
&backup_dir.group,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue