passdb.c revision 473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5
b9f30617c2c96d54acbc4f85ed17b939c4f28916Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "common.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "mech.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "auth-module.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "passdb.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stdlib.h>
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen#ifdef AUTH_MODULES
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic struct auth_module *passdb_module = NULL;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainenstruct passdb_module *passdb;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic const char *
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenpassdb_credentials_to_str(enum passdb_credentials credentials)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen switch (credentials) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen case _PASSDB_CREDENTIALS_INTERNAL:
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen break;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen case PASSDB_CREDENTIALS_PLAINTEXT:
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return "PLAIN";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen case PASSDB_CREDENTIALS_CRYPT:
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return "CRYPT";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen case PASSDB_CREDENTIALS_DIGEST_MD5:
e40840f74672872db99d29b4eb5511869e238004Timo Sirainen return "DIGEST-MD5";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return "??";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenvoid passdb_handle_credentials(enum passdb_credentials credentials,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *user, const char *password,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *scheme,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen lookup_credentials_callback_t *callback,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct auth_request *auth_request)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *wanted_scheme;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (credentials == PASSDB_CREDENTIALS_CRYPT) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* anything goes */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (password != NULL)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen password = t_strdup_printf("{%s}%s", scheme, password);
e40840f74672872db99d29b4eb5511869e238004Timo Sirainen callback(password, auth_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (password != NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen wanted_scheme = passdb_credentials_to_str(credentials);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (strcasecmp(scheme, wanted_scheme) != 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (verbose) {
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen i_info("password(%s): Requested %s scheme, "
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen "but we have only %s", user,
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen wanted_scheme, scheme);
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen }
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen password = NULL;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen callback(password, auth_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenvoid passdb_init(void)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *name, *args;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = NULL;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen name = getenv("PASSDB");
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (name == NULL)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen i_fatal("PASSDB environment is unset");
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen args = strchr(name, ' ');
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen name = t_strcut(name, ' ');
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_PASSWD
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "passwd") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_passwd;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_PASSWD_FILE
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "passwd-file") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_passwd_file;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_PAM
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "pam") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_pam;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_SHADOW
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "shadow") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_shadow;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_VPOPMAIL
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "vpopmail") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_vpopmail;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef PASSDB_LDAP
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (strcasecmp(name, "ldap") == 0)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = &passdb_ldap;
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#ifdef AUTH_MODULES
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb_module = auth_module_open(name);
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (passdb_module != NULL) {
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb = auth_module_sym(passdb_module,
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen t_strconcat("passdb_", name, NULL));
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen }
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen#endif
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (passdb == NULL)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen i_fatal("Unknown passdb type '%s'", name);
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen /* initialize */
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if (passdb->init != NULL)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb->init(args != NULL ? args+1 : "");
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if ((auth_mechanisms & AUTH_MECH_PLAIN) &&
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb->verify_plain == NULL)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen i_fatal("Passdb %s doesn't support PLAIN method", name);
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen if ((auth_mechanisms & AUTH_MECH_DIGEST_MD5) &&
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen passdb->lookup_credentials == NULL)
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen i_fatal("Passdb %s doesn't support DIGEST-MD5 method", name);
a8284e999d091cd29210fa75ecdc8076376a7345Timo Sirainen}
void passdb_deinit(void)
{
if (passdb != NULL && passdb->deinit != NULL)
passdb->deinit();
#ifdef AUTH_MODULES
if (passdb_module != NULL)
auth_module_close(passdb_module);
#endif
}