summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/kcc/kcc_drs_replica_info.c146
1 files changed, 142 insertions, 4 deletions
diff --git a/source4/dsdb/kcc/kcc_drs_replica_info.c b/source4/dsdb/kcc/kcc_drs_replica_info.c
index 8c1829343e..2ae72173a8 100644
--- a/source4/dsdb/kcc/kcc_drs_replica_info.c
+++ b/source4/dsdb/kcc/kcc_drs_replica_info.c
@@ -321,6 +321,137 @@ DONE:
return status;
}
+static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx,
+ struct ldb_context *samdb, struct ldb_dn *nc_dn,
+ struct drsuapi_DsReplicaNeighbour *neigh,
+ struct repsFromTo2 *reps_to)
+{
+ WERROR status;
+ char *dsa_guid_str;
+ int ret;
+ struct ldb_dn *source_dsa_dn;
+
+ neigh->source_dsa_address = reps_to->other_info->dns_name1;
+ neigh->replica_flags = reps_to->replica_flags;
+ neigh->last_attempt = reps_to->last_attempt;
+ neigh->source_dsa_obj_guid = reps_to->source_dsa_obj_guid;
+
+ dsa_guid_str = GUID_string(mem_ctx, &reps_to->source_dsa_obj_guid);
+ W_ERROR_HAVE_NO_MEMORY(dsa_guid_str);
+
+ ret = dsdb_find_dn_by_guid(samdb, mem_ctx, dsa_guid_str, &source_dsa_dn);
+ 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;
+ }
+
+ neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
+ neigh->naming_context_dn = ldb_dn_get_linearized(nc_dn);
+
+ ret = dsdb_find_guid_by_dn(samdb, nc_dn,
+ &neigh->naming_context_obj_guid);
+ 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;
+ }
+
+ /* If everything went fine so far, set the status to OK */
+ status = WERR_OK;
+ DONE: return status;
+}
+
+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)
+{
+ WERROR status;
+ int i, j, k;
+ 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;
+
+ i = j = 0;
+
+ /* foreach nc in ncs */
+ for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) {
+
+ nc_dn = p_nc_list->dn;
+
+ 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;
+ }
+
+ /* foreach r in nc!repsTo */
+ for (i_rep = 0; i_rep < c_reps_to; i_rep++) {
+
+ /* put all info on reps_from */
+ 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 */
+ 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*);
+
+ 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)
{
@@ -483,6 +614,7 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
switch (info_type) {
case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS:
+ 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);
@@ -505,9 +637,16 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
}
}
- status = kccdrs_replica_get_info_neighbours(mem_ctx, samdb, req,
- reply, base_index,
- req_src_dsa_guid, nc_list);
+ 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);
+ }
+
break;
case DRSUAPI_DS_REPLICA_INFO_CURSORS: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_FOR_NC */
@@ -525,7 +664,6 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
case DRSUAPI_DS_REPLICA_INFO_CURSORS3: /* On MS-DRSR it is DS_REPL_INFO_CURSORS_3_FOR_NC */
case DRSUAPI_DS_REPLICA_INFO_CURSORS05: /* On MS-DRSR it is DS_REPL_INFO_UPTODATE_VECTOR_V1 */
- case DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02: /* DS_REPL_INFO_REPSTO */
case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_OBJ */
case DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_OBJ */
case DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA: /* On MS-DRSR it is DS_REPL_INFO_METADATA_FOR_ATTR_VALUE */