passdb.c revision 446e518e4fe86ff40e33543445f4e99edf840a21
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#include "common.h"
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen#include "array.h"
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#include "password-scheme.h"
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen#include "auth-worker-server.h"
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#include "passdb.h"
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen#include <stdlib.h>
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenstatic ARRAY_DEFINE(passdb_interfaces, struct passdb_module_interface *);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenstatic struct passdb_module_interface *passdb_interface_find(const char *name)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct passdb_module_interface *const *ifaces;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen unsigned int i, count;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen ifaces = array_get(&passdb_interfaces, &count);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen for (i = 0; i < count; i++) {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (strcmp(ifaces[i]->name, name) == 0)
48f78a48f2e1cf299026544444666471ae16ad97Timo Sirainen return ifaces[i];
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen }
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen return NULL;
f83fd83f9c6708d198748e714aa947cad9362c02Timo Sirainen}
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainenvoid passdb_register_module(struct passdb_module_interface *iface)
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen{
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen if (passdb_interface_find(iface->name) != NULL) {
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen i_panic("passdb_register_module(%s): Already registered",
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen iface->name);
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen }
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen array_append(&passdb_interfaces, &iface, 1);
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen}
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainenvoid passdb_unregister_module(struct passdb_module_interface *iface)
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen{
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen struct passdb_module_interface *const *ifaces;
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen unsigned int i, count;
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen ifaces = array_get(&passdb_interfaces, &count);
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen for (i = 0; i < count; i++) {
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen if (ifaces[i] == iface) {
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen array_delete(&passdb_interfaces, i, 1);
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen return;
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen }
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen }
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen i_panic("passdb_unregister_module(%s): Not registered", iface->name);
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen}
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainenbool passdb_get_credentials(struct auth_request *auth_request,
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen const char *input, const char *input_scheme,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen const unsigned char **credentials_r, size_t *size_r)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen const char *wanted_scheme = auth_request->credentials_scheme;
48f78a48f2e1cf299026544444666471ae16ad97Timo Sirainen const char *plaintext, *username;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen int ret;
48f78a48f2e1cf299026544444666471ae16ad97Timo Sirainen
48f78a48f2e1cf299026544444666471ae16ad97Timo Sirainen if (auth_request->prefer_plain_credentials &&
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen password_scheme_is_alias(input_scheme, "PLAIN")) {
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen /* we've a plaintext scheme and we prefer to get it instead
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen of converting it to the fallback scheme */
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen wanted_scheme = "";
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen }
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen ret = password_decode(input, input_scheme, credentials_r, size_r);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen if (ret <= 0) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (ret < 0) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_error(auth_request, "password",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "Invalid password format for scheme %s",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen input_scheme);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen } else {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_error(auth_request, "password",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "Unknown scheme %s", input_scheme);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen return FALSE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (*wanted_scheme == '\0') {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen /* anything goes. change the credentials_scheme to what we
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen actually got, so blocking passdbs work. */
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request->credentials_scheme =
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen p_strdup(auth_request->pool, input_scheme);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen return TRUE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen const char *error = t_strdup_printf(
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "Requested %s scheme, but we have only %s",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen wanted_scheme, input_scheme);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (auth_request->auth->verbose_debug_passwords) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen error = t_strdup_printf("%s (input: %s)",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen error, input);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_info(auth_request, "password",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "%s", error);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen return FALSE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen /* we can generate anything out of plaintext passwords */
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen plaintext = t_strndup(*credentials_r, *size_r);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen username = auth_request->original_username;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (!auth_request->domain_is_realm &&
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen strchr(username, '@') != NULL) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen /* domain must not be used as realm. add the @realm. */
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen username = t_strconcat(username, "@",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request->realm, NULL);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (auth_request->auth->verbose_debug_passwords) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_info(auth_request, "password",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "Generating %s from user '%s', password '%s'",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen wanted_scheme, username, plaintext);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (!password_generate(plaintext, username,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen wanted_scheme, credentials_r, size_r)) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_error(auth_request, "password",
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen "Requested unknown scheme %s", wanted_scheme);
14cac26dcb71108abfdc95ea524e74be1f95774cPhil Carmody return FALSE;
14cac26dcb71108abfdc95ea524e74be1f95774cPhil Carmody }
14cac26dcb71108abfdc95ea524e74be1f95774cPhil Carmody }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen return TRUE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen}
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen const char *password, const char *scheme,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen lookup_credentials_callback_t *callback,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen struct auth_request *auth_request)
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen{
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen const unsigned char *credentials;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen size_t size = 0;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (result != PASSDB_RESULT_OK) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen callback(result, NULL, 0, auth_request);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen return;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen if (password == NULL) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen auth_request_log_info(auth_request, "password",
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen "Requested %s scheme, but we have a NULL password",
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen auth_request->credentials_scheme);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen } else if (!passdb_get_credentials(auth_request, password, scheme,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen &credentials, &size)) {
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen }
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen callback(result, credentials, size, auth_request);
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen}
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainenstruct auth_passdb *passdb_preinit(struct auth *auth, const char *driver,
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen const char *args, unsigned int id)
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen{
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen struct passdb_module_interface *iface;
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen struct auth_passdb *auth_passdb;
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen if (args == NULL) args = "";
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen
a8b37b688ceaa3ed3d40b3ccbdba5bb75cfb64b0Timo Sirainen auth_passdb = p_new(auth->pool, struct auth_passdb, 1);
a8b37b688ceaa3ed3d40b3ccbdba5bb75cfb64b0Timo Sirainen auth_passdb->auth = auth;
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen auth_passdb->args = p_strdup(auth->pool, args);
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen auth_passdb->id = id;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen iface = passdb_interface_find(driver);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen if (iface == NULL)
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen i_fatal("Unknown passdb driver '%s'", driver);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen if (iface->verify_plain == NULL) {
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainen i_fatal("Support not compiled in for passdb driver '%s'",
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen driver);
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen }
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen if (iface->preinit == NULL && iface->init == NULL &&
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen *auth_passdb->args != '\0') {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen i_fatal("passdb %s: No args are supported: %s",
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen driver, auth_passdb->args);
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen }
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen if (iface->preinit == NULL) {
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen auth_passdb->passdb =
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen p_new(auth->pool, struct passdb_module, 1);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen } else {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen auth_passdb->passdb =
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen iface->preinit(auth_passdb, auth_passdb->args);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen }
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen auth_passdb->passdb->iface = *iface;
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen return auth_passdb;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen}
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenvoid passdb_init(struct auth_passdb *passdb)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (passdb->passdb->iface.init != NULL)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb->passdb->iface.init(passdb->passdb, passdb->args);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen i_assert(passdb->passdb->default_pass_scheme != NULL ||
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen passdb->passdb->cache_key == NULL);
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen if (passdb->passdb->blocking && !worker) {
f83fd83f9c6708d198748e714aa947cad9362c02Timo Sirainen /* blocking passdb - we need an auth server */
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen auth_worker_server_init();
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen }
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen}
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainenvoid passdb_deinit(struct auth_passdb *passdb)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen if (passdb->passdb->iface.deinit != NULL)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb->passdb->iface.deinit(passdb->passdb);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen}
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen
0dc7891233a973829f00371b27810f849b987c66Timo Sirainenextern struct passdb_module_interface passdb_passwd;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenextern struct passdb_module_interface passdb_bsdauth;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenextern struct passdb_module_interface passdb_shadow;
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenextern struct passdb_module_interface passdb_passwd_file;
4eb418849d5c6bf77b2721e4e6aef2e97deaa197Timo Sirainenextern struct passdb_module_interface passdb_pam;
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenextern struct passdb_module_interface passdb_checkpassword;
0dc7891233a973829f00371b27810f849b987c66Timo Sirainenextern struct passdb_module_interface passdb_vpopmail;
0dc7891233a973829f00371b27810f849b987c66Timo Sirainenextern struct passdb_module_interface passdb_ldap;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainenextern struct passdb_module_interface passdb_sql;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainenextern struct passdb_module_interface passdb_sia;
b5ff746939712c6a9bef71405fa786d5471cf177Timo Sirainen
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenvoid passdbs_init(void)
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen{
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen i_array_init(&passdb_interfaces, 16);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen passdb_register_module(&passdb_passwd);
36af6ff6b0249d0fb98b2c16c2ab8755e9394214Timo Sirainen passdb_register_module(&passdb_bsdauth);
3d2fd3816b79caf8048582f1e951019187ee9d9dTimo Sirainen passdb_register_module(&passdb_passwd_file);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb_register_module(&passdb_pam);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb_register_module(&passdb_checkpassword);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb_register_module(&passdb_shadow);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb_register_module(&passdb_vpopmail);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen passdb_register_module(&passdb_ldap);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen passdb_register_module(&passdb_sql);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen passdb_register_module(&passdb_sia);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen}
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenvoid passdbs_deinit(void)
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen{
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen array_free(&passdb_interfaces);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen}
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen