rusthound_ce/objects/
trust.rs

1use ldap3::SearchEntry;
2use log::{debug, trace};
3use std::collections::HashMap;
4use std::error::Error;
5use serde::{Deserialize, Serialize};
6
7use crate::enums::secdesc::LdapSid;
8use crate::enums::sid::sid_maker;
9use crate::enums::trusts::get_trust_flag;
10
11/// Trust structure
12#[derive(Debug, Clone, Deserialize, Serialize, Default)]
13pub struct Trust {
14   #[serde(rename = "TargetDomainSid")]
15   target_domain_sid: String,
16   #[serde(rename = "TargetDomainName")]
17   target_domain_name: String,
18   #[serde(rename = "IsTransitive")]
19   is_transitive: bool,
20   #[serde(rename = "SidFilteringEnabled")]
21   sid_filtering_enabled: bool,
22   #[serde(rename = "TrustAttributes")]
23   trust_attributes: u32,
24   #[serde(rename = "TrustDirection")]
25   trust_direction: String,
26   #[serde(rename = "TrustType")]
27   trust_type: String,
28}
29
30impl Trust {
31   // New trust link for domain.
32    pub fn new() -> Self { 
33      Self {
34         ..Default::default()
35      } 
36   }
37
38   // Imutable access.
39   pub fn target_domain_sid(&self) -> &String {
40      &self.target_domain_sid
41   }
42   pub fn target_domain_name(&self) -> &String {
43      &self.target_domain_name
44   }
45
46   // Mutable access.
47   pub fn is_transitive_mut(&mut self) -> &mut bool {
48      &mut self.is_transitive
49   }
50   pub fn sid_filtering_enabled_mut(&mut self) -> &mut bool {
51      &mut self.sid_filtering_enabled
52   }
53   pub fn trust_type_mut(&mut self) -> &mut String {
54      &mut self.trust_type
55   }
56
57   /// Function to parse and replace value for trust domain object.
58   pub fn parse(
59      &mut self,
60      result: SearchEntry,
61      domain: &String
62   ) -> Result<(), Box<dyn Error>> {
63      let result_dn: String = result.dn.to_uppercase();
64      let result_attrs: HashMap<String, Vec<String>> = result.attrs;
65      let result_bin: HashMap<String, Vec<Vec<u8>>> = result.bin_attrs;
66
67      // Debug for current object
68      debug!("Parse TrustDomain: {}", result_dn);
69      // Trace all result attributes
70      for (key, value) in &result_attrs {
71         trace!("  {:?}:{:?}", key, value);
72      }
73      // Trace all bin result attributes
74      for (key, value) in &result_bin {
75         trace!("  {:?}:{:?}", key, value);
76      }
77
78      // With a check
79      for (key, value) in &result_attrs {
80         match key.as_str() {
81            "name" => {
82                  self.target_domain_name = value[0].to_uppercase();
83            }
84            "trustDirection" => {
85                  let trustdirection: u8 = value[0].parse::<u8>().unwrap_or(0);
86                  // <https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/5026a939-44ba-47b2-99cf-386a9e674b04>
87                  self.trust_direction = match trustdirection { 
88                     1 => "Inbound",
89                     2 => "Outbound",
90                     3 => "Bidirectional",
91                     _ => "Disabled"
92                  }.to_string()
93            }
94            "trustAttributes" => {
95                  let trustflag: u32 = value[0].parse::<u32>().unwrap_or(0);
96                  get_trust_flag(trustflag, self);
97                  self.trust_attributes = trustflag;
98            }
99            _ => {}
100         }
101      }
102      // For all, bins attributs
103      for (key, value) in &result_bin {
104         match key.as_str() {
105            "securityIdentifier" => {
106                  let sid = sid_maker(LdapSid::parse(&value[0]).unwrap().1, domain);
107                  self.target_domain_sid = sid.to_owned();
108            }
109            _ => {}
110         }
111      }
112      
113      // Trace and return tRUST struct
114      // trace!("TRUST VALUE: {:?}",&self);
115      Ok(())
116   }
117}