Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3656:fda241fa5d77 HEAD
Make auth caching work with non-sql/ldap passdbs too.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Oct 2005 15:49:14 +0300 |
parents | 62fc6883faeb |
children | 0c10475d9968 |
files | dovecot-example.conf src/auth/auth-request.c src/auth/passdb-bsdauth.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-vpopmail.c |
diffstat | 8 files changed, 111 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Sun Oct 16 15:03:37 2005 +0300 +++ b/dovecot-example.conf Sun Oct 16 15:49:14 2005 +0300 @@ -513,10 +513,13 @@ # Set max. process size in megabytes. #auth_process_size = 256 -# Authentication cache size in kilobytes. +# Authentication cache size in kilobytes. 0 means it's disabled. +# Note that bsdauth, PAM and vpopmail require cache_key to be set for caching +# to be used. #auth_cache_size = 0 -# Time to live in seconds for cached data. After this many seconds a cached -# record is forced out of cache. +# Time to live in seconds for cached data. After this many seconds the cached +# record is no longer used, *except* if the main database lookup returns +# internal failure. #auth_cache_ttl = 3600 # Space separated list of realms for SASL authentication mechanisms that need @@ -586,10 +589,21 @@ # so it can't be used as userdb. If you don't want to use a separate user # database (passwd usually), you can use static userdb. passdb pam { - # [-session] [<service name>] + # [-session] [cache_key=<key>] [<service name>] # # -session makes Dovecot open and immediately close PAM session. Some # PAM plugins need this to work. + # + # cache_key can be used to enable authentication caching for PAM + # (auth_cache_size also needs to be set). It isn't enabled by default + # because PAM modules can do all kinds of checks besides checking password, + # such as checking IP address. Dovecot can't know about these checks + # without some help. cache_key is simply a list of variables (see + # doc/variables.txt) which must match for the cached data to be used. + # Here are some examples: + # %u - Username must match. Probably sufficient for most uses. + # %u%r - Username and remote IP address must match. + # %u%s - Username and service (ie. IMAP, POP3) must match. # # If service name is "*", it means the authenticating service name # is used, eg. pop3 or imap. @@ -606,6 +620,12 @@ #passdb shadow { #} + # BSD authentication. Used by at least OpenBSD. + #passdb bsdauth { + # [cache_key=<key>] - See cache_key in PAM for explanation. + #args = + #} + # passwd-like file with specified location #passdb passwd-file { # Path for passwd-file @@ -633,6 +653,8 @@ # vpopmail authentication #passdb vpopmail { + # [cache_key=<key>] - See cache_key in PAM for explanation. + #args = #} #
--- a/src/auth/auth-request.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/auth-request.c Sun Oct 16 15:49:14 2005 +0300 @@ -202,8 +202,13 @@ } if (request->passdb_password == NULL) { - /* save to cache only if we know the password */ - return; + /* passdb didn't provide the correct password */ + if (result != PASSDB_RESULT_OK || + request->mech_password == NULL) + return; + + /* we can still cache valid password lookups though */ + request->passdb_password = request->mech_password; } /* save all except the currently given password in cache */ @@ -323,6 +328,8 @@ if (request->mech_password == NULL) request->mech_password = p_strdup(request->pool, password); + else + i_assert(request->mech_password == password); request->private_callback.verify_plain = callback; cache_key = passdb_cache == NULL ? NULL : passdb->cache_key;
--- a/src/auth/passdb-bsdauth.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-bsdauth.c Sun Oct 16 15:49:14 2005 +0300 @@ -12,6 +12,9 @@ #include <bsd_auth.h> #include <pwd.h> +extern struct passdb_module passdb_bsdauth; +static char *bsdauth_cache_key; + static void bsdauth_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) @@ -52,16 +55,28 @@ callback(PASSDB_RESULT_OK, request); } +static void bsdauth_init(const char *args) +{ + bsdauth_cache_key = NULL; + + if (strncmp(args, "cache_key=", 10) == 0) + bsdauth_cache_key = i_strdup(args + 10); + + passdb_bsdauth.cache_key = bsdauth_cache_key; +} + static void bsdauth_deinit(void) { endpwent(); + i_free(bsdauth_cache_key); } struct passdb_module passdb_bsdauth = { "bsdauth", - "%u", "CRYPT", FALSE, + NULL, NULL, FALSE, - NULL, NULL, + NULL, + bsdauth_init, bsdauth_deinit, bsdauth_verify_plain,
--- a/src/auth/passdb-pam.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-pam.c Sun Oct 16 15:49:14 2005 +0300 @@ -71,8 +71,10 @@ const char *pass; }; +extern struct passdb_module passdb_pam; + static int pam_session; -static char *service_name; +static char *service_name, *pam_cache_key; static struct timeout *to_wait; static int pam_userpass_conv(int num_msg, linux_const struct pam_message **msg, @@ -409,13 +411,17 @@ pam_session = FALSE; service_name = i_strdup("dovecot"); + pam_cache_key = NULL; t_push(); t_args = t_strsplit(args, " "); for(i = 0; t_args[i] != NULL; i++) { if (strcmp(t_args[i], "-session") == 0) pam_session = TRUE; - else if (strcmp(t_args[i], "*") == 0) { + else if (strncmp(t_args[i], "cache_key=", 10) == 0) { + i_free(pam_cache_key); + pam_cache_key = i_strdup(t_args[i] + 10); + } else if (strcmp(t_args[i], "*") == 0) { i_free(service_name); service_name = NULL; } else { @@ -428,6 +434,7 @@ t_pop(); to_wait = NULL; + passdb_pam.cache_key = pam_cache_key; } static void pam_deinit(void) @@ -435,6 +442,7 @@ if (to_wait != NULL) timeout_remove(to_wait); i_free(service_name); + i_free(pam_cache_key); } struct passdb_module passdb_pam = {
--- a/src/auth/passdb-passwd-file.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-passwd-file.c Sun Oct 16 15:49:14 2005 +0300 @@ -8,6 +8,9 @@ #include "password-scheme.h" #include "db-passwd-file.h" +#define PASSWD_FILE_CACHE_KEY "%u" +#define PASSWD_FILE_DEFAULT_SCHEME "CRYPT" + struct db_passwd_file *passdb_pwf = NULL; static void @@ -26,7 +29,10 @@ crypted_pass = pu->password; scheme = password_get_scheme(&crypted_pass); - if (scheme == NULL) scheme = "CRYPT"; + if (scheme == NULL) scheme = PASSWD_FILE_DEFAULT_SCHEME; + + /* save the password so cache can use it */ + auth_request_set_field(request, "password", crypted_pass, scheme); ret = password_verify(password, crypted_pass, scheme, request->user); @@ -81,7 +87,9 @@ struct passdb_module passdb_passwd_file = { "passwd-file", - NULL, NULL, FALSE, + PASSWD_FILE_CACHE_KEY, + NULL, + FALSE, NULL, passwd_file_init,
--- a/src/auth/passdb-passwd.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-passwd.c Sun Oct 16 15:49:14 2005 +0300 @@ -10,6 +10,9 @@ #include <pwd.h> +#define PASSWD_CACHE_KEY "%u" +#define PASSWD_PASS_SCHEME "CRYPT" + static void passwd_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) @@ -31,6 +34,10 @@ return; } + /* save the password so cache can use it */ + auth_request_set_field(request, "password", pw->pw_passwd, + PASSWD_PASS_SCHEME); + /* check if the password is valid */ result = strcmp(mycrypt(password, pw->pw_passwd), pw->pw_passwd) == 0; @@ -56,7 +63,9 @@ struct passdb_module passdb_passwd = { "passwd", - "%u", "CRYPT", FALSE, + PASSWD_CACHE_KEY, + PASSWD_PASS_SCHEME, + FALSE, NULL, NULL, passwd_deinit,
--- a/src/auth/passdb-shadow.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-shadow.c Sun Oct 16 15:49:14 2005 +0300 @@ -10,6 +10,9 @@ #include <shadow.h> +#define SHADOW_CACHE_KEY "%u" +#define SHADOW_PASS_SCHEME "CRYPT" + static void shadow_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) @@ -31,6 +34,10 @@ return; } + /* save the password so cache can use it */ + auth_request_set_field(request, "password", spw->sp_pwdp, + SHADOW_PASS_SCHEME); + /* check if the password is valid */ result = strcmp(mycrypt(password, spw->sp_pwdp), spw->sp_pwdp) == 0; @@ -56,7 +63,9 @@ struct passdb_module passdb_shadow = { "shadow", - "%u", "CRYPT", FALSE, + SHADOW_CACHE_KEY, + SHADOW_PASS_SCHEME, + FALSE, NULL, NULL, shadow_deinit,
--- a/src/auth/passdb-vpopmail.c Sun Oct 16 15:03:37 2005 +0300 +++ b/src/auth/passdb-vpopmail.c Sun Oct 16 15:49:14 2005 +0300 @@ -14,7 +14,10 @@ #include <stdlib.h> +#define VPOPMAIL_DEFAULT_PASS_SCHEME "CRYPT" + extern struct passdb_module passdb_vpopmail; +static char *vpopmail_cache_key; static void vpopmail_verify_plain(struct auth_request *request, const char *password, @@ -91,16 +94,30 @@ callback(PASSDB_RESULT_OK, request); } +static void vpopmail_init(const char *args) +{ + vpopmail_cache_key = NULL; + + if (strncmp(args, "cache_key=", 10) == 0) + vpopmail_cache_key = i_strdup(args + 10); + + passdb_vpopmail.cache_key = vpopmail_cache_key; +} + static void vpopmail_deinit(void) { vclose(); + i_free(vpopmail_cache_key); } struct passdb_module passdb_vpopmail = { "vpopmail", - "%u", "CRYPT", FALSE, + NULL, + VPOPMAIL_DEFAULT_PASS_SCHEME, + FALSE, - NULL, NULL, + NULL, + vpopmail_init, vpopmail_deinit, vpopmail_verify_plain,