diff options
author | Andrew Bartlett <abartlet@samba.org> | 2009-08-25 16:25:55 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-08-25 16:28:44 +1000 |
commit | 6542a084a5dee239866f7d327c47afe2fc3efc6a (patch) | |
tree | 5c99127d9720f5ddb6b264d0d29323c8b2d30f12 | |
parent | 213546103749c30dbb3ad8472872b9a8fad34205 (diff) | |
download | samba-6542a084a5dee239866f7d327c47afe2fc3efc6a.tar.gz samba-6542a084a5dee239866f7d327c47afe2fc3efc6a.tar.bz2 samba-6542a084a5dee239866f7d327c47afe2fc3efc6a.zip |
s4:dsdb Rework show_deleted module not to liniearise the LDAP filter
Instead, use the fact that the ldb_parse_tree structure is public to
construct the 'and not deleted' clause as a structure, and apply each
filter tree to that template.
Andrew Bartlett
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/show_deleted.c | 109 |
1 files changed, 37 insertions, 72 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/show_deleted.c b/source4/dsdb/samdb/ldb_modules/show_deleted.c index b4f52d7cde..12ae59019e 100644 --- a/source4/dsdb/samdb/ldb_modules/show_deleted.c +++ b/source4/dsdb/samdb/ldb_modules/show_deleted.c @@ -2,7 +2,8 @@ ldb database library Copyright (C) Simo Sorce 2005 - Copyright (C) Stefa Metzmacher <metze@samba.org> 2007 + Copyright (C) Stefan Metzmacher <metze@samba.org> 2007 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -36,92 +37,46 @@ #include "ldb/include/ldb_module.h" #include "dsdb/samdb/samdb.h" -/* search */ -struct show_deleted_search_request { - - struct ldb_module *module; - struct ldb_request *req; -}; - -static int show_deleted_search_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct show_deleted_search_request *ar; - - ar = talloc_get_type(req->context, struct show_deleted_search_request); - - if (!ares) { - return ldb_module_done(ar->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ar->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - - return ldb_module_send_entry(ar->req, ares->message, ares->controls); - - case LDB_REPLY_REFERRAL: - return ldb_module_send_referral(ar->req, ares->referral); - - case LDB_REPLY_DONE: - return ldb_module_done(ar->req, ares->controls, - ares->response, LDB_SUCCESS); - - } - return LDB_SUCCESS; -} static int show_deleted_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; struct ldb_control *control; struct ldb_control **saved_controls; - struct show_deleted_search_request *ar; struct ldb_request *down_req; - char *old_filter; - char *new_filter; + struct ldb_parse_tree *nodeleted_tree; + struct ldb_parse_tree *new_tree = req->op.search.tree; int ret; ldb = ldb_module_get_ctx(module); - ar = talloc_zero(req, struct show_deleted_search_request); - if (ar == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ar->module = module; - ar->req = req; - /* check if there's a show deleted control */ control = ldb_request_get_control(req, LDB_CONTROL_SHOW_DELETED_OID); - if ( ! control) { - old_filter = ldb_filter_from_tree(ar, req->op.search.tree); - new_filter = talloc_asprintf(ar, "(&(!(isDeleted=TRUE))%s)", - old_filter); - - ret = ldb_build_search_req(&down_req, ldb, ar, - req->op.search.base, - req->op.search.scope, - new_filter, - req->op.search.attrs, - req->controls, - ar, show_deleted_search_callback, - req); - - } else { - ret = ldb_build_search_req_ex(&down_req, ldb, ar, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - ar, show_deleted_search_callback, - req); + if (! control) { + nodeleted_tree = talloc_get_type(ldb_module_get_private(module), + struct ldb_parse_tree); + if (nodeleted_tree) { + new_tree = talloc(req, struct ldb_parse_tree); + if (!new_tree) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + *new_tree = *nodeleted_tree; + /* Replace dummy part of 'and' with the old, tree, + without a parse step */ + new_tree->u.list.elements[0] = req->op.search.tree; + } } + + ret = ldb_build_search_req_ex(&down_req, ldb, req, + req->op.search.base, + req->op.search.scope, + new_tree, + req->op.search.attrs, + req->controls, + req->context, req->callback, + req); if (ret != LDB_SUCCESS) { return ret; } @@ -138,10 +93,20 @@ static int show_deleted_search(struct ldb_module *module, struct ldb_request *re static int show_deleted_init(struct ldb_module *module) { struct ldb_context *ldb; + struct ldb_parse_tree *nodeleted_tree; int ret; ldb = ldb_module_get_ctx(module); + nodeleted_tree = ldb_parse_tree(module, "(&(replace=me)(!(isDeleted=TRUE)))"); + if (!nodeleted_tree) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "show_deleted: Unable to parse isDeleted master expression!\n"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_module_set_private(module, nodeleted_tree); + ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, |