View | Details | Raw Unified | Return to bug 49293 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/lib/python2.7/dist-packages/samba/provision/__init__.py (-1 / +178 lines)
 Lines 1672-1678    Link Here 
1672
        return True
1672
        return True
1673
    return False
1673
    return False
1674
1674
1675
def check_dir_acl(path, acl, lp, domainsid, direct_db_access):
1675
def check_dir_acl(path, acl_expected_for_gpo, lp, domainsid, direct_db_access):
1676
    try:
1677
        fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1678
        fsacl_sddl = fsacl.as_sddl(domainsid)
1679
    except TypeError as error:
1680
        return
1681
    except NTSTATUSError as error:
1682
        if check_runtime_error(error, ntstatus.NT_STATUS_OBJECT_NAME_NOT_FOUND):
1683
            print "ERROR: File not found", path
1684
            return
1685
        else:
1686
            raise
1687
1688
    ## Sanitize "domainsid" to be a security.dom_sid
1689
    if isinstance(domainsid, str):
1690
        domainsid = security.dom_sid(domainsid)
1691
1692
    LA = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINISTRATOR))
1693
    DA = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINS))
1694
    CO = security.dom_sid(security.SID_CREATOR_OWNER)
1695
1696
    ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1697
    if fsacl.owner_sid == LA:
1698
        fsacl.owner_sid = DA
1699
1700
    """
1701
        MS doc about SE_DACL_AUTO_INHERITED of SECURITY_DESCRIPTOR_CONTROL:
1702
        For Windows 2000 ACLs that support auto-inheritance, this bit is always set.
1703
    """
1704
    ## The default {31B2F340-016D-11D2-945F-00C04FB984F9} and {6AC1786C-016F-11D2-945F-00C04FB984F9} don't have this in Samba
1705
    ## so mask this difference here to avoid false positives
1706
    ##
1707
    ## sysvolreset removes the AI as well, so we always mask this:
1708
    fsacl.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1709
    fix_P_to_AI = True  ## also below in the subdir and file checks
1710
1711
    fsacl_sddl_mapped = fsacl.as_sddl(domainsid)
1712
1713
    ## at least in UCS, all base GPO directories have AI set, so expect that
1714
    sd = security.descriptor.from_sddl(acl_expected_for_gpo, domainsid)
1715
    sd.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1716
    acl_expected_for_gpo = sd.as_sddl(domainsid)
1717
1718
    if fsacl_sddl_mapped != acl_expected_for_gpo:
1719
        raise ProvisioningError('%s NTACL of GPO directory %s does not match value expected from GPO object\nFSACL: %s\nDSACL: %s' % (acl_type(direct_db_access), path, fsacl_sddl_mapped, acl_expected_for_gpo))
1720
1721
    ### After the base GPO directory has passed, now fix the FSACLs calculated by dsacl2fsacl to work for the subdirs and files
1722
    ## copy the security descriptor structure, we have to filter out a few ACEs
1723
    sd_masked = security.descriptor()
1724
    sd_masked.owner_sid = sd.owner_sid
1725
    sd_masked.group_sid = sd.group_sid
1726
    sd_masked.type = sd.type
1727
    sd_masked.revision = sd.revision
1728
1729
    ## the subdirs and files are AI and not P
1730
    sd_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1731
    sd_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1732
1733
    skip_other_da_aces = False
1734
    for i in range(0, len(sd.dacl.aces)):
1735
        if skip_other_da_aces and sd.dacl.aces[i].trustee in (DA, LA):
1736
           ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1737
            continue
1738
        elif sd.dacl.aces[i].trustee in (DA, LA):
1739
            ## flag first occurrence of DA
1740
            skip_other_da_aces = True
1741
        if sd.dacl.aces[i].flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT:
1742
            ## If GPO says CI then the subobjects must show the inherited flag
1743
            ## Note: dsacl2fsacl currently always fakes security.SEC_ACE_FLAG_CONTAINER_INHERIT
1744
            sd.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1745
1746
        sd_masked.dacl_add(sd.dacl.aces[i])
1747
    acl_expected_for_subdir = sd_masked.as_sddl(domainsid)
1748
1749
    ## Additionally for files MS AD and GPMC don't set the CI and OI flags
1750
    for i in range(0, len(sd_masked.dacl.aces)):
1751
        sd_masked.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1752
    try:
1753
        ## also filter out ACE for CO, not present for GPT.INI of new GPOs created via GPMC
1754
        sd_masked.dacl_del(CO)
1755
    except:
1756
        pass
