[dovecot-cvs] dovecot/src/auth auth-request-handler-default.c, 1.4, 1.5 auth-request.c, 1.8, 1.9 auth-request.h, 1.8, 1.9 db-ldap.c, 1.26, 1.27 passdb-bsdauth.c, 1.6, 1.7 passdb-cache.c, 1.5, 1.6 passdb-cache.h, 1.1, 1.2 passdb-checkpassword.c, 1.6, 1.7 passdb-ldap.c, 1.23, 1.24 passdb-pam.c, 1.20, 1.21 passdb-passwd-file.c, 1.14, 1.15 passdb-passwd.c, 1.9, 1.10 passdb-shadow.c, 1.10, 1.11 passdb-sql.c, 1.13, 1.14 passdb-vpopmail.c, 1.14, 1.15 passdb.c, 1.31, 1.32 passdb.h, 1.21, 1.22 userdb-ldap.c, 1.27, 1.28 userdb-passdb.c, 1.3, 1.4

cras at dovecot.org cras at dovecot.org
Sun Feb 27 00:55:06 EET 2005


Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv3072

Modified Files:
	auth-request-handler-default.c auth-request.c auth-request.h 
	db-ldap.c passdb-bsdauth.c passdb-cache.c passdb-cache.h 
	passdb-checkpassword.c passdb-ldap.c passdb-pam.c 
	passdb-passwd-file.c passdb-passwd.c passdb-shadow.c 
	passdb-sql.c passdb-vpopmail.c passdb.c passdb.h userdb-ldap.c 
	userdb-passdb.c 
Log Message:
Moved cache handling from sql/ldap-specific code to generic auth-request
code. Did some small optimizations on the way.



Index: auth-request-handler-default.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request-handler-default.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- auth-request-handler-default.c	12 Feb 2005 13:47:20 -0000	1.4
+++ auth-request-handler-default.c	26 Feb 2005 22:55:03 -0000	1.5
@@ -114,10 +114,10 @@
 		return NULL;
 
 	/* we only wish to remove all fields prefixed with "userdb_" */
-	if (strstr(request->extra_fields, "userdb_") == NULL)
-		return request->extra_fields;
+	if (strstr(str_c(request->extra_fields), "userdb_") == NULL)
+		return str_c(request->extra_fields);
 
-	fields = t_strsplit(request->extra_fields, "\t");
+	fields = t_strsplit(str_c(request->extra_fields), "\t");
 	for (src = dest = 0; fields[src] != NULL; src++) {
 		if (strncmp(fields[src], "userdb_", 7) != 0)
 			fields[dest++] = fields[src];

Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- auth-request.c	12 Feb 2005 13:47:20 -0000	1.8
+++ auth-request.c	26 Feb 2005 22:55:03 -0000	1.9
@@ -14,12 +14,6 @@
 #include "passdb.h"
 #include "passdb-cache.h"
 
-struct auth_request_extra {
-	struct auth_request *request;
-	string_t *str;
-	char *user_password, *password;
-};
-
 struct auth_request *
 auth_request_new(struct auth *auth, struct mech_module *mech,
 		 mech_callback_t *callback, void *context)
@@ -90,19 +84,132 @@
 	request->mech->auth_continue(request, data, data_size);
 }
 
+static void auth_request_save_cache(struct auth_request *request,
+				    enum passdb_result result)
+{
+	struct passdb_module *passdb = request->auth->passdb;
+	string_t *str;
+
+	if (passdb_cache == NULL)
+		return;
+
+	if (passdb->cache_key == NULL)
+		return;
+
+	if (result < 0) {
+		/* lookup failed. */
+		if (result == PASSDB_RESULT_USER_UNKNOWN) {
+			auth_cache_insert(passdb_cache, request,
+					  passdb->cache_key, "");
+		}
+		return;
+	}
+
+	/* save all except the currently given password in cache */
+	str = t_str_new(32 + str_len(request->extra_fields));
+	if (request->passdb_password != NULL) {
+		if (*request->passdb_password != '{') {
+			/* cached passwords must have a known scheme */
+			str_append_c(str, '{');
+			str_append(str, passdb->default_pass_scheme);
+			str_append_c(str, '}');
+		}
+		str_append(str, request->passdb_password);
+	}
+	if (request->extra_fields != NULL) {
+		str_append_c(str, '\t');
+		str_append_str(str, request->extra_fields);
+	}
+	if (request->no_failure_delay) {
+		str_append_c(str, '\t');
+		str_append(str, "nodelay");
+	}
+	auth_cache_insert(passdb_cache, request, passdb->cache_key, str_c(str));
+}
+
+static void auth_request_verify_plain_callback(enum passdb_result result,
+					       struct auth_request *request)
+{
+        auth_request_save_cache(request, result);
+
+	if (request->proxy) {
+		/* we're proxying - send back the password that was
+		   sent by user (not the password in passdb). */
+		str_printfa(request->extra_fields, "\tpass=%s",
+			    request->mech_password);
+	}
+
+	if (request->passdb_password != NULL) {
+		safe_memset(request->passdb_password, 0,
+			    strlen(request->mech_password));
+	}
+
+        safe_memset(request->mech_password, 0, strlen(request->mech_password));
+	request->private_callback.verify_plain(result, request);
+}
+
 void auth_request_verify_plain(struct auth_request *request,
 			       const char *password,
 			       verify_plain_callback_t *callback)
 {
-	request->auth->passdb->verify_plain(request, password, callback);
+	struct passdb_module *passdb = request->auth->passdb;
+	enum passdb_result result;
+	const char *cache_key;
+
+	cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
+	if (cache_key != NULL) {
+		if (passdb_cache_verify_plain(request, cache_key, password,
+					      &result)) {
+			callback(result, request);
+			return;
+		}
+	}
+
+	request->mech_password = p_strdup(request->pool, password);
+	request->private_callback.verify_plain = callback;
+	passdb->verify_plain(request, password,
+			     auth_request_verify_plain_callback);
+}
+
+static void
+auth_request_lookup_credentials_callback(enum passdb_result result,
+					 const char *credentials,
+					 struct auth_request *request)
+{
+        auth_request_save_cache(request, result);
+
+	if (request->passdb_password != NULL) {
+		safe_memset(request->passdb_password, 0,
+			    strlen(request->mech_password));
+	}
+
+	request->private_callback.lookup_credentials(result, credentials,
+						     request);
 }
 
 void auth_request_lookup_credentials(struct auth_request *request,
 				     enum passdb_credentials credentials,
 				     lookup_credentials_callback_t *callback)
 {
-	request->auth->passdb->lookup_credentials(request, credentials,
-						  callback);
+	struct passdb_module *passdb = request->auth->passdb;
+	const char *cache_key, *result, *scheme;
+
+	cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
+	if (cache_key != NULL) {
+		if (passdb_cache_lookup_credentials(request, cache_key,
+						    &result, &scheme)) {
+			passdb_handle_credentials(result != NULL ?
+						  PASSDB_RESULT_OK :
+						  PASSDB_RESULT_USER_UNKNOWN,
+						  credentials, result, scheme,
+						  callback, request);
+			return;
+		}
+	}
+
+	request->private_callback.lookup_credentials = callback;
+	passdb->lookup_credentials(request, credentials,
+				   auth_request_lookup_credentials_callback);
 }
 
 void auth_request_lookup_user(struct auth_request *request,
@@ -142,50 +249,45 @@
 	return TRUE;
 }
 
-struct auth_request_extra *
-auth_request_extra_begin(struct auth_request *request)
-{
-	struct auth_request_extra *extra;
-
-	extra = i_new(struct auth_request_extra, 1);
-	extra->request = request;
-	return extra;
-}
-
-void auth_request_extra_next(struct auth_request_extra *extra,
-			     const char *name, const char *value)
+void auth_request_set_field(struct auth_request *request,
+			    const char *name, const char *value)
 {
 	string_t *str;
 
 	i_assert(value != NULL);
 
 	if (strcmp(name, "password") == 0) {
-		i_assert(extra->password == NULL);
-		extra->password = i_strdup(value);
+		if (request->passdb_password == NULL) {
+			request->passdb_password =
+				p_strdup(request->pool, value);
+		} else {
+			auth_request_log_error(request, "auth",
+				"Multiple password values not supported");
+		}
 		return;
 	}
 
 	if (strcmp(name, "nodelay") == 0) {
 		/* don't delay replying to client of the failure */
-		extra->request->no_failure_delay = TRUE;
+		request->no_failure_delay = TRUE;
 		return;
 	}
 
-	str = extra->str;
+	str = request->extra_fields;
 	if (str == NULL)
-		extra->str = str = str_new(extra->request->pool, 64);
+		request->extra_fields = str = str_new(request->pool, 64);
 
 	if (strcmp(name, "nologin") == 0) {
 		/* user can't actually login - don't keep this
 		   reply for master */
-		extra->request->no_login = TRUE;
+		request->no_login = TRUE;
 		if (str_len(str) > 0)
 			str_append_c(str, '\t');
 		str_append(str, name);
 	} else if (strcmp(name, "proxy") == 0) {
 		/* we're proxying authentication for this user. send
 		   password back if using plaintext authentication. */
-		extra->request->proxy = TRUE;
+		request->proxy = TRUE;
 		if (str_len(str) > 0)
 			str_append_c(str, '\t');
 		str_append(str, name);
@@ -196,45 +298,6 @@
 	}
 }
 
