From 8703d9f5bfd8ded57f263fd4a1f70d121b656b03 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 15 Sep 2009 20:26:24 +0200 Subject: libreplace: white space cleanups --- lib/replace/system/filesys.h | 16 ++++++++-------- lib/replace/system/passwd.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h index 1cf6f231b7..22e3d23f3e 100644 --- a/lib/replace/system/filesys.h +++ b/lib/replace/system/filesys.h @@ -1,16 +1,16 @@ #ifndef _system_filesys_h #define _system_filesys_h -/* +/* Unix SMB/CIFS implementation. filesystem system include wrappers Copyright (C) Andrew Tridgell 2004 - + ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -53,23 +53,23 @@ #include #endif -#ifdef HAVE_SYS_FS_S5PARAM_H +#ifdef HAVE_SYS_FS_S5PARAM_H #include #endif #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) -#include +#include #endif #ifdef HAVE_SYS_STATFS_H # include #endif -#ifdef HAVE_DUSTAT_H +#ifdef HAVE_DUSTAT_H #include #endif -#ifdef HAVE_SYS_STATVFS_H +#ifdef HAVE_SYS_STATVFS_H #include #endif @@ -123,7 +123,7 @@ #endif /* Some POSIX definitions for those without */ - + #ifndef S_IFDIR #define S_IFDIR 0x4000 #endif diff --git a/lib/replace/system/passwd.h b/lib/replace/system/passwd.h index 9d7de34bce..b41608c551 100644 --- a/lib/replace/system/passwd.h +++ b/lib/replace/system/passwd.h @@ -1,17 +1,17 @@ #ifndef _system_passwd_h #define _system_passwd_h -/* +/* Unix SMB/CIFS implementation. passwd system include wrappers Copyright (C) Andrew Tridgell 2004 - + ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -80,7 +80,7 @@ char *rep_getpass(const char *prompt); #define NGROUPS_MAX 32 /* Guess... */ #endif -/* what is the longest significant password available on your system? +/* what is the longest significant password available on your system? Knowing this speeds up password searches a lot */ #ifndef PASSWORD_LENGTH #define PASSWORD_LENGTH 8 -- cgit From 451a537caa2207bb5e0a8818326a5f164c0d559a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 09:23:14 -0700 Subject: s4-repl: add a debug to make it easier to monitor replication --- source4/dsdb/repl/replicated_objects.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index fb6d4c18ec..2f4efc0fee 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -297,6 +297,11 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, return WERR_FOOBAR; } + DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n", + out->num_objects, out->linked_attributes_count, + ldb_dn_get_linearized(out->partition_dn))); + + if (_out) { *_out = out; } else { -- cgit From 6a9c89b3aef02310030ff436cd545eef77b8d1ee Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 09:43:27 -0700 Subject: talloc: when we enable NULL tracking, reparent the autofree context If NULL tracking is enabled after the autofree context is initialised then autofree ends up separate from the null_context. This means that talloc_report_full() doesn't report the autofree context. Fix this by reparenting the autofree context when we create the null_context. --- lib/talloc/talloc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 2709741dfc..478767c955 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -1468,6 +1468,9 @@ void talloc_enable_null_tracking(void) { if (null_context == NULL) { null_context = _talloc_named_const(NULL, 0, "null_context"); + if (autofree_context != NULL) { + talloc_reparent(NULL, null_context, autofree_context); + } } } -- cgit From 4861194f39bf826f3405452adc172cf5c240715b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 10:00:24 -0700 Subject: s4-ldb: cope better with corruption of tdb records When doing an indexed search if we hit a corrupt record we abandoned the indexed search and did a full search. The problem was that we might have sent some records to the caller already, which means the caller ended up with duplicate records. Fix this by returning a search error if indexing returns an error and we have given any records to the caller. --- source4/lib/ldb/ldb_tdb/ldb_index.c | 11 ++++++++--- source4/lib/ldb/ldb_tdb/ldb_pack.c | 4 ++++ source4/lib/ldb/ldb_tdb/ldb_search.c | 18 +++++++++++++++++- source4/lib/ldb/ldb_tdb/ldb_tdb.h | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 85fbfa0458..b959471d16 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -1037,7 +1037,8 @@ static int ltdb_index_dn(struct ldb_module *module, extracting just the given attributes */ static int ltdb_index_filter(const struct dn_list *dn_list, - struct ltdb_context *ac) + struct ltdb_context *ac, + uint32_t *match_count) { struct ldb_context *ldb; struct ldb_message *msg; @@ -1093,6 +1094,8 @@ static int ltdb_index_filter(const struct dn_list *dn_list, ac->request_terminated = true; return ret; } + + (*match_count)++; } return LDB_SUCCESS; @@ -1103,7 +1106,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, returns -1 if an indexed search is not possible, in which case the caller should call ltdb_search_full() */ -int ltdb_search_indexed(struct ltdb_context *ac) +int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count) { struct ldb_context *ldb; void *data = ldb_module_get_private(ac->module); @@ -1166,7 +1169,7 @@ int ltdb_search_indexed(struct ltdb_context *ac) if (ret == LDB_SUCCESS) { /* we've got a candidate list - now filter by the full tree and extract the needed attributes */ - ret = ltdb_index_filter(dn_list, ac); + ret = ltdb_index_filter(dn_list, ac, match_count); } talloc_free(dn_list); @@ -1578,6 +1581,8 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * ret = ltdb_unpack_data(module, &data, msg); if (ret != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); talloc_free(msg); return -1; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c index 5640e7053c..e7aeb47e72 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c @@ -236,6 +236,10 @@ int ltdb_unpack_data(struct ldb_module *module, errno = EIO; goto failed; } + if (len == 0) { + errno = EIO; + goto failed; + } message->elements[i].flags = 0; message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); if (message->elements[i].name == NULL) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index b307c5fb2f..a6647ccd50 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -265,6 +265,9 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes ret = ltdb_unpack_data(module, &tdb_data, msg); free(tdb_data.dptr); if (ret == -1) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); return LDB_ERR_OPERATIONS_ERROR; } @@ -535,7 +538,9 @@ int ltdb_search(struct ltdb_context *ctx) ctx->attrs = req->op.search.attrs; if (ret == LDB_SUCCESS) { - ret = ltdb_search_indexed(ctx); + uint32_t match_count = 0; + + ret = ltdb_search_indexed(ctx, &match_count); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* Not in the index, therefore OK! */ ret = LDB_SUCCESS; @@ -553,6 +558,17 @@ int ltdb_search(struct ltdb_context *ctx) printf("FULL SEARCH: %s\n", expression); talloc_free(expression); #endif + if (match_count != 0) { + /* the indexing code gave an error + * after having returned at least one + * entry. This means the indexes are + * corrupt or a database record is + * corrupt. We cannot continue with a + * full search or we may return + * duplicate entries + */ + return LDB_ERR_OPERATIONS_ERROR; + } ret = ltdb_search_full(ctx); if (ret != LDB_SUCCESS) { ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 75034dcf4b..c8c1dad5de 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -82,7 +82,7 @@ int ltdb_check_at_attributes_values(const struct ldb_val *value); struct ldb_parse_tree; -int ltdb_search_indexed(struct ltdb_context *ctx); +int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *); int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add); -- cgit From e1abb39388a154b405583bd55eb4bb9c8cfa13fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 10:01:26 -0700 Subject: s4-dsdb: use DLIST_ADD() not DLIST_ADD_END() Using DLIST_ADD_END() to construct a long list is very inefficient (it is O(n^2). These lists are not ordered, so using DLIST_ADD() is much better. --- source4/dsdb/schema/schema_init.c | 4 ++-- source4/dsdb/schema/schema_set.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 3b701ad31c..9f7d967158 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -967,7 +967,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_ERR_CONSTRAINT_VIOLATION; } - DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *); + DLIST_ADD(schema->attributes, sa); } for (i=0; i < objectclass_res->count; i++) { @@ -988,7 +988,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_ERR_CONSTRAINT_VIOLATION; } - DLIST_ADD_END(schema->classes, sc, struct dsdb_class *); + DLIST_ADD(schema->classes, sc); } schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner"); diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 6745bde127..6f09f63596 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -555,7 +555,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const goto failed; } - DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *); + DLIST_ADD(schema->attributes, sa); } else if (is_sc) { struct dsdb_class *sc; @@ -569,7 +569,7 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const goto failed; } - DLIST_ADD_END(schema->classes, sc, struct dsdb_class *); + DLIST_ADD(schema->classes, sc); } } -- cgit From 7f3817ab77ce85ab19c2c582eca0df84c36466dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 11:46:59 -0700 Subject: s4-repl: make sure we marshal the replPropertyMetaData after the last change we were setting local_usn after the marshall, so it wasn't going into the object --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index f9411fe95f..26703528a7 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -1352,16 +1352,6 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, &rdn_p->attid); } - /* create the meta data value */ - ndr_err = ndr_push_struct_blob(&nmd_value, msg, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - &nmd, - (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); - return replmd_replicated_request_werror(ar, ntstatus_to_werror(nt_status)); - } - /* * check if some replicated attributes left, otherwise skip the ldb_modify() call */ @@ -1385,6 +1375,16 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) nmd.ctr.ctr1.array[i].local_usn = seq_num; } + /* create the meta data value */ + ndr_err = ndr_push_struct_blob(&nmd_value, msg, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + &nmd, + (ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); + return replmd_replicated_request_werror(ar, ntstatus_to_werror(nt_status)); + } + /* * when we know that we'll modify the record, add the whenChanged, uSNChanged * and replPopertyMetaData attributes -- cgit From 48bc784e089fabf5f3f5a4e4d4ff47ce97ece74b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 11:47:42 -0700 Subject: s4-drs: filter based on local_usn The getncchanges uSN is in our local space, so we must compare it to the local_usn in replPropertyMetaData --- source4/rpc_server/drsuapi/getncchanges.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 165e485d45..a05ddb9a5d 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -86,7 +86,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem obj->meta_data_ctr->meta_data = talloc_array(obj, struct drsuapi_DsReplicaMetaData, md.ctr.ctr1.count); for (n=i=0; imeta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time; obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version; obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id; -- cgit From f5aec9ebb4bf5d0e6f8c6974a485bc5cd2899fdd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 14:04:22 -0700 Subject: tdb: allow reads after prepare commit We previously only allowed a commit to happen after a prepare commit. It is in fact safe to allow reads between a prepare and a commit, and the s4 replication code can make use of that, so allow it. --- lib/tdb/common/transaction.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c index e97fe67b4e..67a035879c 100644 --- a/lib/tdb/common/transaction.c +++ b/lib/tdb/common/transaction.c @@ -137,14 +137,6 @@ static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, { uint32_t blk; - /* Only a commit is allowed on a prepared transaction */ - if (tdb->transaction->prepared) { - tdb->ecode = TDB_ERR_EINVAL; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: transaction already prepared, read not allowed\n")); - tdb->transaction->transaction_error = 1; - return -1; - } - /* break it down into block sized ops */ while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); -- cgit From bfd0877261883d1d6ef1d1757dad386332a8db37 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 14:06:07 -0700 Subject: s4-repl: don't do double replication When we replicate from a remote DC, we need to note the new uSN that the local changes have resulted in, and modify the uSN that the notify task uses to determine if it should send a ReplicaSync message back to the remote DC. Otherwise we end up always triggering a ReplicaSync every time we replicate from another DC --- source4/dsdb/repl/drepl_out_helpers.c | 3 ++- source4/dsdb/repl/replicated_objects.c | 35 +++++++++++++++++++++++++++++++- source4/libnet/libnet_vampire.c | 6 ++++-- source4/torture/libnet/libnet_BecomeDC.c | 6 ++++-- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 168aacdde9..5c63c111f3 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -414,7 +414,8 @@ static void dreplsrv_op_pull_source_apply_changes_send(struct dreplsrv_op_pull_s &rf1, uptodateness_vector, &drsuapi->gensec_skey, - st, NULL); + st, NULL, + &st->op->source_dsa->notify_uSN); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); composite_error(c, werror_to_ntstatus(status)); diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 2f4efc0fee..5ae622eeaa 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -212,7 +212,8 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector, const DATA_BLOB *gensec_skey, TALLOC_CTX *mem_ctx, - struct dsdb_extended_replicated_objects **_out) + struct dsdb_extended_replicated_objects **_out, + uint64_t *notify_uSN) { WERROR status; const struct dsdb_schema *schema; @@ -221,6 +222,7 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, const struct drsuapi_DsReplicaObjectListItemEx *cur; uint32_t i; int ret; + uint64_t seq_num1, seq_num2; schema = dsdb_get_schema(ldb); if (!schema) { @@ -280,6 +282,14 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, return WERR_FOOBAR; } + ret = dsdb_load_partition_usn(ldb, out->partition_dn, &seq_num1); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ " Failed to load partition uSN\n")); + talloc_free(out); + ldb_transaction_cancel(ldb); + return WERR_FOOBAR; + } + ret = ldb_extended(ldb, DSDB_EXTENDED_REPLICATED_OBJECTS_OID, out, &ext_res); if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to apply records: %s: %s\n", @@ -290,6 +300,28 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, } talloc_free(ext_res); + ret = ldb_transaction_prepare_commit(ldb); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ " Failed to prepare commit of transaction\n")); + talloc_free(out); + return WERR_FOOBAR; + } + + ret = dsdb_load_partition_usn(ldb, out->partition_dn, &seq_num2); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ " Failed to load partition uSN\n")); + talloc_free(out); + ldb_transaction_cancel(ldb); + return WERR_FOOBAR; + } + + /* if this replication partner didn't need to be notified + before this transaction then it still doesn't need to be + notified, as the changes came from this server */ + if (seq_num2 > seq_num1 && seq_num1 <= *notify_uSN) { + *notify_uSN = seq_num2; + } + ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { DEBUG(0,(__location__ " Failed to commit transaction\n")); @@ -297,6 +329,7 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, return WERR_FOOBAR; } + DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n", out->num_objects, out->linked_attributes_count, ldb_dn_get_linearized(out->partition_dn))); diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 5e516afaee..327a64daea 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -168,6 +168,7 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, uint32_t i; int ret; bool ok; + uint64_t seq_num; DEBUG(0,("Analyze and apply schema objects\n")); @@ -301,7 +302,7 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, s_dsa, uptodateness_vector, c->gensec_skey, - s, &objs); + s, &objs, &seq_num); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); return werror_to_ntstatus(status); @@ -465,6 +466,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, struct repsFromTo1 *s_dsa; char *tmp_dns_name; uint32_t i; + uint64_t seq_num; s_dsa = talloc_zero(s, struct repsFromTo1); NT_STATUS_HAVE_NO_MEMORY(s_dsa); @@ -541,7 +543,7 @@ static NTSTATUS vampire_store_chunk(void *private_data, s_dsa, uptodateness_vector, c->gensec_skey, - s, &objs); + s, &objs, &seq_num); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); return werror_to_ntstatus(status); diff --git a/source4/torture/libnet/libnet_BecomeDC.c b/source4/torture/libnet/libnet_BecomeDC.c index 7d1c025f18..81bdf342b2 100644 --- a/source4/torture/libnet/libnet_BecomeDC.c +++ b/source4/torture/libnet/libnet_BecomeDC.c @@ -140,6 +140,7 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s, uint32_t i; int ret; bool ok; + uint64_t seq_num; DEBUG(0,("Analyze and apply schema objects\n")); @@ -273,7 +274,7 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s, s_dsa, uptodateness_vector, c->gensec_skey, - s, &objs); + s, &objs, &seq_num); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); return werror_to_ntstatus(status); @@ -447,6 +448,7 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data, struct repsFromTo1 *s_dsa; char *tmp_dns_name; uint32_t i; + uint64_t seq_num; s_dsa = talloc_zero(s, struct repsFromTo1); NT_STATUS_HAVE_NO_MEMORY(s_dsa); @@ -514,7 +516,7 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data, s_dsa, uptodateness_vector, c->gensec_skey, - s, &objs); + s, &objs, &seq_num); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); return werror_to_ntstatus(status); -- cgit From 08f144777d4fc8168d27e71fe107718ba99223c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 14:07:06 -0700 Subject: s4-ldb: expose ldb_transaction_prepare_commit() in ldb It is useful to be able to control the 2 phase commit from application code (s4 replication uses it) --- source4/lib/ldb/common/ldb.c | 78 +++++++++++++++++++++++++---------- source4/lib/ldb/include/ldb.h | 5 +++ source4/lib/ldb/include/ldb_private.h | 2 + 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 6939cefb59..613451a7c2 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -316,6 +316,7 @@ int ldb_transaction_start(struct ldb_context *ldb) /* start a new transaction */ ldb->transaction_active++; + ldb->prepare_commit_done = false; FIRST_OP(ldb, start_transaction); @@ -334,6 +335,57 @@ int ldb_transaction_start(struct ldb_context *ldb) return status; } +/* + prepare for transaction commit (first phase of two phase commit) +*/ +int ldb_transaction_prepare_commit(struct ldb_context *ldb) +{ + struct ldb_module *module; + int status; + + if (ldb->prepare_commit_done) { + return LDB_SUCCESS; + } + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 1) { + return LDB_SUCCESS; + } + + ldb->prepare_commit_done = true; + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "prepare commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + /* call prepare transaction if available */ + FIRST_OP_NOERR(ldb, prepare_commit); + if (module == NULL) { + return LDB_SUCCESS; + } + + status = module->ops->prepare_commit(module); + if (status != LDB_SUCCESS) { + /* if a module fails the prepare then we need + to call the end transaction for everyone */ + FIRST_OP(ldb, end_transaction); + module->ops->end_transaction(module); + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction prepare commit: %s (%d)", + ldb_strerror(status), + status); + } + } + + return status; +} + + /* commit a transaction */ @@ -342,6 +394,10 @@ int ldb_transaction_commit(struct ldb_context *ldb) struct ldb_module *module; int status; + status = ldb_transaction_prepare_commit(ldb); + if (status != LDB_SUCCESS) { + return status; + } ldb->transaction_active--; @@ -361,27 +417,6 @@ int ldb_transaction_commit(struct ldb_context *ldb) return LDB_ERR_OPERATIONS_ERROR; } - /* call prepare transaction if available */ - FIRST_OP_NOERR(ldb, prepare_commit); - if (module != NULL) { - status = module->ops->prepare_commit(module); - if (status != LDB_SUCCESS) { - /* if a module fails the prepare then we need - to call the end transaction for everyone */ - /* preserve err string */ - FIRST_OP(ldb, end_transaction); - module->ops->end_transaction(module); - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction prepare commit: %s (%d)", - ldb_strerror(status), - status); - } - return status; - } - } - ldb_reset_err_string(ldb); FIRST_OP(ldb, end_transaction); @@ -401,6 +436,7 @@ int ldb_transaction_commit(struct ldb_context *ldb) return status; } + /* cancel a transaction */ diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 04b0a22fc1..2c89031919 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -1283,6 +1283,11 @@ int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, ui */ int ldb_transaction_start(struct ldb_context *ldb); +/** + first phase of two phase commit + */ +int ldb_transaction_prepare_commit(struct ldb_context *ldb); + /** commit a transaction */ diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index c12f33495b..1fb3109b1b 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -114,6 +114,8 @@ struct ldb_context { char *modules_dir; struct tevent_context *ev_ctx; + + bool prepare_commit_done; }; /* The following definitions come from lib/ldb/common/ldb.c */ -- cgit From 7b3b66d7a22a4f2b460f979f4f489b09464f6946 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 14:07:43 -0700 Subject: s4-ldb: ldap attribute names can contain a '.' When they are of the form of OIDs --- source4/lib/ldb/common/ldb_parse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index 654a635abf..0fab0026f3 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -267,7 +267,8 @@ static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char * p++; } - while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-')) { /* attribute names can only be alphanums */ + while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { + /* attribute names can only be alphanums */ p++; } -- cgit