[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Jul 25 05:52:03 MDT 2013


The branch, master has been updated
       via  a74c7d7 torture/drs: Expand an error message to aid debugging
       via  63c05e8 dsdb/samdb: use RECYCLED it implies DELETED...
       via  6016ba3 selftest: ensure samba4.nss.test.*using.*winbind is always tested
       via  93b8315 selftest: ensure samba4.rpc.samr.large-dc.two.samr.many is always tested
       via  5e1f279 rpc_server-drsuapi: Improve comments and DEBUG lines
       via  e9faf50 dsdb: Add assert in drepl_take_FSMO_role
       via  ae0ba6b selftest: Ensure the DC has started and and got a RID set before we proceed
       via  db9c3c6 dsdb-ridalloc: Rework ridalloc to return error strings where RID allocation fails
       via  31fb7f9 dsdb: Rework subtree_rename module to use recursive LDB_SCOPE_ONELEVEL searches
       via  03b44d2 dsdb-descriptor: Do not do a subtree search unless we have child entries
      from  ca98d81 dynconfig: Remove last s3 markers now we have just one build system

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


- Log -----------------------------------------------------------------
commit a74c7d780cb6a1e8a5a63ebbbcf36fd7cf717ea1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Jun 17 22:37:54 2013 +1000

    torture/drs: Expand an error message to aid debugging
    
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Jul 25 13:51:44 CEST 2013 on sn-devel-104

commit 63c05e820f1449b2dfa6e4f096d8270284a60bbb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jun 10 14:00:01 2013 +0200

    dsdb/samdb: use RECYCLED it implies DELETED...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 6016ba3a02c5418b44bb61d434f3a25d6e5991b8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Jul 13 19:35:52 2013 +1000

    selftest: ensure samba4.nss.test.*using.*winbind is always tested
    
    With the winbind fixes now in master this should be more reliable.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 93b83151c9563f4c1f47b925fed079d275f8ec43
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Jul 13 19:34:45 2013 +1000

    selftest: ensure samba4.rpc.samr.large-dc.two.samr.many is always tested
    
    This test should now be more reliable with the over-allocation of
    RID values now fixed.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 5e1f2795f28b0a213b4529e046edec68caa3bd41
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 28 09:19:48 2013 +1000

    rpc_server-drsuapi: Improve comments and DEBUG lines
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit e9faf50ee123a8d1d647ebffa39107ca0dce756c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Jun 28 09:15:16 2013 +1000

    dsdb: Add assert in drepl_take_FSMO_role
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit ae0ba6bd833f71c4337ae3b6621bf797cb3c48c2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jun 19 11:33:36 2013 +1000

    selftest: Ensure the DC has started and and got a RID set before we proceed
    
    This avoids errors when a busy DC has not yet fetched a RID set, showing up
    as flapping tests when users are created, such as the samr.large-dc test.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit db9c3c62c89e1328872e3fdedde22b78770728a9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jun 19 10:30:48 2013 +1000

    dsdb-ridalloc: Rework ridalloc to return error strings where RID allocation fails
    
    We now also only poke the RID manager once per request.
    
    This may help track down why RID allocation can fail, as while we
    never wait for the RID set to be created/updated, it may be the only
    clue the admin gets as to why the async allocations were failing.
    
    Andrew Bartlett
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 31fb7f9c1b93b0f2114dec5096e43616ed317720
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sun Jun 23 21:38:40 2013 +1000

    dsdb: Rework subtree_rename module to use recursive LDB_SCOPE_ONELEVEL searches
    
    This should be more efficient, particularly in the leaf node case when renaming and
    deleting entries on large databases.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 03b44d26fd17761675fe33ab29e8f325f59d8a5c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sun Jun 23 19:47:35 2013 +1000

    dsdb-descriptor: Do not do a subtree search unless we have child entries
    
    This avoids a subtree search here in most cases where an object is deleted.
    
    Andrew Bartlett
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 selftest/flapping                                  |    2 -
 selftest/target/Samba4.pm                          |   22 ++-
 source4/dsdb/repl/drepl_fsmo.c                     |    7 +-
 source4/dsdb/samdb/cracknames.c                    |    2 +-
 source4/dsdb/samdb/ldb_modules/descriptor.c        |   33 +++-
 source4/dsdb/samdb/ldb_modules/linked_attributes.c |    4 +-
 source4/dsdb/samdb/ldb_modules/ridalloc.c          |   56 ++++--
 source4/dsdb/samdb/ldb_modules/subtree_rename.c    |  201 ++++++++++----------
 .../dsdb/samdb/ldb_modules/wscript_build_server    |    2 +-
 source4/rpc_server/drsuapi/getncchanges.c          |    7 +-
 source4/torture/drs/python/delete_object.py        |    2 +-
 11 files changed, 203 insertions(+), 135 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/flapping b/selftest/flapping
index 170bf7b..d939650 100644
--- a/selftest/flapping
+++ b/selftest/flapping
@@ -24,5 +24,3 @@
 ^samba3.raw.acls.inheritance\(plugin_s4_dc\) # Seems to flap - succeeds on sn-devel, fails on Fedora 16
 ^samba3.raw.samba3checkfsp.samba3checkfsp\(plugin_s4_dc\) # Seems to flap - succeeds on sn-devel, fails on Fedora 16
 ^samba3.raw.samba3closeerr.samba3closeerr\(plugin_s4_dc\) # Seems to flap - succeeds on sn-devel, fails on Fedora 16
-^samba4.nss.test.*using.*winbind # fails sometimes on sn-devel
-^samba4.rpc.samr.large-dc.two.samr.many.*\(vampire_dc\) # often fails on sn-devel-104, rid allocation?
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index e279beb..e574b48 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -141,6 +141,7 @@ sub check_or_start($$$)
 sub wait_for_start($$)
 {
 	my ($self, $testenv_vars) = @_;
+	my $ret;
 	# give time for nbt server to register its names
 	print "delaying for nbt name registration\n";
 	sleep 2;
@@ -161,7 +162,25 @@ sub wait_for_start($$)
 	system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
 	system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
 
+	# Ensure we have the first RID Set before we start tests.  This makes the tests more reliable.
+	if ($testenv_vars->{SERVER_ROLE} eq "domain controller" and not ($testenv_vars->{NETBIOS_NAME} eq "rodc")) {
+	    print "waiting for working LDAP and a RID Set to be allocated\n";
+	    my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
+	    my $count = 0;
+	    my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
+	    my $rid_set_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
+	    while (system("$ldbsearch -H ldap://$testenv_vars->{SERVER} -U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} -s base -b \"$rid_set_dn\" rIDAllocationPool > /dev/null") != 0) {
+		$count++;
+		if ($count > 40) {
+		    $ret = 1;
+		    last;
+		}
+		sleep(1);
+	    }
+	}
 	print $self->getlog_env($testenv_vars);
+
+	return $ret
 }
 
 sub write_ldb_file($$$)
@@ -692,7 +711,8 @@ nogroup:x:65534:nobody
 	        NSS_WRAPPER_WINBIND_SO_PATH => Samba::nss_wrapper_winbind_so_path($self),
                 LOCAL_PATH => $ctx->{share},
                 UID_RFC2307TEST => $uid_rfc2307test,
-                GID_RFC2307TEST => $gid_rfc2307test
+                GID_RFC2307TEST => $gid_rfc2307test,
+                SERVER_ROLE => $ctx->{server_role}
 	};
 
 	return $ret;
diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c
index 37fb684..7a107da 100644
--- a/source4/dsdb/repl/drepl_fsmo.c
+++ b/source4/dsdb/repl/drepl_fsmo.c
@@ -91,11 +91,10 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
 		extended_op = DRSUAPI_EXOP_FSMO_REQ_PDC;
 		break;
 	default:
-		DEBUG(2,("Unknown role %u in role transfer\n",
+		DEBUG(0,("Unknown role %u in role transfer\n",
 			 (unsigned)role));
-		r->out.result = WERR_DS_DRA_INTERNAL_ERROR;
-		talloc_free(tmp_ctx);
-		return NT_STATUS_OK;
+		/* IRPC messages are trusted, so this really should not happen */
+		smb_panic("Unknown role despite dsdb_get_fsmo_role_info success");
 	}
 
 	ret = samdb_dn_is_our_ntdsa(service->samdb, role_owner_dn, &is_us);
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 15463a7..0c4cdfc 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -945,7 +945,7 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
 			real_search_dn = NULL;
 		}
 		if (format_desired == DRSUAPI_DS_NAME_FORMAT_GUID){
-			 dsdb_flags = dsdb_flags| DSDB_SEARCH_SHOW_DELETED;
+			 dsdb_flags |= DSDB_SEARCH_SHOW_RECYCLED;
 		}
 
 		/* search with the 'phantom root' flag */
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index 7743baa..ceac8db 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -1186,16 +1186,47 @@ static int descriptor_sd_propagation_recursive(struct ldb_module *module,
 	const char * const no_attrs[] = { "@__NONE__", NULL };
 	struct descriptor_changes *c;
 	struct descriptor_changes *stopped_stack = NULL;
+	enum ldb_scope scope;
 	int ret;
 
 	/*
+	 * First confirm this object has children, or exists (depending on change->force_self)
+	 * 
+	 * LDB_SCOPE_SUBTREE searches are expensive.
+	 *
+	 * Note: that we do not search for deleted/recycled objects
+	 */
+	ret = dsdb_module_search(module,
+				 change,
+				 &res,
+				 change->dn,
+				 LDB_SCOPE_ONELEVEL,
+				 no_attrs,
+				 DSDB_FLAG_NEXT_MODULE |
+				 DSDB_FLAG_AS_SYSTEM,
+				 NULL, /* parent_req */
+				 "(objectClass=*)");
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	if (res->count == 0 && !change->force_self) {
+		TALLOC_FREE(res);
+		return LDB_SUCCESS;
+	} else if (res->count == 0 && change->force_self) {
+		scope = LDB_SCOPE_BASE;
+	} else {
+		scope = LDB_SCOPE_SUBTREE;
+	}
+
+	/*
 	 * Note: that we do not search for deleted/recycled objects
 	 */
 	ret = dsdb_module_search(module,
 				 change,
 				 &res,
 				 change->dn,
-				 LDB_SCOPE_SUBTREE,
+				 scope,
 				 no_attrs,
 				 DSDB_FLAG_NEXT_MODULE |
 				 DSDB_FLAG_AS_SYSTEM,
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index eb57f91..63ccbde 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -642,7 +642,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
 		/* We need to figure out our own extended DN, to fill in as the backlink target */
 		if (ret == LDB_SUCCESS) {
 			ret = dsdb_request_add_controls(search_req,
-							DSDB_SEARCH_SHOW_DELETED |
+							DSDB_SEARCH_SHOW_RECYCLED |
 							DSDB_SEARCH_SHOW_EXTENDED_DN);
 		}
 		if (ret == LDB_SUCCESS) {
@@ -1000,7 +1000,7 @@ static int la_add_callback(struct ldb_request *req, struct ldb_reply *ares)
 
 		if (ret == LDB_SUCCESS) {
 			ret = dsdb_request_add_controls(search_req,
-							DSDB_SEARCH_SHOW_DELETED |
+							DSDB_SEARCH_SHOW_RECYCLED |
 							DSDB_SEARCH_SHOW_EXTENDED_DN);
 		}
 		if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c
index c0859d3..f6738f9 100644
--- a/source4/dsdb/samdb/ldb_modules/ridalloc.c
+++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c
@@ -64,7 +64,7 @@
   returns immediately. It should be called well before we
   completely run out of RIDs
  */
-static void ridalloc_poke_rid_manager(struct ldb_module *module)
+static int ridalloc_poke_rid_manager(struct ldb_module *module)
 {
 	struct imessaging_context *msg;
 	struct server_id *server;
@@ -72,26 +72,42 @@ static void ridalloc_poke_rid_manager(struct ldb_module *module)
 	struct loadparm_context *lp_ctx =
 		(struct loadparm_context *)ldb_get_opaque(ldb, "loadparm");
 	TALLOC_CTX *tmp_ctx = talloc_new(module);
+	NTSTATUS status;
 
 	msg = imessaging_client_init(tmp_ctx, lp_ctx,
 				    ldb_get_event_context(ldb));
 	if (!msg) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(module),
+				"Failed to send MSG_DREPL_ALLOCATE_RID, "
+				"unable init client messaging context");
 		DEBUG(3,(__location__ ": Failed to create messaging context\n"));
 		talloc_free(tmp_ctx);
-		return;
+		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
 	server = irpc_servers_byname(msg, msg, "dreplsrv");
 	if (!server) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(module),
+				"Failed to send MSG_DREPL_ALLOCATE_RID, "
+				"unable to locate dreplsrv");
 		/* this means the drepl service is not running */
 		talloc_free(tmp_ctx);
-		return;
+		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
-	imessaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL);
+	status = imessaging_send(msg, server[0], MSG_DREPL_ALLOCATE_RID, NULL);
+
+	/* Only error out if an error happened, not on STATUS_MORE_ENTRIES, ie a delayed message */
+	if (NT_STATUS_IS_ERR(status)) {
+		ldb_asprintf_errstring(ldb_module_get_ctx(module),
+				"Failed to send MSG_DREPL_ALLOCATE_RID to dreplsrv at %s: %s",
+				server_id_str(tmp_ctx, server), nt_errstr(status));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_UNWILLING_TO_PERFORM;
+	}
 
-	/* we don't care if the message got through */
 	talloc_free(tmp_ctx);
+	return LDB_SUCCESS;
 }
 
 
