[SCM] Samba Shared Repository - branch master updated

Matthias Dieter Wallnöfer mdw at samba.org
Sun Jun 20 10:52:58 MDT 2010


The branch, master has been updated
       via  91c49c2... s4:ldap.py - test subtree deletes through a new testcase
       via  449370d... s4:ldap_backend.c - now also the LDAP server supports controls on delete operations
       via  9803c89... s4:ldap_backend.c - move function "ldb_mod_req_with_controls" to a better place in the code
       via  fbd0902... s4:subtree_delete LDB module - now do support tree delete operations
       via  87d0f63... s4:dsdb - add a new dsdb delete function which understands the tree delete control
       via  ad5e19f... ldb:controls - add the "TREE_DELETE" control for allowing subtree deletes
       via  065579b... ldb:ldb.h - add classifications to the control declarations
       via  e062e73... s4:python LDB __init__.py - remove completely unused "erase_partitions" call
       via  2fb715b... s4:samldb LDB module - remove "samldb_set_defaultObjectCategory"
       via  c8d2c5f... s4:ldap_backend.c - add some newlines to make logs easier to read
       via  d7ad7ee... ldb:pyldb.c - introduce a "mem_ctx" also on "py_ldb_search"
       via  00bf608... ldb:pyldb.c - some cleanups and adequations also in "py_ldb_modify" and "py_ldb_rename"
       via  4cc49d3... s4:ldap_controls.c - remove encoding functions for private recalculate SD control
      from  0714e23... provision: Look for Samba prefix a bit harder.

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


- Log -----------------------------------------------------------------
commit 91c49c2fb29a188db24695a78b365aeb4f51db27
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 17:36:43 2010 +0200

    s4:ldap.py - test subtree deletes through a new testcase

commit 449370db545f189449dbce75fd73271caf5ab187
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 15:13:36 2010 +0200

    s4:ldap_backend.c - now also the LDAP server supports controls on delete operations

commit 9803c89ee28b4b4d6e4514b362aa60adb7f93366
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 15:09:55 2010 +0200

    s4:ldap_backend.c - move function "ldb_mod_req_with_controls" to a better place in the code
    
    Under the "add" and over the "delete" function.

commit fbd09029581d2f9b6c6f0c2410d768d501f4b75c
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 12:49:04 2010 +0200

    s4:subtree_delete LDB module - now do support tree delete operations

commit 87d0f636320b3b6818c1703d99b94648f00d0af7
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 12:43:49 2010 +0200

    s4:dsdb - add a new dsdb delete function which understands the tree delete control

commit ad5e19f29e3d716579607e706b42a4e7d2ed11c4
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 12:19:31 2010 +0200

    ldb:controls - add the "TREE_DELETE" control for allowing subtree deletes

commit 065579b4c6a05de7fd867dbe0eb736b86a6bc5f7
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 12:08:50 2010 +0200

    ldb:ldb.h - add classifications to the control declarations
    
    This makes it easier to understand which standard specifies which control.

commit e062e7300bd2993b4a5d641ce3128f9c461f6328
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 13:03:59 2010 +0200

    s4:python LDB __init__.py - remove completely unused "erase_partitions" call
    
    Seems to be a relict from the past.

commit 2fb715b484d1eec3fadbdf3dc79d0fc88f01af52
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 11:46:55 2010 +0200

    s4:samldb LDB module - remove "samldb_set_defaultObjectCategory"
    
    As far as I can tell and the test show the DN gets now normalised automatically
    when stored into the database.
    
    Anyway, if we find a case where this doesn't happen then I propose to do it
    centrally for all DN attributes in common since we should get away from special
    attribute hacks as far as possible.

commit c8d2c5fff017a42ffb75aeaabfa19b8503b9e7af
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 15:33:29 2010 +0200

    s4:ldap_backend.c - add some newlines to make logs easier to read

commit d7ad7eed24108491bb86271f39ef233826f41352
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 18:20:00 2010 +0200

    ldb:pyldb.c - introduce a "mem_ctx" also on "py_ldb_search"
    
    To prevent memory leaks

commit 00bf6084817046481e8d049357638387185c39ca
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 18:06:54 2010 +0200

    ldb:pyldb.c - some cleanups and adequations also in "py_ldb_modify" and "py_ldb_rename"
    
    To make them consistent.

