sddl 0.0.13

a library to parse and analyse SDDL Strings
Documentation
use std::str::FromStr;
use crate::Error;
use crate::constants::*;
use crate::parsing::*;

grammar(domain_rid: Option<&[u32]>);

extern {
    type Error = Error;
}

pub SecurityDescriptor: crate::SecurityDescriptor = {
    "O:" <owner: Sid> "G:" <group: Sid> <dacl: DAcl> <sacl: SAcl> =>
    crate::SecurityDescriptor::new(Some(owner), Some(group), Some(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: crate::Acl = { <dacl: DAcl> => dacl, <sacl: SAcl> => sacl, }

pub DAcl: crate::Acl = {
    "D:" <flags: AclFlags> <ace_list: AceList> => crate::Acl::new(
        crate::AclRevision::ACL_REVISION,
        crate::AclType::DACL,
        flags & !(crate::ControlFlags::SystemAclProtected | crate::ControlFlags::SystemAclAutoInheritRequired | crate::ControlFlags::SystemAclAutoInherited),
        ace_list
    ),
}

pub SAcl: crate::Acl = {
    "S:" <flags: AclFlags> <ace_list: AceList> => crate::Acl::new(
        crate::AclRevision::ACL_REVISION,
        crate::AclType::SACL,
        flags & !(crate::ControlFlags::DiscretionaryAclProtected | crate::ControlFlags::DiscretionaryAclAutoInheritRequired | crate::ControlFlags::DiscretionaryAclAutoInherited),
        ace_list
    )
}

// "PAR" and "PAI" conflict with "PA", so we create distinct tokens for these flags
pub AclFlags: crate::ControlFlags = {
    //<s:SingleAclFlag> => s,
    //<a:AclFlags> <s:SingleAclFlag> => a | s
    "P" =>      crate::ControlFlags::SystemAclProtected |
                crate::ControlFlags::DiscretionaryAclProtected,

    "PAR"   =>  crate::ControlFlags::SystemAclProtected |
                crate::ControlFlags::DiscretionaryAclProtected |
                crate::ControlFlags::SystemAclAutoInheritRequired |
                crate::ControlFlags::DiscretionaryAclAutoInheritRequired,

    "PAI"   =>  crate::ControlFlags::SystemAclProtected |
                crate::ControlFlags::DiscretionaryAclProtected |
                crate::ControlFlags::SystemAclAutoInherited |
                crate::ControlFlags::DiscretionaryAclAutoInherited,
    
    "PAIAR" =>  crate::ControlFlags::SystemAclProtected |
                crate::ControlFlags::DiscretionaryAclProtected |
                crate::ControlFlags::SystemAclAutoInherited |
                crate::ControlFlags::DiscretionaryAclAutoInherited |
                crate::ControlFlags::SystemAclAutoInheritRequired |
                crate::ControlFlags::DiscretionaryAclAutoInheritRequired,
    
    "PARAI" =>  crate::ControlFlags::SystemAclProtected |
                crate::ControlFlags::DiscretionaryAclProtected |
                crate::ControlFlags::SystemAclAutoInherited |
                crate::ControlFlags::DiscretionaryAclAutoInherited |
                crate::ControlFlags::SystemAclAutoInheritRequired |
                crate::ControlFlags::DiscretionaryAclAutoInheritRequired,

    "AR" =>     crate::ControlFlags::SystemAclAutoInheritRequired |
                crate::ControlFlags::DiscretionaryAclAutoInheritRequired,
    "AI" =>     crate::ControlFlags::SystemAclAutoInherited |
                crate::ControlFlags::DiscretionaryAclAutoInherited,
}

SingleAclFlag: crate::ControlFlags = {
    "P" => crate::ControlFlags::SystemAclProtected | crate::ControlFlags::DiscretionaryAclProtected,
    "AR" => crate::ControlFlags::SystemAclAutoInheritRequired | crate::ControlFlags::DiscretionaryAclAutoInheritRequired,
    "AI" => crate::ControlFlags::SystemAclAutoInherited | crate::ControlFlags::DiscretionaryAclAutoInherited,
}

pub AceList: Vec<crate::Ace> = {
    <ace:Ace> => vec![ace],
    <l:AceList> <ace:Ace> => {
        let mut l = l;
        l.push(ace);
        l
    }
}

pub Ace: crate::Ace = {
    "(A;" <a: AceSid> ")" => crate::Ace::access_allowed(a.0, a.1, a.2),
    "(D;" <a: AceSid> ")" => crate::Ace::access_denied(a.0, a.1, a.2),
    "(OA;" <a: AceSidObject> ")" => crate::Ace::access_allowed_object(a.0, a.1, Some(a.2), Some(a.3), a.4),
    "(OD;" <a: AceSidObject> ")" => crate::Ace::access_denied_object(a.0, a.1, Some(a.2), Some(a.3), a.4),
    //"(XA;" <a: AceSidAppdata> ")" => crate::Ace::access_allowed_callback(a.0, a.1, a.2, a.3),
    //"(XD;" <a: AceSidAppdata> ")" => crate::Ace::access_denied_callback(a.0, a.1, a.2, a.3),
    //"(ZA;" <a: AceSidObjectAppdata> ")" => crate::Ace::access_allowed_object_callback(a.0, a.1, a.2, a.3, a.4, a.5),
    //"(ZD;" <a: AceSidObjectAppdata> ")" => crate::Ace::access_denied_object_callback(a.0, a.1, a.2, a.3, a.4, a.5),
    "(AU;" <a: AceSid> ")" => crate::Ace::audit(a.0, a.1, a.2),
    //"(OU;" <a: AceSidObjectAppdata> ")" => crate::Ace::audit_object(a.0, a.1, a.2, a.3, a.4, a.5),
    //"(XU;" <a: AceSidAppdata> ")" => crate::Ace::audit_callback(a.0, a.1, a.2, a.3),
    "(ML;" <a: AceSid> ")" => crate::Ace::mandatory_label(a.0, a.1, a.2),
    //"(ZU;" <a: AceSidObjectAppdata> ")" => crate::Ace::audit_callback_object(a.0, a.1, a.2, a.3, a.4, a.5),
    //"(RA;" <a: AceSidObjectAppdata> ")" => crate::Ace::resource_attribute(a.0, a.1, a.2, a.3, a.4, a.5),
    "(SP;" <a: AceSid> ")" => crate::Ace::scoped_policy_id(a.0, a.1, a.2),
}

AceSid: (crate::AceHeaderFlags, crate::AccessMask, crate::Sid) = {
    <flags:AceHeaderFlags> ";" <mask: AccessMask> ";;;" <sid: Sid> => (flags, mask, sid)
}

AceSidObject: (crate::AceHeaderFlags, crate::AccessMask, crate::Guid, crate::Guid, crate::Sid) = {
    <flags:AceHeaderFlags> ";" <mask: AccessMask> ";" <obj:Guid> ";" <inherited:Guid> ";" <sid: Sid> => (flags, mask, obj, inherited, sid)
}

pub Sid: crate::Sid = {
    "AA" => crate::Sid::new_builtin(579),
    "AC" => APPLICATION_PACKAGE_AUTHORITY.new_sid(&[2, 1]),
    "AN" => SECURITY_NT_AUTHORITY.new_sid(&[7]),
    "AO" => crate::Sid::new_builtin(548),
    "AP" =>? domain_rid.new_domain_sid(525),
    "AS" => AUTHENTICATION_AUTHORITY.new_sid(&[1]),
    "AU" => SECURITY_NT_AUTHORITY.new_sid(&[11]),
    "BA" => crate::Sid::new_builtin(544),
    "BG" => crate::Sid::new_builtin(546),
    "BO" => crate::Sid::new_builtin(551),
    "BU" => crate::Sid::new_builtin(545),
    "CA" =>? domain_rid.new_domain_sid(517),
    "CD" => crate::Sid::new_builtin(574),
    "CG" => SECURITY_CREATOR_SID_AUTHORITY.new_sid(&[1]),
    "CN" =>? domain_rid.new_domain_sid(522),
    "CO" => SECURITY_CREATOR_SID_AUTHORITY.new_sid(&[0]),
    "CY" => crate::Sid::new_builtin(569),
    "DA" =>? domain_rid.new_domain_sid(512),
    "DC" =>? domain_rid.new_domain_sid(515),
    "DD" =>? domain_rid.new_domain_sid(516),
    "DG" =>? domain_rid.new_domain_sid(514),
    "DU" =>? domain_rid.new_domain_sid(513),
    "EA" =>? domain_rid.new_domain_sid(519),
    "ED" => SECURITY_NT_AUTHORITY.new_sid(&[9]),
    "EK" =>? domain_rid.new_domain_sid(527),
    "ER" => crate::Sid::new_builtin(573),
    "ES" => crate::Sid::new_builtin(576),
    "HA" => crate::Sid::new_builtin(578),
    "HI" => MANDATORY_LABEL_AUTHORITY.new_sid(&[12288]),
    "IS" => crate::Sid::new_builtin(568),
    "IU" => SECURITY_NT_AUTHORITY.new_sid(&[4]),
    "KA" =>? domain_rid.new_domain_sid(526),
    "LA" =>? domain_rid.new_domain_sid(500),
    "LG" =>? domain_rid.new_domain_sid(501),
    "LS" => SECURITY_NT_AUTHORITY.new_sid(&[19]),
    "LU" => crate::Sid::new_builtin(559),
    "LW" => MANDATORY_LABEL_AUTHORITY.new_sid(&[4096]),
    "ME" => MANDATORY_LABEL_AUTHORITY.new_sid(&[8192]),
    "MP" => MANDATORY_LABEL_AUTHORITY.new_sid(&[8448]),
    "MS" => crate::Sid::new_builtin(577),
    "MU" => crate::Sid::new_builtin(558),
    "NO" => crate::Sid::new_builtin(556),
    "NS" => SECURITY_NT_AUTHORITY.new_sid(&[20]),
    "NU" => SECURITY_NT_AUTHORITY.new_sid(&[2]),
    "OW" => SECURITY_CREATOR_SID_AUTHORITY.new_sid(&[4]),
    "PA" =>? domain_rid.new_domain_sid(520),
    "PO" => crate::Sid::new_builtin(550),
    "PS" => SECURITY_NT_AUTHORITY.new_sid(&[10]),
    "PU" => crate::Sid::new_builtin(547),
    "RA" => crate::Sid::new_builtin(575),
    "RC" => SECURITY_NT_AUTHORITY.new_sid(&[12]),
    "RD" => crate::Sid::new_builtin(555),
    "RE" => crate::Sid::new_builtin(552),
    "RM" => crate::Sid::new_builtin(580),
    "RO" =>? domain_rid.new_domain_sid(498),
    "RS" =>? domain_rid.new_domain_sid(553),
    "RU" => crate::Sid::new_builtin(554),
    "SA" =>? domain_rid.new_domain_sid(518),
    "SI" => MANDATORY_LABEL_AUTHORITY.new_sid(&[16384]),
    "SO" => crate::Sid::new_builtin(549),
    "SS" => AUTHENTICATION_AUTHORITY.new_sid(&[2]),
    "SU" => SECURITY_NT_AUTHORITY.new_sid(&[6]),
    "SY" => SECURITY_NT_AUTHORITY.new_sid(&[18]),
    "UD" => SECURITY_NT_AUTHORITY.new_sid(&[84, 0, 0, 0, 0, 0]),
    "WD" => SECURITY_WORLD_SID_AUTHORITY.new_sid(&[0]),
    "WR" => SECURITY_NT_AUTHORITY.new_sid(&[33]),
    <s:r#"S-1-\d+(-\d+)*"#> => crate::Sid::try_from(s).unwrap()
}

pub Guid: crate::Guid = {
    <guid: r"[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"> => guid.try_into().unwrap()
}

AceType: &'static str = {
    "A" => crate::sddl_h::SDDL_ACCESS_ALLOWED,
    "D" => crate::sddl_h::SDDL_ACCESS_DENIED,
    "AU" => crate::sddl_h::SDDL_AUDIT,
    "AL" => crate::sddl_h::SDDL_ALARM,
    "OA" => crate::sddl_h::SDDL_OBJECT_ACCESS_ALLOWED,
    "OD" => crate::sddl_h::SDDL_OBJECT_ACCESS_DENIED,
    "OU" => crate::sddl_h::SDDL_OBJECT_AUDIT,
    "OL" => crate::sddl_h::SDDL_OBJECT_ALARM,
    "XA" => crate::sddl_h::SDDL_CALLBACK_ACCESS_ALLOWED,
    "XD" => crate::sddl_h::SDDL_CALLBACK_ACCESS_DENIED,
    "ZA" => crate::sddl_h::SDDL_CALLBACK_OBJECT_ACCESS_ALLOWED,
    "XU" => crate::sddl_h::SDDL_CALLBACK_AUDIT,
    "ML" => crate::sddl_h::SDDL_MANDATORY_LABEL,
    "RA" => crate::sddl_h::SDDL_RESOURCE_ATTRIBUTE,
    "SP" => crate::sddl_h::SDDL_SCOPED_POLICY_ID,
    "TL" => crate::sddl_h::SDDL_PROCESS_TRUST_LABEL,
    "FL" => crate::sddl_h::SDDL_ACCESS_FILTER,
}

pub AceHeaderFlags: crate::AceHeaderFlags = {
    <s:SingleAceFlag> => s,
    <a:AceHeaderFlags> <s:SingleAceFlag> => a | s
}

SingleAceFlag: crate::AceHeaderFlags = {
    "OI" => crate::AceHeaderFlags::OBJECT_INHERIT_ACE,
    "CI" => crate::AceHeaderFlags::CONTAINER_INHERIT_ACE,
    "NP" => crate::AceHeaderFlags::NO_PROPAGATE_INHERIT_ACE,
    "IO" => crate::AceHeaderFlags::INHERIT_ONLY_ACE,
    "ID" => crate::AceHeaderFlags::INHERITED_ACE,
    "CR" => crate::AceHeaderFlags::CRITICAL,
    "SA" => crate::AceHeaderFlags::SUCCESSFUL_ACCESS_ACE_FLAG,
    "FA" => crate::AceHeaderFlags::FAILED_ACCESS_ACE_FLAG,
    "TP" => crate::AceHeaderFlags::TRUST_PROTECTED_FILTER,
}

pub AccessMask: crate::AccessMask = {
    <n:Number> => crate::AccessMask::from(n),
    <s:SingleAccessMask> => s,
    <a:AccessMask> <s:SingleAccessMask> => a | s
};


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()
    }
}

