svn commit: samba r15795 - in branches/SAMBA_4_0/source: dsdb/samdb/ldb_modules lib/ldb/common setup

idra at samba.org idra at samba.org
Mon May 22 03:55:02 GMT 2006


Author: idra
Date: 2006-05-22 03:55:01 +0000 (Mon, 22 May 2006)
New Revision: 15795

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

Log:

Try to use the async code by default
It passess all my tests, but I still need to work on a lot of stuff.
Shouldn't impact anybody else work, so I want to commit now and see what happens

Will work to remove the old code from modules and backends soon, and make some
more restyling in ldb internals.

So, if there is something you don't like in this desgin please speak now.

Simo.


Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/password_hash.c
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samldb.c
   branches/SAMBA_4_0/source/lib/ldb/common/ldb.c
   branches/SAMBA_4_0/source/setup/provision_init.ldif


Changeset:
Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/password_hash.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/password_hash.c	2006-05-22 02:07:11 UTC (rev 15794)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/password_hash.c	2006-05-22 03:55:01 UTC (rev 15795)
@@ -975,16 +975,25 @@
 	return LDB_SUCCESS;
 }
 
-static int set_pwdLastSet(struct ldb_module *module, struct ldb_message *msg)
+static int set_pwdLastSet(struct ldb_module *module, struct ldb_message *msg, int is_mod)
 {
 	NTTIME now_nt;
 
 	/* set it as now */
 	unix_to_nt_time(&now_nt, time(NULL));
 
-	/* replace or add */
-	if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE) != 0) {
-		return LDB_ERR_OPERATIONS_ERROR;
+	if (!is_mod) {
+		/* be sure there isn't a 0 value set (eg. coming from the template) */
+		ldb_msg_remove_attr(msg, "pwdLastSet");
+		/* add */
+		if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_ADD) != 0) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
+	} else {
+		/* replace */
+		if (ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE) != 0) {
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 	}
 
 	if (samdb_msg_add_uint64(module->ldb, msg, msg, "pwdLastSet", now_nt) != 0) {
@@ -1326,7 +1335,7 @@
 
 	/* don't touch it if a value is set. It could be an incoming samsync */
 	if (ldb_msg_find_uint64(msg, "pwdLastSet", 0) == 0) {
-		if (set_pwdLastSet(ac->module, msg) != LDB_SUCCESS) {
+		if (set_pwdLastSet(ac->module, msg, 0) != LDB_SUCCESS) {
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
 	}
@@ -1630,7 +1639,7 @@
 	}
 
 	/* set change time */
-	if (set_pwdLastSet(ac->module, msg) != LDB_SUCCESS) {
+	if (set_pwdLastSet(ac->module, msg, 1) != LDB_SUCCESS) {
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 

Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samldb.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samldb.c	2006-05-22 02:07:11 UTC (rev 15794)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/samldb.c	2006-05-22 03:55:01 UTC (rev 15795)
@@ -94,14 +94,35 @@
 	return (ldb_msg_add_value(msg, name, &v) == 0);
 }
 
-static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value)
+static BOOL samldb_find_or_add_value(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *value, const char *set_value)
 {
+	if (msg == NULL || name == NULL || value == NULL || set_value == NULL) {
+		return False;
+	}
+
 	if (samldb_find_attribute(msg, name, value) == NULL) {
 		return samldb_msg_add_string(module, msg, name, set_value);
 	}
 	return True;
 }
 
+static BOOL samldb_find_or_add_attribute(struct ldb_module *module, struct ldb_message *msg, const char *name, const char *set_value)
+{
+	int j;
+	struct ldb_message_element *el;
+
+	if (msg == NULL || name == NULL || set_value == NULL) {
+		return False;
+	}
+
+       	el = ldb_msg_find_element(msg, name);
+	if (el) {
+		return True;
+	}
+		
+	return samldb_msg_add_string(module, msg, name, set_value);
+}
+
 /*
   allocate a new id, attempting to do it atomically
   return 0 on failure, the id on success
@@ -492,16 +513,15 @@
 				    strcasecmp((char *)el->values[j].data, "secretTemplate") == 0) {
 					continue;
 				}
-				if ( ! samldb_find_or_add_attribute(module, msg, el->name, 
-								    (char *)el->values[j].data,
-								    (char *)el->values[j].data)) {
+				if ( ! samldb_find_or_add_value(module, msg, el->name, 
+								(char *)el->values[j].data,
+								(char *)el->values[j].data)) {
 					ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Attribute adding failed...\n");
 					talloc_free(res);
 					return -1;
 				}
 			} else {
 				if ( ! samldb_find_or_add_attribute(module, msg, el->name, 
-								    NULL,
 								    (char *)el->values[j].data)) {
 					ldb_debug(module->ldb, LDB_DEBUG_FATAL, "Attribute adding failed...\n");
 					talloc_free(res);
@@ -558,7 +578,7 @@
 			talloc_free(mem_ctx);
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
-		if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, name)) {
+		if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) {
 			talloc_free(mem_ctx);
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
@@ -620,7 +640,7 @@
 	}
 
 	/* if the only attribute was: "objectclass: computer", then make sure we also add "user" objectclass */
-	if ( ! samldb_find_or_add_attribute(module, msg2, "objectclass", "user", "user")) {
+	if ( ! samldb_find_or_add_value(module, msg2, "objectclass", "user", "user")) {
 		talloc_free(mem_ctx);
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
@@ -633,7 +653,7 @@
 			talloc_free(mem_ctx);
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
-		if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", NULL, name)) {
+		if ( ! samldb_find_or_add_attribute(module, msg2, "sAMAccountName", name)) {
 			talloc_free(mem_ctx);
 			return LDB_ERR_OPERATIONS_ERROR;
 		}

Modified: branches/SAMBA_4_0/source/lib/ldb/common/ldb.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/common/ldb.c	2006-05-22 02:07:11 UTC (rev 15794)
+++ branches/SAMBA_4_0/source/lib/ldb/common/ldb.c	2006-05-22 03:55:01 UTC (rev 15795)
@@ -2,6 +2,7 @@
    ldb database library
 
    Copyright (C) Andrew Tridgell  2004
+   Copyright (C) Simo Sorce  2005-2006
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -251,6 +252,7 @@
 	return handle->module->ops->async_wait(handle, type);
 }
 
+
 /*
   check for an error return from an op 
   if an op fails, but has not setup an error string, then setup one now
@@ -272,6 +274,7 @@
 /*
   start an ldb request
   autostarts a transacion if none active and the operation is not a search
+  does not work for ASYNC operations
   NOTE: the request must be a talloc context.
   returns LDB_ERR_* on errors.
 */
@@ -285,7 +288,7 @@
 		req->op.search.res = NULL;
 	}
 
-	/* start a transaction if needed */
+	/* start a transaction if not async and not search */
 	if ((!ldb->transaction_active) &&
 	    (req->operation == LDB_REQ_ADD ||
 	     req->operation == LDB_REQ_MODIFY ||
@@ -317,6 +320,71 @@
   Use talloc_free to free the ldb_message returned in 'res', if successful
 
 */
+static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares)
+{
+	struct ldb_result *res;
+	int n;
+	
+ 	if (!context) {
+		ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context in callback"));
+		return LDB_ERR_OPERATIONS_ERROR;
+	}	
+
+	res = *((struct ldb_result **)context);
+
+	if (!res || !ares) {
+		goto error;
+	}
+
+	if (ares->type == LDB_REPLY_ENTRY) {
+		res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2);
+		if (! res->msgs) {
+			goto error;
+		}
+
+		res->msgs[res->count + 1] = NULL;
+
+		res->msgs[res->count] = talloc_steal(res->msgs, ares->message);
+		if (! res->msgs[res->count]) {
+			goto error;
+		}
+
+		res->count++;
+	}
+
+	if (ares->type == LDB_REPLY_REFERRAL) {
+		if (res->refs) {
+			for (n = 0; res->refs[n]; n++) /*noop*/ ;
+		} else {
+			n = 0;
+		}
+
+		res->refs = talloc_realloc(res, res->refs, char *, n + 2);
+		if (! res->refs) {
+			goto error;
+		}
+
+		res->refs[n] = talloc_steal(res->refs, ares->referral);
+		res->refs[n + 1] = NULL;
+	}
+
+	if (ares->controls) {
+		res->controls = talloc_steal(res, ares->controls);
+		if (! res->controls) {
+			goto error;
+		}
+	}
+
+	talloc_free(ares);
+	return LDB_SUCCESS;
+
+error:
+	talloc_free(ares);
+	talloc_free(res);
+	*((struct ldb_result **)context) = NULL;
+	return LDB_ERR_OPERATIONS_ERROR;
+}
+
 int ldb_search(struct ldb_context *ldb, 
 	       const struct ldb_dn *base,
 	       enum ldb_scope scope,
@@ -327,7 +395,10 @@
 	struct ldb_request *req;
 	int ret;
 
-	(*res) = NULL;
+	*res = talloc_zero(ldb, struct ldb_result);
+	if (! *res) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
 
 	req = talloc(ldb, struct ldb_request);
 	if (req == NULL) {
@@ -335,7 +406,7 @@
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	req->operation = LDB_REQ_SEARCH;
+	req->operation = LDB_ASYNC_SEARCH;
 	req->op.search.base = base;
 	req->op.search.scope = scope;
 
@@ -348,16 +419,53 @@
 
 	req->op.search.attrs = attrs;
 	req->controls = NULL;
+	req->creds = NULL;
+	req->async.context = res;
+	req->async.callback = ldb_search_callback;
+	req->async.timeout = 600; /* 10 minutes */
 
 	ret = ldb_request(ldb, req);
 	
 	if (ret == LDB_SUCCESS) {
-		(*res) = talloc_steal(ldb, req->op.search.res);
+		ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
 	}
+	
+	if (ret != LDB_SUCCESS) {
+		talloc_free(*res);
+		*res = NULL;
+	}
+
 	talloc_free(req);
 	return ret;
 }
 
+static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req)
+{
+	int ret, close_transaction;
+
+	close_transaction = 0;
+	if (!ldb->transaction_active) {
+		ret = ldb_transaction_start(ldb);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+		close_transaction = 1;
+	}
+
+	ret = ldb_request(ldb, req);
+
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
+	}
+
+	if (close_transaction) {
+		return ldb_op_finish(ldb, ret);
+	}
+
+	return ret;
+}
+
+
 /*
   add a record to the database. Will fail if a record with the given class and key
   already exists
@@ -377,11 +485,16 @@
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	req->operation = LDB_REQ_ADD;
+	req->operation = LDB_ASYNC_ADD;
 	req->op.add.message = message;
 	req->controls = NULL;
+	req->creds = NULL;
+	req->async.context = NULL;
+	req->async.callback = NULL;
+	req->async.timeout = 600; /* 10 minutes */
 
-	ret = ldb_request(ldb, req);
+	/* do request and autostart a transaction */
+	ret = ldb_autotransaction_request(ldb, req);
 
 	talloc_free(req);
 	return ret;
@@ -405,11 +518,16 @@
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	req->operation = LDB_REQ_MODIFY;
+	req->operation = LDB_ASYNC_MODIFY;
 	req->op.add.message = message;
 	req->controls = NULL;
+	req->creds = NULL;
+	req->async.context = NULL;
+	req->async.callback = NULL;
+	req->async.timeout = 600; /* 10 minutes */
 
-	ret = ldb_request(ldb, req);
+	/* do request and autostart a transaction */
+	ret = ldb_autotransaction_request(ldb, req);
 
 	talloc_free(req);
 	return ret;
@@ -430,11 +548,16 @@
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	req->operation = LDB_REQ_DELETE;
+	req->operation = LDB_ASYNC_DELETE;
 	req->op.del.dn = dn;
 	req->controls = NULL;
+	req->creds = NULL;
+	req->async.context = NULL;
+	req->async.callback = NULL;
+	req->async.timeout = 600; /* 10 minutes */
 
-	ret = ldb_request(ldb, req);
+	/* do request and autostart a transaction */
+	ret = ldb_autotransaction_request(ldb, req);
 
 	talloc_free(req);
 	return ret;
@@ -454,12 +577,17 @@
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	req->operation = LDB_REQ_RENAME;
+	req->operation = LDB_ASYNC_RENAME;
 	req->op.rename.olddn = olddn;
 	req->op.rename.newdn = newdn;
 	req->controls = NULL;
+	req->creds = NULL;
+	req->async.context = NULL;
+	req->async.callback = NULL;
+	req->async.timeout = 600; /* 10 minutes */
 
-	ret = ldb_request(ldb, req);
+	/* do request and autostart a transaction */
+	ret = ldb_autotransaction_request(ldb, req);
 
 	talloc_free(req);
 	return ret;

Modified: branches/SAMBA_4_0/source/setup/provision_init.ldif
===================================================================
--- branches/SAMBA_4_0/source/setup/provision_init.ldif	2006-05-22 02:07:11 UTC (rev 15794)
+++ branches/SAMBA_4_0/source/setup/provision_init.ldif	2006-05-22 03:55:01 UTC (rev 15795)
@@ -82,8 +82,8 @@
 #
 # Some Known ordering constraints:
 # - rootdse must be first, as it makes redirects from "" -> cn=rootdse
-# - password_hash must be before samldb, or else the template code in samldb breaks setting the pwdLastSet attribute
+# - samldb must be before password_hash, because password_hash checks that the objectclass is of type person (filled in by samldb)
 
 dn: @MODULES
- at LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,asq,password_hash,samldb,operational,objectguid,rdn_name,objectclass
+ at LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,objectclass
 



More information about the samba-cvs mailing list