commit 4cc49d365fa096e46259d6795b4626603919d69c
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date:   Sun Jun 20 18:46:51 2010 +0200

    s4:ldap_controls.c - remove encoding functions for private recalculate SD control

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

Summary of changes:
 source4/dsdb/common/util.c                        |    7 ++
 source4/dsdb/common/util.h                        |    4 +-
 source4/dsdb/samdb/ldb_modules/samldb.c           |   78 --------------
 source4/dsdb/samdb/ldb_modules/subtree_delete.c   |   54 ++++++++--
 source4/dsdb/samdb/ldb_modules/util.c             |   53 +++++++++
 source4/ldap_server/ldap_backend.c                |  119 +++++++++++----------
 source4/lib/ldb/common/ldb_controls.c             |   27 +++++
 source4/lib/ldb/include/ldb.h                     |   27 ++++--
 source4/lib/ldb/pyldb.c                           |   78 ++++++++------
 source4/lib/ldb/tests/python/ldap.py              |   48 ++++++++
 source4/libcli/ldap/ldap_controls.c               |   39 ++++----
 source4/scripting/python/samba/__init__.py        |   33 ------
 source4/scripting/python/samba/tests/provision.py |    3 -
 13 files changed, 330 insertions(+), 240 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index d644d2d..28061f3 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3479,6 +3479,13 @@ int dsdb_request_add_controls(struct ldb_request *req, uint32_t dsdb_flags)
 		}
 	}
 
+	if (dsdb_flags & DSDB_TREE_DELETE) {
+		ret = ldb_request_add_control(req, LDB_CONTROL_TREE_DELETE_OID, false, NULL);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
 	return LDB_SUCCESS;
 }
 
diff --git a/source4/dsdb/common/util.h b/source4/dsdb/common/util.h
index 0b6ef3d..edada70 100644
--- a/source4/dsdb/common/util.h
+++ b/source4/dsdb/common/util.h
@@ -31,5 +31,5 @@
 #define DSDB_MODIFY_RELAX		      0x0020
 #define DSDB_MODIFY_PERMISSIVE		      0x0040
 #define DSDB_FLAG_AS_SYSTEM		      0x0080
