summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2006-01-15 06:12:29 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:51:11 -0500
commit3725b1817f1e26370015d955622f0705e9121714 (patch)
tree938954066c19dd5b1265c775f8b08c365c78da2a
parentb71075e836ff3488dd60c54ce9702264fcee6d2f (diff)
downloadsamba-3725b1817f1e26370015d955622f0705e9121714.tar.gz
samba-3725b1817f1e26370015d955622f0705e9121714.tar.bz2
samba-3725b1817f1e26370015d955622f0705e9121714.zip
r12941: Add Attribute Scoped Search control
want to see what it does ? do aq make test and try: ./bin/ldbsearch -H st/private/sam.ldb --controls=asq:1:member -s base -b 'CN=Administrators,CN=Builtin,DC=samba,DC=example,DC=com' 'objectclass=*' have fun. simo. (This used to be commit 900f4fd3435aacc3351f30afb77d3488d2cb4804)
-rw-r--r--source4/lib/ldb/common/ldb_modules.c1
-rw-r--r--source4/lib/ldb/config.mk10
-rw-r--r--source4/lib/ldb/modules/asq.c220
-rw-r--r--source4/lib/ldb/tools/ldbsearch.c4
-rw-r--r--source4/setup/provision_init.ldif2
5 files changed, 236 insertions, 1 deletions
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index f49ccf5413..ddbdddedcc 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -123,6 +123,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
{ "objectclass", objectclass_module_init },
{ "paged_results", paged_results_module_init },
{ "server_sort", server_sort_module_init },
+ { "asq", asq_module_init },
#ifdef _SAMBA_BUILD_
{ "objectguid", objectguid_module_init },
{ "samldb", samldb_module_init },
diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk
index cbd91a6de6..fb1970be08 100644
--- a/source4/lib/ldb/config.mk
+++ b/source4/lib/ldb/config.mk
@@ -1,4 +1,14 @@
################################################
+# Start MODULE libldb_asq
+[MODULE::libldb_asq]
+SUBSYSTEM = LIBLDB
+OUTPUT_TYPE = MERGEDOBJ
+OBJ_FILES = \
+ modules/asq.o
+# End MODULE libldb_asq
+################################################
+
+################################################
# Start MODULE libldb_sort
[MODULE::libldb_sort]
SUBSYSTEM = LIBLDB
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c
new file mode 100644
index 0000000000..1fbf7521fb
--- /dev/null
+++ b/source4/lib/ldb/modules/asq.c
@@ -0,0 +1,220 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005
+
+ ** 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ * 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 "includes.h"
+#include "ldb/include/includes.h"
+
+#define ASQ_CTRL_SUCCESS 0
+#define ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX 21
+#define ASQ_CTRL_UNWILLING_TO_PERFORM 53
+#define ASQ_CTRL_AFFECTS_MULTIPLE_DSA 71
+
+static int build_response(struct ldb_result *res, int result)
+{
+ struct ldb_asq_control *asq;
+ int i;
+
+ if (res->controls) {
+ for (i = 0; res->controls[i]; i++);
+ res->controls = talloc_realloc(res, res->controls, struct ldb_control *, i + 2);
+ } else {
+ i = 0;
+ res->controls = talloc_array(res, struct ldb_control *, 2);
+ }
+ if (res->controls == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ res->controls[i] = talloc(res->controls, struct ldb_control);
+ if (res->controls[i] == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ res->controls[i]->oid = LDB_CONTROL_ASQ_OID;
+ res->controls[i]->critical = 0;
+
+ asq = talloc_zero(res->controls[i], struct ldb_asq_control);
+ if (asq == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ asq->result = result;
+
+ res->controls[i]->data = asq;
+
+ res->controls[i + 1] = NULL;
+
+ return LDB_SUCCESS;
+}
+
+/* search */
+static int asq_search(struct ldb_module *module, struct ldb_request *req)
+{
+ struct ldb_control *control;
+ struct ldb_asq_control *asq_ctrl;
+ struct ldb_request *base_req;
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ char **base_attrs;
+ int i, c, ret;
+
+ /* check if there's a paged request control */
+ control = get_control_from_list(req->controls, LDB_CONTROL_ASQ_OID);
+ if (control == NULL) {
+ /* not found go on */
+ return ldb_next_request(module, req);
+ }
+
+ /* pre-allocate a clean result structure */
+ req->op.search.res = res = talloc_zero(req, struct ldb_result);
+ if (res == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ /* check the search is well formed */
+ if (req->op.search.scope != LDB_SCOPE_BASE) {
+ return build_response(res, ASQ_CTRL_UNWILLING_TO_PERFORM);
+ }
+
+ asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control);
+
+ /* get the object to retrieve the DNs to search */
+ base_req = talloc_zero(req, struct ldb_request);
+ if (base_req == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+ base_req->operation = LDB_REQ_SEARCH;
+ base_req->op.search.base = req->op.search.base;
+ base_req->op.search.scope = LDB_SCOPE_BASE;
+ base_req->op.search.tree = req->op.search.tree;
+ base_attrs = talloc_array(base_req, char *, 2);
+ if (base_attrs == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+ base_attrs[0] = talloc_strdup(base_attrs, asq_ctrl->source_attribute);
+ if (base_attrs[0] == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+ base_attrs[1] = NULL;
+ base_req->op.search.attrs = (const char * const *)base_attrs;
+ base_req->creds = req->creds;
+
+ ret = ldb_request(module->ldb, base_req);
+
+ if (ret != LDB_SUCCESS)
+ return ret;
+
+ /* look up the DNs */
+ el = ldb_msg_find_element(base_req->op.search.res->msgs[0],
+ asq_ctrl->source_attribute);
+ /* no values found */
+ if (el == NULL) {
+ return build_response(res, ASQ_CTRL_SUCCESS);
+ }
+
+ for (i = 0, c = 0; i < el->num_values; i++) {
+ struct ldb_request *exp_req;
+
+ exp_req = talloc_zero(req, struct ldb_request);
+ if (exp_req == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+ exp_req->operation = LDB_REQ_SEARCH;
+ exp_req->op.search.base = ldb_dn_explode(exp_req, el->values[i].data);
+ if (exp_req->op.search.base == NULL) {
+ build_response(res, ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ exp_req->op.search.scope = LDB_SCOPE_BASE;
+ exp_req->op.search.tree = req->op.search.tree;
+ exp_req->op.search.attrs = req->op.search.attrs;
+ exp_req->creds = req->creds;
+
+ ret = ldb_request(module->ldb, exp_req);
+
+ if (ret != LDB_SUCCESS)
+ return ret;
+
+ if (exp_req->op.search.res && exp_req->op.search.res->count != 0) {
+ if (res->msgs == NULL) {
+ res->msgs = talloc_array(res,
+ struct ldb_message *, 2);
+ } else {
+ res->msgs = talloc_realloc(res, res->msgs,
+ struct ldb_message *, c + 2);
+ }
+ if (res->msgs == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ res->msgs[c] = talloc_steal(res->msgs, exp_req->op.search.res->msgs[0]);
+ c++;
+ }
+
+ if (res->msgs) {
+ res->msgs[c] = NULL;
+ res->count = c;
+ }
+
+ talloc_free(exp_req);
+ }
+
+ return build_response(res, ASQ_CTRL_SUCCESS);
+}
+
+static int asq(struct ldb_module *module, struct ldb_request *req)
+{
+ switch (req->operation) {
+
+ case LDB_REQ_SEARCH:
+ return asq_search(module, req);
+
+ default:
+ return ldb_next_request(module, req);
+
+ }
+}
+
+static const struct ldb_module_ops asq_ops = {
+ .name = "asq",
+ .request = asq
+};
+
+struct ldb_module *asq_module_init(struct ldb_context *ldb, const char *options[])
+{
+ struct ldb_module *ctx;
+
+ ctx = talloc(ldb, struct ldb_module);
+ if (!ctx)
+ return NULL;
+
+ ctx->ldb = ldb;
+ ctx->prev = ctx->next = NULL;
+ ctx->ops = &asq_ops;
+ ctx->private_data = NULL;
+
+ return ctx;
+}
diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c
index c81db7eb4d..582861eae2 100644
--- a/source4/lib/ldb/tools/ldbsearch.c
+++ b/source4/lib/ldb/tools/ldbsearch.c
@@ -305,6 +305,10 @@ static int do_search(struct ldb_context *ldb,
ret = ldb_request(ldb, &req);
if (ret != LDB_SUCCESS) {
printf("search failed - %s\n", ldb_errstring(ldb));
+ if (req.op.search.res && req.op.search.res->controls) {
+ /* TODO: handle_control */
+ ;
+ }
return -1;
}
diff --git a/source4/setup/provision_init.ldif b/source4/setup/provision_init.ldif
index 0d0261cf52..a54c5632ca 100644
--- a/source4/setup/provision_init.ldif
+++ b/source4/setup/provision_init.ldif
@@ -78,5 +78,5 @@ isSynchronized: TRUE
#Add modules to the list to activate them by default
#beware often order is important
dn: @MODULES
-@LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,samldb,password_hash,operational,objectguid,rdn_name,objectclass
+@LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,objectclass