summaryrefslogtreecommitdiff
path: root/source4/rpc_server/drsuapi/updaterefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server/drsuapi/updaterefs.c')
-rw-r--r--source4/rpc_server/drsuapi/updaterefs.c122
1 files changed, 70 insertions, 52 deletions
diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c
index 5bf2f2251f..4a888099c0 100644
--- a/source4/rpc_server/drsuapi/updaterefs.c
+++ b/source4/rpc_server/drsuapi/updaterefs.c
@@ -30,6 +30,11 @@
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "auth/auth.h"
+struct repsTo {
+ uint32_t count;
+ struct repsFromToBlob *r;
+};
+
/*
load the repsTo structure for a given partition GUID
*/
@@ -39,8 +44,9 @@ static WERROR uref_loadreps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, st
struct ldb_dn *dn;
const char *attrs[] = { "repsTo", NULL };
struct ldb_result *res;
- const struct ldb_val *v;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ int i;
+ struct ldb_message_element *el;
if (dsdb_find_dn_by_guid(sam_ctx, tmp_ctx, GUID_string(tmp_ctx, guid), &dn) != LDB_SUCCESS) {
DEBUG(0,("drsuapi_addref: failed to find partition with GUID %s\n",
@@ -58,16 +64,27 @@ static WERROR uref_loadreps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, st
return WERR_DS_DRA_INTERNAL_ERROR;
}
- v = ldb_msg_find_ldb_val(res->msgs[0], "repsTo");
- if (v == NULL) {
- /* treat as empty empty */
- ZERO_STRUCTP(reps);
- reps->version = REPSTO_VERSION1;
- } else {
+ ZERO_STRUCTP(reps);
+
+ el = ldb_msg_find_element(res->msgs[0], "repsTo");
+ if (el == NULL) {
+ talloc_free(tmp_ctx);
+ return WERR_OK;
+ }
+
+ reps->count = el->num_values;
+ reps->r = talloc_array(mem_ctx, struct repsFromToBlob, reps->count);
+ if (reps->r == NULL) {
+ talloc_free(tmp_ctx);
+ return WERR_DS_DRA_INTERNAL_ERROR;
+ }
+
+ for (i=0; i<reps->count; i++) {
enum ndr_err_code ndr_err;
- ndr_err = ndr_pull_struct_blob(v, mem_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")),
- reps,
- (ndr_pull_flags_fn_t)ndr_pull_repsTo);
+ ndr_err = ndr_pull_struct_blob(&el->values[i],
+ mem_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")),
+ &reps->r[i],
+ (ndr_pull_flags_fn_t)ndr_pull_repsFromToBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(tmp_ctx);
return WERR_DS_DRA_INTERNAL_ERROR;
@@ -86,11 +103,10 @@ static WERROR uref_savereps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, st
struct repsTo *reps)
{
struct ldb_dn *dn;
- struct ldb_val v;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- enum ndr_err_code ndr_err;
struct ldb_message *msg;
struct ldb_message_element *el;
+ int i;
if (dsdb_find_dn_by_guid(sam_ctx, tmp_ctx, GUID_string(tmp_ctx, guid), &dn) != LDB_SUCCESS) {
DEBUG(0,("drsuapi_addref: failed to find partition with GUID %s\n",
@@ -99,20 +115,31 @@ static WERROR uref_savereps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, st
return WERR_DS_DRA_BAD_NC;
}
- ndr_err = ndr_push_struct_blob(&v, tmp_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")),
- reps,
- (ndr_push_flags_fn_t)ndr_push_repsTo);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- goto failed;
- }
-
msg = ldb_msg_new(tmp_ctx);
msg->dn = dn;
if (ldb_msg_add_empty(msg, "repsTo", LDB_FLAG_MOD_REPLACE, &el) != LDB_SUCCESS) {
goto failed;
}
- el->num_values = 1;
- el->values = &v;
+
+ el->values = talloc_array(msg, struct ldb_val, reps->count);
+ if (!el->values) {
+ goto failed;
+ }
+
+ for (i=0; i<reps->count; i++) {
+ struct ldb_val v;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(&v, tmp_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")),
+ &reps->r[i],
+ (ndr_push_flags_fn_t)ndr_push_repsFromToBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ goto failed;
+ }
+
+ el->num_values++;
+ el->values[i] = v;
+ }
if (ldb_modify(sam_ctx, msg) != LDB_SUCCESS) {
DEBUG(0,("Failed to store repsTo - %s\n", ldb_errstring(sam_ctx)));
@@ -132,30 +159,24 @@ failed:
add a replication destination for a given partition GUID
*/
static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
- struct GUID *guid, struct repsToDest *dest)
+ struct GUID *guid, struct repsFromTo1 *dest)
{
struct repsTo reps;
WERROR werr;
- struct repsTov1 *rv1;
werr = uref_loadreps(sam_ctx, mem_ctx, guid, &reps);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
- if (reps.version != REPSTO_VERSION1) {
- DEBUG(0,("Wrong version number %u on disk\n",
- reps.version));
- return WERR_DS_DRA_INTERNAL_ERROR;
- }
-
- rv1 = &reps.ctr.r;
- rv1->reps = talloc_realloc(mem_ctx, rv1->reps, struct repsToDest, rv1->count+1);
- if (rv1->reps == NULL) {
+ reps.r = talloc_realloc(mem_ctx, reps.r, struct repsFromToBlob, reps.count+1);
+ if (reps.r == NULL) {
return WERR_DS_DRA_INTERNAL_ERROR;
}
- rv1->reps[rv1->count] = *dest;
- rv1->count++;
+ ZERO_STRUCT(reps.r[reps.count]);
+ reps.r[reps.count].version = 1;
+ reps.r[reps.count].ctr.ctr1 = *dest;
+ reps.count++;
werr = uref_savereps(sam_ctx, mem_ctx, guid, &reps);
if (!W_ERROR_IS_OK(werr)) {
@@ -173,7 +194,6 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
{
struct repsTo reps;
WERROR werr;
- struct repsTov1 *rv1;
int i;
werr = uref_loadreps(sam_ctx, mem_ctx, guid, &reps);
@@ -181,19 +201,12 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
return werr;
}
- if (reps.version != REPSTO_VERSION1) {
- DEBUG(0,("Wrong version number %u on disk\n", reps.version));
- return WERR_DS_DRA_INTERNAL_ERROR;
- }
-
- rv1 = &reps.ctr.r;
-
- for (i=0; i<rv1->count; i++) {
- if (GUID_compare(dest_guid, &rv1->reps[i].dest_guid) == 0) {
- if (i+1 < rv1->count) {
- memmove(&rv1->reps[i], &rv1->reps[i+1], sizeof(rv1->reps[i])*(rv1->count-(i+1)));
+ for (i=0; i<reps.count; i++) {
+ if (GUID_compare(dest_guid, &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) {
+ if (i+1 < reps.count) {
+ memmove(&reps.r[i], &reps.r[i+1], sizeof(reps.r[i])*(reps.count-(i+1)));
}
- rv1->count--;
+ reps.count--;
}
}
@@ -248,16 +261,21 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA
}
if (req->options & DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE) {
- struct repsToDest dest;
+ struct repsFromTo1 dest;
+ struct repsFromTo1OtherInfo oi;
+
+ ZERO_STRUCT(dest);
+ ZERO_STRUCT(oi);
- dest.dest_dsa_dns_name = req->dest_dsa_dns_name;
- dest.dest_guid = req->dest_dsa_guid;
- dest.options = req->options;
+ oi.dns_name = req->dest_dsa_dns_name;
+ dest.other_info = &oi;
+ dest.source_dsa_obj_guid = req->dest_dsa_guid;
+ dest.replica_flags = req->options;
werr = uref_add_dest(sam_ctx, mem_ctx, &req->naming_context->guid, &dest);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("Failed to delete repsTo for %s\n",
- GUID_string(dce_call, &dest.dest_guid)));
+ GUID_string(dce_call, &dest.source_dsa_obj_guid)));
goto failed;
}
}