bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic ARRAY(struct passdb_module_interface *) passdb_interfaces;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic ARRAY(struct passdb_module *) passdb_modules;
9d75363d3fbabc2fbc2d80f06672e3ed8965804aTimo Sirainenstatic const struct passdb_module_interface passdb_iface_deinit = {
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenstatic struct passdb_module_interface *passdb_interface_find(const char *name)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct passdb_module_interface *const *ifaces;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen struct passdb_module_interface *iface = *ifaces;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdb_register_module(struct passdb_module_interface *iface)
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 */
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_panic("passdb_register_module(%s): Already registered",
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenvoid passdb_unregister_module(struct passdb_module_interface *iface)
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen struct passdb_module_interface *const *ifaces;
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen idx = array_foreach_idx(&passdb_interfaces, ifaces);
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainen i_panic("passdb_unregister_module(%s): Not registered", iface->name);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainenbool passdb_get_credentials(struct auth_request *auth_request,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen const unsigned char **credentials_r, size_t *size_r)
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen const char *wanted_scheme = auth_request->credentials_scheme;
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov struct password_generate_params pwd_gen_params;
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 */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
ce6c2809b8a1673372a683716566d973efd2f6eeTimo Sirainen "Password data is not valid for scheme %s: %s",
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen /* anything goes. change the credentials_scheme to what we
b4f2560c29dacd066ba89e782d95ceed7ac473a3Timo Sirainen actually got, so blocking passdbs work. */
1479a685cdb1641783ac02ba135450929f5c2658Timo Sirainen p_strdup(auth_request->pool, t_strcut(input_scheme, '.'));
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (!password_scheme_is_alias(input_scheme, wanted_scheme)) {
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen if (!password_scheme_is_alias(input_scheme, "PLAIN")) {
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen "Requested %s scheme, but we have only %s",
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen /* we can generate anything out of plaintext passwords */
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen plaintext = t_strndup(*credentials_r, *size_r);
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov pwd_gen_params.user = auth_request->original_username;
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen /* domain must not be used as realm. add the @realm. */
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov pwd_gen_params.user = t_strconcat(pwd_gen_params.user, "@",
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(auth_request, AUTH_SUBSYS_DB,
446e518e4fe86ff40e33543445f4e99edf840a21Timo Sirainen "Generating %s from user '%s', password '%s'",
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov wanted_scheme, pwd_gen_params.user, plaintext);
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov if (!password_generate(plaintext, &pwd_gen_params,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen "Requested unknown scheme %s", wanted_scheme);
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainenvoid passdb_handle_credentials(enum passdb_result result,
448e068f2fe3904e18656d730e2b7cf0e6572fc1Aki Tuomi } else if (auth_fields_exists(auth_request->extra_fields, "noauthenticate")) {
448e068f2fe3904e18656d730e2b7cf0e6572fc1Aki Tuomi callback(PASSDB_RESULT_NEXT, NULL, 0, auth_request);
b24ffea8baa472d9b542e54ed3f9939eefd020adTimo Sirainen if (!passdb_get_credentials(auth_request, password, scheme,
b24ffea8baa472d9b542e54ed3f9939eefd020adTimo Sirainen } else if (*auth_request->credentials_scheme == '\0') {
b24ffea8baa472d9b542e54ed3f9939eefd020adTimo Sirainen /* We're doing a passdb lookup (not authenticating).
b24ffea8baa472d9b542e54ed3f9939eefd020adTimo Sirainen Pass through a NULL password without an error. */
7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2Timo Sirainen } else if (auth_request->delayed_credentials != NULL) {
7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2Timo Sirainen /* We already have valid credentials from an earlier
7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2Timo Sirainen passdb lookup. auth_request_lookup_credentials_finish()
7d26aee0c0b6c0ce227ef4ae4f20fc86e2c423f2Timo Sirainen will use them. */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
4ed1b49d815ec41a5e4b6a23d23e94b958da1923Timo Sirainen "Requested %s scheme, but we have a NULL password",
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen callback(result, credentials, size, auth_request);
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainenpassdb_find(const char *driver, const char *args, unsigned int *idx_r)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen for (i = 0; i < count; i++) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (strcmp(passdbs[i]->iface.name, driver) == 0 &&
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainenpassdb_preinit(pool_t pool, const struct auth_passdb_settings *set)
8ff9812659728d4166df8e003a1dd3524ae8514eTimo Sirainen if (iface == NULL || iface->verify_plain == NULL) {
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen /* maybe it's a plugin. try to load it. */
966cb0c1aa58578339cea6f79b4a423a851ab074Timo Sirainen auth_module_load(t_strconcat("authdb_", set->driver, NULL));
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen i_fatal("Unknown passdb driver '%s'", set->driver);
d5abbb932a0a598f002da39a8b3326643b1b5efcTimo Sirainen i_fatal("Support not compiled in for passdb driver '%s'",
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen if (iface->preinit == NULL && iface->init == NULL &&
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen i_fatal("passdb %s: No args are supported: %s",
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen passdb = passdb_find(set->driver, set->args, &idx);
e48d89622047bd8bbd0475b881ca9377d592f535Timo Sirainen passdb = p_new(pool, struct passdb_module, 1);
10f6f2224c897fc543973efd2f46b86a3ab1148dAki Tuomi } else if (strcasecmp(set->mechanisms, "none") == 0) {
10f6f2224c897fc543973efd2f46b86a3ab1148dAki Tuomi passdb->mechanisms = (const char* const*)p_strsplit_spaces(pool, set->mechanisms, " ,");
268a76700330d159c805c70d1e3eae2e21f1cb9eAki Tuomi passdb->username_filter = (const char* const*)p_strsplit_spaces(pool, set->username_filter, " ,");
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (passdb->iface.init != NULL && passdb->init_refcount == 0)
849969f639a00eab26791db3cb1b66430420c0cdTimo Sirainenvoid passdb_deinit(struct passdb_module *passdb)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (passdb_find(passdb->iface.name, passdb->args, &idx) == NULL)
9d75363d3fbabc2fbc2d80f06672e3ed8965804aTimo Sirainen /* make sure passdb isn't accessed again */
9625595c47c665f5aee57ebfcb1fcbe9ad1bf3a0Martti Rannanjärvivoid passdbs_generate_md5(unsigned char md5[STATIC_ARRAY MD5_RESULTLEN])
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]->args, strlen(passdbs[i]->args));
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_passwd;
43a66a0b16299bd4f7615acd85e98bd3832c54d5Timo Sirainenextern struct passdb_module_interface passdb_bsdauth;
2028d80c2704bbf62b29b2c624b0ee3c3a03c462Timo Sirainenextern struct passdb_module_interface passdb_dict;
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;
1a669829132a4b68aaba32400e28bb2a4e19bcaaTimo Sirainenextern struct passdb_module_interface passdb_static;
9b670175445a75987a713ff899d1a945255b0b5bAki Tuomiextern struct passdb_module_interface passdb_oauth2;