diff options
Diffstat (limited to 'src/auth/userdb-static.c')
-rw-r--r-- | src/auth/userdb-static.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/auth/userdb-static.c b/src/auth/userdb-static.c new file mode 100644 index 0000000..bed0f58 --- /dev/null +++ b/src/auth/userdb-static.c @@ -0,0 +1,144 @@ +/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ + +#include "auth-common.h" + +#include "array.h" +#include "str.h" +#include "var-expand.h" +#include "userdb.h" +#include "userdb-template.h" + + +struct static_context { + userdb_callback_t *callback, *old_callback; + void *old_context; +}; + +struct static_userdb_module { + struct userdb_module module; + struct userdb_template *tmpl; + + bool allow_all_users:1; +}; + +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 = + (struct static_userdb_module *)_module; + const char *error; + + if (userdb_template_export(module->tmpl, auth_request, &error) < 0) { + e_error(authdb_event(auth_request), + "Failed to expand template: %s", error); + callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); + } + callback(USERDB_RESULT_OK, auth_request); +} + +static void +static_credentials_callback(enum passdb_result result, + const unsigned char *credentials ATTR_UNUSED, + size_t size ATTR_UNUSED, + struct auth_request *auth_request) +{ + struct static_context *ctx = auth_request->context; + + auth_request->userdb_lookup = TRUE; + + auth_request->private_callback.userdb = ctx->old_callback; + auth_request->context = ctx->old_context; + auth_request_set_state(auth_request, 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, auth_request); + break; + case PASSDB_RESULT_SCHEME_NOT_AVAILABLE: + e_error(authdb_event(auth_request), + "passdb doesn't support lookups, " + "can't verify user's existence"); + /* fall through */ + default: + ctx->callback(USERDB_RESULT_INTERNAL_FAILURE, 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->fields.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_set_state(auth_request, + AUTH_REQUEST_STATE_MECH_CONTINUE); + + auth_request->context = ctx; + if (auth_request->passdb != NULL) { + /* kludge: temporarily work as if we weren't doing + a userdb lookup. this is to get auth cache to use + passdb caching instead of userdb caching. */ + auth_request->userdb_lookup = FALSE; + auth_request_lookup_credentials(auth_request, "", + static_credentials_callback); + } else { + static_credentials_callback( + PASSDB_RESULT_SCHEME_NOT_AVAILABLE, + uchar_empty_ptr, 0, auth_request); + } + } else { + static_lookup_real(auth_request, callback); + } +} + +static struct userdb_module * +static_preinit(pool_t pool, const char *args) +{ + struct static_userdb_module *module; + const char *value; + + module = p_new(pool, struct static_userdb_module, 1); + module->tmpl = userdb_template_build(pool, "static", args); + + if (userdb_template_remove(module->tmpl, "allow_all_users", &value)) { + module->allow_all_users = value == NULL || + strcasecmp(value, "yes") == 0; + } + return &module->module; +} + +struct userdb_module_interface userdb_static = { + "static", + + static_preinit, + NULL, + NULL, + + static_lookup, + + NULL, + NULL, + NULL +}; |