Skip to main content

dolang_winterop/security/
sec_desc.rs

1use std::{
2    borrow::Borrow,
3    error, fmt,
4    hash::{Hash, Hasher},
5    ops::Deref,
6};
7
8use serde::{
9    Deserialize, Deserializer, Serialize, Serializer,
10    de::{self, SeqAccess, Visitor},
11    ser::SerializeTuple,
12};
13
14use super::{access_mask::AccessMask, sid::Sid};
15use crate::guid::Guid;
16
17const REVISION: u8 = 1;
18
19/// A component of a Windows security descriptor.
20#[derive(Clone, Copy, Debug, PartialEq, Eq)]
21pub enum SecDescComponent {
22    /// The owner SID.
23    Owner,
24    /// The primary-group SID.
25    Group,
26    /// The discretionary ACL.
27    Dacl,
28    /// The system ACL.
29    Sacl,
30}
31
32impl fmt::Display for SecDescComponent {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        match self {
35            Self::Owner => f.write_str("owner"),
36            Self::Group => f.write_str("group"),
37            Self::Dacl => f.write_str("DACL"),
38            Self::Sacl => f.write_str("SACL"),
39        }
40    }
41}
42
43/// A security descriptor's access-control-list component.
44#[derive(Clone, Copy, Debug, PartialEq, Eq)]
45pub enum AclKind {
46    /// The discretionary ACL.
47    Dacl,
48    /// The system ACL.
49    Sacl,
50}
51
52impl AclKind {
53    const fn component(self) -> SecDescComponent {
54        match self {
55            Self::Dacl => SecDescComponent::Dacl,
56            Self::Sacl => SecDescComponent::Sacl,
57        }
58    }
59}
60
61impl fmt::Display for AclKind {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        self.component().fmt(f)
64    }
65}
66
67bitflags::bitflags! {
68    /// Security-descriptor components selected by a query or represented by a [`SecDesc`].
69    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
70    pub struct SecInfo: u32 {
71        /// Selects the owner SID.
72        const OWNER = 0x0000_0001;
73        /// Selects the primary group SID.
74        const GROUP = 0x0000_0002;
75        /// Selects the discretionary ACL.
76        const DACL = 0x0000_0004;
77        /// Selects the system ACL.
78        const SACL = 0x0000_0008;
79        /// Selects every supported security-descriptor component.
80        const ALL = Self::OWNER.bits() | Self::GROUP.bits() | Self::DACL.bits() | Self::SACL.bits();
81    }
82}
83
84bitflags::bitflags! {
85    /// Flags describing the state and storage of a security descriptor.
86    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
87    pub struct SecDescControl: u16 {
88        const OWNER_DEFAULTED = 0x0001;
89        const GROUP_DEFAULTED = 0x0002;
90        const DACL_PRESENT = 0x0004;
91        const DACL_DEFAULTED = 0x0008;
92        const SACL_PRESENT = 0x0010;
93        const SACL_DEFAULTED = 0x0020;
94        const DACL_AUTO_INHERIT_REQUIRED = 0x0100;
95        const SACL_AUTO_INHERIT_REQUIRED = 0x0200;
96        const DACL_AUTO_INHERITED = 0x0400;
97        const SACL_AUTO_INHERITED = 0x0800;
98        const DACL_PROTECTED = 0x1000;
99        const SACL_PROTECTED = 0x2000;
100        const RM_CONTROL_VALID = 0x4000;
101        const SELF_RELATIVE = 0x8000;
102    }
103}
104
105bitflags::bitflags! {
106    /// Flags stored in an ACE header.
107    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
108    pub struct AceFlags: u8 {
109        const OBJECT_INHERIT = 0x01;
110        const CONTAINER_INHERIT = 0x02;
111        const NO_PROPAGATE_INHERIT = 0x04;
112        const INHERIT_ONLY = 0x08;
113        const INHERITED = 0x10;
114        const CRITICAL = 0x20;
115        const SUCCESSFUL_ACCESS = 0x40;
116        const TRUST_PROTECTED_FILTER = 0x40;
117        const FAILED_ACCESS = 0x80;
118    }
119}
120
121bitflags::bitflags! {
122    /// Object-specific fields present in an object ACE.
123    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
124    pub struct ObjectAceFlags: u32 {
125        const OBJECT_TYPE_PRESENT = 0x1;
126        const INHERITED_OBJECT_TYPE_PRESENT = 0x2;
127    }
128}
129
130/// Native ACL packet revision.
131#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
132pub enum AclRevision {
133    Basic,
134    DirectoryService,
135    Unknown(u8),
136}
137
138impl From<u8> for AclRevision {
139    fn from(value: u8) -> Self {
140        match value {
141            2 => Self::Basic,
142            4 => Self::DirectoryService,
143            value => Self::Unknown(value),
144        }
145    }
146}
147
148impl From<AclRevision> for u8 {
149    fn from(value: AclRevision) -> Self {
150        match value {
151            AclRevision::Basic => 2,
152            AclRevision::DirectoryService => 4,
153            AclRevision::Unknown(value) => value,
154        }
155    }
156}
157
158impl Serialize for AclRevision {
159    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
160        serializer.serialize_u8((*self).into())
161    }
162}
163
164impl<'de> Deserialize<'de> for AclRevision {
165    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
166        Ok(u8::deserialize(deserializer)?.into())
167    }
168}
169
170const ACL_HEADER_LEN: usize = 8;
171const ACE_HEADER_LEN: usize = 4;
172const SELF_RELATIVE_HEADER_LEN: usize = 20;
173
174/// Security descriptor format revision.
175#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
176#[repr(u8)]
177pub enum SecDescRevision {
178    /// Revision 1, the format supported by current security descriptors.
179    One = 1,
180}
181
182impl Serialize for SecDescRevision {
183    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
184    where
185        S: Serializer,
186    {
187        serializer.serialize_u8(*self as u8)
188    }
189}
190
191impl<'de> Deserialize<'de> for SecDescRevision {
192    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
193    where
194        D: Deserializer<'de>,
195    {
196        match u8::deserialize(deserializer)? {
197            REVISION => Ok(Self::One),
198            revision => Err(de::Error::custom(SecDescError::Revision(revision))),
199        }
200    }
201}
202
203type Revision = SecDescRevision;
204
205/// An immutable borrowed native Windows access-control list (ACL).
206#[repr(transparent)]
207pub struct Acl([u8]);
208
209impl Acl {
210    /// Parses and validates a complete native ACL packet.
211    pub fn from_bytes(bytes: &[u8]) -> Result<&Self, AclError> {
212        if bytes.len() < ACL_HEADER_LEN || !bytes.len().is_multiple_of(4) {
213            return Err(AclError::Length(bytes.len()));
214        }
215        let declared = u16::from_le_bytes(bytes[2..4].try_into().unwrap());
216        if usize::from(declared) != bytes.len() {
217            return Err(AclError::Size(declared, bytes.len()));
218        }
219        let count = u16::from_le_bytes(bytes[4..6].try_into().unwrap());
220        let mut offset = ACL_HEADER_LEN;
221        for index in 0..usize::from(count) {
222            let header = bytes
223                .get(offset..offset + ACE_HEADER_LEN)
224                .ok_or(AclError::AceCount(count, index))?;
225            let size = usize::from(u16::from_le_bytes(header[2..4].try_into().unwrap()));
226            let ace = bytes
227                .get(offset..offset.saturating_add(size))
228                .ok_or(AclError::Ace(index, AceError::Bounds(size)))?;
229            Ace::from_bytes(ace).map_err(|error| AclError::Ace(index, error))?;
230            offset += size;
231        }
232        // SAFETY: Acl is transparent over [u8], and the packet was validated above.
233        Ok(unsafe { &*(bytes as *const [u8] as *const Self) })
234    }
235
236    /// Returns the exact native ACL packet.
237    pub const fn as_bytes(&self) -> &[u8] {
238        &self.0
239    }
240
241    /// Returns the ACL revision.
242    pub const fn revision(&self) -> AclRevision {
243        match self.0[0] {
244            2 => AclRevision::Basic,
245            4 => AclRevision::DirectoryService,
246            value => AclRevision::Unknown(value),
247        }
248    }
249
250    /// Returns the declared ACL size.
251    pub fn size(&self) -> u16 {
252        u16::from_le_bytes(self.0[2..4].try_into().unwrap())
253    }
254
255    /// Returns the number of ACEs declared by the ACL.
256    pub fn ace_count(&self) -> u16 {
257        u16::from_le_bytes(self.0[4..6].try_into().unwrap())
258    }
259
260    /// Iterates over the validated ACE packets.
261    pub fn aces(&self) -> Aces<'_> {
262        Aces {
263            bytes: &self.0,
264            offset: ACL_HEADER_LEN,
265            remaining: usize::from(self.ace_count()),
266        }
267    }
268}
269
270impl fmt::Debug for Acl {
271    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272        f.debug_tuple("Acl").field(&&self.0).finish()
273    }
274}
275
276impl PartialEq for Acl {
277    fn eq(&self, other: &Self) -> bool {
278        self.0 == other.0
279    }
280}
281
282impl Eq for Acl {}
283
284impl Hash for Acl {
285    fn hash<H: Hasher>(&self, state: &mut H) {
286        self.0.hash(state);
287    }
288}
289
290impl AsRef<Acl> for Acl {
291    fn as_ref(&self) -> &Acl {
292        self
293    }
294}
295
296/// Iterator over the ACEs in an [`Acl`].
297#[derive(Clone, Debug)]
298pub struct Aces<'a> {
299    bytes: &'a [u8],
300    offset: usize,
301    remaining: usize,
302}
303
304impl<'a> Iterator for Aces<'a> {
305    type Item = &'a Ace;
306
307    fn next(&mut self) -> Option<Self::Item> {
308        if self.remaining == 0 {
309            return None;
310        }
311        let size = usize::from(u16::from_le_bytes(
312            self.bytes[self.offset + 2..self.offset + 4]
313                .try_into()
314                .unwrap(),
315        ));
316        let bytes = &self.bytes[self.offset..self.offset + size];
317        self.offset += size;
318        self.remaining -= 1;
319        // SAFETY: the containing ACL validated every ACE packet.
320        Some(unsafe { &*(bytes as *const [u8] as *const Ace) })
321    }
322
323    fn size_hint(&self) -> (usize, Option<usize>) {
324        (self.remaining, Some(self.remaining))
325    }
326}
327
328impl ExactSizeIterator for Aces<'_> {}
329
330/// A classified native ACE type.
331#[non_exhaustive]
332#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
333pub enum AceType {
334    /// Grants access.
335    AccessAllowed,
336    /// Denies access.
337    AccessDenied,
338    /// Emits an audit event.
339    SystemAudit,
340    /// Raises a system alarm.
341    SystemAlarm,
342    /// A compound access-allowed ACE.
343    AccessAllowedCompound,
344    /// An object-specific access-allowed ACE.
345    AccessAllowedObject,
346    /// An object-specific access-denied ACE.
347    AccessDeniedObject,
348    /// An object-specific system-audit ACE.
349    SystemAuditObject,
350    /// An object-specific system-alarm ACE.
351    SystemAlarmObject,
352    /// A callback access-allowed ACE.
353    AccessAllowedCallback,
354    /// A callback access-denied ACE.
355    AccessDeniedCallback,
356    /// A callback object-specific access-allowed ACE.
357    AccessAllowedCallbackObject,
358    /// A callback object-specific access-denied ACE.
359    AccessDeniedCallbackObject,
360    /// A callback system-audit ACE.
361    SystemAuditCallback,
362    /// A callback system-alarm ACE.
363    SystemAlarmCallback,
364    /// A callback object-specific system-audit ACE.
365    SystemAuditCallbackObject,
366    /// A callback object-specific system-alarm ACE.
367    SystemAlarmCallbackObject,
368    /// A mandatory-integrity-label ACE.
369    SystemMandatoryLabel,
370    /// A resource-attribute ACE.
371    SystemResourceAttribute,
372    /// A scoped-policy-ID ACE.
373    SystemScopedPolicyId,
374    /// A process-trust-label ACE.
375    SystemProcessTrustLabel,
376    /// An access-filter ACE.
377    SystemAccessFilter,
378    /// An unrecognized native ACE type code.
379    Unknown(u8),
380}
381
382impl From<u8> for AceType {
383    fn from(code: u8) -> Self {
384        match code {
385            0 => Self::AccessAllowed,
386            1 => Self::AccessDenied,
387            2 => Self::SystemAudit,
388            3 => Self::SystemAlarm,
389            4 => Self::AccessAllowedCompound,
390            5 => Self::AccessAllowedObject,
391            6 => Self::AccessDeniedObject,
392            7 => Self::SystemAuditObject,
393            8 => Self::SystemAlarmObject,
394            9 => Self::AccessAllowedCallback,
395            10 => Self::AccessDeniedCallback,
396            11 => Self::AccessAllowedCallbackObject,
397            12 => Self::AccessDeniedCallbackObject,
398            13 => Self::SystemAuditCallback,
399            14 => Self::SystemAlarmCallback,
400            15 => Self::SystemAuditCallbackObject,
401            16 => Self::SystemAlarmCallbackObject,
402            17 => Self::SystemMandatoryLabel,
403            18 => Self::SystemResourceAttribute,
404            19 => Self::SystemScopedPolicyId,
405            20 => Self::SystemProcessTrustLabel,
406            21 => Self::SystemAccessFilter,
407            code => Self::Unknown(code),
408        }
409    }
410}
411
412impl From<AceType> for u8 {
413    fn from(value: AceType) -> Self {
414        match value {
415            AceType::AccessAllowed => 0,
416            AceType::AccessDenied => 1,
417            AceType::SystemAudit => 2,
418            AceType::SystemAlarm => 3,
419            AceType::AccessAllowedCompound => 4,
420            AceType::AccessAllowedObject => 5,
421            AceType::AccessDeniedObject => 6,
422            AceType::SystemAuditObject => 7,
423            AceType::SystemAlarmObject => 8,
424            AceType::AccessAllowedCallback => 9,
425            AceType::AccessDeniedCallback => 10,
426            AceType::AccessAllowedCallbackObject => 11,
427            AceType::AccessDeniedCallbackObject => 12,
428            AceType::SystemAuditCallback => 13,
429            AceType::SystemAlarmCallback => 14,
430            AceType::SystemAuditCallbackObject => 15,
431            AceType::SystemAlarmCallbackObject => 16,
432            AceType::SystemMandatoryLabel => 17,
433            AceType::SystemResourceAttribute => 18,
434            AceType::SystemScopedPolicyId => 19,
435            AceType::SystemProcessTrustLabel => 20,
436            AceType::SystemAccessFilter => 21,
437            AceType::Unknown(code) => code,
438        }
439    }
440}
441
442impl Serialize for AceType {
443    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
444        serializer.serialize_u8((*self).into())
445    }
446}
447
448impl<'de> Deserialize<'de> for AceType {
449    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
450        Ok(u8::deserialize(deserializer)?.into())
451    }
452}
453
454/// An immutable borrowed native Windows access-control entry (ACE).
455#[repr(transparent)]
456pub struct Ace([u8]);
457
458#[derive(Debug)]
459struct AceBody {
460    mask: AccessMask,
461    sid: Sid,
462    object_flags: Option<ObjectAceFlags>,
463    object_type: Option<Guid>,
464    inherited_object_type: Option<Guid>,
465    application_data_at: usize,
466}
467
468impl Ace {
469    /// Parses and validates one complete native ACE packet.
470    pub fn from_bytes(bytes: &[u8]) -> Result<&Self, AceError> {
471        if bytes.len() < ACE_HEADER_LEN {
472            return Err(AceError::Length(bytes.len()));
473        }
474        let declared = u16::from_le_bytes(bytes[2..4].try_into().unwrap());
475        if usize::from(declared) != bytes.len() {
476            return Err(AceError::Size(declared, bytes.len()));
477        }
478        if !bytes.len().is_multiple_of(4) {
479            return Err(AceError::Alignment(bytes.len()));
480        }
481        // SAFETY: Ace is transparent over [u8]. Validation below only reads it.
482        let this = unsafe { &*(bytes as *const [u8] as *const Self) };
483        if this.has_simple_body() {
484            this.parse_simple_body()?;
485        } else if this.has_object_body() {
486            this.parse_object_body()?;
487        }
488        Ok(this)
489    }
490
491    /// Returns the exact native ACE packet.
492    pub const fn as_bytes(&self) -> &[u8] {
493        &self.0
494    }
495
496    /// Returns the native ACE type code.
497    pub const fn type_code(&self) -> u8 {
498        self.0[0]
499    }
500
501    /// Returns the classified ACE type.
502    pub fn ace_type(&self) -> AceType {
503        self.type_code().into()
504    }
505
506    /// Returns the native ACE flags byte.
507    pub const fn flags(&self) -> AceFlags {
508        AceFlags::from_bits_retain(self.0[1])
509    }
510
511    /// Returns the declared ACE size.
512    pub fn size(&self) -> u16 {
513        u16::from_le_bytes(self.0[2..4].try_into().unwrap())
514    }
515
516    /// Returns the access mask for ACE layouts that contain one.
517    pub fn mask(&self) -> Option<AccessMask> {
518        self.body().map(|body| body.mask)
519    }
520
521    /// Returns the trustee SID for ACE layouts that contain one.
522    pub fn sid(&self) -> Option<Sid> {
523        self.body().map(|body| body.sid)
524    }
525
526    /// Returns object-specific flags for object ACE layouts.
527    pub fn object_flags(&self) -> Option<ObjectAceFlags> {
528        self.parse_object_body()
529            .ok()
530            .map(|body| body.object_flags.unwrap())
531    }
532
533    /// Returns the optional object-type GUID for object ACE layouts.
534    pub fn object_type(&self) -> Option<Guid> {
535        self.parse_object_body().ok()?.object_type
536    }
537
538    /// Returns the optional inherited-object-type GUID for object ACE layouts.
539    pub fn inherited_object_type(&self) -> Option<Guid> {
540        self.parse_object_body().ok()?.inherited_object_type
541    }
542
543    /// Returns trailing application data for parsed SID-bearing layouts.
544    pub fn application_data(&self) -> Option<&[u8]> {
545        self.body().map(|body| &self.0[body.application_data_at..])
546    }
547
548    const fn has_simple_body(&self) -> bool {
549        matches!(self.type_code(), 0..=3 | 9..=10 | 13..=14 | 17..=21)
550    }
551
552    const fn has_object_body(&self) -> bool {
553        matches!(self.type_code(), 5..=8 | 11..=12 | 15..=16)
554    }
555
556    fn body(&self) -> Option<AceBody> {
557        if self.has_simple_body() {
558            self.parse_simple_body().ok()
559        } else if self.has_object_body() {
560            self.parse_object_body().ok()
561        } else {
562            None
563        }
564    }
565
566    fn parse_simple_body(&self) -> Result<AceBody, AceError> {
567        let mask = AccessMask::from_bits_retain(read_u32(&self.0, 4)?);
568        let (sid, application_data_at) = parse_ace_sid(&self.0, 8)?;
569        Ok(AceBody {
570            mask,
571            sid,
572            object_flags: None,
573            object_type: None,
574            inherited_object_type: None,
575            application_data_at,
576        })
577    }
578
579    fn parse_object_body(&self) -> Result<AceBody, AceError> {
580        let mask = AccessMask::from_bits_retain(read_u32(&self.0, 4)?);
581        let object_flags = ObjectAceFlags::from_bits_retain(read_u32(&self.0, 8)?);
582        let mut offset = 12;
583        let object_type = if object_flags.contains(ObjectAceFlags::OBJECT_TYPE_PRESENT) {
584            let value = Guid::from_bytes(self.0.get(offset..offset + 16).ok_or(AceError::Body)?)
585                .map_err(|_| AceError::Body)?;
586            offset += 16;
587            Some(value)
588        } else {
589            None
590        };
591        let inherited_object_type = if object_flags
592            .contains(ObjectAceFlags::INHERITED_OBJECT_TYPE_PRESENT)
593        {
594            let value = Guid::from_bytes(self.0.get(offset..offset + 16).ok_or(AceError::Body)?)
595                .map_err(|_| AceError::Body)?;
596            offset += 16;
597            Some(value)
598        } else {
599            None
600        };
601        let (sid, application_data_at) = parse_ace_sid(&self.0, offset)?;
602        Ok(AceBody {
603            mask,
604            sid,
605            object_flags: Some(object_flags),
606            object_type,
607            inherited_object_type,
608            application_data_at,
609        })
610    }
611}
612
613impl fmt::Debug for Ace {
614    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
615        f.debug_tuple("Ace").field(&&self.0).finish()
616    }
617}
618
619impl PartialEq for Ace {
620    fn eq(&self, other: &Self) -> bool {
621        self.0 == other.0
622    }
623}
624
625impl Eq for Ace {}
626
627impl Hash for Ace {
628    fn hash<H: Hasher>(&self, state: &mut H) {
629        self.0.hash(state);
630    }
631}
632
633impl AsRef<Ace> for Ace {
634    fn as_ref(&self) -> &Ace {
635        self
636    }
637}
638
639/// Options shared by the supported ACE builders.
640///
641/// Construct options with [`new`](Self::new) and its fluent setters. The
642/// fields are kept private so packet-layout choices remain explicit.
643#[derive(Clone, Debug, PartialEq, Eq)]
644pub struct AceBuildOptions {
645    flags: AceFlags,
646    object_type: Option<Guid>,
647    inherited_object_type: Option<Guid>,
648    callback: bool,
649    object: bool,
650    application_data: Vec<u8>,
651}
652
653impl AceBuildOptions {
654    /// Creates options for a plain, non-callback ACE.
655    #[allow(clippy::new_without_default)]
656    pub const fn new() -> Self {
657        Self {
658            flags: AceFlags::empty(),
659            object_type: None,
660            inherited_object_type: None,
661            callback: false,
662            object: false,
663            application_data: Vec::new(),
664        }
665    }
666
667    /// Replaces the native ACE flags.
668    pub fn flags(mut self, flags: AceFlags) -> Self {
669        self.flags = flags;
670        self
671    }
672
673    /// Adds an object-type GUID, selecting an object ACE layout.
674    pub fn object_type(mut self, object_type: Guid) -> Self {
675        self.object_type = Some(object_type);
676        self
677    }
678
679    /// Adds an inherited-object-type GUID, selecting an object ACE layout.
680    pub fn inherited_object_type(mut self, inherited_object_type: Guid) -> Self {
681        self.inherited_object_type = Some(inherited_object_type);
682        self
683    }
684
685    /// Selects an object ACE layout, even without object GUIDs.
686    pub fn object(mut self) -> Self {
687        self.object = true;
688        self
689    }
690
691    /// Selects a callback ACE layout.
692    pub fn callback(mut self) -> Self {
693        self.callback = true;
694        self
695    }
696
697    /// Appends opaque application data after the trustee SID.
698    pub fn application_data(mut self, application_data: impl Into<Vec<u8>>) -> Self {
699        self.application_data = application_data.into();
700        self
701    }
702}
703
704/// An owned, validated native Windows ACE packet.
705#[derive(Clone, Debug, PartialEq, Eq, Hash)]
706pub struct AceBuf(Box<[u8]>);
707
708impl AceBuf {
709    /// Takes ownership of a raw packet after validating it.
710    pub fn try_from_bytes(bytes: impl Into<Box<[u8]>>) -> Result<Self, AceError> {
711        let bytes = bytes.into();
712        Ace::from_bytes(&bytes)?;
713        Ok(Self(bytes))
714    }
715
716    /// Builds an access-allowed ACE.
717    pub fn allow(
718        sid: &Sid,
719        mask: AccessMask,
720        options: AceBuildOptions,
721    ) -> Result<Self, AceBuildError> {
722        Self::build(AceFamily::Allow, sid, mask, false, false, options)
723    }
724
725    /// Builds an access-denied ACE.
726    pub fn deny(
727        sid: &Sid,
728        mask: AccessMask,
729        options: AceBuildOptions,
730    ) -> Result<Self, AceBuildError> {
731        Self::build(AceFamily::Deny, sid, mask, false, false, options)
732    }
733
734    /// Builds a system-audit ACE.
735    pub fn audit(
736        sid: &Sid,
737        mask: AccessMask,
738        successful: bool,
739        failed: bool,
740        options: AceBuildOptions,
741    ) -> Result<Self, AceBuildError> {
742        if !successful && !failed {
743            return Err(AceBuildError::AuditOutcome);
744        }
745        if options
746            .flags
747            .intersects(AceFlags::SUCCESSFUL_ACCESS | AceFlags::FAILED_ACCESS)
748        {
749            return Err(AceBuildError::AuditFlags);
750        }
751        Self::build(AceFamily::Audit, sid, mask, successful, failed, options)
752    }
753
754    /// Builds a system-alarm ACE with the same outcome rules as an audit ACE.
755    pub fn alarm(
756        sid: &Sid,
757        mask: AccessMask,
758        successful: bool,
759        failed: bool,
760        options: AceBuildOptions,
761    ) -> Result<Self, AceBuildError> {
762        if !successful && !failed {
763            return Err(AceBuildError::AuditOutcome);
764        }
765        if options
766            .flags
767            .intersects(AceFlags::SUCCESSFUL_ACCESS | AceFlags::FAILED_ACCESS)
768        {
769            return Err(AceBuildError::AuditFlags);
770        }
771        Self::build(AceFamily::Alarm, sid, mask, successful, failed, options)
772    }
773
774    fn build(
775        family: AceFamily,
776        sid: &Sid,
777        mask: AccessMask,
778        successful: bool,
779        failed: bool,
780        options: AceBuildOptions,
781    ) -> Result<Self, AceBuildError> {
782        let object = options.object
783            || options.object_type.is_some()
784            || options.inherited_object_type.is_some();
785        let type_code = match (family, options.callback, object) {
786            (AceFamily::Allow, false, false) => 0,
787            (AceFamily::Deny, false, false) => 1,
788            (AceFamily::Audit, false, false) => 2,
789            (AceFamily::Alarm, false, false) => 3,
790            (AceFamily::Allow, false, true) => 5,
791            (AceFamily::Deny, false, true) => 6,
792            (AceFamily::Audit, false, true) => 7,
793            (AceFamily::Alarm, false, true) => 8,
794            (AceFamily::Allow, true, false) => 9,
795            (AceFamily::Deny, true, false) => 10,
796            (AceFamily::Allow, true, true) => 11,
797            (AceFamily::Deny, true, true) => 12,
798            (AceFamily::Audit, true, false) => 13,
799            (AceFamily::Alarm, true, false) => 14,
800            (AceFamily::Audit, true, true) => 15,
801            (AceFamily::Alarm, true, true) => 16,
802        };
803        let mut flags = options.flags;
804        if successful {
805            flags |= AceFlags::SUCCESSFUL_ACCESS;
806        }
807        if failed {
808            flags |= AceFlags::FAILED_ACCESS;
809        }
810
811        let mut bytes = vec![type_code, flags.bits(), 0, 0];
812        bytes.extend_from_slice(&mask.bits().to_le_bytes());
813        if object {
814            let mut object_flags = ObjectAceFlags::empty();
815            object_flags.set(
816                ObjectAceFlags::OBJECT_TYPE_PRESENT,
817                options.object_type.is_some(),
818            );
819            object_flags.set(
820                ObjectAceFlags::INHERITED_OBJECT_TYPE_PRESENT,
821                options.inherited_object_type.is_some(),
822            );
823            bytes.extend_from_slice(&object_flags.bits().to_le_bytes());
824            if let Some(value) = options.object_type {
825                bytes.extend_from_slice(&value.to_bytes());
826            }
827            if let Some(value) = options.inherited_object_type {
828                bytes.extend_from_slice(&value.to_bytes());
829            }
830        }
831        bytes.extend_from_slice(&sid.to_bytes());
832        bytes.extend_from_slice(&options.application_data);
833        bytes.resize(bytes.len().next_multiple_of(4), 0);
834        let size = u16::try_from(bytes.len()).map_err(|_| AceBuildError::Size(bytes.len()))?;
835        bytes[2..4].copy_from_slice(&size.to_le_bytes());
836        Ok(Self(bytes.into_boxed_slice()))
837    }
838
839    /// Returns the owned packet bytes.
840    pub fn into_boxed_bytes(self) -> Box<[u8]> {
841        self.0
842    }
843}
844
845#[derive(Clone, Copy)]
846enum AceFamily {
847    Allow,
848    Deny,
849    Audit,
850    Alarm,
851}
852
853impl Deref for AceBuf {
854    type Target = Ace;
855
856    fn deref(&self) -> &Self::Target {
857        // The constructor invariant guarantees validation.
858        unsafe { &*(&*self.0 as *const [u8] as *const Ace) }
859    }
860}
861
862impl AsRef<Ace> for AceBuf {
863    fn as_ref(&self) -> &Ace {
864        self
865    }
866}
867
868impl Borrow<Ace> for AceBuf {
869    fn borrow(&self) -> &Ace {
870        self
871    }
872}
873
874impl ToOwned for Ace {
875    type Owned = AceBuf;
876
877    fn to_owned(&self) -> Self::Owned {
878        AceBuf(self.0.into())
879    }
880}
881
882impl Serialize for AceBuf {
883    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
884    where
885        S: Serializer,
886    {
887        self.0.serialize(serializer)
888    }
889}
890
891impl<'de> Deserialize<'de> for AceBuf {
892    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
893    where
894        D: Deserializer<'de>,
895    {
896        let bytes = Box::<[u8]>::deserialize(deserializer)?;
897        Self::try_from_bytes(bytes).map_err(de::Error::custom)
898    }
899}
900
901/// An owned, validated native Windows ACL packet.
902#[derive(Clone, Debug, PartialEq, Eq, Hash)]
903pub struct AclBuf(Box<[u8]>);
904
905impl AclBuf {
906    /// Takes ownership of a raw packet after validating it.
907    pub fn try_from_bytes(bytes: impl Into<Box<[u8]>>) -> Result<Self, AclError> {
908        let bytes = bytes.into();
909        Acl::from_bytes(&bytes)?;
910        Ok(Self(bytes))
911    }
912
913    /// Takes ownership of an ACL packet without validating it.
914    ///
915    /// # Safety
916    ///
917    /// `bytes` must contain a complete, structurally valid native ACL packet.
918    /// Violating this invariant can make methods that view it as an [`Acl`]
919    /// perform unchecked indexing.
920    pub unsafe fn from_bytes_unchecked(bytes: impl Into<Box<[u8]>>) -> Self {
921        Self(bytes.into())
922    }
923
924    /// Builds an ACL from already-validated ACE packets.
925    pub fn from_aces<I, A>(aces: I, revision: Option<AclRevision>) -> Result<Self, AclBuildError>
926    where
927        I: IntoIterator<Item = A>,
928        A: AsRef<Ace>,
929    {
930        let aces: Vec<A> = aces.into_iter().collect();
931        let mut size = ACL_HEADER_LEN;
932        let mut has_object = false;
933        for ace in &aces {
934            let ace = ace.as_ref();
935            size = size
936                .checked_add(ace.as_bytes().len())
937                .ok_or(AclBuildError::Size(usize::MAX))?;
938            has_object |= matches!(
939                ace.ace_type(),
940                AceType::AccessAllowedObject
941                    | AceType::AccessDeniedObject
942                    | AceType::SystemAuditObject
943                    | AceType::SystemAlarmObject
944                    | AceType::AccessAllowedCallbackObject
945                    | AceType::AccessDeniedCallbackObject
946                    | AceType::SystemAuditCallbackObject
947                    | AceType::SystemAlarmCallbackObject
948            );
949        }
950        let count = u16::try_from(aces.len()).map_err(|_| AclBuildError::Count(aces.len()))?;
951        let size16 = u16::try_from(size).map_err(|_| AclBuildError::Size(size))?;
952        let revision = revision.unwrap_or(if has_object {
953            AclRevision::DirectoryService
954        } else {
955            AclRevision::Basic
956        });
957        if let AclRevision::Unknown(revision) = revision {
958            return Err(AclBuildError::Revision(revision));
959        }
960        if revision == AclRevision::Basic && has_object {
961            return Err(AclBuildError::ObjectRevision);
962        }
963
964        let mut bytes = Vec::with_capacity(size);
965        bytes.extend_from_slice(&[revision.into(), 0]);
966        bytes.extend_from_slice(&size16.to_le_bytes());
967        bytes.extend_from_slice(&count.to_le_bytes());
968        bytes.extend_from_slice(&[0, 0]);
969        for ace in &aces {
970            bytes.extend_from_slice(ace.as_ref().as_bytes());
971        }
972        Ok(Self(bytes.into_boxed_slice()))
973    }
974
975    /// Returns the owned packet bytes.
976    pub fn into_boxed_bytes(self) -> Box<[u8]> {
977        self.0
978    }
979}
980
981impl Deref for AclBuf {
982    type Target = Acl;
983
984    fn deref(&self) -> &Self::Target {
985        // The constructor invariant guarantees validation.
986        unsafe { &*(&*self.0 as *const [u8] as *const Acl) }
987    }
988}
989
990impl AsRef<Acl> for AclBuf {
991    fn as_ref(&self) -> &Acl {
992        self
993    }
994}
995
996impl Borrow<Acl> for AclBuf {
997    fn borrow(&self) -> &Acl {
998        self
999    }
1000}
1001
1002impl ToOwned for Acl {
1003    type Owned = AclBuf;
1004
1005    fn to_owned(&self) -> Self::Owned {
1006        AclBuf(self.0.into())
1007    }
1008}
1009
1010impl Serialize for AclBuf {
1011    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1012    where
1013        S: Serializer,
1014    {
1015        self.0.serialize(serializer)
1016    }
1017}
1018
1019impl<'de> Deserialize<'de> for AclBuf {
1020    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1021    where
1022        D: Deserializer<'de>,
1023    {
1024        let bytes = Box::<[u8]>::deserialize(deserializer)?;
1025        Self::try_from_bytes(bytes).map_err(de::Error::custom)
1026    }
1027}
1028
1029/// Error returned when building an ACE.
1030#[derive(Clone, Debug, PartialEq, Eq)]
1031pub enum AceBuildError {
1032    /// An audit ACE selected neither successful nor failed access.
1033    AuditOutcome,
1034    /// Audit outcome bits were supplied both explicitly and through `flags`.
1035    AuditFlags,
1036    /// The generated packet exceeds the 16-bit native size field.
1037    Size(usize),
1038}
1039
1040impl fmt::Display for AceBuildError {
1041    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1042        match self {
1043            Self::AuditOutcome => f.write_str("audit ACE requires a successful or failed outcome"),
1044            Self::AuditFlags => f.write_str("audit outcome bits must not be supplied in flags"),
1045            Self::Size(size) => write!(f, "ACE packet size {size} exceeds the native limit"),
1046        }
1047    }
1048}
1049
1050impl error::Error for AceBuildError {}
1051
1052/// Error returned when building an ACL.
1053#[derive(Clone, Debug, PartialEq, Eq)]
1054pub enum AclBuildError {
1055    /// The requested ACL revision is unsupported.
1056    Revision(u8),
1057    /// Revision 2 cannot encode an object ACE.
1058    ObjectRevision,
1059    /// The ACL contains too many ACEs for its 16-bit count field.
1060    Count(usize),
1061    /// The ACL packet exceeds its 16-bit size field.
1062    Size(usize),
1063}
1064
1065impl fmt::Display for AclBuildError {
1066    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1067        match self {
1068            Self::Revision(revision) => write!(f, "unsupported ACL revision {revision}"),
1069            Self::ObjectRevision => f.write_str("ACL revision 2 cannot contain object ACEs"),
1070            Self::Count(count) => write!(f, "ACL ACE count {count} exceeds the native limit"),
1071            Self::Size(size) => write!(f, "ACL packet size {size} exceeds the native limit"),
1072        }
1073    }
1074}
1075
1076impl error::Error for AclBuildError {}
1077
1078fn read_u32(bytes: &[u8], offset: usize) -> Result<u32, AceError> {
1079    let bytes = bytes.get(offset..offset + 4).ok_or(AceError::Body)?;
1080    Ok(u32::from_le_bytes(bytes.try_into().unwrap()))
1081}
1082
1083fn parse_ace_sid(bytes: &[u8], offset: usize) -> Result<(Sid, usize), AceError> {
1084    let header = bytes.get(offset..offset + 8).ok_or(AceError::Sid)?;
1085    let length = 8 + usize::from(header[1]) * 4;
1086    let sid = bytes.get(offset..offset + length).ok_or(AceError::Sid)?;
1087    let sid = Sid::from_bytes(sid).map_err(|_| AceError::Sid)?;
1088    Ok((sid, offset + length))
1089}
1090
1091/// Error returned when parsing an ACL.
1092#[derive(Clone, Debug, PartialEq, Eq)]
1093pub enum AclError {
1094    /// The packet is shorter than an ACL header or is not DWORD-aligned.
1095    Length(usize),
1096    /// The declared packet size differs from the supplied byte length.
1097    Size(u16, usize),
1098    /// Fewer ACE packets could be read than the header declares.
1099    AceCount(u16, usize),
1100    /// An ACE at the supplied index is malformed.
1101    Ace(usize, AceError),
1102}
1103
1104impl fmt::Display for AclError {
1105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1106        match self {
1107            Self::Length(length) => write!(f, "ACL packet has invalid length {length}"),
1108            Self::Size(declared, actual) => write!(
1109                f,
1110                "ACL packet declares size {declared}, but contains {actual} bytes"
1111            ),
1112            Self::AceCount(count, parsed) => write!(
1113                f,
1114                "ACL declares {count} ACEs, but only {parsed} can be traversed"
1115            ),
1116            Self::Ace(index, error) => write!(f, "ACE {index} is invalid: {error}"),
1117        }
1118    }
1119}
1120
1121impl error::Error for AclError {}
1122
1123/// Error returned when parsing an ACE.
1124#[derive(Clone, Debug, PartialEq, Eq)]
1125pub enum AceError {
1126    /// The packet is shorter than an ACE header.
1127    Length(usize),
1128    /// The declared packet size differs from the supplied byte length.
1129    Size(u16, usize),
1130    /// The packet is not DWORD-aligned.
1131    Alignment(usize),
1132    /// An ACE declared inside an ACL extends beyond that ACL's bytes.
1133    Bounds(usize),
1134    /// A recognized ACE body is truncated or malformed.
1135    Body,
1136    /// The ACE's embedded SID is malformed.
1137    Sid,
1138}
1139
1140impl fmt::Display for AceError {
1141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1142        match self {
1143            Self::Length(length) => write!(f, "ACE packet has invalid length {length}"),
1144            Self::Size(declared, actual) => write!(
1145                f,
1146                "ACE packet declares size {declared}, but contains {actual} bytes"
1147            ),
1148            Self::Alignment(length) => write!(f, "ACE packet length {length} is not aligned"),
1149            Self::Bounds(size) => write!(f, "ACE of size {size} exceeds its ACL"),
1150            Self::Body => f.write_str("ACE body is truncated"),
1151            Self::Sid => f.write_str("ACE contains an invalid SID"),
1152        }
1153    }
1154}
1155
1156impl error::Error for AceError {}
1157
1158/// A validated, portable representation of a self-relative Windows security descriptor.
1159///
1160/// A descriptor tracks which components were loaded through its
1161/// [`mask`](Self::mask), so partial security queries can be carried without
1162/// pretending that omitted components were absent on the target. Use
1163/// [`SecDescUpdate`] with [`with`](Self::with) to make a checked update.
1164#[derive(Debug, Clone, PartialEq, Eq)]
1165pub struct SecDesc {
1166    mask: SecInfo,
1167    revision: Revision,
1168    rm_control: u8,
1169    control: SecDescControl,
1170    owner: Option<Sid>,
1171    group: Option<Sid>,
1172    dacl: Option<AclBuf>,
1173    sacl: Option<AclBuf>,
1174}
1175
1176/// A builder for a functional update to a [`SecDesc`].
1177///
1178/// Component and control-flag methods select the values to replace.
1179/// Internally, control changes are stored as compact set/clear bitmasks;
1180/// [`SecDesc::with`] rejects changes that do not apply to loaded components.
1181#[derive(Clone, Debug)]
1182pub struct SecDescUpdate {
1183    owner: Option<Option<Sid>>,
1184    group: Option<Option<Sid>>,
1185    dacl: Option<Option<AclBuf>>,
1186    sacl: Option<Option<AclBuf>>,
1187    set_flags: SecDescControl,
1188    clear_flags: SecDescControl,
1189    rm_control: Option<Option<u8>>,
1190}
1191
1192impl SecDescUpdate {
1193    /// Creates an update with no changes.
1194    #[allow(clippy::new_without_default)]
1195    pub const fn new() -> Self {
1196        Self {
1197            owner: None,
1198            group: None,
1199            dacl: None,
1200            sacl: None,
1201            set_flags: SecDescControl::empty(),
1202            clear_flags: SecDescControl::empty(),
1203            rm_control: None,
1204        }
1205    }
1206
1207    /// Replaces the owner, or clears it with `None`.
1208    pub fn owner(mut self, owner: Option<Sid>) -> Self {
1209        self.owner = Some(owner);
1210        self
1211    }
1212    /// Replaces the primary group, or clears it with `None`.
1213    pub fn group(mut self, group: Option<Sid>) -> Self {
1214        self.group = Some(group);
1215        self
1216    }
1217    /// Replaces the DACL, or supplies a null DACL with `None`.
1218    pub fn dacl(mut self, dacl: Option<AclBuf>) -> Self {
1219        self.dacl = Some(dacl);
1220        self
1221    }
1222    /// Replaces the SACL, or supplies a null SACL with `None`.
1223    pub fn sacl(mut self, sacl: Option<AclBuf>) -> Self {
1224        self.sacl = Some(sacl);
1225        self
1226    }
1227    /// Sets the owner-defaulted control flag.
1228    pub fn owner_defaulted(self, value: bool) -> Self {
1229        self.control_flag(SecDescControl::OWNER_DEFAULTED.bits(), value)
1230    }
1231    /// Sets the group-defaulted control flag.
1232    pub fn group_defaulted(self, value: bool) -> Self {
1233        self.control_flag(SecDescControl::GROUP_DEFAULTED.bits(), value)
1234    }
1235    /// Sets whether a DACL is present.
1236    pub fn dacl_present(self, value: bool) -> Self {
1237        self.control_flag(SecDescControl::DACL_PRESENT.bits(), value)
1238    }
1239    /// Sets the DACL-defaulted control flag.
1240    pub fn dacl_defaulted(self, value: bool) -> Self {
1241        self.control_flag(SecDescControl::DACL_DEFAULTED.bits(), value)
1242    }
1243    /// Sets the DACL auto-inheritance-requested control flag.
1244    pub fn dacl_auto_inherit_required(self, value: bool) -> Self {
1245        self.control_flag(SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(), value)
1246    }
1247    /// Sets the DACL auto-inherited control flag.
1248    pub fn dacl_auto_inherited(self, value: bool) -> Self {
1249        self.control_flag(SecDescControl::DACL_AUTO_INHERITED.bits(), value)
1250    }
1251    /// Sets the DACL-protected control flag.
1252    pub fn dacl_protected(self, value: bool) -> Self {
1253        self.control_flag(SecDescControl::DACL_PROTECTED.bits(), value)
1254    }
1255    /// Sets whether a SACL is present.
1256    pub fn sacl_present(self, value: bool) -> Self {
1257        self.control_flag(SecDescControl::SACL_PRESENT.bits(), value)
1258    }
1259    /// Sets the SACL-defaulted control flag.
1260    pub fn sacl_defaulted(self, value: bool) -> Self {
1261        self.control_flag(SecDescControl::SACL_DEFAULTED.bits(), value)
1262    }
1263    /// Sets the SACL auto-inheritance-requested control flag.
1264    pub fn sacl_auto_inherit_required(self, value: bool) -> Self {
1265        self.control_flag(SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(), value)
1266    }
1267    /// Sets the SACL auto-inherited control flag.
1268    pub fn sacl_auto_inherited(self, value: bool) -> Self {
1269        self.control_flag(SecDescControl::SACL_AUTO_INHERITED.bits(), value)
1270    }
1271    /// Sets the SACL-protected control flag.
1272    pub fn sacl_protected(self, value: bool) -> Self {
1273        self.control_flag(SecDescControl::SACL_PROTECTED.bits(), value)
1274    }
1275    /// Sets the resource-manager control byte, or clears its validity with `None`.
1276    pub fn rm_control(mut self, rm_control: Option<u8>) -> Self {
1277        self.rm_control = Some(rm_control);
1278        self
1279    }
1280
1281    fn control_flag(mut self, flag: u16, value: bool) -> Self {
1282        let flag = SecDescControl::from_bits_retain(flag);
1283        self.set_flags.remove(flag);
1284        self.clear_flags.remove(flag);
1285        if value {
1286            self.set_flags |= flag;
1287        } else {
1288            self.clear_flags |= flag;
1289        }
1290        self
1291    }
1292}
1293
1294impl SecDesc {
1295    /// Creates a security descriptor from its structural components.
1296    #[allow(clippy::too_many_arguments)]
1297    pub fn new(
1298        mask: SecInfo,
1299        rm_control: u8,
1300        control: SecDescControl,
1301        owner: Option<Sid>,
1302        group: Option<Sid>,
1303        dacl: Option<AclBuf>,
1304        sacl: Option<AclBuf>,
1305    ) -> Result<Self, SecDescError> {
1306        if !mask.contains(SecInfo::OWNER) && owner.is_some() {
1307            return Err(SecDescError::OwnerNotLoaded);
1308        }
1309        if !mask.contains(SecInfo::GROUP) && group.is_some() {
1310            return Err(SecDescError::GroupNotLoaded);
1311        }
1312        validate_acl(
1313            AclKind::Dacl,
1314            mask.contains(SecInfo::DACL),
1315            control.contains(SecDescControl::DACL_PRESENT),
1316            dacl.as_ref(),
1317        )?;
1318        validate_acl(
1319            AclKind::Sacl,
1320            mask.contains(SecInfo::SACL),
1321            control.contains(SecDescControl::SACL_PRESENT),
1322            sacl.as_ref(),
1323        )?;
1324
1325        Ok(Self {
1326            mask,
1327            revision: Revision::One,
1328            rm_control,
1329            control: control - SecDescControl::SELF_RELATIVE,
1330            owner,
1331            group,
1332            dacl,
1333            sacl,
1334        })
1335    }
1336
1337    /// Parses a self-relative Windows security descriptor packet.
1338    pub fn from_bytes(bytes: &[u8]) -> Result<Self, SecDescError> {
1339        Self::from_bytes_with_mask(bytes, SecInfo::ALL)
1340    }
1341
1342    /// Parses the selected components of a self-relative Windows security descriptor packet.
1343    pub fn from_bytes_with_mask(bytes: &[u8], mask: SecInfo) -> Result<Self, SecDescError> {
1344        if bytes.len() < SELF_RELATIVE_HEADER_LEN {
1345            return Err(SecDescError::PacketLength);
1346        }
1347        match bytes[0] {
1348            REVISION => {}
1349            revision => return Err(SecDescError::Revision(revision)),
1350        }
1351        let rm_control = bytes[1];
1352        let control = u16::from_le_bytes(bytes[2..4].try_into().unwrap());
1353        if control & SecDescControl::SELF_RELATIVE.bits() == 0 {
1354            return Err(SecDescError::NotSelfRelative);
1355        }
1356
1357        let owner_offset = packet_offset(bytes, 4, SecDescComponent::Owner)?;
1358        let group_offset = packet_offset(bytes, 8, SecDescComponent::Group)?;
1359        let sacl_offset = packet_offset(bytes, 12, SecDescComponent::Sacl)?;
1360        let dacl_offset = packet_offset(bytes, 16, SecDescComponent::Dacl)?;
1361        if control & SecDescControl::SACL_PRESENT.bits() == 0 && sacl_offset != 0 {
1362            return Err(SecDescError::AclNotPresent(AclKind::Sacl));
1363        }
1364        if control & SecDescControl::DACL_PRESENT.bits() == 0 && dacl_offset != 0 {
1365            return Err(SecDescError::AclNotPresent(AclKind::Dacl));
1366        }
1367        let owner = mask
1368            .contains(SecInfo::OWNER)
1369            .then(|| parse_sid(bytes, owner_offset, SecDescComponent::Owner))
1370            .transpose()?
1371            .flatten();
1372        let group = mask
1373            .contains(SecInfo::GROUP)
1374            .then(|| parse_sid(bytes, group_offset, SecDescComponent::Group))
1375            .transpose()?
1376            .flatten();
1377        let sacl = mask
1378            .contains(SecInfo::SACL)
1379            .then(|| parse_acl(bytes, sacl_offset, AclKind::Sacl))
1380            .transpose()?
1381            .flatten();
1382        let dacl = mask
1383            .contains(SecInfo::DACL)
1384            .then(|| parse_acl(bytes, dacl_offset, AclKind::Dacl))
1385            .transpose()?
1386            .flatten();
1387
1388        Self::new(
1389            mask,
1390            rm_control,
1391            SecDescControl::from_bits_retain(control),
1392            owner,
1393            group,
1394            dacl,
1395            sacl,
1396        )
1397    }
1398
1399    /// Converts this descriptor to a canonical self-relative Windows packet.
1400    pub fn to_bytes(&self) -> Vec<u8> {
1401        let mut bytes = vec![0; SELF_RELATIVE_HEADER_LEN];
1402        bytes[0] = self.revision as u8;
1403        bytes[1] = self.rm_control;
1404        bytes[2..4].copy_from_slice(
1405            &(self.control | SecDescControl::SELF_RELATIVE)
1406                .bits()
1407                .to_le_bytes(),
1408        );
1409
1410        let owner = self.owner.as_ref().map(Sid::to_bytes);
1411        let group = self.group.as_ref().map(Sid::to_bytes);
1412        append_component(&mut bytes, 4, owner.as_deref());
1413        append_component(&mut bytes, 8, group.as_deref());
1414        append_component(&mut bytes, 12, self.sacl.as_deref().map(Acl::as_bytes));
1415        append_component(&mut bytes, 16, self.dacl.as_deref().map(Acl::as_bytes));
1416        bytes
1417    }
1418
1419    /// Returns the native SECURITY_INFORMATION mask associated with the descriptor.
1420    pub const fn mask(&self) -> SecInfo {
1421        self.mask
1422    }
1423
1424    /// Returns the security descriptor revision.
1425    pub const fn revision(&self) -> Revision {
1426        self.revision
1427    }
1428
1429    /// Returns the security descriptor control mask.
1430    pub const fn control(&self) -> SecDescControl {
1431        self.control
1432    }
1433
1434    /// Returns the resource-manager control byte when it is valid.
1435    pub const fn rm_control(&self) -> Option<u8> {
1436        if self.rm_control_valid() {
1437            Some(self.rm_control)
1438        } else {
1439            None
1440        }
1441    }
1442
1443    /// Returns whether the resource-manager control byte is valid.
1444    pub const fn rm_control_valid(&self) -> bool {
1445        self.control.contains(SecDescControl::RM_CONTROL_VALID)
1446    }
1447
1448    /// Returns whether the owner component was loaded.
1449    pub const fn owner_loaded(&self) -> bool {
1450        self.mask.contains(SecInfo::OWNER)
1451    }
1452
1453    /// Returns the owner SID, if present.
1454    pub const fn owner(&self) -> Option<&Sid> {
1455        self.owner.as_ref()
1456    }
1457
1458    /// Returns whether the owner SID was supplied by a default mechanism.
1459    pub const fn owner_defaulted(&self) -> bool {
1460        self.control.contains(SecDescControl::OWNER_DEFAULTED)
1461    }
1462
1463    /// Returns whether the group component was loaded.
1464    pub const fn group_loaded(&self) -> bool {
1465        self.mask.contains(SecInfo::GROUP)
1466    }
1467
1468    /// Returns the primary group SID, if present.
1469    pub const fn group(&self) -> Option<&Sid> {
1470        self.group.as_ref()
1471    }
1472
1473    /// Returns whether the group SID was supplied by a default mechanism.
1474    pub const fn group_defaulted(&self) -> bool {
1475        self.control.contains(SecDescControl::GROUP_DEFAULTED)
1476    }
1477
1478    /// Returns whether the DACL component was loaded.
1479    pub const fn dacl_loaded(&self) -> bool {
1480        self.mask.contains(SecInfo::DACL)
1481    }
1482
1483    /// Returns the DACL, if it is non-null.
1484    pub fn dacl(&self) -> Option<&Acl> {
1485        self.dacl.as_deref()
1486    }
1487
1488    /// Returns whether the descriptor marks the DACL as present.
1489    pub const fn dacl_present(&self) -> bool {
1490        self.control.contains(SecDescControl::DACL_PRESENT)
1491    }
1492
1493    /// Returns whether the DACL was supplied by a default mechanism.
1494    pub const fn dacl_defaulted(&self) -> bool {
1495        self.control.contains(SecDescControl::DACL_DEFAULTED)
1496    }
1497
1498    /// Returns whether DACL inheritance computation was requested.
1499    pub const fn dacl_auto_inherit_required(&self) -> bool {
1500        self.control
1501            .contains(SecDescControl::DACL_AUTO_INHERIT_REQUIRED)
1502    }
1503
1504    /// Returns whether the DACL was produced through inheritance.
1505    pub const fn dacl_auto_inherited(&self) -> bool {
1506        self.control.contains(SecDescControl::DACL_AUTO_INHERITED)
1507    }
1508
1509    /// Returns whether the DACL is protected from inheritance.
1510    pub const fn dacl_protected(&self) -> bool {
1511        self.control.contains(SecDescControl::DACL_PROTECTED)
1512    }
1513
1514    /// Returns whether the SACL component was loaded.
1515    pub const fn sacl_loaded(&self) -> bool {
1516        self.mask.contains(SecInfo::SACL)
1517    }
1518
1519    /// Returns the SACL, if it is non-null.
1520    pub fn sacl(&self) -> Option<&Acl> {
1521        self.sacl.as_deref()
1522    }
1523
1524    /// Returns whether the descriptor marks the SACL as present.
1525    pub const fn sacl_present(&self) -> bool {
1526        self.control.contains(SecDescControl::SACL_PRESENT)
1527    }
1528
1529    /// Returns whether the SACL was supplied by a default mechanism.
1530    pub const fn sacl_defaulted(&self) -> bool {
1531        self.control.contains(SecDescControl::SACL_DEFAULTED)
1532    }
1533
1534    /// Returns whether SACL inheritance computation was requested.
1535    pub const fn sacl_auto_inherit_required(&self) -> bool {
1536        self.control
1537            .contains(SecDescControl::SACL_AUTO_INHERIT_REQUIRED)
1538    }
1539
1540    /// Returns whether the SACL was produced through inheritance.
1541    pub const fn sacl_auto_inherited(&self) -> bool {
1542        self.control.contains(SecDescControl::SACL_AUTO_INHERITED)
1543    }
1544
1545    /// Returns whether the SACL is protected from inheritance.
1546    pub const fn sacl_protected(&self) -> bool {
1547        self.control.contains(SecDescControl::SACL_PROTECTED)
1548    }
1549
1550    /// Returns a new descriptor with the supplied component and control updates.
1551    pub fn with(&self, update: SecDescUpdate) -> Result<Self, SecDescError> {
1552        let SecDescUpdate {
1553            owner: owner_update,
1554            group: group_update,
1555            dacl: dacl_update,
1556            sacl: sacl_update,
1557            set_flags,
1558            clear_flags,
1559            rm_control: rm_control_update,
1560        } = update;
1561        let mut mask = self.mask;
1562        let mut control = self.control.bits();
1563        let set_flags = set_flags.bits();
1564        let clear_flags = clear_flags.bits();
1565
1566        let owner = match owner_update {
1567            Some(value) => {
1568                mask |= SecInfo::OWNER;
1569                value
1570            }
1571            None => self.owner.clone(),
1572        };
1573        let group = match group_update {
1574            Some(value) => {
1575                mask |= SecInfo::GROUP;
1576                value
1577            }
1578            None => self.group.clone(),
1579        };
1580
1581        let (dacl, dacl_explicit) = match dacl_update {
1582            Some(value) => {
1583                mask |= SecInfo::DACL;
1584                set_control(&mut control, SecDescControl::DACL_PRESENT.bits(), true);
1585                (value, true)
1586            }
1587            None => (self.dacl.clone(), false),
1588        };
1589        let (sacl, sacl_explicit) = match sacl_update {
1590            Some(value) => {
1591                mask |= SecInfo::SACL;
1592                set_control(&mut control, SecDescControl::SACL_PRESENT.bits(), true);
1593                (value, true)
1594            }
1595            None => (self.sacl.clone(), false),
1596        };
1597
1598        let dacl = apply_presence(
1599            AclKind::Dacl,
1600            &mut mask,
1601            &mut control,
1602            SecInfo::DACL,
1603            SecDescControl::DACL_PRESENT.bits(),
1604            flag_update(set_flags, clear_flags, SecDescControl::DACL_PRESENT.bits()),
1605            dacl_explicit,
1606            dacl,
1607        )?;
1608        let sacl = apply_presence(
1609            AclKind::Sacl,
1610            &mut mask,
1611            &mut control,
1612            SecInfo::SACL,
1613            SecDescControl::SACL_PRESENT.bits(),
1614            flag_update(set_flags, clear_flags, SecDescControl::SACL_PRESENT.bits()),
1615            sacl_explicit,
1616            sacl,
1617        )?;
1618
1619        apply_component_flag(
1620            SecDescComponent::Owner,
1621            mask.contains(SecInfo::OWNER),
1622            &mut control,
1623            SecDescControl::OWNER_DEFAULTED.bits(),
1624            flag_update(
1625                set_flags,
1626                clear_flags,
1627                SecDescControl::OWNER_DEFAULTED.bits(),
1628            ),
1629        )?;
1630        apply_component_flag(
1631            SecDescComponent::Group,
1632            mask.contains(SecInfo::GROUP),
1633            &mut control,
1634            SecDescControl::GROUP_DEFAULTED.bits(),
1635            flag_update(
1636                set_flags,
1637                clear_flags,
1638                SecDescControl::GROUP_DEFAULTED.bits(),
1639            ),
1640        )?;
1641        for (name, loaded, flag, value) in [
1642            (
1643                SecDescComponent::Dacl,
1644                mask.contains(SecInfo::DACL),
1645                SecDescControl::DACL_DEFAULTED.bits(),
1646                flag_update(
1647                    set_flags,
1648                    clear_flags,
1649                    SecDescControl::DACL_DEFAULTED.bits(),
1650                ),
1651            ),
1652            (
1653                SecDescComponent::Dacl,
1654                mask.contains(SecInfo::DACL),
1655                SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(),
1656                flag_update(
1657                    set_flags,
1658                    clear_flags,
1659                    SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(),
1660                ),
1661            ),
1662            (
1663                SecDescComponent::Dacl,
1664                mask.contains(SecInfo::DACL),
1665                SecDescControl::DACL_AUTO_INHERITED.bits(),
1666                flag_update(
1667                    set_flags,
1668                    clear_flags,
1669                    SecDescControl::DACL_AUTO_INHERITED.bits(),
1670                ),
1671            ),
1672            (
1673                SecDescComponent::Dacl,
1674                mask.contains(SecInfo::DACL),
1675                SecDescControl::DACL_PROTECTED.bits(),
1676                flag_update(
1677                    set_flags,
1678                    clear_flags,
1679                    SecDescControl::DACL_PROTECTED.bits(),
1680                ),
1681            ),
1682            (
1683                SecDescComponent::Sacl,
1684                mask.contains(SecInfo::SACL),
1685                SecDescControl::SACL_DEFAULTED.bits(),
1686                flag_update(
1687                    set_flags,
1688                    clear_flags,
1689                    SecDescControl::SACL_DEFAULTED.bits(),
1690                ),
1691            ),
1692            (
1693                SecDescComponent::Sacl,
1694                mask.contains(SecInfo::SACL),
1695                SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(),
1696                flag_update(
1697                    set_flags,
1698                    clear_flags,
1699                    SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(),
1700                ),
1701            ),
1702            (
1703                SecDescComponent::Sacl,
1704                mask.contains(SecInfo::SACL),
1705                SecDescControl::SACL_AUTO_INHERITED.bits(),
1706                flag_update(
1707                    set_flags,
1708                    clear_flags,
1709                    SecDescControl::SACL_AUTO_INHERITED.bits(),
1710                ),
1711            ),
1712            (
1713                SecDescComponent::Sacl,
1714                mask.contains(SecInfo::SACL),
1715                SecDescControl::SACL_PROTECTED.bits(),
1716                flag_update(
1717                    set_flags,
1718                    clear_flags,
1719                    SecDescControl::SACL_PROTECTED.bits(),
1720                ),
1721            ),
1722        ] {
1723            apply_component_flag(name, loaded, &mut control, flag, value)?;
1724        }
1725
1726        let rm_control = match rm_control_update {
1727            Some(Some(value)) => {
1728                set_control(&mut control, SecDescControl::RM_CONTROL_VALID.bits(), true);
1729                value
1730            }
1731            Some(None) => {
1732                set_control(&mut control, SecDescControl::RM_CONTROL_VALID.bits(), false);
1733                0
1734            }
1735            None => self.rm_control,
1736        };
1737
1738        Ok(Self {
1739            mask,
1740            revision: self.revision,
1741            rm_control,
1742            control: SecDescControl::from_bits_retain(control),
1743            owner,
1744            group,
1745            dacl,
1746            sacl,
1747        })
1748    }
1749}
1750
1751fn set_control(control: &mut u16, flag: u16, value: bool) {
1752    if value {
1753        *control |= flag;
1754    } else {
1755        *control &= !flag;
1756    }
1757}
1758
1759fn flag_update(set_flags: u16, clear_flags: u16, flag: u16) -> Option<bool> {
1760    if set_flags & flag != 0 {
1761        Some(true)
1762    } else if clear_flags & flag != 0 {
1763        Some(false)
1764    } else {
1765        None
1766    }
1767}
1768
1769fn apply_component_flag(
1770    component: SecDescComponent,
1771    loaded: bool,
1772    control: &mut u16,
1773    flag: u16,
1774    value: Option<bool>,
1775) -> Result<(), SecDescError> {
1776    if let Some(value) = value {
1777        if !loaded {
1778            return Err(SecDescError::ComponentNotLoaded(component));
1779        }
1780        set_control(control, flag, value);
1781    }
1782    Ok(())
1783}
1784
1785#[allow(clippy::too_many_arguments)]
1786fn apply_presence(
1787    acl_kind: AclKind,
1788    mask: &mut SecInfo,
1789    control: &mut u16,
1790    mask_flag: SecInfo,
1791    present_flag: u16,
1792    requested: Option<bool>,
1793    explicit: bool,
1794    mut acl: Option<AclBuf>,
1795) -> Result<Option<AclBuf>, SecDescError> {
1796    if let Some(present) = requested {
1797        let was_loaded = mask.contains(mask_flag);
1798        if !present {
1799            if explicit {
1800                return Err(SecDescError::AclPresenceConflict(acl_kind));
1801            }
1802            acl = None;
1803            set_control(control, present_flag, false);
1804        } else {
1805            if !explicit && (!was_loaded || *control & present_flag == 0) {
1806                return Err(SecDescError::AclPresenceRequiresValue(acl_kind));
1807            }
1808            set_control(control, present_flag, true);
1809        }
1810        *mask |= mask_flag;
1811    }
1812    Ok(acl)
1813}
1814
1815fn packet_offset(
1816    bytes: &[u8],
1817    at: usize,
1818    component: SecDescComponent,
1819) -> Result<usize, SecDescError> {
1820    let offset = u32::from_le_bytes(bytes[at..at + 4].try_into().unwrap());
1821    usize::try_from(offset).map_err(|_| SecDescError::PacketOffset(component, offset))
1822}
1823
1824fn validate_offset(
1825    bytes: &[u8],
1826    offset: usize,
1827    component: SecDescComponent,
1828) -> Result<(), SecDescError> {
1829    if offset < SELF_RELATIVE_HEADER_LEN || !offset.is_multiple_of(4) || offset >= bytes.len() {
1830        return Err(SecDescError::PacketOffset(
1831            component,
1832            u32::try_from(offset).unwrap_or(u32::MAX),
1833        ));
1834    }
1835    Ok(())
1836}
1837
1838fn parse_sid(
1839    bytes: &[u8],
1840    offset: usize,
1841    component: SecDescComponent,
1842) -> Result<Option<Sid>, SecDescError> {
1843    if offset == 0 {
1844        return Ok(None);
1845    }
1846    validate_offset(bytes, offset, component)?;
1847    let header = bytes
1848        .get(offset..offset + 8)
1849        .ok_or(SecDescError::PacketComponent(component))?;
1850    let length = 8 + usize::from(header[1]) * 4;
1851    let sid = bytes
1852        .get(offset..offset + length)
1853        .ok_or(SecDescError::PacketComponent(component))?;
1854    Sid::from_bytes(sid)
1855        .map(Some)
1856        .map_err(|_| SecDescError::PacketComponent(component))
1857}
1858
1859fn parse_acl(
1860    bytes: &[u8],
1861    offset: usize,
1862    acl_kind: AclKind,
1863) -> Result<Option<AclBuf>, SecDescError> {
1864    if offset == 0 {
1865        return Ok(None);
1866    }
1867    validate_offset(bytes, offset, acl_kind.component())?;
1868    let header = bytes
1869        .get(offset..offset + ACL_HEADER_LEN)
1870        .ok_or(SecDescError::PacketComponent(acl_kind.component()))?;
1871    let length = usize::from(u16::from_le_bytes(header[2..4].try_into().unwrap()));
1872    let acl = bytes
1873        .get(offset..offset + length)
1874        .ok_or(SecDescError::PacketComponent(acl_kind.component()))?;
1875    AclBuf::try_from_bytes(acl.to_vec().into_boxed_slice())
1876        .map(Some)
1877        .map_err(|error| SecDescError::Acl(acl_kind, error))
1878}
1879
1880fn append_component(bytes: &mut Vec<u8>, offset_at: usize, component: Option<&[u8]>) {
1881    let Some(component) = component else {
1882        return;
1883    };
1884    let offset = u32::try_from(bytes.len()).expect("security descriptor exceeds 4 GiB");
1885    bytes[offset_at..offset_at + 4].copy_from_slice(&offset.to_le_bytes());
1886    bytes.extend_from_slice(component);
1887}
1888
1889fn validate_acl(
1890    acl_kind: AclKind,
1891    loaded: bool,
1892    present: bool,
1893    acl: Option<&AclBuf>,
1894) -> Result<(), SecDescError> {
1895    let Some(_acl) = acl else {
1896        return Ok(());
1897    };
1898    if !loaded {
1899        return Err(SecDescError::AclNotLoaded(acl_kind));
1900    }
1901    if !present {
1902        return Err(SecDescError::AclNotPresent(acl_kind));
1903    }
1904    Ok(())
1905}
1906
1907impl Serialize for SecDesc {
1908    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1909    where
1910        S: Serializer,
1911    {
1912        let mut tuple = serializer.serialize_tuple(8)?;
1913        tuple.serialize_element(&self.mask.bits())?;
1914        tuple.serialize_element(&(self.revision as u8))?;
1915        tuple.serialize_element(&self.rm_control)?;
1916        tuple.serialize_element(&self.control.bits())?;
1917        tuple.serialize_element(&self.owner)?;
1918        tuple.serialize_element(&self.group)?;
1919        tuple.serialize_element(&self.dacl)?;
1920        tuple.serialize_element(&self.sacl)?;
1921        tuple.end()
1922    }
1923}
1924
1925impl<'de> Deserialize<'de> for SecDesc {
1926    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1927    where
1928        D: Deserializer<'de>,
1929    {
1930        struct SecDescVisitor;
1931
1932        impl<'de> Visitor<'de> for SecDescVisitor {
1933            type Value = SecDesc;
1934
1935            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1936                formatter.write_str("a structurally encoded Windows security descriptor")
1937            }
1938
1939            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1940            where
1941                A: SeqAccess<'de>,
1942            {
1943                let mask = SecInfo::from_bits_retain(next(&mut seq, 0, &self)?);
1944                match next(&mut seq, 1, &self)? {
1945                    REVISION => {}
1946                    revision => return Err(de::Error::custom(SecDescError::Revision(revision))),
1947                }
1948                let rm_control = next(&mut seq, 2, &self)?;
1949                let control = SecDescControl::from_bits_retain(next(&mut seq, 3, &self)?);
1950                let owner = next(&mut seq, 4, &self)?;
1951                let group = next(&mut seq, 5, &self)?;
1952                let dacl = next(&mut seq, 6, &self)?;
1953                let sacl = next(&mut seq, 7, &self)?;
1954                SecDesc::new(mask, rm_control, control, owner, group, dacl, sacl)
1955                    .map_err(de::Error::custom)
1956            }
1957        }
1958
1959        fn next<'de, A, T>(
1960            seq: &mut A,
1961            index: usize,
1962            visitor: &dyn de::Expected,
1963        ) -> Result<T, A::Error>
1964        where
1965            A: SeqAccess<'de>,
1966            T: Deserialize<'de>,
1967        {
1968            seq.next_element()?
1969                .ok_or_else(|| de::Error::invalid_length(index, visitor))
1970        }
1971
1972        deserializer.deserialize_tuple(8, SecDescVisitor)
1973    }
1974}
1975
1976/// Error returned when constructing or deserializing a security descriptor.
1977#[derive(Debug, Clone, PartialEq, Eq)]
1978pub enum SecDescError {
1979    /// The descriptor uses an unsupported revision.
1980    Revision(u8),
1981    /// An owner SID was supplied without loading the owner component.
1982    OwnerNotLoaded,
1983    /// A group SID was supplied without loading the group component.
1984    GroupNotLoaded,
1985    /// An ACL was supplied without loading its component.
1986    AclNotLoaded(AclKind),
1987    /// An ACL was supplied while its present bit is clear.
1988    AclNotPresent(AclKind),
1989    /// An update supplies an ACL while explicitly marking it absent.
1990    AclPresenceConflict(AclKind),
1991    /// An update marks an unloaded or absent ACL present without supplying one.
1992    AclPresenceRequiresValue(AclKind),
1993    /// An update changes a control bit for an unloaded component.
1994    ComponentNotLoaded(SecDescComponent),
1995    /// A supplied ACL packet is malformed.
1996    Acl(AclKind, AclError),
1997    /// The self-relative descriptor header is truncated.
1998    PacketLength,
1999    /// The descriptor is in absolute rather than self-relative form.
2000    NotSelfRelative,
2001    /// A component offset is invalid or misaligned.
2002    PacketOffset(SecDescComponent, u32),
2003    /// A component packet is truncated or malformed.
2004    PacketComponent(SecDescComponent),
2005}
2006
2007impl fmt::Display for SecDescError {
2008    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2009        match self {
2010            Self::Revision(revision) => {
2011                write!(f, "unsupported security descriptor revision {revision}")
2012            }
2013            Self::OwnerNotLoaded => f.write_str("owner SID supplied when owner was not loaded"),
2014            Self::GroupNotLoaded => f.write_str("group SID supplied when group was not loaded"),
2015            Self::AclNotLoaded(name) => write!(f, "{name} supplied when it was not loaded"),
2016            Self::AclNotPresent(name) => {
2017                write!(f, "{name} supplied when its PRESENT control bit is clear")
2018            }
2019            Self::AclPresenceConflict(name) => {
2020                write!(f, "{name} cannot be supplied with presence false")
2021            }
2022            Self::AclPresenceRequiresValue(name) => {
2023                write!(
2024                    f,
2025                    "{name} presence true requires an existing or supplied ACL"
2026                )
2027            }
2028            Self::ComponentNotLoaded(name) => {
2029                write!(f, "cannot update control flags for unloaded {name}")
2030            }
2031            Self::Acl(name, error) => write!(f, "invalid {name}: {error}"),
2032            Self::PacketLength => f.write_str("security descriptor packet is too short"),
2033            Self::NotSelfRelative => f.write_str("security descriptor packet is not self-relative"),
2034            Self::PacketOffset(name, offset) => {
2035                write!(f, "security descriptor {name} has invalid offset {offset}")
2036            }
2037            Self::PacketComponent(name) => {
2038                write!(f, "security descriptor contains an invalid {name}")
2039            }
2040        }
2041    }
2042}
2043
2044impl error::Error for SecDescError {}
2045
2046#[cfg(test)]
2047mod tests {
2048    use super::*;
2049
2050    fn sid(value: &str) -> Sid {
2051        value.parse().unwrap()
2052    }
2053
2054    fn acl(size: u16) -> Vec<u8> {
2055        let mut value = vec![0; usize::from(size)];
2056        value[0] = 2;
2057        value[2..4].copy_from_slice(&size.to_le_bytes());
2058        value
2059    }
2060
2061    fn valid_acl(size: u16) -> AclBuf {
2062        AclBuf::try_from_bytes(acl(size).into_boxed_slice()).unwrap()
2063    }
2064
2065    fn ace(ace_type: u8, flags: u8, mask: u32, sid: &Sid, application: &[u8]) -> Vec<u8> {
2066        let mut value = vec![ace_type, flags, 0, 0];
2067        value.extend_from_slice(&mask.to_le_bytes());
2068        value.extend_from_slice(&sid.to_bytes());
2069        value.extend_from_slice(application);
2070        let size = u16::try_from(value.len()).unwrap();
2071        value[2..4].copy_from_slice(&size.to_le_bytes());
2072        value
2073    }
2074
2075    fn acl_with_aces(aces: &[Vec<u8>], tail: &[u8]) -> Vec<u8> {
2076        let size = ACL_HEADER_LEN + aces.iter().map(Vec::len).sum::<usize>() + tail.len();
2077        let mut value = vec![2, 0];
2078        value.extend_from_slice(&u16::try_from(size).unwrap().to_le_bytes());
2079        value.extend_from_slice(&u16::try_from(aces.len()).unwrap().to_le_bytes());
2080        value.extend_from_slice(&[0, 0]);
2081        for ace in aces {
2082            value.extend_from_slice(ace);
2083        }
2084        value.extend_from_slice(tail);
2085        value
2086    }
2087
2088    #[test]
2089    fn exposes_known_and_unknown_aces_without_losing_bytes() {
2090        let trustee = sid("S-1-5-32-544");
2091        let known = ace(0, 0x13, 0x1234_5678, &trustee, &[0xde, 0xad, 0xbe, 0xef]);
2092        let unknown = vec![0x7f, 0xa0, 8, 0, 0x11, 0x22, 0x33, 0x44];
2093        let bytes = acl_with_aces(&[known.clone(), unknown.clone()], &[0xaa, 0xbb, 0xcc, 0xdd]);
2094        let acl = Acl::from_bytes(&bytes).unwrap();
2095
2096        assert_eq!(acl.revision(), AclRevision::Basic);
2097        assert_eq!(usize::from(acl.size()), bytes.len());
2098        assert_eq!(acl.ace_count(), 2);
2099        assert_eq!(acl.as_bytes(), bytes);
2100
2101        let mut aces = acl.aces();
2102        let first = aces.next().unwrap();
2103        assert_eq!(first.ace_type(), AceType::AccessAllowed);
2104        assert_eq!(first.flags().bits(), 0x13);
2105        assert_eq!(first.mask().map(|mask| mask.bits()), Some(0x1234_5678));
2106        assert_eq!(first.sid(), Some(trustee));
2107        assert_eq!(
2108            first.application_data(),
2109            Some(&[0xde, 0xad, 0xbe, 0xef][..])
2110        );
2111        assert_eq!(first.as_bytes(), known);
2112
2113        let second = aces.next().unwrap();
2114        assert_eq!(second.ace_type(), AceType::Unknown(0x7f));
2115        assert_eq!(second.mask(), None);
2116        assert_eq!(second.application_data(), None);
2117        assert_eq!(second.as_bytes(), unknown);
2118        assert_eq!(aces.next(), None);
2119    }
2120
2121    #[test]
2122    fn parses_object_ace_guids_and_application_data() {
2123        let object_type: Guid = "00112233-4455-6677-8899-aabbccddeeff".parse().unwrap();
2124        let inherited_type: Guid = "ffeeddcc-bbaa-9988-7766-554433221100".parse().unwrap();
2125        let trustee = sid("S-1-1-0");
2126        for object_flags in 0..=3u32 {
2127            let mut bytes = vec![11, 0, 0, 0];
2128            bytes.extend_from_slice(&0x90ab_cdefu32.to_le_bytes());
2129            bytes.extend_from_slice(&object_flags.to_le_bytes());
2130            if object_flags & 1 != 0 {
2131                bytes.extend_from_slice(&object_type.to_bytes());
2132            }
2133            if object_flags & 2 != 0 {
2134                bytes.extend_from_slice(&inherited_type.to_bytes());
2135            }
2136            bytes.extend_from_slice(&trustee.to_bytes());
2137            bytes.extend_from_slice(&[1, 2, 3, 4]);
2138            let size = u16::try_from(bytes.len()).unwrap();
2139            bytes[2..4].copy_from_slice(&size.to_le_bytes());
2140
2141            let ace = Ace::from_bytes(&bytes).unwrap();
2142            assert_eq!(ace.ace_type(), AceType::AccessAllowedCallbackObject);
2143            assert_eq!(
2144                ace.object_flags().map(|flags| flags.bits()),
2145                Some(object_flags)
2146            );
2147            assert_eq!(
2148                ace.object_type(),
2149                (object_flags & 1 != 0).then_some(object_type)
2150            );
2151            assert_eq!(
2152                ace.inherited_object_type(),
2153                (object_flags & 2 != 0).then_some(inherited_type)
2154            );
2155            assert_eq!(ace.sid(), Some(trustee.clone()));
2156            assert_eq!(ace.application_data(), Some(&[1, 2, 3, 4][..]));
2157        }
2158    }
2159
2160    #[test]
2161    fn rejects_untraversable_or_malformed_aces() {
2162        let mut count_mismatch = acl(8);
2163        count_mismatch[4..6].copy_from_slice(&1u16.to_le_bytes());
2164        assert_eq!(
2165            Acl::from_bytes(&count_mismatch),
2166            Err(AclError::AceCount(1, 0))
2167        );
2168
2169        let malformed = vec![0, 0, 8, 0, 0, 0, 0, 0];
2170        let bytes = acl_with_aces(&[malformed], &[]);
2171        assert_eq!(
2172            Acl::from_bytes(&bytes),
2173            Err(AclError::Ace(0, AceError::Sid))
2174        );
2175
2176        let overrun = vec![0x7f, 0, 12, 0, 0, 0, 0, 0];
2177        let bytes = acl_with_aces(&[overrun], &[]);
2178        assert_eq!(
2179            Acl::from_bytes(&bytes),
2180            Err(AclError::Ace(0, AceError::Bounds(12)))
2181        );
2182    }
2183
2184    #[test]
2185    fn represents_loaded_absent_null_and_non_null_components() {
2186        let unloaded = SecDesc::new(
2187            SecInfo::empty(),
2188            0,
2189            SecDescControl::empty(),
2190            None,
2191            None,
2192            None,
2193            None,
2194        )
2195        .unwrap();
2196        assert!(!unloaded.owner_loaded());
2197        assert!(!unloaded.dacl_loaded());
2198
2199        let absent = SecDesc::new(
2200            SecInfo::OWNER | SecInfo::DACL,
2201            0,
2202            SecDescControl::empty(),
2203            None,
2204            None,
2205            None,
2206            None,
2207        )
2208        .unwrap();
2209        assert!(absent.owner_loaded());
2210        assert_eq!(absent.owner(), None);
2211        assert!(absent.dacl_loaded());
2212        assert!(!absent.dacl_present());
2213
2214        let null = SecDesc::new(
2215            SecInfo::DACL,
2216            0,
2217            SecDescControl::DACL_PRESENT,
2218            None,
2219            None,
2220            None,
2221            None,
2222        )
2223        .unwrap();
2224        assert!(null.dacl_present());
2225        assert_eq!(null.dacl(), None);
2226
2227        let bytes = valid_acl(8);
2228        let present = SecDesc::new(
2229            SecInfo::DACL,
2230            0,
2231            SecDescControl::DACL_PRESENT,
2232            None,
2233            None,
2234            Some(bytes.clone()),
2235            None,
2236        )
2237        .unwrap();
2238        assert_eq!(present.dacl().map(Acl::as_bytes), Some(bytes.as_bytes()));
2239    }
2240
2241    #[test]
2242    fn rejects_inconsistent_components() {
2243        assert_eq!(
2244            SecDesc::new(
2245                SecInfo::empty(),
2246                0,
2247                SecDescControl::empty(),
2248                Some(sid("S-1-5-18")),
2249                None,
2250                None,
2251                None,
2252            ),
2253            Err(SecDescError::OwnerNotLoaded)
2254        );
2255        assert_eq!(
2256            SecDesc::new(
2257                SecInfo::empty(),
2258                0,
2259                SecDescControl::empty(),
2260                None,
2261                Some(sid("S-1-5-18")),
2262                None,
2263                None,
2264            ),
2265            Err(SecDescError::GroupNotLoaded)
2266        );
2267        assert_eq!(
2268            SecDesc::new(
2269                SecInfo::empty(),
2270                0,
2271                SecDescControl::DACL_PRESENT,
2272                None,
2273                None,
2274                Some(valid_acl(8)),
2275                None
2276            ),
2277            Err(SecDescError::AclNotLoaded(AclKind::Dacl))
2278        );
2279        assert_eq!(
2280            SecDesc::new(
2281                SecInfo::DACL,
2282                0,
2283                SecDescControl::empty(),
2284                None,
2285                None,
2286                Some(valid_acl(8)),
2287                None,
2288            ),
2289            Err(SecDescError::AclNotPresent(AclKind::Dacl))
2290        );
2291    }
2292
2293    #[test]
2294    fn validates_acl_packet_and_ace_boundaries() {
2295        assert_eq!(
2296            AclBuf::try_from_bytes(vec![0; 4].into_boxed_slice()),
2297            Err(AclError::Length(4))
2298        );
2299
2300        let mut wrong_size = acl(8);
2301        wrong_size.extend_from_slice(&[0; 4]);
2302        assert_eq!(
2303            AclBuf::try_from_bytes(wrong_size.into_boxed_slice()),
2304            Err(AclError::Size(8, 12))
2305        );
2306
2307        let mut opaque = acl(12);
2308        opaque[8..].copy_from_slice(&[0xff; 4]);
2309        let opaque = unsafe { AclBuf::from_bytes_unchecked(opaque.into_boxed_slice()) };
2310        let descriptor = SecDesc::new(
2311            SecInfo::DACL,
2312            0,
2313            SecDescControl::DACL_PRESENT,
2314            None,
2315            None,
2316            Some(opaque.clone()),
2317            None,
2318        )
2319        .unwrap();
2320        assert_eq!(
2321            descriptor.dacl().map(Acl::as_bytes),
2322            Some(opaque.as_bytes())
2323        );
2324    }
2325
2326    #[test]
2327    fn projects_control_flags_and_normalizes_storage_form() {
2328        let control = SecDescControl::OWNER_DEFAULTED.bits()
2329            | SecDescControl::GROUP_DEFAULTED.bits()
2330            | SecDescControl::DACL_DEFAULTED.bits()
2331            | SecDescControl::SACL_DEFAULTED.bits()
2332            | SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits()
2333            | SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits()
2334            | SecDescControl::DACL_AUTO_INHERITED.bits()
2335            | SecDescControl::SACL_AUTO_INHERITED.bits()
2336            | SecDescControl::DACL_PROTECTED.bits()
2337            | SecDescControl::SACL_PROTECTED.bits()
2338            | SecDescControl::RM_CONTROL_VALID.bits()
2339            | SecDescControl::SELF_RELATIVE.bits();
2340        let descriptor = SecDesc::new(
2341            SecInfo::empty(),
2342            0x5a,
2343            SecDescControl::from_bits_retain(control),
2344            None,
2345            None,
2346            None,
2347            None,
2348        )
2349        .unwrap();
2350        assert_eq!(descriptor.rm_control(), Some(0x5a));
2351        assert!(descriptor.owner_defaulted());
2352        assert!(descriptor.group_defaulted());
2353        assert!(descriptor.dacl_defaulted());
2354        assert!(descriptor.sacl_defaulted());
2355        assert!(descriptor.dacl_auto_inherit_required());
2356        assert!(descriptor.sacl_auto_inherit_required());
2357        assert!(descriptor.dacl_auto_inherited());
2358        assert!(descriptor.sacl_auto_inherited());
2359        assert!(descriptor.dacl_protected());
2360        assert!(descriptor.sacl_protected());
2361        assert!(!descriptor.control().contains(SecDescControl::SELF_RELATIVE));
2362
2363        let descriptor = SecDesc::new(
2364            SecInfo::empty(),
2365            0x5a,
2366            SecDescControl::empty(),
2367            None,
2368            None,
2369            None,
2370            None,
2371        )
2372        .unwrap();
2373        assert_eq!(descriptor.rm_control(), None);
2374    }
2375
2376    #[test]
2377    fn serde_is_structural_and_validated() {
2378        let owner = sid("S-1-5-18");
2379        let dacl = valid_acl(8);
2380        let descriptor = SecDesc::new(
2381            SecInfo::OWNER | SecInfo::DACL,
2382            0x42,
2383            SecDescControl::DACL_PRESENT | SecDescControl::RM_CONTROL_VALID,
2384            Some(owner.clone()),
2385            None,
2386            Some(dacl.clone()),
2387            None,
2388        )
2389        .unwrap();
2390        let encoded = postcard::to_stdvec(&descriptor).unwrap();
2391        let expected = postcard::to_stdvec(&(
2392            (SecInfo::OWNER | SecInfo::DACL).bits(),
2393            1u8,
2394            0x42u8,
2395            SecDescControl::DACL_PRESENT.bits() | SecDescControl::RM_CONTROL_VALID.bits(),
2396            Some(owner),
2397            Option::<Sid>::None,
2398            Some(dacl),
2399            Option::<Vec<u8>>::None,
2400        ))
2401        .unwrap();
2402        assert_eq!(encoded, expected);
2403        assert_eq!(
2404            postcard::from_bytes::<SecDesc>(&encoded).unwrap(),
2405            descriptor
2406        );
2407
2408        let malformed = postcard::to_stdvec(&(
2409            0u32,
2410            2u8,
2411            0u8,
2412            0u16,
2413            Option::<Sid>::None,
2414            Option::<Sid>::None,
2415            Option::<Vec<u8>>::None,
2416            Option::<Vec<u8>>::None,
2417        ))
2418        .unwrap();
2419        assert!(postcard::from_bytes::<SecDesc>(&malformed).is_err());
2420    }
2421
2422    #[test]
2423    fn flag_and_revision_serde_preserve_native_values() {
2424        let info = SecInfo::OWNER | SecInfo::DACL;
2425        let control = SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED;
2426        assert_eq!(
2427            postcard::to_stdvec(&info).unwrap(),
2428            postcard::to_stdvec(&info.bits()).unwrap()
2429        );
2430        assert_eq!(
2431            postcard::to_stdvec(&control).unwrap(),
2432            postcard::to_stdvec(&control.bits()).unwrap()
2433        );
2434        assert_eq!(postcard::to_stdvec(&Revision::One).unwrap(), vec![REVISION]);
2435        assert!(postcard::from_bytes::<Revision>(&[2]).is_err());
2436
2437        for flags in [
2438            AceFlags::OBJECT_INHERIT | AceFlags::FAILED_ACCESS,
2439            AceFlags::from_bits_retain(0xff),
2440        ] {
2441            let encoded = postcard::to_stdvec(&flags).unwrap();
2442            assert_eq!(encoded, postcard::to_stdvec(&flags.bits()).unwrap());
2443            assert_eq!(postcard::from_bytes::<AceFlags>(&encoded).unwrap(), flags);
2444        }
2445        let object_flags = ObjectAceFlags::from_bits_retain(0x8000_0001);
2446        let encoded = postcard::to_stdvec(&object_flags).unwrap();
2447        assert_eq!(encoded, postcard::to_stdvec(&object_flags.bits()).unwrap());
2448        assert_eq!(
2449            postcard::from_bytes::<ObjectAceFlags>(&encoded).unwrap(),
2450            object_flags
2451        );
2452
2453        for ace_type in [AceType::AccessAllowed, AceType::Unknown(0xfe)] {
2454            let encoded = postcard::to_stdvec(&ace_type).unwrap();
2455            assert_eq!(encoded, vec![u8::from(ace_type)]);
2456            assert_eq!(postcard::from_bytes::<AceType>(&encoded).unwrap(), ace_type);
2457        }
2458        for revision in [
2459            AclRevision::Basic,
2460            AclRevision::DirectoryService,
2461            AclRevision::Unknown(3),
2462        ] {
2463            let encoded = postcard::to_stdvec(&revision).unwrap();
2464            assert_eq!(encoded, vec![u8::from(revision)]);
2465            assert_eq!(
2466                postcard::from_bytes::<AclRevision>(&encoded).unwrap(),
2467                revision
2468            );
2469        }
2470    }
2471
2472    #[test]
2473    fn self_relative_packet_round_trip() {
2474        let packet = [
2475            0x01, 0x5a, 0x15, 0xd0, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
2476            0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
2477            0x12, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
2478            0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
2479        ];
2480        let descriptor = SecDesc::from_bytes(&packet).unwrap();
2481        assert_eq!(descriptor.mask(), SecInfo::ALL);
2482        assert_eq!(descriptor.control().bits(), 0x5015);
2483        assert_eq!(descriptor.rm_control(), Some(0x5a));
2484        assert_eq!(descriptor.owner().unwrap().to_string(), "S-1-5-18");
2485        assert_eq!(descriptor.group().unwrap().to_string(), "S-1-5-32-544");
2486        assert!(descriptor.sacl_present());
2487        assert_eq!(descriptor.sacl(), None);
2488        assert_eq!(descriptor.dacl().map(Acl::as_bytes), Some(&packet[48..]));
2489        assert_eq!(descriptor.to_bytes(), packet);
2490    }
2491
2492    #[test]
2493    fn self_relative_parser_tracks_selected_components() {
2494        let descriptor = SecDesc::new(
2495            SecInfo::ALL,
2496            0,
2497            SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED,
2498            Some(sid("S-1-5-18")),
2499            Some(sid("S-1-5-32-544")),
2500            Some(valid_acl(8)),
2501            None,
2502        )
2503        .unwrap();
2504        let packet = descriptor.to_bytes();
2505
2506        let selected = SecDesc::from_bytes_with_mask(&packet, SecInfo::DACL).unwrap();
2507        assert_eq!(selected.mask(), SecInfo::DACL);
2508        assert!(!selected.owner_loaded());
2509        assert_eq!(selected.owner(), None);
2510        assert!(selected.dacl_loaded());
2511        assert_eq!(
2512            selected.dacl().map(Acl::as_bytes),
2513            Some(valid_acl(8).as_bytes())
2514        );
2515        assert!(selected.dacl_protected());
2516
2517        let empty = SecDesc::from_bytes_with_mask(&packet, SecInfo::empty()).unwrap();
2518        assert_eq!(empty.mask(), SecInfo::empty());
2519        assert_eq!(
2520            empty.control(),
2521            SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED
2522        );
2523        assert_eq!(empty.owner(), None);
2524        assert_eq!(empty.dacl(), None);
2525    }
2526
2527    #[test]
2528    fn self_relative_packet_writer_uses_canonical_component_order() {
2529        let descriptor = SecDesc::new(
2530            SecInfo::ALL,
2531            0,
2532            SecDescControl::DACL_PRESENT,
2533            Some(sid("S-1-5-18")),
2534            Some(sid("S-1-5-32-544")),
2535            Some(valid_acl(8)),
2536            None,
2537        )
2538        .unwrap();
2539        let packet = descriptor.to_bytes();
2540        assert_eq!(u32::from_le_bytes(packet[4..8].try_into().unwrap()), 20);
2541        assert_eq!(u32::from_le_bytes(packet[8..12].try_into().unwrap()), 32);
2542        assert_eq!(u32::from_le_bytes(packet[12..16].try_into().unwrap()), 0);
2543        assert_eq!(u32::from_le_bytes(packet[16..20].try_into().unwrap()), 48);
2544        assert_eq!(SecDesc::from_bytes(&packet).unwrap(), descriptor);
2545    }
2546
2547    #[test]
2548    fn rejects_malformed_self_relative_packets() {
2549        assert_eq!(
2550            SecDesc::from_bytes(&[0; SELF_RELATIVE_HEADER_LEN - 1]),
2551            Err(SecDescError::PacketLength)
2552        );
2553
2554        let mut packet = [0; SELF_RELATIVE_HEADER_LEN];
2555        packet[0] = 1;
2556        assert_eq!(
2557            SecDesc::from_bytes(&packet),
2558            Err(SecDescError::NotSelfRelative)
2559        );
2560
2561        packet[2..4].copy_from_slice(&SecDescControl::SELF_RELATIVE.bits().to_le_bytes());
2562        packet[4..8].copy_from_slice(&4u32.to_le_bytes());
2563        assert_eq!(
2564            SecDesc::from_bytes(&packet),
2565            Err(SecDescError::PacketOffset(SecDescComponent::Owner, 4))
2566        );
2567
2568        packet[4..8].copy_from_slice(&20u32.to_le_bytes());
2569        assert_eq!(
2570            SecDesc::from_bytes(&packet),
2571            Err(SecDescError::PacketOffset(SecDescComponent::Owner, 20))
2572        );
2573    }
2574
2575    #[test]
2576    fn owned_ace_builders_select_layouts_and_pad_application_data() {
2577        let trustee = sid("S-1-1-0");
2578        let object_type: Guid = "00112233-4455-6677-8899-aabbccddeeff".parse().unwrap();
2579        let basic = AceBuf::allow(
2580            &trustee,
2581            AccessMask::from_bits_retain(0x1234),
2582            AceBuildOptions::new()
2583                .flags(AceFlags::from_bits_retain(0x03))
2584                .application_data([1, 2, 3]),
2585        )
2586        .unwrap();
2587        assert_eq!(basic.ace_type(), AceType::AccessAllowed);
2588        assert_eq!(basic.flags().bits(), 0x03);
2589        assert_eq!(basic.application_data(), Some(&[1, 2, 3, 0][..]));
2590        assert_eq!(Ace::from_bytes(basic.as_bytes()).unwrap(), &*basic);
2591
2592        let object = AceBuf::deny(
2593            &trustee,
2594            AccessMask::from_bits_retain(u32::MAX),
2595            AceBuildOptions::new().object_type(object_type).callback(),
2596        )
2597        .unwrap();
2598        assert_eq!(object.ace_type(), AceType::AccessDeniedCallbackObject);
2599        assert_eq!(
2600            object.object_flags(),
2601            Some(ObjectAceFlags::OBJECT_TYPE_PRESENT)
2602        );
2603        assert_eq!(object.object_type(), Some(object_type));
2604        assert_eq!(object.inherited_object_type(), None);
2605    }
2606
2607    #[test]
2608    fn audit_builder_enforces_outcomes_and_reserves_audit_flags() {
2609        let trustee = sid("S-1-5-18");
2610        assert_eq!(
2611            AceBuf::audit(
2612                &trustee,
2613                AccessMask::from_specific_rights(1),
2614                false,
2615                false,
2616                AceBuildOptions::new()
2617            ),
2618            Err(AceBuildError::AuditOutcome)
2619        );
2620        assert_eq!(
2621            AceBuf::audit(
2622                &trustee,
2623                AccessMask::from_specific_rights(1),
2624                true,
2625                false,
2626                AceBuildOptions::new().flags(AceFlags::SUCCESSFUL_ACCESS),
2627            ),
2628            Err(AceBuildError::AuditFlags)
2629        );
2630        let audit = AceBuf::audit(
2631            &trustee,
2632            AccessMask::from_specific_rights(1),
2633            true,
2634            true,
2635            AceBuildOptions::new(),
2636        )
2637        .unwrap();
2638        assert_eq!(audit.ace_type(), AceType::SystemAudit);
2639        assert_eq!(audit.flags().bits(), 0xc0);
2640    }
2641
2642    #[test]
2643    fn acl_builder_preserves_packets_and_selects_revision() {
2644        let trustee = sid("S-1-1-0");
2645        let basic = AceBuf::allow(
2646            &trustee,
2647            AccessMask::from_specific_rights(1),
2648            AceBuildOptions::new(),
2649        )
2650        .unwrap();
2651        let object = AceBuf::allow(
2652            &trustee,
2653            AccessMask::from_specific_rights(2),
2654            AceBuildOptions::new()
2655                .object_type("00000000-0000-0000-0000-000000000000".parse().unwrap()),
2656        )
2657        .unwrap();
2658        let acl = AclBuf::from_aces([&*basic], None).unwrap();
2659        assert_eq!(acl.revision(), AclRevision::Basic);
2660        assert_eq!(acl.aces().next().unwrap().as_bytes(), basic.as_bytes());
2661
2662        let acl = AclBuf::from_aces([&*basic, &*object], None).unwrap();
2663        assert_eq!(acl.revision(), AclRevision::DirectoryService);
2664        assert_eq!(
2665            AclBuf::from_aces([&*object], Some(AclRevision::Basic)),
2666            Err(AclBuildError::ObjectRevision)
2667        );
2668        assert_eq!(
2669            AclBuf::from_aces([&*basic], Some(AclRevision::Unknown(3))),
2670            Err(AclBuildError::Revision(3))
2671        );
2672        assert_eq!(Acl::from_bytes(acl.as_bytes()).unwrap(), &*acl);
2673    }
2674
2675    #[test]
2676    fn owned_packets_validate_raw_and_serde_inputs() {
2677        let trustee = sid("S-1-1-0");
2678        let ace = AceBuf::allow(
2679            &trustee,
2680            AccessMask::from_specific_rights(1),
2681            AceBuildOptions::new(),
2682        )
2683        .unwrap();
2684        let encoded = postcard::to_stdvec(&ace).unwrap();
2685        assert_eq!(postcard::from_bytes::<AceBuf>(&encoded).unwrap(), ace);
2686        assert!(AceBuf::try_from_bytes(vec![0, 0, 4, 0].into_boxed_slice()).is_err());
2687
2688        let acl = AclBuf::from_aces([&*ace], None).unwrap();
2689        let encoded = postcard::to_stdvec(&acl).unwrap();
2690        assert_eq!(postcard::from_bytes::<AclBuf>(&encoded).unwrap(), acl);
2691        let mut malformed = acl.as_bytes().to_vec();
2692        malformed[2] = 0;
2693        assert!(AclBuf::try_from_bytes(malformed.into_boxed_slice()).is_err());
2694    }
2695
2696    #[test]
2697    fn functional_updates_cover_component_states_and_controls() {
2698        let descriptor = SecDesc::new(
2699            SecInfo::empty(),
2700            0,
2701            SecDescControl::empty(),
2702            None,
2703            None,
2704            None,
2705            None,
2706        )
2707        .unwrap();
2708        let concrete = AclBuf::from_aces(std::iter::empty::<&Ace>(), None).unwrap();
2709        let updated = descriptor
2710            .with(
2711                SecDescUpdate::new()
2712                    .owner(Some(sid("S-1-5-18")))
2713                    .dacl(Some(concrete.clone()))
2714                    .owner_defaulted(true)
2715                    .dacl_protected(true)
2716                    .rm_control(Some(0x5a)),
2717            )
2718            .unwrap();
2719        assert!(!descriptor.owner_loaded());
2720        assert_eq!(updated.owner().unwrap().to_string(), "S-1-5-18");
2721        assert_eq!(updated.dacl(), Some(&*concrete));
2722        assert!(updated.dacl_present());
2723        assert!(updated.owner_defaulted());
2724        assert!(updated.dacl_protected());
2725        assert_eq!(updated.rm_control(), Some(0x5a));
2726
2727        let null = updated
2728            .with(SecDescUpdate::new().dacl(None).rm_control(None))
2729            .unwrap();
2730        assert!(null.dacl_present());
2731        assert_eq!(null.dacl(), None);
2732        assert_eq!(null.rm_control(), None);
2733
2734        let absent = null.with(SecDescUpdate::new().dacl_present(false)).unwrap();
2735        assert!(absent.dacl_loaded());
2736        assert!(!absent.dacl_present());
2737        assert_eq!(
2738            descriptor.with(SecDescUpdate::new().dacl_present(true)),
2739            Err(SecDescError::AclPresenceRequiresValue(AclKind::Dacl))
2740        );
2741        let unloaded_present = SecDesc::new(
2742            SecInfo::empty(),
2743            0,
2744            SecDescControl::DACL_PRESENT,
2745            None,
2746            None,
2747            None,
2748            None,
2749        )
2750        .unwrap();
2751        assert_eq!(
2752            unloaded_present.with(SecDescUpdate::new().dacl_present(true)),
2753            Err(SecDescError::AclPresenceRequiresValue(AclKind::Dacl))
2754        );
2755        assert_eq!(
2756            descriptor.with(SecDescUpdate::new().dacl_protected(true)),
2757            Err(SecDescError::ComponentNotLoaded(SecDescComponent::Dacl))
2758        );
2759    }
2760}