2 Unix SMB/CIFS implementation.
4 DRS Replica Information
6 Copyright (C) Erick Nogueira do Nascimento 2009
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "dsdb/samdb/samdb.h"
25 #include "auth/auth.h"
26 #include "smbd/service.h"
27 #include "lib/events/events.h"
28 #include "lib/messaging/irpc.h"
29 #include "dsdb/kcc/kcc_service.h"
30 #include "lib/ldb/include/ldb_errors.h"
31 #include "../lib/util/dlinklist.h"
32 #include "librpc/gen_ndr/ndr_misc.h"
33 #include "librpc/gen_ndr/ndr_drsuapi.h"
34 #include "librpc/gen_ndr/ndr_drsblobs.h"
35 #include "param/param.h"
36 #include "dsdb/common/util.h"
39 get metadata for specified object
41 static WERROR kccdrs_replica_get_info_obj_metadata(TALLOC_CTX *mem_ctx,
42 struct ldb_context *samdb,
43 struct drsuapi_DsReplicaGetInfo *r,
44 union drsuapi_DsReplicaInfo *reply,
48 const struct ldb_val *md_value;
49 struct ldb_result *result;
50 enum ndr_err_code ndr_err;
51 struct replPropertyMetaDataBlob md;
52 const struct dsdb_schema *schema;
53 const char *attrs[] = { "replPropertyMetaData", NULL };
55 ret = dsdb_search_dn(samdb, mem_ctx, &result, dn, attrs, DSDB_SEARCH_SHOW_DELETED);
56 if (ret != LDB_SUCCESS) {
57 return WERR_INTERNAL_ERROR;
58 } else if (result->count < 1) {
59 DEBUG(1, (__location__": Failed to find replPropertyMetaData for: %s\n", r->in.req->req1.object_dn));
60 return WERR_INTERNAL_ERROR;
63 md_value = ldb_msg_find_ldb_val(result->msgs[0], "replPropertyMetaData");
65 return WERR_INTERNAL_ERROR;
68 ndr_err = ndr_pull_struct_blob(md_value, mem_ctx,
69 lp_iconv_convenience(ldb_get_opaque(samdb, "loadparm")),
71 (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob);
72 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
73 return WERR_INTERNAL_ERROR;
76 if (md.version != 1) {
77 return WERR_INTERNAL_ERROR;
80 schema = dsdb_get_schema(samdb);
82 DEBUG(0,(__location__": Failed to get the schema\n"));
83 return WERR_INTERNAL_ERROR;
86 reply->objmetadata = talloc(mem_ctx, struct drsuapi_DsReplicaObjMetaDataCtr);
87 W_ERROR_HAVE_NO_MEMORY(reply->objmetadata);
89 reply->objmetadata->reserved = 0;
90 reply->objmetadata->count = md.ctr.ctr1.count;
91 reply->objmetadata->array = talloc_array(mem_ctx, struct drsuapi_DsReplicaObjMetaData, reply->objmetadata->count);
92 for (i=0; i<md.ctr.ctr1.count; i++) {
93 const struct dsdb_attribute *attr = dsdb_attribute_by_attributeID_id(schema, md.ctr.ctr1.array[i].attid);
94 char const* attribute_name = NULL;
96 DEBUG(0, (__location__": Failed to find attribute with id: %d", md.ctr.ctr1.array[i].attid));
98 attribute_name = attr->lDAPDisplayName;
100 reply->objmetadata->array[i].originating_change_time = md.ctr.ctr1.array[i].originating_change_time;
101 reply->objmetadata->array[i].version = md.ctr.ctr1.array[i].version;
102 reply->objmetadata->array[i].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id;
103 reply->objmetadata->array[i].originating_usn = md.ctr.ctr1.array[i].originating_usn;
104 reply->objmetadata->array[i].local_usn = md.ctr.ctr1.array[i].local_usn;
105 reply->objmetadata->array[i].attribute_name = attribute_name;
112 get cursors info for a specified DN
114 static WERROR kccdrs_replica_get_info_cursors(TALLOC_CTX *mem_ctx,
115 struct ldb_context *samdb,
116 struct drsuapi_DsReplicaGetInfo *r,
117 union drsuapi_DsReplicaInfo *reply,
122 if (!ldb_dn_validate(dn)) {
123 return WERR_INVALID_PARAMETER;
125 reply->cursors = talloc(mem_ctx, struct drsuapi_DsReplicaCursorCtr);
126 W_ERROR_HAVE_NO_MEMORY(reply->cursors);
128 reply->cursors->reserved = 0;
130 ret = dsdb_load_udv_v1(samdb, dn, reply->cursors, &reply->cursors->array, &reply->cursors->count);
131 if (ret != LDB_SUCCESS) {
132 return WERR_DS_DRA_BAD_NC;
138 get cursors2 info for a specified DN
140 static WERROR kccdrs_replica_get_info_cursors2(TALLOC_CTX *mem_ctx,
141 struct ldb_context *samdb,
142 struct drsuapi_DsReplicaGetInfo *r,
143 union drsuapi_DsReplicaInfo *reply,
148 if (!ldb_dn_validate(dn)) {
149 return WERR_INVALID_PARAMETER;
151 reply->cursors2 = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2Ctr);
152 W_ERROR_HAVE_NO_MEMORY(reply->cursors2);
154 ret = dsdb_load_udv_v2(samdb, dn, reply->cursors2, &reply->cursors2->array, &reply->cursors2->count);
155 if (ret != LDB_SUCCESS) {
156 return WERR_DS_DRA_BAD_NC;
159 reply->cursors2->enumeration_context = reply->cursors2->count;
164 get pending ops info for a specified DN
166 static WERROR kccdrs_replica_get_info_pending_ops(TALLOC_CTX *mem_ctx,
167 struct ldb_context *samdb,
168 struct drsuapi_DsReplicaGetInfo *r,
169 union drsuapi_DsReplicaInfo *reply,
172 struct timeval now = timeval_current();
174 if (!ldb_dn_validate(dn)) {
175 return WERR_INVALID_PARAMETER;
177 reply->pendingops = talloc(mem_ctx, struct drsuapi_DsReplicaOpCtr);
178 W_ERROR_HAVE_NO_MEMORY(reply->pendingops);
180 /* claim no pending ops for now */
181 reply->pendingops->time = timeval_to_nttime(&now);
182 reply->pendingops->count = 0;
183 reply->pendingops->array = NULL;
190 struct ncList *prev, *next;
194 Fill 'master_nc_list' with the master ncs hosted by this server
196 static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
197 const char *ntds_guid_str, struct ncList **master_nc_list)
199 const char *attrs[] = { "hasMasterNCs", NULL };
200 struct ldb_result *res;
201 struct ncList *nc_list = NULL;
202 struct ncList *nc_list_elem;
207 ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb),
208 LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str);
210 if (ret != LDB_SUCCESS) {
211 DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb)));
212 return WERR_INTERNAL_ERROR;
215 if (res->count == 0) {
216 DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str));
217 return WERR_INTERNAL_ERROR;
220 for (i = 0; i < res->count; i++) {
221 struct ldb_message_element *msg_elem = ldb_msg_find_element(res->msgs[i], "hasMasterNCs");
224 if (!msg_elem || msg_elem->num_values == 0) {
225 DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n",
226 ldb_errstring(samdb)));
227 return WERR_INTERNAL_ERROR;
230 for (k = 0; k < msg_elem->num_values; k++) {
231 int len = msg_elem->values[k].length;
233 /* copy the string on msg_elem->values[k]->data to nc_str */
234 nc_str = talloc_array(mem_ctx, char, len);
235 W_ERROR_HAVE_NO_MEMORY(nc_str);
236 memcpy(nc_str, msg_elem->values[k].data, len);
239 nc_list_elem = talloc_zero(mem_ctx, struct ncList);
240 W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
241 nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str);
242 W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
243 DLIST_ADD(nc_list, nc_list_elem);
248 *master_nc_list = nc_list;
253 Fill 'nc_list' with the ncs list. (MS-DRSR 4.1.13.3)
254 if the object dn is specified, fill 'nc_list' only with this dn
255 otherwise, fill 'nc_list' with all master ncs hosted by this server
257 static WERROR get_ncs_list(TALLOC_CTX *mem_ctx,
258 struct ldb_context *samdb,
259 struct kccsrv_service *service,
260 const char *object_dn_str,
261 struct ncList **nc_list)
264 struct ncList *nc_list_elem;
265 struct ldb_dn *nc_dn;
267 if (object_dn_str != NULL) {
268 /* ncs := { object_dn } */
270 nc_dn = ldb_dn_new(mem_ctx, samdb, object_dn_str);
271 nc_list_elem = talloc_zero(mem_ctx, struct ncList);
272 W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
273 nc_list_elem->dn = nc_dn;
274 DLIST_ADD_END(*nc_list, nc_list_elem, struct ncList*);
276 /* ncs := getNCs() from ldb database.
277 * getNCs() must return an array containing
278 * the DSNames of all NCs hosted by this
281 char *ntds_guid_str = GUID_string(mem_ctx, &service->ntds_guid);
282 W_ERROR_HAVE_NO_MEMORY(ntds_guid_str);
283 status = get_master_ncs(mem_ctx, samdb, ntds_guid_str, nc_list);
284 W_ERROR_NOT_OK_RETURN(status);
291 Copy the fields from 'reps1' to 'reps2', leaving zeroed the fields on
292 'reps2' that aren't available on 'reps1'.
294 static WERROR copy_repsfrom_1_to_2(TALLOC_CTX *mem_ctx,
295 struct repsFromTo2 **reps2,
296 struct repsFromTo1 *reps1)
298 struct repsFromTo2* reps;
300 reps = talloc_zero(mem_ctx, struct repsFromTo2);
301 W_ERROR_HAVE_NO_MEMORY(reps);
303 reps->blobsize = reps1->blobsize;
304 reps->consecutive_sync_failures = reps1->consecutive_sync_failures;
305 reps->last_attempt = reps1->last_attempt;
306 reps->last_success = reps1->last_success;
307 reps->other_info = talloc_zero(mem_ctx, struct repsFromTo2OtherInfo);
308 W_ERROR_HAVE_NO_MEMORY(reps->other_info);
309 reps->other_info->dns_name1 = reps1->other_info->dns_name;
310 reps->replica_flags = reps1->replica_flags;
311 memcpy(reps->schedule, reps1->schedule, sizeof(reps1->schedule));
312 reps->reserved = reps1->reserved;
313 reps->highwatermark = reps1->highwatermark;
314 reps->source_dsa_obj_guid = reps1->source_dsa_obj_guid;
315 reps->source_dsa_invocation_id = reps1->source_dsa_invocation_id;
316 reps->transport_guid = reps1->transport_guid;
322 static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
323 struct ldb_context *samdb,
324 struct ldb_dn *nc_dn,
325 struct drsuapi_DsReplicaNeighbour *neigh,
326 struct repsFromTo2 *reps_from)
328 struct ldb_dn *source_dsa_dn;
330 struct ldb_dn *transport_obj_dn = NULL;
332 neigh->source_dsa_address = reps_from->other_info->dns_name1;
333 neigh->replica_flags = reps_from->replica_flags;
334 neigh->last_attempt = reps_from->last_attempt;
335 neigh->source_dsa_obj_guid = reps_from->source_dsa_obj_guid;
337 ret = dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_from->source_dsa_obj_guid, &source_dsa_dn);
339 if (ret != LDB_SUCCESS) {
340 DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n",
341 GUID_string(mem_ctx, &reps_from->source_dsa_obj_guid)));
342 return WERR_DS_DRA_INTERNAL_ERROR;
345 neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
346 neigh->naming_context_dn = ldb_dn_get_linearized(nc_dn);
348 if (dsdb_find_guid_by_dn(samdb, nc_dn, &neigh->naming_context_obj_guid)
350 return WERR_DS_DRA_INTERNAL_ERROR;
353 if (!GUID_all_zero(&reps_from->transport_guid)) {
354 if (dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_from->transport_guid,
355 &transport_obj_dn) != LDB_SUCCESS)
357 return WERR_DS_DRA_INTERNAL_ERROR;
361 neigh->transport_obj_dn = ldb_dn_get_linearized(transport_obj_dn);
362 neigh->source_dsa_invocation_id = reps_from->source_dsa_invocation_id;
363 neigh->transport_obj_guid = reps_from->transport_guid;
364 neigh->highest_usn = reps_from->highwatermark.highest_usn;
365 neigh->tmp_highest_usn = reps_from->highwatermark.tmp_highest_usn;
366 neigh->last_success = reps_from->last_success;
367 neigh->result_last_attempt = reps_from->result_last_attempt;
368 neigh->consecutive_sync_failures = reps_from->consecutive_sync_failures;
369 neigh->reserved = 0; /* Unused. MUST be 0. */
375 Get the inbound neighbours of this DC
376 See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_NEIGHBORS
378 static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
379 struct kccsrv_service *service,
380 struct ldb_context *samdb,
381 struct drsuapi_DsReplicaGetInfo *r,
382 union drsuapi_DsReplicaInfo *reply,
384 struct GUID req_src_dsa_guid,
385 const char *object_dn_str)
389 struct ldb_dn *nc_dn = NULL;
390 struct ncList *p_nc_list = NULL;
391 struct repsFromToBlob *reps_from_blob = NULL;
392 struct repsFromTo2 *reps_from = NULL;
393 uint32_t c_reps_from;
395 struct drsuapi_DsReplicaNeighbour neigh;
396 struct ncList *nc_list = NULL;
398 status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list);
399 W_ERROR_NOT_OK_RETURN(status);
403 reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr);
404 W_ERROR_HAVE_NO_MEMORY(reply->neighbours);
405 reply->neighbours->reserved = 0;
406 reply->neighbours->count = 0;
408 /* foreach nc in ncs */
409 for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) {
411 nc_dn = p_nc_list->dn;
413 /* load the nc's repsFromTo blob */
414 status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsFrom",
415 &reps_from_blob, &c_reps_from);
416 W_ERROR_NOT_OK_RETURN(status);
418 /* foreach r in nc!repsFrom */
419 for (i_rep = 0; i_rep < c_reps_from; i_rep++) {
421 /* put all info on reps_from */
422 if (reps_from_blob[i_rep].version == 1) {
423 status = copy_repsfrom_1_to_2(mem_ctx, &reps_from,
424 &reps_from_blob[i_rep].ctr.ctr1);
425 W_ERROR_NOT_OK_RETURN(status);
426 } else { /* reps_from->version == 2 */
427 reps_from = &reps_from_blob[i_rep].ctr.ctr2;
430 if (GUID_all_zero(&req_src_dsa_guid) ||
431 GUID_compare(&req_src_dsa_guid, &reps_from->source_dsa_obj_guid) == 0)
434 if (i >= base_index) {
435 status = fill_neighbor_from_repsFrom(mem_ctx, samdb,
438 W_ERROR_NOT_OK_RETURN(status);
440 /* append the neighbour to the neighbours array */
441 reply->neighbours->array = talloc_realloc(mem_ctx,
442 reply->neighbours->array,
443 struct drsuapi_DsReplicaNeighbour,
444 reply->neighbours->count + 1);
445 reply->neighbours->array[reply->neighbours->count++] = neigh;
457 static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx,
458 struct ldb_context *samdb, struct ldb_dn *nc_dn,
459 struct drsuapi_DsReplicaNeighbour *neigh,
460 struct repsFromTo2 *reps_to)
463 struct ldb_dn *source_dsa_dn;
465 neigh->source_dsa_address = reps_to->other_info->dns_name1;
466 neigh->replica_flags = reps_to->replica_flags;
467 neigh->last_attempt = reps_to->last_attempt;
468 neigh->source_dsa_obj_guid = reps_to->source_dsa_obj_guid;
470 ret = dsdb_find_dn_by_guid(samdb, mem_ctx, &reps_to->source_dsa_obj_guid, &source_dsa_dn);
471 if (ret != LDB_SUCCESS) {
472 DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n",
473 GUID_string(mem_ctx, &reps_to->source_dsa_obj_guid)));
474 return WERR_DS_DRA_INTERNAL_ERROR;
477 neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
478 neigh->naming_context_dn = ldb_dn_get_linearized(nc_dn);
480 ret = dsdb_find_guid_by_dn(samdb, nc_dn,
481 &neigh->naming_context_obj_guid);
482 if (ret != LDB_SUCCESS) {
483 DEBUG(0,(__location__ ": Failed to find GUID for DN %s\n",
484 ldb_dn_get_linearized(nc_dn)));
485 return WERR_DS_DRA_INTERNAL_ERROR;
492 Get the outbound neighbours of this DC
493 See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_REPSTO
495 static WERROR kccdrs_replica_get_info_repsto(TALLOC_CTX *mem_ctx,
496 struct kccsrv_service *service,
497 struct ldb_context *samdb,
498 struct drsuapi_DsReplicaGetInfo *r,
499 union drsuapi_DsReplicaInfo *reply,
501 struct GUID req_src_dsa_guid,
502 const char *object_dn_str)
506 struct ncList *p_nc_list = NULL;
507 struct ldb_dn *nc_dn = NULL;
508 struct repsFromToBlob *reps_to_blob;
509 struct repsFromTo2 *reps_to;
512 struct drsuapi_DsReplicaNeighbour neigh;
513 struct ncList *nc_list = NULL;
515 status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list);
516 W_ERROR_NOT_OK_RETURN(status);
520 reply->repsto = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr);
521 W_ERROR_HAVE_NO_MEMORY(reply->repsto);
522 reply->repsto->reserved = 0;
523 reply->repsto->count = 0;
525 /* foreach nc in ncs */
526 for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) {
528 nc_dn = p_nc_list->dn;
530 status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsTo",
531 &reps_to_blob, &c_reps_to);
532 W_ERROR_NOT_OK_RETURN(status);
534 /* foreach r in nc!repsTo */
535 for (i_rep = 0; i_rep < c_reps_to; i_rep++) {
537 /* put all info on reps_to */
538 if (reps_to_blob[i_rep].version == 1) {
539 status = copy_repsfrom_1_to_2(mem_ctx,
541 &reps_to_blob[i_rep].ctr.ctr1);
542 W_ERROR_NOT_OK_RETURN(status);
543 } else { /* reps_to->version == 2 */
544 reps_to = &reps_to_blob[i_rep].ctr.ctr2;
547 if (i >= base_index) {
548 status = fill_neighbor_from_repsTo(mem_ctx,
551 W_ERROR_NOT_OK_RETURN(status);
553 /* append the neighbour to the neighbours array */
554 reply->repsto->array = talloc_realloc(mem_ctx,
555 reply->repsto->array,
556 struct drsuapi_DsReplicaNeighbour,
557 reply->repsto->count + 1);
558 reply->repsto->array[reply->repsto->count++] = neigh;
568 NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
569 struct drsuapi_DsReplicaGetInfo *req)
572 struct drsuapi_DsReplicaGetInfoRequest1 *req1;
573 struct drsuapi_DsReplicaGetInfoRequest2 *req2;
575 union drsuapi_DsReplicaInfo *reply;
576 struct GUID req_src_dsa_guid;
577 const char *object_dn_str = NULL;
578 struct kccsrv_service *service;
579 struct ldb_context *samdb;
581 enum drsuapi_DsReplicaInfoType info_type;
583 service = talloc_get_type(msg->private_data, struct kccsrv_service);
584 samdb = service->samdb;
585 mem_ctx = talloc_new(msg);
586 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
588 NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaGetInfo, req);
590 /* check request version */
591 if (req->in.level != DRSUAPI_DS_REPLICA_GET_INFO &&
592 req->in.level != DRSUAPI_DS_REPLICA_GET_INFO2)
594 DEBUG(1,(__location__ ": Unsupported DsReplicaGetInfo level %u\n",
596 status = WERR_REVISION_MISMATCH;
600 if (req->in.level == DRSUAPI_DS_REPLICA_GET_INFO) {
601 req1 = &req->in.req->req1;
603 info_type = req1->info_type;
604 object_dn_str = req1->object_dn;
605 req_src_dsa_guid = req1->guid1;
607 } else { /* r->in.level == DRSUAPI_DS_REPLICA_GET_INFO2 */
608 req2 = &req->in.req->req2;
609 if (req2->enumeration_context == 0xffffffff) {
610 /* no more data is available */
611 status = WERR_NO_MORE_ITEMS; /* on MS-DRSR it is ERROR_NO_MORE_ITEMS */
615 base_index = req2->enumeration_context;
616 info_type = req2->info_type;
617 object_dn_str = req2->object_dn;
618 req_src_dsa_guid = req2->guid1;
621 /* allocate the reply and fill in some fields */
622 reply = talloc_zero(mem_ctx, union drsuapi_DsReplicaInfo);
623 NT_STATUS_HAVE_NO_MEMORY(reply);
624 req->out.info = reply;
625 req->out.info_type = talloc(mem_ctx, enum drsuapi_DsReplicaInfoType);
626 NT_STATUS_HAVE_NO_MEMORY(req->out.info_type);
627 *req->out.info_type = info_type;
629 /* Based on the infoType requested, retrieve the corresponding
630 * information and construct the response message */
633 case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS:
634 status = kccdrs_replica_get_info_neighbours(mem_ctx, service, samdb, req,
635 reply, base_index, req_src_dsa_guid,
638 case DRSUAPI_DS_REPLICA_INFO_REPSTO: /* On MS-DRSR it is DS_REPL_INFO_REPSTO */
639 status = kccdrs_replica_get_info_repsto(mem_ctx, service, samdb, req,
640 reply, base_index, req_src_dsa_guid,
643 case DRSUAPI_DS_REPLICA_INFO_CURSORS: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_FOR_NC */
644 status = kccdrs_replica_get_info_cursors(mem_ctx, samdb, req, reply,
645 ldb_dn_new(mem_ctx, samdb, object_dn_str));
647 case DRSUAPI_DS_REPLICA_INFO_CURSORS2: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_2_FOR_NC */
648 status = kccdrs_replica_get_info_cursors2(mem_ctx, samdb, req, reply,
649 ldb_dn_new(mem_ctx, samdb, object_dn_str));
651 case DRSUAPI_DS_REPLICA_INFO_PENDING_OPS: /* On MS-DRSR it is DS_REPL_INFO_PENDING_OPS */
652 status = kccdrs_replica_get_info_pending_ops(mem_ctx, samdb, req, reply,
653 ldb_dn_new(mem_ctx, samdb, object_dn_str));
656 case DRSUAPI_DS_REPLICA_INFO_CURSORS3: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_3_FOR_NC */
657 case DRSUAPI_DS_REPLICA_INFO_UPTODATE_VECTOR_V1: /* On MS-DRSR it is DS_REPL_INFO_UPTODATE_VECTOR_V1 */
658 case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_OBJ */
659 status = kccdrs_replica_get_info_obj_metadata(mem_ctx, samdb, req, reply,
660 ldb_dn_new(mem_ctx, samdb, object_dn_str));
662 case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_OBJ */
663 case DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_ATTR_VALUE */
664 case DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2: /* On MS-DRSR it is DS_REPL_INFO_METADATA_2_FOR_ATTR_VALUE */
665 case DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES: /* On MS-DRSR it is DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES */
666 case DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES: /* On MS-DRSR it is DS_REPL_INFO_KCC_LINK_FAILURES */
667 case DRSUAPI_DS_REPLICA_INFO_CLIENT_CONTEXTS: /* On MS-DRSR it is DS_REPL_INFO_CLIENT_CONTEXTS */
668 case DRSUAPI_DS_REPLICA_INFO_SERVER_OUTGOING_CALLS: /* On MS-DRSR it is DS_REPL_INFO_SERVER_OUTGOING_CALLS */
670 DEBUG(1,(__location__ ": Unsupported DsReplicaGetInfo info_type %u\n",
672 status = WERR_INVALID_LEVEL;
677 /* put the status on the result field of the reply */
678 req->out.result = status;
679 NDR_PRINT_OUT_DEBUG(drsuapi_DsReplicaGetInfo, req);