-void auth_request_extra_finish(struct auth_request_extra *extra,
-			       const char *user_password, const char *cache_key)
-{
-	string_t *str;
-
-	if (passdb_cache != NULL && cache_key != NULL) {
-		str = t_str_new(64);
-		if (extra->str != NULL)
-			str_append_str(str, extra->str);
-		if (extra->request->no_failure_delay) {
-			if (str_len(str) > 0)
-				str_append_c(str, '\t');
-			str_append(str, "nodelay");
-		}
-		auth_cache_insert(passdb_cache, extra->request, cache_key,
-				  t_strconcat(extra->password == NULL ? "" :
-					      extra->password,
-					      str_len(str) > 0 ? "\t" : "",
-					      str_c(str), NULL));
-	}
-
-	if (user_password != NULL) {
-		if (extra->request->proxy) {
-			/* we're proxying - send back the password that was
-			   sent by user (not the password in passdb). */
-			str_printfa(extra->str, "\tpass=%s", user_password);
-		}
-	}
-
-	if (extra->str != NULL)
-		extra->request->extra_fields = str_c(extra->str);
-
-	if (extra->password != NULL) {
-		safe_memset(extra->password, 0, strlen(extra->password));
-		i_free(extra->password);
-	}
-	i_free(extra);
-}
-
 static const char *escape_none(const char *str)
 {
 	return str;

Index: auth-request.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- auth-request.h	12 Feb 2005 13:47:20 -0000	1.8
+++ auth-request.h	26 Feb 2005 22:55:03 -0000	1.9
@@ -13,7 +13,9 @@
 
 	pool_t pool;
 	char *user;
-	const char *extra_fields;
+	char *mech_password; /* set if verify_plain() is called */
+	char *passdb_password; /* set after password lookup if successful */
+	string_t *extra_fields;
 
 	struct mech_module *mech;
 	struct auth *auth;
@@ -26,6 +28,11 @@
 	const char *service;
 	struct ip_addr local_ip, remote_ip;
 
+	union {
+		verify_plain_callback_t *verify_plain;
+                lookup_credentials_callback_t *lookup_credentials;
+	} private_callback;
+
 	mech_callback_t *callback;
 	void *context;
 
@@ -68,13 +75,8 @@
 int auth_request_set_username(struct auth_request *request,
 			      const char *username, const char **error_r);
 
-struct auth_request_extra *
-auth_request_extra_begin(struct auth_request *request);
-void auth_request_extra_next(struct auth_request_extra *extra,
-			     const char *name, const char *value);
-void auth_request_extra_finish(struct auth_request_extra *extra,
-			       const char *user_password,
-			       const char *cache_key);
+void auth_request_set_field(struct auth_request *request,
+			    const char *name, const char *value);
 
 const struct var_expand_table *
 auth_request_get_var_expand_table(const struct auth_request *auth_request,

Index: db-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- db-ldap.c	12 Feb 2005 13:47:20 -0000	1.26
+++ db-ldap.c	26 Feb 2005 22:55:03 -0000	1.27
@@ -118,7 +118,6 @@
 	if (!conn->connected) {
 		if (!db_ldap_connect(conn)) {
 			request->callback(conn, request, NULL);
-			i_free(request);
 			return;
 		}
 	}
@@ -128,7 +127,6 @@
 		i_error("LDAP: ldap_search() failed (filter %s): %s",
 			filter, ldap_get_error(conn));
 		request->callback(conn, request, NULL);
-		i_free(request);
 		return;
 	}
 
@@ -171,7 +169,6 @@
 		} else {
 			hash_remove(conn->requests, POINTER_CAST(msgid));
 			request->callback(conn, request, res);
-			i_free(request);
 		}
 
 		ldap_msgfree(res);
@@ -254,7 +251,6 @@
 		struct ldap_request *request = value;
 
 		request->callback(conn, request, NULL);
-		i_free(request);
 	}
 	hash_iterate_deinit(iter);
 	hash_clear(conn->requests, FALSE);

Index: passdb-bsdauth.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-bsdauth.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- passdb-bsdauth.c	8 Jan 2005 16:56:04 -0000	1.6
+++ passdb-bsdauth.c	26 Feb 2005 22:55:03 -0000	1.7
@@ -58,6 +58,7 @@
 
 struct passdb_module passdb_bsdauth = {
 	"bsdauth",
+	"%u", "CRYPT",
 
 	NULL, NULL,
 	bsdauth_deinit,

Index: passdb-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- passdb-cache.c	12 Feb 2005 13:47:20 -0000	1.5
+++ passdb-cache.c	26 Feb 2005 22:55:03 -0000	1.6
@@ -9,16 +9,13 @@
 
 struct auth_cache *passdb_cache = NULL;
 
-static void list_save(struct auth_request *request, const char *password,
-		      const char *const *list)
+static void list_save(struct auth_request *request, const char *const *list)
 {
-	struct auth_request_extra *extra;
 	const char *name, *value;
 
 	if (*list == NULL)
 		return;
 
-	extra = auth_request_extra_begin(request);
 	for (; *list != NULL; list++) {
 		t_push();
 		value = strchr(*list, '=');
@@ -30,21 +27,18 @@
 			value++;
 		}
 
-		auth_request_extra_next(extra, name, value);
+		auth_request_set_field(request, name, value);
 		t_pop();
 	}
-	auth_request_extra_finish(extra, password, NULL);
 }
 
 int passdb_cache_verify_plain(struct auth_request *request, const char *key,
-			      const char *password, const char *default_scheme,
+			      const char *password,
 			      enum passdb_result *result_r)
 {
 	const char *value, *cached_pw, *scheme, *const *list;
 	int ret;
 
-	i_assert(default_scheme != NULL);
-
 	if (passdb_cache == NULL)
 		return FALSE;
 
@@ -63,9 +57,9 @@
 	cached_pw = list[0];
 
 	scheme = password_get_scheme(&cached_pw);
-	if (scheme == NULL)
-		scheme = default_scheme;
-        list_save(request, password, list+1);
+	i_assert(scheme != NULL);
+
+        list_save(request, list + 1);
 
 	ret = password_verify(password, cached_pw, scheme, request->user);
 	if (ret < 0) {
@@ -101,10 +95,11 @@
 	}
 
 	list = t_strsplit(value, "\t");
-        list_save(request, NULL, list+1);
+        list_save(request, list + 1);
 
 	*result_r = list[0];
 	*scheme_r = password_get_scheme(result_r);
+	i_assert(*scheme_r != NULL);
 	return TRUE;
 }
 

