]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/api2/backup.rs
typo fixes all over the place
[proxmox-backup.git] / src / api2 / backup.rs
index a57547a963f106e47524121f340a5d78a928232c..fc5fd691b1ed16e84da94206f5608abc66db24af 100644 (file)
@@ -1,4 +1,4 @@
-use failure::*;
+use anyhow::{bail, format_err, Error};
 use futures::*;
 use hyper::header::{HeaderValue, UPGRADE};
 use hyper::http::request::Parts;
@@ -6,7 +6,7 @@ use hyper::{Body, Response, StatusCode};
 use serde_json::{json, Value};
 
 use proxmox::{sortable, identity, list_subdirs_api_method};
-use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment};
+use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment, Permission};
 use proxmox::api::router::SubdirMap;
 use proxmox::api::schema::*;
 
@@ -14,6 +14,8 @@ use crate::tools::{self, WrappedReaderStream};
 use crate::server::{WorkerTask, H2Service};
 use crate::backup::*;
 use crate::api2::types::*;
+use crate::config::acl::PRIV_DATASTORE_BACKUP;
+use crate::config::cached_user_info::CachedUserInfo;
 
 mod environment;
 use environment::*;
@@ -37,6 +39,10 @@ pub const API_METHOD_UPGRADE_BACKUP: ApiMethod = ApiMethod::new(
             ("debug", true, &BooleanSchema::new("Enable verbose debug logging.").schema()),
         ]),
     )
+).access(
+    // Note: parameter 'store' is no uri parameter, so we need to test inside function body
+    Some("The user needs Datastore.Backup privilege on /datastore/{store} and needs to own the backup group."),
+    &Permission::Anybody
 );
 
 fn upgrade_to_backup_protocol(
@@ -47,10 +53,16 @@ fn upgrade_to_backup_protocol(
     rpcenv: Box<dyn RpcEnvironment>,
 ) -> ApiResponseFuture {
 
-    async move {
+async move {
     let debug = param["debug"].as_bool().unwrap_or(false);
 
+    let username = rpcenv.get_user().unwrap();
+
     let store = tools::required_string_param(&param, "store")?.to_owned();
+
+    let user_info = CachedUserInfo::new()?;
+    user_info.check_privs(&username, &["datastore", &store], PRIV_DATASTORE_BACKUP, false)?;
+
     let datastore = DataStore::lookup_datastore(&store)?;
 
     let backup_type = tools::required_string_param(&param, "backup-type")?;
@@ -73,10 +85,15 @@ fn upgrade_to_backup_protocol(
 
     let worker_id = format!("{}_{}_{}", store, backup_type, backup_id);
 
-    let username = rpcenv.get_user().unwrap();
     let env_type = rpcenv.env_type();
 
     let backup_group = BackupGroup::new(backup_type, backup_id);
+    let owner = datastore.create_backup_group(&backup_group, &username)?;
+    // permission check
+    if owner != username { // only the owner is allowed to create additional snapshots
+        bail!("backup owner check failed ({} != {})", username, owner);
+    }
+
     let last_backup = BackupInfo::last_backup(&datastore.base_path(), &backup_group).unwrap_or(None);
     let backup_dir = BackupDir::new_with_group(backup_group, backup_time);
 
@@ -90,7 +107,7 @@ fn upgrade_to_backup_protocol(
     }
 
     let (path, is_new) = datastore.create_backup_dir(&backup_dir)?;
-    if !is_new { bail!("backup directorty already exists."); }
+    if !is_new { bail!("backup directory already exists."); }
 
     WorkerTask::spawn("backup", Some(worker_id), &username.clone(), true, move |worker| {
         let mut env = BackupEnvironment::new(
@@ -134,7 +151,7 @@ fn upgrade_to_backup_protocol(
 
             match (res, env.ensure_finished()) {
                 (Ok(_), Ok(())) => {
-                    env.log("backup finished sucessfully");
+                    env.log("backup finished successfully");
                     Ok(())
                 },
                 (Err(err), Ok(())) => {
@@ -361,7 +378,7 @@ fn dynamic_append (
 
         env.dynamic_writer_append_chunk(wid, offset, size, &digest)?;
 
-        env.debug(format!("sucessfully added chunk {} to dynamic index {} (offset {}, size {})", digest_str, wid, offset, size));
+        env.debug(format!("successfully added chunk {} to dynamic index {} (offset {}, size {})", digest_str, wid, offset, size));
     }
 
     Ok(Value::Null)
@@ -426,7 +443,7 @@ fn fixed_append (
 
         env.fixed_writer_append_chunk(wid, offset, size, &digest)?;
 
-        env.debug(format!("sucessfully added chunk {} to fixed index {} (offset {}, size {})", digest_str, wid, offset, size));
+        env.debug(format!("successfully added chunk {} to fixed index {} (offset {}, size {})", digest_str, wid, offset, size));
     }
 
     Ok(Value::Null)
@@ -481,7 +498,7 @@ fn close_dynamic_index (
 
     env.dynamic_writer_close(wid, chunk_count, size, csum)?;
 
-    env.log(format!("sucessfully closed dynamic index {}", wid));
+    env.log(format!("successfully closed dynamic index {}", wid));
 
     Ok(Value::Null)
 }
@@ -535,7 +552,7 @@ fn close_fixed_index (
 
     env.fixed_writer_close(wid, chunk_count, size, csum)?;
 
-    env.log(format!("sucessfully closed fixed index {}", wid));
+    env.log(format!("successfully closed fixed index {}", wid));
 
     Ok(Value::Null)
 }
@@ -549,7 +566,7 @@ fn finish_backup (
     let env: &BackupEnvironment = rpcenv.as_ref();
 
     env.finish_backup()?;
-    env.log("sucessfully finished backup");
+    env.log("successfully finished backup");
 
     Ok(Value::Null)
 }