-
-#define DSDB_SEARCH_ONE_ONLY		      0x0020 /* give an error unless 1 record */
+#define DSDB_TREE_DELETE		      0x0100
+#define DSDB_SEARCH_ONE_ONLY		      0x0200 /* give an error unless 1 record */
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 5d64b6d..5b7e4be 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -477,81 +477,6 @@ static int samldb_check_primaryGroupID_2(struct samldb_ctx *ac)
 
 
 /*
- * samldb_set_defaultObjectCategory_callback (async)
- */
-
-static int samldb_set_defaultObjectCategory_callback(struct ldb_request *req,
-						     struct ldb_reply *ares)
-{
-	struct ldb_context *ldb;
-	struct samldb_ctx *ac;
-	int ret;
-
-	ac = talloc_get_type(req->context, struct samldb_ctx);
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if (!ares) {
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-
-	if (ares->type == LDB_REPLY_REFERRAL) {
-		return ldb_module_send_referral(ac->req, ares->referral);
-	}
-
-	if (ares->error != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-	if (ares->type != LDB_REPLY_DONE) {
-		ldb_set_errstring(ldb,
-			"Invalid reply type!");
-		ret = LDB_ERR_OPERATIONS_ERROR;
-		goto done;
-	}
-
-	ret = samldb_next_step(ac);
-
-done:
-	if (ret != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, NULL, NULL, ret);
-	}
-
-	return LDB_SUCCESS;
-}
-
-static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
-{
-	struct ldb_context *ldb;
-	struct ldb_message *msg;
-	struct ldb_request *req;
-	int ret;
-
-	ldb = ldb_module_get_ctx(ac->module);
-
-	/* (Re)set the default object category to have it set to the DN in the
-	 * storage format */
-	msg = ldb_msg_new(ac);
-	msg->dn = ac->msg->dn;
-	ldb_msg_add_empty(msg, "defaultObjectCategory",
-			  LDB_FLAG_MOD_REPLACE, NULL);
-	ldb_msg_add_steal_string(msg, "defaultObjectCategory",
-				 ldb_dn_alloc_linearized(msg, ac->res_dn));
-
-	ret = ldb_build_mod_req(&req, ldb, ac,
-				msg, NULL,
-				ac,
-				samldb_set_defaultObjectCategory_callback,
-				ac->req);
-	if (ret != LDB_SUCCESS) {
-		talloc_free(msg);
-		return ret;
-	}
-
-	return ldb_next_request(ac->module, req);
-}
-
-/*
  * samldb_find_for_defaultObjectCategory (async)
  */
 
@@ -942,9 +867,6 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 		ret = samldb_add_step(ac, samldb_find_for_defaultObjectCategory);
 		if (ret != LDB_SUCCESS) return ret;
 
-		ret = samldb_add_step(ac, samldb_set_defaultObjectCategory);
-		if (ret != LDB_SUCCESS) return ret;
-
 		return samldb_first_step(ac);
 	} else if (strcmp(ac->type, "attributeSchema") == 0) {
 		const struct ldb_val *rdn_value;
diff --git a/source4/dsdb/samdb/ldb_modules/subtree_delete.c b/source4/dsdb/samdb/ldb_modules/subtree_delete.c
index a273437..a29de8e 100644
--- a/source4/dsdb/samdb/ldb_modules/subtree_delete.c
+++ b/source4/dsdb/samdb/ldb_modules/subtree_delete.c
@@ -39,8 +39,10 @@
 static int subtree_delete(struct ldb_module *module, struct ldb_request *req)
 {
 	static const char * const attrs[] = { NULL };
-	int ret;
 	struct ldb_result *res = NULL;
+	uint32_t flags;
+	unsigned int i;
+	int ret;
 
 	if (ldb_dn_is_special(req->op.del.dn)) {
 		/* do not manipulate our control entries */
@@ -56,20 +58,54 @@ static int subtree_delete(struct ldb_module *module, struct ldb_request *req)
 		return ret;
 	}
 	if (res->count > 0) {
-		ldb_asprintf_errstring(ldb_module_get_ctx(module),
-				       "Cannot delete %s, not a leaf node "
-				       "(has %d children)\n",
-				       ldb_dn_get_linearized(req->op.del.dn),
-				       res->count);
-		talloc_free(res);
-		return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF;
+		if (ldb_request_get_control(req, LDB_CONTROL_TREE_DELETE_OID) == NULL) {
+			ldb_asprintf_errstring(ldb_module_get_ctx(module),
+					       "Cannot delete %s, not a leaf node "
+					       "(has %d children)\n",
+					       ldb_dn_get_linearized(req->op.del.dn),
+					       res->count);
+			talloc_free(res);
+			return LDB_ERR_NOT_ALLOWED_ON_NON_LEAF;
+		}
+
+		/* we need to start from the top since other LDB modules could
+		 * enforce constraints (eg "objectclass" and "samldb" do so). */
+		flags = DSDB_FLAG_TOP_MODULE | DSDB_TREE_DELETE;
+		if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID) != NULL) {
+			flags |= DSDB_MODIFY_RELAX;
+		}
+
+		for (i = 0; i < res->count; i++) {
+			ret = dsdb_module_del(module, res->msgs[i]->dn, flags);
+			if (ret != LDB_SUCCESS) {
+				return ret;
+			}
+		}
 	}
 	talloc_free(res);
 
 	return ldb_next_request(module, req);
 }
 
