The branch, master has been updated via c064357 selftest/flapping: add some samba3.blackbox.smbclient_s3 tests via 119e7d0 Revert "s4: tests: Skip drs tests." via 3ce5ad1 selftest: Move repl_schema test to a distinct OID prefix via 1086974 s4:dsdb/repl_meta_data: Add more info on which DN we failed to find an attid on via 111c5fd s4:dsdb/repl: let dsdb_replicated_objects_convert() change remote to local attid for linked attributes via cff6111 s4:dsdb/repl: set working_schema->resolving_in_progress during schema creation via 6bc007a s4:dsdb/schema: move messages for unknown attids to higher debug levels during resolving via 5ee6f93 s4:dsdb/schema: split out a dsdb_attribute_drsuapi_remote_to_local() function via 2e6860d s4:dsdb/schema: don't update the in memory schema->prefixmap without reloading the schema! via b755ec7 s4:dsdb/schema: avoid an implicit prefix map creation in lookup functions via fa580f2 s4:dsdb/objectclass_attrs: call dsdb_attribute_from_ldb() without a prefixmap via edeb577 s4:dsdb/repl: make sure the working_schema prefix map is populated with the remote prefix map via f905ddc s4:dsdb/schema: make dsdb_schema_pfm_add_entry() public and more useful via 29caafa s4:dsdb/schema: Remove unused old schema from memory via c533b60 s4:dsdb/repl: Improve memory handling in replicated schema code via 0a1627d s4:dsdb/schema: don't treat an older remote schema as SCHEMA_MISMATCH via 386dbc4 s4:dsdb/schema: store struct dsdb_schema_info instead of a hexstring via ab63866 s4:dsdb/repl: avoid recursion after fetching schema changes. via 7143aed s4:dsdb/schema: don't change schema->schema_info on originating schema changes. from 8c61e14 Fix a typo in smb.conf man page
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit c064357428799ebb9c8ac5e9bf3a081bdad45072 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 6 10:33:49 2016 +0200 selftest/flapping: add some samba3.blackbox.smbclient_s3 tests BUG: https://bugzilla.samba.org/show_bug.cgi?id=12108 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Aug 11 04:42:30 CEST 2016 on sn-devel-144 commit 119e7d094da26029e16d72598a55377d8010f28f Author: Stefan Metzmacher <me...@samba.org> Date: Fri Aug 5 22:06:41 2016 +0200 Revert "s4: tests: Skip drs tests." This reverts commit 08d03f79de49826dc5dff3bc09193f1404e5f549. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3ce5ad1e6ca25fb91f0a0dcd7e389713913a35b0 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Aug 2 15:45:18 2016 +1200 selftest: Move repl_schema test to a distinct OID prefix We also take the chance to make it clearer that the number being passed in should be unique. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 108697402c9e39511f9ea1b1e21cae9322586f6b Author: Andrew Bartlett <abart...@samba.org> Date: Tue Aug 2 14:28:12 2016 +1200 s4:dsdb/repl_meta_data: Add more info on which DN we failed to find an attid on BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 111c5fd83fa3d0f2e1ae3af0767d8717edab484a Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 09:10:48 2016 +0200 s4:dsdb/repl: let dsdb_replicated_objects_convert() change remote to local attid for linked attributes We already do that for objects in dsdb_convert_object_ex(). We need to be consistent and do the same for linked attributes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cff6111d2fe5b3999447eaa870c5ddee158226aa Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 12:11:53 2016 +0200 s4:dsdb/repl: set working_schema->resolving_in_progress during schema creation BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6bc007a9143a57525732792bb1fcb934fcb2c91c Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 09:10:13 2016 +0200 s4:dsdb/schema: move messages for unknown attids to higher debug levels during resolving BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 5ee6f9371570f968122c6eb1bceeb9bb0518bb4c Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 09:10:13 2016 +0200 s4:dsdb/schema: split out a dsdb_attribute_drsuapi_remote_to_local() function BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2e6860df7149559df84ed3995ed36332ccb0f649 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 11:22:13 2016 +0200 s4:dsdb/schema: don't update the in memory schema->prefixmap without reloading the schema! BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b755ec74e17e9a5ed746af0a2716effe3176965a Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 11:11:20 2016 +0200 s4:dsdb/schema: avoid an implicit prefix map creation in lookup functions dsdb_create_prefix_mapping() should be the only place that calls dsdb_schema_pfm_make_attid(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit fa580f255ca0878b99946cda3f95913ff37f6d54 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 13:02:21 2016 +0200 s4:dsdb/objectclass_attrs: call dsdb_attribute_from_ldb() without a prefixmap We may not have a prefix mapping for the new attribute definition, it will be added later. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit edeb577a59ea88d2a22559ffb8cbe994ea28f3f1 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 11:07:18 2016 +0200 s4:dsdb/repl: make sure the working_schema prefix map is populated with the remote prefix map We should create the working_schema prefix map before we try to resolve the schema. This allows getting the same mapping (if there's not already a conflict) and allows us to remove the implicit prefix mapping creation in the prefix mapping lookup functions. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f905ddc104bb130a63e714d16b6da41bc92d6864 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Aug 8 11:00:02 2016 +0200 s4:dsdb/schema: make dsdb_schema_pfm_add_entry() public and more useful We allow a hint for the id from the remote prefix map. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12128 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 29caafaf2888b25408fcafdb9767a003a910c1d7 Author: Andrew Bartlett <abart...@samba.org> Date: Thu Aug 4 15:25:52 2016 +1200 s4:dsdb/schema: Remove unused old schema from memory This avoids confusion when reading the talloc dump from a ldb context that has been the target of replication, as the dsdb_schema_copy_shallow() memory was still around, if unused. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12115 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c533b60ceb761b609e78dfe270930cb99fdac848 Author: Andrew Bartlett <abart...@samba.org> Date: Thu Aug 4 15:20:27 2016 +1200 s4:dsdb/repl: Improve memory handling in replicated schema code This attempts to make it clear what memory is short term and what memory is long term BUG: https://bugzilla.samba.org/show_bug.cgi?id=12115 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 0a1627de6d7c70f2462a4d4db717ea50c8aefc2f Author: Stefan Metzmacher <me...@samba.org> Date: Thu Aug 4 11:00:34 2016 +0200 s4:dsdb/schema: don't treat an older remote schema as SCHEMA_MISMATCH It's perfectly valid to replicate from a partner with an older schema version, otherwise schema changes would block any other replication until every dc in the forest has the schema changes. The avoids an endless loop trying to get schema in sync with the partner. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12115 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 386dbc428b447bbdf9c500191273658b92b13f7a Author: Stefan Metzmacher <me...@samba.org> Date: Thu Aug 4 10:03:14 2016 +0200 s4:dsdb/schema: store struct dsdb_schema_info instead of a hexstring This will simplify the schema checking in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12115 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ab63866e258c1afbe60663f2a36bea58e5e80d53 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Aug 5 11:05:37 2016 +0200 s4:dsdb/repl: avoid recursion after fetching schema changes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12115 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 7143aed4e428f52bf1381b38a27412fd198060ab Author: Stefan Metzmacher <me...@samba.org> Date: Thu Aug 4 23:04:32 2016 +0200 s4:dsdb/schema: don't change schema->schema_info on originating schema changes. The next reload will take care of it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12114 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/flapping | 2 + selftest/skip | 4 - source4/dsdb/repl/drepl_out_helpers.c | 35 +++++-- source4/dsdb/repl/drepl_service.h | 7 -- source4/dsdb/repl/replicated_objects.c | 114 +++++++++++++++++++-- source4/dsdb/samdb/ldb_modules/objectclass_attrs.c | 16 ++- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 6 +- source4/dsdb/samdb/ldb_modules/schema_util.c | 38 +++---- source4/dsdb/samdb/samdb.h | 2 +- source4/dsdb/schema/schema.h | 10 +- source4/dsdb/schema/schema_info_attr.c | 36 +++++-- source4/dsdb/schema/schema_init.c | 54 ++++++---- source4/dsdb/schema/schema_prefixmap.c | 54 +++++++--- source4/dsdb/schema/schema_set.c | 12 +++ source4/dsdb/schema/schema_syntax.c | 97 +++++++++++++----- source4/libnet/libnet_vampire.c | 7 +- source4/setup/schema_samba4.ldif | 2 + source4/torture/drs/python/repl_schema.py | 26 ++--- source4/torture/drs/unit/prefixmap_tests.c | 106 ++++++++++--------- source4/torture/drs/unit/schemainfo_tests.c | 83 +++++++++++++-- 20 files changed, 522 insertions(+), 189 deletions(-) Changeset truncated at 500 lines: diff --git a/selftest/flapping b/selftest/flapping index 4ea0a44..50fdf1e 100644 --- a/selftest/flapping +++ b/selftest/flapping @@ -32,3 +32,5 @@ # ^samba4.ldap.notification.python\(.*\).__main__.LDAPNotificationTest.test_max_search ^samba3.blackbox.smbclient_tar.* # fails very, very often on sn-devel +^samba3.blackbox.smbclient_s3.*.sending a message to the remote server # flakey on sn-devel-104 and sn-devel-144 +^samba3.blackbox.smbclient_s3.*.creating a good symlink and deleting it by path # flakey on sn-devel-104 and sn-devel-144 diff --git a/selftest/skip b/selftest/skip index 879608d..ba6718a 100644 --- a/selftest/skip +++ b/selftest/skip @@ -138,7 +138,3 @@ bench # don't run benchmarks in our selftest ^samba4.rpc.unixinfo # This contains a server-side getpwuid call which hangs the server when nss_winbindd is in use ^samba.tests.dcerpc.unix # This contains a server-side getpwuid call which hangs the server when nss_winbindd is in use GETADDRINFO # socket wrapper doesn't support threads -# -# drs tests are currently broken. -# Revert this when they are working again. -^samba.*drs.* diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 2a74cb7..9fe8c3b 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -241,6 +241,13 @@ struct dreplsrv_op_pull_source_state { struct tevent_context *ev; struct dreplsrv_out_operation *op; void *ndr_struct_ptr; + /* + * Used when we have to re-try with a different NC, eg for + * EXOP retry or to get a current schema first + */ + struct dreplsrv_partition_source_dsa *source_dsa_retry; + enum drsuapi_DsExtendedOperation extended_op_retry; + bool retry_started; }; static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq); @@ -785,10 +792,17 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req dsdb_repl_flags, state, &objects); - if (W_ERROR_EQUAL(status, WERR_DS_DRA_SCHEMA_MISMATCH) - && state->op->source_dsa_retry == NULL) { + if (W_ERROR_EQUAL(status, WERR_DS_DRA_SCHEMA_MISMATCH)) { struct dreplsrv_partition *p; + if (state->retry_started) { + nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP); + DEBUG(0,("Failed to convert objects after retry: %s/%s\n", + win_errstr(status), nt_errstr(nt_status))); + tevent_req_nterror(req, nt_status); + return; + } + /* * Change info sync or extended operation into a fetch * of the schema partition, so we get all the schema @@ -802,14 +816,14 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req if (state->op->extended_op == DRSUAPI_EXOP_REPL_SECRET) { - state->op->extended_op_retry = state->op->extended_op; + state->extended_op_retry = state->op->extended_op; } else { - state->op->extended_op_retry = DRSUAPI_EXOP_NONE; + state->extended_op_retry = DRSUAPI_EXOP_NONE; } state->op->extended_op = DRSUAPI_EXOP_NONE; if (ldb_dn_compare(nc_root, partition->dn) == 0) { - state->op->source_dsa_retry = state->op->source_dsa; + state->source_dsa_retry = state->op->source_dsa; } else { status = dreplsrv_partition_find_for_nc(service, NULL, NULL, @@ -825,7 +839,7 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req } status = dreplsrv_partition_source_dsa_by_guid(p, &state->op->source_dsa->repsFrom1->source_dsa_obj_guid, - &state->op->source_dsa_retry); + &state->source_dsa_retry); if (!W_ERROR_IS_OK(status)) { struct GUID_txt_buf str; @@ -867,6 +881,7 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req } DEBUG(4,("Wrong schema when applying reply GetNCChanges, retrying\n")); + state->retry_started = true; dreplsrv_op_pull_source_get_changes_trigger(req); return; @@ -930,10 +945,10 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req * pulling the schema, then go back and do the original * operation once we are done. */ - if (state->op->source_dsa_retry != NULL) { - state->op->source_dsa = state->op->source_dsa_retry; - state->op->extended_op = state->op->extended_op_retry; - state->op->source_dsa_retry = NULL; + if (state->source_dsa_retry != NULL) { + state->op->source_dsa = state->source_dsa_retry; + state->op->extended_op = state->extended_op_retry; + state->source_dsa_retry = NULL; dreplsrv_op_pull_source_get_changes_trigger(req); return; } diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h index 317fa87..edba4c4 100644 --- a/source4/dsdb/repl/drepl_service.h +++ b/source4/dsdb/repl/drepl_service.h @@ -130,13 +130,6 @@ struct dreplsrv_out_operation { enum drsuapi_DsExtendedError extended_ret; dreplsrv_extended_callback_t callback; void *cb_data; - - /* - * Used when we have to re-try with a different NC, eg for - * EXOP retry or to get a current schema first - */ - struct dreplsrv_partition_source_dsa *source_dsa_retry; - enum drsuapi_DsExtendedOperation extended_op_retry; }; struct dreplsrv_notify_operation { diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index fb8083d..89d288a 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -103,7 +103,6 @@ static WERROR dsdb_repl_merge_working_schema(struct ldb_context *ldb, } WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap *pfm_remote, uint32_t cycle_before_switching, struct dsdb_schema *initial_schema, @@ -129,10 +128,11 @@ WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb, DRSUAPI_ATTID_systemPossSuperiors, DRSUAPI_ATTID_INVALID }; + TALLOC_CTX *frame = talloc_stackframe(); /* create a list of objects yet to be converted */ for (cur = first_object; cur; cur = cur->next_object) { - schema_list_item = talloc(mem_ctx, struct schema_list); + schema_list_item = talloc(frame, struct schema_list); if (schema_list_item == NULL) { return WERR_NOMEM; } @@ -164,6 +164,7 @@ WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb, working_schema, resulting_schema); if (!W_ERROR_IS_OK(werr)) { + talloc_free(frame); return werr; } } @@ -242,6 +243,7 @@ WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb, "all %d remaining of %d objects " "failed to convert\n", failed_obj_count, object_count)); + talloc_free(frame); return WERR_INTERNAL_ERROR; } @@ -257,12 +259,14 @@ WERROR dsdb_repl_resolve_working_schema(struct ldb_context *ldb, ret = dsdb_setup_sorted_accessors(ldb, working_schema); if (LDB_SUCCESS != ret) { DEBUG(0,("Failed to create schema-cache indexes!\n")); + talloc_free(frame); return WERR_INTERNAL_ERROR; } } pass_no++; } + talloc_free(frame); return WERR_OK; } @@ -287,6 +291,7 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb, { WERROR werr; struct dsdb_schema_prefixmap *pfm_remote; + uint32_t r; struct dsdb_schema *working_schema; /* make a copy of the iniatial_scheam so we don't mess with it */ @@ -295,17 +300,53 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb, DEBUG(0,(__location__ ": schema copy failed!\n")); return WERR_NOMEM; } + working_schema->resolving_in_progress = true; /* we are going to need remote prefixMap for decoding */ werr = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true, - mem_ctx, &pfm_remote, NULL); + working_schema, &pfm_remote, NULL); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s", win_errstr(werr))); + talloc_free(working_schema); return werr; } - werr = dsdb_repl_resolve_working_schema(ldb, mem_ctx, + for (r=0; r < pfm_remote->length; r++) { + const struct dsdb_schema_prefixmap_oid *rm = &pfm_remote->prefixes[r]; + bool found_oid = false; + uint32_t l; + + for (l=0; l < working_schema->prefixmap->length; l++) { + const struct dsdb_schema_prefixmap_oid *lm = &working_schema->prefixmap->prefixes[l]; + int cmp; + + cmp = data_blob_cmp(&rm->bin_oid, &lm->bin_oid); + if (cmp == 0) { + found_oid = true; + break; + } + } + + if (found_oid) { + continue; + } + + /* + * We prefer the same is as we got from the remote peer + * if there's no conflict. + */ + werr = dsdb_schema_pfm_add_entry(working_schema->prefixmap, + rm->bin_oid, &rm->id, NULL); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,(__location__ ": Failed to merge remote prefixMap: %s", + win_errstr(werr))); + talloc_free(working_schema); + return werr; + } + } + + werr = dsdb_repl_resolve_working_schema(ldb, pfm_remote, 0, /* cycle_before_switching */ working_schema, @@ -315,9 +356,12 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb, if (!W_ERROR_IS_OK(werr)) { DEBUG(0, ("%s: dsdb_repl_resolve_working_schema() failed: %s", __location__, win_errstr(werr))); + talloc_free(working_schema); return werr; } + working_schema->resolving_in_progress = false; + *_schema_out = working_schema; return WERR_OK; @@ -605,6 +649,7 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, struct dsdb_schema_prefixmap *pfm_remote; struct dsdb_extended_replicated_objects *out; const struct drsuapi_DsReplicaObjectListItemEx *cur; + struct dsdb_syntax_ctx syntax_ctx; uint32_t i; out = talloc_zero(mem_ctx, struct dsdb_extended_replicated_objects); @@ -628,6 +673,10 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, return status; } + /* use default syntax conversion context */ + dsdb_syntax_ctx_init(&syntax_ctx, ldb, schema); + syntax_ctx.pfm_remote = pfm_remote; + if (ldb_dn_compare(partition_dn, ldb_get_schema_basedn(ldb)) != 0) { /* * check for schema changes in case @@ -653,11 +702,6 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, object_count); 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 == object_count) { talloc_free(out); @@ -706,6 +750,58 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, return WERR_FOOBAR; } + out->linked_attributes = talloc_array(out, + struct drsuapi_DsReplicaLinkedAttribute, + linked_attributes_count); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(out->linked_attributes, out); + + for (i=0; i < linked_attributes_count; i++) { + const struct drsuapi_DsReplicaLinkedAttribute *ra = &linked_attributes[i]; + struct drsuapi_DsReplicaLinkedAttribute *la = &out->linked_attributes[i]; + + if (ra->identifier == NULL) { + talloc_free(out); + return WERR_BAD_NET_RESP; + } + + *la = *ra; + + la->identifier = talloc_zero(out->linked_attributes, + struct drsuapi_DsReplicaObjectIdentifier); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(la->identifier, out); + + /* + * We typically only get the guid filled + * and the repl_meta_data module only cares abouf + * the guid. + */ + la->identifier->guid = ra->identifier->guid; + + if (ra->value.blob != NULL) { + la->value.blob = talloc_zero(out->linked_attributes, + DATA_BLOB); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(la->value.blob, out); + + if (ra->value.blob->length != 0) { + *la->value.blob = data_blob_dup_talloc(la->value.blob, + *ra->value.blob); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(la->value.blob->data, out); + } + } + + status = dsdb_attribute_drsuapi_remote_to_local(&syntax_ctx, + ra->attid, + &la->attid, + NULL); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,(__location__": linked_attribute[%u] attid 0x%08X not found: %s\n", + i, ra->attid, win_errstr(status))); + return status; + } + } + + out->linked_attributes_count = linked_attributes_count; + /* free pfm_remote, we won't need it anymore */ talloc_free(pfm_remote); diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c index e051913..f739c40 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c @@ -437,13 +437,25 @@ static int attr_handler2(struct oc_context *ac) struct dsdb_attribute *att = talloc(ac, struct dsdb_attribute); const struct dsdb_syntax *attrSyntax; WERROR status; - - status= dsdb_attribute_from_ldb(ac->schema, msg, att); + struct dsdb_schema *tmp_schema = NULL; + + /* + * We temporary remove the prefix map from the schema, + * a new prefix map is added by dsdb_create_prefix_mapping() + * via the "schema_data" module. + */ + tmp_schema = dsdb_schema_copy_shallow(ac, ldb, ac->schema); + if (tmp_schema == NULL) { + return ldb_module_oom(ac->module); + } + TALLOC_FREE(tmp_schema->prefixmap); + status= dsdb_attribute_from_ldb(tmp_schema, msg, att); if (!W_ERROR_IS_OK(status)) { ldb_set_errstring(ldb, "objectclass: failed to translate the schemaAttribute to a dsdb_attribute"); return LDB_ERR_UNWILLING_TO_PERFORM; } + TALLOC_FREE(tmp_schema); attrSyntax = dsdb_syntax_for_attribute(att); if (!attrSyntax) { diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 4989a4b..f3573f6 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -6096,7 +6096,11 @@ linked_attributes[0]: /* find the attribute being modified */ attr = dsdb_attribute_by_attributeID_id(schema, la->attid); if (attr == NULL) { - DEBUG(0, (__location__ ": Unable to find attributeID 0x%x\n", la->attid)); + struct GUID_txt_buf guid_str; + ldb_asprintf_errstring(ldb, "Unable to find attributeID 0x%x for link on <GUID=%s>", + la->attid, + GUID_buf_string(&la->identifier->guid, + &guid_str)); talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/dsdb/samdb/ldb_modules/schema_util.c b/source4/dsdb/samdb/ldb_modules/schema_util.c index 7402c04..47d2411 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_util.c +++ b/source4/dsdb/samdb/ldb_modules/schema_util.c @@ -276,9 +276,7 @@ int dsdb_module_schema_info_update(struct ldb_module *ldb_module, { int ret; const struct GUID *invocation_id; - DATA_BLOB ndr_blob; struct dsdb_schema_info *schema_info; - const char *schema_info_str; WERROR werr; TALLOC_CTX *temp_ctx = talloc_new(schema); if (temp_ctx == NULL) { @@ -321,22 +319,26 @@ int dsdb_module_schema_info_update(struct ldb_module *ldb_module, return ret; } - /* finally, update schema_info in the cache */ - werr = dsdb_blob_from_schema_info(schema_info, temp_ctx, &ndr_blob); - if (!W_ERROR_IS_OK(werr)) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_module), "Failed to get schema info"); - talloc_free(temp_ctx); - return ldb_operr(ldb_module_get_ctx(ldb_module)); - } - - schema_info_str = hex_encode_talloc(schema, ndr_blob.data, ndr_blob.length); - if (!schema_info_str) { - talloc_free(temp_ctx); - return ldb_module_oom(ldb_module); - } - - talloc_unlink(schema, discard_const(schema->schema_info)); - schema->schema_info = schema_info_str; + /* + * We don't update the schema->schema_info! + * as that would not represent the other information + * in schema->* + * + * We're not sure if the current transaction will go through! + * E.g. schema changes are only allowed on the schema master, + * otherwise they result in a UNWILLING_TO_PERFORM and a + * + * Note that schema might a global variable shared between + * multiple ldb_contexts. With process model "single" it + * means the drsuapi server also uses it. + * + * We keep it simple and just try to update the + * stored value. + * + * The next schema reload will pick it up, which + * then works for originating and replicated changes + * in the same way. + */ talloc_free(temp_ctx); return LDB_SUCCESS; diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 0acffa1..c7260d0 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -215,7 +215,7 @@ struct dsdb_extended_replicated_objects { struct dsdb_extended_replicated_object *objects; uint32_t linked_attributes_count; - const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; + struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; WERROR error; diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index 6c3581b..ee2b850 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -212,7 +212,7 @@ struct dsdb_schema { * this is the content of the schemaInfo attribute of the * Schema-Partition head object. */ - const char *schema_info; + struct dsdb_schema_info *schema_info; struct dsdb_attribute *attributes; struct dsdb_class *classes; @@ -256,6 +256,14 @@ struct dsdb_schema { /* Should the syntax handlers in this case handle all incoming OIDs automatically, assigning them as an OID if no text name is known? */ bool relax_OID_conversions; + + /* + * we're currently trying to construct a working_schema + * in order to replicate the schema partition. + * + * We use this in order to avoid temporary failure DEBUG messages + */ + bool resolving_in_progress; }; enum dsdb_attr_list_query { diff --git a/source4/dsdb/schema/schema_info_attr.c b/source4/dsdb/schema/schema_info_attr.c index e113033..0d54012 100644 -- Samba Shared Repository