1use binrw::prelude::*;
4
5use crate::binrw_util::prelude::*;
6
7use super::ACE;
8
9#[binrw::binrw]
10#[derive(Debug, PartialEq, Eq, Clone)]
11pub struct ACL {
12 pub acl_revision: AclRevision,
13 #[bw(calc = 0)]
14 #[br(temp)]
15 #[br(assert(sbz1 == 0))]
16 sbz1: u8,
17 #[bw(calc = PosMarker::default())]
18 #[br(temp)]
19 _acl_size: PosMarker<u16>,
20 #[bw(calc = ace.len() as u16)]
21 #[br(temp)]
22 ace_count: u16,
23 #[bw(calc = 0)]
24 #[br(temp)]
25 #[br(assert(sbz2 == 0))]
26 sbz2: u16,
27
28 #[br(count = ace_count)]
29 #[bw(write_with = PosMarker::write_size_plus, args(&_acl_size, Self::HEADER_SIZE))]
30 pub ace: Vec<ACE>,
31}
32
33impl ACL {
34 const HEADER_SIZE: u64 = 8;
35
36 pub fn order_aces(&mut self) {
49 self.ace.sort_by(Self::sort_aces_by);
50 }
51
52 pub fn is_ace_sorted(&self) -> bool {
56 self.ace
57 .is_sorted_by(|a, b| Self::sort_aces_by(a, b).is_le())
58 }
59
60 fn sort_aces_by(a: &ACE, b: &ACE) -> std::cmp::Ordering {
64 let a_inherited = a.ace_flags.inherited();
65 let b_inherited = b.ace_flags.inherited();
66 if a_inherited != b_inherited {
67 return a_inherited.cmp(&b_inherited); }
69 if a_inherited {
70 return std::cmp::Ordering::Equal; }
72 let a_denied = a.value.is_access_allowed();
73 let b_denied = b.value.is_access_allowed();
74 a_denied.cmp(&b_denied) }
77
78 pub fn insert_ace(&mut self, ace: ACE) {
81 self.ace.push(ace);
82 self.order_aces();
83 }
84}
85
86#[binrw::binrw]
87#[derive(Debug, PartialEq, Eq, Copy, Clone)]
88#[brw(repr(u8))]
89pub enum AclRevision {
90 Nt4 = 2,
92 DS = 4,
94}
95
96#[cfg(test)]
97mod tests {
98 use crate::security::{AccessAce, AccessMask, AceFlags, AceValue, SID};
99 use std::str::FromStr;
100
101 use super::*;
102 #[test]
103 fn test_sort_acls() {
104 let fake_access_ace = AccessAce {
105 access_mask: AccessMask::new(),
106 sid: SID::from_str(SID::S_EVERYONE).unwrap(),
107 };
108 let explicit_deny_first = ACE {
109 ace_flags: AceFlags::new().with_inherited(false),
110 value: AceValue::AccessDenied(fake_access_ace.clone()),
111 };
112 let explicit_allow_second = ACE {
113 ace_flags: AceFlags::new().with_inherited(false),
114 value: AceValue::AccessAllowed(fake_access_ace.clone()),
115 };
116 let inherited_last_1 = ACE {
118 ace_flags: AceFlags::new().with_inherited(true),
119 value: AceValue::AccessAllowed(fake_access_ace.clone()),
120 };
121 let inherited_last_2 = ACE {
122 ace_flags: AceFlags::new().with_inherited(true),
123 value: AceValue::AccessDenied(fake_access_ace.clone()),
124 };
125 let dacl = ACL {
126 acl_revision: AclRevision::Nt4,
127 ace: vec![
128 inherited_last_1.clone(), explicit_allow_second.clone(), explicit_deny_first.clone(), inherited_last_2.clone(), ],
133 };
134
135 assert!(!dacl.is_ace_sorted());
136
137 let mut new_dacl = dacl.clone();
138 new_dacl.order_aces();
139
140 assert!(new_dacl.is_ace_sorted());
141
142 assert_eq!(
143 new_dacl,
144 ACL {
145 acl_revision: AclRevision::Nt4,
146 ace: vec![
147 explicit_deny_first,
148 explicit_allow_second,
149 inherited_last_1,
150 inherited_last_2,
151 ]
152 }
153 );
154 }
155}