1use binrw::io::TakeSeekExt;
4use binrw::prelude::*;
5use modular_bitfield::prelude::*;
6
7use crate::{binrw_util::prelude::*, guid::Guid};
8
9use super::SID;
10
11#[macro_export]
19macro_rules! access_mask {
20 (
21 $vis:vis struct $name:ident {
22 $(
23 $(#[$field_meta:meta])*
24 $field_name:ident : $field_ty:ty,
25 )*
26 }) => {
27
28 #[bitfield]
29 #[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
30 #[bw(map = |&x| Self::into_bytes(x))]
31 #[br(map = Self::from_bytes)]
32 $vis struct $name {
33 $(
35 $(#[$field_meta])*
36 pub $field_name : $field_ty,
37 )*
38
39 pub delete: bool,
40 pub read_control: bool,
41 pub write_dacl: bool,
42 pub write_owner: bool,
43
44 pub synchronize: bool,
45 #[skip]
46 __: B3,
47
48 pub access_system_security: bool,
49 pub maximum_allowed: bool,
50 #[skip]
51 __: B2,
52
53 pub generic_all: bool,
54 pub generic_execute: bool,
55 pub generic_write: bool,
56 pub generic_read: bool,
57 }
58 };
59
60}
61
62#[binrw::binrw]
63#[derive(Debug, PartialEq, Eq, Clone)]
64pub struct ACE {
65 #[bw(calc = value.get_type())]
66 pub ace_type: AceType,
67 pub ace_flags: AceFlags,
68 #[bw(calc = PosMarker::default())]
69 _ace_size: PosMarker<u16>,
70 #[br(args(ace_type))]
71 #[br(map_stream = |s| s.take_seek(_ace_size.value as u64 - Self::HEADER_SIZE))]
72 #[bw(write_with = PosMarker::write_size_plus, args(&_ace_size, Self::HEADER_SIZE))]
73 pub value: AceValue,
74}
75
76impl ACE {
77 const HEADER_SIZE: u64 = 4;
78
79 #[inline]
83 pub fn ace_type(&self) -> AceType {
84 self.value.get_type()
85 }
86}
87
88macro_rules! make_ace_value {
89 (
90 $($type:ident($val:ident),)+
91 ) => {
92 paste::paste! {
93
94#[binrw::binrw]
95#[derive(Debug, PartialEq, Eq, Clone)]
96#[br(import(ace_type: AceType))]
97pub enum AceValue {
98 $(
99 #[br(pre_assert(matches!(ace_type, AceType::$type)))]
100 $type($val),
101 )+
102}
103
104impl AceValue {
105 pub fn get_type(&self) -> AceType {
106 match self {
107 $(
108 AceValue::$type(_) => AceType::$type,
109 )+
110 }
111 }
112
113 $(
114 pub fn [<unwrap_ $type:snake>](&self) -> &$val {
115 match self {
116 AceValue::$type(v) => v,
117 _ => panic!("Called unwrap_{} on a different AceValue variant", stringify!($type).to_lowercase()),
118 }
119 }
120
121 pub fn [<as_ $type:snake>](&self) -> Option<&$val> {
122 match self {
123 AceValue::$type(v) => Some(v),
124 _ => None,
125 }
126 }
127
128 pub fn [<as_mut_ $type:snake>](&mut self) -> Option<&mut $val> {
129 match self {
130 AceValue::$type(v) => Some(v),
131 _ => None,
132 }
133 }
134 )+
135}
136
137 }
138 };
139}
140
141make_ace_value! {
142 AccessAllowed(AccessAce),
143 AccessDenied(AccessAce),
144 SystemAudit(AccessAce),
145 AccessAllowedObject(AccessObjectAce),
146 AccessDeniedObject(AccessObjectAce),
147 SystemAuditObject(AccessObjectAce),
148 AccessAllowedCallback(AccessCallbackAce),
149 AccessDeniedCallback(AccessCallbackAce),
150 AccessAllowedCallbackObject(AccessObjectCallbackAce),
151 AccessDeniedCallbackObject(AccessObjectCallbackAce),
152 SystemAuditCallback(AccessCallbackAce),
153 SystemAuditCallbackObject(AccessObjectCallbackAce),
154 SystemMandatoryLabel(SystemMandatoryLabelAce),
155 SystemResourceAttribute(SystemResourceAttributeAce),
156 SystemScopedPolicyId(AccessAce),
157}
158
159impl AceValue {
160 pub fn is_access_allowed(&self) -> bool {
162 matches!(
163 self.get_type(),
164 AceType::AccessAllowed
165 | AceType::AccessAllowedObject
166 | AceType::AccessAllowedCallback
167 | AceType::AccessAllowedCallbackObject
168 )
169 }
170
171 pub fn is_access_denied(&self) -> bool {
173 matches!(
174 self.get_type(),
175 AceType::AccessDenied
176 | AceType::AccessDeniedObject
177 | AceType::AccessDeniedCallback
178 | AceType::AccessDeniedCallbackObject
179 )
180 }
181}
182
183#[binrw::binrw]
184#[derive(Debug, PartialEq, Eq, Clone)]
185pub struct AccessAce {
186 pub access_mask: AccessMask,
187 pub sid: SID,
188}
189
190access_mask! {
191pub struct AccessMask {
192 common: B16,
193}}
194
195access_mask! {
196pub struct ObjectAccessMask {
197 crate_child: bool,
198 delete_child: bool,
199 #[skip]
200 __: bool,
201 ds_self: bool,
202
203 read_prop: bool,
204 write_prop: bool,
205 #[skip]
206 __: B2,
207
208 control_access: bool,
209 #[skip]
210 __: B7,
211}}
212
213access_mask! {
214pub struct MandatoryLabelAccessMask {
215 no_write_up: bool,
216 no_read_up: bool,
217 no_execute_up: bool,
218 #[skip]
219 __: B13,
220}}
221
222#[binrw::binrw]
223#[derive(Debug, PartialEq, Eq, Clone)]
224pub struct AccessObjectAce {
225 pub access_mask: ObjectAccessMask,
226 #[bw(calc = ObjectAceFlags::new().with_object_type_present(object_type.is_some()).with_inherited_object_type_present(inherited_object_type.is_some()))]
227 pub flags: ObjectAceFlags,
228 #[br(if(flags.object_type_present()))]
229 pub object_type: Option<Guid>,
230 #[br(if(flags.inherited_object_type_present()))]
231 pub inherited_object_type: Option<Guid>,
232 pub sid: SID,
233}
234
235#[bitfield]
236#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
237#[bw(map = |&x| Self::into_bytes(x))]
238#[br(map = Self::from_bytes)]
239pub struct ObjectAceFlags {
240 pub object_type_present: bool,
241 pub inherited_object_type_present: bool,
242 #[skip]
243 __: B30,
244}
245
246#[binrw::binrw]
247#[derive(Debug, PartialEq, Eq, Clone)]
248pub struct AccessCallbackAce {
249 pub access_mask: AccessMask,
250 pub sid: SID,
251 #[br(parse_with = binrw::helpers::until_eof)]
252 pub application_data: Vec<u8>,
253}
254
255#[binrw::binrw]
256#[derive(Debug, PartialEq, Eq, Clone)]
257pub struct AccessObjectCallbackAce {
258 pub access_mask: ObjectAccessMask,
259 #[bw(calc = ObjectAceFlags::new().with_object_type_present(object_type.is_some()).with_inherited_object_type_present(inherited_object_type.is_some()))]
260 pub flags: ObjectAceFlags,
261 #[br(if(flags.object_type_present()))]
262 pub object_type: Option<Guid>,
263 #[br(if(flags.inherited_object_type_present()))]
264 pub inherited_object_type: Option<Guid>,
265 pub sid: SID,
266 #[br(parse_with = binrw::helpers::until_eof)]
267 pub application_data: Vec<u8>,
268}
269
270#[binrw::binrw]
271#[derive(Debug, PartialEq, Eq, Clone)]
272pub struct SystemMandatoryLabelAce {
273 pub mask: MandatoryLabelAccessMask,
274 pub sid: SID,
275}
276#[binrw::binrw]
277#[derive(Debug, PartialEq, Eq, Clone)]
278pub struct SystemResourceAttributeAce {
279 pub mask: AccessMask,
280 pub sid: SID,
281 pub attribute_data: ClaimSecurityAttributeRelativeV1,
282}
283
284#[binrw::binrw]
285#[derive(Debug, PartialEq, Eq, Clone)]
286pub struct ClaimSecurityAttributeRelativeV1 {
287 #[bw(calc = PosMarker::default())]
288 _name: PosMarker<u32>, pub value_type: ClaimSecurityAttributeType,
290 #[bw(calc = 0)]
291 #[br(assert(reserved == 0))]
292 reserved: u16,
293 pub flags: FciClaimSecurityAttributes,
294 value_count: u32,
295 #[br(parse_with = binrw::helpers::until_eof)]
296 pub value: Vec<u8>, }
298
299#[binrw::binrw]
300#[derive(Debug, PartialEq, Eq, Clone, Copy)]
301#[brw(repr(u16))]
302pub enum ClaimSecurityAttributeType {
303 None = 0,
304 Int64 = 1,
305 Uint64 = 2,
306 String = 3,
307 SID = 4,
308 Boolean = 5,
309 OctetString = 6,
310}
311
312#[bitfield]
313#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
314#[bw(map = |&x| Self::into_bytes(x))]
315#[br(map = Self::from_bytes)]
316pub struct FciClaimSecurityAttributes {
317 pub non_inheritable: bool,
318 pub value_case_sensitive: bool,
319 pub use_for_deny_only: bool,
320 pub disabled_by_default: bool,
321
322 pub disabled: bool,
323 pub mandatory: bool,
324 #[skip]
325 __: B2,
326
327 pub manual: bool,
328 pub policy_derived: bool,
329 #[skip]
330 __: B6,
331}
332
333#[binrw::binrw]
334#[derive(Debug, PartialEq, Eq, Clone, Copy)]
335#[brw(repr(u8))]
336pub enum AceType {
337 AccessAllowed = 0,
338 AccessDenied = 1,
339 SystemAudit = 2,
340 SystemAlarm = 3,
341 AccessAllowedCompound = 4,
342 AccessAllowedObject = 5,
343 AccessDeniedObject = 6,
344 SystemAuditObject = 7,
345 SystemAlarmObject = 8,
346 AccessAllowedCallback = 9,
347 AccessDeniedCallback = 10,
348 AccessAllowedCallbackObject = 11,
349 AccessDeniedCallbackObject = 12,
350 SystemAuditCallback = 13,
351 SystemAlarmCallback = 14,
352 SystemAuditCallbackObject = 15,
353 SystemAlarmCallbackObject = 16,
354 SystemMandatoryLabel = 17,
355 SystemResourceAttribute = 18,
356 SystemScopedPolicyId = 19,
357}
358
359#[bitfield]
360#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
361#[bw(map = |&x| Self::into_bytes(x))]
362#[br(map = Self::from_bytes)]
363pub struct AceFlags {
364 pub object_inherit: bool,
365 pub container_inherit: bool,
366 pub no_propagate_inherit: bool,
367 pub inherit_only: bool,
368
369 pub inherited: bool,
370 #[skip]
371 __: bool,
372 pub successful_access: bool,
373 pub failed_access: bool,
374}