1use std::collections::HashMap;
2use std::error::Error;
3
4use regex::Regex;
5use crate::enums::ldaptype::*;
6use crate::objects::common::Link;
7use crate::objects::{
8 user::User,
9 computer::Computer,
10 group::Group,
11 ou::Ou,
12 domain::Domain,
13 trust::Trust,
14 common::{Member, GPOChange, LdapObject}
15};
16use crate::ldap::prepare_ldap_dc;
18use crate::utils::format::domain_to_dc;
19use crate::enums::regex::{COMMON_RE1,DOMAIN_SID_RE1};
20use indicatif::ProgressBar;
21use log::{error,trace};
22
23pub fn add_default_groups(
26 vec_groups: &mut Vec<Group>,
27 vec_computers: &[Computer],
28 domain: String
29) -> Result<(), Box<dyn Error>> {
30 let mut member_sid = "".to_owned();
31 let mut domain_sid = "".to_owned();
32
33 let mut template_member = Member::new();
34 *template_member.object_type_mut() = "Computer".to_string();
35
36 let mut edc_group = Group::new();
38 let mut sid = domain.to_uppercase();
39 sid.push_str("-S-1-5-9");
40
41 let mut name = "ENTERPRISE DOMAIN CONTROLLERS@".to_owned();
42 name.push_str(&domain.to_uppercase());
43
44 let mut vec_members: Vec<Member> = Vec::new();
45 for computer in vec_computers {
46 if computer.properties().get_is_dc().to_owned()
47 {
48 *template_member.object_identifier_mut() = computer.object_identifier().clone();
58 vec_members.push(template_member.clone());
59 if let Some(capture) = COMMON_RE1.captures(computer.object_identifier()) {
60
61 member_sid = capture.get(0).map(|m| m.as_str().to_string()).unwrap_or_default();
62
63 if let Some(capture) = DOMAIN_SID_RE1.captures(computer.object_identifier()) {
64 domain_sid = capture.get(0).unwrap().as_str().to_string();
65 }
66
67 }
68 }
69 }
70
71 *edc_group.object_identifier_mut() = sid;
72 *edc_group.properties_mut().name_mut() = name;
73 *edc_group.members_mut() = vec_members;
74 *edc_group.properties_mut().domain_mut() = domain.to_owned();
75 *edc_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
76 vec_groups.push(edc_group);
77
78 let mut account_operators_group = Group::new();
80 sid = domain.to_owned().to_uppercase();
81 sid.push_str("-S-1-5-32-548");
82 let mut name = "ACCOUNT OPERATORS@".to_owned();
83 name.push_str(&domain.to_uppercase());
84
85 *account_operators_group.object_identifier_mut() = sid;
86 *account_operators_group.properties_mut().name_mut() = name;
87 *account_operators_group.properties_mut().highvalue_mut() = true;
88 *account_operators_group.properties_mut().domain_mut() = domain.to_owned();
89 *account_operators_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
90 vec_groups.push(account_operators_group);
91
92 let mut waag_group = Group::new();
94 sid = domain.to_uppercase();
95 sid.push_str("-S-1-5-32-560");
96 let mut name = "WINDOWS AUTHORIZATION ACCESS GROUP@".to_owned();
97 name.push_str(&domain.to_uppercase());
98 *waag_group.object_identifier_mut() = sid;
99 *waag_group.properties_mut().name_mut() = name;
100 *waag_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
101 vec_groups.push(waag_group);
102
103 let mut everyone_group = Group::new();
105 sid = domain.to_uppercase();
106 sid.push_str("-S-1-1-0");
107 let mut name = "EVERYONE@".to_owned();
108 name.push_str(&domain.to_uppercase());
109
110 let mut vec_everyone_members: Vec<Member> = Vec::new();
111 let mut member_id = member_sid.to_owned();
112 member_id.push_str("-515");
113 *template_member.object_identifier_mut() = member_id.to_owned();
114 *template_member.object_type_mut() = "Group".to_string();
115 vec_everyone_members.push(template_member.to_owned());
116
117 member_id = member_sid.to_owned();
118 member_id.push_str("-513");
119 *template_member.object_identifier_mut() = member_id.to_owned();
120 *template_member.object_type_mut() = "Group".to_string();
121 vec_everyone_members.push(template_member.to_owned());
122
123 *everyone_group.object_identifier_mut() = sid;
124 *everyone_group.properties_mut().name_mut() = name;
125 *everyone_group.properties_mut().domain_mut() = domain.to_owned();
126 *everyone_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
127 *everyone_group.members_mut() = vec_everyone_members;
128 vec_groups.push(everyone_group);
129
130 let mut auth_users_group = Group::new();
132 sid = domain.to_uppercase();
133 sid.push_str("-S-1-5-11");
134 let mut name = "AUTHENTICATED USERS@".to_owned();
135 name.push_str(&domain.to_uppercase());
136
137 let mut vec_auth_users_members: Vec<Member> = Vec::new();
138 member_id = member_sid.to_owned();
139 member_id.push_str("-515");
140 *template_member.object_identifier_mut() = member_id.to_owned();
141 *template_member.object_type_mut() = "Group".to_string();
142 vec_auth_users_members.push(template_member.to_owned());
143
144 member_id = member_sid.to_owned();
145 member_id.push_str("-513");
146 *template_member.object_identifier_mut() = member_id.to_owned();
147 *template_member.object_type_mut() = "Group".to_string();
148 vec_auth_users_members.push(template_member.to_owned());
149
150 *auth_users_group.object_identifier_mut() = sid;
151 *auth_users_group.properties_mut().name_mut() = name;
152 *auth_users_group.properties_mut().domain_mut() = domain.to_owned();
153 *auth_users_group.members_mut() = vec_auth_users_members;
154 *auth_users_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
155 vec_groups.push(auth_users_group);
156
157 let mut administrators_group = Group::new();
159 sid = domain.to_uppercase();
160 sid.push_str("-S-1-5-32-544");
161 let mut name = "ADMINISTRATORS@".to_owned();
162 name.push_str(&domain.to_uppercase());
163
164 *administrators_group.object_identifier_mut() = sid;
165 *administrators_group.properties_mut().name_mut() = name;
166 *administrators_group.properties_mut().highvalue_mut() = true;
167 *administrators_group.properties_mut().domain_mut() = domain.to_owned();
168 *administrators_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
169 vec_groups.push(administrators_group);
170
171 let mut pw2000ca_group = Group::new();
173 sid = domain.to_uppercase();
174 sid.push_str("-S-1-5-32-554");
175 let mut name = "PRE-WINDOWS 2000 COMPATIBLE ACCESS@".to_owned();
176 name.push_str(&domain.to_uppercase());
177
178 *pw2000ca_group.object_identifier_mut() = sid;
179 *pw2000ca_group.properties_mut().name_mut() = name;
180 *pw2000ca_group.properties_mut().domain_mut() = domain.to_owned();
181 *pw2000ca_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
182 vec_groups.push(pw2000ca_group);
183
184 let mut interactive_group = Group::new();
186 sid = domain.to_uppercase();
187 sid.push_str("-S-1-5-4");
188 let mut name = "INTERACTIVE@".to_owned();
189 name.push_str(&domain.to_uppercase());
190
191 *interactive_group.object_identifier_mut() = sid;
192 *interactive_group.properties_mut().name_mut() = name;
193 *interactive_group.properties_mut().domain_mut() = domain.to_owned();
194 *interactive_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
195 vec_groups.push(interactive_group);
196
197 let mut print_operators_group = Group::new();
199 sid = domain.to_uppercase();
200 sid.push_str("-S-1-5-32-550");
201 let mut name = "PRINT OPERATORS@".to_owned();
202 name.push_str(&domain.to_uppercase());
203
204 *print_operators_group.object_identifier_mut() = sid;
205 *print_operators_group.properties_mut().name_mut() = name;
206 *print_operators_group.properties_mut().highvalue_mut() = true;
207 *print_operators_group.properties_mut().domain_mut() = domain.to_owned();
208 *print_operators_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
209 vec_groups.push(print_operators_group);
210
211 let mut tsls_group = Group::new();
213 sid = domain.to_uppercase();
214 sid.push_str("-S-1-5-32-561");
215 let mut name = "TERMINAL SERVER LICENSE SERVERS@".to_owned();
216 name.push_str(&domain.to_uppercase());
217
218 *tsls_group.object_identifier_mut() = sid;
219 *tsls_group.properties_mut().name_mut() = name;
220 *tsls_group.properties_mut().domain_mut() = domain.to_owned();
221 *tsls_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
222 vec_groups.push(tsls_group);
223
224 let mut iftb_group = Group::new();
226 sid = domain.to_uppercase();
227 sid.push_str("-S-1-5-32-557");
228 let mut name = "INCOMING FOREST TRUST BUILDERS@".to_owned();
229 name.push_str(&domain.to_uppercase());
230
231 *iftb_group.object_identifier_mut() = sid;
232 *iftb_group.properties_mut().name_mut() = name;
233 *iftb_group.properties_mut().domain_mut() = domain.to_owned();
234 *iftb_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
235 vec_groups.push(iftb_group);
236
237 let mut this_organization_group = Group::new();
239 sid = domain.to_uppercase();
240 sid.push_str("-S-1-5-15");
241 let mut name = "THIS ORGANIZATION@".to_owned();
242 name.push_str(&domain.to_uppercase());
243
244 *this_organization_group.object_identifier_mut() = sid;
245 *this_organization_group.properties_mut().name_mut() = name;
246 *this_organization_group.properties_mut().domain_mut() = domain.to_owned();
247 *this_organization_group.properties_mut().domainsid_mut() = domain_sid.to_owned();
248 vec_groups.push(this_organization_group);
249 Ok(())
250}
251
252pub fn add_default_users(
255 vec_users: &mut Vec<User>,
256 domain: String
257) -> Result<(), Box<dyn Error>> {
258 let mut ntauthority_user = User::new();
260 let mut sid = domain.to_uppercase();
261 sid.push_str("-S-1-5-20");
262 let mut name = "NT AUTHORITY@".to_owned();
263 name.push_str(&domain.to_uppercase());
264 *ntauthority_user.properties_mut().name_mut() = name;
265 *ntauthority_user.object_identifier_mut() = sid;
266
267 if let Some(first_user) = vec_users.get(0) {
268 *ntauthority_user.properties_mut().domainsid_mut() = first_user.properties().domainsid().to_string();
269 } else {
270 error!("vec_users is empty, skipping domain SID assignment");
271 }
272
273 vec_users.push(ntauthority_user);
274 Ok(())
275}
276
277pub fn add_childobjects_members<T: LdapObject>(
279 vec_replaced: &mut [T],
280 dn_sid: &HashMap<String, String>,
281 sid_type: &HashMap<String, String>,
282) -> Result<(), Box<dyn Error>> {
283 let total = vec_replaced.len();
285 let pb = ProgressBar::new(total as u64);
286
287 for (count, object) in vec_replaced.iter_mut().enumerate() {
289 if count % (total / 100).max(1) == 0 {
291 pb.set_position(count as u64);
292 }
293
294 let sid = object.get_object_identifier().to_uppercase();
296 let dn = dn_sid
297 .iter()
298 .find(|(_, v)| **v == sid)
299 .map(|(k, _)| k)
300 .unwrap_or(&sid);
301 let name = get_name_from_full_distinguishedname(dn);
302 let _otype = sid_type.get(&sid).unwrap();
303
304 let direct_members: Vec<Member> = dn_sid
306 .iter()
307 .filter_map(|(dn_object, value_sid)| {
308 let dn_object_upper = dn_object.to_uppercase();
309
310 if dn_object_upper.contains(dn)
312 && &dn_object_upper != dn
313 && dn_object_upper.split(',')
314 .nth(1)
315 .and_then(|s| s.split('=').nth(1))
316 == Some(&name)
317 {
318 let mut member = Member::new();
319 *member.object_identifier_mut() = value_sid.clone();
320 *member.object_type_mut() = sid_type.get(value_sid).unwrap_or(&value_sid).to_string();
321 if !member.object_identifier().is_empty() {
322 return Some(member);
323 }
324 }
325 None
326 })
327 .collect();
328
329 object.set_child_objects(direct_members);
331 }
332
333 pb.finish_and_clear();
334 Ok(())
335}
336
337pub fn add_childobjects_members_for_ou(
339 vec_replaced: &mut [Ou],
340 dn_sid: &HashMap<String, String>,
341 sid_type: &HashMap<String, String>,
342) -> Result<(), Box<dyn Error>> {
343 let total = vec_replaced.len();
345 let pb = ProgressBar::new(total as u64);
346
347 let null = "NULL".to_string();
349
350 for (count, object) in vec_replaced.iter_mut().enumerate() {
351 if count % (total / 100).max(1) == 0 {
353 pb.set_position(count as u64);
354 }
355
356 let mut direct_members = Vec::new();
357 let mut affected_computers = Vec::new();
358
359 let dn = object.properties().distinguishedname();
361 let mut name = object.properties().name().to_owned();
362 let sid = dn_sid.get(dn).unwrap_or(&null);
363 let otype = sid_type.get(sid).unwrap_or(&null);
364
365 if otype != "Domain" {
367 if let Some(first_part) = name.split('@').next() {
368 name = first_part.to_string();
369 }
370 }
371
372 for (dn_object, value_sid) in dn_sid {
374 let dn_object_upper = dn_object.to_uppercase();
375
376 let first = dn_object_upper
378 .split(',')
379 .nth(1)
380 .and_then(|part| part.split('=').nth(1))
381 .unwrap_or("");
382
383 if otype != "Domain" {
384 if dn_object_upper.contains(dn) && &dn_object_upper != dn && first == name {
386 let mut member = Member::new();
387 *member.object_identifier_mut() = value_sid.clone();
388 let object_type = sid_type.get(value_sid).unwrap_or(&null).to_string();
389 *member.object_type_mut() = object_type.clone();
390
391 direct_members.push(member.clone());
392
393 if object_type == "Computer" {
395 affected_computers.push(member);
396 }
397 }
398 } else {
399 if let Some(cn) = name.split('.').next() {
401 if first.contains(cn) {
402 let mut member = Member::new();
403 *member.object_identifier_mut() = value_sid.clone();
404 *member.object_type_mut() = sid_type.get(value_sid).unwrap_or(&null).to_string();
405 direct_members.push(member);
406 }
407 }
408 }
409 }
410
411 *object.child_objects_mut() = direct_members;
413 if otype == "OU" {
414 let mut gpo_changes = GPOChange::new();
415 *gpo_changes.affected_computers_mut() = affected_computers;
416 *object.gpo_changes_mut() = gpo_changes;
417 }
418 }
419
420 pb.finish_and_clear();
421 Ok(())
422}
423
424pub fn replace_guid_gplink<T: LdapObject>(
426 vec_replaced: &mut [T],
427 dn_sid: &HashMap<String, String>,
428) -> Result<(), Box<dyn Error>> {
429 let total = vec_replaced.len();
431 let pb = ProgressBar::new(total as u64);
432
433 for (count, object) in vec_replaced.iter_mut().enumerate() {
435 if count % (total / 100).max(1) == 0 {
437 pb.set_position(count as u64);
438 }
439
440 if !object.get_links().is_empty() {
442 let updated_links: Vec<Link> = object
444 .get_links()
445 .iter()
446 .map(|link| {
447 let mut new_link = link.clone(); if let Some(new_guid) = dn_sid
449 .iter()
450 .find(|(key, _)| key.contains(link.guid()))
451 .map(|(_, guid)| guid.to_owned())
452 {
453 *new_link.guid_mut() = new_guid;
454 }
455 new_link
456 })
457 .collect();
458
459 object.set_links(updated_links);
461 }
462 }
463
464 pb.finish_and_clear();
465 Ok(())
466}
467
468pub fn add_affected_computers(
470 vec_domains: &mut [Domain],
471 sid_type: &HashMap<String, String>,
472) -> Result<(), Box<dyn Error>> {
473 let vec_affected_computers: Vec<Member> = sid_type
475 .iter()
476 .filter(|&(_, obj_type)| obj_type == "Computer")
477 .map(|(sid, _)| {
478 let mut member = Member::new();
479 *member.object_type_mut() = "Computer".to_string();
480 *member.object_identifier_mut() = sid.clone();
481 member
482 })
483 .collect();
484
485 if let Some(domain) = vec_domains.get_mut(0) {
487 let mut gpo_changes = GPOChange::new();
488 *gpo_changes.affected_computers_mut() = vec_affected_computers;
489 *domain.gpo_changes_mut() = gpo_changes;
490 }
491 Ok(())
492}
493
494pub fn add_affected_computers_for_ou(
496 vec_ous: &mut [Ou],
497 dn_sid: &HashMap<String, String>,
498 sid_type: &HashMap<String, String>,
499) -> Result<(), Box<dyn Error>> {
500 let dn_sid_filtered: Vec<(&String, &String)> = dn_sid
502 .iter()
503 .filter(|(_, sid)| sid_type.get(*sid).map(|t| t == "Computer").unwrap_or(false))
504 .collect();
505
506 let ou_dn_map: HashMap<String, String> = vec_ous
508 .iter()
509 .filter_map(|ou| {
510 dn_sid
511 .iter()
512 .find_map(|(dn, sid)| {
513 if *sid == *ou.get_object_identifier() {
514 Some((ou.get_object_identifier().to_owned(), dn.clone()))
515 } else {
516 None
517 }
518 })
519 })
520 .collect();
521
522 for ou in vec_ous.iter_mut() {
524 if let Some(ou_dn) = ou_dn_map.get(ou.get_object_identifier()) {
525 let vec_affected_computers: Vec<Member> = dn_sid_filtered
526 .iter()
527 .filter_map(|(dn, sid)| {
528 if get_contained_by_name_from_distinguishedname(
529 &get_cn_object_name_from_full_distinguishedname(dn),
530 dn,
531 ) == *ou_dn
532 {
533 let mut member = Member::new();
534 *member.object_identifier_mut() = sid.to_string();
535 *member.object_type_mut() = "Computer".to_string();
536 Some(member)
537 } else {
538 None
539 }
540 })
541 .collect();
542
543 let mut gpo_changes = GPOChange::new();
545 *gpo_changes.affected_computers_mut() = vec_affected_computers;
546 *ou.gpo_changes_mut() = gpo_changes;
547 }
548 }
549 Ok(())
550}
551
552pub fn replace_fqdn_by_sid<T: LdapObject>(
554 object_type: Type,
555 vec_src: &mut [T],
556 fqdn_sid: &HashMap<String, String>,
557) -> Result<(), Box<dyn Error>> {
558 let total = vec_src.len();
560 let pb = ProgressBar::new(total as u64);
561
562 match object_type {
564 Type::User => {
565 for (count, obj) in vec_src.iter_mut().enumerate() {
566 if count % (total / 100).max(1) == 0 {
568 pb.set_position(count as u64);
569 }
570
571 for target in obj.get_spntargets_mut().iter_mut() {
573 let sid = fqdn_sid
574 .get(target.computer_sid())
575 .unwrap_or_else(|| target.computer_sid());
576 *target.computer_sid_mut() = sid.to_string();
577 }
578
579 for target in obj.get_allowed_to_delegate_mut().iter_mut() {
581 let sid = fqdn_sid
582 .get(target.object_identifier())
583 .unwrap_or_else(|| target.object_identifier());
584 *target.object_identifier_mut() = sid.to_string();
585 }
586 }
587 }
588 Type::Computer => {
589 for (count, obj) in vec_src.iter_mut().enumerate() {
590 if count % (total / 100).max(1) == 0 {
592 pb.set_position(count as u64);
593 }
594
595 for delegate in obj.get_allowed_to_delegate_mut().iter_mut() {
597 let sid = fqdn_sid
598 .get(delegate.object_identifier())
599 .unwrap_or_else(|| delegate.object_identifier());
600 *delegate.object_identifier_mut() = sid.to_string();
601 }
602 }
603 }
604 _ => {}
605 }
606
607 pb.finish_and_clear();
608 Ok(())
609}
610
611pub fn replace_sid_members(
613 vec_groups: &mut [Group],
614 dn_sid: &HashMap<String, String>,
615 sid_type: &HashMap<String, String>,
616 vec_trusts: &[Trust],
617) -> Result<(), Box<dyn Error>> {
618 let total = vec_groups.len();
619 let pb = ProgressBar::new(total as u64);
620
621 let default_type = "Group".to_string();
622
623 for (count, group) in vec_groups.iter_mut().enumerate() {
624 if count % (total / 100).max(1) == 0 {
625 pb.set_position(count as u64);
626 }
627
628 for member in group.members_mut() {
629 let member_dn = member.object_identifier();
630
631 if member_dn.trim().is_empty() || member_dn.eq_ignore_ascii_case("SID") {
633 error!("Skipping empty/invalid member DN in group");
634 continue;
635 }
636
637 if let Some(sid) = dn_sid.get(member_dn) {
639 if !sid.is_empty() && sid != "NULL" {
640 let type_object =
641 sid_type.get(sid).cloned().unwrap_or_else(|| default_type.clone());
642 *member.object_identifier_mut() = sid.clone();
643 *member.object_type_mut() = type_object;
644 continue;
645 }
646 }
647
648 let generated_sid = sid_maker_from_another_domain(vec_trusts, member_dn)?;
650 if !generated_sid.is_empty() {
651 *member.object_identifier_mut() = generated_sid;
652 *member.object_type_mut() = default_type.clone();
653 } else {
654 error!("Could not resolve SID for member DN: {}", member_dn);
655 }
656 }
657 }
658
659 pb.finish_and_clear();
660 Ok(())
661}
662
663fn sid_maker_from_another_domain(
665 vec_trusts: &[Trust],
666 object_identifier: &String,
667) -> Result<String, Box<dyn Error>> {
668 let sid_regex = Regex::new(r"S-[0-9]+-[0-9]+-[0-9]+(?:-[0-9]+)+")?;
670
671 for trust in vec_trusts {
673 let ldap_dc = prepare_ldap_dc(trust.target_domain_name());
674 if object_identifier.contains(&ldap_dc[0]) {
675 let id = get_id_from_objectidentifier(object_identifier)?;
676 return Ok(format!("{}{}", trust.target_domain_name(), id))
677 }
678 }
679
680 if object_identifier.contains("CN=S-") {
682 if let Some(capture) = sid_regex.captures(object_identifier).and_then(|cap| cap.get(0)) {
683 return Ok(capture.as_str().to_owned())
684 }
685 }
686
687 Ok(object_identifier.to_string())
689}
690
691fn get_id_from_objectidentifier(
694 object_identifier: &str
695) -> Result<String, Box<dyn Error>> {
696
697 const NAME_TO_RID: [(&str, &str); 16] = [
699 ("DOMAIN ADMINS", "-512"),
700 ("ADMINISTRATEURS DU DOMAINE", "-512"),
701 ("DOMAIN USERS", "-513"),
702 ("UTILISATEURS DU DOMAINE", "-513"),
703 ("DOMAIN GUESTS", "-514"),
704 ("INVITES DE DOMAINE", "-514"),
705 ("DOMAIN COMPUTERS", "-515"),
706 ("ORDINATEURS DE DOMAINE", "-515"),
707 ("DOMAIN CONTROLLERS", "-516"),
708 ("CONTRÔLEURS DE DOMAINE", "-516"),
709 ("CERT PUBLISHERS", "-517"),
710 ("EDITEURS DE CERTIFICATS", "-517"),
711 ("SCHEMA ADMINS", "-518"),
712 ("ADMINISTRATEURS DU SCHEMA", "-518"),
713 ("ENTERPRISE ADMINS", "-519"),
714 ("ADMINISTRATEURS DE L'ENTREPRISE", "-519"),
715 ];
716
717 for (name, rid) in NAME_TO_RID.iter() {
719 if object_identifier.contains(name) {
720 return Ok(rid.to_string())
721 }
722 }
723
724 Ok("NULL_ID1".to_string())
726}
727
728pub fn add_trustdomain(
730 vec_domains: &mut Vec<Domain>,
731 vec_trusts: &mut [Trust]
732) -> Result<(), Box<dyn Error>> {
733 if !&vec_trusts[0].target_domain_sid().to_string().contains("SID") {
734 let mut trusts: Vec<Trust> = Vec::new();
735 for trust in vec_trusts {
736 trusts.push(trust.to_owned());
737 let mut new_domain = Domain::new();
738 *new_domain.object_identifier_mut() = trust.target_domain_sid().to_string();
739 *new_domain.properties_mut().name_mut() = trust.target_domain_name().to_string();
740 *new_domain.properties_mut().domain_mut() = trust.target_domain_name().to_string();
741 *new_domain.properties_mut().distinguishedname_mut() = domain_to_dc(trust.target_domain_name());
742 *new_domain.properties_mut().highvalue_mut() = true;
743 vec_domains.push(new_domain);
744 }
745 *vec_domains[0].trusts_mut() = trusts.to_owned();
746 }
747 Ok(())
748}
749
750pub fn add_type_for_ace<T: LdapObject>(
752 object: &mut [T],
753 sid_type: &HashMap<String, String>,
754) -> Result<(), Box<dyn Error>> {
755 let total = object.len();
757 let pb = ProgressBar::new(total as u64);
758
759 let default_type = "Group".to_string();
761
762 for (count, obj) in object.iter_mut().enumerate() {
764 if count % (total / 100).max(1) == 0 {
766 pb.set_position(count as u64);
767 }
768
769 for ace in obj.get_aces_mut() {
771 let type_object = sid_type
773 .get(ace.principal_sid())
774 .unwrap_or(&default_type)
775 .clone();
776
777 *ace.principal_type_mut() = type_object;
779 }
780 }
781
782 pb.finish_and_clear();
783 Ok(())
784}
785
786pub fn add_type_for_allowtedtoact(
788 computer: &mut [Computer],
789 sid_type: &HashMap<String, String>,
790) -> Result<(), Box<dyn Error>> {
791 let total = computer.len();
793 let pb = ProgressBar::new(total as u64);
794
795 let default_type = "Computer".to_string();
797
798 for (count, comp) in computer.iter_mut().enumerate() {
800 if count % (total / 100).max(1) == 0 {
802 pb.set_position(count as u64);
803 }
804
805 for allowed in comp.allowed_to_act_mut() {
807 let type_object = sid_type
808 .get(allowed.object_identifier())
809 .unwrap_or(&default_type)
810 .clone();
811
812 *allowed.object_type_mut() = type_object;
813 }
814 }
815
816 pb.finish_and_clear();
817 Ok(())
818}
819
820pub fn add_contained_by_for<T: LdapObject>(
822 vec_replaced: &mut [T],
823 dn_sid: &HashMap<String, String>,
824 sid_type: &HashMap<String, String>,
825) -> Result<(), Box<dyn Error>> {
826 let total = vec_replaced.len();
828 let pb = ProgressBar::new(total as u64);
829
830 let default_type = "Group".to_string();
832
833 for (count, object) in vec_replaced.iter_mut().enumerate() {
834 if count % (total / 100).max(1) == 0 {
836 pb.set_position(count as u64);
837 }
838
839 let sid = object.get_object_identifier();
841 let dn = dn_sid.iter().find_map(|(key, value)| if value == sid { Some(key) } else { None });
842
843 if let Some(dn) = dn {
844 let otype = sid_type.get(sid).unwrap_or(&default_type);
845
846 if otype != "Domain" {
847 let cn_name = get_cn_object_name_from_full_distinguishedname(dn);
849 let contained_by_name = get_contained_by_name_from_distinguishedname(&cn_name, dn);
850
851 if let Some(sid_contained_by) = dn_sid.get(&contained_by_name) {
853 let type_contained_by = sid_type.get(sid_contained_by).unwrap_or(&default_type);
854
855 let mut contained_by = Member::new();
857 *contained_by.object_identifier_mut() = sid_contained_by.to_string();
858 *contained_by.object_type_mut() = type_contained_by.to_string();
859 object.set_contained_by(Some(contained_by));
860 }
861 }
862 }
863 }
864
865 pb.finish_and_clear();
866 Ok(())
867}
868
869pub fn get_name_from_full_distinguishedname(dn_object: &str) -> String {
871 trace!("get_name_from_full_distinguishedname() {:?}",&dn_object);
874 let split1 = dn_object.split(",");
875 let vec1 = split1.collect::<Vec<&str>>();
876 let split2 = vec1[0].split("=");
877 let vec2 = split2.collect::<Vec<&str>>();
878 let name = vec2[1].to_owned();
879 name
881}
882
883fn get_cn_object_name_from_full_distinguishedname(dn_object: &String) -> String {
885 let name = dn_object.to_owned();
888 let split = name.split(",");
889 let vec = split.collect::<Vec<&str>>();
890 let name = vec[0].to_owned();
891 name
893}
894
895fn get_contained_by_name_from_distinguishedname(cn_name: &str, dn_object: &str) -> String {
897 let name = format!("{},",cn_name);
900 let split = dn_object.split(&name);
901 let vec = split.collect::<Vec<&str>>();
902 let dn_contained_by = vec[1].to_owned();
903 dn_contained_by
905}
906
907#[cfg(test)]
910mod tests {
911
912 use crate::json::checker::common::{
913 get_name_from_full_distinguishedname,
914 get_cn_object_name_from_full_distinguishedname,
915 get_contained_by_name_from_distinguishedname
916 };
917
918 #[test]
919 #[rustfmt::skip]
920 pub fn test_get_name_from_full_distinguishedname() {
921 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
924 let cn_name = get_name_from_full_distinguishedname(&dn_object);
925 println!("dn_object: {:?}",dn_object);
926 println!("cn_name: {:?}",cn_name);
927 assert_eq!(cn_name, "G0H4N".to_string());
928 }
929
930 #[test]
931 #[rustfmt::skip]
932 pub fn test_get_cn_object_name_from_full_distinguishedname() {
933 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
936 let cn_name = get_cn_object_name_from_full_distinguishedname(&dn_object);
937 println!("dn_object: {:?}",dn_object);
938 println!("cn_name: {:?}",cn_name);
939 assert_eq!(cn_name, "CN=G0H4N".to_string());
940 }
941
942 #[test]
943 #[rustfmt::skip]
944 pub fn test_get_contained_by_name_from_name() {
945 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
948 let cn_name = "CN=G0H4N".to_string();
949 let contained_by_dn = get_contained_by_name_from_distinguishedname(&cn_name, &dn_object);
950 println!("dn_object: {:?}",dn_object);
951 println!("contained_by_dn: {:?}",contained_by_dn);
952 assert_eq!(contained_by_dn, "CN=USERS,DC=ESSOS,DC=LOCAL".to_string());
953 }
954}