]> git.proxmox.com Git - proxmox-backup.git/blob - pbs-config/src/lib.rs
ba1289ede4754805fd1f4f0ef600cdb11ea51faf
[proxmox-backup.git] / pbs-config / src / lib.rs
1 pub mod acl;
2 mod cached_user_info;
3 pub use cached_user_info::CachedUserInfo;
4 pub mod datastore;
5 pub mod domains;
6 pub mod drive;
7 pub mod key_config;
8 pub mod media_pool;
9 pub mod network;
10 pub mod remote;
11 pub mod sync;
12 pub mod tape_encryption_keys;
13 pub mod tape_job;
14 pub mod token_shadow;
15 pub mod traffic_control;
16 pub mod user;
17 pub mod verify;
18
19 mod config_version_cache;
20 pub use config_version_cache::ConfigVersionCache;
21
22 use anyhow::{format_err, Error};
23
24 pub use pbs_buildcfg::{BACKUP_USER_NAME, BACKUP_GROUP_NAME};
25
26 /// Return User info for the 'backup' user (``getpwnam_r(3)``)
27 pub fn backup_user() -> Result<nix::unistd::User, Error> {
28 pbs_tools::sys::query_user(BACKUP_USER_NAME)?
29 .ok_or_else(|| format_err!("Unable to lookup '{}' user.", BACKUP_USER_NAME))
30 }
31
32 /// Return Group info for the 'backup' group (``getgrnam(3)``)
33 pub fn backup_group() -> Result<nix::unistd::Group, Error> {
34 pbs_tools::sys::query_group(BACKUP_GROUP_NAME)?
35 .ok_or_else(|| format_err!("Unable to lookup '{}' group.", BACKUP_GROUP_NAME))
36 }
37 pub struct BackupLockGuard(Option<std::fs::File>);
38
39 #[doc(hidden)]
40 /// Note: do not use for production code, this is only intended for tests
41 pub unsafe fn create_mocked_lock() -> BackupLockGuard {
42 BackupLockGuard(None)
43 }
44
45 /// Open or create a lock file owned by user "backup" and lock it.
46 ///
47 /// Owner/Group of the file is set to backup/backup.
48 /// File mode is 0660.
49 /// Default timeout is 10 seconds.
50 ///
51 /// Note: This method needs to be called by user "root" or "backup".
52 pub fn open_backup_lockfile<P: AsRef<std::path::Path>>(
53 path: P,
54 timeout: Option<std::time::Duration>,
55 exclusive: bool,
56 ) -> Result<BackupLockGuard, Error> {
57 let user = backup_user()?;
58 let options = proxmox::tools::fs::CreateOptions::new()
59 .perm(nix::sys::stat::Mode::from_bits_truncate(0o660))
60 .owner(user.uid)
61 .group(user.gid);
62
63 let timeout = timeout.unwrap_or(std::time::Duration::new(10, 0));
64
65 let file = proxmox::tools::fs::open_file_locked(&path, timeout, exclusive, options)?;
66 Ok(BackupLockGuard(Some(file)))
67 }
68
69 /// Atomically write data to file owned by "root:backup" with permission "0640"
70 ///
71 /// Only the superuser can write those files, but group 'backup' can read them.
72 pub fn replace_backup_config<P: AsRef<std::path::Path>>(
73 path: P,
74 data: &[u8],
75 ) -> Result<(), Error> {
76 let backup_user = backup_user()?;
77 let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
78 // set the correct owner/group/permissions while saving file
79 // owner(rw) = root, group(r)= backup
80 let options = proxmox::tools::fs::CreateOptions::new()
81 .perm(mode)
82 .owner(nix::unistd::ROOT)
83 .group(backup_user.gid);
84
85 proxmox::tools::fs::replace_file(path, data, options, true)?;
86
87 Ok(())
88 }
89
90 /// Atomically write data to file owned by "root:root" with permission "0600"
91 ///
92 /// Only the superuser can read and write those files.
93 pub fn replace_secret_config<P: AsRef<std::path::Path>>(
94 path: P,
95 data: &[u8],
96 ) -> Result<(), Error> {
97 let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
98 // set the correct owner/group/permissions while saving file
99 // owner(rw) = root, group(r)= root
100 let options = proxmox::tools::fs::CreateOptions::new()
101 .perm(mode)
102 .owner(nix::unistd::ROOT)
103 .group(nix::unistd::Gid::from_raw(0));
104
105 proxmox::tools::fs::replace_file(path, data, options, true)?;
106
107 Ok(())
108 }