use std::collections::HashMap;
use windows_sddl::sid::Guid;
pub mod names {
pub const LAPS_LEGACY: &str = "ms-Mcs-AdmPwd";
pub const LAPS_PASSWORD: &str = "msLAPS-Password";
pub const LAPS_ENCRYPTED: &str = "msLAPS-EncryptedPassword";
pub const MANAGED_PASSWORD: &str = "msDS-ManagedPassword";
pub const DMSA_CLASS: &str = "msDS-DelegatedManagedServiceAccount";
}
#[derive(Clone, Debug, Default)]
pub struct SchemaMap {
by_guid: HashMap<Guid, String>,
by_name: HashMap<String, Guid>,
}
impl SchemaMap {
pub fn new() -> Self {
Self::default()
}
pub fn from_entries<I, S>(entries: I) -> Self
where
I: IntoIterator<Item = (S, Guid)>,
S: AsRef<str>,
{
let mut m = SchemaMap::new();
for (name, guid) in entries {
m.insert(name.as_ref(), guid);
}
m
}
pub fn insert(&mut self, name: &str, guid: Guid) {
self.by_guid.insert(guid, name.to_string());
self.by_name.insert(name.to_ascii_lowercase(), guid);
}
pub fn is_empty(&self) -> bool {
self.by_name.is_empty()
}
pub fn name(&self, g: &Guid) -> Option<&str> {
self.by_guid.get(g).map(String::as_str)
}
pub fn guid(&self, name: &str) -> Option<Guid> {
self.by_name.get(&name.to_ascii_lowercase()).copied()
}
pub fn is_laps_attr(&self, g: &Guid) -> bool {
matches!(
self.name(g),
Some(n) if n.eq_ignore_ascii_case(names::LAPS_LEGACY)
|| n.eq_ignore_ascii_case(names::LAPS_PASSWORD)
|| n.eq_ignore_ascii_case(names::LAPS_ENCRYPTED)
)
}
pub fn is_managed_password_attr(&self, g: &Guid) -> bool {
matches!(self.name(g), Some(n) if n.eq_ignore_ascii_case(names::MANAGED_PASSWORD))
}
pub fn is_dmsa_class(&self, g: &Guid) -> bool {
matches!(self.name(g), Some(n) if n.eq_ignore_ascii_case(names::DMSA_CLASS))
}
}