use binrw::BinRead;
use binrw::BinReaderExt;
use binrw::BinWrite;
use binrw::BinWriterExt;
use enumflags2::{bitflags, BitFlags};
use serde::Serialize;
use crate::*;
#[derive(Eq, PartialEq, Debug, Copy, Clone, Serialize)]
#[repr(u16)]
#[allow(non_camel_case_types)]
#[bitflags]
pub enum ControlFlag {
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, }
flag_wrapper!(ControlFlags, ControlFlag, u16);
#[macro_export]
macro_rules! control_flags {
( $($variant:ident)|* ) => {
{
use $crate::ControlFlag;
$crate::ControlFlags::from_bitflags(enumflags2::make_bitflags!(ControlFlag::{$($variant)|*}))
}
};
($flag:ident) => {
{
use $crate::ControlFlag;
$crate::ControlFlags::from_bitflags(enumflags2::make_bitflags!(ControlFlag::{$flag}))
}
};
}
impl ControlFlags {
pub fn remove_sacl_flags(self) -> Self {
Self::from(
self.flags
& !(crate::ControlFlag::SystemAclProtected
| crate::ControlFlag::SystemAclAutoInheritRequired
| crate::ControlFlag::SystemAclAutoInherited),
)
}
pub fn remove_dacl_flags(self) -> Self {
Self::from(
self.flags
& !(crate::ControlFlag::DiscretionaryAclProtected
| crate::ControlFlag::DiscretionaryAclAutoInheritRequired
| crate::ControlFlag::DiscretionaryAclAutoInherited),
)
}
pub fn sddl_string(&self, acl_type: acl::Type) -> String {
if self.flags == BitFlags::<ControlFlag, u16>::EMPTY {
SDDL_NULL_ACL.into()
} else {
let mut sddl = String::with_capacity(32);
let mut flag = |flag: ControlFlag, s: &str| {
if self.flags.contains(flag) {
sddl.push_str(s);
}
};
match acl_type {
acl::Type::SACL => {
flag(ControlFlag::SystemAclProtected, SDDL_PROTECTED);
flag(
ControlFlag::SystemAclAutoInheritRequired,
SDDL_AUTO_INHERIT_REQ,
);
flag(ControlFlag::SystemAclAutoInherited, SDDL_AUTO_INHERITED);
}
acl::Type::DACL => {
flag(ControlFlag::DiscretionaryAclProtected, SDDL_PROTECTED);
flag(
ControlFlag::DiscretionaryAclAutoInheritRequired,
SDDL_AUTO_INHERIT_REQ,
);
flag(
ControlFlag::DiscretionaryAclAutoInherited,
SDDL_AUTO_INHERITED,
);
}
}
sddl
}
}
}