@@ -423,8 +439,16 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me
 	}
 
 	if (!GUID_equal(&fsmo_role_guid, our_ntds_guid)) {
-		ridalloc_poke_rid_manager(module);
-		ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
+		ret = ridalloc_poke_rid_manager(module);
+		if (ret != LDB_SUCCESS) {
+			ldb_asprintf_errstring(ldb,
+					"Request for remote creation of "
+					"RID Set for this DC failed: %s",
+					ldb_errstring(ldb));
+		} else {
+			ldb_asprintf_errstring(ldb,
+					"Remote RID Set creation needed");
+		}
 		talloc_free(tmp_ctx);
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
@@ -473,8 +497,13 @@ static int ridalloc_new_own_pool(struct ldb_module *module, uint64_t *new_pool,
 	}
 	
 	if (!is_us) {
-		ridalloc_poke_rid_manager(module);
-		ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
+		ret = ridalloc_poke_rid_manager(module);
+		if (ret != LDB_SUCCESS) {
+			ldb_asprintf_errstring(ldb, "Request for remote refresh of RID Set allocation failed: %s",
+					       ldb_errstring(ldb));
+		} else {
+			ldb_asprintf_errstring(ldb, "Remote RID Set refresh needed");
+		}
 		talloc_free(tmp_ctx);
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
@@ -568,12 +597,9 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid, struct ldb_r
 			 * ask async for a new pool.
 			 */
 			ret = ridalloc_new_own_pool(module, &nridset.alloc_pool, parent);
-			if (ret == LDB_ERR_UNWILLING_TO_PERFORM) {
-				ridalloc_poke_rid_manager(module);
-				talloc_free(tmp_ctx);
-				return ret;
-			}
 			if (ret != LDB_SUCCESS) {
+				ldb_asprintf_errstring(ldb, "NO RID values available: %s",
+						       ldb_errstring(ldb));
 				talloc_free(tmp_ctx);
 				return ret;
 			}
@@ -616,7 +642,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid, struct ldb_r
 		 */
 		ret = ridalloc_new_own_pool(module, &nridset.alloc_pool, parent);
 		if (ret == LDB_ERR_UNWILLING_TO_PERFORM) {
-			ridalloc_poke_rid_manager(module);
+			ldb_reset_err_string(ldb);
 			ret = LDB_SUCCESS;
 		}
 		if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/samdb/ldb_modules/subtree_rename.c b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
index ee787d1..d26dabe 100644
--- a/source4/dsdb/samdb/ldb_modules/subtree_rename.c
+++ b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
@@ -34,19 +34,11 @@
 #include <ldb_module.h>
 #include "libds/common/flags.h"
 #include "dsdb/samdb/samdb.h"
-
-struct subren_msg_store {
-	struct subren_msg_store *next;
-	struct ldb_dn *olddn;
-	struct ldb_dn *newdn;
-};
+#include "dsdb/samdb/ldb_modules/util.h"
 
 struct subtree_rename_context {
 	struct ldb_module *module;
 	struct ldb_request *req;
-
-	struct subren_msg_store *list;
-	struct subren_msg_store *current;
 };
 
 static struct subtree_rename_context *subren_ctx_init(struct ldb_module *module,
@@ -66,14 +58,11 @@ static struct subtree_rename_context *subren_ctx_init(struct ldb_module *module,
 	return ac;
 }
 
-static int subtree_rename_next_request(struct subtree_rename_context *ac);
-
 static int subtree_rename_callback(struct ldb_request *req,
 				   struct ldb_reply *ares)
 {
 	struct ldb_context *ldb;
 	struct subtree_rename_context *ac;
-	int ret;
 
 	ac = talloc_get_type(req->context, struct subtree_rename_context);
 	ldb = ldb_module_get_ctx(ac->module);
@@ -98,47 +87,8 @@ static int subtree_rename_callback(struct ldb_request *req,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
 
-	if (ac->current == NULL) {
-		/* this was the last one */
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, LDB_SUCCESS);
-	}
-
-	ret = subtree_rename_next_request(ac);
-	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
-	}
-
 	talloc_free(ares);
-	return LDB_SUCCESS;
-}
-
-static int subtree_rename_next_request(struct subtree_rename_context *ac)
-{
-	struct ldb_context *ldb;
-	struct ldb_request *req;
-	int ret;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if (ac->current == NULL) {
-		return ldb_operr(ldb);
-	}
-
-	ret = ldb_build_rename_req(&req, ldb, ac->current,
-				   ac->current->olddn,
-				   ac->current->newdn,
-				   ac->req->controls,
-				   ac, subtree_rename_callback,
-				   ac->req);
-	LDB_REQ_SET_LOCATION(req);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ac->current = ac->current->next;
-
-	return ldb_next_request(ac->module, req);
+	return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
 }
 
 static int check_constraints(struct ldb_message *msg,
@@ -297,16 +247,15 @@ static int check_constraints(struct ldb_message *msg,
 	return LDB_SUCCESS;
 }
 
-static int subtree_rename_search_callback(struct ldb_request *req,
-					  struct ldb_reply *ares)
+static int subtree_rename_search_onelevel_callback(struct ldb_request *req,
+						   struct ldb_reply *ares)
 {
-	struct subren_msg_store *store;
 	struct subtree_rename_context *ac;
 	int ret;
 
 	ac = talloc_get_type(req->context, struct subtree_rename_context);
 
-	if (!ares || !ac->current) {
+	if (!ares) {
 		return ldb_module_done(ac->req, NULL, NULL,
 					LDB_ERR_OPERATIONS_ERROR);
 	}
@@ -317,46 +266,89 @@ static int subtree_rename_search_callback(struct ldb_request *req,
 
 	switch (ares->type) {
 	case LDB_REPLY_ENTRY:
-		if (ldb_dn_compare(ares->message->dn, ac->list->olddn) == 0) {
-			/*
-			 * This is the root entry of the originating move
-			 * respectively rename request. It has been already
-			 * stored in the list using "subtree_rename_search()".
-			 * Only this one is subject to constraint checking.
-			 */
-			ret = check_constraints(ares->message, ac,
-						ac->list->olddn,
-						ac->list->newdn);
-			if (ret != LDB_SUCCESS) {
-				return ldb_module_done(ac->req, NULL, NULL,
-						       ret);
-			}
-
-			talloc_free(ares);
-			return LDB_SUCCESS;
+	{
+		struct ldb_dn *old_dn = ares->message->dn;
+		struct ldb_dn *new_dn = ldb_dn_copy(ares, old_dn);
+		if (!new_dn) {
+			return ldb_module_oom(ac->module);
 		}
 
-		store = talloc_zero(ac, struct subren_msg_store);
-		if (store == NULL) {
+		if ( ! ldb_dn_remove_base_components(new_dn,
+				ldb_dn_get_comp_num(ac->req->op.rename.olddn))) {
 			return ldb_module_done(ac->req, NULL, NULL,
 						LDB_ERR_OPERATIONS_ERROR);
 		}
-		ac->current->next = store;
-		ac->current = store;
-
-		/* the first list element contains the base for the rename */
-		store->olddn = talloc_steal(store, ares->message->dn);
-		store->newdn = ldb_dn_copy(store, store->olddn);
 
-		if ( ! ldb_dn_remove_base_components(store->newdn,
-				ldb_dn_get_comp_num(ac->list->olddn))) {
+		if ( ! ldb_dn_add_base(new_dn, ac->req->op.rename.newdn)) {
 			return ldb_module_done(ac->req, NULL, NULL,
 						LDB_ERR_OPERATIONS_ERROR);
 		}
+		ret = dsdb_module_rename(ac->module, old_dn, new_dn, DSDB_FLAG_OWN_MODULE, req);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+
+		talloc_free(ares);
 
-		if ( ! ldb_dn_add_base(store->newdn, ac->list->newdn)) {
+		return LDB_SUCCESS;
+	}
+	case LDB_REPLY_REFERRAL:
+		/* ignore */
+		break;
+
+	case LDB_REPLY_DONE:
+
+		ret = ldb_build_rename_req(&req, ldb_module_get_ctx(ac->module), ac,
+					   ac->req->op.rename.olddn,
+					   ac->req->op.rename.newdn,
+					   ac->req->controls,
+					   ac, subtree_rename_callback,
+					   ac->req);
+		LDB_REQ_SET_LOCATION(req);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+
+		talloc_free(ares);
+		return ldb_next_request(ac->module, req);
+	}
+
+	return LDB_SUCCESS;
+}
+
+static int subtree_rename_search_base_callback(struct ldb_request *req,
+					       struct ldb_reply *ares)
+{
+	struct ldb_request *search_req;
+	struct subtree_rename_context *ac;
+	static const char * const no_attrs[] = {NULL};
+	int ret;
+
+	ac = talloc_get_type(req->context, struct subtree_rename_context);
+
+	if (!ares) {
+		return ldb_module_done(ac->req, NULL, NULL,
+					LDB_ERR_OPERATIONS_ERROR);
+	}
+	if (ares->error != LDB_SUCCESS) {
+		return ldb_module_done(ac->req, ares->controls,
+					ares->response, ares->error);
+	}
+
+	switch (ares->type) {
+	case LDB_REPLY_ENTRY:
+		/*
+		 * This is the root entry of the originating move
+		 * respectively rename request. It has been already
+		 * stored in the list using "subtree_rename_search()".


-- 
Samba Shared Repository


More information about the samba-cvs mailing list