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    application_data: Vec<u8>,
650}
651
652impl AceBuildOptions {
653    /// Creates options for a plain, non-callback ACE.
654    #[allow(clippy::new_without_default)]
655    pub const fn new() -> Self {
656        Self {
657            flags: AceFlags::empty(),
658            object_type: None,
659            inherited_object_type: None,
660            callback: false,
661            application_data: Vec::new(),
662        }
663    }
664
665    /// Replaces the native ACE flags.
666    pub fn flags(mut self, flags: AceFlags) -> Self {
667        self.flags = flags;
668        self
669    }
670
671    /// Adds an object-type GUID, selecting an object ACE layout.
672    pub fn object_type(mut self, object_type: Guid) -> Self {
673        self.object_type = Some(object_type);
674        self
675    }
676
677    /// Adds an inherited-object-type GUID, selecting an object ACE layout.
678    pub fn inherited_object_type(mut self, inherited_object_type: Guid) -> Self {
679        self.inherited_object_type = Some(inherited_object_type);
680        self
681    }
682
683    /// Selects a callback ACE layout.
684    pub fn callback(mut self) -> Self {
685        self.callback = true;
686        self
687    }
688
689    /// Appends opaque application data after the trustee SID.
690    pub fn application_data(mut self, application_data: impl Into<Vec<u8>>) -> Self {
691        self.application_data = application_data.into();
692        self
693    }
694}
695
696/// An owned, validated native Windows ACE packet.
697#[derive(Clone, Debug, PartialEq, Eq, Hash)]
698pub struct AceBuf(Box<[u8]>);
699
700impl AceBuf {
701    /// Takes ownership of a raw packet after validating it.
702    pub fn try_from_bytes(bytes: impl Into<Box<[u8]>>) -> Result<Self, AceError> {
703        let bytes = bytes.into();
704        Ace::from_bytes(&bytes)?;
705        Ok(Self(bytes))
706    }
707
708    /// Builds an access-allowed ACE.
709    pub fn allow(
710        sid: &Sid,
711        mask: AccessMask,
712        options: AceBuildOptions,
713    ) -> Result<Self, AceBuildError> {
714        Self::build(AceFamily::Allow, sid, mask, false, false, options)
715    }
716
717    /// Builds an access-denied ACE.
718    pub fn deny(
719        sid: &Sid,
720        mask: AccessMask,
721        options: AceBuildOptions,
722    ) -> Result<Self, AceBuildError> {
723        Self::build(AceFamily::Deny, sid, mask, false, false, options)
724    }
725
726    /// Builds a system-audit ACE.
727    pub fn audit(
728        sid: &Sid,
729        mask: AccessMask,
730        successful: bool,
731        failed: bool,
732        options: AceBuildOptions,
733    ) -> Result<Self, AceBuildError> {
734        if !successful && !failed {
735            return Err(AceBuildError::AuditOutcome);
736        }
737        if options
738            .flags
739            .intersects(AceFlags::SUCCESSFUL_ACCESS | AceFlags::FAILED_ACCESS)
740        {
741            return Err(AceBuildError::AuditFlags);
742        }
743        Self::build(AceFamily::Audit, sid, mask, successful, failed, options)
744    }
745
746    fn build(
747        family: AceFamily,
748        sid: &Sid,
749        mask: AccessMask,
750        successful: bool,
751        failed: bool,
752        options: AceBuildOptions,
753    ) -> Result<Self, AceBuildError> {
754        let object = options.object_type.is_some() || options.inherited_object_type.is_some();
755        let type_code = match (family, options.callback, object) {
756            (AceFamily::Allow, false, false) => 0,
757            (AceFamily::Deny, false, false) => 1,
758            (AceFamily::Audit, false, false) => 2,
759            (AceFamily::Allow, false, true) => 5,
760            (AceFamily::Deny, false, true) => 6,
761            (AceFamily::Audit, false, true) => 7,
762            (AceFamily::Allow, true, false) => 9,
763            (AceFamily::Deny, true, false) => 10,
764            (AceFamily::Allow, true, true) => 11,
765            (AceFamily::Deny, true, true) => 12,
766            (AceFamily::Audit, true, false) => 13,
767            (AceFamily::Audit, true, true) => 15,
768        };
769        let mut flags = options.flags;
770        if successful {
771            flags |= AceFlags::SUCCESSFUL_ACCESS;
772        }
773        if failed {
774            flags |= AceFlags::FAILED_ACCESS;
775        }
776
777        let mut bytes = vec![type_code, flags.bits(), 0, 0];
778        bytes.extend_from_slice(&mask.bits().to_le_bytes());
779        if object {
780            let mut object_flags = ObjectAceFlags::empty();
781            object_flags.set(
782                ObjectAceFlags::OBJECT_TYPE_PRESENT,
783                options.object_type.is_some(),
784            );
785            object_flags.set(
786                ObjectAceFlags::INHERITED_OBJECT_TYPE_PRESENT,
787                options.inherited_object_type.is_some(),
788            );
789            bytes.extend_from_slice(&object_flags.bits().to_le_bytes());
790            if let Some(value) = options.object_type {
791                bytes.extend_from_slice(&value.to_bytes());
792            }
793            if let Some(value) = options.inherited_object_type {
794                bytes.extend_from_slice(&value.to_bytes());
795            }
796        }
797        bytes.extend_from_slice(&sid.to_bytes());
798        bytes.extend_from_slice(&options.application_data);
799        bytes.resize(bytes.len().next_multiple_of(4), 0);
800        let size = u16::try_from(bytes.len()).map_err(|_| AceBuildError::Size(bytes.len()))?;
801        bytes[2..4].copy_from_slice(&size.to_le_bytes());
802        Ok(Self(bytes.into_boxed_slice()))
803    }
804
805    /// Returns the owned packet bytes.
806    pub fn into_boxed_bytes(self) -> Box<[u8]> {
807        self.0
808    }
809}
810
811#[derive(Clone, Copy)]
812enum AceFamily {
813    Allow,
814    Deny,
815    Audit,
816}
817
818impl Deref for AceBuf {
819    type Target = Ace;
820
821    fn deref(&self) -> &Self::Target {
822        // The constructor invariant guarantees validation.
823        unsafe { &*(&*self.0 as *const [u8] as *const Ace) }
824    }
825}
826
827impl AsRef<Ace> for AceBuf {
828    fn as_ref(&self) -> &Ace {
829        self
830    }
831}
832
833impl Borrow<Ace> for AceBuf {
834    fn borrow(&self) -> &Ace {
835        self
836    }
837}
838
839impl ToOwned for Ace {
840    type Owned = AceBuf;
841
842    fn to_owned(&self) -> Self::Owned {
843        AceBuf(self.0.into())
844    }
845}
846
847impl Serialize for AceBuf {
848    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
849    where
850        S: Serializer,
851    {
852        self.0.serialize(serializer)
853    }
854}
855
856impl<'de> Deserialize<'de> for AceBuf {
857    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
858    where
859        D: Deserializer<'de>,
860    {
861        let bytes = Box::<[u8]>::deserialize(deserializer)?;
862        Self::try_from_bytes(bytes).map_err(de::Error::custom)
863    }
864}
865
866/// An owned, validated native Windows ACL packet.
867#[derive(Clone, Debug, PartialEq, Eq, Hash)]
868pub struct AclBuf(Box<[u8]>);
869
870impl AclBuf {
871    /// Takes ownership of a raw packet after validating it.
872    pub fn try_from_bytes(bytes: impl Into<Box<[u8]>>) -> Result<Self, AclError> {
873        let bytes = bytes.into();
874        Acl::from_bytes(&bytes)?;
875        Ok(Self(bytes))
876    }
877
878    /// Takes ownership of an ACL packet without validating it.
879    ///
880    /// # Safety
881    ///
882    /// `bytes` must contain a complete, structurally valid native ACL packet.
883    /// Violating this invariant can make methods that view it as an [`Acl`]
884    /// perform unchecked indexing.
885    pub unsafe fn from_bytes_unchecked(bytes: impl Into<Box<[u8]>>) -> Self {
886        Self(bytes.into())
887    }
888
889    /// Builds an ACL from already-validated ACE packets.
890    pub fn from_aces<I, A>(aces: I, revision: Option<AclRevision>) -> Result<Self, AclBuildError>
891    where
892        I: IntoIterator<Item = A>,
893        A: AsRef<Ace>,
894    {
895        let aces: Vec<A> = aces.into_iter().collect();
896        let mut size = ACL_HEADER_LEN;
897        let mut has_object = false;
898        for ace in &aces {
899            let ace = ace.as_ref();
900            size = size
901                .checked_add(ace.as_bytes().len())
902                .ok_or(AclBuildError::Size(usize::MAX))?;
903            has_object |= matches!(
904                ace.ace_type(),
905                AceType::AccessAllowedObject
906                    | AceType::AccessDeniedObject
907                    | AceType::SystemAuditObject
908                    | AceType::SystemAlarmObject
909                    | AceType::AccessAllowedCallbackObject
910                    | AceType::AccessDeniedCallbackObject
911                    | AceType::SystemAuditCallbackObject
912                    | AceType::SystemAlarmCallbackObject
913            );
914        }
915        let count = u16::try_from(aces.len()).map_err(|_| AclBuildError::Count(aces.len()))?;
916        let size16 = u16::try_from(size).map_err(|_| AclBuildError::Size(size))?;
917        let revision = revision.unwrap_or(if has_object {
918            AclRevision::DirectoryService
919        } else {
920            AclRevision::Basic
921        });
922        if let AclRevision::Unknown(revision) = revision {
923            return Err(AclBuildError::Revision(revision));
924        }
925        if revision == AclRevision::Basic && has_object {
926            return Err(AclBuildError::ObjectRevision);
927        }
928
929        let mut bytes = Vec::with_capacity(size);
930        bytes.extend_from_slice(&[revision.into(), 0]);
931        bytes.extend_from_slice(&size16.to_le_bytes());
932        bytes.extend_from_slice(&count.to_le_bytes());
933        bytes.extend_from_slice(&[0, 0]);
934        for ace in &aces {
935            bytes.extend_from_slice(ace.as_ref().as_bytes());
936        }
937        Ok(Self(bytes.into_boxed_slice()))
938    }
939
940    /// Returns the owned packet bytes.
941    pub fn into_boxed_bytes(self) -> Box<[u8]> {
942        self.0
943    }
944}
945
946impl Deref for AclBuf {
947    type Target = Acl;
948
949    fn deref(&self) -> &Self::Target {
950        // The constructor invariant guarantees validation.
951        unsafe { &*(&*self.0 as *const [u8] as *const Acl) }
952    }
953}
954
955impl AsRef<Acl> for AclBuf {
956    fn as_ref(&self) -> &Acl {
957        self
958    }
959}
960
961impl Borrow<Acl> for AclBuf {
962    fn borrow(&self) -> &Acl {
963        self
964    }
965}
966
967impl ToOwned for Acl {
968    type Owned = AclBuf;
969
970    fn to_owned(&self) -> Self::Owned {
971        AclBuf(self.0.into())
972    }
973}
974
975impl Serialize for AclBuf {
976    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
977    where
978        S: Serializer,
979    {
980        self.0.serialize(serializer)
981    }
982}
983
984impl<'de> Deserialize<'de> for AclBuf {
985    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
986    where
987        D: Deserializer<'de>,
988    {
989        let bytes = Box::<[u8]>::deserialize(deserializer)?;
990        Self::try_from_bytes(bytes).map_err(de::Error::custom)
991    }
992}
993
994/// Error returned when building an ACE.
995#[derive(Clone, Debug, PartialEq, Eq)]
996pub enum AceBuildError {
997    /// An audit ACE selected neither successful nor failed access.
998    AuditOutcome,
999    /// Audit outcome bits were supplied both explicitly and through `flags`.
1000    AuditFlags,
1001    /// The generated packet exceeds the 16-bit native size field.
1002    Size(usize),
1003}
1004
1005impl fmt::Display for AceBuildError {
1006    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1007        match self {
1008            Self::AuditOutcome => f.write_str("audit ACE requires a successful or failed outcome"),
1009            Self::AuditFlags => f.write_str("audit outcome bits must not be supplied in flags"),
1010            Self::Size(size) => write!(f, "ACE packet size {size} exceeds the native limit"),
1011        }
1012    }
1013}
1014
1015impl error::Error for AceBuildError {}
1016
1017/// Error returned when building an ACL.
1018#[derive(Clone, Debug, PartialEq, Eq)]
1019pub enum AclBuildError {
1020    /// The requested ACL revision is unsupported.
1021    Revision(u8),
1022    /// Revision 2 cannot encode an object ACE.
1023    ObjectRevision,
1024    /// The ACL contains too many ACEs for its 16-bit count field.
1025    Count(usize),
1026    /// The ACL packet exceeds its 16-bit size field.
1027    Size(usize),
1028}
1029
1030impl fmt::Display for AclBuildError {
1031    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1032        match self {
1033            Self::Revision(revision) => write!(f, "unsupported ACL revision {revision}"),
1034            Self::ObjectRevision => f.write_str("ACL revision 2 cannot contain object ACEs"),
1035            Self::Count(count) => write!(f, "ACL ACE count {count} exceeds the native limit"),
1036            Self::Size(size) => write!(f, "ACL packet size {size} exceeds the native limit"),
1037        }
1038    }
1039}
1040
1041impl error::Error for AclBuildError {}
1042
1043fn read_u32(bytes: &[u8], offset: usize) -> Result<u32, AceError> {
1044    let bytes = bytes.get(offset..offset + 4).ok_or(AceError::Body)?;
1045    Ok(u32::from_le_bytes(bytes.try_into().unwrap()))
1046}
1047
1048fn parse_ace_sid(bytes: &[u8], offset: usize) -> Result<(Sid, usize), AceError> {
1049    let header = bytes.get(offset..offset + 8).ok_or(AceError::Sid)?;
1050    let length = 8 + usize::from(header[1]) * 4;
1051    let sid = bytes.get(offset..offset + length).ok_or(AceError::Sid)?;
1052    let sid = Sid::from_bytes(sid).map_err(|_| AceError::Sid)?;
1053    Ok((sid, offset + length))
1054}
1055
1056/// Error returned when parsing an ACL.
1057#[derive(Clone, Debug, PartialEq, Eq)]
1058pub enum AclError {
1059    /// The packet is shorter than an ACL header or is not DWORD-aligned.
1060    Length(usize),
1061    /// The declared packet size differs from the supplied byte length.
1062    Size(u16, usize),
1063    /// Fewer ACE packets could be read than the header declares.
1064    AceCount(u16, usize),
1065    /// An ACE at the supplied index is malformed.
1066    Ace(usize, AceError),
1067}
1068
1069impl fmt::Display for AclError {
1070    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1071        match self {
1072            Self::Length(length) => write!(f, "ACL packet has invalid length {length}"),
1073            Self::Size(declared, actual) => write!(
1074                f,
1075                "ACL packet declares size {declared}, but contains {actual} bytes"
1076            ),
1077            Self::AceCount(count, parsed) => write!(
1078                f,
1079                "ACL declares {count} ACEs, but only {parsed} can be traversed"
1080            ),
1081            Self::Ace(index, error) => write!(f, "ACE {index} is invalid: {error}"),
1082        }
1083    }
1084}
1085
1086impl error::Error for AclError {}
1087
1088/// Error returned when parsing an ACE.
1089#[derive(Clone, Debug, PartialEq, Eq)]
1090pub enum AceError {
1091    /// The packet is shorter than an ACE header.
1092    Length(usize),
1093    /// The declared packet size differs from the supplied byte length.
1094    Size(u16, usize),
1095    /// The packet is not DWORD-aligned.
1096    Alignment(usize),
1097    /// An ACE declared inside an ACL extends beyond that ACL's bytes.
1098    Bounds(usize),
1099    /// A recognized ACE body is truncated or malformed.
1100    Body,
1101    /// The ACE's embedded SID is malformed.
1102    Sid,
1103}
1104
1105impl fmt::Display for AceError {
1106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1107        match self {
1108            Self::Length(length) => write!(f, "ACE packet has invalid length {length}"),
1109            Self::Size(declared, actual) => write!(
1110                f,
1111                "ACE packet declares size {declared}, but contains {actual} bytes"
1112            ),
1113            Self::Alignment(length) => write!(f, "ACE packet length {length} is not aligned"),
1114            Self::Bounds(size) => write!(f, "ACE of size {size} exceeds its ACL"),
1115            Self::Body => f.write_str("ACE body is truncated"),
1116            Self::Sid => f.write_str("ACE contains an invalid SID"),
1117        }
1118    }
1119}
1120
1121impl error::Error for AceError {}
1122
1123/// A validated, portable representation of a self-relative Windows security descriptor.
1124///
1125/// A descriptor tracks which components were loaded through its
1126/// [`mask`](Self::mask), so partial security queries can be carried without
1127/// pretending that omitted components were absent on the target. Use
1128/// [`SecDescUpdate`] with [`with`](Self::with) to make a checked update.
1129#[derive(Debug, Clone, PartialEq, Eq)]
1130pub struct SecDesc {
1131    mask: SecInfo,
1132    revision: Revision,
1133    rm_control: u8,
1134    control: SecDescControl,
1135    owner: Option<Sid>,
1136    group: Option<Sid>,
1137    dacl: Option<AclBuf>,
1138    sacl: Option<AclBuf>,
1139}
1140
1141/// A builder for a functional update to a [`SecDesc`].
1142///
1143/// Component and control-flag methods select the values to replace.
1144/// Internally, control changes are stored as compact set/clear bitmasks;
1145/// [`SecDesc::with`] rejects changes that do not apply to loaded components.
1146#[derive(Clone, Debug)]
1147pub struct SecDescUpdate {
1148    owner: Option<Option<Sid>>,
1149    group: Option<Option<Sid>>,
1150    dacl: Option<Option<AclBuf>>,
1151    sacl: Option<Option<AclBuf>>,
1152    set_flags: SecDescControl,
1153    clear_flags: SecDescControl,
1154    rm_control: Option<Option<u8>>,
1155}
1156
1157impl SecDescUpdate {
1158    /// Creates an update with no changes.
1159    #[allow(clippy::new_without_default)]
1160    pub const fn new() -> Self {
1161        Self {
1162            owner: None,
1163            group: None,
1164            dacl: None,
1165            sacl: None,
1166            set_flags: SecDescControl::empty(),
1167            clear_flags: SecDescControl::empty(),
1168            rm_control: None,
1169        }
1170    }
1171
1172    /// Replaces the owner, or clears it with `None`.
1173    pub fn owner(mut self, owner: Option<Sid>) -> Self {
1174        self.owner = Some(owner);
1175        self
1176    }
1177    /// Replaces the primary group, or clears it with `None`.
1178    pub fn group(mut self, group: Option<Sid>) -> Self {
1179        self.group = Some(group);
1180        self
1181    }
1182    /// Replaces the DACL, or supplies a null DACL with `None`.
1183    pub fn dacl(mut self, dacl: Option<AclBuf>) -> Self {
1184        self.dacl = Some(dacl);
1185        self
1186    }
1187    /// Replaces the SACL, or supplies a null SACL with `None`.
1188    pub fn sacl(mut self, sacl: Option<AclBuf>) -> Self {
1189        self.sacl = Some(sacl);
1190        self
1191    }
1192    /// Sets the owner-defaulted control flag.
1193    pub fn owner_defaulted(self, value: bool) -> Self {
1194        self.control_flag(SecDescControl::OWNER_DEFAULTED.bits(), value)
1195    }
1196    /// Sets the group-defaulted control flag.
1197    pub fn group_defaulted(self, value: bool) -> Self {
1198        self.control_flag(SecDescControl::GROUP_DEFAULTED.bits(), value)
1199    }
1200    /// Sets whether a DACL is present.
1201    pub fn dacl_present(self, value: bool) -> Self {
1202        self.control_flag(SecDescControl::DACL_PRESENT.bits(), value)
1203    }
1204    /// Sets the DACL-defaulted control flag.
1205    pub fn dacl_defaulted(self, value: bool) -> Self {
1206        self.control_flag(SecDescControl::DACL_DEFAULTED.bits(), value)
1207    }
1208    /// Sets the DACL auto-inheritance-requested control flag.
1209    pub fn dacl_auto_inherit_required(self, value: bool) -> Self {
1210        self.control_flag(SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(), value)
1211    }
1212    /// Sets the DACL auto-inherited control flag.
1213    pub fn dacl_auto_inherited(self, value: bool) -> Self {
1214        self.control_flag(SecDescControl::DACL_AUTO_INHERITED.bits(), value)
1215    }
1216    /// Sets the DACL-protected control flag.
1217    pub fn dacl_protected(self, value: bool) -> Self {
1218        self.control_flag(SecDescControl::DACL_PROTECTED.bits(), value)
1219    }
1220    /// Sets whether a SACL is present.
1221    pub fn sacl_present(self, value: bool) -> Self {
1222        self.control_flag(SecDescControl::SACL_PRESENT.bits(), value)
1223    }
1224    /// Sets the SACL-defaulted control flag.
1225    pub fn sacl_defaulted(self, value: bool) -> Self {
1226        self.control_flag(SecDescControl::SACL_DEFAULTED.bits(), value)
1227    }
1228    /// Sets the SACL auto-inheritance-requested control flag.
1229    pub fn sacl_auto_inherit_required(self, value: bool) -> Self {
1230        self.control_flag(SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(), value)
1231    }
1232    /// Sets the SACL auto-inherited control flag.
1233    pub fn sacl_auto_inherited(self, value: bool) -> Self {
1234        self.control_flag(SecDescControl::SACL_AUTO_INHERITED.bits(), value)
1235    }
1236    /// Sets the SACL-protected control flag.
1237    pub fn sacl_protected(self, value: bool) -> Self {
1238        self.control_flag(SecDescControl::SACL_PROTECTED.bits(), value)
1239    }
1240    /// Sets the resource-manager control byte, or clears its validity with `None`.
1241    pub fn rm_control(mut self, rm_control: Option<u8>) -> Self {
1242        self.rm_control = Some(rm_control);
1243        self
1244    }
1245
1246    fn control_flag(mut self, flag: u16, value: bool) -> Self {
1247        let flag = SecDescControl::from_bits_retain(flag);
1248        self.set_flags.remove(flag);
1249        self.clear_flags.remove(flag);
1250        if value {
1251            self.set_flags |= flag;
1252        } else {
1253            self.clear_flags |= flag;
1254        }
1255        self
1256    }
1257}
1258
1259impl SecDesc {
1260    /// Creates a security descriptor from its structural components.
1261    #[allow(clippy::too_many_arguments)]
1262    pub fn new(
1263        mask: SecInfo,
1264        rm_control: u8,
1265        control: SecDescControl,
1266        owner: Option<Sid>,
1267        group: Option<Sid>,
1268        dacl: Option<AclBuf>,
1269        sacl: Option<AclBuf>,
1270    ) -> Result<Self, SecDescError> {
1271        if !mask.contains(SecInfo::OWNER) && owner.is_some() {
1272            return Err(SecDescError::OwnerNotLoaded);
1273        }
1274        if !mask.contains(SecInfo::GROUP) && group.is_some() {
1275            return Err(SecDescError::GroupNotLoaded);
1276        }
1277        validate_acl(
1278            AclKind::Dacl,
1279            mask.contains(SecInfo::DACL),
1280            control.contains(SecDescControl::DACL_PRESENT),
1281            dacl.as_ref(),
1282        )?;
1283        validate_acl(
1284            AclKind::Sacl,
1285            mask.contains(SecInfo::SACL),
1286            control.contains(SecDescControl::SACL_PRESENT),
1287            sacl.as_ref(),
1288        )?;
1289
1290        Ok(Self {
1291            mask,
1292            revision: Revision::One,
1293            rm_control,
1294            control: control - SecDescControl::SELF_RELATIVE,
1295            owner,
1296            group,
1297            dacl,
1298            sacl,
1299        })
1300    }
1301
1302    /// Parses a self-relative Windows security descriptor packet.
1303    pub fn from_bytes(bytes: &[u8]) -> Result<Self, SecDescError> {
1304        Self::from_bytes_with_mask(bytes, SecInfo::ALL)
1305    }
1306
1307    /// Parses the selected components of a self-relative Windows security descriptor packet.
1308    pub fn from_bytes_with_mask(bytes: &[u8], mask: SecInfo) -> Result<Self, SecDescError> {
1309        if bytes.len() < SELF_RELATIVE_HEADER_LEN {
1310            return Err(SecDescError::PacketLength);
1311        }
1312        match bytes[0] {
1313            REVISION => {}
1314            revision => return Err(SecDescError::Revision(revision)),
1315        }
1316        let rm_control = bytes[1];
1317        let control = u16::from_le_bytes(bytes[2..4].try_into().unwrap());
1318        if control & SecDescControl::SELF_RELATIVE.bits() == 0 {
1319            return Err(SecDescError::NotSelfRelative);
1320        }
1321
1322        let owner_offset = packet_offset(bytes, 4, SecDescComponent::Owner)?;
1323        let group_offset = packet_offset(bytes, 8, SecDescComponent::Group)?;
1324        let sacl_offset = packet_offset(bytes, 12, SecDescComponent::Sacl)?;
1325        let dacl_offset = packet_offset(bytes, 16, SecDescComponent::Dacl)?;
1326        if control & SecDescControl::SACL_PRESENT.bits() == 0 && sacl_offset != 0 {
1327            return Err(SecDescError::AclNotPresent(AclKind::Sacl));
1328        }
1329        if control & SecDescControl::DACL_PRESENT.bits() == 0 && dacl_offset != 0 {
1330            return Err(SecDescError::AclNotPresent(AclKind::Dacl));
1331        }
1332        let owner = mask
1333            .contains(SecInfo::OWNER)
1334            .then(|| parse_sid(bytes, owner_offset, SecDescComponent::Owner))
1335            .transpose()?
1336            .flatten();
1337        let group = mask
1338            .contains(SecInfo::GROUP)
1339            .then(|| parse_sid(bytes, group_offset, SecDescComponent::Group))
1340            .transpose()?
1341            .flatten();
1342        let sacl = mask
1343            .contains(SecInfo::SACL)
1344            .then(|| parse_acl(bytes, sacl_offset, AclKind::Sacl))
1345            .transpose()?
1346            .flatten();
1347        let dacl = mask
1348            .contains(SecInfo::DACL)
1349            .then(|| parse_acl(bytes, dacl_offset, AclKind::Dacl))
1350            .transpose()?
1351            .flatten();
1352
1353        Self::new(
1354            mask,
1355            rm_control,
1356            SecDescControl::from_bits_retain(control),
1357            owner,
1358            group,
1359            dacl,
1360            sacl,
1361        )
1362    }
1363
1364    /// Converts this descriptor to a canonical self-relative Windows packet.
1365    pub fn to_bytes(&self) -> Vec<u8> {
1366        let mut bytes = vec![0; SELF_RELATIVE_HEADER_LEN];
1367        bytes[0] = self.revision as u8;
1368        bytes[1] = self.rm_control;
1369        bytes[2..4].copy_from_slice(
1370            &(self.control | SecDescControl::SELF_RELATIVE)
1371                .bits()
1372                .to_le_bytes(),
1373        );
1374
1375        let owner = self.owner.as_ref().map(Sid::to_bytes);
1376        let group = self.group.as_ref().map(Sid::to_bytes);
1377        append_component(&mut bytes, 4, owner.as_deref());
1378        append_component(&mut bytes, 8, group.as_deref());
1379        append_component(&mut bytes, 12, self.sacl.as_deref().map(Acl::as_bytes));
1380        append_component(&mut bytes, 16, self.dacl.as_deref().map(Acl::as_bytes));
1381        bytes
1382    }
1383
1384    /// Returns the native SECURITY_INFORMATION mask associated with the descriptor.
1385    pub const fn mask(&self) -> SecInfo {
1386        self.mask
1387    }
1388
1389    /// Returns the security descriptor revision.
1390    pub const fn revision(&self) -> Revision {
1391        self.revision
1392    }
1393
1394    /// Returns the security descriptor control mask.
1395    pub const fn control(&self) -> SecDescControl {
1396        self.control
1397    }
1398
1399    /// Returns the resource-manager control byte when it is valid.
1400    pub const fn rm_control(&self) -> Option<u8> {
1401        if self.rm_control_valid() {
1402            Some(self.rm_control)
1403        } else {
1404            None
1405        }
1406    }
1407
1408    /// Returns whether the resource-manager control byte is valid.
1409    pub const fn rm_control_valid(&self) -> bool {
1410        self.control.contains(SecDescControl::RM_CONTROL_VALID)
1411    }
1412
1413    /// Returns whether the owner component was loaded.
1414    pub const fn owner_loaded(&self) -> bool {
1415        self.mask.contains(SecInfo::OWNER)
1416    }
1417
1418    /// Returns the owner SID, if present.
1419    pub const fn owner(&self) -> Option<&Sid> {
1420        self.owner.as_ref()
1421    }
1422
1423    /// Returns whether the owner SID was supplied by a default mechanism.
1424    pub const fn owner_defaulted(&self) -> bool {
1425        self.control.contains(SecDescControl::OWNER_DEFAULTED)
1426    }
1427
1428    /// Returns whether the group component was loaded.
1429    pub const fn group_loaded(&self) -> bool {
1430        self.mask.contains(SecInfo::GROUP)
1431    }
1432
1433    /// Returns the primary group SID, if present.
1434    pub const fn group(&self) -> Option<&Sid> {
1435        self.group.as_ref()
1436    }
1437
1438    /// Returns whether the group SID was supplied by a default mechanism.
1439    pub const fn group_defaulted(&self) -> bool {
1440        self.control.contains(SecDescControl::GROUP_DEFAULTED)
1441    }
1442
1443    /// Returns whether the DACL component was loaded.
1444    pub const fn dacl_loaded(&self) -> bool {
1445        self.mask.contains(SecInfo::DACL)
1446    }
1447
1448    /// Returns the DACL, if it is non-null.
1449    pub fn dacl(&self) -> Option<&Acl> {
1450        self.dacl.as_deref()
1451    }
1452
1453    /// Returns whether the descriptor marks the DACL as present.
1454    pub const fn dacl_present(&self) -> bool {
1455        self.control.contains(SecDescControl::DACL_PRESENT)
1456    }
1457
1458    /// Returns whether the DACL was supplied by a default mechanism.
1459    pub const fn dacl_defaulted(&self) -> bool {
1460        self.control.contains(SecDescControl::DACL_DEFAULTED)
1461    }
1462
1463    /// Returns whether DACL inheritance computation was requested.
1464    pub const fn dacl_auto_inherit_required(&self) -> bool {
1465        self.control
1466            .contains(SecDescControl::DACL_AUTO_INHERIT_REQUIRED)
1467    }
1468
1469    /// Returns whether the DACL was produced through inheritance.
1470    pub const fn dacl_auto_inherited(&self) -> bool {
1471        self.control.contains(SecDescControl::DACL_AUTO_INHERITED)
1472    }
1473
1474    /// Returns whether the DACL is protected from inheritance.
1475    pub const fn dacl_protected(&self) -> bool {
1476        self.control.contains(SecDescControl::DACL_PROTECTED)
1477    }
1478
1479    /// Returns whether the SACL component was loaded.
1480    pub const fn sacl_loaded(&self) -> bool {
1481        self.mask.contains(SecInfo::SACL)
1482    }
1483
1484    /// Returns the SACL, if it is non-null.
1485    pub fn sacl(&self) -> Option<&Acl> {
1486        self.sacl.as_deref()
1487    }
1488
1489    /// Returns whether the descriptor marks the SACL as present.
1490    pub const fn sacl_present(&self) -> bool {
1491        self.control.contains(SecDescControl::SACL_PRESENT)
1492    }
1493
1494    /// Returns whether the SACL was supplied by a default mechanism.
1495    pub const fn sacl_defaulted(&self) -> bool {
1496        self.control.contains(SecDescControl::SACL_DEFAULTED)
1497    }
1498
1499    /// Returns whether SACL inheritance computation was requested.
1500    pub const fn sacl_auto_inherit_required(&self) -> bool {
1501        self.control
1502            .contains(SecDescControl::SACL_AUTO_INHERIT_REQUIRED)
1503    }
1504
1505    /// Returns whether the SACL was produced through inheritance.
1506    pub const fn sacl_auto_inherited(&self) -> bool {
1507        self.control.contains(SecDescControl::SACL_AUTO_INHERITED)
1508    }
1509
1510    /// Returns whether the SACL is protected from inheritance.
1511    pub const fn sacl_protected(&self) -> bool {
1512        self.control.contains(SecDescControl::SACL_PROTECTED)
1513    }
1514
1515    /// Returns a new descriptor with the supplied component and control updates.
1516    pub fn with(&self, update: SecDescUpdate) -> Result<Self, SecDescError> {
1517        let SecDescUpdate {
1518            owner: owner_update,
1519            group: group_update,
1520            dacl: dacl_update,
1521            sacl: sacl_update,
1522            set_flags,
1523            clear_flags,
1524            rm_control: rm_control_update,
1525        } = update;
1526        let mut mask = self.mask;
1527        let mut control = self.control.bits();
1528        let set_flags = set_flags.bits();
1529        let clear_flags = clear_flags.bits();
1530
1531        let owner = match owner_update {
1532            Some(value) => {
1533                mask |= SecInfo::OWNER;
1534                value
1535            }
1536            None => self.owner.clone(),
1537        };
1538        let group = match group_update {
1539            Some(value) => {
1540                mask |= SecInfo::GROUP;
1541                value
1542            }
1543            None => self.group.clone(),
1544        };
1545
1546        let (dacl, dacl_explicit) = match dacl_update {
1547            Some(value) => {
1548                mask |= SecInfo::DACL;
1549                set_control(&mut control, SecDescControl::DACL_PRESENT.bits(), true);
1550                (value, true)
1551            }
1552            None => (self.dacl.clone(), false),
1553        };
1554        let (sacl, sacl_explicit) = match sacl_update {
1555            Some(value) => {
1556                mask |= SecInfo::SACL;
1557                set_control(&mut control, SecDescControl::SACL_PRESENT.bits(), true);
1558                (value, true)
1559            }
1560            None => (self.sacl.clone(), false),
1561        };
1562
1563        let dacl = apply_presence(
1564            AclKind::Dacl,
1565            &mut mask,
1566            &mut control,
1567            SecInfo::DACL,
1568            SecDescControl::DACL_PRESENT.bits(),
1569            flag_update(set_flags, clear_flags, SecDescControl::DACL_PRESENT.bits()),
1570            dacl_explicit,
1571            dacl,
1572        )?;
1573        let sacl = apply_presence(
1574            AclKind::Sacl,
1575            &mut mask,
1576            &mut control,
1577            SecInfo::SACL,
1578            SecDescControl::SACL_PRESENT.bits(),
1579            flag_update(set_flags, clear_flags, SecDescControl::SACL_PRESENT.bits()),
1580            sacl_explicit,
1581            sacl,
1582        )?;
1583
1584        apply_component_flag(
1585            SecDescComponent::Owner,
1586            mask.contains(SecInfo::OWNER),
1587            &mut control,
1588            SecDescControl::OWNER_DEFAULTED.bits(),
1589            flag_update(
1590                set_flags,
1591                clear_flags,
1592                SecDescControl::OWNER_DEFAULTED.bits(),
1593            ),
1594        )?;
1595        apply_component_flag(
1596            SecDescComponent::Group,
1597            mask.contains(SecInfo::GROUP),
1598            &mut control,
1599            SecDescControl::GROUP_DEFAULTED.bits(),
1600            flag_update(
1601                set_flags,
1602                clear_flags,
1603                SecDescControl::GROUP_DEFAULTED.bits(),
1604            ),
1605        )?;
1606        for (name, loaded, flag, value) in [
1607            (
1608                SecDescComponent::Dacl,
1609                mask.contains(SecInfo::DACL),
1610                SecDescControl::DACL_DEFAULTED.bits(),
1611                flag_update(
1612                    set_flags,
1613                    clear_flags,
1614                    SecDescControl::DACL_DEFAULTED.bits(),
1615                ),
1616            ),
1617            (
1618                SecDescComponent::Dacl,
1619                mask.contains(SecInfo::DACL),
1620                SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(),
1621                flag_update(
1622                    set_flags,
1623                    clear_flags,
1624                    SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits(),
1625                ),
1626            ),
1627            (
1628                SecDescComponent::Dacl,
1629                mask.contains(SecInfo::DACL),
1630                SecDescControl::DACL_AUTO_INHERITED.bits(),
1631                flag_update(
1632                    set_flags,
1633                    clear_flags,
1634                    SecDescControl::DACL_AUTO_INHERITED.bits(),
1635                ),
1636            ),
1637            (
1638                SecDescComponent::Dacl,
1639                mask.contains(SecInfo::DACL),
1640                SecDescControl::DACL_PROTECTED.bits(),
1641                flag_update(
1642                    set_flags,
1643                    clear_flags,
1644                    SecDescControl::DACL_PROTECTED.bits(),
1645                ),
1646            ),
1647            (
1648                SecDescComponent::Sacl,
1649                mask.contains(SecInfo::SACL),
1650                SecDescControl::SACL_DEFAULTED.bits(),
1651                flag_update(
1652                    set_flags,
1653                    clear_flags,
1654                    SecDescControl::SACL_DEFAULTED.bits(),
1655                ),
1656            ),
1657            (
1658                SecDescComponent::Sacl,
1659                mask.contains(SecInfo::SACL),
1660                SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(),
1661                flag_update(
1662                    set_flags,
1663                    clear_flags,
1664                    SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits(),
1665                ),
1666            ),
1667            (
1668                SecDescComponent::Sacl,
1669                mask.contains(SecInfo::SACL),
1670                SecDescControl::SACL_AUTO_INHERITED.bits(),
1671                flag_update(
1672                    set_flags,
1673                    clear_flags,
1674                    SecDescControl::SACL_AUTO_INHERITED.bits(),
1675                ),
1676            ),
1677            (
1678                SecDescComponent::Sacl,
1679                mask.contains(SecInfo::SACL),
1680                SecDescControl::SACL_PROTECTED.bits(),
1681                flag_update(
1682                    set_flags,
1683                    clear_flags,
1684                    SecDescControl::SACL_PROTECTED.bits(),
1685                ),
1686            ),
1687        ] {
1688            apply_component_flag(name, loaded, &mut control, flag, value)?;
1689        }
1690
1691        let rm_control = match rm_control_update {
1692            Some(Some(value)) => {
1693                set_control(&mut control, SecDescControl::RM_CONTROL_VALID.bits(), true);
1694                value
1695            }
1696            Some(None) => {
1697                set_control(&mut control, SecDescControl::RM_CONTROL_VALID.bits(), false);
1698                0
1699            }
1700            None => self.rm_control,
1701        };
1702
1703        Ok(Self {
1704            mask,
1705            revision: self.revision,
1706            rm_control,
1707            control: SecDescControl::from_bits_retain(control),
1708            owner,
1709            group,
1710            dacl,
1711            sacl,
1712        })
1713    }
1714}
1715
1716fn set_control(control: &mut u16, flag: u16, value: bool) {
1717    if value {
1718        *control |= flag;
1719    } else {
1720        *control &= !flag;
1721    }
1722}
1723
1724fn flag_update(set_flags: u16, clear_flags: u16, flag: u16) -> Option<bool> {
1725    if set_flags & flag != 0 {
1726        Some(true)
1727    } else if clear_flags & flag != 0 {
1728        Some(false)
1729    } else {
1730        None
1731    }
1732}
1733
1734fn apply_component_flag(
1735    component: SecDescComponent,
1736    loaded: bool,
1737    control: &mut u16,
1738    flag: u16,
1739    value: Option<bool>,
1740) -> Result<(), SecDescError> {
1741    if let Some(value) = value {
1742        if !loaded {
1743            return Err(SecDescError::ComponentNotLoaded(component));
1744        }
1745        set_control(control, flag, value);
1746    }
1747    Ok(())
1748}
1749
1750#[allow(clippy::too_many_arguments)]
1751fn apply_presence(
1752    acl_kind: AclKind,
1753    mask: &mut SecInfo,
1754    control: &mut u16,
1755    mask_flag: SecInfo,
1756    present_flag: u16,
1757    requested: Option<bool>,
1758    explicit: bool,
1759    mut acl: Option<AclBuf>,
1760) -> Result<Option<AclBuf>, SecDescError> {
1761    if let Some(present) = requested {
1762        let was_loaded = mask.contains(mask_flag);
1763        if !present {
1764            if explicit {
1765                return Err(SecDescError::AclPresenceConflict(acl_kind));
1766            }
1767            acl = None;
1768            set_control(control, present_flag, false);
1769        } else {
1770            if !explicit && (!was_loaded || *control & present_flag == 0) {
1771                return Err(SecDescError::AclPresenceRequiresValue(acl_kind));
1772            }
1773            set_control(control, present_flag, true);
1774        }
1775        *mask |= mask_flag;
1776    }
1777    Ok(acl)
1778}
1779
1780fn packet_offset(
1781    bytes: &[u8],
1782    at: usize,
1783    component: SecDescComponent,
1784) -> Result<usize, SecDescError> {
1785    let offset = u32::from_le_bytes(bytes[at..at + 4].try_into().unwrap());
1786    usize::try_from(offset).map_err(|_| SecDescError::PacketOffset(component, offset))
1787}
1788
1789fn validate_offset(
1790    bytes: &[u8],
1791    offset: usize,
1792    component: SecDescComponent,
1793) -> Result<(), SecDescError> {
1794    if offset < SELF_RELATIVE_HEADER_LEN || !offset.is_multiple_of(4) || offset >= bytes.len() {
1795        return Err(SecDescError::PacketOffset(
1796            component,
1797            u32::try_from(offset).unwrap_or(u32::MAX),
1798        ));
1799    }
1800    Ok(())
1801}
1802
1803fn parse_sid(
1804    bytes: &[u8],
1805    offset: usize,
1806    component: SecDescComponent,
1807) -> Result<Option<Sid>, SecDescError> {
1808    if offset == 0 {
1809        return Ok(None);
1810    }
1811    validate_offset(bytes, offset, component)?;
1812    let header = bytes
1813        .get(offset..offset + 8)
1814        .ok_or(SecDescError::PacketComponent(component))?;
1815    let length = 8 + usize::from(header[1]) * 4;
1816    let sid = bytes
1817        .get(offset..offset + length)
1818        .ok_or(SecDescError::PacketComponent(component))?;
1819    Sid::from_bytes(sid)
1820        .map(Some)
1821        .map_err(|_| SecDescError::PacketComponent(component))
1822}
1823
1824fn parse_acl(
1825    bytes: &[u8],
1826    offset: usize,
1827    acl_kind: AclKind,
1828) -> Result<Option<AclBuf>, SecDescError> {
1829    if offset == 0 {
1830        return Ok(None);
1831    }
1832    validate_offset(bytes, offset, acl_kind.component())?;
1833    let header = bytes
1834        .get(offset..offset + ACL_HEADER_LEN)
1835        .ok_or(SecDescError::PacketComponent(acl_kind.component()))?;
1836    let length = usize::from(u16::from_le_bytes(header[2..4].try_into().unwrap()));
1837    let acl = bytes
1838        .get(offset..offset + length)
1839        .ok_or(SecDescError::PacketComponent(acl_kind.component()))?;
1840    AclBuf::try_from_bytes(acl.to_vec().into_boxed_slice())
1841        .map(Some)
1842        .map_err(|error| SecDescError::Acl(acl_kind, error))
1843}
1844
1845fn append_component(bytes: &mut Vec<u8>, offset_at: usize, component: Option<&[u8]>) {
1846    let Some(component) = component else {
1847        return;
1848    };
1849    let offset = u32::try_from(bytes.len()).expect("security descriptor exceeds 4 GiB");
1850    bytes[offset_at..offset_at + 4].copy_from_slice(&offset.to_le_bytes());
1851    bytes.extend_from_slice(component);
1852}
1853
1854fn validate_acl(
1855    acl_kind: AclKind,
1856    loaded: bool,
1857    present: bool,
1858    acl: Option<&AclBuf>,
1859) -> Result<(), SecDescError> {
1860    let Some(_acl) = acl else {
1861        return Ok(());
1862    };
1863    if !loaded {
1864        return Err(SecDescError::AclNotLoaded(acl_kind));
1865    }
1866    if !present {
1867        return Err(SecDescError::AclNotPresent(acl_kind));
1868    }
1869    Ok(())
1870}
1871
1872impl Serialize for SecDesc {
1873    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1874    where
1875        S: Serializer,
1876    {
1877        let mut tuple = serializer.serialize_tuple(8)?;
1878        tuple.serialize_element(&self.mask.bits())?;
1879        tuple.serialize_element(&(self.revision as u8))?;
1880        tuple.serialize_element(&self.rm_control)?;
1881        tuple.serialize_element(&self.control.bits())?;
1882        tuple.serialize_element(&self.owner)?;
1883        tuple.serialize_element(&self.group)?;
1884        tuple.serialize_element(&self.dacl)?;
1885        tuple.serialize_element(&self.sacl)?;
1886        tuple.end()
1887    }
1888}
1889
1890impl<'de> Deserialize<'de> for SecDesc {
1891    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1892    where
1893        D: Deserializer<'de>,
1894    {
1895        struct SecDescVisitor;
1896
1897        impl<'de> Visitor<'de> for SecDescVisitor {
1898            type Value = SecDesc;
1899
1900            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1901                formatter.write_str("a structurally encoded Windows security descriptor")
1902            }
1903
1904            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1905            where
1906                A: SeqAccess<'de>,
1907            {
1908                let mask = SecInfo::from_bits_retain(next(&mut seq, 0, &self)?);
1909                match next(&mut seq, 1, &self)? {
1910                    REVISION => {}
1911                    revision => return Err(de::Error::custom(SecDescError::Revision(revision))),
1912                }
1913                let rm_control = next(&mut seq, 2, &self)?;
1914                let control = SecDescControl::from_bits_retain(next(&mut seq, 3, &self)?);
1915                let owner = next(&mut seq, 4, &self)?;
1916                let group = next(&mut seq, 5, &self)?;
1917                let dacl = next(&mut seq, 6, &self)?;
1918                let sacl = next(&mut seq, 7, &self)?;
1919                SecDesc::new(mask, rm_control, control, owner, group, dacl, sacl)
1920                    .map_err(de::Error::custom)
1921            }
1922        }
1923
1924        fn next<'de, A, T>(
1925            seq: &mut A,
1926            index: usize,
1927            visitor: &dyn de::Expected,
1928        ) -> Result<T, A::Error>
1929        where
1930            A: SeqAccess<'de>,
1931            T: Deserialize<'de>,
1932        {
1933            seq.next_element()?
1934                .ok_or_else(|| de::Error::invalid_length(index, visitor))
1935        }
1936
1937        deserializer.deserialize_tuple(8, SecDescVisitor)
1938    }
1939}
1940
1941/// Error returned when constructing or deserializing a security descriptor.
1942#[derive(Debug, Clone, PartialEq, Eq)]
1943pub enum SecDescError {
1944    /// The descriptor uses an unsupported revision.
1945    Revision(u8),
1946    /// An owner SID was supplied without loading the owner component.
1947    OwnerNotLoaded,
1948    /// A group SID was supplied without loading the group component.
1949    GroupNotLoaded,
1950    /// An ACL was supplied without loading its component.
1951    AclNotLoaded(AclKind),
1952    /// An ACL was supplied while its present bit is clear.
1953    AclNotPresent(AclKind),
1954    /// An update supplies an ACL while explicitly marking it absent.
1955    AclPresenceConflict(AclKind),
1956    /// An update marks an unloaded or absent ACL present without supplying one.
1957    AclPresenceRequiresValue(AclKind),
1958    /// An update changes a control bit for an unloaded component.
1959    ComponentNotLoaded(SecDescComponent),
1960    /// A supplied ACL packet is malformed.
1961    Acl(AclKind, AclError),
1962    /// The self-relative descriptor header is truncated.
1963    PacketLength,
1964    /// The descriptor is in absolute rather than self-relative form.
1965    NotSelfRelative,
1966    /// A component offset is invalid or misaligned.
1967    PacketOffset(SecDescComponent, u32),
1968    /// A component packet is truncated or malformed.
1969    PacketComponent(SecDescComponent),
1970}
1971
1972impl fmt::Display for SecDescError {
1973    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1974        match self {
1975            Self::Revision(revision) => {
1976                write!(f, "unsupported security descriptor revision {revision}")
1977            }
1978            Self::OwnerNotLoaded => f.write_str("owner SID supplied when owner was not loaded"),
1979            Self::GroupNotLoaded => f.write_str("group SID supplied when group was not loaded"),
1980            Self::AclNotLoaded(name) => write!(f, "{name} supplied when it was not loaded"),
1981            Self::AclNotPresent(name) => {
1982                write!(f, "{name} supplied when its PRESENT control bit is clear")
1983            }
1984            Self::AclPresenceConflict(name) => {
1985                write!(f, "{name} cannot be supplied with presence false")
1986            }
1987            Self::AclPresenceRequiresValue(name) => {
1988                write!(
1989                    f,
1990                    "{name} presence true requires an existing or supplied ACL"
1991                )
1992            }
1993            Self::ComponentNotLoaded(name) => {
1994                write!(f, "cannot update control flags for unloaded {name}")
1995            }
1996            Self::Acl(name, error) => write!(f, "invalid {name}: {error}"),
1997            Self::PacketLength => f.write_str("security descriptor packet is too short"),
1998            Self::NotSelfRelative => f.write_str("security descriptor packet is not self-relative"),
1999            Self::PacketOffset(name, offset) => {
2000                write!(f, "security descriptor {name} has invalid offset {offset}")
2001            }
2002            Self::PacketComponent(name) => {
2003                write!(f, "security descriptor contains an invalid {name}")
2004            }
2005        }
2006    }
2007}
2008
2009impl error::Error for SecDescError {}
2010
2011#[cfg(test)]
2012mod tests {
2013    use super::*;
2014
2015    fn sid(value: &str) -> Sid {
2016        value.parse().unwrap()
2017    }
2018
2019    fn acl(size: u16) -> Vec<u8> {
2020        let mut value = vec![0; usize::from(size)];
2021        value[0] = 2;
2022        value[2..4].copy_from_slice(&size.to_le_bytes());
2023        value
2024    }
2025
2026    fn valid_acl(size: u16) -> AclBuf {
2027        AclBuf::try_from_bytes(acl(size).into_boxed_slice()).unwrap()
2028    }
2029
2030    fn ace(ace_type: u8, flags: u8, mask: u32, sid: &Sid, application: &[u8]) -> Vec<u8> {
2031        let mut value = vec![ace_type, flags, 0, 0];
2032        value.extend_from_slice(&mask.to_le_bytes());
2033        value.extend_from_slice(&sid.to_bytes());
2034        value.extend_from_slice(application);
2035        let size = u16::try_from(value.len()).unwrap();
2036        value[2..4].copy_from_slice(&size.to_le_bytes());
2037        value
2038    }
2039
2040    fn acl_with_aces(aces: &[Vec<u8>], tail: &[u8]) -> Vec<u8> {
2041        let size = ACL_HEADER_LEN + aces.iter().map(Vec::len).sum::<usize>() + tail.len();
2042        let mut value = vec![2, 0];
2043        value.extend_from_slice(&u16::try_from(size).unwrap().to_le_bytes());
2044        value.extend_from_slice(&u16::try_from(aces.len()).unwrap().to_le_bytes());
2045        value.extend_from_slice(&[0, 0]);
2046        for ace in aces {
2047            value.extend_from_slice(ace);
2048        }
2049        value.extend_from_slice(tail);
2050        value
2051    }
2052
2053    #[test]
2054    fn exposes_known_and_unknown_aces_without_losing_bytes() {
2055        let trustee = sid("S-1-5-32-544");
2056        let known = ace(0, 0x13, 0x1234_5678, &trustee, &[0xde, 0xad, 0xbe, 0xef]);
2057        let unknown = vec![0x7f, 0xa0, 8, 0, 0x11, 0x22, 0x33, 0x44];
2058        let bytes = acl_with_aces(&[known.clone(), unknown.clone()], &[0xaa, 0xbb, 0xcc, 0xdd]);
2059        let acl = Acl::from_bytes(&bytes).unwrap();
2060
2061        assert_eq!(acl.revision(), AclRevision::Basic);
2062        assert_eq!(usize::from(acl.size()), bytes.len());
2063        assert_eq!(acl.ace_count(), 2);
2064        assert_eq!(acl.as_bytes(), bytes);
2065
2066        let mut aces = acl.aces();
2067        let first = aces.next().unwrap();
2068        assert_eq!(first.ace_type(), AceType::AccessAllowed);
2069        assert_eq!(first.flags().bits(), 0x13);
2070        assert_eq!(first.mask().map(|mask| mask.bits()), Some(0x1234_5678));
2071        assert_eq!(first.sid(), Some(trustee));
2072        assert_eq!(
2073            first.application_data(),
2074            Some(&[0xde, 0xad, 0xbe, 0xef][..])
2075        );
2076        assert_eq!(first.as_bytes(), known);
2077
2078        let second = aces.next().unwrap();
2079        assert_eq!(second.ace_type(), AceType::Unknown(0x7f));
2080        assert_eq!(second.mask(), None);
2081        assert_eq!(second.application_data(), None);
2082        assert_eq!(second.as_bytes(), unknown);
2083        assert_eq!(aces.next(), None);
2084    }
2085
2086    #[test]
2087    fn parses_object_ace_guids_and_application_data() {
2088        let object_type: Guid = "00112233-4455-6677-8899-aabbccddeeff".parse().unwrap();
2089        let inherited_type: Guid = "ffeeddcc-bbaa-9988-7766-554433221100".parse().unwrap();
2090        let trustee = sid("S-1-1-0");
2091        for object_flags in 0..=3u32 {
2092            let mut bytes = vec![11, 0, 0, 0];
2093            bytes.extend_from_slice(&0x90ab_cdefu32.to_le_bytes());
2094            bytes.extend_from_slice(&object_flags.to_le_bytes());
2095            if object_flags & 1 != 0 {
2096                bytes.extend_from_slice(&object_type.to_bytes());
2097            }
2098            if object_flags & 2 != 0 {
2099                bytes.extend_from_slice(&inherited_type.to_bytes());
2100            }
2101            bytes.extend_from_slice(&trustee.to_bytes());
2102            bytes.extend_from_slice(&[1, 2, 3, 4]);
2103            let size = u16::try_from(bytes.len()).unwrap();
2104            bytes[2..4].copy_from_slice(&size.to_le_bytes());
2105
2106            let ace = Ace::from_bytes(&bytes).unwrap();
2107            assert_eq!(ace.ace_type(), AceType::AccessAllowedCallbackObject);
2108            assert_eq!(
2109                ace.object_flags().map(|flags| flags.bits()),
2110                Some(object_flags)
2111            );
2112            assert_eq!(
2113                ace.object_type(),
2114                (object_flags & 1 != 0).then_some(object_type)
2115            );
2116            assert_eq!(
2117                ace.inherited_object_type(),
2118                (object_flags & 2 != 0).then_some(inherited_type)
2119            );
2120            assert_eq!(ace.sid(), Some(trustee.clone()));
2121            assert_eq!(ace.application_data(), Some(&[1, 2, 3, 4][..]));
2122        }
2123    }
2124
2125    #[test]
2126    fn rejects_untraversable_or_malformed_aces() {
2127        let mut count_mismatch = acl(8);
2128        count_mismatch[4..6].copy_from_slice(&1u16.to_le_bytes());
2129        assert_eq!(
2130            Acl::from_bytes(&count_mismatch),
2131            Err(AclError::AceCount(1, 0))
2132        );
2133
2134        let malformed = vec![0, 0, 8, 0, 0, 0, 0, 0];
2135        let bytes = acl_with_aces(&[malformed], &[]);
2136        assert_eq!(
2137            Acl::from_bytes(&bytes),
2138            Err(AclError::Ace(0, AceError::Sid))
2139        );
2140
2141        let overrun = vec![0x7f, 0, 12, 0, 0, 0, 0, 0];
2142        let bytes = acl_with_aces(&[overrun], &[]);
2143        assert_eq!(
2144            Acl::from_bytes(&bytes),
2145            Err(AclError::Ace(0, AceError::Bounds(12)))
2146        );
2147    }
2148
2149    #[test]
2150    fn represents_loaded_absent_null_and_non_null_components() {
2151        let unloaded = SecDesc::new(
2152            SecInfo::empty(),
2153            0,
2154            SecDescControl::empty(),
2155            None,
2156            None,
2157            None,
2158            None,
2159        )
2160        .unwrap();
2161        assert!(!unloaded.owner_loaded());
2162        assert!(!unloaded.dacl_loaded());
2163
2164        let absent = SecDesc::new(
2165            SecInfo::OWNER | SecInfo::DACL,
2166            0,
2167            SecDescControl::empty(),
2168            None,
2169            None,
2170            None,
2171            None,
2172        )
2173        .unwrap();
2174        assert!(absent.owner_loaded());
2175        assert_eq!(absent.owner(), None);
2176        assert!(absent.dacl_loaded());
2177        assert!(!absent.dacl_present());
2178
2179        let null = SecDesc::new(
2180            SecInfo::DACL,
2181            0,
2182            SecDescControl::DACL_PRESENT,
2183            None,
2184            None,
2185            None,
2186            None,
2187        )
2188        .unwrap();
2189        assert!(null.dacl_present());
2190        assert_eq!(null.dacl(), None);
2191
2192        let bytes = valid_acl(8);
2193        let present = SecDesc::new(
2194            SecInfo::DACL,
2195            0,
2196            SecDescControl::DACL_PRESENT,
2197            None,
2198            None,
2199            Some(bytes.clone()),
2200            None,
2201        )
2202        .unwrap();
2203        assert_eq!(present.dacl().map(Acl::as_bytes), Some(bytes.as_bytes()));
2204    }
2205
2206    #[test]
2207    fn rejects_inconsistent_components() {
2208        assert_eq!(
2209            SecDesc::new(
2210                SecInfo::empty(),
2211                0,
2212                SecDescControl::empty(),
2213                Some(sid("S-1-5-18")),
2214                None,
2215                None,
2216                None,
2217            ),
2218            Err(SecDescError::OwnerNotLoaded)
2219        );
2220        assert_eq!(
2221            SecDesc::new(
2222                SecInfo::empty(),
2223                0,
2224                SecDescControl::empty(),
2225                None,
2226                Some(sid("S-1-5-18")),
2227                None,
2228                None,
2229            ),
2230            Err(SecDescError::GroupNotLoaded)
2231        );
2232        assert_eq!(
2233            SecDesc::new(
2234                SecInfo::empty(),
2235                0,
2236                SecDescControl::DACL_PRESENT,
2237                None,
2238                None,
2239                Some(valid_acl(8)),
2240                None
2241            ),
2242            Err(SecDescError::AclNotLoaded(AclKind::Dacl))
2243        );
2244        assert_eq!(
2245            SecDesc::new(
2246                SecInfo::DACL,
2247                0,
2248                SecDescControl::empty(),
2249                None,
2250                None,
2251                Some(valid_acl(8)),
2252                None,
2253            ),
2254            Err(SecDescError::AclNotPresent(AclKind::Dacl))
2255        );
2256    }
2257
2258    #[test]
2259    fn validates_acl_packet_and_ace_boundaries() {
2260        assert_eq!(
2261            AclBuf::try_from_bytes(vec![0; 4].into_boxed_slice()),
2262            Err(AclError::Length(4))
2263        );
2264
2265        let mut wrong_size = acl(8);
2266        wrong_size.extend_from_slice(&[0; 4]);
2267        assert_eq!(
2268            AclBuf::try_from_bytes(wrong_size.into_boxed_slice()),
2269            Err(AclError::Size(8, 12))
2270        );
2271
2272        let mut opaque = acl(12);
2273        opaque[8..].copy_from_slice(&[0xff; 4]);
2274        let opaque = unsafe { AclBuf::from_bytes_unchecked(opaque.into_boxed_slice()) };
2275        let descriptor = SecDesc::new(
2276            SecInfo::DACL,
2277            0,
2278            SecDescControl::DACL_PRESENT,
2279            None,
2280            None,
2281            Some(opaque.clone()),
2282            None,
2283        )
2284        .unwrap();
2285        assert_eq!(
2286            descriptor.dacl().map(Acl::as_bytes),
2287            Some(opaque.as_bytes())
2288        );
2289    }
2290
2291    #[test]
2292    fn projects_control_flags_and_normalizes_storage_form() {
2293        let control = SecDescControl::OWNER_DEFAULTED.bits()
2294            | SecDescControl::GROUP_DEFAULTED.bits()
2295            | SecDescControl::DACL_DEFAULTED.bits()
2296            | SecDescControl::SACL_DEFAULTED.bits()
2297            | SecDescControl::DACL_AUTO_INHERIT_REQUIRED.bits()
2298            | SecDescControl::SACL_AUTO_INHERIT_REQUIRED.bits()
2299            | SecDescControl::DACL_AUTO_INHERITED.bits()
2300            | SecDescControl::SACL_AUTO_INHERITED.bits()
2301            | SecDescControl::DACL_PROTECTED.bits()
2302            | SecDescControl::SACL_PROTECTED.bits()
2303            | SecDescControl::RM_CONTROL_VALID.bits()
2304            | SecDescControl::SELF_RELATIVE.bits();
2305        let descriptor = SecDesc::new(
2306            SecInfo::empty(),
2307            0x5a,
2308            SecDescControl::from_bits_retain(control),
2309            None,
2310            None,
2311            None,
2312            None,
2313        )
2314        .unwrap();
2315        assert_eq!(descriptor.rm_control(), Some(0x5a));
2316        assert!(descriptor.owner_defaulted());
2317        assert!(descriptor.group_defaulted());
2318        assert!(descriptor.dacl_defaulted());
2319        assert!(descriptor.sacl_defaulted());
2320        assert!(descriptor.dacl_auto_inherit_required());
2321        assert!(descriptor.sacl_auto_inherit_required());
2322        assert!(descriptor.dacl_auto_inherited());
2323        assert!(descriptor.sacl_auto_inherited());
2324        assert!(descriptor.dacl_protected());
2325        assert!(descriptor.sacl_protected());
2326        assert!(!descriptor.control().contains(SecDescControl::SELF_RELATIVE));
2327
2328        let descriptor = SecDesc::new(
2329            SecInfo::empty(),
2330            0x5a,
2331            SecDescControl::empty(),
2332            None,
2333            None,
2334            None,
2335            None,
2336        )
2337        .unwrap();
2338        assert_eq!(descriptor.rm_control(), None);
2339    }
2340
2341    #[test]
2342    fn serde_is_structural_and_validated() {
2343        let owner = sid("S-1-5-18");
2344        let dacl = valid_acl(8);
2345        let descriptor = SecDesc::new(
2346            SecInfo::OWNER | SecInfo::DACL,
2347            0x42,
2348            SecDescControl::DACL_PRESENT | SecDescControl::RM_CONTROL_VALID,
2349            Some(owner.clone()),
2350            None,
2351            Some(dacl.clone()),
2352            None,
2353        )
2354        .unwrap();
2355        let encoded = postcard::to_stdvec(&descriptor).unwrap();
2356        let expected = postcard::to_stdvec(&(
2357            (SecInfo::OWNER | SecInfo::DACL).bits(),
2358            1u8,
2359            0x42u8,
2360            SecDescControl::DACL_PRESENT.bits() | SecDescControl::RM_CONTROL_VALID.bits(),
2361            Some(owner),
2362            Option::<Sid>::None,
2363            Some(dacl),
2364            Option::<Vec<u8>>::None,
2365        ))
2366        .unwrap();
2367        assert_eq!(encoded, expected);
2368        assert_eq!(
2369            postcard::from_bytes::<SecDesc>(&encoded).unwrap(),
2370            descriptor
2371        );
2372
2373        let malformed = postcard::to_stdvec(&(
2374            0u32,
2375            2u8,
2376            0u8,
2377            0u16,
2378            Option::<Sid>::None,
2379            Option::<Sid>::None,
2380            Option::<Vec<u8>>::None,
2381            Option::<Vec<u8>>::None,
2382        ))
2383        .unwrap();
2384        assert!(postcard::from_bytes::<SecDesc>(&malformed).is_err());
2385    }
2386
2387    #[test]
2388    fn flag_and_revision_serde_preserve_native_values() {
2389        let info = SecInfo::OWNER | SecInfo::DACL;
2390        let control = SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED;
2391        assert_eq!(
2392            postcard::to_stdvec(&info).unwrap(),
2393            postcard::to_stdvec(&info.bits()).unwrap()
2394        );
2395        assert_eq!(
2396            postcard::to_stdvec(&control).unwrap(),
2397            postcard::to_stdvec(&control.bits()).unwrap()
2398        );
2399        assert_eq!(postcard::to_stdvec(&Revision::One).unwrap(), vec![REVISION]);
2400        assert!(postcard::from_bytes::<Revision>(&[2]).is_err());
2401
2402        for flags in [
2403            AceFlags::OBJECT_INHERIT | AceFlags::FAILED_ACCESS,
2404            AceFlags::from_bits_retain(0xff),
2405        ] {
2406            let encoded = postcard::to_stdvec(&flags).unwrap();
2407            assert_eq!(encoded, postcard::to_stdvec(&flags.bits()).unwrap());
2408            assert_eq!(postcard::from_bytes::<AceFlags>(&encoded).unwrap(), flags);
2409        }
2410        let object_flags = ObjectAceFlags::from_bits_retain(0x8000_0001);
2411        let encoded = postcard::to_stdvec(&object_flags).unwrap();
2412        assert_eq!(encoded, postcard::to_stdvec(&object_flags.bits()).unwrap());
2413        assert_eq!(
2414            postcard::from_bytes::<ObjectAceFlags>(&encoded).unwrap(),
2415            object_flags
2416        );
2417
2418        for ace_type in [AceType::AccessAllowed, AceType::Unknown(0xfe)] {
2419            let encoded = postcard::to_stdvec(&ace_type).unwrap();
2420            assert_eq!(encoded, vec![u8::from(ace_type)]);
2421            assert_eq!(postcard::from_bytes::<AceType>(&encoded).unwrap(), ace_type);
2422        }
2423        for revision in [
2424            AclRevision::Basic,
2425            AclRevision::DirectoryService,
2426            AclRevision::Unknown(3),
2427        ] {
2428            let encoded = postcard::to_stdvec(&revision).unwrap();
2429            assert_eq!(encoded, vec![u8::from(revision)]);
2430            assert_eq!(
2431                postcard::from_bytes::<AclRevision>(&encoded).unwrap(),
2432                revision
2433            );
2434        }
2435    }
2436
2437    #[test]
2438    fn self_relative_packet_round_trip() {
2439        let packet = [
2440            0x01, 0x5a, 0x15, 0xd0, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
2441            0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
2442            0x12, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
2443            0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
2444        ];
2445        let descriptor = SecDesc::from_bytes(&packet).unwrap();
2446        assert_eq!(descriptor.mask(), SecInfo::ALL);
2447        assert_eq!(descriptor.control().bits(), 0x5015);
2448        assert_eq!(descriptor.rm_control(), Some(0x5a));
2449        assert_eq!(descriptor.owner().unwrap().to_string(), "S-1-5-18");
2450        assert_eq!(descriptor.group().unwrap().to_string(), "S-1-5-32-544");
2451        assert!(descriptor.sacl_present());
2452        assert_eq!(descriptor.sacl(), None);
2453        assert_eq!(descriptor.dacl().map(Acl::as_bytes), Some(&packet[48..]));
2454        assert_eq!(descriptor.to_bytes(), packet);
2455    }
2456
2457    #[test]
2458    fn self_relative_parser_tracks_selected_components() {
2459        let descriptor = SecDesc::new(
2460            SecInfo::ALL,
2461            0,
2462            SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED,
2463            Some(sid("S-1-5-18")),
2464            Some(sid("S-1-5-32-544")),
2465            Some(valid_acl(8)),
2466            None,
2467        )
2468        .unwrap();
2469        let packet = descriptor.to_bytes();
2470
2471        let selected = SecDesc::from_bytes_with_mask(&packet, SecInfo::DACL).unwrap();
2472        assert_eq!(selected.mask(), SecInfo::DACL);
2473        assert!(!selected.owner_loaded());
2474        assert_eq!(selected.owner(), None);
2475        assert!(selected.dacl_loaded());
2476        assert_eq!(
2477            selected.dacl().map(Acl::as_bytes),
2478            Some(valid_acl(8).as_bytes())
2479        );
2480        assert!(selected.dacl_protected());
2481
2482        let empty = SecDesc::from_bytes_with_mask(&packet, SecInfo::empty()).unwrap();
2483        assert_eq!(empty.mask(), SecInfo::empty());
2484        assert_eq!(
2485            empty.control(),
2486            SecDescControl::DACL_PRESENT | SecDescControl::DACL_PROTECTED
2487        );
2488        assert_eq!(empty.owner(), None);
2489        assert_eq!(empty.dacl(), None);
2490    }
2491
2492    #[test]
2493    fn self_relative_packet_writer_uses_canonical_component_order() {
2494        let descriptor = SecDesc::new(
2495            SecInfo::ALL,
2496            0,
2497            SecDescControl::DACL_PRESENT,
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        assert_eq!(u32::from_le_bytes(packet[4..8].try_into().unwrap()), 20);
2506        assert_eq!(u32::from_le_bytes(packet[8..12].try_into().unwrap()), 32);
2507        assert_eq!(u32::from_le_bytes(packet[12..16].try_into().unwrap()), 0);
2508        assert_eq!(u32::from_le_bytes(packet[16..20].try_into().unwrap()), 48);
2509        assert_eq!(SecDesc::from_bytes(&packet).unwrap(), descriptor);
2510    }
2511
2512    #[test]
2513    fn rejects_malformed_self_relative_packets() {
2514        assert_eq!(
2515            SecDesc::from_bytes(&[0; SELF_RELATIVE_HEADER_LEN - 1]),
2516            Err(SecDescError::PacketLength)
2517        );
2518
2519        let mut packet = [0; SELF_RELATIVE_HEADER_LEN];
2520        packet[0] = 1;
2521        assert_eq!(
2522            SecDesc::from_bytes(&packet),
2523            Err(SecDescError::NotSelfRelative)
2524        );
2525
2526        packet[2..4].copy_from_slice(&SecDescControl::SELF_RELATIVE.bits().to_le_bytes());
2527        packet[4..8].copy_from_slice(&4u32.to_le_bytes());
2528        assert_eq!(
2529            SecDesc::from_bytes(&packet),
2530            Err(SecDescError::PacketOffset(SecDescComponent::Owner, 4))
2531        );
2532
2533        packet[4..8].copy_from_slice(&20u32.to_le_bytes());
2534        assert_eq!(
2535            SecDesc::from_bytes(&packet),
2536            Err(SecDescError::PacketOffset(SecDescComponent::Owner, 20))
2537        );
2538    }
2539
2540    #[test]
2541    fn owned_ace_builders_select_layouts_and_pad_application_data() {
2542        let trustee = sid("S-1-1-0");
2543        let object_type: Guid = "00112233-4455-6677-8899-aabbccddeeff".parse().unwrap();
2544        let basic = AceBuf::allow(
2545            &trustee,
2546            AccessMask::from_bits_retain(0x1234),
2547            AceBuildOptions::new()
2548                .flags(AceFlags::from_bits_retain(0x03))
2549                .application_data([1, 2, 3]),
2550        )
2551        .unwrap();
2552        assert_eq!(basic.ace_type(), AceType::AccessAllowed);
2553        assert_eq!(basic.flags().bits(), 0x03);
2554        assert_eq!(basic.application_data(), Some(&[1, 2, 3, 0][..]));
2555        assert_eq!(Ace::from_bytes(basic.as_bytes()).unwrap(), &*basic);
2556
2557        let object = AceBuf::deny(
2558            &trustee,
2559            AccessMask::from_bits_retain(u32::MAX),
2560            AceBuildOptions::new().object_type(object_type).callback(),
2561        )
2562        .unwrap();
2563        assert_eq!(object.ace_type(), AceType::AccessDeniedCallbackObject);
2564        assert_eq!(
2565            object.object_flags(),
2566            Some(ObjectAceFlags::OBJECT_TYPE_PRESENT)
2567        );
2568        assert_eq!(object.object_type(), Some(object_type));
2569        assert_eq!(object.inherited_object_type(), None);
2570    }
2571
2572    #[test]
2573    fn audit_builder_enforces_outcomes_and_reserves_audit_flags() {
2574        let trustee = sid("S-1-5-18");
2575        assert_eq!(
2576            AceBuf::audit(
2577                &trustee,
2578                AccessMask::from_specific_rights(1),
2579                false,
2580                false,
2581                AceBuildOptions::new()
2582            ),
2583            Err(AceBuildError::AuditOutcome)
2584        );
2585        assert_eq!(
2586            AceBuf::audit(
2587                &trustee,
2588                AccessMask::from_specific_rights(1),
2589                true,
2590                false,
2591                AceBuildOptions::new().flags(AceFlags::SUCCESSFUL_ACCESS),
2592            ),
2593            Err(AceBuildError::AuditFlags)
2594        );
2595        let audit = AceBuf::audit(
2596            &trustee,
2597            AccessMask::from_specific_rights(1),
2598            true,
2599            true,
2600            AceBuildOptions::new(),
2601        )
2602        .unwrap();
2603        assert_eq!(audit.ace_type(), AceType::SystemAudit);
2604        assert_eq!(audit.flags().bits(), 0xc0);
2605    }
2606
2607    #[test]
2608    fn acl_builder_preserves_packets_and_selects_revision() {
2609        let trustee = sid("S-1-1-0");
2610        let basic = AceBuf::allow(
2611            &trustee,
2612            AccessMask::from_specific_rights(1),
2613            AceBuildOptions::new(),
2614        )
2615        .unwrap();
2616        let object = AceBuf::allow(
2617            &trustee,
2618            AccessMask::from_specific_rights(2),
2619            AceBuildOptions::new()
2620                .object_type("00000000-0000-0000-0000-000000000000".parse().unwrap()),
2621        )
2622        .unwrap();
2623        let acl = AclBuf::from_aces([&*basic], None).unwrap();
2624        assert_eq!(acl.revision(), AclRevision::Basic);
2625        assert_eq!(acl.aces().next().unwrap().as_bytes(), basic.as_bytes());
2626
2627        let acl = AclBuf::from_aces([&*basic, &*object], None).unwrap();
2628        assert_eq!(acl.revision(), AclRevision::DirectoryService);
2629        assert_eq!(
2630            AclBuf::from_aces([&*object], Some(AclRevision::Basic)),
2631            Err(AclBuildError::ObjectRevision)
2632        );
2633        assert_eq!(
2634            AclBuf::from_aces([&*basic], Some(AclRevision::Unknown(3))),
2635            Err(AclBuildError::Revision(3))
2636        );
2637        assert_eq!(Acl::from_bytes(acl.as_bytes()).unwrap(), &*acl);
2638    }
2639
2640    #[test]
2641    fn owned_packets_validate_raw_and_serde_inputs() {
2642        let trustee = sid("S-1-1-0");
2643        let ace = AceBuf::allow(
2644            &trustee,
2645            AccessMask::from_specific_rights(1),
2646            AceBuildOptions::new(),
2647        )
2648        .unwrap();
2649        let encoded = postcard::to_stdvec(&ace).unwrap();
2650        assert_eq!(postcard::from_bytes::<AceBuf>(&encoded).unwrap(), ace);
2651        assert!(AceBuf::try_from_bytes(vec![0, 0, 4, 0].into_boxed_slice()).is_err());
2652
2653        let acl = AclBuf::from_aces([&*ace], None).unwrap();
2654        let encoded = postcard::to_stdvec(&acl).unwrap();
2655        assert_eq!(postcard::from_bytes::<AclBuf>(&encoded).unwrap(), acl);
2656        let mut malformed = acl.as_bytes().to_vec();
2657        malformed[2] = 0;
2658        assert!(AclBuf::try_from_bytes(malformed.into_boxed_slice()).is_err());
2659    }
2660
2661    #[test]
2662    fn functional_updates_cover_component_states_and_controls() {
2663        let descriptor = SecDesc::new(
2664            SecInfo::empty(),
2665            0,
2666            SecDescControl::empty(),
2667            None,
2668            None,
2669            None,
2670            None,
2671        )
2672        .unwrap();
2673        let concrete = AclBuf::from_aces(std::iter::empty::<&Ace>(), None).unwrap();
2674        let updated = descriptor
2675            .with(
2676                SecDescUpdate::new()
2677                    .owner(Some(sid("S-1-5-18")))
2678                    .dacl(Some(concrete.clone()))
2679                    .owner_defaulted(true)
2680                    .dacl_protected(true)
2681                    .rm_control(Some(0x5a)),
2682            )
2683            .unwrap();
2684        assert!(!descriptor.owner_loaded());
2685        assert_eq!(updated.owner().unwrap().to_string(), "S-1-5-18");
2686        assert_eq!(updated.dacl(), Some(&*concrete));
2687        assert!(updated.dacl_present());
2688        assert!(updated.owner_defaulted());
2689        assert!(updated.dacl_protected());
2690        assert_eq!(updated.rm_control(), Some(0x5a));
2691
2692        let null = updated
2693            .with(SecDescUpdate::new().dacl(None).rm_control(None))
2694            .unwrap();
2695        assert!(null.dacl_present());
2696        assert_eq!(null.dacl(), None);
2697        assert_eq!(null.rm_control(), None);
2698
2699        let absent = null.with(SecDescUpdate::new().dacl_present(false)).unwrap();
2700        assert!(absent.dacl_loaded());
2701        assert!(!absent.dacl_present());
2702        assert_eq!(
2703            descriptor.with(SecDescUpdate::new().dacl_present(true)),
2704            Err(SecDescError::AclPresenceRequiresValue(AclKind::Dacl))
2705        );
2706        let unloaded_present = SecDesc::new(
2707            SecInfo::empty(),
2708            0,
2709            SecDescControl::DACL_PRESENT,
2710            None,
2711            None,
2712            None,
2713            None,
2714        )
2715        .unwrap();
2716        assert_eq!(
2717            unloaded_present.with(SecDescUpdate::new().dacl_present(true)),
2718            Err(SecDescError::AclPresenceRequiresValue(AclKind::Dacl))
2719        );
2720        assert_eq!(
2721            descriptor.with(SecDescUpdate::new().dacl_protected(true)),
2722            Err(SecDescError::ComponentNotLoaded(SecDescComponent::Dacl))
2723        );
2724    }
2725}