From 8a76e711299143b01412ca763d3dc63720da85e0 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 3 Mar 2021 13:16:15 +0100 Subject: [PATCH] tape: impl access permission for media content list --- src/api2/tape/media.rs | 79 +++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/src/api2/tape/media.rs b/src/api2/tape/media.rs index a4ed5b39..82ab306a 100644 --- a/src/api2/tape/media.rs +++ b/src/api2/tape/media.rs @@ -4,7 +4,7 @@ use anyhow::{bail, format_err, Error}; use serde::{Serialize, Deserialize}; use proxmox::{ - api::{api, Router, SubdirMap}, + api::{api, Router, SubdirMap, RpcEnvironment, Permission}, list_subdirs_api_method, tools::Uuid, }; @@ -12,8 +12,13 @@ use proxmox::{ use crate::{ config::{ self, + cached_user_info::CachedUserInfo, + acl::{ + PRIV_TAPE_AUDIT, + }, }, api2::types::{ + Authid, BACKUP_ID_SCHEMA, BACKUP_TYPE_SCHEMA, MEDIA_POOL_NAME_SCHEMA, @@ -65,13 +70,20 @@ use crate::{ type: MediaListEntry, }, }, + access: { + description: "List of registered backup media filtered by Tape.Audit privileges on pool", + permission: &Permission::Anybody, + }, )] /// List pool media pub async fn list_media( pool: Option, update_status: bool, update_status_changer: Option, + rpcenv: &mut dyn RpcEnvironment, ) -> Result, Error> { + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; + let user_info = CachedUserInfo::new()?; let (config, _digest) = config::media_pool::config()?; @@ -102,6 +114,11 @@ pub async fn list_media( } } + let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", pool_name]); + if (privs & PRIV_TAPE_AUDIT) == 0 { + continue; + } + let config: MediaPoolConfig = config.lookup("pool", pool_name)?; let changer_name = None; // does not matter here @@ -150,30 +167,33 @@ pub async fn list_media( let inventory = Inventory::load(status_path)?; - if pool.is_none() { + let privs = user_info.lookup_privs(&auth_id, &["tape", "pool"]); + if (privs & PRIV_TAPE_AUDIT) != 0 { + if pool.is_none() { - for media_id in inventory.list_unassigned_media() { + for media_id in inventory.list_unassigned_media() { - let (mut status, location) = inventory.status_and_location(&media_id.label.uuid); + let (mut status, location) = inventory.status_and_location(&media_id.label.uuid); - if status == MediaStatus::Unknown { - status = MediaStatus::Writable; + if status == MediaStatus::Unknown { + status = MediaStatus::Writable; + } + + list.push(MediaListEntry { + uuid: media_id.label.uuid.clone(), + ctime: media_id.label.ctime, + label_text: media_id.label.label_text.to_string(), + location, + status, + catalog: true, // empty, so we do not need a catalog + expired: false, + media_set_uuid: None, + media_set_name: None, + media_set_ctime: None, + seq_nr: None, + pool: None, + }); } - - list.push(MediaListEntry { - uuid: media_id.label.uuid.clone(), - ctime: media_id.label.ctime, - label_text: media_id.label.label_text.to_string(), - location, - status, - catalog: true, // empty, so we do not need a catalog - expired: false, - media_set_uuid: None, - media_set_name: None, - media_set_ctime: None, - seq_nr: None, - pool: None, - }); } } @@ -190,6 +210,11 @@ pub async fn list_media( continue; } + let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &media_set_label.pool]); + if (privs & PRIV_TAPE_AUDIT) == 0 { + continue; + } + let (_status, location) = inventory.status_and_location(uuid); let media_set_name = inventory.generate_media_set_name(&media_set_label.uuid, None)?; @@ -349,11 +374,18 @@ pub struct MediaContentListFilter { type: MediaContentEntry, }, }, + access: { + description: "List content filtered by Tape.Audit privilege on pool", + permission: &Permission::Anybody, + }, )] /// List media content pub fn list_content( filter: MediaContentListFilter, + rpcenv: &mut dyn RpcEnvironment, ) -> Result, Error> { + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; + let user_info = CachedUserInfo::new()?; let (config, _digest) = config::media_pool::config()?; @@ -373,6 +405,11 @@ pub fn list_content( if &set.pool != pool { continue; } } + let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &set.pool]); + if (privs & PRIV_TAPE_AUDIT) == 0 { + continue; + } + if let Some(ref media_uuid) = filter.media { if &media_id.label.uuid != media_uuid { continue; } }