+static int subtree_delete_init(struct ldb_module *module)
+{
+	struct ldb_context *ldb;
+	int ret;
+
+	ldb = ldb_module_get_ctx(module);
+
+	ret = ldb_mod_register_control(module, LDB_CONTROL_TREE_DELETE_OID);
+	if (ret != LDB_SUCCESS) {
+		ldb_debug(ldb, LDB_DEBUG_ERROR,
+			"subtree_delete: Unable to register control with rootdse!\n");
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	return ldb_next_init(module);
+}
+
 _PUBLIC_ const struct ldb_module_ops ldb_subtree_delete_module_ops = {
 	.name		   = "subtree_delete",
-	.del               = subtree_delete,
+	.init_context      = subtree_delete_init,
+	.del               = subtree_delete
 };
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index bf92774..ec07350 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -407,6 +407,59 @@ int dsdb_module_add(struct ldb_module *module,
 	return ret;
 }
 
+/*
+  a ldb_delete request operating on modules below the
+  current module
+ */
+int dsdb_module_del(struct ldb_module *module,
+		    struct ldb_dn *dn,
+		    uint32_t dsdb_flags)
+{
+	struct ldb_request *req;
+	int ret;
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
+	TALLOC_CTX *tmp_ctx = talloc_new(module);
+	struct ldb_result *res;
+
+	res = talloc_zero(tmp_ctx, struct ldb_result);
+	if (!res) {
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = ldb_build_del_req(&req, ldb, tmp_ctx,
+				dn,
+				NULL,
+				res,
+				ldb_modify_default_callback,
+				NULL);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return ret;
+	}
+
+	ret = dsdb_request_add_controls(req, dsdb_flags);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return ret;
+	}
+
+	/* Run the new request */
+	if (dsdb_flags & DSDB_FLAG_OWN_MODULE) {
+		const struct ldb_module_ops *ops = ldb_module_get_ops(module);
+		ret = ops->del(module, req);
+	} else if (dsdb_flags & DSDB_FLAG_TOP_MODULE) {
+		ret = ldb_request(ldb_module_get_ctx(module), req);
+	} else {
+		ret = ldb_next_request(module, req);
+	}
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	}
+
+	talloc_free(tmp_ctx);
+	return ret;
+}
 
 const struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema,const struct ldb_message_element *element)
 {
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index e1be4de..c1bd630 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -175,51 +175,6 @@ static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
 	/* result is 1:1 for now */
 	return ldb_err;
 }
-/* create and execute a modify request */
-static int ldb_mod_req_with_controls(struct ldb_context *ldb,
-				     const struct ldb_message *message,
-				     struct ldb_control **controls,
-				     void *context)
-{
-	struct ldb_request *req;
-	int ret;
-
-	ret = ldb_msg_sanity_check(ldb, message);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ret = ldb_build_mod_req(&req, ldb, ldb,
-					message,
-					controls,
-					context,
-					ldb_modify_default_callback,
-					NULL);
-
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ret = ldb_transaction_start(ldb);
-	if (ret != LDB_SUCCESS) {
-		return ret;
-	}
-
-	ret = ldb_request(ldb, req);
-	if (ret == LDB_SUCCESS) {
-		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
-	}
-
-	if (ret == LDB_SUCCESS) {
-		ret = ldb_transaction_commit(ldb);
-	}
-	else {
-		ldb_transaction_cancel(ldb);
-	}
-
-	talloc_free(req);
-	return ret;
-}
 
 /*
   connect to the sam database
@@ -320,9 +275,9 @@ static NTSTATUS ldapsrv_unwilling(struct ldapsrv_call *call, int error)
 	return NT_STATUS_OK;
 }
 
-int ldb_add_with_context(struct ldb_context *ldb,
-			 const struct ldb_message *message,
-			 void *context)
+static int ldb_add_with_context(struct ldb_context *ldb,
+				const struct ldb_message *message,
+				void *context)
 {
 	struct ldb_request *req;
 	int ret;
@@ -362,16 +317,64 @@ int ldb_add_with_context(struct ldb_context *ldb,
 	return ret;
 }
 
-int ldb_delete_with_context(struct ldb_context *ldb,
-			    struct ldb_dn *dn,
-			    void *context)
+/* create and execute a modify request */
+static int ldb_mod_req_with_controls(struct ldb_context *ldb,
+				     const struct ldb_message *message,
+				     struct ldb_control **controls,
+				     void *context)
+{
+	struct ldb_request *req;
+	int ret;
+
+	ret = ldb_msg_sanity_check(ldb, message);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_build_mod_req(&req, ldb, ldb,
+					message,
+					controls,
+					context,
+					ldb_modify_default_callback,
+					NULL);
+
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_transaction_start(ldb);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	ret = ldb_request(ldb, req);
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	}
+
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_transaction_commit(ldb);
+	}
+	else {
+		ldb_transaction_cancel(ldb);
+	}
+
+	talloc_free(req);
+	return ret;
+}
+
+/* create and execute a delete request */
+static int ldb_del_req_with_controls(struct ldb_context *ldb,
+				     struct ldb_dn *dn,
+				     struct ldb_control **controls,
+				     void *context)
 {
 	struct ldb_request *req;
 	int ret;
 
 	ret = ldb_build_del_req(&req, ldb, ldb,
 					dn,
-					NULL,
+					controls,
 					context,
 					ldb_modify_default_callback,
 					NULL);
@@ -672,7 +675,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
 	struct ldb_result *res = NULL;
 
 	DEBUG(10, ("ModifyRequest"));
-	DEBUGADD(10, (" dn: %s", req->dn));
+	DEBUGADD(10, (" dn: %s\n", req->dn));
 
 	local_ctx = talloc_named(call, 0, "ModifyRequest local memory context");
 	NT_STATUS_HAVE_NO_MEMORY(local_ctx);
@@ -780,7 +783,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call)
 	struct ldb_result *res = NULL;
 
 	DEBUG(10, ("AddRequest"));
