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

Collapse All | Expand All

(-)file_not_specified_in_diff (-9 / +189 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 str(sd.dacl.aces[i].trustee) == security.SID_CREATOR_OWNER:
1800
            ## filter out ACE for CO, there is some ordering issue
1801
            continue
1802
        if sd.dacl.aces[i].flags & security.SEC_ACE_FLAG_CONTAINER_INHERIT:
1803
            ## If GPO says CI then the subobjects must show the inherited flag
1804
            ## Note: dsacl2fsacl currently always fakes security.SEC_ACE_FLAG_CONTAINER_INHERIT
1805
            sd.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1806
1807
        sd_masked.dacl_add(sd.dacl.aces[i])
1808
    acl_expected_for_subdir = sd_masked.as_sddl(domainsid) 
1809
1810
    ## Additionally for files MS AD and GPMC don't set the CI and OI flags
1811
    for i in range(0, len(sd_masked.dacl.aces)):
1812
        sd_masked.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1813
    acl_expected_for_file = sd_masked.as_sddl(domainsid) 
1814
1815
    #print "ACL GPO:    %s" % acl_expected_for_gpo
1816
    #print "ACL DIR:    %s" % acl_expected_for_subdir
1817
    #print "ACL FILE:   %s" % acl_expected_for_file
1818
1819
    for root, dirs, files in os.walk(path, topdown=False):
1820
        for name in files:
1821
            fsacl = getntacl(lp, os.path.join(root, name),
1822
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1823
            if fsacl is None:
1824
                raise ProvisioningError('%s ACL on GPO file %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1825
1826
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1827
            if fsacl.owner_sid == LA:
1828
                fsacl.owner_sid = DA
1829
1830
            ## Mask current differences between Samba and MS AD & GPMC
1831
            fsacl_masked = security.descriptor()
1832
            fsacl_masked.owner_sid = fsacl.owner_sid
1833
            fsacl_masked.group_sid = fsacl.group_sid
1834
            fsacl_masked.type = fsacl.type
1835
            fsacl_masked.revision = fsacl.revision
1836
1837
            if fix_P_to_AI:
1838
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1839
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1840
1841
            skip_other_da_aces = False
1842
            for i in range(0, len(fsacl.dacl.aces)):
1843
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1844
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1845
                    continue
1846
                elif fsacl.dacl.aces[i].trustee == DA:
1847
                    ## flag first occurrence of DA
1848
                    skip_other_da_aces = True
1849
                if str(fsacl.dacl.aces[i].trustee) == security.SID_CREATOR_OWNER:
1850
                    ## filter out ACE for CO, there is some ordering issue
1851
                    continue
1852
                if fix_P_to_AI:
1853
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1854
                    ## The OI and CI flags don't make sense for files and are neither set by MS AD nor MS GPMC
1855
                    fsacl.dacl.aces[i].flags &= ~ (security.SEC_ACE_FLAG_OBJECT_INHERIT | security.SEC_ACE_FLAG_CONTAINER_INHERIT)
1856
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1857
1858
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid) 
1859
1860
            if fsacl_sddl_mapped != acl_expected_for_file:
1861
                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))
1862
1863
        for name in dirs:
1864
            fsacl = getntacl(lp, os.path.join(root, name),
1865
                             direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
1866
            if fsacl is None:
1867
                raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name)))
1868
1869
            ## If LA in filesystem then treat it as DA for comparison (reversing what samba.ntacls.setntacl did)
1870
            if fsacl.owner_sid == LA:
1871
                fsacl.owner_sid = DA
1872
1873
            ## Mask current differences between Samba and MS AD & GPMC
1874
            fsacl_masked = security.descriptor()
1875
            fsacl_masked.owner_sid = fsacl.owner_sid
1876
            fsacl_masked.group_sid = fsacl.group_sid
1877
            fsacl_masked.type = fsacl.type
1878
            fsacl_masked.revision = fsacl.revision
1879
1880
            if fix_P_to_AI:
1881
                fsacl_masked.type &= ~security.SEC_DESC_DACL_PROTECTED
1882
                fsacl_masked.type |= security.SEC_DESC_DACL_AUTO_INHERITED
1883
1884
            skip_other_da_aces = False
1885
            for i in range(0, len(fsacl.dacl.aces)):
1886
                if skip_other_da_aces and fsacl.dacl.aces[i].trustee in (DA, LA):
1887
                    ## filter out additional ACEs for DA and LA, there is some duplication and ordering issue
1888
                    continue
1889
                elif fsacl.dacl.aces[i].trustee == DA:
1890
                    ## flag first occurrence of DA
1891
                    skip_other_da_aces = True
1892
                if str(fsacl.dacl.aces[i].trustee) == security.SID_CREATOR_OWNER:
1893
                    ## filter out ACE for CO, there is some ordering issue
1894
                    continue
1895
                if fix_P_to_AI:
1896
                    fsacl.dacl.aces[i].flags |= security.SEC_ACE_FLAG_INHERITED_ACE
1897
                fsacl_masked.dacl_add(fsacl.dacl.aces[i])
1898
1899
            fsacl_sddl_mapped = fsacl_masked.as_sddl(domainsid) 
1900
1901
            if fsacl_sddl_mapped != acl_expected_for_subdir:
1902
                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))
1903
1904
1731
def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1905
def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
1732
                   direct_db_access):
1906
                   direct_db_access, mask_msad_differences=False):
1733
    """Set ACL on the sysvol/<dnsname>/Policies folder and the policy
1907
    """Set ACL on the sysvol/<dnsname>/Policies folder and the policy
1734
    folders beneath.
1908
    folders beneath.
1735
1909
 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