From 65a35acbf33dd6dfd6ba6b2fb76580126829b597 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Mar 2016 15:49:33 +1300 Subject: [PATCH] repl: Pass in the full partition DN to dsdb_replicated_objects_convert() When we were processing an EXOP, we would pass in a DN specific to that operation, but this stopped repl_meta_data from finding the parent object Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam --- source4/dsdb/repl/drepl_out_helpers.c | 17 ++++++++++++++++- source4/dsdb/repl/replicated_objects.c | 8 ++------ source4/libnet/libnet_vampire.c | 28 ++++++++++++++++++++++++++-- source4/torture/drs/rpc/dssync.c | 5 ++++- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index a1e8dcbb244..a217e833e73 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -671,6 +671,8 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req WERROR status; NTSTATUS nt_status; uint32_t dsdb_repl_flags = 0; + struct ldb_dn *nc_root = NULL; + int ret; switch (ctr_level) { case 1: @@ -744,9 +746,22 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req dsdb_repl_flags |= DSDB_REPL_FLAG_EXPECT_NO_SECRETS; } + if (state->op->extended_op != DRSUAPI_EXOP_NONE) { + ret = dsdb_find_nc_root(service->samdb, partition, + partition->dn, &nc_root); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find nc_root for %s\n", + ldb_dn_get_linearized(partition->dn))); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + } else { + nc_root = partition->dn; + } + status = dsdb_replicated_objects_convert(service->samdb, working_schema ? working_schema : schema, - partition->nc.dn, + nc_root, mapping_ctr, object_count, first_object, diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 0ac2b540fef..2e3676c81bb 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -639,7 +639,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb, WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, const struct dsdb_schema *schema, - const char *partition_dn_str, + struct ldb_dn *partition_dn, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, uint32_t object_count, const struct drsuapi_DsReplicaObjectListItemEx *first_object, @@ -653,7 +653,6 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, 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; @@ -671,9 +670,6 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, 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)) { @@ -691,7 +687,7 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, 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)); + ldb_dn_get_linearized(partition_dn))); talloc_free(out); return status; } diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 97c6d1a009d..0d4d69f7cf2 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -232,6 +232,7 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s struct repsFromTo1 *s_dsa; char *tmp_dns_name; struct ldb_context *schema_ldb; + struct ldb_dn *partition_dn; struct ldb_message *msg; struct ldb_message_element *prefixMap_el; uint32_t i; @@ -361,10 +362,16 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s s->schema = s->self_made_schema; s->self_made_schema = NULL; + partition_dn = ldb_dn_new(s, s->ldb, c->partition->nc.dn); + if (partition_dn == NULL) { + DEBUG(0,("Failed to parse partition DN from DRS.\n")); + return NT_STATUS_FOOBAR; + } + /* Now convert the schema elements again, using the schema we finalised, ready to actually import */ status = dsdb_replicated_objects_convert(s->ldb, s->schema, - c->partition->nc.dn, + partition_dn, mapping_ctr, object_count, first_object, @@ -559,6 +566,8 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, uint32_t i; uint64_t seq_num; bool is_exop = false; + struct ldb_dn *partition_dn = NULL; + struct ldb_dn *nc_root = NULL; s_dsa = talloc_zero(s, struct repsFromTo1); NT_STATUS_HAVE_NO_MEMORY(s_dsa); @@ -653,7 +662,14 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, } s->total_objects += object_count; + partition_dn = ldb_dn_new(s, s->ldb, c->partition->nc.dn); + if (partition_dn == NULL) { + DEBUG(0,("Failed to parse partition DN from DRS.\n")); + return NT_STATUS_FOOBAR; + } + if (is_exop) { + int ret; if (nc_object_count) { DEBUG(0,("Exop on[%s] objects[%u/%u] linked_values[%u/%u]\n", c->partition->nc.dn, s->total_objects, nc_object_count, @@ -662,6 +678,13 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, DEBUG(0,("Exop on[%s] objects[%u] linked_values[%u]\n", c->partition->nc.dn, s->total_objects, linked_attributes_count)); } + ret = dsdb_find_nc_root(s->ldb, s, + partition_dn, &nc_root); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find nc_root for %s\n", + ldb_dn_get_linearized(partition_dn))); + return NT_STATUS_INTERNAL_ERROR; + } } else { if (nc_object_count) { DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n", @@ -671,6 +694,7 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, DEBUG(0,("Partition[%s] objects[%u] linked_values[%u]\n", c->partition->nc.dn, s->total_objects, linked_attributes_count)); } + nc_root = partition_dn; } @@ -690,7 +714,7 @@ NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, status = dsdb_replicated_objects_convert(s->ldb, schema, - c->partition->nc.dn, + nc_root, mapping_ctr, object_count, first_object, diff --git a/source4/torture/drs/rpc/dssync.c b/source4/torture/drs/rpc/dssync.c index 5dbda4c7b3b..8fa04c32b48 100644 --- a/source4/torture/drs/rpc/dssync.c +++ b/source4/torture/drs/rpc/dssync.c @@ -358,6 +358,9 @@ static bool test_analyse_objects(struct torture_context *tctx, struct dsdb_extended_replicated_objects *objs; struct ldb_extended_dn_control *extended_dn_ctrl; struct dsdb_schema *ldap_schema; + struct ldb_dn *partition_dn = ldb_dn_new(tctx, ldb, partition); + + torture_assert_not_null(tctx, partition_dn, "Failed to parse partition DN as as DN"); /* load dsdb_schema using remote prefixMap */ torture_assert(tctx, @@ -367,7 +370,7 @@ static bool test_analyse_objects(struct torture_context *tctx, status = dsdb_replicated_objects_convert(ldb, ldap_schema, - partition, + partition_dn, mapping_ctr, object_count, first_object, -- 2.11.4.GIT