passdb.c revision 747e77e3ab073a8e9e69c7a3e71b4593c5655d03
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "common.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "auth-module.h"
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#include "password-scheme.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "auth-worker-server.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "passdb.h"
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <stdlib.h>
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenextern struct passdb_module_interface passdb_passwd;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct passdb_module_interface passdb_bsdauth;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct passdb_module_interface passdb_shadow;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct passdb_module_interface passdb_passwd_file;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenextern struct passdb_module_interface passdb_pam;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenextern struct passdb_module_interface passdb_checkpassword;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenextern struct passdb_module_interface passdb_vpopmail;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenextern struct passdb_module_interface passdb_ldap;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenextern struct passdb_module_interface passdb_sql;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct passdb_module_interface *passdb_interfaces[] = {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_PASSWD
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_passwd,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_BSDAUTH
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_bsdauth,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_PASSWD_FILE
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_passwd_file,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_PAM
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_pam,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#ifdef PASSDB_CHECKPASSWORD
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen &passdb_checkpassword,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#endif
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen#ifdef PASSDB_SHADOW
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_shadow,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#ifdef PASSDB_VPOPMAIL
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen &passdb_vpopmail,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_LDAP
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_ldap,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#ifdef PASSDB_SQL
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen &passdb_sql,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#endif
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen NULL
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenconst char *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenpassdb_credentials_to_str(enum passdb_credentials credentials)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen switch (credentials) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case _PASSDB_CREDENTIALS_INTERNAL:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case PASSDB_CREDENTIALS_PLAINTEXT:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "PLAIN";
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case PASSDB_CREDENTIALS_CRYPT:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "CRYPT";
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case PASSDB_CREDENTIALS_CRAM_MD5:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "HMAC-MD5";
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen case PASSDB_CREDENTIALS_DIGEST_MD5:
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen return "DIGEST-MD5";
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen case PASSDB_CREDENTIALS_LANMAN:
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen return "LANMAN";
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case PASSDB_CREDENTIALS_NTLM:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "NTLM";
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case PASSDB_CREDENTIALS_RPA:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "RPA";
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return "??";
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen}
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenconst char *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenpassdb_get_credentials(struct auth_request *auth_request,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *password, const char *scheme)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *wanted_scheme;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (auth_request->credentials == PASSDB_CREDENTIALS_CRYPT) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* anything goes */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return t_strdup_printf("{%s}%s", scheme, password);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen wanted_scheme = passdb_credentials_to_str(auth_request->credentials);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (strcasecmp(scheme, wanted_scheme) != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (strcasecmp(scheme, "PLAIN") != 0 &&
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen strcasecmp(scheme, "CLEARTEXT") != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen auth_request_log_info(auth_request, "password",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "Requested %s scheme, but we have only %s",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen wanted_scheme, scheme);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return NULL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* we can generate anything out of plaintext passwords */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen password = password_generate(password, auth_request->user,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen wanted_scheme);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_assert(password != NULL);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen }
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen return password;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen const char *password, const char *scheme,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen lookup_credentials_callback_t *callback,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen struct auth_request *auth_request)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (result != PASSDB_RESULT_OK) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen callback(result, NULL, auth_request);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen return;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen }
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen i_assert(password != NULL);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen password = passdb_get_credentials(auth_request, password, scheme);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (password == NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen callback(result, password, auth_request);
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainenstruct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const char *args)
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct passdb_module_interface **p, *iface;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct auth_passdb *auth_passdb, **dest;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (args == NULL) args = "";
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->auth = auth;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->args = p_strdup(auth->pool, args);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (dest = &auth->passdbs; *dest != NULL; dest = &(*dest)->next)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->num++;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen *dest = auth_passdb;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen iface = NULL;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (p = passdb_interfaces; *p != NULL; p++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (strcmp((*p)->name, driver) == 0) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen iface = *p;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen break;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#ifdef HAVE_MODULES
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (iface == NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->module = auth_module_open(driver);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (auth_passdb->module != NULL) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen iface = auth_module_sym(auth_passdb->module,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen t_strconcat("passdb_", driver, NULL));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#endif
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen if (iface == NULL) {
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen i_fatal("Unknown passdb driver '%s' "
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen "(typo, or Dovecot was built without support for it? "
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen "Check with dovecot --build-options)",
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen driver);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (iface->preinit == NULL) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->passdb =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen p_new(auth->pool, struct passdb_module, 1);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen } else {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->passdb =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen iface->preinit(auth_passdb, auth_passdb->args);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_passdb->passdb->iface = iface;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen return auth_passdb;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenvoid passdb_init(struct auth_passdb *passdb)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (passdb->passdb->iface->init != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen passdb->passdb->iface->init(passdb->passdb, passdb->args);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_assert(passdb->passdb->default_pass_scheme != NULL ||
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen passdb->passdb->cache_key == NULL);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (passdb->passdb->blocking && !worker) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* blocking passdb - we need an auth server */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_worker_server_init();
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen }
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenvoid passdb_deinit(struct auth_passdb *passdb)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen{
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (passdb->passdb->iface->deinit != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen passdb->passdb->iface->deinit(passdb->passdb);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#ifdef HAVE_MODULES
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (passdb->module != NULL)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen auth_module_close(passdb->module);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen#endif
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen