From 396fd747a677349c1e16c5b780c14d06f46858ad Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 3 Mar 2021 12:44:39 +0100 Subject: [PATCH] tape: impl access permissions for tape jobs --- src/api2/config/tape_backup_job.rs | 36 ++++++++++++++++++++++++++++-- src/api2/tape/backup.rs | 16 +++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/api2/config/tape_backup_job.rs b/src/api2/config/tape_backup_job.rs index 560766f2..fbd36a53 100644 --- a/src/api2/config/tape_backup_job.rs +++ b/src/api2/config/tape_backup_job.rs @@ -2,16 +2,22 @@ use anyhow::{bail, format_err, Error}; use serde_json::Value; use ::serde::{Deserialize, Serialize}; -use proxmox::api::{api, Router, RpcEnvironment, schema::Updatable}; +use proxmox::api::{api, Router, RpcEnvironment, Permission, schema::Updatable}; use proxmox::tools::fs::open_file_locked; use crate::{ api2::types::{ + Authid, JOB_ID_SCHEMA, PROXMOX_CONFIG_DIGEST_SCHEMA, }, config::{ self, + cached_user_info::CachedUserInfo, + acl::{ + PRIV_TAPE_AUDIT, + PRIV_TAPE_MODIFY, + }, tape_job::{ TAPE_JOB_CFG_LOCKFILE, TapeBackupJobConfig, @@ -29,16 +35,30 @@ use crate::{ type: Array, items: { type: TapeBackupJobConfig }, }, + access: { + description: "List configured tape jobs filtered by Tape.Audit privileges", + permission: &Permission::Anybody, + }, )] /// List all tape backup jobs pub fn list_tape_backup_jobs( _param: Value, mut 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::tape_job::config()?; - let list = config.convert_to_typed_array("backup")?; + let list = config.convert_to_typed_array::("backup")?; + + let list = list + .into_iter() + .filter(|job| { + let privs = user_info.lookup_privs(&auth_id, &["tape", "job", &job.id]); + privs & PRIV_TAPE_AUDIT != 0 + }) + .collect(); rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into(); @@ -55,6 +75,9 @@ pub fn list_tape_backup_jobs( }, }, }, + access: { + permission: &Permission::Privilege(&["tape", "job"], PRIV_TAPE_MODIFY, false), + }, )] /// Create a new tape backup job. pub fn create_tape_backup_job( @@ -88,6 +111,9 @@ pub fn create_tape_backup_job( }, }, returns: { type: TapeBackupJobConfig }, + access: { + permission: &Permission::Privilege(&["tape", "job", "{id}"], PRIV_TAPE_AUDIT, false), + }, )] /// Read a tape backup job configuration. pub fn read_tape_backup_job( @@ -143,6 +169,9 @@ pub enum DeletableProperty { }, }, }, + access: { + permission: &Permission::Privilege(&["tape", "job", "{id}"], PRIV_TAPE_MODIFY, false), + }, )] /// Update the tape backup job pub fn update_tape_backup_job( @@ -185,6 +214,9 @@ pub fn update_tape_backup_job( }, }, }, + access: { + permission: &Permission::Privilege(&["tape", "job", "{id}"], PRIV_TAPE_MODIFY, false), + }, )] /// Remove a tape backup job configuration pub fn delete_tape_backup_job( diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs index eeef5528..2f9f03d0 100644 --- a/src/api2/tape/backup.rs +++ b/src/api2/tape/backup.rs @@ -10,6 +10,7 @@ use proxmox::{ RpcEnvironment, RpcEnvironmentType, Router, + Permission, }, }; @@ -17,6 +18,10 @@ use crate::{ task_log, config::{ self, + cached_user_info::CachedUserInfo, + acl::{ + PRIV_TAPE_AUDIT, + }, tape_job::{ TapeBackupJobConfig, TapeBackupJobSetup, @@ -72,12 +77,18 @@ pub const ROUTER: Router = Router::new() type: Array, items: { type: TapeBackupJobStatus }, }, + access: { + description: "List configured tape jobs filtered by Tape.Audit privileges", + permission: &Permission::Anybody, + }, )] /// List all tape backup jobs pub fn list_tape_backup_jobs( _param: Value, mut 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::tape_job::config()?; @@ -92,6 +103,11 @@ pub fn list_tape_backup_jobs( let mut list = Vec::new(); for job in job_list_iter { + let privs = user_info.lookup_privs(&auth_id, &["tape", "job", &job.id]); + if (privs & PRIV_TAPE_AUDIT) == 0 { + continue; + } + let last_state = JobState::load("tape-backup-job", &job.id) .map_err(|err| format_err!("could not open statefile for {}: {}", &job.id, err))?;