--- __init__.py.basic 2019-01-23 16:48:07.324848486 +0100 +++ __init__.py.basic 2019-01-23 16:53:23.676809834 +0100 @@ -1662,8 +1662,28 @@ def check_dir_acl(path, acl, lp, domainsid, direct_db_access): fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE) fsacl_sddl = fsacl.as_sddl(domainsid) - if fsacl_sddl != acl: - raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), path, fsacl_sddl, acl)) + + ## Sanitize "domainsid" to be a security.dom_sid + if isinstance(domainsid, str): + domainsid = security.dom_sid(domainsid) + sd = security.descriptor.from_sddl(acl, domainsid) + ## Mask AI and P in DACL flags for comparison + sd.type &= ~ (security.SEC_DESC_DACL_AUTO_INHERITED | security.SEC_DESC_DACL_PROTECTED) + acl_sddl_masked = sd.as_sddl(domainsid) + + ## Mask AI and P in DACL flags for comparison + fsacl_inheritance_flags = fsacl.type & (security.SEC_DESC_DACL_AUTO_INHERITED | security.SEC_DESC_DACL_PROTECTED) + ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did) + if fsacl.owner_sid == security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINISTRATOR)): + fsacl.owner_sid = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINS)) + + ## Mask AI and P in DACL flags for comparison + fsacl.type &= ~ (security.SEC_DESC_DACL_AUTO_INHERITED | security.SEC_DESC_DACL_PROTECTED) + fsacl_sddl_mapped_and_masked = fsacl.as_sddl(domainsid) + + + if fsacl_sddl_mapped_and_masked != acl_sddl_masked: + raise ProvisioningError('%s NTACL of GPO directory %s %s does not match value %s expected from GPO object' % (acl_type(direct_db_access), path, fsacl_sddl, acl)) for root, dirs, files in os.walk(path, topdown=False): for name in files: @@ -1672,18 +1692,38 @@ if fsacl is None: raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name))) fsacl_sddl = fsacl.as_sddl(domainsid) - if fsacl_sddl != acl: - raise ProvisioningError('%s ACL on GPO file %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl)) + ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did) + if fsacl.owner_sid == security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINISTRATOR)): + fsacl.owner_sid = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINS)) + + ## Mask AI and P in DACL flags for comparison + fsacl.type &= ~ (security.SEC_DESC_DACL_AUTO_INHERITED | security.SEC_DESC_DACL_PROTECTED) + fsacl_sddl_mapped_and_masked = fsacl.as_sddl(domainsid) + + print "%s" % fsacl_sddl_mapped_and_masked + print "%s" % acl_sddl_masked + + if fsacl_sddl_mapped_and_masked != acl_sddl_masked: + raise ProvisioningError('%s NTACL of GPO file %s %s does not match value %s expected from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl)) + for name in dirs: fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access, service=SYSVOL_SERVICE) if fsacl is None: raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name))) fsacl_sddl = fsacl.as_sddl(domainsid) - if fsacl_sddl != acl: - raise ProvisioningError('%s ACL on GPO directory %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl)) + ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did) + if fsacl.owner_sid == security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINISTRATOR)): + fsacl.owner_sid = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINS)) + + ## Mask AI and P in DACL flags for comparison + fsacl.type &= ~ (security.SEC_DESC_DACL_AUTO_INHERITED | security.SEC_DESC_DACL_PROTECTED) + fsacl_sddl_mapped_and_masked = fsacl.as_sddl(domainsid) + + if fsacl_sddl_mapped_and_masked != acl_sddl_masked: + raise ProvisioningError('%s NTACL of GPO directory %s %s does not match value %s expected from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl)) def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, direct_db_access): @@ -1715,8 +1755,12 @@ acl = ndr_unpack(security.descriptor, str(policy["nTSecurityDescriptor"])).as_sddl() policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) - check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, + try: + check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, domainsid, direct_db_access) + except Exception as e: + print e + continue def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn,