Пример #1
0
def _drs_fetch_pfm(server, samdb, creds, lp):
    """Fetch prefixMap using DRS interface"""
    binding_str = "ncacn_ip_tcp:%s[print,seal]" % server

    drs = drsuapi.drsuapi(binding_str, lp, creds)
    (drs_handle, supported_extensions) = drs_DsBind(drs)
    print "DRS Handle: %s" % drs_handle

    req8 = drsuapi.DsGetNCChangesRequest8()

    dest_dsa = misc.GUID("9c637462-5b8c-4467-aef2-bdb1f57bc4ef")
    replica_flags = 0

    req8.destination_dsa_guid = dest_dsa
    req8.source_dsa_invocation_id = misc.GUID(samdb.get_invocation_id())
    req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
    req8.naming_context.dn = unicode(samdb.get_schema_basedn())
    req8.highwatermark = drsuapi.DsReplicaHighWaterMark()
    req8.highwatermark.tmp_highest_usn = 0
    req8.highwatermark.reserved_usn = 0
    req8.highwatermark.highest_usn = 0
    req8.uptodateness_vector = None
    req8.replica_flags = replica_flags
    req8.max_object_count = 0
    req8.max_ndr_size = 402116
    req8.extended_op = 0
    req8.fsmo_info = 0
    req8.partial_attribute_set = None
    req8.partial_attribute_set_ex = None
    req8.mapping_ctr.num_mappings = 0
    req8.mapping_ctr.mappings = None

    (level, ctr) = drs.DsGetNCChanges(drs_handle, 8, req8)
    pfm = ctr.mapping_ctr
    # check for schemaInfo element
    pfm_it = pfm.mappings[-1]
    assert pfm_it.id_prefix == 0
    assert pfm_it.oid.length == 21
    s = ''
    for x in pfm_it.oid.binary_oid:
        s += chr(x)
    pfm_schi = ndr_unpack(drsblobs.schemaInfoBlob, s)
    assert pfm_schi.marker == 0xFF
    # remove schemaInfo element
    pfm.num_mappings -= 1
    return (pfm, pfm_schi)
Пример #2
0
    def DsAddEntry(ctx, rec):
        '''add a record via the DRSUAPI DsAddEntry call'''
        if ctx.drsuapi is None:
            ctx.drsuapi_connect()
        if ctx.tmp_samdb is None:
            ctx.create_tmp_samdb()

        id = drsuapi.DsReplicaObjectIdentifier()
        id.dn = rec['dn']

        attrs = []
        for a in rec:
            if a == 'dn':
                continue
            if not isinstance(rec[a], list):
                v = [rec[a]]
            else:
                v = rec[a]
            rattr = ctx.tmp_samdb.dsdb_DsReplicaAttribute(ctx.tmp_samdb, a, v)
            attrs.append(rattr)

        attribute_ctr = drsuapi.DsReplicaAttributeCtr()
        attribute_ctr.num_attributes = len(attrs)
        attribute_ctr.attributes = attrs

        object = drsuapi.DsReplicaObject()
        object.identifier = id
        object.attribute_ctr = attribute_ctr

        first_object = drsuapi.DsReplicaObjectListItem()
        first_object.object = object

        req2 = drsuapi.DsAddEntryRequest2()
        req2.first_object = first_object

        (level, ctr) = ctx.drsuapi.DsAddEntry(ctx.drsuapi_handle, 2, req2)
        if ctr.err_ver != 1:
            raise RuntimeError("expected err_ver 1, got %u" % ctr.err_ver)
        if ctr.err_data.status != (0, 'WERR_OK'):
            print("DsAddEntry failed with status %s info %s" %
                  (ctr.err_data.status, ctr.err_data.info.extended_err))
            raise RuntimeError("DsAddEntry failed")
Пример #3
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 = str(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
Пример #4
0
 def _exop_req8(self, dest_dsa, invocation_id, nc_dn_str, exop):
     req8 = drsuapi.DsGetNCChangesRequest8()
 
     req8.destination_dsa_guid = misc.GUID(dest_dsa)
     req8.source_dsa_invocation_id = misc.GUID(invocation_id)
     req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
     req8.naming_context.dn = unicode(nc_dn_str)
     req8.highwatermark = drsuapi.DsReplicaHighWaterMark()
     req8.highwatermark.tmp_highest_usn = 0
     req8.highwatermark.reserved_usn = 0
     req8.highwatermark.highest_usn = 0
     req8.uptodateness_vector = None
     req8.replica_flags = 0
     req8.max_object_count = 0
     req8.max_ndr_size = 402116
     req8.extended_op = exop
     req8.fsmo_info = 0
     req8.partial_attribute_set = None
     req8.partial_attribute_set_ex = None
     req8.mapping_ctr.num_mappings = 0
     req8.mapping_ctr.mappings = None
 
     return req8
Пример #5
0
    def replicate(self,
                  dn,
                  source_dsa_invocation_id,
                  destination_dsa_guid,
                  schema=False,
                  exop=drsuapi.DRSUAPI_EXOP_NONE,
                  rodc=False,
                  replica_flags=None):
        '''replicate a single DN'''

        # setup for a GetNCChanges call
        req8 = drsuapi.DsGetNCChangesRequest8()

        req8.destination_dsa_guid = destination_dsa_guid
        req8.source_dsa_invocation_id = source_dsa_invocation_id
        req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
        req8.naming_context.dn = dn
        req8.highwatermark = drsuapi.DsReplicaHighWaterMark()
        req8.highwatermark.tmp_highest_usn = 0
        req8.highwatermark.reserved_usn = 0
        req8.highwatermark.highest_usn = 0
        req8.uptodateness_vector = None
        if replica_flags is not None:
            req8.replica_flags = replica_flags
        elif exop == drsuapi.DRSUAPI_EXOP_REPL_SECRET:
            req8.replica_flags = 0
        else:
            req8.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC
                                  | drsuapi.DRSUAPI_DRS_PER_SYNC
                                  | drsuapi.DRSUAPI_DRS_GET_ANC
                                  | drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
                                  drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
            if rodc:
                req8.replica_flags |= (
                    drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
            else:
                req8.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP
        req8.max_object_count = 402
        req8.max_ndr_size = 402116
        req8.extended_op = exop
        req8.fsmo_info = 0
        req8.partial_attribute_set = None
        req8.partial_attribute_set_ex = None
        req8.mapping_ctr.num_mappings = 0
        req8.mapping_ctr.mappings = None

        if not schema and rodc:
            req8.partial_attribute_set = self.drs_get_rodc_partial_attribute_set(
            )

        if self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
            req_level = 8
            req = req8
        else:
            req_level = 5
            req5 = drsuapi.DsGetNCChangesRequest5()
            for a in dir(req5):
                if a[0] != '_':
                    setattr(req5, a, getattr(req8, a))
            req = req5

        while True:
            (level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level,
                                                   req)
            if ctr.first_object is None and ctr.object_count != 0:
                raise RuntimeError(
                    "DsGetNCChanges: NULL first_object with object_count=%u" %
                    (ctr.object_count))
            self.net.replicate_chunk(self.replication_state,
                                     level,
                                     ctr,
                                     schema=schema,
                                     req_level=req_level,
                                     req=req)
            if ctr.more_data == 0:
                break
            req.highwatermark = ctr.new_highwatermark
Пример #6
0
    def replicate(self,
                  dn,
                  source_dsa_invocation_id,
                  destination_dsa_guid,
                  schema=False,
                  exop=drsuapi.DRSUAPI_EXOP_NONE,
                  rodc=False,
                  replica_flags=None,
                  full_sync=True,
                  sync_forced=False):
        '''replicate a single DN'''

        # setup for a GetNCChanges call
        req8 = drsuapi.DsGetNCChangesRequest8()

        req8.destination_dsa_guid = destination_dsa_guid
        req8.source_dsa_invocation_id = source_dsa_invocation_id
        req8.naming_context = drsuapi.DsReplicaObjectIdentifier()
        req8.naming_context.dn = dn

        # Default to a full replication if we don't find an upToDatenessVector
        udv = None
        hwm = drsuapi.DsReplicaHighWaterMark()
        hwm.tmp_highest_usn = 0
        hwm.reserved_usn = 0
        hwm.highest_usn = 0

        if not full_sync:
            res = self.samdb.search(base=dn,
                                    scope=ldb.SCOPE_BASE,
                                    attrs=["repsFrom"])
            if "repsFrom" in res[0]:
                for reps_from_packed in res[0]["repsFrom"]:
                    reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob,
                                               reps_from_packed)
                    if reps_from_obj.ctr.source_dsa_invocation_id == source_dsa_invocation_id:
                        hwm = reps_from_obj.ctr.highwatermark

            udv = drsuapi.DsReplicaCursorCtrEx()
            udv.version = 1
            udv.reserved1 = 0
            udv.reserved2 = 0

            cursors_v1 = []
            cursors_v2 = dsdb._dsdb_load_udv_v2(
                self.samdb, self.samdb.get_default_basedn())
            for cursor_v2 in cursors_v2:
                cursor_v1 = drsuapi.DsReplicaCursor()
                cursor_v1.source_dsa_invocation_id = cursor_v2.source_dsa_invocation_id
                cursor_v1.highest_usn = cursor_v2.highest_usn
                cursors_v1.append(cursor_v1)

            udv.cursors = cursors_v1
            udv.count = len(cursors_v1)

        req8.highwatermark = hwm
        req8.uptodateness_vector = udv

        if replica_flags is not None:
            req8.replica_flags = replica_flags
        elif exop == drsuapi.DRSUAPI_EXOP_REPL_SECRET:
            req8.replica_flags = 0
        else:
            req8.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC
                                  | drsuapi.DRSUAPI_DRS_PER_SYNC
                                  | drsuapi.DRSUAPI_DRS_GET_ANC
                                  | drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
                                  drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
            if rodc:
                req8.replica_flags |= (
                    drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
            else:
                req8.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP

        if sync_forced:
            req8.replica_flags |= drsuapi.DRSUAPI_DRS_SYNC_FORCED

        req8.max_object_count = 402
        req8.max_ndr_size = 402116
        req8.extended_op = exop
        req8.fsmo_info = 0
        req8.partial_attribute_set = None
        req8.partial_attribute_set_ex = None
        req8.mapping_ctr.num_mappings = 0
        req8.mapping_ctr.mappings = None

        if not schema and rodc:
            req8.partial_attribute_set = drs_get_rodc_partial_attribute_set(
                self.samdb)

        if self.supported_extensions & drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
            req_level = 8
            req = req8
        else:
            req_level = 5
            req5 = drsuapi.DsGetNCChangesRequest5()
            for a in dir(req5):
                if a[0] != '_':
                    setattr(req5, a, getattr(req8, a))
            req = req5

        num_objects = 0
        num_links = 0
        while True:
            (level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level,
                                                   req)
            if ctr.first_object is None and ctr.object_count != 0:
                raise RuntimeError(
                    "DsGetNCChanges: NULL first_object with object_count=%u" %
                    (ctr.object_count))
            self.net.replicate_chunk(self.replication_state,
                                     level,
                                     ctr,
                                     schema=schema,
                                     req_level=req_level,
                                     req=req)

            num_objects += ctr.object_count

            # Cope with servers that do not return level 6, so do not return any links
            try:
                num_links += ctr.linked_attributes_count
            except AttributeError:
                pass

            if ctr.more_data == 0:
                break
            req.highwatermark = ctr.new_highwatermark

        return (num_objects, num_links)
Пример #7
0
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7
    bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT
    (info,
     drs_handle) = drs_conn.DsBind(misc.GUID(drsuapi.DRSUAPI_DS_BIND_GUID),
                                   bind_info)

    null_guid = misc.GUID()

    naming_context = drsuapi.DsReplicaObjectIdentifier()
    naming_context.dn = dn
    highwatermark = store_hwm
    uptodateness_vector = None
    if store_utdv is not None:
        uptodateness_vector = drsuapi.DsReplicaCursorCtrEx()
        if store_utdv.version == 1:
            uptodateness_vector.cursors = store_utdv.cursors
        elif store_utdv.version == 2:
            cursors = []
            for i in range(0, store_utdv.ctr.count):
                cursor = drsuapi.DsReplicaCursor()
                cursor.source_dsa_invocation_id = store_utdv.ctr.cursors[
                    i].source_dsa_invocation_id
                cursor.highest_usn = store_utdv.ctr.cursors[i].highest_usn
                cursors.append(cursor)
Пример #8
0
def get_password_from_ad(connector, user_dn, reconnect=False):
    _d = ud.function('ldap.ad.get_password_from_ad')  # noqa: F841
    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 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 i.attid == drsuapi.DRSUAPI_ATTID_supplementalCredentials and connector.baseConfig.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
Пример #9
0
    def replicate(self,
                  dn,
                  source_dsa_invocation_id,
                  destination_dsa_guid,
                  schema=False,
                  exop=drsuapi.DRSUAPI_EXOP_NONE,
                  rodc=False,
                  replica_flags=None,
                  full_sync=True,
                  sync_forced=False,
                  more_flags=0):
        '''replicate a single DN'''

        # setup for a GetNCChanges call
        if self.supports_ext & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10:
            req = drsuapi.DsGetNCChangesRequest10()
            req.more_flags = (more_flags | self.more_flags)
            req_level = 10
        else:
            req_level = 8
            req = drsuapi.DsGetNCChangesRequest8()

        req.destination_dsa_guid = destination_dsa_guid
        req.source_dsa_invocation_id = source_dsa_invocation_id
        req.naming_context = drsuapi.DsReplicaObjectIdentifier()
        req.naming_context.dn = dn

        # Default to a full replication if we don't find an upToDatenessVector
        udv = None
        hwm = drsuapi.DsReplicaHighWaterMark()
        hwm.tmp_highest_usn = 0
        hwm.reserved_usn = 0
        hwm.highest_usn = 0

        if not full_sync:
            res = self.samdb.search(base=dn,
                                    scope=ldb.SCOPE_BASE,
                                    attrs=["repsFrom"])
            if "repsFrom" in res[0]:
                for reps_from_packed in res[0]["repsFrom"]:
                    reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob,
                                               reps_from_packed)
                    if reps_from_obj.ctr.source_dsa_invocation_id == source_dsa_invocation_id:
                        hwm = reps_from_obj.ctr.highwatermark

            udv = drsuapi.DsReplicaCursorCtrEx()
            udv.version = 1
            udv.reserved1 = 0
            udv.reserved2 = 0

            cursors_v1 = []
            cursors_v2 = dsdb._dsdb_load_udv_v2(
                self.samdb, self.samdb.get_default_basedn())
            for cursor_v2 in cursors_v2:
                cursor_v1 = drsuapi.DsReplicaCursor()
                cursor_v1.source_dsa_invocation_id = cursor_v2.source_dsa_invocation_id
                cursor_v1.highest_usn = cursor_v2.highest_usn
                cursors_v1.append(cursor_v1)

            udv.cursors = cursors_v1
            udv.count = len(cursors_v1)

        req.highwatermark = hwm
        req.uptodateness_vector = udv

        if replica_flags is not None:
            req.replica_flags = replica_flags
        elif exop == drsuapi.DRSUAPI_EXOP_REPL_SECRET:
            req.replica_flags = 0
        else:
            req.replica_flags = (drsuapi.DRSUAPI_DRS_INIT_SYNC
                                 | drsuapi.DRSUAPI_DRS_PER_SYNC
                                 | drsuapi.DRSUAPI_DRS_GET_ANC
                                 | drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
                                 drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
            if rodc:
                req.replica_flags |= (
                    drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
            else:
                req.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP

        if sync_forced:
            req.replica_flags |= drsuapi.DRSUAPI_DRS_SYNC_FORCED

        req.max_object_count = 402
        req.max_ndr_size = 402116
        req.extended_op = exop
        req.fsmo_info = 0
        req.partial_attribute_set = None
        req.partial_attribute_set_ex = None
        req.mapping_ctr.num_mappings = 0
        req.mapping_ctr.mappings = None

        if not schema and rodc:
            req.partial_attribute_set = drs_get_rodc_partial_attribute_set(
                self.samdb)

        if not self.supports_ext & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
            req_level = 5
            req5 = drsuapi.DsGetNCChangesRequest5()
            for a in dir(req5):
                if a[0] != '_':
                    setattr(req5, a, getattr(req, a))
            req = req5

        num_objects = 0
        num_links = 0
        first_chunk = True

        while True:
            (level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level,
                                                   req)
            if ctr.first_object is None and ctr.object_count != 0:
                raise RuntimeError(
                    "DsGetNCChanges: NULL first_object with object_count=%u" %
                    (ctr.object_count))

            try:
                self.process_chunk(level, ctr, schema, req_level, req,
                                   first_chunk)
            except WERRORError as e:
                # Check if retrying with the GET_TGT flag set might resolve this error
                if self._should_retry_with_get_tgt(e.args[0], req):

                    print("Missing target object - retrying with DRS_GET_TGT")
                    req.more_flags |= drsuapi.DRSUAPI_DRS_GET_TGT

                    # try sending the request again (this has the side-effect
                    # of causing the DC to restart the replication from scratch)
                    first_chunk = True
                    continue
                else:
                    raise e

            first_chunk = False
            num_objects += ctr.object_count

            # Cope with servers that do not return level 6, so do not return any links
            try:
                num_links += ctr.linked_attributes_count
            except AttributeError:
                pass

            if ctr.more_data == 0:
                break

            # update the request's HWM so we get the next chunk
            drs_copy_highwater_mark(req.highwatermark, ctr.new_highwatermark)

        return (num_objects, num_links)