summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_search.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2007-11-15 01:53:44 +0100
committerStefan Metzmacher <metze@samba.org>2007-12-21 05:45:18 +0100
commitd544879e434c36f02bfc7d1322f1179d00294669 (patch)
treee3296fdf646c1476e2318bc5d932250063892aeb /source4/lib/ldb/ldb_tdb/ldb_search.c
parentf8bf16960e701433572d12f4c888ab271f05f485 (diff)
downloadsamba-d544879e434c36f02bfc7d1322f1179d00294669.tar.gz
samba-d544879e434c36f02bfc7d1322f1179d00294669.tar.bz2
samba-d544879e434c36f02bfc7d1322f1179d00294669.zip
r25959: Add a new special DN to LDB: @OPTIONS
Use the checkBaseOnSearch attribute to control if we should check the base DN on search requests. Also ensure we honour any errors in searching, not just errors in the supplied 'done' callback. Andrew Bartlett (This used to be commit deaac92f439ef001bfe052df170d6e34e8ba5845)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_search.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c122
1 files changed, 110 insertions, 12 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index 8151b458d4..1fa20740a5 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -200,6 +200,35 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
return ret;
}
+/*
+ search the database for a single simple dn.
+ return LDB_ERR_NO_SUCH_OBJECT on record-not-found
+ and LDB_SUCCESS on success
+*/
+int ltdb_search_base(struct ldb_module *module, struct ldb_dn *dn)
+{
+ struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data;
+ TDB_DATA tdb_key, tdb_data;
+
+ if (ldb_dn_is_null(dn)) {
+ return LDB_ERR_NO_SUCH_OBJECT;
+ }
+
+ /* form the key */
+ tdb_key = ltdb_key(module, dn);
+ if (!tdb_key.dptr) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
+ talloc_free(tdb_key.dptr);
+ if (!tdb_data.dptr) {
+ return LDB_ERR_NO_SUCH_OBJECT;
+ }
+
+ free(tdb_data.dptr);
+ return LDB_SUCCESS;
+}
/*
search the database for a single simple dn, returning all attributes
@@ -227,7 +256,7 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes
if (!tdb_data.dptr) {
return LDB_ERR_NO_SUCH_OBJECT;
}
-
+
msg->num_elements = 0;
msg->elements = NULL;
@@ -473,10 +502,6 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
struct ldb_reply *ares;
int ret;
- if ((( ! ldb_dn_is_valid(req->op.search.base)) || ldb_dn_is_null(req->op.search.base)) &&
- (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL))
- return LDB_ERR_OPERATIONS_ERROR;
-
if (ltdb_lock_read(module) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -496,6 +521,65 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
ltdb_unlock_read(module);
return LDB_ERR_OPERATIONS_ERROR;
}
+
+ if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) {
+
+ /* Check what we should do with a NULL dn */
+ switch (req->op.search.scope) {
+ case LDB_SCOPE_BASE:
+ ldb_asprintf_errstring(module->ldb,
+ "NULL Base DN invalid for a base search");
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+ case LDB_SCOPE_ONELEVEL:
+ ldb_asprintf_errstring(module->ldb,
+ "NULL Base DN invalid for a one-level search");
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+ case LDB_SCOPE_SUBTREE:
+ default:
+ /* We accept subtree searches from a NULL base DN, ie over the whole DB */
+ ret = LDB_SUCCESS;
+ }
+ } else if (ldb_dn_is_valid(req->op.search.base) == false) {
+
+ /* We don't want invalid base DNs here */
+ ldb_asprintf_errstring(module->ldb,
+ "Invalid Base DN: %s",
+ ldb_dn_get_linearized(req->op.search.base));
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+
+ } else if (ldb_dn_is_null(req->op.search.base) == true) {
+
+ /* Check what we should do with a NULL dn */
+ switch (req->op.search.scope) {
+ case LDB_SCOPE_BASE:
+ ldb_asprintf_errstring(module->ldb,
+ "NULL Base DN invalid for a base search");
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+ case LDB_SCOPE_ONELEVEL:
+ ldb_asprintf_errstring(module->ldb,
+ "NULL Base DN invalid for a one-level search");
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+ case LDB_SCOPE_SUBTREE:
+ default:
+ /* We accept subtree searches from a NULL base DN, ie over the whole DB */
+ ret = LDB_SUCCESS;
+ }
+
+ } else if (ltdb->check_base) {
+ /* This database has been marked as 'checkBaseOnSearch', so do a spot check of the base dn */
+ ret = ltdb_search_base(module, req->op.search.base);
+
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ ldb_asprintf_errstring(module->ldb,
+ "No such Base DN: %s",
+ ldb_dn_get_linearized(req->op.search.base));
+ }
+
+ } else {
+ /* If we are not checking the base DN life is easy */
+ ret = LDB_SUCCESS;
+ }
+
ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context);
ltdb_ac->tree = req->op.search.tree;
@@ -503,12 +587,23 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
ltdb_ac->base = req->op.search.base;
ltdb_ac->attrs = req->op.search.attrs;
- ret = ltdb_search_indexed(req->handle);
- if (ret == LDB_ERR_OPERATIONS_ERROR) {
- ret = ltdb_search_full(req->handle);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ltdb_search_indexed(req->handle);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ /* Not in the index, therefore OK! */
+ ret = LDB_SUCCESS;
+
+ } else if (ret == LDB_ERR_OPERATIONS_ERROR) {
+ /* Not indexed, so we need to do a full scan */
+ ret = ltdb_search_full(req->handle);
+ if (ret != LDB_SUCCESS) {
+ ldb_set_errstring(module->ldb, "Indexed and full searches both failed!\n");
+ }
+ }
}
+
if (ret != LDB_SUCCESS) {
- ldb_set_errstring(module->ldb, "Indexed and full searches both failed!\n");
req->handle->state = LDB_ASYNC_DONE;
req->handle->status = ret;
}
@@ -522,10 +617,13 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
}
req->handle->state = LDB_ASYNC_DONE;
- ares->type = LDB_REPLY_DONE;
- ret = req->callback(module->ldb, req->context, ares);
- req->handle->status = ret;
+ if (ret == LDB_SUCCESS) {
+ ares->type = LDB_REPLY_DONE;
+
+ ret = req->callback(module->ldb, req->context, ares);
+ req->handle->status = ret;
+ }
ltdb_unlock_read(module);