passdb.c revision 19b30b0c64b0eaaaec8903036356838918e86a7a
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "common.h"
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen#include "auth-module.h"
ff487c974815bdaa2d05a3b834f4c2c841f4cc34Timo Sirainen#include "password-scheme.h"
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen#include "auth-worker-server.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "passdb.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include <stdlib.h>
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_passwd;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_bsdauth;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_shadow;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_passwd_file;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_pam;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_checkpassword;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_vpopmail;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_ldap;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenextern struct passdb_module_interface passdb_sql;
19b30b0c64b0eaaaec8903036356838918e86a7aTimo Sirainenextern struct passdb_module_interface passdb_sia;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainenstruct passdb_module_interface *passdb_interfaces[] = {
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_PASSWD
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_passwd,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_BSDAUTH
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_bsdauth,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_PASSWD_FILE
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_passwd_file,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_PAM
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_pam,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_CHECKPASSWORD
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_checkpassword,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_SHADOW
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_shadow,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_VPOPMAIL
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_vpopmail,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_LDAP
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_ldap,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#ifdef PASSDB_SQL
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen &passdb_sql,
19b30b0c64b0eaaaec8903036356838918e86a7aTimo Sirainen#endif
19b30b0c64b0eaaaec8903036356838918e86a7aTimo Sirainen#ifdef PASSDB_SIA
19b30b0c64b0eaaaec8903036356838918e86a7aTimo Sirainen &passdb_sia,
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen#endif
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen NULL
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen};
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
0af3274706d337b2930bd34f0377f2cc2dbcd18aTimo Sirainenconst char *
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainenpassdb_credentials_to_str(enum passdb_credentials credentials)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen switch (credentials) {
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen case _PASSDB_CREDENTIALS_INTERNAL:
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen break;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen case PASSDB_CREDENTIALS_PLAINTEXT:
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen return "PLAIN";
e82af44fe25ca9b88210f313548dc08538e4a677Timo Sirainen case PASSDB_CREDENTIALS_CRYPT:
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen return "CRYPT";
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen case PASSDB_CREDENTIALS_CRAM_MD5:
6c07b8ddc5e894feead4d422075b079451721241Timo Sirainen return "HMAC-MD5";
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen case PASSDB_CREDENTIALS_DIGEST_MD5:
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen return "DIGEST-MD5";
d43c646d4b84635aa795946555be04a553d5413aTimo Sirainen case PASSDB_CREDENTIALS_LANMAN:
d43c646d4b84635aa795946555be04a553d5413aTimo Sirainen return "LANMAN";
c7480644202e5451fbed448508ea29a25cffc99cTimo Sirainen case PASSDB_CREDENTIALS_NTLM:
c7480644202e5451fbed448508ea29a25cffc99cTimo Sirainen return "NTLM";
a4ac325c2802693c6b761e5a8fda961e5d7490eaTimo Sirainen case PASSDB_CREDENTIALS_RPA:
a4ac325c2802693c6b761e5a8fda961e5d7490eaTimo Sirainen return "RPA";
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen }
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen return "??";
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainenconst char *
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainenpassdb_get_credentials(struct auth_request *auth_request,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen const char *password, const char *scheme)
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen{
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen const char *wanted_scheme;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen if (auth_request->credentials == PASSDB_CREDENTIALS_CRYPT) {
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen /* anything goes */
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen return t_strdup_printf("{%s}%s", scheme, password);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen wanted_scheme = passdb_credentials_to_str(auth_request->credentials);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen if (strcasecmp(scheme, wanted_scheme) != 0) {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen if (strcasecmp(scheme, "PLAIN") != 0 &&
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen strcasecmp(scheme, "CLEARTEXT") != 0) {
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen auth_request_log_info(auth_request, "password",
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen "Requested %s scheme, but we have only %s",
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen wanted_scheme, scheme);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen return NULL;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen /* we can generate anything out of plaintext passwords */
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen password = password_generate(password, auth_request->user,
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen wanted_scheme);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen i_assert(password != NULL);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen return password;
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen}
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen const char *password, const char *scheme,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen lookup_credentials_callback_t *callback,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen struct auth_request *auth_request)
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen{
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen if (result != PASSDB_RESULT_OK) {
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen callback(result, NULL, auth_request);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen return;
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen }
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen i_assert(password != NULL);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen password = passdb_get_credentials(auth_request, password, scheme);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen if (password == NULL)
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen callback(result, password, auth_request);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen}
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
157bce86d0a01477bb8ebd0d380e6b2297f326f7Timo Sirainenstruct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen const char *args, unsigned int id)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen struct passdb_module_interface **p, *iface;
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen struct auth_passdb *auth_passdb;
965ed6ea3fc8f7637bd0d159d2fdb283a191ce34Timo Sirainen
91e4199476cb2add8143c18583fa57e1decfea88Timo Sirainen if (args == NULL) args = "";
0727e38ac12efb8963a339daf56255e2be1f29fcTimo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->auth = auth;
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen auth_passdb->args = p_strdup(auth->pool, args);
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen auth_passdb->id = id;
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen iface = NULL;
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen for (p = passdb_interfaces; *p != NULL; p++) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (strcmp((*p)->name, driver) == 0) {
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen iface = *p;
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen break;
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen }
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen }
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
98a711be68ba64e1cabf8cacc150af44421e2ac9Timo Sirainen#ifdef HAVE_MODULES
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen if (iface == NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->module = auth_module_open(driver);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (auth_passdb->module != NULL) {
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen iface = auth_module_sym(auth_passdb->module,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen t_strconcat("passdb_", driver, NULL));
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen }
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen if (iface == NULL) {
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen i_fatal("Unknown passdb driver '%s' "
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen "(typo, or Dovecot was built without support for it? "
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen "Check with dovecot --build-options)",
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen driver);
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen }
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen if (iface->preinit == NULL) {
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen auth_passdb->passdb =
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen p_new(auth->pool, struct passdb_module, 1);
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen } else {
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen auth_passdb->passdb =
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen iface->preinit(auth_passdb, auth_passdb->args);
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen }
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen auth_passdb->passdb->iface = *iface;
157bce86d0a01477bb8ebd0d380e6b2297f326f7Timo Sirainen return auth_passdb;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenvoid passdb_init(struct auth_passdb *passdb)
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen{
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen if (passdb->passdb->iface.init != NULL)
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen passdb->passdb->iface.init(passdb->passdb, passdb->args);
e4d34f2fbee451219599d71505594df704093ce3Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_assert(passdb->passdb->default_pass_scheme != NULL ||
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen passdb->passdb->cache_key == NULL);
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (passdb->passdb->blocking && !worker) {
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen /* blocking passdb - we need an auth server */
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen auth_worker_server_init();
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen }
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen}
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenvoid passdb_deinit(struct auth_passdb *passdb)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen if (passdb->passdb->iface.deinit != NULL)
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen passdb->passdb->iface.deinit(passdb->passdb);
98a711be68ba64e1cabf8cacc150af44421e2ac9Timo Sirainen#ifdef HAVE_MODULES
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (passdb->module != NULL)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen auth_module_close(&passdb->module);
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}