Index: passdb-cache.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- passdb-cache.h	21 Oct 2004 02:23:12 -0000	1.1
+++ passdb-cache.h	26 Feb 2005 22:55:03 -0000	1.2
@@ -7,7 +7,7 @@
 extern struct auth_cache *passdb_cache;
 
 int passdb_cache_verify_plain(struct auth_request *request, const char *key,
-			      const char *password, const char *default_scheme,
+			      const char *password,
 			      enum passdb_result *result_r);
 int passdb_cache_lookup_credentials(struct auth_request *request,
 				    const char *key, const char **result_r,

Index: passdb-checkpassword.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-checkpassword.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- passdb-checkpassword.c	8 Jan 2005 16:56:04 -0000	1.6
+++ passdb-checkpassword.c	26 Feb 2005 22:55:03 -0000	1.7
@@ -62,8 +62,10 @@
 
 	if (result == PASSDB_RESULT_OK) {
 		request->request->extra_fields =
-			p_strdup(request->request->pool,
-				 str_c(request->input_buf));
+			str_new(request->request->pool,
+				str_len(request->input_buf));
+		str_append_str(request->request->extra_fields,
+			       request->input_buf);
 	}
 
 	if (auth_request_unref(request->request)) {
@@ -341,6 +343,7 @@
 
 struct passdb_module passdb_checkpassword = {
 	"checkpassword",
+	NULL, NULL,
 
 	NULL,
 	checkpassword_init,

Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- passdb-ldap.c	12 Feb 2005 13:47:20 -0000	1.23
+++ passdb-ldap.c	26 Feb 2005 22:55:03 -0000	1.24
@@ -10,13 +10,15 @@
 #include "str.h"
 #include "var-expand.h"
 #include "password-scheme.h"
+#include "auth-cache.h"
 #include "db-ldap.h"
 #include "passdb.h"
-#include "passdb-cache.h"
 
 #include <ldap.h>
 #include <stdlib.h>
 
+extern struct passdb_module passdb_ldap;
+
 static const char *default_attr_map[] = {
 	"user", "password", NULL
 };
@@ -36,30 +38,25 @@
 static struct ldap_connection *passdb_ldap_conn;
 static char *passdb_ldap_cache_key;
 
-static const char *
+static void
 ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry,
-                       struct passdb_ldap_request *ldap_request,
 		       struct auth_request *auth_request)
 {
-	struct auth_request_extra *extra;
 	BerElement *ber;
-	const char *name, *password;
+	const char *name;
 	char *attr, **vals;
 	unsigned int i;
 
-	extra = auth_request_extra_begin(auth_request);
-
-	password = NULL;
 	attr = ldap_first_attribute(conn->ld, entry, &ber);
 	while (attr != NULL) {
 		name = hash_lookup(passdb_ldap_conn->attr_map, attr);
 		vals = ldap_get_values(conn->ld, entry, attr);
 
-		if (name != NULL && vals != NULL && vals[0] != NULL) {
-			if (strcmp(name, "password") == 0 && vals[1] == NULL)
-				password = t_strdup(vals[0]);
-			for (i = 0; vals[i] != NULL; i++)
-				auth_request_extra_next(extra, name, vals[i]);
+		if (name != NULL && vals != NULL) {
+			for (i = 0; vals[i] != NULL; i++) {
+				auth_request_set_field(auth_request,
+						       name, vals[i]);
+			}
 		}
 
 		ldap_value_free(vals);
@@ -67,9 +64,6 @@
 
 		attr = ldap_next_attribute(conn->ld, entry, ber);
 	}
-
-	auth_request_extra_finish(extra, ldap_request->password, NULL);
-	return password;
 }
 
 static void handle_request(struct ldap_connection *conn,
@@ -78,12 +72,12 @@
 	struct passdb_ldap_request *ldap_request =
 		(struct passdb_ldap_request *) request;
         struct auth_request *auth_request = request->context;
-	enum passdb_result result;
+	enum passdb_result passdb_result;
 	LDAPMessage *entry;
 	const char *password, *scheme;
 	int ret;
 
-	result = PASSDB_RESULT_USER_UNKNOWN;
+	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
 	password = NULL;
 
 	if (res != NULL) {
@@ -92,8 +86,6 @@
 			auth_request_log_error(auth_request, "ldap",
 					       "ldap_search() failed: %s",
 					       ldap_err2string(ret));
-
-                        result = PASSDB_RESULT_INTERNAL_FAILURE;
 			res = NULL;
 		}
 	}
@@ -103,18 +95,20 @@
 		if (res != NULL) {
 			auth_request_log_info(auth_request, "ldap",
 					      "unknown user");
+			passdb_result = PASSDB_RESULT_USER_UNKNOWN;
 		}
 	} else {
-		password = ldap_query_save_result(conn, entry, ldap_request,
-						  auth_request);
+		ldap_query_save_result(conn, entry, auth_request);
 
-		if (password == NULL) {
+		if (auth_request->passdb_password == NULL) {
 			auth_request_log_error(auth_request, "ldap",
 					       "No password in reply");
 		} else if (ldap_next_entry(conn->ld, entry) != NULL) {
 			auth_request_log_error(auth_request, "ldap",
 					       "Multiple password replies");
-			password = NULL;
+		} else {
+			password = auth_request->passdb_password;
+			passdb_result = PASSDB_RESULT_OK;
 		}
 	}
 
@@ -130,8 +124,8 @@
 	}
 
 	if (ldap_request->credentials != -1) {
-		passdb_handle_credentials(result, ldap_request->credentials,
-			password, scheme,
+		passdb_handle_credentials(passdb_result,
+			ldap_request->credentials, password, scheme,
 			ldap_request->callback.lookup_credentials,
 			auth_request);
 		return;
@@ -139,7 +133,8 @@
 
 	/* verify plain */
 	if (password == NULL) {
-		ldap_request->callback.verify_plain(result, auth_request);
+		ldap_request->callback.verify_plain(passdb_result,
+						    auth_request);
 		return;
 	}
 
@@ -192,24 +187,15 @@
 }
 
 static void
-ldap_verify_plain(struct auth_request *request, const char *password,
+ldap_verify_plain(struct auth_request *request,
+		  const char *password __attr_unused__,
 		  verify_plain_callback_t *callback)
 {
 	struct passdb_ldap_request *ldap_request;
-	enum passdb_result result;
 
-	if (passdb_cache_verify_plain(request, passdb_ldap_cache_key, password,
-				      passdb_ldap_conn->set.default_pass_scheme,
-				      &result)) {
-		callback(result, request);
-		return;
-	}
-
-	ldap_request = i_malloc(sizeof(struct passdb_ldap_request) +
-				strlen(password));
+	ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
 	ldap_request->credentials = -1;
 	ldap_request->callback.verify_plain = callback;
-	strcpy(ldap_request->password, password);
 
         ldap_lookup_pass(request, &ldap_request->request);
 }
@@ -219,20 +205,8 @@
 				    lookup_credentials_callback_t *callback)
 {
 	struct passdb_ldap_request *ldap_request;
-	const char *result, *scheme;
-
-	if (passdb_cache_lookup_credentials(request, passdb_ldap_cache_key,
-					    &result, &scheme)) {
-		if (scheme == NULL)
-			scheme = passdb_ldap_conn->set.default_pass_scheme;
-		passdb_handle_credentials(result != NULL ? PASSDB_RESULT_OK :
-					  PASSDB_RESULT_USER_UNKNOWN,
-					  credentials, result, scheme,
-					  callback, request);
-		return;
-	}
 
-	ldap_request = i_new(struct passdb_ldap_request, 1);
+	ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
 	ldap_request->credentials = credentials;
 	ldap_request->callback.lookup_credentials = callback;
 
@@ -245,8 +219,10 @@
 
 	db_ldap_set_attrs(passdb_ldap_conn, passdb_ldap_conn->set.pass_attrs,
 			  default_attr_map);
-	passdb_ldap_cache_key =
+	passdb_ldap.cache_key = passdb_ldap_cache_key =
 		auth_cache_parse_key(passdb_ldap_conn->set.pass_filter);
+	passdb_ldap.default_pass_scheme =
+		passdb_ldap_conn->set.default_pass_scheme;
 }
 
 static void passdb_ldap_init(const char *args __attr_unused__)
@@ -263,6 +239,7 @@
 
 struct passdb_module passdb_ldap = {
 	"ldap",
+	NULL, NULL,
 
 	passdb_ldap_preinit,
 	passdb_ldap_init,

Index: passdb-pam.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-pam.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- passdb-pam.c	8 Jan 2005 16:56:04 -0000	1.20
+++ passdb-pam.c	26 Feb 2005 22:55:03 -0000	1.21
@@ -401,6 +401,7 @@
 
 struct passdb_module passdb_pam = {
 	"pam",
+	NULL, NULL,
 
 	NULL,
 	pam_init,

Index: passdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- passdb-passwd-file.c	8 Jan 2005 16:56:04 -0000	1.14
+++ passdb-passwd-file.c	26 Feb 2005 22:55:03 -0000	1.15
@@ -84,6 +84,7 @@
 
 struct passdb_module passdb_passwd_file = {
 	"passwd-file",
+	NULL, NULL,
 
 	NULL,
 	passwd_file_init,

Index: passdb-passwd.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-passwd.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- passdb-passwd.c	8 Jan 2005 16:56:04 -0000	1.9
+++ passdb-passwd.c	26 Feb 2005 22:55:03 -0000	1.10
@@ -55,6 +55,7 @@
 
 struct passdb_module passdb_passwd = {
 	"passwd",
+	"%u", "CRYPT",
 
 	NULL, NULL,
 	passwd_deinit,

Index: passdb-shadow.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-shadow.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- passdb-shadow.c	8 Jan 2005 16:56:04 -0000	1.10
+++ passdb-shadow.c	26 Feb 2005 22:55:03 -0000	1.11
@@ -55,6 +55,7 @@
 
 struct passdb_module passdb_shadow = {
 	"shadow",
+	"%u", "CRYPT",
 
 	NULL, NULL,
 	shadow_deinit,

Index: passdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-sql.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- passdb-sql.c	12 Feb 2005 13:47:20 -0000	1.13
+++ passdb-sql.c	26 Feb 2005 22:55:03 -0000	1.14
@@ -10,13 +10,15 @@
 #include "strescape.h"
 #include "var-expand.h"
 #include "password-scheme.h"
+#include "auth-cache.h"
 #include "db-sql.h"
 #include "passdb.h"
-#include "passdb-cache.h"
 
 #include <stdlib.h>
 #include <string.h>
 
+extern struct passdb_module passdb_sql;
+
 struct passdb_sql_request {
 	struct auth_request *auth_request;
 	enum passdb_credentials credentials;
@@ -24,38 +26,26 @@
 		verify_plain_callback_t *verify_plain;
                 lookup_credentials_callback_t *lookup_credentials;
 	} callback;
-
-	char password[1];
 };
 
 static struct sql_connection *passdb_sql_conn;
 static char *passdb_sql_cache_key;
 
-static void result_save_extra_fields(struct sql_result *result,
-				     unsigned int skip_idx,
-				     struct passdb_sql_request *sql_request)
+static void sql_query_save_results(struct sql_result *result,
+				   struct passdb_sql_request *sql_request)
 {
 	struct auth_request *auth_request = sql_request->auth_request;
-	struct auth_request_extra *extra;
 	unsigned int i, fields_count;
 	const char *name, *value;
 
-	extra = auth_request_extra_begin(auth_request);
-
-	fields_count = sql_result_get_fields_count(result);
+        fields_count = sql_result_get_fields_count(result);
 	for (i = 0; i < fields_count; i++) {
-		if (i == skip_idx)
-			continue;
-
 		name = sql_result_get_field_name(result, i);
 		value = sql_result_get_field_value(result, i);
 
 		if (value != NULL)
-			auth_request_extra_next(extra, name, value);
+			auth_request_set_field(auth_request, name, value);
 	}
-
-	auth_request_extra_finish(extra, sql_request->password,
-				  passdb_sql_cache_key);
 }
 
 static void sql_query_callback(struct sql_result *result, void *context)
@@ -64,9 +54,9 @@
 	struct auth_request *auth_request = sql_request->auth_request;
 	enum passdb_result passdb_result;
 	const char *user, *password, *scheme;
-	int ret, idx;
+	int ret;
 
-	passdb_result = PASSDB_RESULT_USER_UNKNOWN;
+	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
 	user = auth_request->user;
 	password = NULL;
 
@@ -75,28 +65,22 @@
 		auth_request_log_error(auth_request, "sql",
 				       "Password query failed: %s",
 				       sql_result_get_error(result));
-		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
 	} else if (ret == 0) {
 		auth_request_log_info(auth_request, "sql", "unknown user");
-		if (passdb_cache != NULL) {
-			auth_cache_insert(passdb_cache, auth_request,
-					  passdb_sql_cache_key, "");
-		}
-	} else if ((idx = sql_result_find_field(result, "password")) < 0) {
-		auth_request_log_error(auth_request, "sql",
-			"Password query must return a field named 'password'");
+		passdb_result = PASSDB_RESULT_USER_UNKNOWN;
 	} else {
-		password = t_strdup(sql_result_get_field_value(result, idx));
-		result_save_extra_fields(result, idx, sql_request);
-		passdb_result = PASSDB_RESULT_OK;
-	}
+		sql_query_save_results(result, sql_request);
 
-	if (ret > 0) {
-		/* make sure there was only one row returned */
-		if (sql_result_next_row(result) > 0) {
+		if (auth_request->passdb_password == NULL) {
+			auth_request_log_error(auth_request, "sql",
+				"Password query must return a field named "
+				"'password'");
+		} else if (sql_result_next_row(result) > 0) {
 			auth_request_log_error(auth_request, "sql",
 				"Password query returned multiple matches");
-			password = NULL;
+		} else {
+			password = auth_request->passdb_password;
+			passdb_result = PASSDB_RESULT_OK;
 		}
 	}
 
@@ -111,18 +95,17 @@
 			sql_request->credentials, password, scheme,
 			sql_request->callback.lookup_credentials,
 			auth_request);
-		i_free(sql_request);
 		return;
 	}
 
 	/* verify plain */
 	if (password == NULL) {
 		sql_request->callback.verify_plain(passdb_result, auth_request);
-		i_free(sql_request);
 		return;
 	}
 
-	ret = password_verify(sql_request->password, password, scheme, user);
+	ret = password_verify(auth_request->mech_password, password,
+			      scheme, user);
 	if (ret < 0) {
 		auth_request_log_error(auth_request, "sql",
 				       "Unknown password scheme %s", scheme);
@@ -133,7 +116,6 @@
 	sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
 					   PASSDB_RESULT_PASSWORD_MISMATCH,
 					   auth_request);
-	i_free(sql_request);
 }
 
 static void sql_lookup_pass(struct passdb_sql_request *sql_request)
@@ -152,25 +134,16 @@
 		  sql_query_callback, sql_request);
 }
 
-static void sql_verify_plain(struct auth_request *request, const char *password,
+static void sql_verify_plain(struct auth_request *request,
+			     const char *password __attr_unused__,
 			     verify_plain_callback_t *callback)
 {
 	struct passdb_sql_request *sql_request;
-	enum passdb_result result;
-
-	if (passdb_cache_verify_plain(request, passdb_sql_cache_key, password,
-				      passdb_sql_conn->set.default_pass_scheme,
-				      &result)) {
-		callback(result, request);
-		return;
-	}
 
-	sql_request = i_malloc(sizeof(struct passdb_sql_request) +
-			       strlen(password));
+	sql_request = p_new(request->pool, struct passdb_sql_request, 1);
 	sql_request->auth_request = request;
 	sql_request->credentials = -1;
 	sql_request->callback.verify_plain = callback;
-	strcpy(sql_request->password, password);
 
 	sql_lookup_pass(sql_request);
 }
@@ -180,20 +153,8 @@
 				   lookup_credentials_callback_t *callback)
 {
 	struct passdb_sql_request *sql_request;
-	const char *result, *scheme;
-
-	if (passdb_cache_lookup_credentials(request, passdb_sql_cache_key,
-					    &result, &scheme)) {
-		if (scheme == NULL)
-			scheme = passdb_sql_conn->set.default_pass_scheme;
-		passdb_handle_credentials(result != NULL ? PASSDB_RESULT_OK :
-					  PASSDB_RESULT_USER_UNKNOWN,
-					  credentials, result, scheme,
-					  callback, request);
-		return;
-	}
 
-	sql_request = i_new(struct passdb_sql_request, 1);
+	sql_request = p_new(request->pool, struct passdb_sql_request, 1);
 	sql_request->auth_request = request;
 	sql_request->credentials = credentials;
 	sql_request->callback.lookup_credentials = callback;
@@ -204,8 +165,11 @@
 static void passdb_sql_preinit(const char *args)
 {
 	passdb_sql_conn = db_sql_init(args);
-	passdb_sql_cache_key =
+
+	passdb_sql.cache_key = passdb_sql_cache_key =
 		auth_cache_parse_key(passdb_sql_conn->set.password_query);
+	passdb_sql.default_pass_scheme =
+		passdb_sql_conn->set.default_pass_scheme;
 }
 
 static void passdb_sql_init(const char *args __attr_unused__)
@@ -221,11 +185,12 @@
 
 struct passdb_module passdb_sql = {
 	"sql",
+	NULL, NULL,
 
 	passdb_sql_preinit,
 	passdb_sql_init,
 	passdb_sql_deinit,
-
+       
 	sql_verify_plain,
 	sql_lookup_credentials
 };

Index: passdb-vpopmail.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-vpopmail.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- passdb-vpopmail.c	8 Jan 2005 16:56:04 -0000	1.14
+++ passdb-vpopmail.c	26 Feb 2005 22:55:03 -0000	1.15
@@ -47,7 +47,7 @@
 
 	crypted_pass = vpw->pw_passwd;
 	scheme = password_get_scheme(&crypted_pass);
-	if (scheme == NULL) scheme = "CRYPT";
+	if (scheme == NULL) scheme = passdb_vpopmail->default_pass_scheme;
 
 	ret = password_verify(password, crypted_pass, scheme, request->user);
 
@@ -98,6 +98,7 @@
 
 struct passdb_module passdb_vpopmail = {
 	"vpopmail",
+	"%u", "CRYPT",
 
 	NULL, NULL,
 	vpopmail_deinit,

Index: passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- passdb.c	8 Jan 2005 16:56:04 -0000	1.31
+++ passdb.c	26 Feb 2005 22:55:03 -0000	1.32
@@ -159,6 +159,9 @@
 	passdb_cache_init();
 	if (auth->passdb->init != NULL)
 		auth->passdb->init(auth->passdb_args);
+
+	i_assert(auth->passdb->default_pass_scheme != NULL ||
+		 auth->passdb->cache_key == NULL);
 }
 
 void passdb_deinit(struct auth *auth)

Index: passdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- passdb.h	8 Jan 2005 15:59:49 -0000	1.21
+++ passdb.h	26 Feb 2005 22:55:03 -0000	1.22
@@ -37,6 +37,12 @@
 struct passdb_module {
 	const char *name;
 
+	/* The caching key for this module, or NULL if caching isn't wanted. */
+	const char *cache_key;
+	/* Default password scheme for this module.
+	   If cache_key is set, must not be NULL. */
+	const char *default_pass_scheme;
+
 	void (*preinit)(const char *args);
 	void (*init)(const char *args);
 	void (*deinit)(void);

Index: userdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-ldap.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- userdb-ldap.c	12 Feb 2005 13:47:20 -0000	1.27
+++ userdb-ldap.c	26 Feb 2005 22:55:03 -0000	1.28
@@ -181,7 +181,7 @@
 	var_expand(str, conn->set.user_filter, vars);
 	filter = str_c(str);
 
-	request = i_new(struct userdb_ldap_request, 1);
+	request = p_new(auth_request->pool, struct userdb_ldap_request, 1);
 	request->request.callback = handle_request;
 	request->request.context = context;
 	request->auth_request = auth_request;

Index: userdb-passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-passdb.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- userdb-passdb.c	12 Feb 2005 13:47:20 -0000	1.3
+++ userdb-passdb.c	26 Feb 2005 22:55:03 -0000	1.4
@@ -36,7 +36,7 @@
 	str = t_str_new(256);
 	str_append(str, auth_request->user);
 
-	args = t_strsplit(auth_request->extra_fields, "\t");
+	args = t_strsplit(str_c(auth_request->extra_fields), "\t");
 	for (; *args != NULL; args++) {
 		const char *arg = *args;
 



More information about the dovecot-cvs mailing list