Mercurial > dovecot > core-2.2
changeset 4955:f0cc5486696e HEAD
Authentication cache caches now also userdb data. Code by Tommi Saviranta.
author | Timo Sirainen <timo.sirainen@movial.fi> |
---|---|
date | Thu, 21 Dec 2006 18:01:15 +0200 |
parents | 8bc6aeec99d9 |
children | 8fd9913adad8 |
files | src/auth/auth-cache.c src/auth/auth-request.c src/auth/auth-request.h src/auth/userdb-ldap.c src/auth/userdb-passwd-file.c src/auth/userdb-passwd.c src/auth/userdb-sql.c src/auth/userdb-vpopmail.c src/auth/userdb.h |
diffstat | 9 files changed, 141 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-cache.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/auth-cache.c Thu Dec 21 18:01:15 2006 +0200 @@ -159,7 +159,8 @@ /* %! is prepended automatically. it contains the passdb ID number. */ str = t_str_new(256); - var_expand(str, t_strconcat("%!/", key, NULL), + var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", + "%!/", key, NULL), auth_request_get_var_expand_table(request, auth_request_str_escape)); @@ -195,9 +196,10 @@ struct auth_cache_node *node; size_t data_size, alloc_size, value_len = strlen(value); - /* %! is prepended automatically. it contains the passdb ID number. */ + /* %! is prepended automatically. it contains the db ID number. */ str = t_str_new(256); - var_expand(str, t_strconcat("%!/", key, NULL), + var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", + "%!/", key, NULL), auth_request_get_var_expand_table(request, auth_request_str_escape));
--- a/src/auth/auth-request.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/auth-request.c Thu Dec 21 18:01:15 2006 +0200 @@ -9,6 +9,7 @@ #include "str-sanitize.h" #include "strescape.h" #include "var-expand.h" +#include "auth-cache.h" #include "auth-request.h" #include "auth-client-connection.h" #include "auth-master-connection.h" @@ -564,10 +565,52 @@ } } +static void auth_request_userdb_save_cache(struct auth_request *request, + struct auth_stream_reply *reply, + enum userdb_result result) +{ + struct userdb_module *userdb = request->userdb->userdb; + const char *str; + + str = auth_stream_reply_export(reply); + auth_cache_insert(passdb_cache, request, userdb->cache_key, str, + result == PASSDB_RESULT_OK); +} + +static bool auth_request_lookup_user_cache(struct auth_request *request, + const char *key, + struct auth_stream_reply **reply_r, + enum userdb_result *result_r, + bool use_expired) +{ + const char *value; + struct auth_cache_node *node; + bool expired; + + value = auth_cache_lookup(passdb_cache, request, key, &node, + &expired); + if (value == NULL || (expired && !use_expired)) + return FALSE; + + if (*value == '\0') { + /* negative cache entry */ + *result_r = PASSDB_RESULT_USER_UNKNOWN; + *reply_r = auth_stream_reply_init(request); + return TRUE; + } + + *result_r = PASSDB_RESULT_OK; + *reply_r = auth_stream_reply_init(request); + auth_stream_reply_import(*reply_r, value); + return TRUE; +} + void auth_request_userdb_callback(enum userdb_result result, struct auth_stream_reply *reply, struct auth_request *request) { + struct userdb_module *userdb = request->userdb->userdb; + if (result != USERDB_RESULT_OK && request->userdb->next != NULL) { /* try next userdb. */ if (result == USERDB_RESULT_INTERNAL_FAILURE) @@ -591,6 +634,20 @@ "user not found from userdb"); } + if (result != PASSDB_RESULT_INTERNAL_FAILURE) + auth_request_userdb_save_cache(request, reply, result); + else { + /* lookup failed. if we're looking here only because the + request was expired in cache, fallback to using cached + expired record. */ + const char *cache_key = userdb->cache_key; + + if (auth_request_lookup_user_cache(request, cache_key, &reply, + &result, TRUE)) + auth_request_log_info(request, "userdb", + "Fallbacking to expired data from cache"); + } + request->private_callback.userdb(result, reply, request); } @@ -598,8 +655,24 @@ userdb_callback_t *callback) { struct userdb_module *userdb = request->userdb->userdb; + const char *cache_key; request->private_callback.userdb = callback; + request->userdb_lookup = TRUE; + + /* (for now) auth_cache is shared between passdb and userdb */ + cache_key = passdb_cache == NULL ? NULL : userdb->cache_key; + if (cache_key != NULL) { + struct auth_stream_reply *reply; + enum userdb_result result; + + if (auth_request_lookup_user_cache(request, cache_key, &reply, + &result, FALSE)) { + request->private_callback.userdb(result, reply, + request); + return; + } + } if (userdb->blocking) userdb_blocking_lookup(request); @@ -994,8 +1067,13 @@ tab[8].value = escape_func(auth_request->mech_password, auth_request); } - tab[9].value = auth_request->passdb == NULL ? "" : - dec2str(auth_request->passdb->id); + if (auth_request->userdb_lookup) { + tab[9].value = auth_request->userdb == NULL ? "" : + dec2str(auth_request->userdb->num); + } else { + tab[9].value = auth_request->passdb == NULL ? "" : + dec2str(auth_request->passdb->id); + } return tab; }
--- a/src/auth/auth-request.h Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/auth-request.h Thu Dec 21 18:01:15 2006 +0200 @@ -81,6 +81,7 @@ unsigned int skip_password_check:1; unsigned int proxy:1; unsigned int cert_username:1; + unsigned int userdb_lookup:1; /* ... mechanism specific data ... */ };
--- a/src/auth/userdb-ldap.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb-ldap.c Thu Dec 21 18:01:15 2006 +0200 @@ -7,6 +7,7 @@ #include "hash.h" #include "str.h" #include "var-expand.h" +#include "auth-cache.h" #include "db-ldap.h" #include "userdb.h" @@ -224,6 +225,9 @@ db_ldap_set_attrs(conn, conn->set.user_attrs, &conn->user_attr_names, conn->user_attr_map, default_attr_map, NULL); + module->module.cache_key = + auth_cache_parse_key(auth_userdb->auth->pool, + conn->set.user_filter); return &module->module; }
--- a/src/auth/userdb-passwd-file.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb-passwd-file.c Thu Dec 21 18:01:15 2006 +0200 @@ -5,10 +5,13 @@ #ifdef USERDB_PASSWD_FILE #include "str.h" +#include "auth-cache.h" #include "var-expand.h" #include "userdb.h" #include "db-passwd-file.h" +#define PASSWD_FILE_CACHE_KEY "%u" + struct passwd_file_userdb_module { struct userdb_module module; @@ -78,6 +81,16 @@ module->auth = auth_userdb->auth; module->pwf = db_passwd_file_init(args, TRUE, module->auth->verbose_debug); + + if (!module->pwf->vars) + module->module.cache_key = PASSWD_FILE_CACHE_KEY; + else { + module->module.cache_key = + auth_cache_parse_key(auth_userdb->auth->pool, + t_strconcat(PASSWD_FILE_CACHE_KEY, + module->pwf->path, + NULL)); + } return &module->module; }
--- a/src/auth/userdb-passwd.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb-passwd.c Thu Dec 21 18:01:15 2006 +0200 @@ -8,6 +8,8 @@ #include <pwd.h> +#define USER_CACHE_KEY "%u" + static void passwd_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { @@ -39,10 +41,19 @@ callback(USERDB_RESULT_OK, reply, auth_request); } +static void passwd_passwd_init(struct userdb_module *module, + const char *args __attr_unused__) +{ + module->cache_key = USER_CACHE_KEY; +} + struct userdb_module_interface userdb_passwd = { "passwd", - NULL, NULL, NULL, + NULL, + passwd_passwd_init, + NULL, + passwd_lookup };
--- a/src/auth/userdb-sql.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb-sql.c Thu Dec 21 18:01:15 2006 +0200 @@ -7,6 +7,7 @@ #include "str.h" #include "strescape.h" #include "var-expand.h" +#include "auth-cache.h" #include "db-sql.h" #include "userdb.h" @@ -147,6 +148,10 @@ module = p_new(auth_userdb->auth->pool, struct sql_userdb_module, 1); module->conn = db_sql_init(args); + + module->module.cache_key = + auth_cache_parse_key(auth_userdb->auth->pool, + module->conn->set.user_query); return &module->module; }
--- a/src/auth/userdb-vpopmail.c Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb-vpopmail.c Thu Dec 21 18:01:15 2006 +0200 @@ -5,7 +5,6 @@ #include "common.h" #if defined(PASSDB_VPOPMAIL) || defined(USERDB_VPOPMAIL) - #include "userdb.h" #include "userdb-vpopmail.h" @@ -38,7 +37,6 @@ } #ifdef USERDB_VPOPMAIL - static void vpopmail_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { @@ -95,10 +93,27 @@ callback(USERDB_RESULT_OK, reply, auth_request); } +static struct userdb_module * +vpopmail_preinit(struct auth_userdb *auth_userdb, const char *args) +{ + struct userdb_module *module; + + module = p_new(auth_userdb->auth->pool, struct userdb_module, 1); + + if (strncmp(args, "cache_key=", 10) == 0) { + module->cache_key = p_strconcat(auth_userdb->auth->pool, + args + 10, NULL); + } + return module; +} + struct userdb_module_interface userdb_vpopmail = { "vpopmail", - NULL, NULL, NULL, + vpopmail_preinit, + NULL, + NULL, + vpopmail_lookup };
--- a/src/auth/userdb.h Thu Dec 21 17:59:05 2006 +0200 +++ b/src/auth/userdb.h Thu Dec 21 18:01:15 2006 +0200 @@ -17,6 +17,9 @@ struct auth_request *request); struct userdb_module { + /* The caching key for this module, or NULL if caching isn't wanted. */ + const char *cache_key; + /* If blocking is set to TRUE, use child processes to access this userdb. */ bool blocking;