passdb.c revision be5c76fabc7439fd33bc799bc3ab3f570799977b
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "auth-common.h"
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen#include "array.h"
ff487c974815bdaa2d05a3b834f4c2c841f4cc34Timo Sirainen#include "password-scheme.h"
66d2db642fe24d555d113ba463e446b038d476efTimo Sirainen#include "auth-worker-server.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include "passdb.h"
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen#include <stdlib.h>
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic ARRAY_DEFINE(passdb_interfaces, struct passdb_module_interface *);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenstatic ARRAY_DEFINE(passdb_modules, struct passdb_module *);
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic struct passdb_module_interface *passdb_interface_find(const char *name)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct passdb_module_interface *const *ifaces;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen array_foreach(&passdb_interfaces, ifaces) {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen struct passdb_module_interface *iface = *ifaces;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen if (strcmp(iface->name, name) == 0)
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen return iface;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen return NULL;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdb_register_module(struct passdb_module_interface *iface)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen struct passdb_module_interface *old_iface;
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen old_iface = passdb_interface_find(iface->name);
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen if (old_iface != NULL && old_iface->verify_plain == NULL) {
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen /* replacing a "support not compiled in" passdb */
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen passdb_unregister_module(old_iface);
5c99eaa4e3e07ee065580d163240b4ce95b66befTimo Sirainen } else if (old_iface != NULL) {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_panic("passdb_register_module(%s): Already registered",
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen iface->name);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen array_append(&passdb_interfaces, &iface, 1);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdb_unregister_module(struct passdb_module_interface *iface)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct passdb_module_interface *const *ifaces;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen unsigned int idx;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen array_foreach(&passdb_interfaces, ifaces) {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen if (*ifaces == iface) {
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen idx = array_foreach_idx(&passdb_interfaces, ifaces);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen array_delete(&passdb_interfaces, idx, 1);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen return;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen }
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_panic("passdb_unregister_module(%s): Not registered", iface->name);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
1f1e81aab38d833d1c9cdc244c91fd762e0080d4Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainenbool passdb_get_credentials(struct auth_request *auth_request,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const char *input, const char *input_scheme,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const unsigned char **credentials_r, size_t *size_r)
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen{
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen const char *wanted_scheme = auth_request->credentials_scheme;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen const char *plaintext, *username;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen int ret;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen if (auth_request->prefer_plain_credentials &&
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen password_scheme_is_alias(input_scheme, "PLAIN")) {
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen /* we've a plaintext scheme and we prefer to get it instead
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen of converting it to the fallback scheme */
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen wanted_scheme = "";
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen }
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen ret = password_decode(input, input_scheme, credentials_r, size_r);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (ret <= 0) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (ret < 0) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen auth_request_log_error(auth_request, "password",
88f73e2ed3e99417255c90890fa46e11e6378c9dTimo Sirainen "Password in passdb is not in expected scheme %s",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen input_scheme);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen } else {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen auth_request_log_error(auth_request, "password",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen "Unknown scheme %s", input_scheme);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return FALSE;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen if (*wanted_scheme == '\0') {
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen /* anything goes. change the credentials_scheme to what we
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen actually got, so blocking passdbs work. */
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen auth_request->credentials_scheme =
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen p_strdup(auth_request->pool, input_scheme);
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen return TRUE;
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen }
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen const char *error = t_strdup_printf(
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen "Requested %s scheme, but we have only %s",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen wanted_scheme, input_scheme);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (auth_request->set->debug_passwords) {
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen error = t_strdup_printf("%s (input: %s)",
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen error, input);
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen }
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen auth_request_log_info(auth_request, "password",
ac713658d206e8d001fef7c0e36945793f2eb942Timo Sirainen "%s", error);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return FALSE;
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen /* we can generate anything out of plaintext passwords */
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen plaintext = t_strndup(*credentials_r, *size_r);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen username = auth_request->original_username;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen if (!auth_request->domain_is_realm &&
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen strchr(username, '@') != NULL) {
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen /* domain must not be used as realm. add the @realm. */
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen username = t_strconcat(username, "@",
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen auth_request->realm, NULL);
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen }
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (auth_request->set->debug_passwords) {
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk auth_request_log_debug(auth_request, "password",
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen "Generating %s from user '%s', password '%s'",
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen wanted_scheme, username, plaintext);
d368bfd671ae6d04a69eb7f418521d49b8bbf77aTimo Sirainen }
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen if (!password_generate(plaintext, username,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen wanted_scheme, credentials_r, size_r)) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen auth_request_log_error(auth_request, "password",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen "Requested unknown scheme %s", wanted_scheme);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return FALSE;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen }
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return TRUE;
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen}
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen const char *password, const char *scheme,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen lookup_credentials_callback_t *callback,
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen struct auth_request *auth_request)
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen{
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const unsigned char *credentials;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen size_t size = 0;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen if (result != PASSDB_RESULT_OK) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen callback(result, NULL, 0, auth_request);
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen return;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen }
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen if (password == NULL) {
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen auth_request_log_info(auth_request, "password",
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen "Requested %s scheme, but we have a NULL password",
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen auth_request->credentials_scheme);
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen } else if (!passdb_get_credentials(auth_request, password, scheme,
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen &credentials, &size)) {
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen }
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen callback(result, credentials, size, auth_request);
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen}
473080c7c0d25ddfdf77e7dfa0ba8f73c6c669d5Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenstatic struct passdb_module *
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenpassdb_find(const char *driver, const char *args, unsigned int *idx_r)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen struct passdb_module *const *passdbs;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen unsigned int i, count;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen passdbs = array_get(&passdb_modules, &count);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen for (i = 0; i < count; i++) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (strcmp(passdbs[i]->iface.name, driver) == 0 &&
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen strcmp(passdbs[i]->args, args) == 0) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen *idx_r = i;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return passdbs[i];
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen }
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen }
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return NULL;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen}
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainenstruct passdb_module *
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainenpassdb_preinit(pool_t pool, const char *driver, const char *args)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen static unsigned int auth_passdb_id = 0;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct passdb_module_interface *iface;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen struct passdb_module *passdb;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen unsigned int idx;
0727e38ac12efb8963a339daf56255e2be1f29fcTimo Sirainen
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen iface = passdb_interface_find(driver);
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen if (iface == NULL)
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen i_fatal("Unknown passdb driver '%s'", driver);
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen if (iface->verify_plain == NULL) {
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen i_fatal("Support not compiled in for passdb driver '%s'",
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen driver);
747e77e3ab073a8e9e69c7a3e71b4593c5655d03Timo Sirainen }
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen if (iface->preinit == NULL && iface->init == NULL && *args != '\0')
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen i_fatal("passdb %s: No args are supported: %s", driver, args);
dd93aba1901a457346990f49c54a738947dc7128Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen passdb = passdb_find(driver, args, &idx);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (passdb != NULL)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return passdb;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen if (iface->preinit == NULL)
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen passdb = p_new(pool, struct passdb_module, 1);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen else
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen passdb = iface->preinit(pool, args);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen passdb->id = ++auth_passdb_id;
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen passdb->iface = *iface;
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainen passdb->args = p_strdup(pool, args);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen array_append(&passdb_modules, &passdb, 1);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen return passdb;
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainenvoid passdb_init(struct passdb_module *passdb)
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (passdb->iface.init != NULL && passdb->init_refcount == 0)
f3d506e525a720f214020ca0f989a1966b30edaeTimo Sirainen passdb->iface.init(passdb);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen passdb->init_refcount++;
e4d34f2fbee451219599d71505594df704093ce3Timo Sirainen
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen i_assert(passdb->default_pass_scheme != NULL ||
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen passdb->cache_key == NULL);
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen}
08aea01ef9a9d20703e0fcf8618e6195c0037a44Timo Sirainen
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainenvoid passdb_deinit(struct passdb_module *passdb)
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen unsigned int idx;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_assert(passdb->init_refcount > 0);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (--passdb->init_refcount > 0)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen return;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (passdb_find(passdb->iface.name, passdb->args, &idx) == NULL)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_unreached();
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen array_delete(&passdb_modules, idx, 1);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen if (passdb->iface.deinit != NULL)
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainen passdb->iface.deinit(passdb);
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainenvoid passdbs_generate_md5(unsigned char md5[MD5_RESULTLEN])
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen{
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen struct md5_context ctx;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen struct passdb_module *const *passdbs;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen unsigned int i, count;
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen md5_init(&ctx);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen passdbs = array_get(&passdb_modules, &count);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen for (i = 0; i < count; i++) {
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen md5_update(&ctx, &passdbs[i]->id, sizeof(passdbs[i]->id));
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen md5_update(&ctx, passdbs[i]->iface.name,
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen strlen(passdbs[i]->iface.name));
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen md5_update(&ctx, passdbs[i]->args, strlen(passdbs[i]->args));
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen }
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen md5_final(&ctx, md5);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen}
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_passwd;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_bsdauth;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_shadow;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_passwd_file;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_pam;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_checkpassword;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_vpopmail;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_ldap;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_sql;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_sia;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdbs_init(void)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_array_init(&passdb_interfaces, 16);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen i_array_init(&passdb_modules, 16);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_passwd);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_bsdauth);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_passwd_file);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_pam);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_checkpassword);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_shadow);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_vpopmail);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_ldap);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_sql);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen passdb_register_module(&passdb_sia);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdbs_deinit(void)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen{
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen array_free(&passdb_modules);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen array_free(&passdb_interfaces);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen}