s4-drs: DsReplGetInfo() for DS_REPL_INFO_REPSTO infoType
authorErick Nogueira do Nascimento <erick.nogueira.nascimento@gmail.com>
Fri, 29 Jan 2010 22:07:47 +0000 (20:07 -0200)
committerAndrew Tridgell <tridge@samba.org>
Mon, 15 Feb 2010 21:34:28 +0000 (08:34 +1100)
Implements the DS_REPL_INFO_REPSTO infoType of DsReplGetInfo().

source4/dsdb/kcc/kcc_drs_replica_info.c

index 8c1829343e1c63b6cbcdab7363af5ba8d4725ae8..2ae72173a8930671f795af3d3120f7193f3ce346 100644 (file)
@@ -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 */