From 23d1dd5189e0662efb532c31b26c71434a00cff4 Mon Sep 17 00:00:00 2001 From: Erick Nogueira do Nascimento Date: Thu, 11 Feb 2010 19:04:00 -0200 Subject: [PATCH] s4-drs: DsGetReplInfo() refactoring --- source4/dsdb/kcc/kcc_drs_replica_info.c | 453 ++++++++++-------------- source4/torture/rpc/dsgetinfo.c | 19 +- 2 files changed, 205 insertions(+), 267 deletions(-) diff --git a/source4/dsdb/kcc/kcc_drs_replica_info.c b/source4/dsdb/kcc/kcc_drs_replica_info.c index 2ae72173a8..da89a470a3 100644 --- a/source4/dsdb/kcc/kcc_drs_replica_info.c +++ b/source4/dsdb/kcc/kcc_drs_replica_info.c @@ -112,17 +112,112 @@ static WERROR kccdrs_replica_get_info_pending_ops(TALLOC_CTX *mem_ctx, return WERR_OK; } - struct ncList { struct ldb_dn *dn; struct ncList *prev, *next; }; -struct neighList { - struct drsuapi_DsReplicaNeighbour *neigh; - struct neighList *prev, *next; -}; +/* + Fill 'master_nc_list' with the master ncs hosted by this server +*/ +static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb, + const char *ntds_guid_str, struct ncList **master_nc_list) +{ + const char *attrs[] = { "hasMasterNCs", NULL }; + struct ldb_result *res; + struct ncList *nc_list = NULL; + struct ncList *nc_list_elem; + int ret; + int i; + char *nc_str; + + ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb), + LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str); + + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb))); + return WERR_INTERNAL_ERROR; + } + + if (res->count == 0) { + DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str)); + return WERR_INTERNAL_ERROR; + } + + for (i = 0; i < res->count; i++) { + struct ldb_message_element *msg_elem = ldb_msg_find_element(res->msgs[i], "hasMasterNCs"); + int k; + + if (!msg_elem || msg_elem->num_values == 0) { + DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n", + ldb_errstring(samdb))); + return WERR_INTERNAL_ERROR; + } + + for (k = 0; k < msg_elem->num_values; k++) { + int len = msg_elem->values[k].length; + + /* copy the string on msg_elem->values[k]->data to nc_str */ + nc_str = talloc_array(mem_ctx, char, len); + W_ERROR_HAVE_NO_MEMORY(nc_str); + memcpy(nc_str, msg_elem->values[k].data, len); + nc_str[len] = '\0'; + + nc_list_elem = talloc_zero(mem_ctx, struct ncList); + W_ERROR_HAVE_NO_MEMORY(nc_list_elem); + nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str); + W_ERROR_HAVE_NO_MEMORY(nc_list_elem); + DLIST_ADD(nc_list, nc_list_elem); + } + + } + + *master_nc_list = nc_list; + return WERR_OK; +} + +/* + Fill 'nc_list' with the ncs list. (MS-DRSR 4.1.13.3) + if the object dn is specified, fill 'nc_list' only with this dn + otherwise, fill 'nc_list' with all master ncs hosted by this server +*/ +static WERROR get_ncs_list(TALLOC_CTX *mem_ctx, + struct ldb_context *samdb, + struct kccsrv_service *service, + const char *object_dn_str, + struct ncList **nc_list) +{ + WERROR status; + struct ncList *nc_list_elem; + struct ldb_dn *nc_dn; + + if (object_dn_str != NULL) { + /* ncs := { object_dn } */ + *nc_list = NULL; + nc_dn = ldb_dn_new(mem_ctx, samdb, object_dn_str); + nc_list_elem = talloc_zero(mem_ctx, struct ncList); + W_ERROR_HAVE_NO_MEMORY(nc_list_elem); + nc_list_elem->dn = nc_dn; + DLIST_ADD_END(*nc_list, nc_list_elem, struct ncList*); + } else { + /* ncs := getNCs() from ldb database. + * getNCs() must return an array containing + * the DSNames of all NCs hosted by this + * server. + */ + char *ntds_guid_str = GUID_string(mem_ctx, &service->ntds_guid); + W_ERROR_HAVE_NO_MEMORY(ntds_guid_str); + status = get_master_ncs(mem_ctx, samdb, ntds_guid_str, nc_list); + W_ERROR_NOT_OK_RETURN(status); + } + + return WERR_OK; +} +/* + Copy the fields from 'reps1' to 'reps2', leaving zeroed the fields on + 'reps2' that aren't available on 'reps1'. +*/ static WERROR copy_repsfrom_1_to_2(TALLOC_CTX *mem_ctx, struct repsFromTo2 **reps2, struct repsFromTo1 *reps1) @@ -157,7 +252,6 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaNeighbour *neigh, struct repsFromTo2 *reps_from) { - WERROR status; struct ldb_dn *source_dsa_dn; int ret; char *dsa_guid_str; @@ -175,8 +269,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx, if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n", dsa_guid_str)); - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; + return WERR_DS_DRA_INTERNAL_ERROR; } neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn); @@ -184,8 +277,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx, if (dsdb_find_guid_by_dn(samdb, nc_dn, &neigh->naming_context_obj_guid) != LDB_SUCCESS) { - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; + return WERR_DS_DRA_INTERNAL_ERROR; } if (!GUID_all_zero(&reps_from->transport_guid)) { @@ -194,8 +286,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx, if (dsdb_find_dn_by_guid(samdb, mem_ctx, transp_guid_str, &transport_obj_dn) != LDB_SUCCESS) { - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; + return WERR_DS_DRA_INTERNAL_ERROR; } } @@ -209,42 +300,42 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx, neigh->consecutive_sync_failures = reps_from->consecutive_sync_failures; neigh->reserved = 0; /* Unused. MUST be 0. */ - /* If everything went fine so far, set the status to OK */ - status = WERR_OK; -DONE: - return status; + return WERR_OK; } /* - * See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_NEIGHBORS - * */ + Get the inbound neighbours of this DC + See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_NEIGHBORS +*/ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx, + struct kccsrv_service *service, struct ldb_context *samdb, struct drsuapi_DsReplicaGetInfo *r, union drsuapi_DsReplicaInfo *reply, int base_index, struct GUID req_src_dsa_guid, - struct ncList *nc_list) + const char *object_dn_str) { WERROR status; - - int i, j, k; + int i, j; struct ldb_dn *nc_dn = NULL; struct ncList *p_nc_list = NULL; - struct repsFromToBlob *reps_from_blob = NULL; struct repsFromTo2 *reps_from = NULL; uint32_t c_reps_from; - int i_rep; + struct drsuapi_DsReplicaNeighbour neigh; + struct ncList *nc_list = NULL; - struct neighList *neigh_list = NULL; - struct neighList *neigh_elem = NULL; - - struct drsuapi_DsReplicaNeighbour *neigh = NULL; + status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list); + W_ERROR_NOT_OK_RETURN(status); i = j = 0; - neigh_list = NULL; + + reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr); + W_ERROR_HAVE_NO_MEMORY(reply->neighbours); + reply->neighbours->reserved = 0; + reply->neighbours->count = 0; /* foreach nc in ncs */ for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) { @@ -254,10 +345,7 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx, /* load the nc's repsFromTo blob */ status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsFrom", &reps_from_blob, &c_reps_from); - if (!W_ERROR_IS_OK(status)) { - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; - } + W_ERROR_NOT_OK_RETURN(status); /* foreach r in nc!repsFrom */ for (i_rep = 0; i_rep < c_reps_from; i_rep++) { @@ -266,9 +354,7 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx, if (reps_from_blob[i_rep].version == 1) { status = copy_repsfrom_1_to_2(mem_ctx, &reps_from, &reps_from_blob[i_rep].ctr.ctr1); - if (!W_ERROR_IS_OK(status)) { - goto DONE; - } + W_ERROR_NOT_OK_RETURN(status); } else { /* reps_from->version == 2 */ reps_from = &reps_from_blob[i_rep].ctr.ctr2; } @@ -278,22 +364,17 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx, { if (i >= base_index) { - neigh = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbour); - W_ERROR_HAVE_NO_MEMORY(neigh); - status = fill_neighbor_from_repsFrom(mem_ctx, samdb, - nc_dn, neigh, + nc_dn, &neigh, reps_from); - if (!W_ERROR_IS_OK(status)) { - goto DONE; - } - - /* append the neighbor to neigh_list */ - neigh_elem = talloc_zero(mem_ctx, struct neighList); - W_ERROR_HAVE_NO_MEMORY(neigh_elem); - neigh_elem->neigh = neigh; - DLIST_ADD_END(neigh_list, neigh_elem, struct neighList*); - + W_ERROR_NOT_OK_RETURN(status); + + /* append the neighbour to the neighbours array */ + reply->neighbours->array = talloc_realloc(mem_ctx, + reply->neighbours->array, + struct drsuapi_DsReplicaNeighbour, + reply->neighbours->count + 1); + reply->neighbours->array[reply->neighbours->count++] = neigh; j++; } @@ -302,23 +383,7 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx, } } - /* put all neighbours on neigh_list on reply->neighbours->array */ - reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr); - W_ERROR_HAVE_NO_MEMORY(reply->neighbours); - - reply->neighbours->count = j; - reply->neighbours->reserved = 0; - reply->neighbours->array = talloc_array(mem_ctx, struct drsuapi_DsReplicaNeighbour, j); - W_ERROR_HAVE_NO_MEMORY(reply->neighbours->array); - - for (k = 0; neigh_list != NULL; neigh_list = neigh_list->next, k++) { - reply->neighbours->array[k] = *neigh_list->neigh; - } - - /* If everything went fine so far, set the status to OK */ - status = WERR_OK; -DONE: - return status; + return WERR_OK; } static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx, @@ -326,7 +391,6 @@ static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaNeighbour *neigh, struct repsFromTo2 *reps_to) { - WERROR status; char *dsa_guid_str; int ret; struct ldb_dn *source_dsa_dn; @@ -343,8 +407,7 @@ static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx, if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n", dsa_guid_str)); - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; + return WERR_DS_DRA_INTERNAL_ERROR; } neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn); @@ -355,34 +418,46 @@ static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx, if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find GUID for DN %s\n", ldb_dn_get_linearized(nc_dn))); - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; + return WERR_DS_DRA_INTERNAL_ERROR; } - /* If everything went fine so far, set the status to OK */ - status = WERR_OK; - DONE: return status; + return WERR_OK; } +/* + Get the outbound neighbours of this DC + See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_REPSTO +*/ static WERROR kccdrs_replica_get_info_repsto(TALLOC_CTX *mem_ctx, - struct ldb_context *samdb, struct drsuapi_DsReplicaGetInfo *r, - union drsuapi_DsReplicaInfo *reply, int base_index, - struct GUID req_src_dsa_guid, struct ncList *nc_list) + struct kccsrv_service *service, + struct ldb_context *samdb, + struct drsuapi_DsReplicaGetInfo *r, + union drsuapi_DsReplicaInfo *reply, + int base_index, + struct GUID req_src_dsa_guid, + const char *object_dn_str) { WERROR status; - int i, j, k; + int i, j; struct ncList *p_nc_list = NULL; struct ldb_dn *nc_dn = NULL; struct repsFromToBlob *reps_to_blob; struct repsFromTo2 *reps_to; uint32_t c_reps_to; int i_rep; - struct drsuapi_DsReplicaNeighbour *neigh; - struct neighList *neigh_list = NULL; - struct neighList *neigh_elem = NULL; + struct drsuapi_DsReplicaNeighbour neigh; + struct ncList *nc_list = NULL; + + status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list); + W_ERROR_NOT_OK_RETURN(status); i = j = 0; + reply->neighbours02 = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr); + W_ERROR_HAVE_NO_MEMORY(reply->neighbours02); + reply->neighbours02->reserved = 0; + reply->neighbours02->count = 0; + /* foreach nc in ncs */ for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) { @@ -390,153 +465,56 @@ static WERROR kccdrs_replica_get_info_repsto(TALLOC_CTX *mem_ctx, status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsTo", &reps_to_blob, &c_reps_to); - if (!W_ERROR_IS_OK(status)) { - status = WERR_DS_DRA_INTERNAL_ERROR; - goto DONE; - } + W_ERROR_NOT_OK_RETURN(status); /* foreach r in nc!repsTo */ for (i_rep = 0; i_rep < c_reps_to; i_rep++) { - /* put all info on reps_from */ + /* put all info on reps_to */ if (reps_to_blob[i_rep].version == 1) { status = copy_repsfrom_1_to_2(mem_ctx, &reps_to, &reps_to_blob[i_rep].ctr.ctr1); - if (!W_ERROR_IS_OK(status)) { - goto DONE; - } - } else { /* reps_from->version == 2 */ + W_ERROR_NOT_OK_RETURN(status); + } else { /* reps_to->version == 2 */ reps_to = &reps_to_blob[i_rep].ctr.ctr2; } if (i >= base_index) { - neigh = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbour); - W_ERROR_HAVE_NO_MEMORY(neigh); - status = fill_neighbor_from_repsTo(mem_ctx, samdb, nc_dn, - neigh, reps_to); - if (!W_ERROR_IS_OK(status)) { - goto DONE; - } - - /* append the neighbor to neigh_list */ - neigh_elem = talloc_zero(mem_ctx, struct neighList); - W_ERROR_HAVE_NO_MEMORY(neigh_elem); - neigh_elem->neigh = neigh; - DLIST_ADD_END(neigh_list, neigh_elem, struct neighList*); - + &neigh, reps_to); + W_ERROR_NOT_OK_RETURN(status); + + /* append the neighbour to the neighbours array */ + reply->neighbours02->array = talloc_realloc(mem_ctx, + reply->neighbours02->array, + struct drsuapi_DsReplicaNeighbour, + reply->neighbours02->count + 1); + reply->neighbours02->array[reply->neighbours02->count++] = neigh; j++; } - i++; } } - /* put all neighbours on neigh_list on reply->neighbours->array */ - reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr); - W_ERROR_HAVE_NO_MEMORY(reply->neighbours); - - reply->neighbours->count = j; - reply->neighbours->reserved = 0; - reply->neighbours->array = talloc_array(mem_ctx, struct drsuapi_DsReplicaNeighbour, j); - W_ERROR_HAVE_NO_MEMORY(reply->neighbours->array); - - for (k = 0; neigh_list != NULL; neigh_list = neigh_list->next, k++) { - reply->neighbours->array[k] = *neigh_list->neigh; - } - - /* If everything went fine so far, set the status to OK */ - status = WERR_OK; - DONE: return status; -} - -static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb, - const char *ntds_guid_str, struct ncList **master_nc_list) -{ - WERROR status; - const char *attrs[] = { "hasMasterNCs", NULL }; - struct ldb_result *res; - struct ncList *nc_list = NULL; - struct ncList *nc_list_elem; - int ret; - int i; - char *nc_str; - - ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb), - LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str); - - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb))); - status = WERR_INTERNAL_ERROR; - goto DONE; - } - - if (res->count == 0) { - DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str)); - status = WERR_INTERNAL_ERROR; - goto DONE; - } - - for (i = 0; i < res->count; i++) { - - struct ldb_message_element *msg_elem = ldb_msg_find_element( - res->msgs[i], "hasMasterNCs"); - int k; - - if (!msg_elem || msg_elem->num_values == 0) { - DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n", - ldb_errstring(samdb))); - status = WERR_INTERNAL_ERROR; - goto DONE; - } - - for (k = 0; k < msg_elem->num_values; k++) { - int len = msg_elem->values[k].length; - - /* copy the string on msg_elem->values[k]->data to nc_str */ - nc_str = talloc_array(mem_ctx, char, len); - W_ERROR_HAVE_NO_MEMORY(nc_str); - memcpy(nc_str, msg_elem->values[k].data, len); - nc_str[len] = '\0'; - - nc_list_elem = talloc_zero(mem_ctx, struct ncList); - W_ERROR_HAVE_NO_MEMORY(nc_list_elem); - nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str); - W_ERROR_HAVE_NO_MEMORY(nc_list_elem); - DLIST_ADD(nc_list, nc_list_elem); - } - - } - - *master_nc_list = nc_list; - /* If everything went fine so far, set the status to OK */ - status = WERR_OK; -DONE: - return status; + return WERR_OK; } NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg, struct drsuapi_DsReplicaGetInfo *req) { WERROR status; - struct drsuapi_DsReplicaGetInfoRequest1 *req1; struct drsuapi_DsReplicaGetInfoRequest2 *req2; - enum drsuapi_DsReplicaInfoType info_type, *tmp_p_info_type; - int base_index; union drsuapi_DsReplicaInfo *reply; - struct GUID req_src_dsa_guid; - const char *object_dn = NULL; - struct ldb_dn *nc_dn = NULL; - struct ncList *nc_list = NULL, *nc_list_elem = NULL; - + const char *object_dn_str = NULL; struct kccsrv_service *service; struct ldb_context *samdb; TALLOC_CTX *mem_ctx; + enum drsuapi_DsReplicaInfoType info_type; service = talloc_get_type(msg->private_data, struct kccsrv_service); samdb = service->samdb; @@ -552,14 +530,14 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg, DEBUG(1,(__location__ ": Unsupported DsReplicaGetInfo level %u\n", req->in.level)); status = WERR_REVISION_MISMATCH; - goto DONE; + goto done; } if (req->in.level == DRSUAPI_DS_REPLICA_GET_INFO) { req1 = &req->in.req->req1; base_index = 0; info_type = req1->info_type; - object_dn = req1->object_dn; + object_dn_str = req1->object_dn; req_src_dsa_guid = req1->guid1; } else { /* r->in.level == DRSUAPI_DS_REPLICA_GET_INFO2 */ @@ -567,99 +545,48 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg, if (req2->enumeration_context == 0xffffffff) { /* no more data is available */ status = WERR_NO_MORE_ITEMS; /* on MS-DRSR it is ERROR_NO_MORE_ITEMS */ - goto DONE; + goto done; } base_index = req2->enumeration_context; info_type = req2->info_type; - object_dn = req2->object_dn; + object_dn_str = req2->object_dn; req_src_dsa_guid = req2->guid1; } - /* TODO: Perform the necessary access permission checking here according to the infoType requested */ - switch (info_type) { - case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS: - case DRSUAPI_DS_REPLICA_INFO_CURSORS: - case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA: - case DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES: - case DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES: - case DRSUAPI_DS_REPLICA_INFO_PENDING_OPS: - case DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA: - case DRSUAPI_DS_REPLICA_INFO_CURSORS2: - case DRSUAPI_DS_REPLICA_INFO_CURSORS3: - case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2: - case DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2: - case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02: - case DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04: - case DRSUAPI_DS_REPLICA_INFO_CURSORS05: - case DRSUAPI_DS_REPLICA_INFO_06: - break; - default: - DEBUG(0,(__location__ ": infoType %u requested is invalid.", (unsigned)info_type)); - status = WERR_INVALID_PARAMETER; /* infoType is invalid */ - goto DONE; - } - /* allocate the reply and fill in some fields */ reply = talloc_zero(mem_ctx, union drsuapi_DsReplicaInfo); NT_STATUS_HAVE_NO_MEMORY(reply); req->out.info = reply; - tmp_p_info_type = talloc(mem_ctx, enum drsuapi_DsReplicaInfoType); - NT_STATUS_HAVE_NO_MEMORY(tmp_p_info_type); - *tmp_p_info_type = info_type; - req->out.info_type = tmp_p_info_type; + req->out.info_type = talloc(mem_ctx, enum drsuapi_DsReplicaInfoType); + NT_STATUS_HAVE_NO_MEMORY(req->out.info_type); + *req->out.info_type = info_type; /* Based on the infoType requested, retrieve the corresponding * information and construct the response message */ switch (info_type) { case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS: + status = kccdrs_replica_get_info_neighbours(mem_ctx, service, samdb, req, + reply, base_index, req_src_dsa_guid, + object_dn_str); + break; case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02: /* On MS-DRSR it is DS_REPL_INFO_REPSTO */ - if (object_dn != NULL) { /* ncs := { object_dn } */ - nc_list = NULL; - nc_dn = ldb_dn_new(mem_ctx, samdb, object_dn); - nc_list_elem = talloc_zero(mem_ctx, struct ncList); - NT_STATUS_HAVE_NO_MEMORY(nc_list_elem); - nc_list_elem->dn = nc_dn; - DLIST_ADD_END(nc_list, nc_list_elem, struct ncList*); - - } else { - /* ncs := getNCs() from ldb database. - * getNCs() must return an array containing - * the DSNames of all NCs hosted by this - * server. - */ - char *ntds_guid_str = GUID_string(mem_ctx, &service->ntds_guid); - NT_STATUS_HAVE_NO_MEMORY(ntds_guid_str); - status = get_master_ncs(mem_ctx, samdb, ntds_guid_str, &nc_list); - if (!W_ERROR_IS_OK(status)) { - goto DONE; - } - } - - if (info_type == DRSUAPI_DS_REPLICA_INFO_NEIGHBORS) { - status = kccdrs_replica_get_info_neighbours(mem_ctx, samdb, req, - reply, base_index, - req_src_dsa_guid, nc_list); - } else { /* info_type == DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02 */ - status = kccdrs_replica_get_info_repsto(mem_ctx, samdb, req, - reply, base_index, - req_src_dsa_guid, nc_list); - } - + status = kccdrs_replica_get_info_repsto(mem_ctx, service, samdb, req, + reply, base_index, req_src_dsa_guid, + object_dn_str); break; - case DRSUAPI_DS_REPLICA_INFO_CURSORS: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_FOR_NC */ status = kccdrs_replica_get_info_cursors(mem_ctx, samdb, req, reply, - ldb_dn_new(mem_ctx, samdb, object_dn)); + ldb_dn_new(mem_ctx, samdb, object_dn_str)); break; case DRSUAPI_DS_REPLICA_INFO_CURSORS2: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_2_FOR_NC */ status = kccdrs_replica_get_info_cursors2(mem_ctx, samdb, req, reply, - ldb_dn_new(mem_ctx, samdb, object_dn)); + ldb_dn_new(mem_ctx, samdb, object_dn_str)); break; case DRSUAPI_DS_REPLICA_INFO_PENDING_OPS: /* On MS-DRSR it is DS_REPL_INFO_PENDING_OPS */ status = kccdrs_replica_get_info_pending_ops(mem_ctx, samdb, req, reply, - ldb_dn_new(mem_ctx, samdb, object_dn)); + ldb_dn_new(mem_ctx, samdb, object_dn_str)); break; case DRSUAPI_DS_REPLICA_INFO_CURSORS3: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_3_FOR_NC */ @@ -679,7 +606,7 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg, break; } -DONE: +done: /* put the status on the result field of the reply */ req->out.result = status; NDR_PRINT_OUT_DEBUG(drsuapi_DsReplicaGetInfo, req); diff --git a/source4/torture/rpc/dsgetinfo.c b/source4/torture/rpc/dsgetinfo.c index acad1a0916..03bda7e70e 100644 --- a/source4/torture/rpc/dsgetinfo.c +++ b/source4/torture/rpc/dsgetinfo.c @@ -172,6 +172,7 @@ static bool test_getinfo(struct torture_context *tctx, union drsuapi_DsReplicaInfo info; enum drsuapi_DsReplicaInfoType info_type; int i; + int invalid_levels = 0; struct { int32_t level; int32_t infotype; @@ -278,14 +279,24 @@ static bool test_getinfo(struct torture_context *tctx, r.out.info_type = &info_type; status = dcerpc_drsuapi_DsReplicaGetInfo(p, tctx, &r); - torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo"); - if (!NT_STATUS_IS_OK(status) && p->last_fault_code == DCERPC_FAULT_INVALID_TAG) { + + if (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL)) { + /* this is a not yet supported level */ + torture_comment(tctx, + "DsReplicaGetInfo level %d and/or infotype %d not yet supported by server\n", + array[i].level, array[i].infotype); + invalid_levels++; + } else if (!NT_STATUS_IS_OK(status) && p->last_fault_code == DCERPC_FAULT_INVALID_TAG) { torture_comment(tctx, "DsReplicaGetInfo level %d and/or infotype %d not supported by server\n", array[i].level, array[i].infotype); - } else { + }/* else { torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo"); - } + }*/ + } + + if (invalid_levels > 0) { + return false; } return true; -- 2.34.1