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