[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1361-gd3d6713

Andrew Tridgell tridge at samba.org
Thu Sep 3 02:37:02 MDT 2009


The branch, master has been updated
       via  d3d6713c599fa74f5fdd890bd00ab0dd721749d8 (commit)
       via  b72b8f6e7d6a83999153b71edd6f50a1803eff95 (commit)
       via  47f52e7a337f1f0e35c77f480146bbee3ac1d309 (commit)
       via  7dbe0797b1c98fc63af20af03c2b36cc04a7386e (commit)
       via  bfccc4590dc94b37258b7225d153c4c01d1a28d6 (commit)
       via  c37f290043c55ec6428a313b4ec3ca2f91e5e98e (commit)
       via  617bbd913dcd6335cfcee3db6d23e8d3262dd566 (commit)
       via  348824da759a78b06e75d6ab7f8f85aa9912957c (commit)
       via  aff1e623aadb5ec67ac2bd83abb53f3e6f5280d4 (commit)
       via  e6257d94de5ba72f4c14ee13f3643f39d2caf5c6 (commit)
       via  95fd3c8ee061100fc5949440f257e53084df72a7 (commit)
       via  5d23ad8c2d5f647a1bd2fb41ec63e5c5bf245ad2 (commit)
       via  642a84c12927176726c24f5d709a3479c36bd7e3 (commit)
       via  127bf61a4006c60a70b0e43b61c60e532990d3b8 (commit)
       via  c033b2dd2d09e3699e0756c8cc21388e383d8fd7 (commit)
      from  5c54e4c103c99ec5be836cdd51469ce2558366fb (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d3d6713c599fa74f5fdd890bd00ab0dd721749d8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:36:02 2009 +1000

    another large change to the linked_attribute module
    
    This one copes with deleted objects where linked attributes have been
    set on the module. We hit this when we do the ldb wipe at the start of
    a provision, which trigers linked attribute updates, but for objects
    that have disappeared. We need to ensure that the linked attribute
    updates only happen on the right object, and if the object gets
    re-created (as happens with a provision) then it is not the right
    object.
    
    To cope with this we record the GUID of the object when the operation
    that triggered the linked attribute update comes in, and then find the
    DN by suing that GUID when we apply the change in the prepare commit
    hook.

commit b72b8f6e7d6a83999153b71edd6f50a1803eff95
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:33:17 2009 +1000

    hook on prepare_commit instead of transaction_end
    
    This allows for safe transaction end aborts

commit 47f52e7a337f1f0e35c77f480146bbee3ac1d309
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:32:42 2009 +1000

    greatly simplify the transaction processing in the partition module
    
    Now that ldb is calling prepare commit separately, the job of the
    partition module on transaction end is much simpler (and more robust!)

commit 7dbe0797b1c98fc63af20af03c2b36cc04a7386e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:31:45 2009 +1000

    show more reasonable object counts during a vampire
    
    We now show the total number of objects we have processed, which gives
    the user a better idea of how much has been done. A vampire on a large
    domain can take an hour or more (which needs to be fixed btw, it is a
    problem with the lack of scalability of the ltdb index code). Watching
    the same msg for an hour makes you wonder if any progress is being
    made!

commit bfccc4590dc94b37258b7225d153c4c01d1a28d6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:29:58 2009 +1000

    always use prepare_commit in ldb transaction commits if possible
    
    The reason we need this is to make multi-tdb transactions safe, with
    the partition module. The linked_attributes and repl_meta_data modules
    now do extra processing when the transaction ends, and that processing
    can fail. When it fails we need to cancel the transaction, which we
    can only do if the hook is on the prepare commit instead of the end
    transaction call. Otherwise the partition module cannot ensure that no
    commit has been done on another partition.

commit c37f290043c55ec6428a313b4ec3ca2f91e5e98e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 18:27:29 2009 +1000

    added dsdb_find_guid_by_dn()
    
    This will be used by the linked_attribute module

commit 617bbd913dcd6335cfcee3db6d23e8d3262dd566
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 13:03:31 2009 +1000

    allow setting of the debug level in python from C

commit 348824da759a78b06e75d6ab7f8f85aa9912957c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:55:57 2009 +1000

    change repl_meta_data to process linked_attributes structures in end_transaction
    
    When running at functional level 2 or above, the repl_meta_data module
    can receive linked attribute structures from the repl replication
    task. These attributes can come through DRS before the associated
    objects have been created. To cope with this, we need to process
    linked attributes in the end_transaction hook.

commit aff1e623aadb5ec67ac2bd83abb53f3e6f5280d4
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:53:36 2009 +1000

    fixed transaction handling in linked_attributes module
    
    We need to call down to the next transaction function when we finish
    in linked_attributes.
    
    This also changes linked_attributes to use the common
    dsdb_find_dn_by_guid() function

commit e6257d94de5ba72f4c14ee13f3643f39d2caf5c6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:52:31 2009 +1000

    add the the linked attributes elements to the repl structure
    
    This exposes the linked_attributes to the repl_meta_data module

commit 95fd3c8ee061100fc5949440f257e53084df72a7
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:51:42 2009 +1000

    tell the server that we support linked attribute replication

commit 5d23ad8c2d5f647a1bd2fb41ec63e5c5bf245ad2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:51:22 2009 +1000

    added dsdb_find_dn_by_guid()
    
    This came from the linked_attributes module, but now the
    repl_meta_data module needs the same functionality, so move it to a
    common routine.

commit 642a84c12927176726c24f5d709a3479c36bd7e3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 3 12:50:19 2009 +1000

    fix the ndr print routines for samba4
    
    This uses a hackish #if just for samba4. The proper fix is much more
    complex.

commit 127bf61a4006c60a70b0e43b61c60e532990d3b8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 2 21:51:02 2009 +1000

    support config files in the current directory

commit c033b2dd2d09e3699e0756c8cc21388e383d8fd7
Author: Anatoliy Atanasov <anatoliy.atanasov at postpath.com>
Date:   Tue Aug 25 18:39:06 2009 +0300

    Fix for DSSYNC test against Windows 2003

-----------------------------------------------------------------------

Summary of changes:
 librpc/ndr/ndr.c                                   |   16 ++
 source4/dsdb/common/util.c                         |   98 +++++++
 source4/dsdb/repl/drepl_service.c                  |    7 +-
 source4/dsdb/repl/replicated_objects.c             |    5 +
 source4/dsdb/samdb/ldb_modules/linked_attributes.c |  160 +++++-------
 source4/dsdb/samdb/ldb_modules/partition.c         |   80 ++----
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c    |  283 +++++++++++++++++++-
 source4/dsdb/samdb/ldb_modules/update_keytab.c     |    8 +-
 source4/dsdb/samdb/samdb.h                         |    5 +-
 source4/lib/ldb/common/ldb.c                       |   37 +++-
 source4/lib/ldb/common/ldb_modules.c               |   19 ++-
 source4/lib/ldb/include/ldb_module.h               |    1 +
 source4/libnet/libnet_vampire.c                    |   22 ++-
 source4/param/provision.c                          |    5 +-
 source4/param/util.c                               |    9 +-
 source4/scripting/python/pyglue.c                  |   11 +
 source4/scripting/python/samba/provision.py        |    4 +-
 17 files changed, 596 insertions(+), 174 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index 8188ec9..837690b 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -255,6 +255,14 @@ _PUBLIC_ void ndr_print_function_debug(ndr_print_function_t fn, const char *name
 	ndr->print = ndr_print_debug_helper;
 	ndr->depth = 1;
 	ndr->flags = 0;
+
+	/* this is a s4 hack until we build up the courage to pass
+	 * this all the way down 
+	 */
+#if _SAMBA_BUILD_ == 4
+	ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+#endif
+
 	fn(ndr, name, flags, ptr);
 	talloc_free(ndr);
 }
@@ -276,6 +284,14 @@ _PUBLIC_ char *ndr_print_struct_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, c
 	ndr->print = ndr_print_string_helper;
 	ndr->depth = 1;
 	ndr->flags = 0;
+
+	/* this is a s4 hack until we build up the courage to pass
+	 * this all the way down 
+	 */
+#if _SAMBA_BUILD_ == 4
+	ndr->iconv_convenience = smb_iconv_convenience_init(talloc_autofree_context(), "ASCII", "UTF-8", true);
+#endif
+
 	fn(ndr, name, ptr);
 	ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
 failed:
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index af31f17..0ffec8a 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2042,3 +2042,101 @@ struct ldb_dn *samdb_domain_to_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
 	return samdb_result_dn(ldb, mem_ctx, res_domain_ref->msgs[0], "nCName", NULL);
 
 }
+
+
+/*
+  use a GUID to find a DN
+ */
+int dsdb_find_dn_by_guid(struct ldb_context *ldb, 
+			 TALLOC_CTX *mem_ctx,
+			 const char *guid_str, struct ldb_dn **dn)
+{
+	int ret;
+	struct ldb_result *res;
+	const char *attrs[] = { NULL };
+	struct ldb_request *search_req;
+	char *expression;
+	struct ldb_search_options_control *options;
+
+	expression = talloc_asprintf(mem_ctx, "objectGUID=%s", guid_str);
+	if (!expression) {
+		DEBUG(0, (__location__ ": out of memory\n"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	res = talloc_zero(mem_ctx, struct ldb_result);
+	if (!res) {
+		DEBUG(0, (__location__ ": out of memory\n"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = ldb_build_search_req(&search_req, ldb, mem_ctx,
+				   ldb_get_default_basedn(ldb),
+				   LDB_SCOPE_SUBTREE,
+				   expression, attrs,
+				   NULL,
+				   res, ldb_search_default_callback,
+				   NULL);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* we need to cope with cross-partition links, so search for
+	   the GUID over all partitions */
+	options = talloc(search_req, struct ldb_search_options_control);
+	if (options == NULL) {
+		DEBUG(0, (__location__ ": out of memory\n"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
+
+	ret = ldb_request_add_control(search_req,
+				      LDB_CONTROL_SEARCH_OPTIONS_OID,
+				      true, options);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_request(ldb, search_req);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_wait(search_req->handle, LDB_WAIT_ALL);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* this really should be exactly 1, but there is a bug in the
+	   partitions module that can return two here with the
+	   search_options control set */
+	if (res->count < 1) {
+		return LDB_ERR_NO_SUCH_OBJECT;
+	}
+
+	*dn = res->msgs[0]->dn;
+
+	return LDB_SUCCESS;
+}
+
+
+/*
+  use a DN to find a GUID
+ */
+int dsdb_find_guid_by_dn(struct ldb_context *ldb, 
+			 struct ldb_dn *dn, struct GUID *guid)
+{
+	int ret;
+	struct ldb_result *res;
+	const char *attrs[] = { "objectGUID" };
+	TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+
+	ret = ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return ret;
+	}
+	*guid = samdb_result_guid(res->msgs[0], "objectGUID");
+	talloc_free(tmp_ctx);
+	return LDB_SUCCESS;
+}
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 53e4aec..27572af 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -73,12 +73,7 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
-#if 0
-	if (s->domain_behavior_version == 2) {
-		/* TODO: find out how this is really triggered! */
-		bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
-	}
-#endif
+	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
 	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index 8018254..4005d0b 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -231,6 +231,11 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb,
 					       out->num_objects);
 	W_ERROR_HAVE_NO_MEMORY(out->objects);
 
+	/* 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 == out->num_objects) {
 			return WERR_FOOBAR;
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index 3486b7f..fc101bd 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -32,6 +32,7 @@
 #include "ldb_module.h"
 #include "dlinklist.h"
 #include "dsdb/samdb/samdb.h"
+#include "librpc/gen_ndr/ndr_misc.h"
 
 struct la_private {
 	struct la_context *la_list;
@@ -41,7 +42,7 @@ struct la_op_store {
 	struct la_op_store *next;
 	struct la_op_store *prev;
 	enum la_op {LA_OP_ADD, LA_OP_DEL} op;
-	struct ldb_dn *dn;
+	struct GUID guid;
 	char *name;
 	char *value;
 };
@@ -99,15 +100,46 @@ static struct la_context *linked_attributes_init(struct ldb_module *module,
 	return ac;
 }
 
+/*
+  turn a DN into a GUID
+ */
+static int la_guid_from_dn(struct la_context *ac, struct ldb_dn *dn, struct GUID *guid)
+{
+	const struct ldb_val *guid_val;
+	int ret;
+
+	guid_val = ldb_dn_get_extended_component(dn, "GUID");
+	if (guid_val) {
+		/* there is a GUID embedded in the DN */
+		enum ndr_err_code ndr_err;
+		ndr_err = ndr_pull_struct_blob(guid_val, ac, NULL, guid,
+					       (ndr_pull_flags_fn_t)ndr_pull_GUID);
+		if (ndr_err != NDR_ERR_SUCCESS) {
+			DEBUG(0,(__location__ ": Failed to parse GUID\n"));
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+	} else {
+		ret = dsdb_find_guid_by_dn(ldb_module_get_ctx(ac->module), dn, guid);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(4,(__location__ ": Failed to find GUID for dn %s\n",
+				 ldb_dn_get_linearized(dn)));
+			return ret;
+		}
+	}
+	return LDB_SUCCESS;
+}
+
+
 /* Common routine to handle reading the attributes and creating a
  * series of modify requests */
 static int la_store_op(struct la_context *ac,
 		       enum la_op op, struct ldb_val *dn,
-			const char *name)
+		       const char *name)
 {
 	struct ldb_context *ldb;
 	struct la_op_store *os;
 	struct ldb_dn *op_dn;
+	int ret;
 
 	ldb = ldb_module_get_ctx(ac->module);
 
@@ -126,7 +158,20 @@ static int la_store_op(struct la_context *ac,
 
 	os->op = op;
 
-	os->dn = talloc_steal(os, op_dn);
+	ret = la_guid_from_dn(ac, op_dn, &os->guid);
+	if (ret == LDB_ERR_NO_SUCH_OBJECT && ac->req->operation == LDB_DELETE) {
+		/* we are deleting an object, and we've found it has a
+		 * forward link to a target that no longer
+		 * exists. This is not an error in the delete, and we
+		 * should just not do the deferred delete of the
+		 * target attribute
+		 */
+		talloc_free(os);
+		return LDB_SUCCESS;
+	}
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
 
 	os->name = talloc_strdup(os, name);
 	if (!os->name) {
@@ -1025,87 +1070,10 @@ static int la_down_req(struct la_context *ac)
   use the GUID part of an extended DN to find the target DN, in case
   it has moved
  */
-static int la_find_dn_target(struct ldb_module *module, struct la_context *ac, struct ldb_dn **dn)
+static int la_find_dn_target(struct ldb_module *module, struct la_context *ac, 
+			     struct GUID *guid, struct ldb_dn **dn)
 {
-	const struct ldb_val *guid;
-	struct ldb_context *ldb;
-	int ret;
-	struct ldb_result *res;
-	const char *attrs[] = { NULL };
-	struct ldb_request *search_req;
-	char *expression;
-	struct ldb_search_options_control *options;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	guid = ldb_dn_get_extended_component(*dn, "GUID");
-	if (guid == NULL) {
-		return LDB_SUCCESS;
-	}
-
-	expression = talloc_asprintf(ac, "objectGUID=%s", ldb_binary_encode(ac, *guid));
-	if (!expression) {
-		ldb_oom(ldb);
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	res = talloc_zero(ac, struct ldb_result);
-	if (!res) {
-		ldb_oom(ldb);
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	ret = ldb_build_search_req(&search_req, ldb, ac,
-				   ldb_get_default_basedn(ldb),
-				   LDB_SCOPE_SUBTREE,
-				   expression, attrs,
-				   NULL,
-				   res, ldb_search_default_callback,
-				   NULL);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	/* we need to cope with cross-partition links, so search for
-	   the GUID over all partitions */
-	options = talloc(search_req, struct ldb_search_options_control);
-	if (options == NULL) {
-		ldb_oom(ldb);
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-	options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
-
-	ret = ldb_request_add_control(search_req,
-				      LDB_CONTROL_SEARCH_OPTIONS_OID,
-				      true, options);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ret = ldb_next_request(module, search_req);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ret = ldb_wait(search_req->handle, LDB_WAIT_ALL);
-	if (ret != LDB_SUCCESS) {
-		ldb_debug(ldb, LDB_DEBUG_ERROR, "GUID search failed (%s) for %s\n", 
-			  ldb_errstring(ldb), ldb_dn_get_extended_linearized(ac, *dn, 1));
-		return ret;
-	}
-
-	/* this really should be exactly 1, but there is a bug in the
-	   partitions module that can return two here with the
-	   search_options control set */
-	if (res->count < 1) {
-		ldb_debug(ldb, LDB_DEBUG_ERROR, "GUID search gave count=%d for %s\n", 
-			  res->count, ldb_dn_get_extended_linearized(ac, *dn, 1));
-		return LDB_ERR_OPERATIONS_ERROR;
-	}
-
-	*dn = res->msgs[0]->dn;
-
-	return LDB_SUCCESS;
+	return dsdb_find_dn_by_guid(ldb_module_get_ctx(ac->module), ac, GUID_string(ac, guid), dn);
 }
 
 /* apply one la_context op change */
@@ -1126,8 +1094,7 @@ static int la_do_op_request(struct ldb_module *module, struct la_context *ac, st
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	new_msg->dn = op->dn;
-	ret = la_find_dn_target(module, ac, &new_msg->dn);
+	ret = la_find_dn_target(module, ac, &op->guid, &new_msg->dn);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
@@ -1203,7 +1170,9 @@ static int la_do_mod_request(struct ldb_module *module, struct la_context *ac)
 	for (op = ac->ops; op; op=op->next) {
 		int ret = la_do_op_request(module, ac, op);
 		if (ret != LDB_SUCCESS) {
-			return ret;
+			if (ret != LDB_ERR_NO_SUCH_OBJECT) {
+				return ret;
+			}
 		}
 	}
 
@@ -1230,14 +1199,14 @@ static int linked_attributes_start_transaction(struct ldb_module *module)
 	}
 	la_private->la_list = NULL;
 	ldb_module_set_private(module, la_private);
-	return LDB_SUCCESS;
+	return ldb_next_start_trans(module);
 }
 
 /*
-  on end transaction we loop over our queued la_context structures and
-  apply each of them  
+  on prepare commit we loop over our queued la_context structures
+  and apply each of them
  */
-static int linked_attributes_end_transaction(struct ldb_module *module)
+static int linked_attributes_prepare_commit(struct ldb_module *module)
 {
 	struct la_private *la_private = 
 		talloc_get_type(ldb_module_get_private(module), struct la_private);
@@ -1253,12 +1222,15 @@ static int linked_attributes_end_transaction(struct ldb_module *module)
 		ac->req = NULL;
 		ret = la_do_mod_request(module, ac);
 		if (ret != LDB_SUCCESS) {
-			ret = la_do_mod_request(module, ac);
+			DEBUG(0,(__location__ ": Failed mod request ret=%d\n", ret));
 			return ret;
 		}
 	}
+
+	talloc_free(la_private);
+	ldb_module_set_private(module, NULL);	
 	
-	return LDB_SUCCESS;
+	return ldb_next_prepare_commit(module);
 }
 
 static int linked_attributes_del_transaction(struct ldb_module *module)
@@ -1267,7 +1239,7 @@ static int linked_attributes_del_transaction(struct ldb_module *module)
 		talloc_get_type(ldb_module_get_private(module), struct la_private);
 	talloc_free(la_private);
 	ldb_module_set_private(module, NULL);
-	return LDB_SUCCESS;
+	return ldb_next_del_trans(module);
 }
 
 
@@ -1278,6 +1250,6 @@ _PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {
 	.del               = linked_attributes_del,
 	.rename            = linked_attributes_rename,
 	.start_transaction = linked_attributes_start_transaction,
-	.end_transaction   = linked_attributes_end_transaction,
+	.prepare_commit    = linked_attributes_prepare_commit,
 	.del_transaction   = linked_attributes_del_transaction,
 };
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 515d437..e8b55a4 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -680,97 +680,74 @@ static int partition_start_trans(struct ldb_module *module)
 	return LDB_SUCCESS;
 }
 
-/* end a transaction */
-static int partition_end_trans(struct ldb_module *module)
+/* prepare for a commit */
+static int partition_prepare_commit(struct ldb_module *module)
 {
-	int i, ret, final_ret;
+	int i;
 	struct partition_private_data *data = talloc_get_type(module->private_data, 
 							      struct partition_private_data);
-	ret = ldb_next_end_trans(module);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
 
-	/* if the backend has a prepare_commit op then use that, to ensure
-	   that all partitions are committed safely together */
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
-		struct ldb_module *next_end = data->partitions[i]->module;
 		struct ldb_module *next_prepare = data->partitions[i]->module;
-		struct ldb_module *next_del = data->partitions[i]->module;
+		int ret;
 
 		PARTITION_FIND_OP_NOERROR(next_prepare, prepare_commit);
 		if (next_prepare == NULL) {
 			continue;
 		}
 
-		PARTITION_FIND_OP(next_end, end_transaction);
-		PARTITION_FIND_OP(next_del, del_transaction);
-
-		if (next_end != next_prepare || next_del != next_end) {
-			ldb_asprintf_errstring(ldb_module_get_ctx(module), "ERROR: Mismatch between prepare and commit ops in ldb module");
-			return LDB_ERR_OPERATIONS_ERROR;
-		}
-		
 		ret = next_prepare->ops->prepare_commit(next_prepare);
 		if (ret != LDB_SUCCESS) {
-			/* if one fails, cancel all but this one */
-			int j;
-			for (j=0; data->partitions[j]; j++) {
-				if (j == i) continue;
-				next_del = data->partitions[j]->module;
-				PARTITION_FIND_OP(next_del, del_transaction);
-				next_del->ops->del_transaction(next_del);
-			}
-			ldb_next_del_trans(module);
 			return ret;
 		}
 	}
 
-	/* Look at base DN */
-	/* Figure out which partition it is under */
-	/* Skip the lot if 'data' isn't here yet (initialisation) */
-	final_ret = LDB_SUCCESS;
+	return ldb_next_prepare_commit(module);
+}
+
 
+/* end a transaction */
+static int partition_end_trans(struct ldb_module *module)
+{


-- 
Samba Shared Repository


More information about the samba-cvs mailing list