passdb.c revision ba3a54872528db0eae3f36e45592219965b9faf8
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "common.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "auth-module.h"
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#include "password-scheme.h"
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "passdb.h"
ccd44abfe14f51cc1f6d8c0ec1aa6dc31242e2d3Timo Sirainen#include "passdb-cache.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen#include <stdlib.h>
94e1adead9faddec88a623485b9999a87b1684faTimo Sirainen
94e1adead9faddec88a623485b9999a87b1684faTimo Sirainenextern struct passdb_module passdb_passwd;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenextern struct passdb_module passdb_bsdauth;
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainenextern struct passdb_module passdb_shadow;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenextern struct passdb_module passdb_passwd_file;
b87436ebb957a9eb182be72ba00e2c8eae59a2e4Timo Sirainenextern struct passdb_module passdb_pam;
7ca2a9f1cca63cbc2ebffc185c7e5a2b32bc2780Timo Sirainenextern struct passdb_module passdb_checkpassword;
7ca2a9f1cca63cbc2ebffc185c7e5a2b32bc2780Timo Sirainenextern struct passdb_module passdb_vpopmail;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenextern struct passdb_module passdb_ldap;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenextern struct passdb_module passdb_sql;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenstruct passdb_module *passdbs[] = {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen#ifdef PASSDB_PASSWD
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen &passdb_passwd,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen#endif
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#ifdef PASSDB_BSDAUTH
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen &passdb_bsdauth,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#endif
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#ifdef PASSDB_PASSWD_FILE
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen &passdb_passwd_file,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#endif
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen#ifdef PASSDB_PAM
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen &passdb_pam,
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen#endif
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen#ifdef PASSDB_CHECKPASSWORD
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen &passdb_checkpassword,
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen#endif
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen#ifdef PASSDB_SHADOW
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen &passdb_shadow,
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen#endif
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen#ifdef PASSDB_VPOPMAIL
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen &passdb_vpopmail,
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen#endif
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen#ifdef PASSDB_LDAP
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen &passdb_ldap,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#endif
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#ifdef PASSDB_SQL
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen &passdb_sql,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#endif
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen NULL
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen};
fc84f8af4794f4bb6caf6e5ec3fb1f8cebd0462aTimo Sirainen
b87436ebb957a9eb182be72ba00e2c8eae59a2e4Timo Sirainenstatic const char *
b87436ebb957a9eb182be72ba00e2c8eae59a2e4Timo Sirainenpassdb_credentials_to_str(enum passdb_credentials credentials)
b87436ebb957a9eb182be72ba00e2c8eae59a2e4Timo Sirainen{
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen switch (credentials) {
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen case _PASSDB_CREDENTIALS_INTERNAL:
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen break;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen case PASSDB_CREDENTIALS_PLAINTEXT:
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return "PLAIN";
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen case PASSDB_CREDENTIALS_CRYPT:
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen return "CRYPT";
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen case PASSDB_CREDENTIALS_CRAM_MD5:
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen return "HMAC-MD5";
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen case PASSDB_CREDENTIALS_DIGEST_MD5:
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return "DIGEST-MD5";
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen case PASSDB_CREDENTIALS_LANMAN:
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return "LANMAN";
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen case PASSDB_CREDENTIALS_NTLM:
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen return "NTLM";
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen case PASSDB_CREDENTIALS_RPA:
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return "RPA";
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return "??";
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen}
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen enum passdb_credentials credentials,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen const char *password, const char *scheme,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen lookup_credentials_callback_t *callback,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct auth_request *auth_request)
fd1f0e9ef52b3e157cfd1a01c464c2ac7458ab17Timo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen const char *wanted_scheme;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (result != PASSDB_RESULT_OK) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen callback(result, NULL, auth_request);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen }
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen i_assert(password != NULL);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (credentials == PASSDB_CREDENTIALS_CRYPT) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen /* anything goes */
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen password = t_strdup_printf("{%s}%s", scheme, password);
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen callback(result, password, auth_request);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen wanted_scheme = passdb_credentials_to_str(credentials);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (strcasecmp(scheme, wanted_scheme) != 0) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (strcasecmp(scheme, "PLAIN") != 0 &&
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen strcasecmp(scheme, "CLEARTEXT") != 0) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (verbose) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_info("password(%s): Requested %s "
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen "scheme, but we have only %s",
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen auth_request->user,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen wanted_scheme, scheme);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen callback(PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen NULL, auth_request);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen /* we can generate anything out of plaintext passwords */
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen password = password_generate(password, auth_request->user,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen wanted_scheme);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_assert(password != NULL);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen callback(PASSDB_RESULT_OK, password, auth_request);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenvoid passdb_preinit(struct auth *auth, const char *data)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct passdb_module **p;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen const char *name, *args;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen args = strchr(data, ' ');
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen name = t_strcut(data, ' ');
e3077468777f5d324224365e34d7bbc449168e52Timo Sirainen
e3077468777f5d324224365e34d7bbc449168e52Timo Sirainen if (args == NULL) args = "";
e3077468777f5d324224365e34d7bbc449168e52Timo Sirainen while (*args == ' ' || *args == '\t')
e3077468777f5d324224365e34d7bbc449168e52Timo Sirainen args++;
e3077468777f5d324224365e34d7bbc449168e52Timo Sirainen
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen auth->passdb_args = i_strdup(args);
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen
26a8b7deb3a5b6f26f9c4d71538e1248f680e4beTimo Sirainen for (p = passdbs; *p != NULL; p++) {
26a8b7deb3a5b6f26f9c4d71538e1248f680e4beTimo Sirainen if (strcmp((*p)->name, name) == 0) {
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen auth->passdb = *p;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen break;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen#ifdef HAVE_MODULES
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen auth->passdb_module = auth->passdb != NULL ? NULL :
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen auth_module_open(name);
608aa112aa7d94a1720c909747dcd0b61c079453Timo Sirainen if (auth->passdb_module != NULL) {
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen auth->passdb = auth_module_sym(auth->passdb_module,
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen t_strconcat("passdb_", name,
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen NULL));
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen }
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen#endif
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen if (auth->passdb == NULL)
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen i_fatal("Unknown passdb type '%s'", name);
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen if (auth->passdb->preinit != NULL)
65e14cef911d5d3fac8993c8a76911a587f05cd7Timo Sirainen auth->passdb->preinit(auth->passdb_args);
608aa112aa7d94a1720c909747dcd0b61c079453Timo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainenvoid passdb_init(struct auth *auth)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen{
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen passdb_cache_init();
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen if (auth->passdb->init != NULL)
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen auth->passdb->init(auth->passdb_args);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainenvoid passdb_deinit(struct auth *auth)
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen if (auth->passdb->deinit != NULL)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen auth->passdb->deinit();
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen#ifdef HAVE_MODULES
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen if (auth->passdb_module != NULL)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen auth_module_close(auth->passdb_module);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#endif
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen passdb_cache_deinit();
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen i_free(auth->passdb_args);
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen}
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen