passdb.c revision 0af3274706d337b2930bd34f0377f2cc2dbcd18a
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
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_passwd;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_bsdauth;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_shadow;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_passwd_file;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_pam;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_checkpassword;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_vpopmail;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_ldap;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainenextern struct passdb_module passdb_sql;
ba3a54872528db0eae3f36e45592219965b9faf8Timo Sirainen
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainenstruct passdb_module *passdbs[] = {
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,
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
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen enum passdb_credentials credentials,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen const char *password, const char *scheme,
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen lookup_credentials_callback_t *callback,
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen struct auth_request *auth_request)
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen{
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen const char *wanted_scheme;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen if (result != PASSDB_RESULT_OK) {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen callback(result, NULL, auth_request);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen return;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen }
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen i_assert(password != NULL);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen if (credentials == PASSDB_CREDENTIALS_CRYPT) {
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen /* anything goes */
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen password = t_strdup_printf("{%s}%s", scheme, password);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen callback(result, password, auth_request);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen return;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen wanted_scheme = passdb_credentials_to_str(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);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen callback(PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen NULL, auth_request);
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen return;
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
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen callback(PASSDB_RESULT_OK, password, auth_request);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen}
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenvoid passdb_preinit(struct auth *auth, const char *driver, const char *args)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen struct passdb_module **p;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen struct auth_passdb *auth_passdb, **dest;
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;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->args = p_strdup(auth->pool, args);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen for (dest = &auth->passdbs; *dest != NULL; dest = &(*dest)->next)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->num++;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen *dest = auth_passdb;
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen for (p = passdbs; *p != NULL; p++) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (strcmp((*p)->name, driver) == 0) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->passdb = *p;
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen break;
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen }
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen }
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
98a711be68ba64e1cabf8cacc150af44421e2ac9Timo Sirainen#ifdef HAVE_MODULES
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (auth_passdb->passdb == NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->module = auth_module_open(driver);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (auth_passdb->module != NULL) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->passdb =
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_module_sym(auth_passdb->module,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen t_strconcat("passdb_", driver, NULL));
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen }
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (auth_passdb->passdb == NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_fatal("Unknown passdb driver '%s'", driver);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (auth_passdb->passdb->preinit != NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_passdb->passdb->preinit(auth_passdb->args);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenvoid passdb_init(struct auth_passdb *passdb)
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (passdb->passdb->init != NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen passdb->passdb->init(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{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (passdb->passdb->deinit != NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen passdb->passdb->deinit();
98a711be68ba64e1cabf8cacc150af44421e2ac9Timo Sirainen#ifdef HAVE_MODULES
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (passdb->module != NULL)
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_module_close(passdb->module);
70cb37c37e4dce8f57cd3f882f7444e76b918befTimo Sirainen#endif
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}