sync job: don't require privs on datastore
syncing to a namespace only requires privileges on the namespace (and potentially its children during execution). Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Thomas Lamprecht
					
				
			
			
				
	
			
			
			
						parent
						
							4a4dd66c26
						
					
				
				
					commit
					83e3000349
				
			@ -7,9 +7,9 @@ use serde::{Deserialize, Serialize};
 | 
				
			|||||||
use proxmox_schema::*;
 | 
					use proxmox_schema::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    Authid, BackupNamespace, BackupType, RateLimitConfig, Userid, BACKUP_GROUP_SCHEMA,
 | 
					    Authid, BackupNamespace, BackupType, DatastoreWithNamespace, RateLimitConfig, Userid,
 | 
				
			||||||
    BACKUP_NAMESPACE_SCHEMA, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
 | 
					    BACKUP_GROUP_SCHEMA, BACKUP_NAMESPACE_SCHEMA, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA,
 | 
				
			||||||
    NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT, REMOTE_ID_SCHEMA,
 | 
					    MEDIA_POOL_NAME_SCHEMA, NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT, REMOTE_ID_SCHEMA,
 | 
				
			||||||
    SINGLE_LINE_COMMENT_SCHEMA,
 | 
					    SINGLE_LINE_COMMENT_SCHEMA,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -498,6 +498,15 @@ pub struct SyncJobConfig {
 | 
				
			|||||||
    pub limit: RateLimitConfig,
 | 
					    pub limit: RateLimitConfig,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl SyncJobConfig {
 | 
				
			||||||
 | 
					    pub fn store_with_ns(&self) -> DatastoreWithNamespace {
 | 
				
			||||||
 | 
					        DatastoreWithNamespace {
 | 
				
			||||||
 | 
					            store: self.store.clone(),
 | 
				
			||||||
 | 
					            ns: self.ns.clone().unwrap_or_default(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[api(
 | 
					#[api(
 | 
				
			||||||
    properties: {
 | 
					    properties: {
 | 
				
			||||||
        config: {
 | 
					        config: {
 | 
				
			||||||
 | 
				
			|||||||
@ -20,18 +20,11 @@ pub fn check_sync_job_read_access(
 | 
				
			|||||||
    auth_id: &Authid,
 | 
					    auth_id: &Authid,
 | 
				
			||||||
    job: &SyncJobConfig,
 | 
					    job: &SyncJobConfig,
 | 
				
			||||||
) -> bool {
 | 
					) -> bool {
 | 
				
			||||||
    let datastore_privs = user_info.lookup_privs(auth_id, &["datastore", &job.store]);
 | 
					    let ns_anchor_privs = user_info.lookup_privs(auth_id, &job.store_with_ns().acl_path());
 | 
				
			||||||
    if datastore_privs & PRIV_DATASTORE_AUDIT == 0 {
 | 
					    if ns_anchor_privs & PRIV_DATASTORE_AUDIT == 0 {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(ref ns) = job.ns {
 | 
					 | 
				
			||||||
        let ns_privs = user_info.lookup_privs(auth_id, &["datastore", &job.store, &ns.to_string()]);
 | 
					 | 
				
			||||||
        if ns_privs & PRIV_DATASTORE_AUDIT == 0 {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let remote_privs = user_info.lookup_privs(auth_id, &["remote", &job.remote]);
 | 
					    let remote_privs = user_info.lookup_privs(auth_id, &["remote", &job.remote]);
 | 
				
			||||||
    remote_privs & PRIV_REMOTE_AUDIT != 0
 | 
					    remote_privs & PRIV_REMOTE_AUDIT != 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -45,20 +38,13 @@ pub fn check_sync_job_modify_access(
 | 
				
			|||||||
    auth_id: &Authid,
 | 
					    auth_id: &Authid,
 | 
				
			||||||
    job: &SyncJobConfig,
 | 
					    job: &SyncJobConfig,
 | 
				
			||||||
) -> bool {
 | 
					) -> bool {
 | 
				
			||||||
    let datastore_privs = user_info.lookup_privs(auth_id, &["datastore", &job.store]);
 | 
					    let ns_anchor_privs = user_info.lookup_privs(auth_id, &job.store_with_ns().acl_path());
 | 
				
			||||||
    if datastore_privs & PRIV_DATASTORE_BACKUP == 0 {
 | 
					    if ns_anchor_privs & PRIV_DATASTORE_BACKUP == 0 {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(ref ns) = job.ns {
 | 
					 | 
				
			||||||
        let ns_privs = user_info.lookup_privs(auth_id, &["datastore", &job.store, &ns.to_string()]);
 | 
					 | 
				
			||||||
        if ns_privs & PRIV_DATASTORE_BACKUP == 0 {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if let Some(true) = job.remove_vanished {
 | 
					    if let Some(true) = job.remove_vanished {
 | 
				
			||||||
        if datastore_privs & PRIV_DATASTORE_PRUNE == 0 {
 | 
					        if ns_anchor_privs & PRIV_DATASTORE_PRUNE == 0 {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -73,7 +59,7 @@ pub fn check_sync_job_modify_access(
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // same permission as changing ownership after syncing
 | 
					    // same permission as changing ownership after syncing
 | 
				
			||||||
    if !correct_owner && datastore_privs & PRIV_DATASTORE_MODIFY == 0 {
 | 
					    if !correct_owner && ns_anchor_privs & PRIV_DATASTORE_MODIFY == 0 {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user