/* get a list of our replication partners from repsFrom, returning it in *proxy_list */ static WERROR kdc_proxy_get_writeable_dcs(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, char ***proxy_list) { WERROR werr; uint32_t count, i; struct repsFromToBlob *reps; werr = dsdb_loadreps(kdc->samdb, mem_ctx, ldb_get_default_basedn(kdc->samdb), "repsFrom", &reps, &count); W_ERROR_NOT_OK_RETURN(werr); if (count == 0) { /* we don't have any DCs to replicate with. Very strange for a RODC */ DEBUG(1,(__location__ ": No replication sources for RODC in KDC proxy\n")); talloc_free(reps); return WERR_DS_DRA_NO_REPLICA; } (*proxy_list) = talloc_array(mem_ctx, char *, count+1); W_ERROR_HAVE_NO_MEMORY_AND_FREE(*proxy_list, reps); talloc_steal(*proxy_list, reps); for (i=0; i<count; i++) { const char *dns_name = NULL; if (reps->version == 1) { dns_name = reps->ctr.ctr1.other_info->dns_name; } else if (reps->version == 2) { dns_name = reps->ctr.ctr2.other_info->dns_name1; } (*proxy_list)[i] = talloc_strdup(*proxy_list, dns_name); W_ERROR_HAVE_NO_MEMORY_AND_FREE((*proxy_list)[i], *proxy_list); } (*proxy_list)[i] = NULL; talloc_free(reps); return WERR_OK; }
WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, const struct dsdb_schema *schema, const char *partition_dn_str, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, uint32_t object_count, const struct drsuapi_DsReplicaObjectListItemEx *first_object, uint32_t linked_attributes_count, const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes, const struct repsFromTo1 *source_dsa, const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector, const DATA_BLOB *gensec_skey, uint32_t dsdb_repl_flags, TALLOC_CTX *mem_ctx, struct dsdb_extended_replicated_objects **objects) { WERROR status; struct ldb_dn *partition_dn; struct dsdb_schema_prefixmap *pfm_remote; struct dsdb_extended_replicated_objects *out; const struct drsuapi_DsReplicaObjectListItemEx *cur; uint32_t i; out = talloc_zero(mem_ctx, struct dsdb_extended_replicated_objects); W_ERROR_HAVE_NO_MEMORY(out); out->version = DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION; out->dsdb_repl_flags = dsdb_repl_flags; /* * Ensure schema is kept valid for as long as 'out' * which may contain pointers to it */ schema = talloc_reference(out, schema); W_ERROR_HAVE_NO_MEMORY(schema); partition_dn = ldb_dn_new(out, ldb, partition_dn_str); W_ERROR_HAVE_NO_MEMORY_AND_FREE(partition_dn, out); status = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true, out, &pfm_remote, NULL); if (!W_ERROR_IS_OK(status)) { DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s", win_errstr(status))); talloc_free(out); return status; } if (ldb_dn_compare(partition_dn, ldb_get_schema_basedn(ldb)) != 0) { /* * check for schema changes in case * we are not replicating Schema NC */ status = dsdb_schema_info_cmp(schema, mapping_ctr); if (!W_ERROR_IS_OK(status)) { DEBUG(1,("Remote schema has changed while replicating %s\n", partition_dn_str)); talloc_free(out); return status; } } out->partition_dn = partition_dn; out->source_dsa = source_dsa; out->uptodateness_vector= uptodateness_vector; out->num_objects = object_count; out->objects = talloc_array(out, struct dsdb_extended_replicated_object, out->num_objects); W_ERROR_HAVE_NO_MEMORY_AND_FREE(out->objects, out); /* pass the linked attributes down to the repl_meta_data module */ out->linked_attributes_count = linked_attributes_count; out->linked_attributes = linked_attributes; for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { if (i == out->num_objects) { talloc_free(out); return WERR_FOOBAR; } status = dsdb_convert_object_ex(ldb, schema, pfm_remote, cur, gensec_skey, NULL, dsdb_repl_flags, out->objects, &out->objects[i]); if (!W_ERROR_IS_OK(status)) { talloc_free(out); DEBUG(0,("Failed to convert object %s: %s\n", cur->object.identifier->dn, win_errstr(status))); return status; } } if (i != out->num_objects) { talloc_free(out); return WERR_FOOBAR; } /* free pfm_remote, we won't need it anymore */ talloc_free(pfm_remote); *objects = out; return WERR_OK; }