WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; static const char *attrs[] = { "namingContexts", NULL }; unsigned int i; int ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message_element *el; tmp_ctx = talloc_new(s); W_ERROR_HAVE_NO_MEMORY(tmp_ctx); ret = ldb_search(s->samdb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, s->samdb, ""), LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } el = ldb_msg_find_element(res->msgs[0], "namingContexts"); if (!el) { DEBUG(1,("Finding namingContexts element in root_res failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } for (i=0; i<el->num_values; i++) { struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); if (pdn == NULL) { talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (!ldb_dn_validate(pdn)) { return WERR_DS_DRA_INTERNAL_ERROR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); } talloc_free(tmp_ctx); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }
/** * Called when drplsrv should refresh its state. * For example, when KCC change topology, dreplsrv * should update its cache * * @param partition_dn If not empty/NULL, partition to update */ static NTSTATUS dreplsrv_refresh(struct irpc_message *msg, struct dreplsrv_refresh *r) { struct dreplsrv_service *s = talloc_get_type(msg->private_data, struct dreplsrv_service); r->out.result = dreplsrv_refresh_partitions(s); return NT_STATUS_OK; }
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; struct ldb_dn *basedn; struct ldb_result *r; struct ldb_message_element *el; static const char *attrs[] = { "namingContexts", NULL }; uint32_t i; int ret; basedn = ldb_dn_new(s, s->samdb, NULL); W_ERROR_HAVE_NO_MEMORY(basedn); ret = ldb_search(s->samdb, s, &r, basedn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); talloc_free(basedn); if (ret != LDB_SUCCESS) { return WERR_FOOBAR; } else if (r->count != 1) { talloc_free(r); return WERR_FOOBAR; } el = ldb_msg_find_element(r->msgs[0], "namingContexts"); if (!el) { return WERR_FOOBAR; } for (i=0; el && i < el->num_values; i++) { const char *v = (const char *)el->values[i].data; struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_new(s, s->samdb, v); if (!ldb_dn_validate(pdn)) { return WERR_FOOBAR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", v)); } talloc_free(r); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }
/* load the partitions list based on replicated NC attributes in our NTDSDSA object */ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; static const char *attrs[] = { "hasMasterNCs", "msDs-hasMasterNCs", "hasPartialReplicaNCs", "msDS-HasFullReplicaNCs", NULL }; unsigned int a; int ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message_element *el; struct ldb_dn *ntds_dn; tmp_ctx = talloc_new(s); W_ERROR_HAVE_NO_MEMORY(tmp_ctx); ntds_dn = samdb_ntds_settings_dn(s->samdb); if (!ntds_dn) { DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN); if (ret != LDB_SUCCESS) { DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } for (a=0; attrs[a]; a++) { int i; el = ldb_msg_find_element(res->msgs[0], attrs[a]); if (el == NULL) { continue; } for (i=0; i<el->num_values; i++) { struct ldb_dn *pdn; struct dreplsrv_partition *p, *tp; bool found; pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); if (pdn == NULL) { talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (!ldb_dn_validate(pdn)) { return WERR_DS_DRA_INTERNAL_ERROR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); p->service = s; if (strcasecmp(attrs[a], "hasPartialReplicaNCs") == 0) { p->partial_replica = true; } else if (strcasecmp(attrs[a], "msDS-HasFullReplicaNCs") == 0) { p->rodc_replica = true; } /* Do not add partitions more than once */ found = false; for (tp = s->partitions; tp; tp = tp->next) { if (ldb_dn_compare(tp->dn, p->dn) == 0) { found = true; break; } } if (found) { talloc_free(p); continue; } DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); } } talloc_free(tmp_ctx); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s) { WERROR status; static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL }; unsigned int i; int ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message_element *el; struct ldb_dn *ntds_dn; tmp_ctx = talloc_new(s); W_ERROR_HAVE_NO_MEMORY(tmp_ctx); ntds_dn = samdb_ntds_settings_dn(s->samdb); if (!ntds_dn) { DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN); if (ret != LDB_SUCCESS) { DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs"); if (!el) { DEBUG(1,("Finding hasMasterNCs element in root_res failed: %s\n", ldb_errstring(s->samdb))); talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } for (i=0; i<el->num_values; i++) { struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); if (pdn == NULL) { talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (!ldb_dn_validate(pdn)) { return WERR_DS_DRA_INTERNAL_ERROR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); p->service = s; DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn))); } el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs"); for (i=0; el && i<el->num_values; i++) { struct ldb_dn *pdn; struct dreplsrv_partition *p; pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]); if (pdn == NULL) { talloc_free(tmp_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (!ldb_dn_validate(pdn)) { return WERR_DS_DRA_INTERNAL_ERROR; } p = talloc_zero(s, struct dreplsrv_partition); W_ERROR_HAVE_NO_MEMORY(p); p->dn = talloc_steal(p, pdn); p->partial_replica = true; p->service = s; DLIST_ADD(s->partitions, p); DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", ldb_dn_get_linearized(p->dn))); } talloc_free(tmp_ctx); status = dreplsrv_refresh_partitions(s); W_ERROR_NOT_OK_RETURN(status); return WERR_OK; }