1use binrw::BinRead;
2use binrw::BinReaderExt;
3use binrw::BinWrite;
4use binrw::BinWriterExt;
5use enumflags2::{bitflags, BitFlags};
6use serde::Serialize;
7
8use crate::*;
9#[derive(Eq, PartialEq, Debug, Copy, Clone, Serialize)]
11#[repr(u16)]
12#[allow(non_camel_case_types)]
13#[bitflags]
14pub enum ControlFlag {
15 OwnerDefaulted = 0x0001, GroupDefaulted = 0x0002, DiscretionaryAclPresent = 0x0004, DiscretionaryAclDefaulted = 0x0008, SystemAclPresent = 0x0010, SystemAclDefaulted = 0x0020, DiscretionaryAclUntrusted = 0x0040, ServerSecurity = 0x0080, DiscretionaryAclAutoInheritRequired = 0x0100, SystemAclAutoInheritRequired = 0x0200, DiscretionaryAclAutoInherited = 0x0400, SystemAclAutoInherited = 0x0800, DiscretionaryAclProtected = 0x1000, SystemAclProtected = 0x2000, RMControlValid = 0x4000, SelfRelative = 0x8000, }
32
33flag_wrapper!(ControlFlags, ControlFlag, u16);
34
35#[macro_export]
36macro_rules! control_flags {
37 ( $($variant:ident)|* ) => {
38 {
39 use $crate::ControlFlag;
40 $crate::ControlFlags::from_bitflags(enumflags2::make_bitflags!(ControlFlag::{$($variant)|*}))
41 }
42 };
43 ($flag:ident) => {
44 {
45 use $crate::ControlFlag;
46 $crate::ControlFlags::from_bitflags(enumflags2::make_bitflags!(ControlFlag::{$flag}))
47 }
48 };
49}
50
51impl ControlFlags {
52 pub fn remove_sacl_flags(self) -> Self {
53 Self::from(
54 self.flags
55 & !(crate::ControlFlag::SystemAclProtected
56 | crate::ControlFlag::SystemAclAutoInheritRequired
57 | crate::ControlFlag::SystemAclAutoInherited),
58 )
59 }
60
61 pub fn remove_dacl_flags(self) -> Self {
62 Self::from(
63 self.flags
64 & !(crate::ControlFlag::DiscretionaryAclProtected
65 | crate::ControlFlag::DiscretionaryAclAutoInheritRequired
66 | crate::ControlFlag::DiscretionaryAclAutoInherited),
67 )
68 }
69
70 pub fn sddl_string(&self, acl_type: acl::Type) -> String {
71 if self.flags == BitFlags::<ControlFlag, u16>::EMPTY {
72 SDDL_NULL_ACL.into()
73 } else {
74 let mut sddl = String::with_capacity(32);
75 let mut flag = |flag: ControlFlag, s: &str| {
76 if self.flags.contains(flag) {
77 sddl.push_str(s);
78 }
79 };
80
81 match acl_type {
82 acl::Type::SACL => {
83 flag(ControlFlag::SystemAclProtected, SDDL_PROTECTED);
84 flag(
85 ControlFlag::SystemAclAutoInheritRequired,
86 SDDL_AUTO_INHERIT_REQ,
87 );
88 flag(ControlFlag::SystemAclAutoInherited, SDDL_AUTO_INHERITED);
89 }
90 acl::Type::DACL => {
91 flag(ControlFlag::DiscretionaryAclProtected, SDDL_PROTECTED);
92 flag(
93 ControlFlag::DiscretionaryAclAutoInheritRequired,
94 SDDL_AUTO_INHERIT_REQ,
95 );
96 flag(
97 ControlFlag::DiscretionaryAclAutoInherited,
98 SDDL_AUTO_INHERITED,
99 );
100 }
101 }
102 sddl
103 }
104 }
105}