1757
    acl_expected_for_file = sd_masked.as_sddl(domainsid)
1758
    sd_masked.type &= ~security.SEC_DESC_DACL_AUTO_INHERIT_REQ
1759
    acl_expected_for_registry_pol = sd_masked.as_sddl(domainsid)
1760
1761
    #print "ACL GPO:    %s" % acl_expected_for_gpo
1762
    #print "ACL DIR:    %s" % acl_expected_for_subdir
1763
    #print "ACL FILE:   %s" % acl_expected_for_file
1764
1765
    for root, dirs, files in os.walk(path, topdown=False):
1766
        for name in files:
1767
            fsacl = getntacl(lp, os.path.join(root, name),
1768
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1769
            if fsacl is None:
1770
                raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1771
1772
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1773
            if fsacl.owner_sid == LA:
1774
                fsacl.owner_sid = DA
1775
1776
            ## Mask current differences between Samba and MS AD & GPMC
1777
            fsacl_masked = security.descriptor()
1778
            fsacl_masked.owner_sid = fsacl.owner_sid
1779
            fsacl_masked.group_sid = fsacl.group_sid
1780
            fsacl_masked.type = fsacl.type
1781
            fsacl_masked.revision = fsacl.revision
1782
1783
            if fix_P_to_AI:
1784
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1785
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1786
1787
            skip_other_da_aces = False
1788
            for i in range(0, len(fsacl.dacl.aces)):
1789
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1790
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1791
                    continue
1792
                elif fsacl.dacl.aces[i].trustee in (DA, LA):
1793
                    ## flag first occurrence of DA
1794
                    skip_other_da_aces = True
1795
                if str(fsacl.dacl.aces[i].trustee) == security.SID_CREATOR_OWNER:
1796
                    ## filter out ACE for CO, not present for GPT.INI of new GPOs created via GPMC
1797
                    continue
1798
                if fix_P_to_AI:
1799
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1800
                    ## The OI and CI flags don't make sense for files and are neither set by MS AD nor MS GPMC
1801
                    fsacl.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1802
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1803
1804
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid)
1805
1806
            if name in ("GPT.INI", "GptTmpl.inf", "comment.cmtx"):
1807
                if fsacl_sddl_mapped != acl_expected_for_file:
1808
                    raise ProvisioningError('%s NTACL of GPO file %s does not match value expected from GPO object\nFSACL: %s\nDSACL: %s' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl_mapped, acl_expected_for_file))
1809
            else:
1810
                if fsacl_sddl_mapped != acl_expected_for_registry_pol:
1811
                    raise ProvisioningError('%s NTACL of GPO file %s does not match value expected from GPO object\nFSACL: %s\nDSACL: %s' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl_mapped, acl_expected_for_registry_pol))
1812
1813
        for name in dirs:
1814
            fsacl = getntacl(lp, os.path.join(root, name),
1815
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1816
            if fsacl is None:
1817
                raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1818
1819
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1820
            if fsacl.owner_sid == LA:
1821
                fsacl.owner_sid = DA
1822
1823
            ## Mask current differences between Samba and MS AD & GPMC
1824
            fsacl_masked = security.descriptor()
1825
            fsacl_masked.owner_sid = fsacl.owner_sid
1826
            fsacl_masked.group_sid = fsacl.group_sid
1827
            fsacl_masked.type = fsacl.type
1828
            fsacl_masked.revision = fsacl.revision
1829
1830
            if fix_P_to_AI:
1831
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1832
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1833
1834
            skip_other_da_aces = False
1835
            for i in range(0, len(fsacl.dacl.aces)):
1836
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1837
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1838
                    continue
1839
                elif fsacl.dacl.aces[i].trustee == DA:
1840
                    ## flag first occurrence of DA
1841
                    skip_other_da_aces = True
1842
                if fix_P_to_AI:
1843
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1844
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1845
1846
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid)
1847
1848
            if fsacl_sddl_mapped != acl_expected_for_subdir:
1849
                raise ProvisioningError('%s NTACL of GPO subdirectory %s does not match value expected from GPO object\nFSACL: %s\nDSACL: %s' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl_mapped, acl_expected_for_subdir))
1850
1851
1852
def check_dir_acl_orig(path, acl, lp, domainsid, direct_db_access):
1676
    try:
1853
    try:
1677
        fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1854
        fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1678
        fsacl_sddl = fsacl.as_sddl(domainsid) 
1855
        fsacl_sddl = fsacl.as_sddl(domainsid) 

Return to bug 49293