passdb.c revision 9ed2951bd0bb1878a27437d7c00611b2baadd614
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic ARRAY_DEFINE(passdb_interfaces, struct passdb_module_interface *);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic ARRAY_DEFINE(passdb_modules, struct passdb_module *);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic struct passdb_module_interface *passdb_interface_find(const char *name)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct passdb_module_interface *iface = *ifaces;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid passdb_register_module(struct passdb_module_interface *iface)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct passdb_module_interface *old_iface;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher old_iface = passdb_interface_find(iface->name);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (old_iface != NULL && old_iface->verify_plain == NULL) {
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher /* replacing a "support not compiled in" passdb */
cc98edd9479d4622634a1275c98058916c14059aStephen Gallagher i_panic("passdb_register_module(%s): Already registered",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher array_append(&passdb_interfaces, &iface, 1);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid passdb_unregister_module(struct passdb_module_interface *iface)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher struct passdb_module_interface *const *ifaces;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int idx;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher array_foreach(&passdb_interfaces, ifaces) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher idx = array_foreach_idx(&passdb_interfaces, ifaces);
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorce i_panic("passdb_unregister_module(%s): Not registered", iface->name);
c89589fa349f38214c9cb8d9389c0fd557e5dca2Simo Sorcebool passdb_get_credentials(struct auth_request *auth_request,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *input, const char *input_scheme,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const unsigned char **credentials_r, size_t *size_r)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *wanted_scheme = auth_request->credentials_scheme;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (auth_request->prefer_plain_credentials &&
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher password_scheme_is_alias(input_scheme, "PLAIN")) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* we've a plaintext scheme and we prefer to get it instead
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher of converting it to the fallback scheme */
d921c1eba437662437847279f251a0a5d8f70127Maxim ret = password_decode(input, input_scheme, credentials_r, size_r);
d921c1eba437662437847279f251a0a5d8f70127Maxim if (ret <= 0) {
d921c1eba437662437847279f251a0a5d8f70127Maxim if (ret < 0) {
d921c1eba437662437847279f251a0a5d8f70127Maxim "Password in passdb is not in expected scheme %s",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* anything goes. change the credentials_scheme to what we
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher actually got, so blocking passdbs work. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher p_strdup(auth_request->pool, input_scheme);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "Requested %s scheme, but we have only %s",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher auth_request_log_info(auth_request, "password",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* we can generate anything out of plaintext passwords */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher plaintext = t_strndup(*credentials_r, *size_r);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher username = auth_request->original_username;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* domain must not be used as realm. add the @realm. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher auth_request_log_debug(auth_request, "password",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "Generating %s from user '%s', password '%s'",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (!password_generate(plaintext, username,
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek auth_request_log_error(auth_request, "password",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "Requested unknown scheme %s", wanted_scheme);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid passdb_handle_credentials(enum passdb_result result,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const unsigned char *credentials;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher auth_request_log_info(auth_request, "password",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher "Requested %s scheme, but we have a NULL password",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher result = PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher } else if (!passdb_get_credentials(auth_request, password, scheme,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher callback(result, credentials, size, auth_request);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherpassdb_find(const char *driver, const char *args, unsigned int *idx_r)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher unsigned int i, count;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher passdbs = array_get(&passdb_modules, &count);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher for (i = 0; i < count; i++) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (strcmp(passdbs[i]->iface.name, driver) == 0 &&
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozekpassdb_preinit(pool_t pool, const char *driver, const char *args)
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek static unsigned int auth_passdb_id = 0;
172c07013d1ea99447a780fd36f49d5c3a76981bJakub Hrozek unsigned int idx;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_fatal("Support not compiled in for passdb driver '%s'",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (iface->preinit == NULL && iface->init == NULL && *args != '\0')
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_fatal("passdb %s: No args are supported: %s", driver, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher passdb = p_new(pool, struct passdb_module, 1);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher array_append(&passdb_modules, &passdb, 1);
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallaghervoid passdb_init(struct passdb_module *passdb)
unsigned int idx;
i_unreached();
void passdbs_init(void)
void passdbs_deinit(void)