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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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 <m...@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

Reply via email to