]> git.proxmox.com Git - proxmox-backup.git/commitdiff
src/server/worker_task.rs: carefully handle file permissions
authorDietmar Maurer <dietmar@proxmox.com>
Sat, 6 Apr 2019 15:53:12 +0000 (17:53 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Sat, 6 Apr 2019 15:53:12 +0000 (17:53 +0200)
src/auth_helpers.rs
src/bin/proxmox-backup-api.rs
src/server/worker_task.rs
src/tools.rs

index d2e0a9fa4eab0f5ae7d3fd5cd59b99332a728bad..1ae86e043f2014d15f9eb56be250835b5dd66759 100644 (file)
@@ -94,12 +94,12 @@ pub fn generate_csrf_key() -> Result<(), Error> {
 
     use nix::sys::stat::Mode;
 
-    tools::file_set_contents(
-        &path, &pem, Some(Mode::from_bits_truncate(0o0640)))?;
-
     let (_, backup_gid) = tools::getpwnam_ugid("backup")?;
+    let uid = Some(nix::unistd::ROOT);
+    let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
 
-    nix::unistd::chown(&path, Some(nix::unistd::ROOT), Some(nix::unistd::Gid::from_raw(backup_gid)))?;
+    tools::file_set_contents_full(
+        &path, &pem, Some(Mode::from_bits_truncate(0o0640)), uid, gid)?;
 
     Ok(())
 }
index 20e33c4fcb6a18dafd1afec568b66f9c2bd3c701..ec942d5e95ef72215d3ed1dbd2f0a323f6dab379 100644 (file)
@@ -4,6 +4,7 @@ extern crate proxmox_backup;
 use proxmox_backup::api_schema::router::*;
 use proxmox_backup::api_schema::config::*;
 use proxmox_backup::server::rest::*;
+use proxmox_backup::server;
 use proxmox_backup::tools::daemon;
 use proxmox_backup::auth_helpers::*;
 use proxmox_backup::config;
@@ -31,6 +32,8 @@ fn run() -> Result<(), Error> {
         bail!("unable to inititialize syslog - {}", err);
     }
 
+    server::create_task_log_dir()?;
+
     config::create_configdir()?;
 
     if let Err(err) = generate_auth_key() {
index 983743c48821cb2d60efbbdbcca35f68f4d9e60f..c86373d4f33e1487b277fac2b4271c8d352f13f9 100644 (file)
@@ -13,7 +13,8 @@ use std::fs::File;
 
 use crate::tools::{self, FileLogger};
 
-macro_rules! PROXMOX_BACKUP_TASK_DIR { () => ("/var/log/proxmox-backup/tasks") }
+macro_rules! PROXMOX_BACKUP_LOG_DIR { () => ("/var/log/proxmox-backup") }
+macro_rules! PROXMOX_BACKUP_TASK_DIR { () => (concat!( PROXMOX_BACKUP_LOG_DIR!(), "/tasks")) }
 macro_rules! PROXMOX_BACKUP_TASK_LOCK_FN { () => (concat!(PROXMOX_BACKUP_TASK_DIR!(), "/.active.lock")) }
 macro_rules! PROXMOX_BACKUP_ACTIVE_TASK_FN { () => (concat!(PROXMOX_BACKUP_TASK_DIR!(), "/active")) }
 
@@ -116,6 +117,23 @@ fn parse_worker_status_line(line: &str) -> Result<(String, UPID, Option<(i64, St
     }
 }
 
+/// Create task log directory with correct permissions
+pub fn create_task_log_dir() -> Result<(), Error> {
+
+    try_block!({
+        let (backup_uid, backup_gid) = tools::getpwnam_ugid("backup")?;
+        let uid = Some(nix::unistd::Uid::from_raw(backup_uid));
+        let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
+
+        tools::create_dir_chown(PROXMOX_BACKUP_LOG_DIR!(), None, uid, gid)?;
+        tools::create_dir_chown(PROXMOX_BACKUP_TASK_DIR!(), None, uid, gid)?;
+
+        Ok(())
+    }).map_err(|err: Error| format_err!("unable to create task log dir - {}", err))?;
+
+    Ok(())
+}
+
 /// Returns the absolute path to the task log file
 pub fn upid_log_path(upid: &UPID) -> std::path::PathBuf {
     let mut path = std::path::PathBuf::from(PROXMOX_BACKUP_TASK_DIR!());
@@ -175,7 +193,12 @@ fn update_active_workers(new_upid: Option<&UPID>) -> Result<Vec<TaskListInfo>, E
     let my_pid  = unsafe { libc::getpid() };
     let my_pid_stat = tools::procfs::read_proc_pid_stat(my_pid)?;
 
+    let (backup_uid, backup_gid) = tools::getpwnam_ugid("backup")?;
+    let uid = Some(nix::unistd::Uid::from_raw(backup_uid));
+    let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
+
     let lock = tools::open_file_locked(PROXMOX_BACKUP_TASK_LOCK_FN!(), std::time::Duration::new(10, 0))?;
+    nix::unistd::chown(PROXMOX_BACKUP_TASK_LOCK_FN!(), uid, gid)?;
 
     let reader = match File::open(PROXMOX_BACKUP_ACTIVE_TASK_FN!()) {
         Ok(f) => Some(BufReader::new(f)),
@@ -280,7 +303,7 @@ fn update_active_workers(new_upid: Option<&UPID>) -> Result<Vec<TaskListInfo>, E
         }
     }
 
-    tools::file_set_contents(PROXMOX_BACKUP_ACTIVE_TASK_FN!(), raw.as_bytes(), None)?;
+    tools::file_set_contents_full(PROXMOX_BACKUP_ACTIVE_TASK_FN!(), raw.as_bytes(), None, uid, gid)?;
 
     drop(lock);
 
@@ -348,15 +371,21 @@ impl WorkerTask {
         };
 
         let mut path = std::path::PathBuf::from(PROXMOX_BACKUP_TASK_DIR!());
+
         path.push(format!("{:02X}", upid.pstart % 256));
 
-        let _ = std::fs::create_dir_all(&path); // ignore errors here
+        let (backup_uid, backup_gid) = tools::getpwnam_ugid("backup")?;
+        let uid = Some(nix::unistd::Uid::from_raw(backup_uid));
+        let gid = Some(nix::unistd::Gid::from_raw(backup_gid));
+
+        tools::create_dir_chown(&path, None, uid, gid)?;
 
         path.push(upid.to_string());
 
         println!("FILE: {:?}", path);
 
-        let logger = FileLogger::new(path, to_stdout)?;
+        let logger = FileLogger::new(&path, to_stdout)?;
+        nix::unistd::chown(&path, uid, gid)?;
 
         update_active_workers(Some(&upid))?;
 
index fd48c535dc95de4ce9c5593f641b89455b0b5289..bbf8f6473d591566091b9176dfc4ae3acd49ee6f 100644 (file)
@@ -351,21 +351,28 @@ pub fn getpwnam_ugid(username: &str) -> Result<(libc::uid_t,libc::gid_t), Error>
     Ok((info.pw_uid, info.pw_gid))
 }
 
-/// Creates a new, empty directory at the provided path witzh specified ownership
+/// Creates directory at the provided path with specified ownership
+///
+/// Simply returns if the directory already exists.
 pub fn create_dir_chown<P: AsRef<Path>>(
     path: P,
     perm: Option<stat::Mode>,
     owner: Option<unistd::Uid>,
     group: Option<unistd::Gid>,
-) -> Result<(), Error>
+) -> Result<(), nix::Error>
 {
-    let mode : stat::Mode = perm.unwrap_or(stat::Mode::from(
-        stat::Mode::S_IRWXO | stat::Mode::S_IRWXG
-    ));
+    let mode : stat::Mode = perm.unwrap_or(stat::Mode::from_bits_truncate(0o770));
 
     let path = path.as_ref();
 
-    unistd::mkdir(path, mode)?;
+    match nix::unistd::mkdir(path, mode) {
+        Ok(()) => {},
+        Err(nix::Error::Sys(nix::errno::Errno::EEXIST)) => {
+            return Ok(());
+        },
+        err => return err,
+    }
+
     unistd::chown(path, owner, group)?;
 
     Ok(())