signstar_common/
admin_credentials.rs1use std::{
13 fs::{Permissions, create_dir_all, set_permissions},
14 os::unix::fs::{PermissionsExt, chown},
15 path::PathBuf,
16};
17
18use crate::common::{CREDENTIALS_DIR_MODE, get_data_home};
19
20const PLAINTEXT_CREDENTIALS_FILE: &str = "admin-credentials.toml";
22
23const SYSTEMD_CREDS_CREDENTIALS_FILE: &str = "admin-credentials.creds";
25
26const CREDENTIALS_DIR: &str = "creds/";
28
29#[derive(Debug, thiserror::Error)]
31pub enum Error {
32 #[error("Unable to apply permissions {permissions} to {path}:\n{source}")]
34 ApplyPermissions {
35 permissions: u32,
37 path: PathBuf,
39 source: std::io::Error,
41 },
42
43 #[error("Unable to create directory {dir}:\n{source}")]
45 CreateDirectory {
46 dir: &'static str,
48 source: std::io::Error,
50 },
51
52 #[error("Ownership of directory {dir} can not be changed to user {system_user}: {source}")]
54 DirChangeOwner {
55 dir: PathBuf,
57 system_user: String,
59 source: std::io::Error,
61 },
62}
63
64pub fn get_credentials_dir() -> PathBuf {
66 get_data_home().join(PathBuf::from(CREDENTIALS_DIR))
67}
68
69pub fn get_plaintext_credentials_file() -> PathBuf {
71 get_credentials_dir().join(PathBuf::from(PLAINTEXT_CREDENTIALS_FILE))
72}
73
74pub fn get_systemd_creds_credentials_file() -> PathBuf {
76 get_credentials_dir().join(PathBuf::from(SYSTEMD_CREDS_CREDENTIALS_FILE))
77}
78
79pub fn create_credentials_dir() -> Result<(), Error> {
86 let credentials_dir = get_credentials_dir();
87 create_dir_all(credentials_dir.as_path()).map_err(|source| Error::CreateDirectory {
88 dir: CREDENTIALS_DIR,
89 source,
90 })?;
91
92 set_permissions(
94 credentials_dir.as_path(),
95 Permissions::from_mode(CREDENTIALS_DIR_MODE),
96 )
97 .map_err(|source| Error::ApplyPermissions {
98 permissions: CREDENTIALS_DIR_MODE,
99 path: credentials_dir.clone(),
100 source,
101 })?;
102
103 let data_home = get_data_home();
106 let mut chown_dir = credentials_dir.clone();
107 while chown_dir != data_home {
108 chown(&chown_dir, Some(0), Some(0)).map_err(|source| Error::DirChangeOwner {
109 dir: chown_dir.to_path_buf(),
110 system_user: "root".to_string(),
111 source,
112 })?;
113 if let Some(parent) = &chown_dir.parent() {
114 chown_dir = parent.to_path_buf()
115 } else {
116 break;
117 }
118 }
119
120 Ok(())
121}