)
from samba.idmap import IDmapDB
from samba.ms_display_specifiers import read_ms_ldif
-from samba.ntacls import setntacl, getntacl, dsacl2fsacl, fsacl_child_sd
+from samba.ntacls import setntacl, getntacl, dsacl2fsacl
from samba.ndr import ndr_pack, ndr_unpack
from samba.provision.backend import (
ExistingBackend,
DEFAULTSITE = "Default-First-Site-Name"
LAST_PROVISION_USN_ATTRIBUTE = "lastProvisionUSN"
-SYSVOL_FOLDER_SD = "O:BAG:SYD:PAI(A;;0x001200a9;;;AU)(A;OICIIO;GRGX;;;AU)(A;;0x001200a9;;;SO)(A;OICIIO;GRGX;;;SO)(A;;0x001e01bf;;;BA)(A;OICIIO;WOWDGRGWGX;;;BA)(A;;0x001f01ff;;;SY)(A;OICIIO;GA;;;SY)(A;;0x001e01bf;;;BA)(A;OICIIO;WOWDGRGWGX;;;CO)S:AI(AU;OICISA;SD;;;WD)"
-SYSVOL_SUBFOLDER_SD = "O:BAG:SYD:PAI(A;;0x001200a9;;;AU)(A;OICIIO;GRGX;;;AU)(A;;0x001200a9;;;SO)(A;OICIIO;GRGX;;;SO)(A;;0x001e01bf;;;BA)(A;OICIIO;GA;;;BA)(A;;0x001f01ff;;;SY)(A;OICIIO;GA;;;SY)(A;;0x001e01bf;;;BA)(A;OICIIO;GA;;;CO)S:AI(AU;SA;SD;;;WD)"
-SYSVOL_SUBFILE_SD = "O:BAG:SYD:AI(A;ID;0x001200a9;;;AU)(A;ID;0x001200a9;;;SO)(A;ID;0x001f01ff;;;BA)(A;ID;0x001f01ff;;;SY)"
-POLICIES_FOLDER_SD = "O:BAG:SYD:PAI(A;;0x001200a9;;;AU)(A;OICIIO;GRGX;;;AU)(A;;0x001200a9;;;SO)(A;OICIIO;GRGX;;;SO)(A;;0x001e01bf;;;BA)(A;OICIIO;GA;;;BA)(A;;0x001f01ff;;;SY)(A;OICIIO;GA;;;SY)(A;;0x001e01bf;;;BA)(A;OICIIO;GA;;;CO)(A;;0x001201bf;;;PA)(A;OICIIO;GRGWGX;;;PA)S:AI(AU;SA;SD;;;WD)"
class ProvisionPaths(object):
FILL_SUBDOMAIN = "SUBDOMAIN"
FILL_NT4SYNC = "NT4SYNC"
FILL_DRS = "DRS"
+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, 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)
+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)
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
- setntacl(lp, os.path.join(root, name), subfile_sd, domsid,
- use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb,
- service=service)
+ setntacl(lp, os.path.join(root, name), acl, domsid,
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
for name in dirs:
- setntacl(lp, os.path.join(root, name), subfolder_sd, domsid,
- use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb,
- service=service)
+ setntacl(lp, os.path.join(root, name), acl, domsid,
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb, service=service)
def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb):
# Set ACL for GPO root folder
root_policy_path = os.path.join(sysvol, dnsdomain, "Policies")
- setntacl(lp, root_policy_path, POLICIES_FOLDER_SD, str(domainsid),
- use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=passdb,
- service=SYSVOL_SERVICE)
+ setntacl(lp, root_policy_path, POLICIES_ACL, 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),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
- 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,
+ acl = ndr_unpack(security.descriptor,
+ str(policy["nTSecurityDescriptor"])).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)
+
def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
domaindn, lp, use_ntvfs):
"""Set the ACL for the sysvol share and the subfolders
else:
canchown = True
- setntacl(lp,sysvol, SYSVOL_FOLDER_SD, str(domainsid), use_ntvfs=use_ntvfs,
+ # Set the SYSVOL_ACL on the sysvol folder and subfolder (first level)
+ setntacl(lp,sysvol, SYSVOL_ACL, str(domainsid), use_ntvfs=use_ntvfs,
skip_invalid_chown=True, passdb=s4_passdb,
service=SYSVOL_SERVICE)
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(lp, os.path.join(root, name), SYSVOL_SUBFILE_SD, str(domainsid),
- use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb,
- service=SYSVOL_SERVICE)
-
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+ passdb=s4_passdb, service=SYSVOL_SERVICE)
for name in dirs:
if use_ntvfs and canchown:
os.chown(os.path.join(root, name), -1, gid)
- setntacl(lp, os.path.join(root, name), SYSVOL_SUBFOLDER_SD, str(domainsid),
- use_ntvfs=use_ntvfs, skip_invalid_chown=True, passdb=s4_passdb,
- service=SYSVOL_SERVICE)
+ setntacl(lp, os.path.join(root, name), SYSVOL_ACL, str(domainsid),
+ use_ntvfs=use_ntvfs, skip_invalid_chown=True,
+ passdb=s4_passdb, service=SYSVOL_SERVICE)
# Set acls on Policy folder and policies folders
set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, passdb=s4_passdb)
else:
return "VFS"
-def check_dir_acl(path, self_sddl, subfolder_sddl, subfile_sddl, domsid, lp, direct_db_access):
+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 != 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))
+ 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))
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
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 != 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))
+ 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))
for name in dirs:
fsacl = getntacl(lp, os.path.join(root, name),
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 != 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))
+ 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))
+
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_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))
+ 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))
res = samdb.search(base="CN=Policies,CN=System,%s"%(domaindn),
attrs=["cn", "nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res:
- 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)
+ 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,
+ domainsid, 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_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))
+ 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))
# Check acls on Policy folder and policies folders
check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp,
const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
uint32_t object_count,
const struct drsuapi_DsReplicaObjectListItemEx *first_object,
- uint32_t linked_attributes_count,
- const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes,
const DATA_BLOB *gensec_skey)
{
static uint32_t object_id;
mapping_ctr,
object_count,
first_object,
- linked_attributes_count,
- linked_attributes,
+ 0, NULL,
NULL, NULL,
gensec_skey,
0,
struct ldb_request *search_req;
struct ldb_result *res;
struct ldb_message *new_msg, *drs_msg, *ldap_msg;
- const char **attrs = talloc_array(objs, const char *, objs->objects[i].msg->num_elements+1+1);
+ const char **attrs = talloc_array(objs, const char *, objs->objects[i].msg->num_elements+1);
for (j=0; j < objs->objects[i].msg->num_elements; j++) {
attrs[j] = objs->objects[i].msg->elements[j].name;
}
- attrs[j] = "uSNChanged";
- j++;
attrs[j] = NULL;
res = talloc_zero(objs, struct ldb_result);
if (!res) {
return false;
}
- ret = ldb_request_add_control(search_req, LDB_CONTROL_SHOW_RECYCLED_OID, false, NULL);
- if (ret != LDB_SUCCESS) {
- return false;
- }
-
ret = ldb_request_add_control(search_req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_dn_ctrl);
if (ret != LDB_SUCCESS) {
return false;
ldb_errstring(ldb)));
torture_assert_int_equal(tctx, res->count, 1, "Could not re-fetch object just delivered over DRS");
ldap_msg = res->msgs[0];
-
-{
-uint64_t usn = ldb_msg_find_attr_as_int64(ldap_msg, "uSNChanged", 0);
-struct GUID g;
-GUID_from_ndr_blob(&objs->objects[i].guid_value, &g);
-torture_comment(tctx, "o[%d] usn_changed[%llu]: %s - %s\n", i, (unsigned long long)usn,
- GUID_string(objs, &g),
- ldb_dn_get_linearized(objs->objects[i].msg->dn));
-continue;
-}
for (j=0; j < ldap_msg->num_elements; j++) {
ldap_msg->elements[j].flags = LDB_FLAG_MOD_ADD;
/* For unknown reasons, there is no nTSecurityDescriptor on cn=deleted objects over LDAP, but there is over DRS! Skip it on both transports for now here so */
talloc_free(search_req);
}
- for (i=0; i < objs->linked_attributes_count; i++) {
-torture_comment(tctx, "l[%d] usn_changed[%llu]: attid[%u] %s\n", i,
- (unsigned long long)objs->linked_attributes[i].meta_data.originating_usn,
- objs->linked_attributes[i].attid,
- GUID_string(objs, &objs->linked_attributes[i].identifier->guid));
- }
if (!lpcfg_parm_bool(tctx->lp_ctx, NULL, "dssync", "print_pwd_blobs", false)) {
talloc_free(objs);
return true;
}
};
- struct drsuapi_DsReplicaCursorCtrEx utdv;
- struct drsuapi_DsReplicaCursor cursors[1];
-
- ZERO_STRUCT(utdv);
- utdv.version = 1;
- utdv.count = ARRAY_SIZE(cursors);
- utdv.cursors = cursors;
- ZERO_STRUCT(cursors);
- GUID_from_string("0d36ca05-5507-4e62-aca3-354bab0d39e1",
- &cursors[0].source_dsa_invocation_id);
- cursors[0].highest_usn = 12755;
-/*
- uptodateness_vector : *
- uptodateness_vector: struct drsuapi_DsReplicaCursorCtrEx
- version : 0x00000001 (1)
- reserved1 : 0x00000000 (0)
- count : 0x00000001 (1)
- reserved2 : 0x00000000 (0)
- cursors: ARRAY(1)
- cursors: struct drsuapi_DsReplicaCursor
- source_dsa_invocation_id : 0d36ca05-5507-4e62-aca3-354bab0d39e1
- highest_usn : 0x00000000000031d3 (12755)
-*/
ZERO_STRUCT(null_guid);
ZERO_STRUCT(null_sid);
r.in.req->req8.highwatermark.tmp_highest_usn = highest_usn;
r.in.req->req8.highwatermark.reserved_usn = 0;
r.in.req->req8.highwatermark.highest_usn = highest_usn;
- r.in.req->req8.uptodateness_vector = NULL;//&utdv;
+ r.in.req->req8.uptodateness_vector = NULL;
r.in.req->req8.replica_flags = 0;
if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "dssync", "compression", false)) {
r.in.req->req8.replica_flags |= DRSUAPI_DRS_USE_COMPRESSION;
| DRSUAPI_DRS_GET_ANC
| DRSUAPI_DRS_NEVER_SYNCED
;
- r.in.req->req8.replica_flags = 0x00201074;
- //r.in.req->req8.replica_flags |= DRSUAPI_DRS_GET_ANC;
r.in.req->req8.max_object_count = 402;
r.in.req->req8.max_ndr_size = 402116;
(unsigned long long) ctr1->new_highwatermark.highest_usn);
if (!test_analyse_objects(tctx, ctx, nc_dn_str, &ctr1->mapping_ctr, ctr1->object_count,
- ctr1->first_object, 0, NULL, &gensec_skey)) {
+ ctr1->first_object, &gensec_skey)) {
return false;
}
(unsigned long long) ctr6->new_highwatermark.highest_usn);
if (!test_analyse_objects(tctx, ctx, nc_dn_str, &ctr6->mapping_ctr, ctr6->object_count,
- ctr6->first_object,
- ctr6->linked_attributes_count,
- ctr6->linked_attributes,
- &gensec_skey)) {
+ ctr6->first_object, &gensec_skey)) {
return false;
}