passdb.c revision 6d239203867965ad42f38747f0b84e7314d215d3
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* Copyright (C) 2002-2003 Timo Sirainen */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include "common.h"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include "mech.h"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include "auth-module.h"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include "password-scheme.h"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include "passdb.h"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#include <stdlib.h>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef AUTH_MODULES
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncstatic struct auth_module *passdb_module = NULL;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncstruct passdb_module *passdb;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncstatic const char *
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncpassdb_credentials_to_str(enum passdb_credentials credentials)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync{
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync switch (credentials) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync case _PASSDB_CREDENTIALS_INTERNAL:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync break;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync case PASSDB_CREDENTIALS_PLAINTEXT:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return "PLAIN";
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync case PASSDB_CREDENTIALS_CRYPT:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return "CRYPT";
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync case PASSDB_CREDENTIALS_DIGEST_MD5:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return "DIGEST-MD5";
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return "??";
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync}
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncvoid passdb_handle_credentials(enum passdb_credentials credentials,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync const char *user, const char *password,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync const char *scheme,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync lookup_credentials_callback_t *callback,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync struct auth_request *auth_request)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync{
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync const char *wanted_scheme;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (credentials == PASSDB_CREDENTIALS_CRYPT) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync /* anything goes */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (password != NULL)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync password = t_strdup_printf("{%s}%s", scheme, password);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync callback(password, auth_request);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (password != NULL) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync wanted_scheme = passdb_credentials_to_str(credentials);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(scheme, wanted_scheme) != 0) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(scheme, "PLAIN") == 0) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync /* we can generate anything out of plaintext
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passwords */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync password = password_generate(password, user,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync wanted_scheme);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } else {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (verbose) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync i_info("password(%s): Requested %s "
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "scheme, but we have only %s",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync user, wanted_scheme, scheme);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync password = NULL;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync }
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync callback(password, auth_request);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync}
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncvoid passdb_init(void)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync{
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync const char *name, *args;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = NULL;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync name = getenv("PASSDB");
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (name == NULL)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync i_fatal("PASSDB environment is unset");
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync args = strchr(name, ' ');
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync name = t_strcut(name, ' ');
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_PASSWD
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "passwd") == 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = &passdb_passwd;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_PASSWD_FILE
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "passwd-file") == 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = &passdb_passwd_file;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_PAM
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "pam") == 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = &passdb_pam;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_SHADOW
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "shadow") == 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = &passdb_shadow;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_VPOPMAIL
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "vpopmail") == 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync passdb = &passdb_vpopmail;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#ifdef PASSDB_LDAP
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (strcasecmp(name, "ldap") == 0)
passdb = &passdb_ldap;
#endif
#ifdef PASSDB_PGSQL
if (strcasecmp(name, "pgsql") == 0)
passdb = &passdb_pgsql;
#endif
#ifdef AUTH_MODULES
passdb_module = passdb != NULL ? NULL : auth_module_open(name);
if (passdb_module != NULL) {
passdb = auth_module_sym(passdb_module,
t_strconcat("passdb_", name, NULL));
}
#endif
if (passdb == NULL)
i_fatal("Unknown passdb type '%s'", name);
/* initialize */
if (passdb->init != NULL)
passdb->init(args != NULL ? args+1 : "");
if ((auth_mechanisms & AUTH_MECH_PLAIN) &&
passdb->verify_plain == NULL)
i_fatal("Passdb %s doesn't support PLAIN method", name);
if ((auth_mechanisms & AUTH_MECH_DIGEST_MD5) &&
passdb->lookup_credentials == NULL)
i_fatal("Passdb %s doesn't support DIGEST-MD5 method", name);
}
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
}