diff options
Diffstat (limited to 'ldb/modules')
-rw-r--r-- | ldb/modules/asq.c | 388 | ||||
-rw-r--r-- | ldb/modules/operational.c | 307 | ||||
-rw-r--r-- | ldb/modules/paged_results.c | 414 | ||||
-rw-r--r-- | ldb/modules/paged_searches.c | 374 | ||||
-rw-r--r-- | ldb/modules/rdn_name.c | 321 | ||||
-rw-r--r-- | ldb/modules/skel.c | 131 | ||||
-rw-r--r-- | ldb/modules/sort.c | 335 |
7 files changed, 0 insertions, 2270 deletions
diff --git a/ldb/modules/asq.c b/ldb/modules/asq.c deleted file mode 100644 index c650970af..000000000 --- a/ldb/modules/asq.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: ldb - * - * Component: ldb attribute scoped query control module - * - * Description: this module searches all the the objects pointed - * by the DNs contained in the references attribute - * - * Author: Simo Sorce - */ - -#include "ldb_includes.h" - -struct asq_context { - - enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_asq_control *asq_ctrl; - - const char * const *req_attrs; - char *req_attribute; - enum { - ASQ_CTRL_SUCCESS = 0, - ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, - ASQ_CTRL_UNWILLING_TO_PERFORM = 53, - ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 - } asq_ret; - - struct ldb_reply *base_res; - - struct ldb_request **reqs; - int num_reqs; - int cur_req; - - struct ldb_control **controls; -}; - -static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) -{ - struct asq_context *ac; - - ac = talloc_zero(req, struct asq_context); - if (ac == NULL) { - ldb_oom(module->ldb); - return NULL; - } - - ac->module = module; - ac->req = req; - - return ac; -} - -static int asq_search_continue(struct asq_context *ac); - -static int asq_search_terminate(struct asq_context *ac) -{ - struct ldb_asq_control *asq; - int i; - - if (ac->controls) { - for (i = 0; ac->controls[i]; i++) /* count em */ ; - } else { - i = 0; - } - - ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); - - if (ac->controls == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i] = talloc(ac->controls, struct ldb_control); - if (ac->controls[i] == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; - ac->controls[i]->critical = 0; - - asq = talloc_zero(ac->controls[i], struct ldb_asq_control); - if (asq == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - asq->result = ac->asq_ret; - - ac->controls[i]->data = asq; - - ac->controls[i + 1] = NULL; - - return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); -} - -static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_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: - ac->base_res = talloc_move(ac, &ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - /* next step */ - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - } - return LDB_SUCCESS; -} - -static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_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: - /* pass the message up to the original callback as we - * do not have to elaborate on it any further */ - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_free(ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - } - - return LDB_SUCCESS; -} - -static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) -{ - const char **base_attrs; - int ret; - - ac->req_attrs = ac->req->op.search.attrs; - ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); - if (ac->req_attribute == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - base_attrs = talloc_array(ac, const char *, 2); - if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); - if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[1] = NULL; - - ret = ldb_build_search_req(base_req, ac->module->ldb, ac, - ac->req->op.search.base, - LDB_SCOPE_BASE, - NULL, - (const char * const *)base_attrs, - NULL, - ac, asq_base_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) -{ - struct ldb_control **saved_controls; - struct ldb_control *control; - struct ldb_dn *dn; - struct ldb_message_element *el; - int ret, i; - - if (ac->base_res == NULL) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); - /* no values found */ - if (el == NULL) { - ac->asq_ret = ASQ_CTRL_SUCCESS; - *terminated = true; - return asq_search_terminate(ac); - } - - ac->num_reqs = el->num_values; - ac->cur_req = 0; - ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); - if (ac->reqs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < el->num_values; i++) { - - dn = ldb_dn_new(ac, ac->module->ldb, - (const char *)el->values[i].data); - if ( ! ldb_dn_validate(dn)) { - ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; - *terminated = true; - return asq_search_terminate(ac); - } - - ret = ldb_build_search_req_ex(&ac->reqs[i], - ac->module->ldb, ac, - dn, LDB_SCOPE_BASE, - ac->req->op.search.tree, - ac->req_attrs, - ac->req->controls, - ac, asq_reqs_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* remove the ASQ control itself */ - control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); - if (!save_controls(control, ac->reqs[i], &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -static int asq_search_continue(struct asq_context *ac) -{ - bool terminated = false; - int ret; - - switch (ac->step) { - case ASQ_SEARCH_BASE: - - /* build up the requests call chain */ - ret = asq_build_multiple_requests(ac, &terminated); - if (ret != LDB_SUCCESS || terminated) { - return ret; - } - - ac->step = ASQ_SEARCH_MULTI; - - return ldb_request(ac->module->ldb, ac->reqs[ac->cur_req]); - - case ASQ_SEARCH_MULTI: - - ac->cur_req++; - - if (ac->cur_req == ac->num_reqs) { - /* done */ - return asq_search_terminate(ac); - } - - return ldb_request(ac->module->ldb, ac->reqs[ac->cur_req]); - } - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int asq_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *base_req; - struct ldb_control *control; - struct asq_context *ac; - int ret; - - /* check if there's a paged request control */ - control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = asq_context_init(module, req); - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* check the search is well formed */ - if (req->op.search.scope != LDB_SCOPE_BASE) { - ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; - return asq_search_terminate(ac); - } - - ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); - if (!ac->asq_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - ret = asq_build_first_request(ac, &base_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->step = ASQ_SEARCH_BASE; - - return ldb_request(module->ldb, base_req); -} - -static int asq_init(struct ldb_module *module) -{ - int ret; - - ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n"); - } - - return ldb_next_init(module); -} - -const struct ldb_module_ops ldb_asq_module_ops = { - .name = "asq", - .search = asq_search, - .init_context = asq_init -}; diff --git a/ldb/modules/operational.c b/ldb/modules/operational.c deleted file mode 100644 index 345441b5e..000000000 --- a/ldb/modules/operational.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Simo Sorce 2006-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -/* - handle operational attributes - */ - -/* - createTimestamp: HIDDEN, searchable, ldaptime, alias for whenCreated - modifyTimestamp: HIDDEN, searchable, ldaptime, alias for whenChanged - - for the above two, we do the search as normal, and if - createTimestamp or modifyTimestamp is asked for, then do - additional searches for whenCreated and whenChanged and fill in - the resulting values - - we also need to replace these with the whenCreated/whenChanged - equivalent in the search expression trees - - whenCreated: not-HIDDEN, CONSTRUCTED, SEARCHABLE - whenChanged: not-HIDDEN, CONSTRUCTED, SEARCHABLE - - on init we need to setup attribute handlers for these so - comparisons are done correctly. The resolution is 1 second. - - on add we need to add both the above, for current time - - on modify we need to change whenChanged - - - subschemaSubentry: HIDDEN, not-searchable, - points at DN CN=Aggregate,$SCHEMADN - - for this one we do the search as normal, then add the static - value if requested. How do we work out the $BASEDN from inside a - module? - - - structuralObjectClass: HIDDEN, CONSTRUCTED, not-searchable. always same as objectclass? - - for this one we do the search as normal, then if requested ask - for objectclass, change the attribute name, and add it - - allowedAttributesEffective: HIDDEN, CONSTRUCTED, not-searchable, - list of attributes that can be modified - requires schema lookup - - - attributeTypes: in schema only - objectClasses: in schema only - matchingRules: in schema only - matchingRuleUse: in schema only - creatorsName: not supported by w2k3? - modifiersName: not supported by w2k3? -*/ - -#include "ldb_includes.h" - -/* - construct a canonical name from a message -*/ -static int construct_canonical_name(struct ldb_module *module, struct ldb_message *msg) -{ - char *canonicalName; - canonicalName = ldb_dn_canonical_string(msg, msg->dn); - if (canonicalName == NULL) { - return -1; - } - return ldb_msg_add_steal_string(msg, "canonicalName", canonicalName); -} - -/* - a list of attribute names that should be substituted in the parse - tree before the search is done -*/ -static const struct { - const char *attr; - const char *replace; -} parse_tree_sub[] = { - { "createTimestamp", "whenCreated" }, - { "modifyTimestamp", "whenChanged" } -}; - - -/* - a list of attribute names that are hidden, but can be searched for - using another (non-hidden) name to produce the correct result -*/ -static const struct { - const char *attr; - const char *replace; - int (*constructor)(struct ldb_module *, struct ldb_message *); -} search_sub[] = { - { "createTimestamp", "whenCreated", NULL }, - { "modifyTimestamp", "whenChanged", NULL }, - { "structuralObjectClass", "objectClass", NULL }, - { "canonicalName", "distinguishedName", construct_canonical_name } -}; - -/* - post process a search result record. For any search_sub[] attributes that were - asked for, we need to call the appropriate copy routine to copy the result - into the message, then remove any attributes that we added to the search but were - not asked for by the user -*/ -static int operational_search_post_process(struct ldb_module *module, - struct ldb_message *msg, - const char * const *attrs) -{ - int i, a=0; - - for (a=0;attrs && attrs[a];a++) { - for (i=0;i<ARRAY_SIZE(search_sub);i++) { - if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) { - continue; - } - - /* construct the new attribute, using either a supplied - constructor or a simple copy */ - if (search_sub[i].constructor) { - if (search_sub[i].constructor(module, msg) != 0) { - goto failed; - } - } else if (ldb_msg_copy_attr(msg, - search_sub[i].replace, - search_sub[i].attr) != 0) { - goto failed; - } - - /* remove the added search attribute, unless it was asked for - by the user */ - if (search_sub[i].replace == NULL || - ldb_attr_in_list(attrs, search_sub[i].replace) || - ldb_attr_in_list(attrs, "*")) { - continue; - } - - ldb_msg_remove_attr(msg, search_sub[i].replace); - } - } - - return 0; - -failed: - ldb_debug_set(module->ldb, LDB_DEBUG_WARNING, - "operational_search_post_process failed for attribute '%s'\n", - attrs[a]); - return -1; -} - - -/* - hook search operations -*/ - -struct operational_context { - struct ldb_module *module; - struct ldb_request *req; - - const char * const *attrs; -}; - -static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct operational_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct operational_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: - /* for each record returned post-process to add any derived - attributes that have been asked for */ - ret = operational_search_post_process(ac->module, - ares->message, - ac->attrs); - if (ret != 0) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - return ldb_module_send_entry(ac->req, ares->message, ares->controls); - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - break; - - case LDB_REPLY_DONE: - - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int operational_search(struct ldb_module *module, struct ldb_request *req) -{ - struct operational_context *ac; - struct ldb_request *down_req; - const char **search_attrs = NULL; - int i, a; - int ret; - - ac = talloc(req, struct operational_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->attrs = req->op.search.attrs; - - /* FIXME: We must copy the tree and keep the original - * unmodified. SSS */ - /* replace any attributes in the parse tree that are - searchable, but are stored using a different name in the - backend */ - for (i=0;i<ARRAY_SIZE(parse_tree_sub);i++) { - ldb_parse_tree_attr_replace(req->op.search.tree, - parse_tree_sub[i].attr, - parse_tree_sub[i].replace); - } - - /* in the list of attributes we are looking for, rename any - attributes to the alias for any hidden attributes that can - be fetched directly using non-hidden names */ - for (a=0;ac->attrs && ac->attrs[a];a++) { - for (i=0;i<ARRAY_SIZE(search_sub);i++) { - if (ldb_attr_cmp(ac->attrs[a], search_sub[i].attr) == 0 && - search_sub[i].replace) { - if (!search_attrs) { - search_attrs = ldb_attr_list_copy(req, ac->attrs); - if (search_attrs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - search_attrs[a] = search_sub[i].replace; - } - } - } - - /* use new set of attrs if any */ - if (search_attrs == NULL) { - search_attrs = req->op.search.attrs; - } - - ret = ldb_build_search_req_ex(&down_req, module->ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - (const char * const *)search_attrs, - req->controls, - ac, operational_callback, - req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* perform the search */ - return ldb_next_request(module, down_req); -} - -static int operational_init(struct ldb_module *ctx) -{ - int ret = 0; - - if (ret != 0) { - return ret; - } - - return ldb_next_init(ctx); -} - -const struct ldb_module_ops ldb_operational_module_ops = { - .name = "operational", - .search = operational_search, - .init_context = operational_init -}; diff --git a/ldb/modules/paged_results.c b/ldb/modules/paged_results.c deleted file mode 100644 index dfc565fef..000000000 --- a/ldb/modules/paged_results.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: paged_result - * - * Component: ldb paged results control module - * - * Description: this module caches a complete search and sends back - * results in chunks as asked by the client - * - * Author: Simo Sorce - */ - -#include "ldb_includes.h" - -struct message_store { - /* keep the whole ldb_reply as an optimization - * instead of freeing and talloc-ing the container - * on each result */ - struct ldb_reply *r; - struct message_store *next; -}; - -struct private_data; - -struct results_store { - - struct private_data *priv; - - char *cookie; - time_t timestamp; - - struct results_store *next; - - struct message_store *first; - struct message_store *last; - int num_entries; - - struct message_store *first_ref; - struct message_store *last_ref; - - struct ldb_control **controls; -}; - -struct private_data { - - int next_free_id; - struct results_store *store; - -}; - -static int store_destructor(struct results_store *del) -{ - struct private_data *priv = del->priv; - struct results_store *loop; - - if (priv->store == del) { - priv->store = del->next; - return 0; - } - - for (loop = priv->store; loop; loop = loop->next) { - if (loop->next == del) { - loop->next = del->next; - return 0; - } - } - - /* is not in list ? */ - return -1; -} - -static struct results_store *new_store(struct private_data *priv) -{ - struct results_store *newr; - int new_id = priv->next_free_id++; - - /* TODO: we should have a limit on the number of - * outstanding paged searches - */ - - newr = talloc(priv, struct results_store); - if (!newr) return NULL; - - newr->priv = priv; - - newr->cookie = talloc_asprintf(newr, "%d", new_id); - if (!newr->cookie) { - talloc_free(newr); - return NULL; - } - - newr->timestamp = time(NULL); - - newr->first = NULL; - newr->num_entries = 0; - newr->first_ref = NULL; - newr->controls = NULL; - - newr->next = priv->store; - priv->store = newr; - - talloc_set_destructor(newr, store_destructor); - - return newr; -} - -struct paged_context { - struct ldb_module *module; - struct ldb_request *req; - - struct results_store *store; - int size; - struct ldb_control **controls; -}; - -static int paged_results(struct paged_context *ac) -{ - struct ldb_paged_control *paged; - struct message_store *msg; - int i, num_ctrls, ret; - - if (ac->store == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - while (ac->store->num_entries > 0 && ac->size > 0) { - msg = ac->store->first; - ret = ldb_module_send_entry(ac->req, msg->r->message, msg->r->controls); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->store->first = msg->next; - talloc_free(msg); - ac->store->num_entries--; - ac->size--; - } - - while (ac->store->first_ref != NULL) { - msg = ac->store->first_ref; - ret = ldb_module_send_referral(ac->req, msg->r->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->store->first_ref = msg->next; - talloc_free(msg); - } - - /* return result done */ - num_ctrls = 1; - i = 0; - - if (ac->store->controls != NULL) { - while (ac->store->controls[i]) i++; /* counting */ - - num_ctrls += i; - } - - ac->controls = talloc_array(ac, struct ldb_control *, num_ctrls +1); - if (ac->controls == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac->controls[num_ctrls] = NULL; - - for (i = 0; i < (num_ctrls -1); i++) { - ac->controls[i] = talloc_reference(ac->controls, ac->store->controls[i]); - } - - ac->controls[i] = talloc(ac->controls, struct ldb_control); - if (ac->controls[i] == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->oid = talloc_strdup(ac->controls[i], - LDB_CONTROL_PAGED_RESULTS_OID); - if (ac->controls[i]->oid == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->critical = 0; - - paged = talloc(ac->controls[i], struct ldb_paged_control); - if (paged == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->data = paged; - - if (ac->size > 0) { - paged->size = 0; - paged->cookie = NULL; - paged->cookie_len = 0; - } else { - paged->size = ac->store->num_entries; - paged->cookie = talloc_strdup(paged, ac->store->cookie); - paged->cookie_len = strlen(paged->cookie) + 1; - } - - return LDB_SUCCESS; -} - -static int paged_search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct paged_context *ac ; - struct message_store *msg_store; - int ret; - - ac = talloc_get_type(req->context, struct paged_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: - msg_store = talloc(ac->store, struct message_store); - if (msg_store == NULL) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - msg_store->next = NULL; - msg_store->r = talloc_steal(msg_store, ares); - - if (ac->store->first == NULL) { - ac->store->first = msg_store; - } else { - ac->store->last->next = msg_store; - } - ac->store->last = msg_store; - - ac->store->num_entries++; - - break; - - case LDB_REPLY_REFERRAL: - msg_store = talloc(ac->store, struct message_store); - if (msg_store == NULL) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - msg_store->next = NULL; - msg_store->r = talloc_steal(msg_store, ares); - - if (ac->store->first_ref == NULL) { - ac->store->first_ref = msg_store; - } else { - ac->store->last_ref->next = msg_store; - } - ac->store->last_ref = msg_store; - - break; - - case LDB_REPLY_DONE: - ac->store->controls = talloc_move(ac->store, &ares->controls); - ret = paged_results(ac); - return ldb_module_done(ac->req, ac->controls, - ares->response, ret); - } - - return LDB_SUCCESS; -} - -static int paged_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct private_data *private_data; - struct ldb_paged_control *paged_ctrl; - struct ldb_control **saved_controls; - struct ldb_request *search_req; - struct paged_context *ac; - int ret; - - /* check if there's a paged request control */ - control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - paged_ctrl = talloc_get_type(control->data, struct ldb_paged_control); - if (!paged_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - private_data = talloc_get_type(module->private_data, struct private_data); - - ac = talloc_zero(req, struct paged_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->size = paged_ctrl->size; - - /* check if it is a continuation search the store */ - if (paged_ctrl->cookie_len == 0) { - if (paged_ctrl->size == 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->store = new_store(private_data); - if (ac->store == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req_ex(&search_req, module->ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - ac, - paged_search_callback, - req); - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(control, search_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); - - } else { - struct results_store *current = NULL; - - /* TODO: age out old outstanding requests */ - for (current = private_data->store; current; current = current->next) { - if (strcmp(current->cookie, paged_ctrl->cookie) == 0) { - current->timestamp = time(NULL); - break; - } - } - if (current == NULL) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ac->store = current; - - /* check if it is an abandon */ - if (ac->size == 0) { - return ldb_module_done(req, NULL, NULL, - LDB_SUCCESS); - } - - ret = paged_results(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - return ldb_module_done(req, ac->controls, NULL, - LDB_SUCCESS); - } -} - -static int paged_request_init(struct ldb_module *module) -{ - struct private_data *data; - int ret; - - data = talloc(module, struct private_data); - if (data == NULL) { - return LDB_ERR_OTHER; - } - - data->next_free_id = 1; - data->store = NULL; - module->private_data = data; - - ret = ldb_mod_register_control(module, LDB_CONTROL_PAGED_RESULTS_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, - "paged_request:" - "Unable to register control with rootdse!\n"); - } - - return ldb_next_init(module); -} - -const struct ldb_module_ops ldb_paged_results_module_ops = { - .name = "paged_results", - .search = paged_search, - .init_context = paged_request_init -}; diff --git a/ldb/modules/paged_searches.c b/ldb/modules/paged_searches.c deleted file mode 100644 index 56f9b1cac..000000000 --- a/ldb/modules/paged_searches.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: paged_searches - * - * Component: ldb paged searches module - * - * Description: this module detects if the remote ldap server supports - * paged results and use them to transparently access all objects - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb_includes.h" - -#define PS_DEFAULT_PAGE_SIZE 500 -/* 500 objects per query seem to be a decent compromise - * the default AD limit per request is 1000 entries */ - -struct private_data { - - bool paged_supported; -}; - -struct ps_context { - struct ldb_module *module; - struct ldb_request *req; - - bool pending; - - char **saved_referrals; - int num_referrals; -}; - -static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ps_context *ac; - struct ldb_paged_control *rep_control, *req_control; - - ac = talloc_get_type(req->context, struct ps_context); - - /* look up our paged control */ - if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) { - /* we are done */ - ac->pending = false; - return LDB_SUCCESS; - } - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - /* if there's a reply control we must find a request - * control matching it */ - - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control); - - if (req_control->cookie) { - talloc_free(req_control->cookie); - } - - req_control->cookie = talloc_memdup(req_control, - rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - ac->pending = true; - return LDB_SUCCESS; -} - -static int store_referral(struct ps_context *ac, char *referral) -{ - ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); - if (!ac->saved_referrals) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); - if (!ac->saved_referrals[ac->num_referrals]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->num_referrals++; - ac->saved_referrals[ac->num_referrals] = NULL; - - return LDB_SUCCESS; -} - -static int send_referrals(struct ps_context *ac) -{ - struct ldb_reply *ares; - int ret; - int i; - - for (i = 0; i < ac->num_referrals; i++) { - ares = talloc_zero(ac->req, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = ac->saved_referrals[i]; - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int ps_next_request(struct ps_context *ac); - -static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ps_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct ps_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: - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_REFERRAL: - ret = store_referral(ac, ares->referral); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_DONE: - - ret = check_ps_continuation(req, ares); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - if (ac->pending) { - - ret = ps_next_request(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - } else { - - /* send referrals */ - ret = send_referrals(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - /* send REPLY_DONE */ - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - break; - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_search(struct ldb_module *module, struct ldb_request *req) -{ - struct private_data *private_data; - struct ps_context *ac; - - private_data = talloc_get_type(module->private_data, struct private_data); - - /* check if paging is supported and if there is a any control */ - if (!private_data || !private_data->paged_supported || req->controls) { - /* do not touch this request paged controls not - * supported or explicit controls have been set or we - * are just not setup yet */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct ps_context); - if (ac == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->pending = false; - ac->saved_referrals = NULL; - ac->num_referrals = 0; - - return ps_next_request(ac); -} - -static int ps_next_request(struct ps_context *ac) { - - struct ldb_paged_control *control; - struct ldb_control **controls; - struct ldb_request *new_req; - int ret; - - controls = talloc_array(ac, struct ldb_control *, 2); - if (!controls) { - return LDB_ERR_OPERATIONS_ERROR; - } - - controls[0] = talloc(controls, struct ldb_control); - if (!controls[0]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control = talloc(controls[0], struct ldb_paged_control); - if (!control) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control->size = PS_DEFAULT_PAGE_SIZE; - control->cookie = NULL; - control->cookie_len = 0; - - controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID; - controls[0]->critical = 1; - controls[0]->data = control; - controls[1] = NULL; - - ret = ldb_build_search_req_ex(&new_req, ac->module->ldb, ac, - ac->req->op.search.base, - ac->req->op.search.scope, - ac->req->op.search.tree, - ac->req->op.search.attrs, - controls, - ac, - ps_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - talloc_steal(new_req, controls); - - return ldb_next_request(ac->module, new_req); -} - -static int check_supported_paged(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct private_data *data; - - data = talloc_get_type(req->context, struct private_data); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - if (ldb_msg_check_string_attribute(ares->message, - "supportedControl", - LDB_CONTROL_PAGED_RESULTS_OID)) { - data->paged_supported = true; - } - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - break; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_init(struct ldb_module *module) -{ - static const char *attrs[] = { "supportedControl", NULL }; - struct private_data *data; - struct ldb_dn *base; - int ret; - struct ldb_request *req; - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - module->private_data = data; - data->paged_supported = false; - - base = ldb_dn_new(module, module->ldb, ""); - if (base == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_build_search_req(&req, module->ldb, module, - base, LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, NULL, - data, check_supported_paged, - NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_next_request(module, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_free(base); - talloc_free(req); - - return ldb_next_init(module); -} - -_PUBLIC_ const struct ldb_module_ops ldb_paged_searches_module_ops = { - .name = "paged_searches", - .search = ps_search, - .init_context = ps_init -}; diff --git a/ldb/modules/rdn_name.c b/ldb/modules/rdn_name.c deleted file mode 100644 index 62b8ce511..000000000 --- a/ldb/modules/rdn_name.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlet 2005 - Copyright (C) Simo Sorce 2006-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: rdb_name - * - * Component: ldb rdn name module - * - * Description: keep a consistent name attribute on objects manpulations - * - * Author: Andrew Bartlet - * - * Modifications: - * - made the module async - * Simo Sorce Mar 2006 - */ - -#include "ldb_includes.h" - -struct rename_context { - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_reply *ares; -}; - -static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name) -{ - int i; - - for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(name, msg->elements[i].name) == 0) { - return &msg->elements[i]; - } - } - - return NULL; -} - -static int rdn_name_add_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct 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); - } - - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); -} - -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *down_req; - struct rename_context *ac; - struct ldb_message *msg; - struct ldb_message_element *attribute; - const struct ldb_schema_attribute *a; - const char *rdn_name; - struct ldb_val rdn_val; - int i, ret; - - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n"); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - msg = ldb_msg_copy_shallow(req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn)); - - /* Perhaps someone above us tried to set this? */ - if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { - attribute->num_values = 0; - } - - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - attribute = rdn_name_find_attribute(msg, rdn_name); - - if (!attribute) { - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - a = ldb_schema_attribute_by_name(module->ldb, rdn_name); - - for (i = 0; i < attribute->num_values; i++) { - ret = a->syntax->comparison_fn(module->ldb, msg, - &rdn_val, &attribute->values[i]); - if (ret == 0) { - /* overwrite so it matches in case */ - attribute->values[i] = rdn_val; - break; - } - } - if (i == attribute->num_values) { - ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, - "RDN mismatch on %s: %s (%s)", - ldb_dn_get_linearized(msg->dn), rdn_name, rdn_val.data); - talloc_free(ac); - /* Match AD's error here */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - } - - ret = ldb_build_add_req(&down_req, module->ldb, req, - msg, - req->controls, - ac, rdn_name_add_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(down_req, msg); - - /* go on with the call chain */ - return ldb_next_request(module, down_req); -} - -static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct 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); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* send saved controls eventually */ - return ldb_module_done(ac->req, ac->ares->controls, - ac->ares->response, LDB_SUCCESS); -} - -static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct rename_context *ac; - struct ldb_request *mod_req; - const char *rdn_name; - struct ldb_val rdn_val; - struct ldb_message *msg; - int ret; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - goto error; - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - goto error; - } - - /* save reply for caller */ - ac->ares = talloc_steal(ac, ares); - - msg = ldb_msg_new(ac); - if (msg == NULL) { - goto error; - } - msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); - if (msg->dn == NULL) { - goto error; - } - rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); - if (rdn_name == NULL) { - goto error; - } - - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn)); - - if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - goto error; - } - if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - goto error; - } - - ret = ldb_build_mod_req(&mod_req, ac->module->ldb, - ac, msg, NULL, - ac, rdn_modify_callback, - req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_steal(mod_req, msg); - - /* do the mod call */ - return ldb_request(ac->module->ldb, mod_req); - -error: - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); -} - -static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct rename_context *ac; - struct ldb_request *down_req; - int ret; - - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n"); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.newdn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - ret = ldb_build_rename_req(&down_req, - module->ldb, - ac, - req->op.rename.olddn, - req->op.rename.newdn, - req->controls, - ac, - rdn_rename_callback, - req); - - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* rename first, modify "name" if rename is ok */ - return ldb_next_request(module, down_req); -} - -const struct ldb_module_ops ldb_rdn_name_module_ops = { - .name = "rdn_name", - .add = rdn_name_add, - .rename = rdn_name_rename, -}; diff --git a/ldb/modules/skel.c b/ldb/modules/skel.c deleted file mode 100644 index 0cd29ac4b..000000000 --- a/ldb/modules/skel.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: ldb - * - * Component: ldb skel module - * - * Description: example module - * - * Author: Simo Sorce - */ - -#include "ldb_includes.h" - -struct private_data { - - char *some_private_data; -}; - -/* search */ -static int skel_search(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* add */ -static int skel_add(struct ldb_module *module, struct ldb_request *req){ - return ldb_next_request(module, req); -} - -/* modify */ -static int skel_modify(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* delete */ -static int skel_delete(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* rename */ -static int skel_rename(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* start a transaction */ -static int skel_start_trans(struct ldb_module *module) -{ - return ldb_next_start_trans(module); -} - -/* end a transaction */ -static int skel_end_trans(struct ldb_module *module) -{ - return ldb_next_end_trans(module); -} - -/* delete a transaction */ -static int skel_del_trans(struct ldb_module *module) -{ - return ldb_next_del_trans(module); -} - -static int skel_destructor(struct ldb_module *ctx) -{ - struct private_data *data = talloc_get_type(ctx->private_data, struct private_data); - /* put your clean-up functions here */ - if (data->some_private_data) talloc_free(data->some_private_data); - return 0; -} - -static int skel_request(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -static int skel_init(struct ldb_module *module) -{ - struct private_data *data; - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - data->some_private_data = NULL; - module->private_data = data; - - talloc_set_destructor (module, skel_destructor); - - return ldb_next_init(module); -} - -const struct ldb_module_ops ldb_skel_module_ops = { - .name = "skel", - .init_context = skel_init, - .search = skel_search, - .add = skel_add, - .modify = skel_modify, - .del = skel_delete, - .rename = skel_rename, - .request = skel_request, - .start_transaction = skel_start_trans, - .end_transaction = skel_end_trans, - .del_transaction = skel_del_trans, -}; diff --git a/ldb/modules/sort.c b/ldb/modules/sort.c deleted file mode 100644 index 25e56b24c..000000000 --- a/ldb/modules/sort.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ - -/* - * Name: ldb - * - * Component: ldb server side sort control module - * - * Description: this module sorts the results of a search - * - * Author: Simo Sorce - */ - -#include "ldb_includes.h" - -struct opaque { - struct ldb_context *ldb; - const struct ldb_attrib_handler *h; - const char *attribute; - int reverse; - int result; -}; - -struct sort_context { - struct ldb_module *module; - - char *attributeName; - char *orderingRule; - int reverse; - - struct ldb_request *req; - struct ldb_message **msgs; - char **referrals; - int num_msgs; - int num_refs; - - const struct ldb_schema_attribute *a; - int sort_result; -}; - -static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) -{ - struct ldb_control **controls; - struct ldb_sort_resp_control *resp; - int i; - - if (*ctrls) { - controls = *ctrls; - for (i = 0; controls[i]; i++); - controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); - } else { - i = 0; - controls = talloc_array(mem_ctx, struct ldb_control *, 2); - } - if (! controls ) - return LDB_ERR_OPERATIONS_ERROR; - - *ctrls = controls; - - controls[i+1] = NULL; - controls[i] = talloc(controls, struct ldb_control); - if (! controls[i] ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; - controls[i]->critical = 0; - - resp = talloc(controls[i], struct ldb_sort_resp_control); - if (! resp ) - return LDB_ERR_OPERATIONS_ERROR; - - resp->result = result; - resp->attr_desc = talloc_strdup(resp, desc); - - if (! resp->attr_desc ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->data = resp; - - return LDB_SUCCESS; -} - -static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) -{ - struct sort_context *ac = talloc_get_type(opaque, struct sort_context); - struct ldb_message_element *el1, *el2; - - if (!ac || ac->sort_result != 0) { - /* an error occurred previously, - * let's exit the sorting by returning always 0 */ - return 0; - } - - el1 = ldb_msg_find_element(*msg1, ac->attributeName); - el2 = ldb_msg_find_element(*msg2, ac->attributeName); - - if (!el1 || !el2) { - /* the attribute was not found return and - * set an error */ - ac->sort_result = LDB_ERR_UNWILLING_TO_PERFORM; - return 0; - } - - if (ac->reverse) - return ac->a->syntax->comparison_fn(ac->module->ldb, ac, &el2->values[0], &el1->values[0]); - - return ac->a->syntax->comparison_fn(ac->module->ldb, ac, &el1->values[0], &el2->values[0]); -} - -static int server_sort_results(struct sort_context *ac) -{ - struct ldb_reply *ares; - int i, ret; - - ac->a = ldb_schema_attribute_by_name(ac->module->ldb, ac->attributeName); - ac->sort_result = 0; - - ldb_qsort(ac->msgs, ac->num_msgs, - sizeof(struct ldb_message *), - ac, (ldb_qsort_cmp_fn_t)sort_compare); - - if (ac->sort_result != LDB_SUCCESS) { - return ac->sort_result; - } - - for (i = 0; i < ac->num_msgs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_move(ares, &ac->msgs[i]); - - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - for (i = 0; i < ac->num_refs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_move(ares, &ac->referrals[i]); - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct sort_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct sort_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: - ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); - if (! ac->msgs) { - talloc_free(ares); - ldb_oom(ac->module->ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); - ac->num_msgs++; - ac->msgs[ac->num_msgs] = NULL; - - break; - - case LDB_REPLY_REFERRAL: - ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); - if (! ac->referrals) { - talloc_free(ares); - ldb_oom(ac->module->ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); - ac->num_refs++; - ac->referrals[ac->num_refs] = NULL; - - break; - - case LDB_REPLY_DONE: - - ret = server_sort_results(ac); - return ldb_module_done(ac->req, ares->controls, - ares->response, ret); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int server_sort_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct ldb_server_sort_control **sort_ctrls; - struct ldb_control **saved_controls; - struct ldb_control **controls; - struct ldb_request *down_req; - struct sort_context *ac; - int ret; - - /* check if there's a paged request control */ - control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct sort_context); - if (ac == NULL) { - ldb_oom(module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); - if (!sort_ctrls) { - return LDB_ERR_PROTOCOL_ERROR; - } - - /* FIXME: we do not support more than one attribute for sorting right now */ - /* FIXME: we need to check if the attribute type exist or return an error */ - - if (sort_ctrls[1] != NULL) { - if (control->critical) { - - /* callback immediately */ - ret = build_response(req, &controls, - LDB_ERR_UNWILLING_TO_PERFORM, - "sort control is not complete yet"); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(req, controls, NULL, ret); - } else { - /* just pass the call down and don't do any sorting */ - return ldb_next_request(module, req); - } - } - - ac->attributeName = sort_ctrls[0]->attributeName; - ac->orderingRule = sort_ctrls[0]->orderingRule; - ac->reverse = sort_ctrls[0]->reverse; - - ret = ldb_build_search_req_ex(&down_req, module->ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - ac, - server_sort_search_callback, - req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, down_req); -} - -static int server_sort_init(struct ldb_module *module) -{ - int ret; - - ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, - "server_sort:" - "Unable to register control with rootdse!\n"); - } - - return ldb_next_init(module); -} - -const struct ldb_module_ops ldb_server_sort_module_ops = { - .name = "server_sort", - .search = server_sort_search, - .init_context = server_sort_init -}; |