Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5371:fdcea7e3cf0c HEAD
If doing a plain userdb lookup with userdb static, verify the user's
existence from passdb first, unless allow_all_users=yes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 21 Mar 2007 22:12:59 +0200 |
parents | c1d53e221cb2 |
children | 56cb17817e06 |
files | dovecot-example.conf src/auth/auth-master-connection.c src/auth/userdb-static.c |
diffstat | 3 files changed, 85 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Wed Mar 21 22:06:19 2007 +0200 +++ b/dovecot-example.conf Wed Mar 21 22:12:59 2007 +0200 @@ -909,6 +909,13 @@ # # args = uid=500 gid=500 home=/var/mail/%u # + # If you use deliver, it needs to look up users only from the userdb. This + # of course doesn't work with static because there is no list of users. + # Normally static userdb handles this by doing a passdb lookup. This works + # with most passdbs, with PAM being the most notable exception. If you do + # the user verification another way, you can add allow_all_users=yes to + # the args in which case the passdb lookup is skipped. + # #args = #}
--- a/src/auth/auth-master-connection.c Wed Mar 21 22:06:19 2007 +0200 +++ b/src/auth/auth-master-connection.c Wed Mar 21 22:12:59 2007 +0200 @@ -142,6 +142,7 @@ return FALSE; } + auth_request->state = AUTH_REQUEST_STATE_USERDB; auth_request_lookup_user(auth_request, user_callback); return TRUE; }
--- a/src/auth/userdb-static.c Wed Mar 21 22:06:19 2007 +0200 +++ b/src/auth/userdb-static.c Wed Mar 21 22:12:59 2007 +0200 @@ -11,14 +11,21 @@ #include <stdlib.h> +struct static_context { + userdb_callback_t *callback, *old_callback; + void *old_context; +}; + struct static_userdb_module { struct userdb_module module; ARRAY_DEFINE(template, const char *); + + unsigned int allow_all_users:1; }; -static void static_lookup(struct auth_request *auth_request, - userdb_callback_t *callback) +static void static_lookup_real(struct auth_request *auth_request, + userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct static_userdb_module *module = @@ -53,6 +60,70 @@ t_pop(); } +static void +static_credentials_callback(enum passdb_result result, + const char *password __attr_unused__, + struct auth_request *auth_request) +{ + struct static_context *ctx = auth_request->context; + + auth_request->private_callback.userdb = ctx->old_callback; + auth_request->context = ctx->old_context; + auth_request->state = AUTH_REQUEST_STATE_USERDB; + + switch (result) { + case PASSDB_RESULT_OK: + static_lookup_real(auth_request, ctx->callback); + break; + case PASSDB_RESULT_USER_UNKNOWN: + case PASSDB_RESULT_USER_DISABLED: + case PASSDB_RESULT_PASS_EXPIRED: + ctx->callback(USERDB_RESULT_USER_UNKNOWN, NULL, auth_request); + break; + case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: + auth_request_log_error(auth_request, "static", + "passdb doesn't support lookups, " + "can't verify user's existence"); + /* fall through */ + default: + ctx->callback(USERDB_RESULT_INTERNAL_FAILURE, + NULL, auth_request); + break; + } + + i_free(ctx); +} + +static void static_lookup(struct auth_request *auth_request, + userdb_callback_t *callback) +{ + struct userdb_module *_module = auth_request->userdb->userdb; + struct static_userdb_module *module = + (struct static_userdb_module *)_module; + struct static_context *ctx; + + if (!auth_request->successful && !module->allow_all_users) { + /* this is a userdb-only lookup. we need to know if this + users exists or not. use a passdb lookup to do that. + if the passdb doesn't support returning credentials, this + will of course fail.. */ + ctx = i_new(struct static_context, 1); + ctx->old_callback = auth_request->private_callback.userdb; + ctx->old_context = auth_request->context; + ctx->callback = callback; + + i_assert(auth_request->state == AUTH_REQUEST_STATE_USERDB); + auth_request->state = AUTH_REQUEST_STATE_MECH_CONTINUE; + + auth_request->context = ctx; + auth_request_lookup_credentials(auth_request, + PASSDB_CREDENTIALS_CRYPT, + static_credentials_callback); + } else { + static_lookup_real(auth_request, callback); + } +} + static struct userdb_module * static_preinit(struct auth_userdb *auth_userdb, const char *args) { @@ -94,6 +165,10 @@ value); } value = dec2str(gid); + } else if (strcmp(key, "allow_all_users") == 0) { + module->allow_all_users = value == NULL || + strcasecmp(value, "yes") == 0; + continue; } else if (*key == '\0') { i_fatal("Status userdb: Empty key (=%s)", value); }