login-settings.c revision 2454dfa32c93c20a8522c6ed42fe057baaac9f9a
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2005-2017 Dovecot authors, see the included COPYING file */
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "login-common.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "hostpid.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "var-expand.h"
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi#include "settings-parser.h"
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi#include "master-service.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "master-service-settings.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "master-service-ssl-settings.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "master-service-settings-cache.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#include "login-settings.h"
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi#include <stddef.h>
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi#include <unistd.h>
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomistatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#undef DEF
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk#define DEF(type, name) \
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { type, #name, offsetof(struct login_settings, name), NULL }
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainenstatic const struct setting_define login_setting_defines[] = {
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov DEF(SET_STR, login_trusted_networks),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_source_ips),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR_VARS, login_greeting),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_log_format_elements),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_log_format),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_access_sockets),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_plugin_dir),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, login_plugins),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_TIME, login_proxy_max_disconnect_delay),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, director_username_hash),
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen DEF(SET_STR, ssl_client_cert),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk DEF(SET_STR, ssl_client_key),
58d21a174d971834cfcd6d363349222749a54650Aki Tuomi DEF(SET_BOOL, ssl_require_crl),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk DEF(SET_BOOL, auth_ssl_require_client_cert),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk DEF(SET_BOOL, auth_ssl_username_from_cert),
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi DEF(SET_BOOL, disable_plaintext_auth),
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi DEF(SET_BOOL, auth_verbose),
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov DEF(SET_BOOL, auth_debug),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk DEF(SET_BOOL, verbose_proctitle),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk DEF(SET_UINT, mail_max_userip_connections),
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk SETTING_DEFINE_LIST_END
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk};
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volkstatic const struct login_settings login_default_settings = {
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_trusted_networks = "",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_source_ips = "",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_greeting = PACKAGE_NAME" ready.",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}>",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_log_format = "%$: %s",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_access_sockets = "",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_plugin_dir = MODULEDIR"/login",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_plugins = "",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .login_proxy_max_disconnect_delay = 0,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .director_username_hash = "%u",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk .ssl_client_cert = "",
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk .ssl_client_key = "",
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk .ssl_require_crl = TRUE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .auth_ssl_require_client_cert = FALSE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .auth_ssl_username_from_cert = FALSE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .disable_plaintext_auth = TRUE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .auth_verbose = FALSE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .auth_debug = FALSE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .verbose_proctitle = FALSE,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .mail_max_userip_connections = 10
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi};
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomiconst struct setting_parser_info login_setting_parser_info = {
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .module_name = "login",
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .defines = login_setting_defines,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .defaults = &login_default_settings,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .type_offset = (size_t)-1,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .struct_size = sizeof(struct login_settings),
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .parent_offset = (size_t)-1,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi .check_func = login_settings_check
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi};
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomistatic const struct setting_parser_info *default_login_set_roots[] = {
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi &login_setting_parser_info,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi NULL
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi};
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomiconst struct setting_parser_info **login_set_roots = default_login_set_roots;
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomistatic struct master_service_settings_cache *set_cache;
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk/* <settings checks> */
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitovstatic bool login_settings_check(void *_set, pool_t pool,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const char **error_r ATTR_UNUSED)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk{
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk struct login_settings *set = _set;
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk set->log_format_elements_split =
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk p_strsplit(pool, set->login_log_format_elements, " ");
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk if (set->auth_debug_passwords)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk set->auth_debug = TRUE;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk if (set->auth_debug)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk set->auth_verbose = TRUE;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk return TRUE;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk}
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk/* </settings checks> */
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volkstatic const struct var_expand_table *
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volklogin_set_var_expand_table(const struct master_service_settings_input *input)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk{
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const struct var_expand_table stack_tab[] = {
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { 'l', net_ip2addr(&input->local_ip), "lip" },
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { 'r', net_ip2addr(&input->remote_ip), "rip" },
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { 'p', my_pid, "pid" },
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { 's', input->service, "service" },
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov { '\0', input->local_name, "local_name" },
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk { '\0', NULL, NULL }
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk };
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk struct var_expand_table *tab;
605c40c77fc3851cb2845da1c5319e32c791592aSergey Kitov
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk tab = t_malloc_no0(sizeof(stack_tab));
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk memcpy(tab, stack_tab, sizeof(stack_tab));
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk return tab;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk}
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volkstatic void *
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volklogin_setting_dup(pool_t pool, const struct setting_parser_info *info,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const void *src_set)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk{
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const char *error;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk void *dest;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk dest = settings_dup(info, src_set, pool);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk if (!settings_check(info, pool, dest, &error)) {
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const char *name = info->module_name;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk i_fatal("settings_check(%s) failed: %s",
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk name != NULL ? name : "unknown", error);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk }
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk return dest;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk}
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volkstruct login_settings *
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volklogin_settings_read(pool_t pool,
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen const struct ip_addr *local_ip,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const struct ip_addr *remote_ip,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const char *local_name,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const struct master_service_ssl_settings **ssl_set_r,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk void ***other_settings_r)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk{
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk struct master_service_settings_input input;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const char *error;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk const struct setting_parser_context *parser;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk void *const *cache_sets;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk void **sets;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk unsigned int i, count;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi i_zero(&input);
54a1b3574acab5f778843f7f1e04d2d26d61a852Timo Sirainen input.roots = login_set_roots;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk input.module = login_binary->process_name;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk input.service = login_binary->protocol;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk input.local_name = local_name;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk if (local_ip != NULL)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk input.local_ip = *local_ip;
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi if (remote_ip != NULL)
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi input.remote_ip = *remote_ip;
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi if (set_cache == NULL) {
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi set_cache = master_service_settings_cache_init(master_service,
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi input.module,
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi input.service);
4bed0c5f99c1ed3ebe409796275a234b56a413fdAki Tuomi }
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi if (master_service_settings_cache_read(set_cache, &input, NULL,
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk &parser, &error) < 0)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk i_fatal("Error reading configuration: %s", error);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk cache_sets = master_service_settings_parser_get_others(master_service, parser);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk for (count = 0; input.roots[count] != NULL; count++) ;
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk i_assert(cache_sets[count] == NULL);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk sets = p_new(pool, void *, count + 1);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk for (i = 0; i < count; i++)
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk sets[i] = login_setting_dup(pool, input.roots[i], cache_sets[i]);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk if (settings_var_expand(&login_setting_parser_info, sets[0], pool,
1ebb6094e5105ba7ef521a0177c42d3ea81243f0Aki Tuomi login_set_var_expand_table(&input), &error) <= 0)
cfb22f2f9b28d5888ba00ad910e47c9a490ca673Aki Tuomi i_fatal("Failed to expand settings: %s", error);
42fb278a57f1c6d7d5d0c7bd2318edb721dc0ec0Pascal Volk
*ssl_set_r =
login_setting_dup(pool, &master_service_ssl_setting_parser_info,
settings_parser_get_list(parser)[1]);
*other_settings_r = sets + 1;
return sets[0];
}
void login_settings_deinit(void)
{
if (set_cache != NULL)
master_service_settings_cache_deinit(&set_cache);
}