login-settings.c revision 4819488364b20ee82a9d60177d15c79d0b5abbe0
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/* Copyright (c) 2005-2016 Dovecot authors, see the included COPYING file */
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "login-common.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "hostpid.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "var-expand.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "settings-parser.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "master-service.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "master-service-settings.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "master-service-ssl-settings.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "master-service-settings-cache.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "login-settings.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include <stddef.h>
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include <unistd.h>
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#undef DEF
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define DEF(type, name) \
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { type, #name, offsetof(struct login_settings, name), NULL }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic const struct setting_define login_setting_defines[] = {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_trusted_networks),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_source_ips),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR_VARS, login_greeting),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_log_format_elements),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_log_format),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_access_sockets),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_plugin_dir),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, login_plugins),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_TIME, login_proxy_max_disconnect_delay),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, director_username_hash),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, ssl_client_cert),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_STR, ssl_client_key),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, ssl_require_crl),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, auth_ssl_require_client_cert),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, auth_ssl_username_from_cert),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, disable_plaintext_auth),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, auth_verbose),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, auth_debug),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_BOOL, verbose_proctitle),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEF(SET_UINT, mail_max_userip_connections),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SETTING_DEFINE_LIST_END
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock};
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic const struct login_settings login_default_settings = {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_trusted_networks = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_source_ips = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_greeting = PACKAGE_NAME" ready.",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}>",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_log_format = "%$: %s",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_access_sockets = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_plugin_dir = MODULEDIR"/login",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_plugins = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .login_proxy_max_disconnect_delay = 0,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .director_username_hash = "%u",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .ssl_client_cert = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .ssl_client_key = "",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .ssl_require_crl = TRUE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .auth_ssl_require_client_cert = FALSE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .auth_ssl_username_from_cert = FALSE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .disable_plaintext_auth = TRUE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .auth_verbose = FALSE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .auth_debug = FALSE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .verbose_proctitle = FALSE,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .mail_max_userip_connections = 10
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock};
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockconst struct setting_parser_info login_setting_parser_info = {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .module_name = "login",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .defines = login_setting_defines,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .defaults = &login_default_settings,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .type_offset = (size_t)-1,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .struct_size = sizeof(struct login_settings),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .parent_offset = (size_t)-1,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock .check_func = login_settings_check
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock};
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic const struct setting_parser_info *default_login_set_roots[] = {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &login_setting_parser_info,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock NULL
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock};
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockconst struct setting_parser_info **login_set_roots = default_login_set_roots;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic struct master_service_settings_cache *set_cache;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/* <settings checks> */
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic bool login_settings_check(void *_set, pool_t pool,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const char **error_r ATTR_UNUSED)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock struct login_settings *set = _set;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set->log_format_elements_split =
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock p_strsplit(pool, set->login_log_format_elements, " ");
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (set->auth_debug_passwords)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set->auth_debug = TRUE;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (set->auth_debug)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set->auth_verbose = TRUE;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return TRUE;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/* </settings checks> */
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic const struct var_expand_table *
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrocklogin_set_var_expand_table(const struct master_service_settings_input *input)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock static struct var_expand_table static_tab[] = {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { 'l', NULL, "lip" },
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { 'r', NULL, "rip" },
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { 'p', NULL, "pid" },
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { 's', NULL, "service" },
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock { '\0', NULL, NULL }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock };
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock struct var_expand_table *tab;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tab = t_malloc(sizeof(static_tab));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock memcpy(tab, static_tab, sizeof(static_tab));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tab[0].value = net_ip2addr(&input->local_ip);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tab[1].value = net_ip2addr(&input->remote_ip);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tab[2].value = my_pid;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock tab[3].value = input->service;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return tab;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstatic void *
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrocklogin_setting_dup(pool_t pool, const struct setting_parser_info *info,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const void *src_set)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const char *error;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock void *dest;
9af3851a3a831b4de34b42482c22351e14f33f16eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock dest = settings_dup(info, src_set, pool);
9af3851a3a831b4de34b42482c22351e14f33f16eschrock if (!settings_check(info, pool, dest, &error)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const char *name = info->module_name;
9af3851a3a831b4de34b42482c22351e14f33f16eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i_fatal("settings_check(%s) failed: %s",
9af3851a3a831b4de34b42482c22351e14f33f16eschrock name != NULL ? name : "unknown", error);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return dest;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockstruct login_settings *
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrocklogin_settings_read(pool_t pool,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const struct ip_addr *local_ip,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const struct ip_addr *remote_ip,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const char *local_name,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const struct master_service_ssl_settings **ssl_set_r,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock void ***other_settings_r)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock struct master_service_settings_input input;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const char *error;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock const struct setting_parser_context *parser;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock void *const *cache_sets;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock void **sets;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock unsigned int i, count;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock memset(&input, 0, sizeof(input));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.roots = login_set_roots;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.module = login_binary->process_name;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.service = login_binary->protocol;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.local_name = local_name;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (local_ip != NULL)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.local_ip = *local_ip;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (remote_ip != NULL)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.remote_ip = *remote_ip;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (set_cache == NULL) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock set_cache = master_service_settings_cache_init(master_service,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.module,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock input.service);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (master_service_settings_cache_read(set_cache, &input, NULL,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &parser, &error) < 0)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i_fatal("Error reading configuration: %s", error);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock cache_sets = master_service_settings_parser_get_others(master_service, parser);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock for (count = 0; input.roots[count] != NULL; count++) ;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock i_assert(cache_sets[count] == NULL);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sets = p_new(pool, void *, count + 1);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock for (i = 0; i < count; i++)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock sets[i] = login_setting_dup(pool, input.roots[i], cache_sets[i]);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock settings_var_expand(&login_setting_parser_info, sets[0], pool,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock login_set_var_expand_table(&input));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *ssl_set_r =
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock login_setting_dup(pool, &master_service_ssl_setting_parser_info,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock settings_parser_get_list(parser)[1]);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *other_settings_r = sets + 1;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return sets[0];
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockvoid login_settings_deinit(void)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (set_cache != NULL)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock master_service_settings_cache_deinit(&set_cache);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock