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

Collapse All | Expand All

(-)file_not_specified_in_diff (-9 / +188 lines)
Line     Link Here 
0
-- a/python/samba/netcmd/ntacl.py
0
++ b/python/samba/netcmd/ntacl.py
 Lines 293-299   class cmd_ntacl_sysvolcheck(Command): Link Here 
293
        "versionopts": options.VersionOptions,
293
        "versionopts": options.VersionOptions,
294
    }
294
    }
295
295
296
    def run(self, credopts=None, sambaopts=None, versionopts=None):
296
    takes_options = [
297
        Option("--mask-msad-differences", help="Ignore standard differences to MS AD ACLs", action="store_true"),
298
        ]
299
    def run(self, mask_msad_differences=False, credopts=None, sambaopts=None, versionopts=None):
297
        lp = sambaopts.get_loadparm()
300
        lp = sambaopts.get_loadparm()
298
        creds = credopts.get_credentials(lp)
301
        creds = credopts.get_credentials(lp)
299
        creds.set_kerberos_state(DONT_USE_KERBEROS)
302
        creds.set_kerberos_state(DONT_USE_KERBEROS)
 Lines 311-317   class cmd_ntacl_sysvolcheck(Command): Link Here 
311
        provision.checksysvolacl(samdb, netlogon, sysvol,
359
        provision.checksysvolacl(samdb, netlogon, sysvol,
312
                                 domain_sid,
360
                                 domain_sid,
313
                                 lp.get("realm").lower(), samdb.domain_dn(),
361
                                 lp.get("realm").lower(), samdb.domain_dn(),
314
                                 lp)
362
                                 lp, mask_msad_differences)
315
363
316
364
317
class cmd_ntacl(SuperCommand):
365
class cmd_ntacl(SuperCommand):
318
-- a/python/samba/provision/__init__.py
366
++ b/python/samba/provision/__init__.py
 Lines 1728-1735   def check_dir_acl(path, acl, lp, domains Link Here 
1728
                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_mapped, acl))
1729
                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_mapped, acl))
1729
1730
1730
1731
1732
def check_dir_acl_masked(path, acl_expected_for_gpo, lp, domainsid, direct_db_access):
1733
    try:
1734
        fsacl = getntacl(lp, path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1735
        fsacl_sddl = fsacl.as_sddl(domainsid) 
1736
    except TypeError as error:
1737
        return
1738
    except NTSTATUSError as error:
1739
        if check_runtime_error(error, ntstatus.NT_STATUS_OBJECT_NAME_NOT_FOUND):
1740
            print "ERROR: File not found", path
1741
            return
1742
        else:
1743
            raise
1744
1745
    ## Sanitize "domainsid" to be a security.dom_sid
1746
    if isinstance(domainsid, str):
1747
        domainsid = security.dom_sid(domainsid)
1748
1749
    LA = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINISTRATOR))
1750
    DA = security.dom_sid("%s-%d" % (domainsid, security.DOMAIN_RID_ADMINS))
1751
    CO = security.dom_sid(security.SID_CREATOR_OWNER)
1752
1753
    ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1754
    if fsacl.owner_sid == LA:
1755
        fsacl.owner_sid = DA
1756
1757
    """
1758
        MS doc about SE_DACL_AUTO_INHERITED of SECURITY_DESCRIPTOR_CONTROL:
1759
        For Windows 2000 ACLs that support auto-inheritance, this bit is always set.
1760
    """
1761
    ## The default {31B2F340-016D-11D2-945F-00C04FB984F9} and {6AC1786C-016F-11D2-945F-00C04FB984F9} don't have this in Samba
1762
    ## so mask this difference here to avoid false positives
1763
    if os.path.split(path)[-1] in ("{31B2F340-016D-11D2-945F-00C04FB984F9}", "{6AC1786C-016F-11D2-945F-00C04FB984F9}"):
1764
        fsacl.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1765
        fix_P_to_AI = True  ## also below in the subdir and file checks
1766
    else:
1767
        fix_P_to_AI = False
1768
1769
    fsacl_sddl_mapped = fsacl.as_sddl(domainsid) 
1770
1771
    ## at least in UCS, all base GPO directories have AI set, so expect that
1772
    sd = security.descriptor.from_sddl(acl_expected_for_gpo, domainsid)
1773
    sd.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1774
    acl_expected_for_gpo = sd.as_sddl(domainsid) 
1775
1776
    if fsacl_sddl_mapped != acl_expected_for_gpo:
1777
        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))
1778
1779
    ### After the base GPO directory has passed, now fix the FSACLs calculated by dsacl2fsacl to work for the subdirs and files
1780
    ## copy the security descriptor structure, we have to filter out a few ACEs
1781
    sd_masked = security.descriptor()
1782
    sd_masked.owner_sid = sd.owner_sid
1783
    sd_masked.group_sid = sd.group_sid
1784
    sd_masked.type = sd.type
1785
    sd_masked.revision = sd.revision
1786
1787
    ## the subdirs and files are AI and not P
1788
    sd_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1789
    sd_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1790
1791
    skip_other_da_aces = False
1792
    for i in range(0, len(sd.dacl.aces)):
1793
        if skip_other_da_aces and sd.dacl.aces[i].trustee in (DA, LA):
1794
           ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1795
            continue
1796
        elif sd.dacl.aces[i].trustee == DA:
1797
            ## flag first occurrence of DA
1798
            skip_other_da_aces = True
1799
        if sd.dacl.aces[i].flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT:
1800
            ## If GPO says CI then the subobjects must show the inherited flag
1801
            ## Note: dsacl2fsacl currently always fakes security.SEC_ACE_FLAG_CONTAINER_INHERIT
1802
            sd.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1803
1804
        sd_masked.dacl_add(sd.dacl.aces[i])
1805
    acl_expected_for_subdir = sd_masked.as_sddl(domainsid) 
1806
1807
    ## Additionally for files MS AD and GPMC don't set the CI and OI flags
1808
    for i in range(0, len(sd_masked.dacl.aces)):
1809
        sd_masked.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1810
    try:
1811
        ## also filter out ACE for CO, not present for GPT.INI of new GPOs created via GPMC
1812
        sd_masked.dacl_del(CO)
1813
    except:
1814
        pass
1815
    acl_expected_for_file = sd_masked.as_sddl(domainsid) 
1816
1817
    #print "ACL GPO:    %s" % acl_expected_for_gpo
1818
    #print "ACL DIR:    %s" % acl_expected_for_subdir
1819
    #print "ACL FILE:   %s" % acl_expected_for_file
1820
1821
    for root, dirs, files in os.walk(path, topdown=False):
1822
        for name in files:
1823
            fsacl = getntacl(lp, os.path.join(root, name),
1824
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1825
            if fsacl is None:
1826
                raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1827
1828
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1829
            if fsacl.owner_sid == LA:
1830
                fsacl.owner_sid = DA
1831
1832
            ## Mask current differences between Samba and MS AD & GPMC
1833
            fsacl_masked = security.descriptor()
1834
            fsacl_masked.owner_sid = fsacl.owner_sid
1835
            fsacl_masked.group_sid = fsacl.group_sid
1836
            fsacl_masked.type = fsacl.type
1837
            fsacl_masked.revision = fsacl.revision
1838
1839
            if fix_P_to_AI:
1840
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1841
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1842
1843
            skip_other_da_aces = False
1844
            for i in range(0, len(fsacl.dacl.aces)):
1845
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1846
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1847
                    continue
1848
                elif fsacl.dacl.aces[i].trustee == DA:
1849
                    ## flag first occurrence of DA
1850
                    skip_other_da_aces = True
1851
                if str(fsacl.dacl.aces[i].trustee) == security.SID_CREATOR_OWNER:
1852
                    ## filter out ACE for CO, not present for GPT.INI of new GPOs created via GPMC
1853
                    continue
1854
                if fix_P_to_AI:
1855
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1856
                    ## The OI and CI flags don't make sense for files and are neither set by MS AD nor MS GPMC
1857
                    fsacl.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1858
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1859
1860
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid) 
1861
1862
            if fsacl_sddl_mapped != acl_expected_for_file:
1863
                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))
1864
1865
        for name in dirs:
1866
            fsacl = getntacl(lp, os.path.join(root, name),
1867
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1868
            if fsacl is None:
1869
                raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1870
1871
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1872
            if fsacl.owner_sid == LA:
1873
                fsacl.owner_sid = DA
1874
1875
            ## Mask current differences between Samba and MS AD & GPMC
1876
            fsacl_masked = security.descriptor()
1877
            fsacl_masked.owner_sid = fsacl.owner_sid
1878
            fsacl_masked.group_sid = fsacl.group_sid
1879
            fsacl_masked.type = fsacl.type
1880
            fsacl_masked.revision = fsacl.revision
1881
1882
            if fix_P_to_AI:
1883
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1884
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1885
1886
            skip_other_da_aces = False
1887
            for i in range(0, len(fsacl.dacl.aces)):
1888
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1889
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1890
                    continue
1891
                elif fsacl.dacl.aces[i].trustee == DA:
1892
                    ## flag first occurrence of DA
1893
                    skip_other_da_aces = True
1894
                if fix_P_to_AI:
1895
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1896
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1897
1898
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid) 
1899
1900
            if fsacl_sddl_mapped != acl_expected_for_subdir:
1901
                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))
1902
1903
1731
def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1904
def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1732
                   direct_db_access):
1905
                   direct_db_access, mask_msad_differences=False):
1733
    """Set ACL on the sysvol/<dnsname>/Policies folder and the policy
1906
    """Set ACL on the sysvol/<dnsname>/Policies folder and the policy
1734
    folders beneath.
1907
    folders beneath.
1735
1908
 Lines 1759-1773   def check_gpos_acl(sysvol, dnsdomain, do Link Here 
1759
                         policy["nTSecurityDescriptor"][0]).as_sddl()
1932
                         policy["nTSecurityDescriptor"][0]).as_sddl()
1760
        policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
1933
        policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
1761
        try:
1934
        try:
1762
            check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
1935
            if mask_msad_differences:
1763
                      domainsid, direct_db_access)
1936
                check_dir_acl_masked(policy_path, dsacl2fsacl(acl, domainsid), lp,
1937
                          domainsid, direct_db_access)
1938
            else:
1939
                check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
1940
                          domainsid, direct_db_access)
1764
        except Exception as e:
1941
        except Exception as e:
1765
            print(e)
1942
            print(e)
1766
            continue
1943
            continue
1767
1944
1768
1945
1769
def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn,
1946
def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn,
1770
                   lp):
1947
                   lp, mask_msad_differences=False):
1771
    """Set the ACL for the sysvol share and the subfolders
1948
    """Set the ACL for the sysvol share and the subfolders
1772
1949
1773
    :param samdb: An LDB object on the SAM db
1950
    :param samdb: An LDB object on the SAM db
 Lines 1812-1818   def checksysvolacl(samdb, netlogon, sysv Link Here 
1812
1989
1813
        # Check acls on Policy folder and policies folders
1990
        # Check acls on Policy folder and policies folders
1814
        check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1991
        check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1815
                       direct_db_access)
1992
                       direct_db_access, mask_msad_differences)
1816
1993
1817
1994
1818
def interface_ips_v4(lp):
1995
def interface_ips_v4(lp):

Return to bug 46643