-	DEBUGADD(10, (" dn: %s", req->dn));
+	DEBUGADD(10, (" dn: %s\n", req->dn));
 
 	local_ctx = talloc_named(call, 0, "AddRequest local memory context");
 	NT_STATUS_HAVE_NO_MEMORY(local_ctx);
@@ -868,7 +871,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call)
 	struct ldb_result *res = NULL;
 
 	DEBUG(10, ("DelRequest"));
-	DEBUGADD(10, (" dn: %s", req->dn));
+	DEBUGADD(10, (" dn: %s\n", req->dn));
 
 	local_ctx = talloc_named(call, 0, "DelRequest local memory context");
 	NT_STATUS_HAVE_NO_MEMORY(local_ctx);
@@ -885,7 +888,7 @@ reply:
 	if (result == LDAP_SUCCESS) {
 		res = talloc_zero(local_ctx, struct ldb_result);
 		NT_STATUS_HAVE_NO_MEMORY(res);
-		ldb_ret = ldb_delete_with_context(samdb, dn, res);
+		ldb_ret = ldb_del_req_with_controls(samdb, dn, call->request->controls, res);
 		result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
 				       &errstr);
 	}
@@ -926,7 +929,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
 
 	DEBUG(10, ("ModifyDNRequest"));
 	DEBUGADD(10, (" dn: %s", req->dn));
-	DEBUGADD(10, (" newrdn: %s", req->newrdn));
+	DEBUGADD(10, (" newrdn: %s\n", req->newrdn));
 
 	local_ctx = talloc_named(call, 0, "ModifyDNRequest local memory context");
 	NT_STATUS_HAVE_NO_MEMORY(local_ctx);
@@ -1034,7 +1037,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
 	int ldb_ret;
 
 	DEBUG(10, ("CompareRequest"));
-	DEBUGADD(10, (" dn: %s", req->dn));
+	DEBUGADD(10, (" dn: %s\n", req->dn));
 
 	local_ctx = talloc_named(call, 0, "CompareRequest local_memory_context");
 	NT_STATUS_HAVE_NO_MEMORY(local_ctx);
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index aff03a0..abdbb14 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -694,6 +694,33 @@ struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *me
 			continue;
 		}
 
+		if (strncmp(control_strings[i], "tree_delete:", 12) == 0) {
+			const char *p;
+			int crit, ret;
+
+			p = &(control_strings[i][12]);
+			ret = sscanf(p, "%d", &crit);
+			if ((ret != 1) || (crit < 0) || (crit > 1)) {
+				error_string = talloc_asprintf(mem_ctx, "invalid tree_delete control syntax\n");
+				error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+				error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+				ldb_set_errstring(ldb, error_string);
+				talloc_free(error_string);
+				return NULL;
+			}
+
+			ctrl[i] = talloc(ctrl, struct ldb_control);
+			if (!ctrl[i]) {
+				ldb_oom(ldb);
+				return NULL;
+			}
+			ctrl[i]->oid = LDB_CONTROL_TREE_DELETE_OID;
+			ctrl[i]->critical = crit;
+			ctrl[i]->data = NULL;
+
+			continue;
+		}
+
 		if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
 			const char *p;
 			int crit, ret;
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h


-- 
Samba Shared Repository


More information about the samba-cvs mailing list