use std::str::FromStr;
use crate::*;
grammar(domain_rid: Option<&[u32]>);
extern {
type Error = Error;
}
pub SecurityDescriptor: SecurityDescriptor = {
// only DACL or DACL first and SACL second
"O:" <owner: SidOrAlias> "G:" <group: SidOrAlias> <dacl: DAcl> <sacl: SAcl?> =>? {
Ok(SecurityDescriptor::new(Some(owner), Some(group), Some(dacl), sacl))
},
// only SACL or SACL first and DACL second
"O:" <owner: SidOrAlias> "G:" <group: SidOrAlias> <sacl: SAcl> <dacl: DAcl?> =>? {
Ok(SecurityDescriptor::new(Some(owner), Some(group), dacl, Some(sacl)))
},
}
// (Type;Flags;Access;[ObjectType];[InheritedObjectType];SID[;ExtraData])
// there is no way to parse SACL and DACL flags separately. So, we set both,
// the DACL and SACL flags, and delete the unwanted flags afterwards
pub Acl: Acl = { <dacl: DAcl> => dacl, <sacl: SAcl> => sacl, }
pub DAcl: Acl = {
"D:" <flags: AclFlags?> <ace_list: Ace*> => Acl::new(
acl::Revision::ACL_REVISION,
acl::Type::DACL,
flags.unwrap_or(ControlFlags::empty()).remove_sacl_flags(),
ace_list
),
}
pub SAcl: Acl = {
"S:" <flags: AclFlags?> <ace_list: Ace*> => Acl::new(
acl::Revision::ACL_REVISION,
acl::Type::SACL,
flags.unwrap_or(ControlFlags::empty()).remove_dacl_flags(),
ace_list
)
}
// "PAR" and "PAI" conflict with the well-known SID "PA", so we create distinct tokens for these flags
pub AclFlags: ControlFlags = {
"P" => control_flags!(
SystemAclProtected |
DiscretionaryAclProtected),
"PAR" => control_flags!(
SystemAclProtected |
DiscretionaryAclProtected |
SystemAclAutoInheritRequired |
DiscretionaryAclAutoInheritRequired),
"PAI" => control_flags!(
SystemAclProtected |
DiscretionaryAclProtected |
SystemAclAutoInherited |
DiscretionaryAclAutoInherited),
"PAIAR" => control_flags!(
SystemAclProtected |
DiscretionaryAclProtected |
SystemAclAutoInherited |
DiscretionaryAclAutoInherited |
SystemAclAutoInheritRequired |
DiscretionaryAclAutoInheritRequired),
"PARAI" => control_flags!(
SystemAclProtected |
DiscretionaryAclProtected |
SystemAclAutoInherited |
DiscretionaryAclAutoInherited |
SystemAclAutoInheritRequired |
DiscretionaryAclAutoInheritRequired),
"AR" => control_flags!(
SystemAclAutoInheritRequired |
DiscretionaryAclAutoInheritRequired),
"AI" => control_flags!(
SystemAclAutoInherited |
DiscretionaryAclAutoInherited)
}
SingleAclFlag: ControlFlags = {
"P" => control_flags!(SystemAclProtected | DiscretionaryAclProtected),
"AR" => control_flags!(SystemAclAutoInheritRequired | DiscretionaryAclAutoInheritRequired),
"AI" => control_flags!(SystemAclAutoInherited | DiscretionaryAclAutoInherited),
}
pub Ace: Ace = {
"(A;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::ACCESS_ALLOWED_ACE_TYPE),
"(D;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::ACCESS_DENIED_ACE_TYPE),
"(OA;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::ACCESS_ALLOWED_OBJECT_ACE_TYPE),
"(OD;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::ACCESS_DENIED_OBJECT_ACE_TYPE),
"(AU;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::SYSTEM_AUDIT_ACE_TYPE),
"(OU;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::SYSTEM_AUDIT_OBJECT_ACE_TYPE),
"(ML;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::SYSTEM_MANDATORY_LABEL_ACE_TYPE),
"(SP;" <a: AceSimpleData> ")" => a.into_ace(ace::Type::SYSTEM_SCOPED_POLICY_ID_ACE_TYPE)
}
/*
pub ConditionalAce: Ace = {
//"(XA;" <a: AceSidAppdata> ")" => Ace::access_allowed_callback(a.0, a.1, a.2, a.3),
//"(XD;" <a: AceSidAppdata> ")" => Ace::access_denied_callback(a.0, a.1, a.2, a.3),
//"(ZA;" <a: AceSidObjectAppdata> ")" => Ace::access_allowed_object_callback(a.0, a.1, a.2, a.3, a.4, a.5),
//"(ZD;" <a: AceSidObjectAppdata> ")" => Ace::access_denied_object_callback(a.0, a.1, a.2, a.3, a.4, a.5),
//"(XU;" <a: AceSidAppdata> ")" => Ace::audit_callback(a.0, a.1, a.2, a.3),
//"(ZU;" <a: AceSidObjectAppdata> ")" => Ace::audit_callback_object(a.0, a.1, a.2, a.3, a.4, a.5),
}
*/
AceSimpleData: ace::ParsedContents = {
<flags: AceHeaderFlags> ";"
<mask: AccessMask> ";"
<object_type: Guid?> ";"
<inherited_object_type: Guid?> ";"
<sid: SidOrAlias> =>? {
Ok(ace::ParsedContents::new(flags, mask, sid, object_type, inherited_object_type))
}
}
SidOrAlias: Sid = {
<alias: Alias> =>? Ok(Sid::try_from_alias(alias, domain_rid)?),
<sid:r#"S-1-\d+(-\d+)*"#> =>? Ok(Sid::try_from(sid)?)
}
AceHeaderFlags: ace::header::Flags = {
<s:AceHeaderFlagAlias*> =>? Ok(s.into_iter().fold(ace::header::Flags::empty(), |v, s| v|s ))
}
AceHeaderFlagAlias: ace::header::Flags = {
<alias: Alias> =>? Ok(ace::header::Flags::try_from_alias(alias)?)
}
pub AccessMask: AccessMask = {
<s:SingleAccessMask*> =>? Ok(s.into_iter().fold(AccessMask::empty(), |v, s| v|s )),
<n:Number> =>? Ok(AccessMask::from(n)),
};
SingleAccessMask: AccessMask = {
<alias: Alias> =>? Ok(AccessMask::try_from_alias(alias)?)
}
pub Guid: Guid = {
<guid: r"[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"> => guid.try_into().unwrap()
}
Alias: &'input str = {
<alias: r"[A-Z]{2}"> => alias
}
Number: u32 = {
<s:r#"0x[0-9a-fA-F]+"#> => {
u32::from_str_radix(&s[2..], 16).unwrap()
},
<s:r#"0[0-7]+"#> => {
u32::from_str_radix(s, 8).unwrap()
},
<s:r#"[1-9][0-9]*"#> => {
u32::from_str(s).unwrap()
}
}
/*
ace::Type: &'static str = {
"A" => sddl_h::SDDL_ACCESS_ALLOWED,
"D" => sddl_h::SDDL_ACCESS_DENIED,
"AU" => sddl_h::SDDL_AUDIT,
"AL" => sddl_h::SDDL_ALARM,
"OA" => sddl_h::SDDL_OBJECT_ACCESS_ALLOWED,
"OD" => sddl_h::SDDL_OBJECT_ACCESS_DENIED,
"OU" => sddl_h::SDDL_OBJECT_AUDIT,
"OL" => sddl_h::SDDL_OBJECT_ALARM,
"XA" => sddl_h::SDDL_CALLBACK_ACCESS_ALLOWED,
"XD" => sddl_h::SDDL_CALLBACK_ACCESS_DENIED,
"ZA" => sddl_h::SDDL_CALLBACK_OBJECT_ACCESS_ALLOWED,
"XU" => sddl_h::SDDL_CALLBACK_AUDIT,
"ML" => sddl_h::SDDL_MANDATORY_LABEL,
"RA" => sddl_h::SDDL_RESOURCE_ATTRIBUTE,
"SP" => sddl_h::SDDL_SCOPED_POLICY_ID,
"TL" => sddl_h::SDDL_PROCESS_TRUST_LABEL,
"FL" => sddl_h::SDDL_ACCESS_FILTER,
}
*/