1use win_sd::{AccessMask, SecurityDescriptor, SecurityDescriptorBuilder, Sid};
12
13pub mod sec_info {
15 pub const OWNER: u32 = 0x0000_0001;
17 pub const GROUP: u32 = 0x0000_0002;
19 pub const DACL: u32 = 0x0000_0004;
21 pub const SACL: u32 = 0x0000_0008;
23 pub const DEFAULT: u32 = OWNER | GROUP | DACL;
25}
26
27fn default_descriptor() -> SecurityDescriptor {
30 SecurityDescriptorBuilder::new()
31 .owner(Sid::administrators())
32 .group(Sid::administrators())
33 .allow(Sid::everyone(), AccessMask::FILE_ALL_ACCESS)
34 .build()
35}
36
37pub fn query_security(stored: Option<&[u8]>, additional: u32) -> Option<Vec<u8>> {
40 let src = match stored {
41 Some(bytes) => SecurityDescriptor::from_bytes(bytes).unwrap_or_else(|_| default_descriptor()),
42 None => default_descriptor(),
43 };
44 let mut out = SecurityDescriptor::new();
45 if additional & sec_info::OWNER != 0
46 && let Some(o) = src.owner() {
47 out.set_owner(o.clone());
48 }
49 if additional & sec_info::GROUP != 0
50 && let Some(g) = src.group() {
51 out.set_group(g.clone());
52 }
53 if additional & sec_info::DACL != 0
54 && let Some(d) = src.dacl() {
55 out.set_dacl(d.clone());
56 }
57 out.to_bytes().ok()
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn default_query_is_parseable_and_has_dacl() {
66 let bytes = query_security(None, sec_info::DEFAULT).expect("encode");
67 let sd = SecurityDescriptor::from_bytes(&bytes).expect("round-trip parse");
68 assert!(sd.owner().is_some(), "owner present");
69 assert!(sd.dacl().is_some(), "DACL present");
70 }
71
72 #[test]
73 fn dacl_only_omits_owner() {
74 let bytes = query_security(None, sec_info::DACL).expect("encode");
75 let sd = SecurityDescriptor::from_bytes(&bytes).expect("parse");
76 assert!(sd.owner().is_none(), "owner omitted when not requested");
77 assert!(sd.dacl().is_some(), "DACL still present");
78 }
79
80 #[test]
81 fn stored_descriptor_round_trips() {
82 let stored = SecurityDescriptorBuilder::new()
83 .owner(Sid::local_system())
84 .allow(Sid::everyone(), AccessMask::FILE_GENERIC_READ)
85 .build()
86 .to_bytes()
87 .unwrap();
88 let out = query_security(Some(&stored), sec_info::OWNER).expect("encode");
89 let sd = SecurityDescriptor::from_bytes(&out).expect("parse");
90 assert_eq!(sd.owner(), Some(&Sid::local_system()), "stored owner preserved");
91 }
92}