def _getnc_req10(self, dest_dsa, invocation_id, nc_dn_str, exop, replica_flags=0, max_objects=0, partial_attribute_set=None, partial_attribute_set_ex=None, mapping_ctr=None, more_flags=0): req10 = drsuapi.DsGetNCChangesRequest10() req10.destination_dsa_guid = misc.GUID(dest_dsa) if dest_dsa else misc.GUID() req10.source_dsa_invocation_id = misc.GUID(invocation_id) req10.naming_context = drsuapi.DsReplicaObjectIdentifier() req10.naming_context.dn = unicode(nc_dn_str) req10.highwatermark = drsuapi.DsReplicaHighWaterMark() req10.highwatermark.tmp_highest_usn = 0 req10.highwatermark.reserved_usn = 0 req10.highwatermark.highest_usn = 0 req10.uptodateness_vector = None req10.replica_flags = replica_flags req10.max_object_count = max_objects req10.max_ndr_size = 402116 req10.extended_op = exop req10.fsmo_info = 0 req10.partial_attribute_set = partial_attribute_set req10.partial_attribute_set_ex = partial_attribute_set_ex if mapping_ctr: req10.mapping_ctr = mapping_ctr else: req10.mapping_ctr.num_mappings = 0 req10.mapping_ctr.mappings = None req10.more_flags = more_flags return req10
def test_ldif_to_samdb_forced_local_dsa(self): for dsa, site in MULTISITE_LDIF_DSAS: dburl = os.path.join(self.tempdir, "ldif-to-samba-forced-local-dsa" "-%s" % dsa) samdb = ldif_import_export.ldif_to_samdb(dburl, self.lp, MULTISITE_LDIF, forced_local_dsa=dsa) self.assertIsInstance(samdb, SamDB) self.assertEqual(samdb.server_site_name(), site) res = samdb.search(ldb.Dn(samdb, "CN=NTDS Settings," + dsa), scope=ldb.SCOPE_BASE, attrs=["objectGUID"]) ntds_guid = misc.GUID(samdb.get_ntds_GUID()) self.assertEqual(misc.GUID(res[0]["objectGUID"][0]), ntds_guid) service_name_res = samdb.search(base="", scope=ldb.SCOPE_BASE, attrs=["dsServiceName"]) dn = ldb.Dn(samdb, service_name_res[0]["dsServiceName"][0].decode('utf8')) self.assertEqual(dn, ldb.Dn(samdb, "CN=NTDS Settings," + dsa)) self.remove_files(dburl)
def test_do_ridalloc_get_anc(self): """Test doing a RID allocation with a valid destination DSA guid and GET_ANC flag""" fsmo_dn = ldb.Dn(self.ldb_dc1, "CN=RID Manager$,CN=System," + self.ldb_dc1.domain_dn()) (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) req8 = self._exop_req8(dest_dsa=fsmo_not_owner["ntds_guid"], invocation_id=fsmo_owner["invocation_id"], nc_dn_str=fsmo_dn, exop=drsuapi.DRSUAPI_EXOP_FSMO_RID_ALLOC, replica_flags=drsuapi.DRSUAPI_DRS_GET_ANC) (drs, drs_handle) = self._ds_bind(fsmo_owner["dns_name"]) (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) self.assertEqual(level, 6, "Expected level 6 response!") self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_owner["ntds_guid"])) self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_owner["invocation_id"])) ctr6 = ctr self.assertEqual(ctr6.extended_ret, drsuapi.DRSUAPI_EXOP_ERR_SUCCESS) self.assertEqual(ctr6.object_count, 3) self.assertNotEqual(ctr6.first_object, None) self.assertEqual(ldb.Dn(self.ldb_dc1, ctr6.first_object.object.identifier.dn), fsmo_dn) self.assertNotEqual(ctr6.first_object.next_object, None) self.assertNotEqual(ctr6.first_object.next_object.next_object, None) second_object = ctr6.first_object.next_object.object self.assertEqual(ldb.Dn(self.ldb_dc1, second_object.identifier.dn), fsmo_not_owner["rid_set_dn"]) third_object = ctr6.first_object.next_object.next_object.object self.assertEqual(ldb.Dn(self.ldb_dc1, third_object.identifier.dn), fsmo_not_owner["server_acct_dn"]) self.assertEqual(ctr6.more_data, False) self.assertEqual(ctr6.nc_object_count, 0) self.assertEqual(ctr6.nc_linked_attributes_count, 0) self.assertEqual(ctr6.drs_error[0], 0)
def join_add_objects2(ctx): """add the various objects needed for the join, for subdomains post replication""" print "Adding %s" % ctx.partition_dn # NOTE: windows sends a ntSecurityDescriptor here, we # let it default rec = { "dn" : ctx.partition_dn, "objectclass" : "crossRef", "objectCategory" : "CN=Cross-Ref,%s" % ctx.schema_dn, "nCName" : ctx.base_dn, "nETBIOSName" : ctx.domain_name, "dnsRoot": ctx.dnsdomain, "trustParent" : ctx.parent_partition_dn, "systemFlags" : str(samba.dsdb.SYSTEM_FLAG_CR_NTDS_NC|samba.dsdb.SYSTEM_FLAG_CR_NTDS_DOMAIN)} if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: rec["msDS-Behavior-Version"] = str(ctx.behavior_version) rec2 = { "dn" : ctx.ntds_dn, "objectclass" : "nTDSDSA", "systemFlags" : str(samba.dsdb.SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE), "dMDLocation" : ctx.schema_dn} nc_list = [ ctx.base_dn, ctx.config_dn, ctx.schema_dn ] if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: rec2["msDS-Behavior-Version"] = str(ctx.behavior_version) if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: rec2["msDS-HasDomainNCs"] = ctx.base_dn rec2["objectCategory"] = "CN=NTDS-DSA,%s" % ctx.schema_dn rec2["HasMasterNCs"] = nc_list if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: rec2["msDS-HasMasterNCs"] = ctx.nc_list rec2["options"] = "1" rec2["invocationId"] = ndr_pack(ctx.invocation_id) objects = ctx.DsAddEntry([rec, rec2]) if len(objects) != 2: raise DCJoinException("Expected 2 objects from DsAddEntry") ctx.ntds_guid = objects[1].guid print("Replicating partition DN") ctx.repl.replicate(ctx.partition_dn, misc.GUID("00000000-0000-0000-0000-000000000000"), ctx.ntds_guid, exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ, replica_flags=drsuapi.DRSUAPI_DRS_WRIT_REP) print("Replicating NTDS DN") ctx.repl.replicate(ctx.ntds_dn, misc.GUID("00000000-0000-0000-0000-000000000000"), ctx.ntds_guid, exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ, replica_flags=drsuapi.DRSUAPI_DRS_WRIT_REP)
def set_attribute_replmetadata_version(self, dn, att, value, addifnotexist=False): res = self.search(expression="distinguishedName=%s" % dn, scope=ldb.SCOPE_SUBTREE, controls=["search_options:1:2"], attrs=["replPropertyMetaData"]) if len(res) == 0: return None repl = ndr_unpack(drsblobs.replPropertyMetaDataBlob, res[0]["replPropertyMetaData"][0]) ctr = repl.ctr now = samba.unix2nttime(int(time.time())) found = False if len(self.hash_oid_name.keys()) == 0: self._populate_oid_attid() for o in ctr.array: # Search for Description att_oid = self.get_oid_from_attid(o.attid) if att_oid in self.hash_oid_name and\ att.lower() == self.hash_oid_name[att_oid].lower(): found = True seq = self.sequence_number(ldb.SEQ_NEXT) o.version = value o.originating_change_time = now o.originating_invocation_id = misc.GUID( self.get_invocation_id()) o.originating_usn = seq o.local_usn = seq if not found and addifnotexist and len(ctr.array) > 0: o2 = drsblobs.replPropertyMetaData1() o2.attid = 589914 att_oid = self.get_oid_from_attid(o2.attid) seq = self.sequence_number(ldb.SEQ_NEXT) o2.version = value o2.originating_change_time = now o2.originating_invocation_id = misc.GUID(self.get_invocation_id()) o2.originating_usn = seq o2.local_usn = seq found = True tab = ctr.array tab.append(o2) ctr.count = ctr.count + 1 ctr.array = tab if found: replBlob = ndr_pack(repl) msg = ldb.Message() msg.dn = res[0].dn msg["replPropertyMetaData"] = \ ldb.MessageElement(replBlob, ldb.FLAG_MOD_REPLACE, "replPropertyMetaData") self.modify(msg, ["local_oid:1.3.6.1.4.1.7165.4.3.14:0"])
def _get_replication(self, replica_flags, drs_error=drsuapi.DRSUAPI_EXOP_ERR_NONE, drs=None, drs_handle=None, highwatermark=None, uptodateness_vector=None, more_flags=0, max_objects=133, exop=0, dest_dsa=drsuapi.DRSUAPI_DS_BIND_GUID_W2K3, source_dsa=None, invocation_id=None, nc_dn_str=None): """ Builds a DsGetNCChanges request based on the information provided and returns the response received from the DC. """ if source_dsa is None: source_dsa = self.test_ldb_dc.get_ntds_GUID() if invocation_id is None: invocation_id = self.test_ldb_dc.get_invocation_id() if nc_dn_str is None: nc_dn_str = self.test_ldb_dc.domain_dn() if highwatermark is None: if self.default_hwm is None: (highwatermark, _) = self._get_highest_hwm_utdv(self.test_ldb_dc) else: highwatermark = self.default_hwm if drs is None: drs = self.drs if drs_handle is None: drs_handle = self.drs_handle req10 = self._getnc_req10(dest_dsa=dest_dsa, invocation_id=invocation_id, nc_dn_str=nc_dn_str, exop=exop, max_objects=max_objects, replica_flags=replica_flags, more_flags=more_flags) req10.highwatermark = highwatermark if uptodateness_vector is not None: uptodateness_vector_v1 = drsuapi.DsReplicaCursorCtrEx() cursors = [] for i in xrange(0, uptodateness_vector.count): c = uptodateness_vector.cursors[i] c1 = drsuapi.DsReplicaCursor() c1.source_dsa_invocation_id = c.source_dsa_invocation_id c1.highest_usn = c.highest_usn cursors.append(c1) uptodateness_vector_v1.count = len(cursors) uptodateness_vector_v1.cursors = cursors req10.uptodateness_vector = uptodateness_vector_v1 (level, ctr) = drs.DsGetNCChanges(drs_handle, 10, req10) self._ctr6_debug(ctr) self.assertEqual(level, 6, "expected level 6 response!") self.assertEqual(ctr.source_dsa_guid, misc.GUID(source_dsa)) self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(invocation_id)) self.assertEqual(ctr.extended_ret, drs_error) return ctr
def get_password_from_ad(connector, user_dn, reconnect=False): ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: Read password from AD: %s" % user_dn) nt_hash = None if not connector.drs or reconnect: connector.open_drs_connection() req8 = drsuapi.DsGetNCChangesRequest8() req8.destination_dsa_guid = misc.GUID(connector.computer_guid) req8.source_dsa_invocation_id = misc.GUID(connector.computer_guid) req8.naming_context = drsuapi.DsReplicaObjectIdentifier() req8.naming_context.dn = user_dn req8.replica_flags = 0 req8.max_object_count = 402 req8.max_ndr_size = 402116 req8.extended_op = drsuapi.DRSUAPI_EXOP_REPL_SECRET req8.fsmo_info = 0 while True: (level, ctr) = connector.drs.DsGetNCChanges(connector.drsuapi_handle, 8, req8) rid = None unicode_blob = None keys = [] if ctr.first_object is None: break for i in ctr.first_object.object.attribute_ctr.attributes: if i.attid == 589970: # DRSUAPI_ATTID_objectSid if i.value_ctr.values: for j in i.value_ctr.values: sid = ndr_unpack(security.dom_sid, j.blob) _tmp, rid = sid.split() if i.attid == 589914: # DRSUAPI_ATTID_unicodePwd if i.value_ctr.values: for j in i.value_ctr.values: unicode_blob = j.blob ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: Found unicodePwd blob") if i.attid == drsuapi.DRSUAPI_ATTID_supplementalCredentials and connector.configRegistry.is_true('%s/ad/mapping/user/password/kerberos/enabled' % connector.CONFIGBASENAME, False): if i.value_ctr.values: for j in i.value_ctr.values: ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: Found supplementalCredentials blob") spl = decrypt_supplementalCredentials(connector, j.blob) keys = calculate_krb5keys(spl) if rid and unicode_blob: nt_hash = decrypt(connector.drs.user_session_key, unicode_blob, rid).upper() if ctr.more_data == 0: break ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: AD Hash: %s" % nt_hash) return nt_hash, keys
def _test_conflict_existing_single_valued_link(self, sync_order): """ Tests a single-valued link conflict, where the conflicting link value already exists (as inactive) on both DCs. """ # create the link objects src_ou = self.unique_dn("OU=src") src_guid = self.add_object(self.ldb_dc1, src_ou) target1_ou = self.unique_dn("OU=target1") target2_ou = self.unique_dn("OU=target2") target1_guid = self.add_object(self.ldb_dc1, target1_ou) target2_guid = self.add_object(self.ldb_dc1, target2_ou) # add the links, but then delete them self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.del_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target2_ou) self.del_link_attr(self.ldb_dc1, src_ou, "managedBy", target2_ou) self.sync_DCs() # re-add the links independently on each DC self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.ensure_unique_timestamp() self.add_link_attr(self.ldb_dc2, src_ou, "managedBy", target2_ou) # try to sync the 2 DCs self.sync_DCs(sync_order=sync_order) res1 = self.ldb_dc1.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) res2 = self.ldb_dc2.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) # check the object has only have one occurence of the single-valued # attribute and it matches on both DCs self.assert_attrs_match(res1, res2, "managedBy", 1) # here we expect DC2 to win because it has the more recent link self.assertTrue( str(res1[0]["managedBy"][0]) == target2_ou, "Expected most recent update to win conflict") # we can't query the deleted links over LDAP, but we can check DRS # to make sure the DC kept a copy of the conflicting link link1 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, 0, misc.GUID(src_guid), misc.GUID(target1_guid)) link2 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE, misc.GUID(src_guid), misc.GUID(target2_guid)) self._check_replicated_links(src_ou, [link1, link2])
def get_password_from_ad(connector, user_dn): _d = ud.function('ldap.ad.get_password_from_ad') ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: Read password from AD: %s" % user_dn) nt_hash = None if not connector.drs: connector.open_drs_connection() req8 = drsuapi.DsGetNCChangesRequest8() req8.destination_dsa_guid = misc.GUID(connector.computer_guid) req8.source_dsa_invocation_id = misc.GUID(connector.computer_guid) req8.naming_context = drsuapi.DsReplicaObjectIdentifier() req8.naming_context.dn = user_dn req8.replica_flags = 0 req8.max_object_count = 402 req8.max_ndr_size = 402116 req8.extended_op = drsuapi.DRSUAPI_EXOP_REPL_SECRET req8.fsmo_info = 0 while True: (level, ctr) = connector.drs.DsGetNCChanges(connector.drsuapi_handle, 8, req8) rid = None unicode_blob = None if ctr.first_object is None: break for i in ctr.first_object.object.attribute_ctr.attributes: if str(i.attid) == "589970": # DRSUAPI_ATTID_objectSid if i.value_ctr.values: for j in i.value_ctr.values: sid = ndr_unpack(security.dom_sid, j.blob) _tmp, rid = sid.split() if str(i.attid) == "589914": # DRSUAPI_ATTID_unicodePwd if i.value_ctr.values: for j in i.value_ctr.values: unicode_blob = j.blob ud.debug( ud.LDAP, ud.INFO, "get_password_from_ad: Found unicodePwd blob") if rid and unicode_blob: nt_hash = decrypt(connector.drs.user_session_key, unicode_blob, rid).upper() if ctr.more_data == 0: break ud.debug(ud.LDAP, ud.INFO, "get_password_from_ad: AD Hash: %s" % nt_hash) return nt_hash
def run(self, *accounts, **kwargs): sambaopts = kwargs.get("sambaopts") credopts = kwargs.get("credopts") versionpts = kwargs.get("versionopts") server = kwargs.get("server") accounts_file = kwargs.get("file") if server is None: raise Exception("You must supply a server") if accounts_file is not None: accounts = [] if accounts_file == "-": for line in sys.stdin: accounts.append(line.strip()) else: for line in open(accounts_file, 'r'): accounts.append(line.strip()) lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) # connect to the remote and local SAMs samdb = SamDB(url="ldap://%s" % server, session_info=system_session(), credentials=creds, lp=lp) local_samdb = SamDB(url=None, session_info=system_session(), credentials=creds, lp=lp) destination_dsa_guid = misc.GUID(local_samdb.get_ntds_GUID()) repl = drs_Replicate("ncacn_ip_tcp:%s[seal,print]" % server, lp, creds, local_samdb, destination_dsa_guid) for account in accounts: # work out the source and destination GUIDs dc_ntds_dn = samdb.get_dsServiceName() res = samdb.search(base=dc_ntds_dn, scope=ldb.SCOPE_BASE, attrs=["invocationId"]) source_dsa_invocation_id = misc.GUID(local_samdb.schema_format_value("objectGUID", res[0]["invocationId"][0])) dn = self.get_dn(samdb, account) self.outf.write("Replicating DN %s\n" % dn) local_samdb.transaction_start() try: repl.replicate(dn, source_dsa_invocation_id, destination_dsa_guid, exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, rodc=True) except Exception, e: local_samdb.transaction_cancel() raise CommandError("Error replicating DN %s" % dn, e) local_samdb.transaction_commit()
def _singleval_link_conflict_deleted_loser(self, sync_order): """ Tests a single-valued link conflict, where the losing link value is deleted. """ src_ou = self.unique_dn("OU=src") src_guid = self.add_object(self.ldb_dc1, src_ou) self.sync_DCs() # create a unique target on each DC target1_ou = self.unique_dn("OU=target1") target2_ou = self.unique_dn("OU=target2") target1_guid = self.add_object(self.ldb_dc1, target1_ou) target2_guid = self.add_object(self.ldb_dc2, target2_ou) # add the links - we want the link to end up deleted on DC2, but active # on DC1. DC1 has the better version and DC2 has the better timestamp - # the better version should win self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.del_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.ensure_unique_timestamp() self.add_link_attr(self.ldb_dc2, src_ou, "managedBy", target2_ou) self.del_link_attr(self.ldb_dc2, src_ou, "managedBy", target2_ou) self.sync_DCs(sync_order=sync_order) res1 = self.ldb_dc1.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) res2 = self.ldb_dc2.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) # check the object has only have one occurence of the single-valued # attribute and it matches on both DCs self.assert_attrs_match(res1, res2, "managedBy", 1) self.assertTrue( str(res1[0]["managedBy"][0]) == target1_ou, "Expected most recent update to win conflict") # we can't query the deleted links over LDAP, but we can check DRS # to make sure the DC kept a copy of the conflicting link link1 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE, misc.GUID(src_guid), misc.GUID(target1_guid)) link2 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, 0, misc.GUID(src_guid), misc.GUID(target2_guid)) self._check_replicated_links(src_ou, [link1, link2])
def run(self, account, sambaopts=None, credopts=None, versionopts=None, server=None): if server is None: raise Exception("You must supply a server") lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) # connect to the remote and local SAMs samdb = SamDB(url="ldap://%s" % server, session_info=system_session(), credentials=creds, lp=lp) local_samdb = SamDB(url=None, session_info=system_session(), credentials=creds, lp=lp) # work out the source and destination GUIDs dc_ntds_dn = samdb.get_dsServiceName() res = samdb.search(base=dc_ntds_dn, scope=ldb.SCOPE_BASE, attrs=["invocationId"]) source_dsa_invocation_id = misc.GUID( local_samdb.schema_format_value("objectGUID", res[0]["invocationId"][0])) dn = self.get_dn(samdb, account) self.outf.write("Replicating DN %s\n" % dn) destination_dsa_guid = misc.GUID(local_samdb.get_ntds_GUID()) local_samdb.transaction_start() repl = drs_Replicate("ncacn_ip_tcp:%s[seal,print]" % server, lp, creds, local_samdb, destination_dsa_guid) try: repl.replicate(dn, source_dsa_invocation_id, destination_dsa_guid, exop=drsuapi.DRSUAPI_EXOP_REPL_SECRET, rodc=True) except Exception, e: local_samdb.transaction_cancel() raise CommandError("Error replicating DN %s" % dn, e)
def __cmp__(self, other): ''' compare dsdb_Dn values similar to parsed_dn_compare()''' dn1 = self dn2 = other guid1 = dn1.dn.get_extended_component("GUID") guid1b = ndr_pack(misc.GUID(guid1)) guid2 = dn2.dn.get_extended_component("GUID") guid2b = ndr_pack(misc.GUID(guid2)) v = cmp(guid1, guid2) if v != 0: return v v = cmp(dn1.binary, dn2.binary) return v
def _singleval_link_conflict_deleted_winner(self, sync_order): """ Tests a single-value link conflict where the more-up-to-date link value is deleted. """ src_ou = self.unique_dn("OU=src") src_guid = self.add_object(self.ldb_dc1, src_ou) self.sync_DCs() # create a unique target on each DC target1_ou = self.unique_dn("OU=target1") target2_ou = self.unique_dn("OU=target2") target1_guid = self.add_object(self.ldb_dc1, target1_ou) target2_guid = self.add_object(self.ldb_dc2, target2_ou) # add the links for the respective targets, and delete one of the links self.add_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) self.add_link_attr(self.ldb_dc2, src_ou, "managedBy", target2_ou) self.ensure_unique_timestamp() self.del_link_attr(self.ldb_dc1, src_ou, "managedBy", target1_ou) # sync the 2 DCs self.sync_DCs(sync_order=sync_order) res1 = self.ldb_dc1.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) res2 = self.ldb_dc2.search(base="<GUID=%s>" % src_guid, scope=SCOPE_BASE, attrs=["managedBy"]) # Although the more up-to-date link value is deleted, this shouldn't # trump DC1's active link self.assert_attrs_match(res1, res2, "managedBy", 1) self.assertTrue( str(res1[0]["managedBy"][0]) == target2_ou, "Expected active link win conflict") # we can't query the deleted links over LDAP, but we can check that # the deleted links exist using DRS link1 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, 0, misc.GUID(src_guid), misc.GUID(target1_guid)) link2 = AbstractLink(drsuapi.DRSUAPI_ATTID_managedBy, drsuapi.DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE, misc.GUID(src_guid), misc.GUID(target2_guid)) self._check_replicated_links(src_ou, [link1, link2])
def test_negative_into_uint8_list(self): g = misc.GUID() def assign(): g.node[1] = -1 self.assertRaises(OverflowError, assign)
def test_long_list_over_uint8_list(self): g = misc.GUID() def assign(): g.node = [5, 0, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] self.assertRaises(TypeError, assign)
def test_overflow_list_over_uint8_list(self): g = misc.GUID() def assign(): g.node = [256, 0, 5, 0, 7, 4] self.assertRaises(OverflowError, assign)
def test_overflow_bitmap_into_uint16_2(self): g = misc.GUID() def assign(): g.time_mid = misc.SV_TYPE_DOMAIN_ENUM self.assertRaises(OverflowError, assign)
def test_overflow_bitmap_into_uint16(self): g = misc.GUID() def assign(): g.time_mid = misc.SV_TYPE_LOCAL_LIST_ONLY self.assertRaises(OverflowError, assign)
def test_FSMONotOwner(self): """Test role transfer with against DC not owner of the role""" fsmo_dn = self.ldb_dc1.get_schema_basedn() (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) req8 = self._exop_req8(dest_dsa=fsmo_owner["ntds_guid"], invocation_id=fsmo_not_owner["invocation_id"], nc_dn_str=fsmo_dn, exop=drsuapi.DRSUAPI_EXOP_FSMO_REQ_ROLE) (drs, drs_handle) = self._ds_bind(fsmo_not_owner["dns_name"]) (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) self.assertEqual(level, 6, "Expected level 6 response!") self._check_exop_failed(ctr, drsuapi.DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER) self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_not_owner["ntds_guid"])) self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_not_owner["invocation_id"]))
def join_provision_own_domain(ctx): """Provision the local SAM.""" # we now operate exclusively on the local database, which # we need to reopen in order to get the newly created schema print("Reconnecting to local samdb") ctx.samdb = SamDB(url=ctx.local_samdb.url, session_info=system_session(), lp=ctx.local_samdb.lp, global_schema=False) ctx.samdb.set_invocation_id(str(ctx.invocation_id)) ctx.local_samdb = ctx.samdb print("Finding domain GUID from ncName") res = ctx.local_samdb.search(base=ctx.partition_dn, scope=ldb.SCOPE_BASE, attrs=['ncName'], controls=["extended_dn:1:1"]) domguid = str(misc.GUID(ldb.Dn(ctx.samdb, res[0]['ncName'][0]).get_extended_component('GUID'))) print("Got domain GUID %s" % domguid) print("Calling own domain provision") logger = logging.getLogger("provision") logger.addHandler(logging.StreamHandler(sys.stdout)) secrets_ldb = Ldb(ctx.paths.secrets, session_info=system_session(), lp=ctx.lp) presult = provision_fill(ctx.local_samdb, secrets_ldb, logger, ctx.names, ctx.paths, domainsid=security.dom_sid(ctx.domsid), domainguid=domguid, targetdir=ctx.targetdir, samdb_fill=FILL_SUBDOMAIN, machinepass=ctx.acct_pass, serverrole="domain controller", lp=ctx.lp, hostip=ctx.names.hostip, hostip6=ctx.names.hostip6, dns_backend=ctx.dns_backend) print("Provision OK for domain %s" % ctx.names.dnsdomain)
def _samdb_fetch_pfm_and_schi(self): """Fetch prefixMap and schemaInfo stored in SamDB using LDB connection""" samdb = self.ldb_dc1 res = samdb.search(base=samdb.get_schema_basedn(), scope=SCOPE_BASE, attrs=["prefixMap", "schemaInfo"]) pfm = ndr_unpack(drsblobs.prefixMapBlob, res[0]['prefixMap'][0]) schi = drsuapi.DsReplicaOIDMapping() schi.id_prefix = 0 if 'schemaInfo' in res[0]: binary_oid = [ x if isinstance(x, int) else ord(x) for x in res[0]['schemaInfo'][0] ] schi.oid.length = len(binary_oid) schi.oid.binary_oid = binary_oid else: schema_info = drsblobs.schemaInfoBlob() schema_info.revision = 0 schema_info.marker = 0xFF schema_info.invocation_id = misc.GUID(samdb.get_invocation_id()) binary_oid = [ x if isinstance(x, int) else ord(x) for x in ndr_pack(schema_info) ] # you have to set the length before setting binary_oid schi.oid.length = len(binary_oid) schi.oid.binary_oid = binary_oid pfm.ctr.mappings = pfm.ctr.mappings + [schi] pfm.ctr.num_mappings += 1 return pfm.ctr
def transfer_dns_role(outf, sambaopts, credopts, role, samdb): """Transfer dns FSMO role. """ if role == "domaindns": domain_dn = samdb.domain_dn() role_object = "CN=Infrastructure,DC=DomainDnsZones," + domain_dn elif role == "forestdns": forest_dn = samba.dn_from_dns_name(samdb.forest_dns_name()) role_object = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn try: res = samdb.search(role_object, attrs=["fSMORoleOwner"], scope=ldb.SCOPE_BASE, controls=["extended_dn:1:1"]) if 'fSMORoleOwner' in res[0]: try: master_guid = str( misc.GUID( ldb.Dn(samdb, res[0]['fSMORoleOwner'] [0]).get_extended_component('GUID'))) master_owner = str(ldb.Dn(samdb, res[0]['fSMORoleOwner'][0])) except LdbError, (num, msg): raise CommandError( "GUID not found in partition naming master DN %s : %s \n" % (res[0]['fSMORoleOwner'][0], msg)) except LdbError, (num, msg): raise CommandError("DNS partion %s not found : %s" % (role, msg))
def test_InvalidDestDSA_ridalloc(self): """Test RID allocation with invalid destination DSA guid""" fsmo_dn = ldb.Dn(self.ldb_dc1, "CN=RID Manager$,CN=System," + self.ldb_dc1.domain_dn()) (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) req8 = self._exop_req8(dest_dsa="9c637462-5b8c-4467-aef2-bdb1f57bc4ef", invocation_id=fsmo_owner["invocation_id"], nc_dn_str=fsmo_dn, exop=drsuapi.DRSUAPI_EXOP_FSMO_RID_ALLOC) (drs, drs_handle) = self._ds_bind(fsmo_owner["dns_name"]) (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) self.assertEqual(level, 6, "Expected level 6 response!") self._check_exop_failed(ctr, drsuapi.DRSUAPI_EXOP_ERR_UNKNOWN_CALLER) self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_owner["ntds_guid"])) self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_owner["invocation_id"]))
def test_overflow_into_uint8_list(self): g = misc.GUID() def assign(): g.node[1] = 256 self.assertRaises(OverflowError, assign)
def test_hyper_into_uint16(self): g = misc.GUID() def assign(): g.time_mid = server_id.SERVERID_UNIQUE_ID_NOT_TO_VERIFY self.assertRaises(OverflowError, assign)
def sendDsReplicaSync(drsuapiBind, drsuapi_handle, source_dsa_guid, naming_context, req_option): """Send DS replica sync request. :param drsuapiBind: a drsuapi Bind object :param drsuapi_handle: a drsuapi hanle on the drsuapi connection :param source_dsa_guid: the guid of the source dsa for the replication :param naming_context: the DN of the naming context to replicate :param req_options: replication options for the DsReplicaSync call :raise drsException: if any error occur while sending and receiving the reply for the dsReplicaSync """ nc = drsuapi.DsReplicaObjectIdentifier() nc.dn = naming_context req1 = drsuapi.DsReplicaSyncRequest1() req1.naming_context = nc req1.options = req_option req1.source_dsa_guid = misc.GUID(source_dsa_guid) try: drsuapiBind.DsReplicaSync(drsuapi_handle, 1, req1) except Exception, estr: raise drsException("DsReplicaSync failed %s" % estr)
def test_negative_int_into_uint16(self): g = misc.GUID() def assign(): g.time_mid = -2 self.assertRaises(OverflowError, assign)
def _samdb_fetch_pfm_and_schi(self): """Fetch prefixMap and schemaInfo stored in SamDB using LDB connection""" samdb = self.ldb_dc1 res = samdb.search(base=samdb.get_schema_basedn(), scope=SCOPE_BASE, attrs=["prefixMap", "schemaInfo"]) pfm = ndr_unpack(drsblobs.prefixMapBlob, str(res[0]['prefixMap'])) schi = drsuapi.DsReplicaOIDMapping() schi.id_prefix = 0 if 'schemaInfo' in res[0]: schi.oid.length = len(map(ord, str(res[0]['schemaInfo']))) schi.oid.binary_oid = map(ord, str(res[0]['schemaInfo'])) else: schema_info = drsblobs.schemaInfoBlob() schema_info.revision = 0 schema_info.marker = 0xFF schema_info.invocation_id = misc.GUID(samdb.get_invocation_id()) schi.oid.length = len(map(ord, ndr_pack(schema_info))) schi.oid.binary_oid = map(ord, ndr_pack(schema_info)) pfm.ctr.mappings = pfm.ctr.mappings + [schi] pfm.ctr.num_mappings += 1 return pfm.ctr
def test_InvalidDestDSA(self): """Test role transfer with invalid destination DSA guid""" fsmo_dn = self.ldb_dc1.get_schema_basedn() (fsmo_owner, fsmo_not_owner) = self._determine_fSMORoleOwner(fsmo_dn) req8 = self._exop_req8(dest_dsa="9c637462-5b8c-4467-aef2-bdb1f57bc4ef", invocation_id=fsmo_owner["invocation_id"], nc_dn_str=fsmo_dn, exop=drsuapi.DRSUAPI_EXOP_FSMO_REQ_ROLE) (drs, drs_handle) = self._ds_bind(fsmo_owner["dns_name"]) (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8) self.assertEqual(level, 6, "Expected level 6 response!") self._check_exop_failed(ctr, drsuapi.DRSUAPI_EXOP_ERR_UNKNOWN_CALLER) self.assertEqual(ctr.source_dsa_guid, misc.GUID(fsmo_owner["ntds_guid"])) self.assertEqual(ctr.source_dsa_invocation_id, misc.GUID(fsmo_owner["invocation_id"]))