From 35950380a9f02aa1a1201bcdff90de8c41cf4aa4 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 6 Apr 2019 17:53:12 +0200 Subject: [PATCH] src/server/worker_task.rs: carefully handle file permissions --- src/auth_helpers.rs | 8 ++++---- src/bin/proxmox-backup-api.rs | 3 +++ src/server/worker_task.rs | 37 +++++++++++++++++++++++++++++++---- src/tools.rs | 19 ++++++++++++------ 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/auth_helpers.rs b/src/auth_helpers.rs index d2e0a9fa..1ae86e04 100644 --- a/src/auth_helpers.rs +++ b/src/auth_helpers.rs @@ -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(()) } diff --git a/src/bin/proxmox-backup-api.rs b/src/bin/proxmox-backup-api.rs index 20e33c4f..ec942d5e 100644 --- a/src/bin/proxmox-backup-api.rs +++ b/src/bin/proxmox-backup-api.rs @@ -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() { diff --git a/src/server/worker_task.rs b/src/server/worker_task.rs index 983743c4..c86373d4 100644 --- a/src/server/worker_task.rs +++ b/src/server/worker_task.rs @@ -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, 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, 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))?; diff --git a/src/tools.rs b/src/tools.rs index fd48c535..bbf8f647 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -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>( path: P, perm: Option, owner: Option, group: Option, -) -> 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(()) -- 2.39.2