passdb.c revision f968e62caa52a8924bd05ebf76ff515b5c18e17b
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2002-2003 Timo Sirainen */
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include "common.h"
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include "auth-module.h"
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include "password-scheme.h"
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include "auth-worker-server.h"
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include "passdb.h"
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#include <stdlib.h>
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_passwd;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_bsdauth;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_shadow;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_passwd_file;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_pam;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_checkpassword;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_vpopmail;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_ldap;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_sql;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiextern struct passdb_module_interface passdb_sia;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomistruct passdb_module_interface *passdb_interfaces[] = {
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_PASSWD
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_passwd,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_BSDAUTH
bcab95c672604588f1645e4a52e43f52ee567593Timo Sirainen &passdb_bsdauth,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_PASSWD_FILE
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_passwd_file,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_PAM
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_pam,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_CHECKPASSWORD
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_checkpassword,
bcab95c672604588f1645e4a52e43f52ee567593Timo Sirainen#endif
bcab95c672604588f1645e4a52e43f52ee567593Timo Sirainen#ifdef PASSDB_SHADOW
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_shadow,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_VPOPMAIL
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_vpopmail,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_LDAP
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_ldap,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_SQL
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_sql,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#ifdef PASSDB_SIA
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi &passdb_sia,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi#endif
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi NULL
bcab95c672604588f1645e4a52e43f52ee567593Timo Sirainen};
bcab95c672604588f1645e4a52e43f52ee567593Timo Sirainen
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomiconst char *
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomipassdb_credentials_to_str(enum passdb_credentials credentials,
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi const char *wanted_scheme)
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi{
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi switch (credentials) {
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case _PASSDB_CREDENTIALS_INTERNAL:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi break;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_PLAINTEXT:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi if (strcasecmp(wanted_scheme, "CLEARTEXT") == 0)
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return wanted_scheme;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "PLAIN";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_CRYPT:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "CRYPT";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_CRAM_MD5:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi if (strcasecmp(wanted_scheme, "HMAC-MD5") == 0)
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return wanted_scheme;
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "CRAM-MD5";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_DIGEST_MD5:
2935863763d8655c2c23e52591f2cbfff54811a6Aki Tuomi return "DIGEST-MD5";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_LANMAN:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "LANMAN";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_NTLM:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "NTLM";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_OTP:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "OTP";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_SKEY:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "SKEY";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi case PASSDB_CREDENTIALS_RPA:
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "RPA";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi }
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi return "??";
662bb64be818407c6719a69780411f7ca8d6c96fAki Tuomi}
const char *
passdb_get_credentials(struct auth_request *auth_request,
const char *password, const char *scheme)
{
const char *wanted_scheme;
if (auth_request->credentials == PASSDB_CREDENTIALS_CRYPT) {
/* anything goes */
return t_strdup_printf("{%s}%s", scheme, password);
}
wanted_scheme = passdb_credentials_to_str(auth_request->credentials,
scheme);
if (strcasecmp(scheme, wanted_scheme) != 0) {
if (strcasecmp(scheme, "PLAIN") != 0 &&
strcasecmp(scheme, "CLEARTEXT") != 0) {
auth_request_log_info(auth_request, "password",
"Requested %s scheme, but we have only %s",
wanted_scheme, scheme);
return NULL;
}
/* we can generate anything out of plaintext passwords */
password = password_generate(password, auth_request->user,
wanted_scheme);
i_assert(password != NULL);
}
return password;
}
void passdb_handle_credentials(enum passdb_result result,
const char *password, const char *scheme,
lookup_credentials_callback_t *callback,
struct auth_request *auth_request)
{
if (result != PASSDB_RESULT_OK) {
callback(result, NULL, auth_request);
return;
}
password = password == NULL ? NULL :
passdb_get_credentials(auth_request, password, scheme);
if (password == NULL)
result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
callback(result, password, auth_request);
}
struct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
const char *args, unsigned int id)
{
struct passdb_module_interface **p, *iface;
struct auth_passdb *auth_passdb;
if (args == NULL) args = "";
auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
auth_passdb->auth = auth;
auth_passdb->args = p_strdup(auth->pool, args);
auth_passdb->id = id;
iface = NULL;
for (p = passdb_interfaces; *p != NULL; p++) {
if (strcmp((*p)->name, driver) == 0) {
iface = *p;
break;
}
}
#ifdef HAVE_MODULES
if (iface == NULL)
auth_passdb->module = auth_module_open(driver);
if (auth_passdb->module != NULL) {
iface = auth_module_sym(auth_passdb->module,
t_strconcat("passdb_", driver, NULL));
}
#endif
if (iface == NULL) {
i_fatal("Unknown passdb driver '%s' "
"(typo, or Dovecot was built without support for it? "
"Check with dovecot --build-options)",
driver);
}
if (iface->preinit == NULL) {
auth_passdb->passdb =
p_new(auth->pool, struct passdb_module, 1);
} else {
auth_passdb->passdb =
iface->preinit(auth_passdb, auth_passdb->args);
}
auth_passdb->passdb->iface = *iface;
return auth_passdb;
}
void passdb_init(struct auth_passdb *passdb)
{
if (passdb->passdb->iface.init != NULL)
passdb->passdb->iface.init(passdb->passdb, passdb->args);
i_assert(passdb->passdb->default_pass_scheme != NULL ||
passdb->passdb->cache_key == NULL);
if (passdb->passdb->blocking && !worker) {
/* blocking passdb - we need an auth server */
auth_worker_server_init();
}
}
void passdb_deinit(struct auth_passdb *passdb)
{
if (passdb->passdb->iface.deinit != NULL)
passdb->passdb->iface.deinit(passdb->passdb);
#ifdef HAVE_MODULES
if (passdb->module != NULL)
auth_module_close(&passdb->module);
#endif
}