SingleAccessMask: crate::AccessMask = {
    "GR" => crate::AccessMask::GENERIC_READ,
    "GW" => crate::AccessMask::GENERIC_WRITE,
    "GX" => crate::AccessMask::GENERIC_EXECUTE,
    "GA" => crate::AccessMask::GENERIC_ALL,
    "MA" => crate::AccessMask::MAXIMUM_ALLOWED,
    "AS" => crate::AccessMask::ACCESS_SYSTEM_SECURITY,
    "WO" => crate::AccessMask::WRITE_OWNER,
    "WD" => crate::AccessMask::WRITE_DACL,
    "RC" => crate::AccessMask::READ_CONTROL,
    "SD" => crate::AccessMask::DELETE,
    "CR" => crate::AccessMask::CONTROL_ACCESS,

    "CA" => crate::constants::ADS_RIGHT_DS_CONTROL_ACCESS,
    "LO" => crate::constants::ADS_RIGHT_DS_LIST_OBJECT,
    "DT" => crate::constants::ADS_RIGHT_DS_DELETE_TREE,
    "WP" => crate::constants::ADS_RIGHT_DS_WRITE_PROP,
    "RP" => crate::constants::ADS_RIGHT_DS_READ_PROP,
    "SW" => crate::constants::ADS_RIGHT_DS_SELF,
    "LC" => crate::constants::ADS_RIGHT_ACTRL_DS_LIST,
    "DC" => crate::constants::ADS_RIGHT_DS_DELETE_CHILD,
    "CC" => crate::constants::ADS_RIGHT_DS_CREATE_CHILD,
    "NW" => crate::constants::SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
    "NR" => crate::constants::SYSTEM_MANDATORY_LABEL_NO_READ_UP,
    "NX" => crate::constants::SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP,
    "FA" => *crate::constants::FILE_ALL,
    "FR" => *crate::constants::FILE_READ,
    "FW" => *crate::constants::FILE_WRITE,
    "FX" => *crate::constants::FILE_EXECUTE,
    "KA" => *crate::constants::KEY_ALL,
    "KR" => *crate::constants::KEY_READ,
    "KW" => *crate::constants::KEY_WRITE,
    "KX" => *crate::constants::KEY_EXECUTE,
}