]> git.proxmox.com Git - proxmox-backup.git/blame - pbs-config/src/domains.rs
manager: add subcommand for managing AD realms
[proxmox-backup.git] / pbs-config / src / domains.rs
CommitLineData
6ef1b649
WB
1use std::collections::HashMap;
2
35f151e0 3use anyhow::Error;
bbff6c49 4use lazy_static::lazy_static;
bbff6c49 5
3f22f650
LW
6use pbs_buildcfg::configdir;
7use proxmox_schema::{ApiType, ObjectSchema};
6ef1b649 8use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
bbff6c49 9
21211748 10use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
d07013a4 11use pbs_api_types::{AdRealmConfig, LdapRealmConfig, OpenIdRealmConfig, REALM_ID_SCHEMA};
bbff6c49
DM
12
13lazy_static! {
14 pub static ref CONFIG: SectionConfig = init();
15}
16
bbff6c49 17fn init() -> SectionConfig {
d07013a4 18 const AD_SCHEMA: &ObjectSchema = AdRealmConfig::API_SCHEMA.unwrap_object_schema();
3f22f650
LW
19 const LDAP_SCHEMA: &ObjectSchema = LdapRealmConfig::API_SCHEMA.unwrap_object_schema();
20 const OPENID_SCHEMA: &ObjectSchema = OpenIdRealmConfig::API_SCHEMA.unwrap_object_schema();
21
22 let mut config = SectionConfig::new(&REALM_ID_SCHEMA);
bbff6c49 23
35f151e0
TL
24 let plugin = SectionConfigPlugin::new(
25 "openid".to_string(),
26 Some(String::from("realm")),
3f22f650 27 OPENID_SCHEMA,
35f151e0 28 );
3f22f650
LW
29
30 config.register_plugin(plugin);
31
32 let plugin =
33 SectionConfigPlugin::new("ldap".to_string(), Some(String::from("realm")), LDAP_SCHEMA);
34
bbff6c49
DM
35 config.register_plugin(plugin);
36
d07013a4
CH
37 let plugin = SectionConfigPlugin::new("ad".to_string(), Some(String::from("realm")), AD_SCHEMA);
38
39 config.register_plugin(plugin);
40
bbff6c49
DM
41 config
42}
43
3f22f650
LW
44pub const DOMAINS_CFG_FILENAME: &str = configdir!("/domains.cfg");
45pub const DOMAINS_CFG_LOCKFILE: &str = configdir!("/.domains.lck");
bbff6c49
DM
46
47/// Get exclusive lock
7526d864
DM
48pub fn lock_config() -> Result<BackupLockGuard, Error> {
49 open_backup_lockfile(DOMAINS_CFG_LOCKFILE, None, true)
bbff6c49
DM
50}
51
35f151e0 52pub fn config() -> Result<(SectionConfigData, [u8; 32]), Error> {
16f6766a
FG
53 let content =
54 proxmox_sys::fs::file_read_optional_string(DOMAINS_CFG_FILENAME)?.unwrap_or_default();
bbff6c49
DM
55
56 let digest = openssl::sha::sha256(content.as_bytes());
57 let data = CONFIG.parse(DOMAINS_CFG_FILENAME, &content)?;
58 Ok((data, digest))
59}
60
61pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
9a37bd6c 62 let raw = CONFIG.write(DOMAINS_CFG_FILENAME, config)?;
21211748 63 replace_backup_config(DOMAINS_CFG_FILENAME, raw.as_bytes())
bbff6c49
DM
64}
65
3f22f650
LW
66/// Check if a realm with the given name exists
67pub fn exists(domains: &SectionConfigData, realm: &str) -> bool {
68 realm == "pbs" || realm == "pam" || domains.sections.get(realm).is_some()
69}
70
bbff6c49
DM
71// shell completion helper
72pub fn complete_realm_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
73 match config() {
82c0194e 74 Ok((data, _digest)) => data.sections.keys().map(|id| id.to_string()).collect(),
4597eedf 75 Err(_) => Vec::new(),
bbff6c49
DM
76 }
77}
0decd11e 78
2b75fbaa 79fn complete_realm_of_type(realm_type: &str) -> Vec<String> {
0decd11e 80 match config() {
35f151e0
TL
81 Ok((data, _digest)) => data
82 .sections
83 .iter()
84 .filter_map(|(id, (t, _))| {
2b75fbaa 85 if t == realm_type {
35f151e0
TL
86 Some(id.to_string())
87 } else {
88 None
89 }
90 })
0decd11e 91 .collect(),
4597eedf 92 Err(_) => Vec::new(),
0decd11e
DM
93 }
94}
2b75fbaa
LW
95
96pub fn complete_openid_realm_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
97 complete_realm_of_type("openid")
98}
99
100pub fn complete_ldap_realm_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
101 complete_realm_of_type("ldap")
102}
1819989b
CH
103
104pub fn complete_ad_realm_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
105 complete_realm_of_type("ad")
106}