Mercurial > dovecot > core-2.2
changeset 3161:6a3254e3c3de HEAD
Moved cache handling from sql/ldap-specific code to generic auth-request
code. Did some small optimizations on the way.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 27 Feb 2005 00:55:03 +0200 |
parents | 42d18b4e5047 |
children | 5d6787582410 |
files | src/auth/auth-request-handler-default.c src/auth/auth-request.c src/auth/auth-request.h src/auth/db-ldap.c src/auth/passdb-bsdauth.c src/auth/passdb-cache.c src/auth/passdb-cache.h src/auth/passdb-checkpassword.c src/auth/passdb-ldap.c src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-passwd.c src/auth/passdb-shadow.c src/auth/passdb-sql.c src/auth/passdb-vpopmail.c src/auth/passdb.c src/auth/passdb.h src/auth/userdb-ldap.c src/auth/userdb-passdb.c |
diffstat | 19 files changed, 236 insertions(+), 220 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request-handler-default.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/auth-request-handler-default.c Sun Feb 27 00:55:03 2005 +0200 @@ -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];
--- a/src/auth/auth-request.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/auth-request.c Sun Feb 27 00:55:03 2005 +0200 @@ -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;
--- a/src/auth/auth-request.h Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/auth-request.h Sun Feb 27 00:55:03 2005 +0200 @@ -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,
--- a/src/auth/db-ldap.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/db-ldap.c Sun Feb 27 00:55:03 2005 +0200 @@ -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);
--- a/src/auth/passdb-bsdauth.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-bsdauth.c Sun Feb 27 00:55:03 2005 +0200 @@ -58,6 +58,7 @@ struct passdb_module passdb_bsdauth = { "bsdauth", + "%u", "CRYPT", NULL, NULL, bsdauth_deinit,
--- a/src/auth/passdb-cache.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-cache.c Sun Feb 27 00:55:03 2005 +0200 @@ -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; }
--- a/src/auth/passdb-cache.h Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-cache.h Sun Feb 27 00:55:03 2005 +0200 @@ -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,
--- a/src/auth/passdb-checkpassword.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-checkpassword.c Sun Feb 27 00:55:03 2005 +0200 @@ -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,
--- a/src/auth/passdb-ldap.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-ldap.c Sun Feb 27 00:55:03 2005 +0200 @@ -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,
--- a/src/auth/passdb-pam.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-pam.c Sun Feb 27 00:55:03 2005 +0200 @@ -401,6 +401,7 @@ struct passdb_module passdb_pam = { "pam", + NULL, NULL, NULL, pam_init,
--- a/src/auth/passdb-passwd-file.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-passwd-file.c Sun Feb 27 00:55:03 2005 +0200 @@ -84,6 +84,7 @@ struct passdb_module passdb_passwd_file = { "passwd-file", + NULL, NULL, NULL, passwd_file_init,
--- a/src/auth/passdb-passwd.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-passwd.c Sun Feb 27 00:55:03 2005 +0200 @@ -55,6 +55,7 @@ struct passdb_module passdb_passwd = { "passwd", + "%u", "CRYPT", NULL, NULL, passwd_deinit,
--- a/src/auth/passdb-shadow.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-shadow.c Sun Feb 27 00:55:03 2005 +0200 @@ -55,6 +55,7 @@ struct passdb_module passdb_shadow = { "shadow", + "%u", "CRYPT", NULL, NULL, shadow_deinit,
--- a/src/auth/passdb-sql.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-sql.c Sun Feb 27 00:55:03 2005 +0200 @@ -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 };
--- a/src/auth/passdb-vpopmail.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb-vpopmail.c Sun Feb 27 00:55:03 2005 +0200 @@ -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,
--- a/src/auth/passdb.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb.c Sun Feb 27 00:55:03 2005 +0200 @@ -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)
--- a/src/auth/passdb.h Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/passdb.h Sun Feb 27 00:55:03 2005 +0200 @@ -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);
--- a/src/auth/userdb-ldap.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/userdb-ldap.c Sun Feb 27 00:55:03 2005 +0200 @@ -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;
--- a/src/auth/userdb-passdb.c Fri Feb 25 01:59:45 2005 +0200 +++ b/src/auth/userdb-passdb.c Sun Feb 27 00:55:03 2005 +0200 @@ -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;