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;
20use indicatif::ProgressBar;
21
22pub fn add_default_groups(
25 vec_groups: &mut Vec<Group>,
26 vec_computers: &[Computer],
27 domain: String
28) -> Result<(), Box<dyn Error>> {
29 let mut domain_sid = "".to_owned();
30 let mut template_member = Member::new();
31 *template_member.object_type_mut() = "Computer".to_string();
32
33 let mut edc_group = Group::new();
35 let mut sid = domain.to_uppercase();
36 sid.push_str("-S-1-5-9");
37
38 let mut name = "ENTERPRISE DOMAIN CONTROLLERS@".to_owned();
39 name.push_str(&domain.to_uppercase());
40
41 let mut vec_members: Vec<Member> = Vec::new();
42 for computer in vec_computers {
43 if computer.properties().get_is_dc().to_owned()
44 {
45 *template_member.object_identifier_mut() = computer.object_identifier().clone();
55 vec_members.push(template_member.clone());
56 if let Some(capture) = COMMON_RE1.captures(computer.object_identifier()) {
57 domain_sid = capture.get(0).map(|m| m.as_str().to_string()).unwrap_or_default();
58 }
59 }
60 }
61
62 *edc_group.object_identifier_mut() = sid;
63 *edc_group.properties_mut().name_mut() = name;
64 *edc_group.members_mut() = vec_members;
65 vec_groups.push(edc_group);
66
67 let mut account_operators_group = Group::new();
69 sid = domain.to_uppercase();
70 sid.push_str("-S-1-5-32-548");
71 let mut name = "ACCOUNT OPERATORS@".to_owned();
72 name.push_str(&domain.to_uppercase());
73
74 *account_operators_group.object_identifier_mut() = sid;
75 *account_operators_group.properties_mut().name_mut() = name;
76 *account_operators_group.properties_mut().highvalue_mut() = true;
77 vec_groups.push(account_operators_group);
78
79 let mut waag_group = Group::new();
81 sid = domain.to_uppercase();
82 sid.push_str("-S-1-5-32-560");
83 let mut name = "WINDOWS AUTHORIZATION ACCESS GROUP@".to_owned();
84 name.push_str(&domain.to_uppercase());
85 *waag_group.object_identifier_mut() = sid;
86 *waag_group.properties_mut().name_mut() = name;
87 vec_groups.push(waag_group);
88
89 let mut everyone_group = Group::new();
91 sid = domain.to_uppercase();
92 sid.push_str("-S-1-1-0");
93 let mut name = "EVERYONE@".to_owned();
94 name.push_str(&domain.to_uppercase());
95
96 let mut vec_everyone_members: Vec<Member> = Vec::new();
97 let mut member_id = domain_sid.to_owned();
98 member_id.push_str("-515");
99 *template_member.object_identifier_mut() = member_id.to_owned();
100 *template_member.object_type_mut() = "Group".to_string();
101 vec_everyone_members.push(template_member.to_owned());
102
103 member_id = domain_sid.to_owned();
104 member_id.push_str("-513");
105 *template_member.object_identifier_mut() = member_id.to_owned();
106 *template_member.object_type_mut() = "Group".to_string();
107 vec_everyone_members.push(template_member.to_owned());
108
109 *everyone_group.object_identifier_mut() = sid;
110 *everyone_group.properties_mut().name_mut() = name;
111 *everyone_group.members_mut() = vec_everyone_members;
112 vec_groups.push(everyone_group);
113
114 let mut auth_users_group = Group::new();
116 sid = domain.to_uppercase();
117 sid.push_str("-S-1-5-11");
118 let mut name = "AUTHENTICATED USERS@".to_owned();
119 name.push_str(&domain.to_uppercase());
120
121 let mut vec_auth_users_members: Vec<Member> = Vec::new();
122 member_id = domain_sid.to_owned();
123 member_id.push_str("-515");
124 *template_member.object_identifier_mut() = member_id.to_owned();
125 *template_member.object_type_mut() = "Group".to_string();
126 vec_auth_users_members.push(template_member.to_owned());
127
128 member_id = domain_sid.to_owned();
129 member_id.push_str("-513");
130 *template_member.object_identifier_mut() = member_id.to_owned();
131 *template_member.object_type_mut() = "Group".to_string();
132 vec_auth_users_members.push(template_member.to_owned());
133
134 *auth_users_group.object_identifier_mut() = sid;
135 *auth_users_group.properties_mut().name_mut() = name;
136 *auth_users_group.members_mut() = vec_auth_users_members;
137 vec_groups.push(auth_users_group);
138
139 let mut administrators_group = Group::new();
141 sid = domain.to_uppercase();
142 sid.push_str("-S-1-5-32-544");
143 let mut name = "ADMINISTRATORS@".to_owned();
144 name.push_str(&domain.to_uppercase());
145
146 *administrators_group.object_identifier_mut() = sid;
147 *administrators_group.properties_mut().name_mut() = name;
148 *administrators_group.properties_mut().highvalue_mut() = true;
149 vec_groups.push(administrators_group);
150
151 let mut pw2000ca_group = Group::new();
153 sid = domain.to_uppercase();
154 sid.push_str("-S-1-5-32-554");
155 let mut name = "PRE-WINDOWS 2000 COMPATIBLE ACCESS@".to_owned();
156 name.push_str(&domain.to_uppercase());
157
158 *pw2000ca_group.object_identifier_mut() = sid;
159 *pw2000ca_group.properties_mut().name_mut() = name;
160 vec_groups.push(pw2000ca_group);
161
162 let mut interactive_group = Group::new();
164 sid = domain.to_uppercase();
165 sid.push_str("-S-1-5-4");
166 let mut name = "INTERACTIVE@".to_owned();
167 name.push_str(&domain.to_uppercase());
168
169 *interactive_group.object_identifier_mut() = sid;
170 *interactive_group.properties_mut().name_mut() = name;
171 vec_groups.push(interactive_group);
172
173 let mut print_operators_group = Group::new();
175 sid = domain.to_uppercase();
176 sid.push_str("-S-1-5-32-550");
177 let mut name = "PRINT OPERATORS@".to_owned();
178 name.push_str(&domain.to_uppercase());
179
180 *print_operators_group.object_identifier_mut() = sid;
181 *print_operators_group.properties_mut().name_mut() = name;
182 *print_operators_group.properties_mut().highvalue_mut() = true;
183 vec_groups.push(print_operators_group);
184
185 let mut tsls_group = Group::new();
187 sid = domain.to_uppercase();
188 sid.push_str("-S-1-5-32-561");
189 let mut name = "TERMINAL SERVER LICENSE SERVERS@".to_owned();
190 name.push_str(&domain.to_uppercase());
191
192 *tsls_group.object_identifier_mut() = sid;
193 *tsls_group.properties_mut().name_mut() = name;
194 vec_groups.push(tsls_group);
195
196 let mut iftb_group = Group::new();
198 sid = domain.to_uppercase();
199 sid.push_str("-S-1-5-32-557");
200 let mut name = "INCOMING FOREST TRUST BUILDERS@".to_owned();
201 name.push_str(&domain.to_uppercase());
202
203 *iftb_group.object_identifier_mut() = sid;
204 *iftb_group.properties_mut().name_mut() = name;
205 vec_groups.push(iftb_group);
206
207 let mut this_organization_group = Group::new();
209 sid = domain.to_uppercase();
210 sid.push_str("-S-1-5-15");
211 let mut name = "THIS ORGANIZATION@".to_owned();
212 name.push_str(&domain.to_uppercase());
213
214 *this_organization_group.object_identifier_mut() = sid;
215 *this_organization_group.properties_mut().name_mut() = name;
216 vec_groups.push(this_organization_group);
217 Ok(())
218}
219
220pub fn add_default_users(
223 vec_users: &mut Vec<User>,
224 domain: String
225) -> Result<(), Box<dyn Error>> {
226 let mut ntauthority_user = User::new();
228 let mut sid = domain.to_uppercase();
229 sid.push_str("-S-1-5-20");
230 let mut name = "NT AUTHORITY@".to_owned();
231 name.push_str(&domain.to_uppercase());
232 *ntauthority_user.properties_mut().name_mut() = name;
233 *ntauthority_user.object_identifier_mut() = sid;
234 *ntauthority_user.properties_mut().domainsid_mut() = vec_users[0].properties().domainsid().to_string();
235 vec_users.push(ntauthority_user);
236 Ok(())
237}
238
239pub fn add_childobjects_members<T: LdapObject>(
241 vec_replaced: &mut [T],
242 dn_sid: &HashMap<String, String>,
243 sid_type: &HashMap<String, String>,
244) -> Result<(), Box<dyn Error>> {
245 let total = vec_replaced.len();
247 let pb = ProgressBar::new(total as u64);
248
249 let null: String = "NULL".to_string();
251
252 for (count, object) in vec_replaced.iter_mut().enumerate() {
254 if count % (total / 100).max(1) == 0 {
256 pb.set_position(count as u64);
257 }
258
259 let sid = object.get_object_identifier().to_uppercase();
261 let dn = dn_sid
262 .iter()
263 .find(|(_, v)| **v == sid)
264 .map(|(k, _)| k)
265 .unwrap_or(&null);
266 let name = get_name_from_full_distinguishedname(dn);
267 let _otype = sid_type.get(&sid).unwrap();
268
269 let direct_members: Vec<Member> = dn_sid
271 .iter()
272 .filter_map(|(dn_object, value_sid)| {
273 let dn_object_upper = dn_object.to_uppercase();
274
275 if dn_object_upper.contains(dn)
277 && &dn_object_upper != dn
278 && dn_object_upper.split(',')
279 .nth(1)
280 .and_then(|s| s.split('=').nth(1))
281 == Some(&name)
282 {
283 let mut member = Member::new();
284 *member.object_identifier_mut() = value_sid.clone();
285 *member.object_type_mut() = sid_type.get(value_sid).unwrap_or(&null).to_string();
286 if !member.object_identifier().is_empty() {
287 return Some(member);
288 }
289 }
290 None
291 })
292 .collect();
293
294 object.set_child_objects(direct_members);
296 }
297
298 pb.finish_and_clear();
299 Ok(())
300}
301
302pub fn add_childobjects_members_for_ou(
304 vec_replaced: &mut [Ou],
305 dn_sid: &HashMap<String, String>,
306 sid_type: &HashMap<String, String>,
307) -> Result<(), Box<dyn Error>> {
308 let total = vec_replaced.len();
310 let pb = ProgressBar::new(total as u64);
311
312 let null = "NULL".to_string();
314
315 for (count, object) in vec_replaced.iter_mut().enumerate() {
316 if count % (total / 100).max(1) == 0 {
318 pb.set_position(count as u64);
319 }
320
321 let mut direct_members = Vec::new();
322 let mut affected_computers = Vec::new();
323
324 let dn = object.properties().distinguishedname();
326 let mut name = object.properties().name().to_owned();
327 let sid = dn_sid.get(dn).unwrap_or(&null);
328 let otype = sid_type.get(sid).unwrap_or(&null);
329
330 if otype != "Domain" {
332 if let Some(first_part) = name.split('@').next() {
333 name = first_part.to_string();
334 }
335 }
336
337 for (dn_object, value_sid) in dn_sid {
339 let dn_object_upper = dn_object.to_uppercase();
340
341 let first = dn_object_upper
343 .split(',')
344 .nth(1)
345 .and_then(|part| part.split('=').nth(1))
346 .unwrap_or("");
347
348 if otype != "Domain" {
349 if dn_object_upper.contains(dn) && &dn_object_upper != dn && first == name {
351 let mut member = Member::new();
352 *member.object_identifier_mut() = value_sid.clone();
353 let object_type = sid_type.get(value_sid).unwrap_or(&null).to_string();
354 *member.object_type_mut() = object_type.clone();
355
356 direct_members.push(member.clone());
357
358 if object_type == "Computer" {
360 affected_computers.push(member);
361 }
362 }
363 } else {
364 if let Some(cn) = name.split('.').next() {
366 if first.contains(cn) {
367 let mut member = Member::new();
368 *member.object_identifier_mut() = value_sid.clone();
369 *member.object_type_mut() = sid_type.get(value_sid).unwrap_or(&null).to_string();
370 direct_members.push(member);
371 }
372 }
373 }
374 }
375
376 *object.child_objects_mut() = direct_members;
378 if otype == "OU" {
379 let mut gpo_changes = GPOChange::new();
380 *gpo_changes.affected_computers_mut() = affected_computers;
381 *object.gpo_changes_mut() = gpo_changes;
382 }
383 }
384
385 pb.finish_and_clear();
386 Ok(())
387}
388
389pub fn replace_guid_gplink<T: LdapObject>(
391 vec_replaced: &mut [T],
392 dn_sid: &HashMap<String, String>,
393) -> Result<(), Box<dyn Error>> {
394 let total = vec_replaced.len();
396 let pb = ProgressBar::new(total as u64);
397
398 for (count, object) in vec_replaced.iter_mut().enumerate() {
400 if count % (total / 100).max(1) == 0 {
402 pb.set_position(count as u64);
403 }
404
405 if !object.get_links().is_empty() {
407 let updated_links: Vec<Link> = object
409 .get_links()
410 .iter()
411 .map(|link| {
412 let mut new_link = link.clone(); if let Some(new_guid) = dn_sid
414 .iter()
415 .find(|(key, _)| key.contains(link.guid()))
416 .map(|(_, guid)| guid.to_owned())
417 {
418 *new_link.guid_mut() = new_guid;
419 }
420 new_link
421 })
422 .collect();
423
424 object.set_links(updated_links);
426 }
427 }
428
429 pb.finish_and_clear();
430 Ok(())
431}
432
433pub fn add_affected_computers(
435 vec_domains: &mut [Domain],
436 sid_type: &HashMap<String, String>,
437) -> Result<(), Box<dyn Error>> {
438 let vec_affected_computers: Vec<Member> = sid_type
440 .iter()
441 .filter(|&(_, obj_type)| obj_type == "Computer")
442 .map(|(sid, _)| {
443 let mut member = Member::new();
444 *member.object_type_mut() = "Computer".to_string();
445 *member.object_identifier_mut() = sid.clone();
446 member
447 })
448 .collect();
449
450 if let Some(domain) = vec_domains.get_mut(0) {
452 let mut gpo_changes = GPOChange::new();
453 *gpo_changes.affected_computers_mut() = vec_affected_computers;
454 *domain.gpo_changes_mut() = gpo_changes;
455 }
456 Ok(())
457}
458
459pub fn add_affected_computers_for_ou(
461 vec_ous: &mut [Ou],
462 dn_sid: &HashMap<String, String>,
463 sid_type: &HashMap<String, String>,
464) -> Result<(), Box<dyn Error>> {
465 let dn_sid_filtered: Vec<(&String, &String)> = dn_sid
467 .iter()
468 .filter(|(_, sid)| sid_type.get(*sid).map(|t| t == "Computer").unwrap_or(false))
469 .collect();
470
471 let ou_dn_map: HashMap<String, String> = vec_ous
473 .iter()
474 .filter_map(|ou| {
475 dn_sid
476 .iter()
477 .find_map(|(dn, sid)| {
478 if *sid == *ou.get_object_identifier() {
479 Some((ou.get_object_identifier().to_owned(), dn.clone()))
480 } else {
481 None
482 }
483 })
484 })
485 .collect();
486
487 for ou in vec_ous.iter_mut() {
489 if let Some(ou_dn) = ou_dn_map.get(ou.get_object_identifier()) {
490 let vec_affected_computers: Vec<Member> = dn_sid_filtered
491 .iter()
492 .filter_map(|(dn, sid)| {
493 if get_contained_by_name_from_distinguishedname(
494 &get_cn_object_name_from_full_distinguishedname(dn),
495 dn,
496 ) == *ou_dn
497 {
498 let mut member = Member::new();
499 *member.object_identifier_mut() = sid.to_string();
500 *member.object_type_mut() = "Computer".to_string();
501 Some(member)
502 } else {
503 None
504 }
505 })
506 .collect();
507
508 let mut gpo_changes = GPOChange::new();
510 *gpo_changes.affected_computers_mut() = vec_affected_computers;
511 *ou.gpo_changes_mut() = gpo_changes;
512 }
513 }
514 Ok(())
515}
516
517pub fn replace_fqdn_by_sid<T: LdapObject>(
519 object_type: Type,
520 vec_src: &mut [T],
521 fqdn_sid: &HashMap<String, String>,
522) -> Result<(), Box<dyn Error>> {
523 let total = vec_src.len();
525 let pb = ProgressBar::new(total as u64);
526
527 match object_type {
529 Type::User => {
530 for (count, obj) in vec_src.iter_mut().enumerate() {
531 if count % (total / 100).max(1) == 0 {
533 pb.set_position(count as u64);
534 }
535
536 for target in obj.get_spntargets_mut().iter_mut() {
538 let sid = fqdn_sid
539 .get(target.computer_sid())
540 .unwrap_or_else(|| target.computer_sid());
541 *target.computer_sid_mut() = sid.to_string();
542 }
543
544 for target in obj.get_allowed_to_delegate_mut().iter_mut() {
546 let sid = fqdn_sid
547 .get(target.object_identifier())
548 .unwrap_or_else(|| target.object_identifier());
549 *target.object_identifier_mut() = sid.to_string();
550 }
551 }
552 }
553 Type::Computer => {
554 for (count, obj) in vec_src.iter_mut().enumerate() {
555 if count % (total / 100).max(1) == 0 {
557 pb.set_position(count as u64);
558 }
559
560 for delegate in obj.get_allowed_to_delegate_mut().iter_mut() {
562 let sid = fqdn_sid
563 .get(delegate.object_identifier())
564 .unwrap_or_else(|| delegate.object_identifier());
565 *delegate.object_identifier_mut() = sid.to_string();
566 }
567 }
568 }
569 _ => {}
570 }
571
572 pb.finish_and_clear();
573 Ok(())
574}
575
576pub fn replace_sid_members(
578 vec_groups: &mut [Group],
579 dn_sid: &HashMap<String, String>,
580 sid_type: &HashMap<String, String>,
581 vec_trusts: &[Trust],
582) -> Result<(), Box<dyn Error>> {
583 let total = vec_groups.len();
585 let pb = ProgressBar::new(total as u64);
586
587 let default_sid = "NULL".to_string();
589 let default_type = "Group".to_string();
590
591 for (count, group) in vec_groups.iter_mut().enumerate() {
593 if count % (total / 100).max(1) == 0 {
595 pb.set_position(count as u64);
596 }
597
598 for member in group.members_mut() {
600 let member_dn = member.object_identifier();
601
602 let sid = dn_sid.get(member_dn).unwrap_or(&default_sid);
604 if sid == "NULL" {
605 let generated_sid = sid_maker_from_another_domain(vec_trusts, member_dn)?;
607 *member.object_identifier_mut() = generated_sid.to_owned();
608 *member.object_type_mut() = default_type.clone();
609 } else {
610 let type_object = sid_type.get(sid).unwrap_or(&default_type).to_owned();
612 *member.object_identifier_mut() = sid.to_owned();
613 *member.object_type_mut() = type_object;
614 }
615 }
616 }
617
618 pb.finish_and_clear();
619 Ok(())
620}
621
622fn sid_maker_from_another_domain(
624 vec_trusts: &[Trust],
625 object_identifier: &String,
626) -> Result<String, Box<dyn Error>> {
627 let sid_regex = Regex::new(r"S-[0-9]+-[0-9]+-[0-9]+(?:-[0-9]+)+")?;
629
630 for trust in vec_trusts {
632 let ldap_dc = prepare_ldap_dc(trust.target_domain_name());
633 if object_identifier.contains(&ldap_dc[0]) {
634 let id = get_id_from_objectidentifier(object_identifier)?;
635 return Ok(format!("{}{}", trust.target_domain_name(), id))
636 }
637 }
638
639 if object_identifier.contains("CN=S-") {
641 if let Some(capture) = sid_regex.captures(object_identifier).and_then(|cap| cap.get(0)) {
642 return Ok(capture.as_str().to_owned())
643 }
644 }
645
646 Ok(object_identifier.to_string())
648}
649
650fn get_id_from_objectidentifier(
653 object_identifier: &str
654) -> Result<String, Box<dyn Error>> {
655
656 const NAME_TO_RID: [(&str, &str); 16] = [
658 ("DOMAIN ADMINS", "-512"),
659 ("ADMINISTRATEURS DU DOMAINE", "-512"),
660 ("DOMAIN USERS", "-513"),
661 ("UTILISATEURS DU DOMAINE", "-513"),
662 ("DOMAIN GUESTS", "-514"),
663 ("INVITES DE DOMAINE", "-514"),
664 ("DOMAIN COMPUTERS", "-515"),
665 ("ORDINATEURS DE DOMAINE", "-515"),
666 ("DOMAIN CONTROLLERS", "-516"),
667 ("CONTRÔLEURS DE DOMAINE", "-516"),
668 ("CERT PUBLISHERS", "-517"),
669 ("EDITEURS DE CERTIFICATS", "-517"),
670 ("SCHEMA ADMINS", "-518"),
671 ("ADMINISTRATEURS DU SCHEMA", "-518"),
672 ("ENTERPRISE ADMINS", "-519"),
673 ("ADMINISTRATEURS DE L'ENTREPRISE", "-519"),
674 ];
675
676 for (name, rid) in NAME_TO_RID.iter() {
678 if object_identifier.contains(name) {
679 return Ok(rid.to_string())
680 }
681 }
682
683 Ok("NULL_ID1".to_string())
685}
686
687pub fn add_trustdomain(
689 vec_domains: &mut Vec<Domain>,
690 vec_trusts: &mut [Trust]
691) -> Result<(), Box<dyn Error>> {
692 if !&vec_trusts[0].target_domain_sid().to_string().contains("SID") {
693 let mut trusts: Vec<Trust> = Vec::new();
694 for trust in vec_trusts {
695 trusts.push(trust.to_owned());
696 let mut new_domain = Domain::new();
697 *new_domain.object_identifier_mut() = trust.target_domain_sid().to_string();
698 *new_domain.properties_mut().name_mut() = trust.target_domain_name().to_string();
699 *new_domain.properties_mut().domain_mut() = trust.target_domain_name().to_string();
700 *new_domain.properties_mut().distinguishedname_mut() = domain_to_dc(trust.target_domain_name());
701 *new_domain.properties_mut().highvalue_mut() = true;
702 vec_domains.push(new_domain);
703 }
704 *vec_domains[0].trusts_mut() = trusts.to_owned();
705 }
706 Ok(())
707}
708
709pub fn add_type_for_ace<T: LdapObject>(
711 object: &mut [T],
712 sid_type: &HashMap<String, String>,
713) -> Result<(), Box<dyn Error>> {
714 let total = object.len();
716 let pb = ProgressBar::new(total as u64);
717
718 let default_type = "Group".to_string();
720
721 for (count, obj) in object.iter_mut().enumerate() {
723 if count % (total / 100).max(1) == 0 {
725 pb.set_position(count as u64);
726 }
727
728 for ace in obj.get_aces_mut() {
730 let type_object = sid_type
732 .get(ace.principal_sid())
733 .unwrap_or(&default_type)
734 .clone();
735
736 *ace.principal_type_mut() = type_object;
738 }
739 }
740
741 pb.finish_and_clear();
742 Ok(())
743}
744
745pub fn add_type_for_allowtedtoact(
747 computer: &mut [Computer],
748 sid_type: &HashMap<String, String>,
749) -> Result<(), Box<dyn Error>> {
750 let total = computer.len();
752 let pb = ProgressBar::new(total as u64);
753
754 let default_type = "Computer".to_string();
756
757 for (count, comp) in computer.iter_mut().enumerate() {
759 if count % (total / 100).max(1) == 0 {
761 pb.set_position(count as u64);
762 }
763
764 for allowed in comp.allowed_to_act_mut() {
766 let type_object = sid_type
767 .get(allowed.object_identifier())
768 .unwrap_or(&default_type)
769 .clone();
770
771 *allowed.object_type_mut() = type_object;
772 }
773 }
774
775 pb.finish_and_clear();
776 Ok(())
777}
778
779pub fn add_contained_by_for<T: LdapObject>(
781 vec_replaced: &mut [T],
782 dn_sid: &HashMap<String, String>,
783 sid_type: &HashMap<String, String>,
784) -> Result<(), Box<dyn Error>> {
785 let total = vec_replaced.len();
787 let pb = ProgressBar::new(total as u64);
788
789 let default_type = "Group".to_string();
791
792 for (count, object) in vec_replaced.iter_mut().enumerate() {
793 if count % (total / 100).max(1) == 0 {
795 pb.set_position(count as u64);
796 }
797
798 let sid = object.get_object_identifier();
800 let dn = dn_sid.iter().find_map(|(key, value)| if value == sid { Some(key) } else { None });
801
802 if let Some(dn) = dn {
803 let otype = sid_type.get(sid).unwrap_or(&default_type);
804
805 if otype != "Domain" {
806 let cn_name = get_cn_object_name_from_full_distinguishedname(dn);
808 let contained_by_name = get_contained_by_name_from_distinguishedname(&cn_name, dn);
809
810 if let Some(sid_contained_by) = dn_sid.get(&contained_by_name) {
812 let type_contained_by = sid_type.get(sid_contained_by).unwrap_or(&default_type);
813
814 let mut contained_by = Member::new();
816 *contained_by.object_identifier_mut() = sid_contained_by.to_string();
817 *contained_by.object_type_mut() = type_contained_by.to_string();
818 object.set_contained_by(Some(contained_by));
819 }
820 }
821 }
822 }
823
824 pb.finish_and_clear();
825 Ok(())
826}
827
828pub fn get_name_from_full_distinguishedname(dn_object: &str) -> String {
830 let split1 = dn_object.split(",");
833 let vec1 = split1.collect::<Vec<&str>>();
834 let split2 = vec1[0].split("=");
835 let vec2 = split2.collect::<Vec<&str>>();
836 let name = vec2[1].to_owned();
837 name
839}
840
841fn get_cn_object_name_from_full_distinguishedname(dn_object: &String) -> String {
843 let name = dn_object.to_owned();
846 let split = name.split(",");
847 let vec = split.collect::<Vec<&str>>();
848 let name = vec[0].to_owned();
849 name
851}
852
853fn get_contained_by_name_from_distinguishedname(cn_name: &str, dn_object: &str) -> String {
855 let name = format!("{},",cn_name);
858 let split = dn_object.split(&name);
859 let vec = split.collect::<Vec<&str>>();
860 let dn_contained_by = vec[1].to_owned();
861 dn_contained_by
863}
864
865#[cfg(test)]
868mod tests {
869
870 use crate::json::checker::common::{
871 get_name_from_full_distinguishedname,
872 get_cn_object_name_from_full_distinguishedname,
873 get_contained_by_name_from_distinguishedname
874 };
875
876 #[test]
877 #[rustfmt::skip]
878 pub fn test_get_name_from_full_distinguishedname() {
879 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
882 let cn_name = get_name_from_full_distinguishedname(&dn_object);
883 println!("dn_object: {:?}",dn_object);
884 println!("cn_name: {:?}",cn_name);
885 assert_eq!(cn_name, "G0H4N".to_string());
886 }
887
888 #[test]
889 #[rustfmt::skip]
890 pub fn test_get_cn_object_name_from_full_distinguishedname() {
891 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
894 let cn_name = get_cn_object_name_from_full_distinguishedname(&dn_object);
895 println!("dn_object: {:?}",dn_object);
896 println!("cn_name: {:?}",cn_name);
897 assert_eq!(cn_name, "CN=G0H4N".to_string());
898 }
899
900 #[test]
901 #[rustfmt::skip]
902 pub fn test_get_contained_by_name_from_name() {
903 let dn_object = "CN=G0H4N,CN=USERS,DC=ESSOS,DC=LOCAL".to_string();
906 let cn_name = "CN=G0H4N".to_string();
907 let contained_by_dn = get_contained_by_name_from_distinguishedname(&cn_name, &dn_object);
908 println!("dn_object: {:?}",dn_object);
909 println!("contained_by_dn: {:?}",contained_by_dn);
910 assert_eq!(contained_by_dn, "CN=USERS,DC=ESSOS,DC=LOCAL".to_string());
911 }
912}