Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
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)
Example #5
0
    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"])
Example #6
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
Example #8
0
    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])
Example #9
0
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
Example #10
0
    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()
Example #11
0
    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])
Example #12
0
    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)
Example #13
0
    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
Example #14
0
    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])
Example #15
0
    def test_negative_into_uint8_list(self):
        g = misc.GUID()

        def assign():
            g.node[1] = -1

        self.assertRaises(OverflowError, assign)
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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)
Example #19
0
    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)
Example #20
0
    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"]))
Example #21
0
    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)
Example #22
0
    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
Example #23
0
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))
Example #24
0
    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"]))
Example #25
0
    def test_overflow_into_uint8_list(self):
        g = misc.GUID()

        def assign():
            g.node[1] = 256

        self.assertRaises(OverflowError, assign)
Example #26
0
    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)
Example #27
0
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)
Example #28
0
    def test_negative_int_into_uint16(self):
        g = misc.GUID()

        def assign():
            g.time_mid = -2

        self.assertRaises(OverflowError, assign)
Example #29
0
    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
Example #30
0
    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"]))