src/server/worker_task.rs: carefully handle file permissions

This commit is contained in:
Dietmar Maurer 2019-04-06 17:53:12 +02:00
parent 1619a72063
commit 35950380a9
4 changed files with 53 additions and 14 deletions

View 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(())
}

View 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() {

View 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))?;

View 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(())