pub fn parse(b: &[u8]) -> Result<SecurityDescriptor, SddlError>Expand description
Parse a self-relative SECURITY_DESCRIPTOR. Offsets are from the start of b. Never panics
on malformed / hostile input — returns SddlError instead.
Examples found in repository?
examples/parse_sd.rs (line 20)
9fn main() {
10 let bytes = match std::env::args().nth(1) {
11 Some(hex) => (0..hex.len())
12 .step_by(2)
13 .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).expect("hex"))
14 .collect::<Vec<u8>>(),
15 None => {
16 windows_sddl::build_rbcd_sd(&windows_sddl::Sid::parse("S-1-5-21-1-2-3-1104").unwrap())
17 }
18 };
19
20 let sd = parse(&bytes).expect("parse security descriptor");
21 if let Some(o) = &sd.owner {
22 println!("owner: {o}");
23 }
24 for ace in sd.dacl.iter().flat_map(|d| &d.aces) {
25 if !ace.is_allow() {
26 continue;
27 }
28 let mut notes = Vec::new();
29 if ace.mask.contains(AccessMask::GENERIC_ALL) {
30 notes.push("GenericAll".to_string());
31 }
32 if ace.mask.contains(AccessMask::WRITE_DAC) {
33 notes.push("WriteDacl".to_string());
34 }
35 if ace.mask.contains(AccessMask::WRITE_OWNER) {
36 notes.push("WriteOwner".to_string());
37 }
38 if let Some(g) = &ace.object_type {
39 if rights::is_dcsync_right(g) {
40 notes.push("DCSync".to_string());
41 }
42 if rights::is_enrollment_right(g) {
43 notes.push("Cert-Enrollment".to_string());
44 }
45 if rights::KEY_CREDENTIAL_LINK.matches(g) {
46 notes.push("Shadow-Credentials".to_string());
47 }
48 if rights::RBCD_ATTR.matches(g) {
49 notes.push("RBCD".to_string());
50 }
51 }
52 if !notes.is_empty() {
53 println!(" {} → {}", ace.trustee, notes.join(", "));
54 }
55 }
56}