svn commit: samba r25959 - in branches/SAMBA_4_0/source/lib/ldb/ldb_tdb: .

abartlet at samba.org abartlet at samba.org
Thu Nov 15 01:53:45 GMT 2007


Author: abartlet
Date: 2007-11-15 01:53:44 +0000 (Thu, 15 Nov 2007)
New Revision: 25959

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=25959

Log:
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

Modified:
   branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_cache.c
   branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_search.c
   branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.h


Changeset:
Modified: branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_cache.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_cache.c	2007-11-15 01:13:24 UTC (rev 25958)
+++ branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_cache.c	2007-11-15 01:53:44 UTC (rev 25959)
@@ -113,11 +113,13 @@
 	if (dn == NULL) goto failed;
 
 	r = ltdb_search_dn1(module, dn, msg);
+	talloc_free(dn);
 	if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
-		talloc_free(dn);
 		goto failed;
 	}
-	talloc_free(dn);
+	if (r == LDB_ERR_NO_SUCH_OBJECT) {
+		return 0;
+	}
 	/* mapping these flags onto ldap 'syntaxes' isn't strictly correct,
 	   but its close enough for now */
 	for (i=0;i<msg->num_elements;i++) {
@@ -247,10 +249,10 @@
 int ltdb_cache_load(struct ldb_module *module)
 {
 	struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data;
-	struct ldb_dn *baseinfo_dn = NULL;
+	struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL;
 	struct ldb_dn *indexlist_dn = NULL;
 	uint64_t seq;
-	struct ldb_message *baseinfo = NULL;
+	struct ldb_message *baseinfo = NULL, *options = NULL;
 	int r;
 
 	/* a very fast check to avoid extra database reads */
@@ -282,7 +284,7 @@
 	}
 	
 	/* possibly initialise the baseinfo */
-	if (!baseinfo->dn) {
+	if (r == LDB_ERR_NO_SUCH_OBJECT) {
 		if (ltdb_baseinfo_init(module) != LDB_SUCCESS) {
 			goto failed;
 		}
@@ -301,6 +303,25 @@
 	}
 	ltdb->sequence_number = seq;
 
+	/* Read an interpret database options */
+	options = talloc(ltdb->cache, struct ldb_message);
+	if (options == NULL) goto failed;
+
+	options_dn = ldb_dn_new(module, module->ldb, LTDB_OPTIONS);
+	if (options_dn == NULL) goto failed;
+
+	r= ltdb_search_dn1(module, options_dn, options);
+	if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) {
+		goto failed;
+	}
+	
+	/* possibly initialise the baseinfo */
+	if (r == LDB_SUCCESS) {
+		ltdb->check_base = ldb_msg_find_attr_as_bool(options, LTDB_CHECK_BASE, false);
+	} else {
+		ltdb->check_base = false;
+	}
+
 	talloc_free(ltdb->cache->last_attribute.name);
 	memset(&ltdb->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
 
@@ -328,12 +349,16 @@
 	}
 
 done:
+	talloc_free(options);
+	talloc_free(options_dn);
 	talloc_free(baseinfo);
 	talloc_free(baseinfo_dn);
 	talloc_free(indexlist_dn);
 	return 0;
 
 failed:
+	talloc_free(options);
+	talloc_free(options_dn);
 	talloc_free(baseinfo);
 	talloc_free(baseinfo_dn);
 	talloc_free(indexlist_dn);

Modified: branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_search.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_search.c	2007-11-15 01:13:24 UTC (rev 25958)
+++ branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_search.c	2007-11-15 01:53:44 UTC (rev 25959)
@@ -200,7 +200,36 @@
 	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
   in a single message
@@ -227,7 +256,7 @@
 	if (!tdb_data.dptr) {
 		return LDB_ERR_NO_SUCH_OBJECT;
 	}
-
+	
 	msg->num_elements = 0;
 	msg->elements = NULL;
 
@@ -473,10 +502,6 @@
 	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 @@
 		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 @@
 	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 @@
 	}
 
 	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);
 

Modified: branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.h
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.h	2007-11-15 01:13:24 UTC (rev 25958)
+++ branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.h	2007-11-15 01:53:44 UTC (rev 25959)
@@ -31,6 +31,8 @@
 	} *cache;
 
 	int in_transaction;
+
+	bool check_base;
 };
 
 /*
@@ -58,10 +60,12 @@
 #define LTDB_IDXATTR    "@IDXATTR"
 #define LTDB_IDXONE     "@IDXONE"
 #define LTDB_BASEINFO   "@BASEINFO"
+#define LTDB_OPTIONS    "@OPTIONS"
 #define LTDB_ATTRIBUTES "@ATTRIBUTES"
 
 /* special attribute types */
 #define LTDB_SEQUENCE_NUMBER "sequenceNumber"
+#define LTDB_CHECK_BASE "checkBaseOnSearch"
 #define LTDB_MOD_TIMESTAMP "whenChanged"
 #define LTDB_OBJECTCLASS "objectClass"
 



More information about the samba-cvs mailing list