diff --git a/src/auth_helpers.rs b/src/auth_helpers.rs index 6e2d04f8..5382da27 100644 --- a/src/auth_helpers.rs +++ b/src/auth_helpers.rs @@ -97,7 +97,7 @@ pub fn generate_csrf_key() -> Result<(), Error> { use nix::sys::stat::Mode; - let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?; + let backup_user = crate::backup::backup_user()?; replace_file( &path, @@ -105,7 +105,7 @@ pub fn generate_csrf_key() -> Result<(), Error> { CreateOptions::new() .perm(Mode::from_bits_truncate(0o0640)) .owner(nix::unistd::ROOT) - .group(nix::unistd::Gid::from_raw(backup_gid)), + .group(backup_user.gid), )?; Ok(()) @@ -131,7 +131,7 @@ pub fn generate_auth_key() -> Result<(), Error> { let public_pem = rsa.public_key_to_pem()?; - let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?; + let backup_user = crate::backup::backup_user()?; replace_file( &public_path, @@ -139,7 +139,7 @@ pub fn generate_auth_key() -> Result<(), Error> { CreateOptions::new() .perm(Mode::from_bits_truncate(0o0640)) .owner(nix::unistd::ROOT) - .group(nix::unistd::Gid::from_raw(backup_gid)), + .group(backup_user.gid), )?; Ok(()) diff --git a/src/backup.rs b/src/backup.rs index 5f8bafe8..19830077 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -103,6 +103,8 @@ //! //! Not sure if this is better. TODO +use failure::*; + // Note: .pcat1 => Proxmox Catalog Format version 1 pub const CATALOG_NAME: &str = "catalog.pcat1.didx"; @@ -116,6 +118,17 @@ macro_rules! PROXMOX_BACKUP_READER_PROTOCOL_ID_V1 { () => { "proxmox-backup-reader-protocol-v1" } } +/// Unix system user used by proxmox-backup-proxy +pub const BACKUP_USER_NAME: &str = "backup"; + +/// Return User info for the 'backup' user (``getpwnam_r(3)``) +pub fn backup_user() -> Result { + match nix::unistd::User::from_name(BACKUP_USER_NAME)? { + Some(user) => Ok(user), + None => bail!("Unable to lookup backup user."), + } +} + mod file_formats; pub use file_formats::*; diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs index 844097e8..c16d622f 100644 --- a/src/backup/chunk_store.rs +++ b/src/backup/chunk_store.rs @@ -95,13 +95,11 @@ impl ChunkStore { let chunk_dir = Self::chunk_dir(&base); - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; - let uid = nix::unistd::Uid::from_raw(backup_uid); - let gid = nix::unistd::Gid::from_raw(backup_gid); + let backup_user = crate::backup::backup_user()?; let options = CreateOptions::new() - .owner(uid) - .group(gid); + .owner(backup_user.uid) + .group(backup_user.gid); let default_options = CreateOptions::new(); diff --git a/src/config.rs b/src/config.rs index f8cd22cc..88afdc43 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,10 @@ pub mod datastore; /// * nobody else can read (mode 0700) pub fn check_configdir_permissions() -> Result<(), Error> { let cfgdir = buildcfg::CONFIGDIR; - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; + + let backup_user = crate::backup::backup_user()?; + let backup_uid = backup_user.uid.as_raw(); + let backup_gid = backup_user.gid.as_raw(); try_block!({ let stat = nix::sys::stat::stat(cfgdir)?; @@ -49,7 +52,6 @@ pub fn create_configdir() -> Result<(), Error> { use nix::sys::stat::Mode; let cfgdir = buildcfg::CONFIGDIR; - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; match nix::unistd::mkdir(cfgdir, Mode::from_bits_truncate(0o700)) { Ok(()) => {} @@ -64,19 +66,14 @@ pub fn create_configdir() -> Result<(), Error> { ), } - try_block!({ - let uid = nix::unistd::Uid::from_raw(backup_uid); - let gid = nix::unistd::Gid::from_raw(backup_gid); + let backup_user = crate::backup::backup_user()?; - nix::unistd::chown(cfgdir, Some(uid), Some(gid))?; - - Ok(()) - }) - .map_err(|err: Error| { - format_err!( - "unable to set configuration directory '{}' permissions - {}", - cfgdir, - err - ) - }) + nix::unistd::chown(cfgdir, Some(backup_user.uid), Some(backup_user.gid)) + .map_err(|err| { + format_err!( + "unable to set configuration directory '{}' permissions - {}", + cfgdir, + err + ) + }) } diff --git a/src/config/datastore.rs b/src/config/datastore.rs index 8d71f6f5..78947178 100644 --- a/src/config/datastore.rs +++ b/src/config/datastore.rs @@ -58,15 +58,14 @@ pub fn config() -> Result { pub fn save_config(config: &SectionConfigData) -> Result<(), Error> { let raw = CONFIG.write(DATASTORE_CFG_FILENAME, &config)?; - let (_, backup_gid) = crate::tools::getpwnam_ugid("backup")?; - let gid = nix::unistd::Gid::from_raw(backup_gid); + let backup_user = crate::backup::backup_user()?; let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640); // set the correct owner/group/permissions while saving file // owner(rw) = root, group(r)= backup let options = CreateOptions::new() .perm(mode) .owner(nix::unistd::ROOT) - .group(gid); + .group(backup_user.gid); replace_file(DATASTORE_CFG_FILENAME, raw.as_bytes(), options)?; diff --git a/src/server/worker_task.rs b/src/server/worker_task.rs index 7be02ab5..f8947c1b 100644 --- a/src/server/worker_task.rs +++ b/src/server/worker_task.rs @@ -132,10 +132,10 @@ fn parse_worker_status_line(line: &str) -> Result<(String, UPID, Option<(i64, St pub fn create_task_log_dirs() -> Result<(), Error> { try_block!({ - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; + let backup_user = crate::backup::backup_user()?; let opts = CreateOptions::new() - .owner(nix::unistd::Uid::from_raw(backup_uid)) - .group(nix::unistd::Gid::from_raw(backup_gid)); + .owner(backup_user.uid) + .group(backup_user.gid); create_path(PROXMOX_BACKUP_LOG_DIR, None, Some(opts.clone()))?; create_path(PROXMOX_BACKUP_TASK_DIR, None, Some(opts.clone()))?; @@ -201,12 +201,10 @@ pub struct TaskListInfo { // Returns a sorted list of known tasks, fn update_active_workers(new_upid: Option<&UPID>) -> Result, Error> { - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; - let uid = nix::unistd::Uid::from_raw(backup_uid); - let gid = nix::unistd::Gid::from_raw(backup_gid); + let backup_user = crate::backup::backup_user()?; let lock = crate::tools::open_file_locked(PROXMOX_BACKUP_TASK_LOCK_FN, std::time::Duration::new(10, 0))?; - nix::unistd::chown(PROXMOX_BACKUP_TASK_LOCK_FN, Some(uid), Some(gid))?; + nix::unistd::chown(PROXMOX_BACKUP_TASK_LOCK_FN, Some(backup_user.uid), Some(backup_user.gid))?; let reader = match File::open(PROXMOX_BACKUP_ACTIVE_TASK_FN) { Ok(f) => Some(BufReader::new(f)), @@ -305,8 +303,8 @@ fn update_active_workers(new_upid: Option<&UPID>) -> Result, E PROXMOX_BACKUP_ACTIVE_TASK_FN, raw.as_bytes(), CreateOptions::new() - .owner(uid) - .group(gid), + .owner(backup_user.uid) + .group(backup_user.gid), )?; drop(lock); @@ -367,18 +365,16 @@ impl WorkerTask { path.push(format!("{:02X}", upid.pstart % 256)); - let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?; - let uid = nix::unistd::Uid::from_raw(backup_uid); - let gid = nix::unistd::Gid::from_raw(backup_gid); + let backup_user = crate::backup::backup_user()?; - create_path(&path, None, Some(CreateOptions::new().owner(uid).group(gid)))?; + create_path(&path, None, Some(CreateOptions::new().owner(backup_user.uid).group(backup_user.gid)))?; path.push(upid.to_string()); println!("FILE: {:?}", path); let logger = FileLogger::new(&path, to_stdout)?; - nix::unistd::chown(&path, Some(uid), Some(gid))?; + nix::unistd::chown(&path, Some(backup_user.uid), Some(backup_user.gid))?; update_active_workers(Some(&upid))?; diff --git a/src/tools.rs b/src/tools.rs index 6a67efee..5861f0e0 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -199,19 +199,6 @@ where Ok(()) } -/// Returns the Unix uid/gid for the sepcified system user. -pub fn getpwnam_ugid(username: &str) -> Result<(libc::uid_t, libc::gid_t), Error> { - let c_username = std::ffi::CString::new(username).unwrap(); - let info = unsafe { libc::getpwnam(c_username.as_ptr()) }; - if info.is_null() { - bail!("getpwnam '{}' failed", username); - } - - let info = unsafe { *info }; - - Ok((info.pw_uid, info.pw_gid)) -} - pub fn json_object_to_query(data: Value) -> Result { let mut query = url::form_urlencoded::Serializer::new(String::new());