ntdsextract2 1.4.7

Display contents of Active Directory database files (ntds.dit)
use std::collections::HashMap;

use base64::prelude::*;

use crate::{
    cache::{self, Value, WithValue},
    win32_types::SecurityDescriptor,
};

pub struct SdTable {
    descriptors: HashMap<i64, Vec<u8>>,
}

impl SdTable {
    pub fn new(sd_table: &cache::SdTable) -> crate::ntds::Result<Self> {
        let sd_id_column = sd_table.sd_id_column();
        let sd_value_column = sd_table.sd_value_column();

        let descriptors = sd_table
            .iter()
            .map(|record| {
                let sd_id = record
                    .with_value(*sd_id_column, |v| match v.unwrap() {
                        Value::I16(v) => Ok(i64::from(*v)),
                        Value::I32(v) => Ok(i64::from(*v)),
                        Value::I64(v) => Ok(*v),
                        Value::Currency(v) => Ok(*v),
                        v => unimplemented!("no support for {v} as sd_id"),
                    })
                    .unwrap();
                let sd_value = record
                    .with_value(*sd_value_column, |v| match v.unwrap() {
                        Value::Long(v) | Value::Binary(v) | Value::LargeBinary(v) => {
                            Ok(v.as_ref().clone())
                        }
                        v => unimplemented!("no support for {v} as sd_value"),
                    })
                    .unwrap();

                (sd_id, sd_value)
            })
            .collect();
        Ok(Self { descriptors })
    }

    pub fn descriptor(
        &self,
        sd_id: &i64,
    ) -> Option<Result<SecurityDescriptor, crate::ntds::Error>> {
        self.descriptors
            .get(sd_id)
            .map(|v| match SecurityDescriptor::try_from(&v[..]) {
                Ok(sd) => Ok(sd),
                Err(why) => {
                    log::error!("failed descriptor was: {}", BASE64_STANDARD.encode(v));
                    log::error!("{why}");
                    Err(why)
                }
            })
    }
}