)
from samba.idmap import IDmapDB
from samba.ms_display_specifiers import read_ms_ldif
-from samba.ntacls import setntacl, getntacl, dsacl2fsacl
+from samba.ntacls import setntacl, getntacl, dsacl2fsacl, fsacl_child_sd
from samba.ndr import ndr_pack, ndr_unpack
from samba.provision.backend import (
FDSBackend,
return samdb
-SYSVOL_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)"
-POLICIES_ACL = "O:LAG:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;SO)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001301bf;;;PA)"
SYSVOL_SERVICE = "sysvol"
-def set_dir_acl(path, acl, lp, domsid, use_ntvfs, passdb, service=SYSVOL_SERVICE):
- setntacl(lp, path, acl, domsid, use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
+def set_dir_acl(path, self_sd, subfolder_sd, subfile_sd, domsid, lp, use_ntvfs,
+ passdb, service=SYSVOL_SERVICE):
+ setntacl(lp, path, self_sd, domsid, use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+ passdb=passdb, service=service)
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
- setntacl(lp, os.path.join(root, name), acl, domsid,
+ setntacl(lp, os.path.join(root, name), subfile_sd, domsid,
use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
for name in dirs:
- setntacl(lp, os.path.join(root, name), acl, domsid,
+ setntacl(lp, os.path.join(root, name), subfolder_sd, domsid,
use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
# Set ACL for GPO root folder
root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
- setntacl(lp, root_policy_path, POLICIES_ACL, str(domainsid),
+ setntacl(lp, root_policy_path, POLICIES_FOLDER_SD, str(domainsid),
use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=SYSVOL_SERVICE)
res = samdb.search(base="CN=Policies,CN=System,%s" %(domaindn),
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
- acl = ndr_unpack(security.descriptor,
- policy["nTSecurityDescriptor"][0]).as_sddl()
- policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
- set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
- str(domainsid), use_ntvfs,
- passdb=passdb)
+ guid = str(policy["cn"])
+ policy_path = getpolicypath(sysvol, dnsdomain, guid)
+ if DEFAULT_POLICY_GUID in guid or DEFAULT_DC_POLICY_GUID in guid:
+ self_sd = SYSVOL_SUBFOLDER_SD
+ sub_folder_sd = SYSVOL_SUBFOLDER_SD
+ sub_file_sd = SYSVOL_SUBFILE_SD
+ else:
+ acl = ndr_unpack(security.descriptor,
+ str(policy["nTSecurityDescriptor"])).as_sddl()
+ owner_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)
+ group_sid = security.dom_sid("%s-%d" % (str(domainsid), security.DOMAIN_RID_USERS))
+ self_sd = dsacl2fsacl(acl, domainsid)
+ sub_folder_sd = fsacl_child_sd(self_sd, domainsid, owner_sid, group_sid, container=True)
+ sub_file_sd = fsacl_child_sd(self_sd, domainsid, owner_sid, group_sid, container=False)
+
+ set_dir_acl(policy_path, self_sd,
+ sub_folder_sd, sub_file_sd,
+ str(domainsid), lp, use_ntvfs,
+ passdb=passdb)
def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
domaindn, lp, use_ntvfs):
session_info = auth.user_session(samdb, lp_ctx=lp, dn=userdn,
session_info_flags=flags)
- def _setntacl(path):
+ def _setntacl(path, acl):
"""A helper to reuse args"""
return setntacl(
- lp, path, SYSVOL_ACL, str(domainsid),
+ lp, path, acl, str(domainsid),
use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb,
service=SYSVOL_SERVICE, session_info=session_info)
- # Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
- _setntacl(sysvol)
+ # Set the SYSVOL_FOLDER_SD on the sysvol folder and
+ # SYSVOL_SUBFILE_SD on files and SYSVOL_SUBFOLDER_SD on the subfolder (first level)
+ _setntacl(sysvol, SYSVOL_FOLDER_SD)
for root, dirs, files in os.walk(sysvol, topdown=False):
for name in files:
if use_ntvfs and canchown:
os.chown(os.path.join(root, name), -1, gid)
- _setntacl(os.path.join(root, name))
+ _setntacl(os.path.join(root, name), SYSVOL_SUBFILE_SD)
for name in dirs:
if use_ntvfs and canchown:
os.chown(os.path.join(root, name), -1, gid)
- _setntacl(os.path.join(root, name))
+ _setntacl(os.path.join(root, name), SYSVOL_SUBFOLDER_SD)
# Set acls on Policy folder and policies folders
set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb=s4_passdb)
return "VFS"
-def check_dir_acl(path, acl, lp, domainsid, direct_db_access):
+def check_dir_acl(path, self_sddl, subfolder_sddl, subfile_sddl, domsid, lp, 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))
+ if fsacl_sddl != self_sddl:
+ 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, self_sddl))
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
(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 fsacl_sddl != subfile_sddl:
+ 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, subfile_sddl))
for name in dirs:
fsacl = getntacl(lp, os.path.join(root, name),
% (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 fsacl_sddl != subfolder_sddl:
+ 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, subfolder_sddl))
def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
direct_db_access):
if fsacl is None:
raise ProvisioningError('DB ACL on policy root %s %s not found!' % (acl_type(direct_db_access), root_policy_path))
fsacl_sddl = fsacl.as_sddl(domainsid)
- if fsacl_sddl != POLICIES_ACL:
- raise ProvisioningError('%s ACL on policy root %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), root_policy_path, fsacl_sddl, fsacl))
+ if fsacl_sddl != POLICIES_FOLDER_SD:
+ raise ProvisioningError('%s ACL on policy root %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), root_policy_path, fsacl_sddl, POLICIES_FOLDER_SD))
res = samdb.search(base="CN=Policies,CN=System,%s" %(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
- acl = ndr_unpack(security.descriptor,
- policy["nTSecurityDescriptor"][0]).as_sddl()
- policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"]))
- check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp,
- domainsid, direct_db_access)
+ guid = str(policy["cn"])
+ policy_path = getpolicypath(sysvol, dnsdomain, guid)
+
+ if DEFAULT_POLICY_GUID in guid or DEFAULT_DC_POLICY_GUID in guid:
+ self_sd = SYSVOL_SUBFOLDER_SD
+ sub_folder_sd = SYSVOL_SUBFOLDER_SD
+ sub_file_sd = SYSVOL_SUBFILE_SD
+ else:
+ acl = ndr_unpack(security.descriptor,
+ str(policy["nTSecurityDescriptor"])).as_sddl()
+ owner_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS)
+ group_sid = security.dom_sid("%s-%d" % (str(domainsid), security.DOMAIN_RID_USERS))
+ self_sd = dsacl2fsacl(acl, domainsid)
+ sub_folder_sd = fsacl_child_sd(self_sd, domainsid, owner_sid, group_sid, container=True)
+ sub_file_sd = fsacl_child_sd(self_sd, domainsid, owner_sid, group_sid, container=False)
+
+ check_dir_acl(policy_path, self_sd,
+ sub_folder_sd, subfile_sd,
+ domainsid, lp, direct_db_access)
def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn,
:param samdb: An LDB object on the SAM db
:param netlogon: Physical path for the netlogon folder
:param sysvol: Physical path for the sysvol folder
- :param uid: The UID of the "Administrator" user
- :param gid: The GID of the "Domain adminstrators" group
:param domainsid: The SID of the domain
:param dnsdomain: The DNS name of the domain
:param domaindn: The DN of the domain (ie. DC=...)
# Ensure we can read this directly, and via the smbd VFS
for direct_db_access in [True, False]:
- # Check the SYSVOL_ACL on the sysvol folder and subfolder (first level)
for dir_path in [os.path.join(sysvol, dnsdomain), netlogon]:
fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access, service=SYSVOL_SERVICE)
if fsacl is None:
raise ProvisioningError('%s ACL on sysvol directory %s not found!' % (acl_type(direct_db_access), dir_path))
fsacl_sddl = fsacl.as_sddl(domainsid)
- if fsacl_sddl != SYSVOL_ACL:
- raise ProvisioningError('%s ACL on sysvol directory %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), dir_path, fsacl_sddl, SYSVOL_ACL))
+ if fsacl_sddl != SYSVOL_SUBFOLDER_ACL:
+ raise ProvisioningError('%s ACL on sysvol directory %s %s does not match expected value %s from provision' % (acl_type(direct_db_access), dir_path, fsacl_sddl, SYSVOL_SUBFOLDER_ACL))
# Check acls on Policy folder and policies folders
check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,