/* * add any missing repsFrom structures to our partitions */ static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ctx, struct repsFromToBlob *reps, uint32_t count) { struct kccsrv_partition *p; /* update the repsFrom on all partitions */ for (p=s->partitions; p; p=p->next) { struct repsFromToBlob *old_reps; uint32_t old_count; WERROR werr; int i; bool modified = false; werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsFrom", &old_reps, &old_count); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,(__location__ ": Failed to load repsFrom from %s - %s\n", ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* add any new ones */ for (i=0; i<count; i++) { if (!reps_in_list(&reps[i], old_reps, old_count)) { old_reps = talloc_realloc(mem_ctx, old_reps, struct repsFromToBlob, old_count+1); NT_STATUS_HAVE_NO_MEMORY(old_reps); old_reps[old_count] = reps[i]; old_count++; modified = true; } } /* remove any stale ones */ for (i=0; i<old_count; i++) { if (!reps_in_list(&old_reps[i], reps, count)) { memmove(&old_reps[i], &old_reps[i+1], (old_count-(i+1))*sizeof(old_reps[0])); old_count--; i--; modified = true; } } if (modified) { werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsFrom", old_reps, old_count); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,(__location__ ": Failed to save repsFrom to %s - %s\n", ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } } }
/* 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; }