login-settings.c revision 46552a931924c2d743f045e95b08c3ce6beda91a
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser#include "login-common.h"
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser#include "hostpid.h"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#include "var-expand.h"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#include "settings-parser.h"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#include "master-service-settings.h"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#include "login-settings.h"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser#include <stddef.h>
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser#include <unistd.h>
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moserstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
d24d56d7ee3420bb79238ff84cad07c20cf4757dScott Moser#undef DEF
54e339f91785368a7825b2edaad04c2177a1a382Scott Moser#define DEF(type, name) \
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser { type, #name, offsetof(struct login_settings, name), NULL }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
1e0f62acaacb4e7639d6203a9f008c66be712026Serge Hallynstatic const struct setting_define login_setting_defines[] = {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, login_trusted_networks),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR_VARS, login_greeting),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, login_log_format_elements),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, login_log_format),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_ENUM, ssl),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_ca),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_cert),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_key),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_key_password),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_parameters_file),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_cipher_list),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_STR, ssl_cert_username_field),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, ssl_verify_client_cert),
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser DEF(SET_BOOL, ssl_require_client_cert),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, ssl_username_from_cert),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, verbose_ssl),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, disable_plaintext_auth),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, verbose_auth),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_BOOL, auth_debug),
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser DEF(SET_BOOL, verbose_proctitle),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser DEF(SET_UINT, mail_max_userip_connections),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser SETTING_DEFINE_LIST_END
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser};
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserstatic const struct login_settings login_default_settings = {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .login_trusted_networks = "",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .login_greeting = PACKAGE_NAME" ready.",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l %c",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .login_log_format = "%$: %s",
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser .ssl = "yes:no:required",
d24d56d7ee3420bb79238ff84cad07c20cf4757dScott Moser .ssl_ca = "",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_cert = "",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_key = "",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_key_password = "",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_parameters_file = "ssl-parameters.dat",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_cipher_list = "ALL:!LOW:!SSLv2:!EXP:!aNULL",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_cert_username_field = "commonName",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_verify_client_cert = FALSE,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .ssl_require_client_cert = FALSE,
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser .ssl_username_from_cert = FALSE,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .verbose_ssl = FALSE,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .disable_plaintext_auth = TRUE,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .verbose_auth = FALSE,
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser .auth_debug = FALSE,
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser .verbose_proctitle = FALSE,
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser .mail_max_userip_connections = 10
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser};
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserconst struct setting_parser_info login_setting_parser_info = {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .module_name = "login",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .defines = login_setting_defines,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .defaults = &login_default_settings,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .type_offset = (size_t)-1,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .struct_size = sizeof(struct login_settings),
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .parent_offset = (size_t)-1,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser .check_func = login_settings_check
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser};
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserstatic const struct setting_parser_info *default_login_set_roots[] = {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser &login_setting_parser_info,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser NULL
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser};
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserconst struct setting_parser_info **login_set_roots = default_login_set_roots;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser/* <settings checks> */
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserstatic int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r)
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser{
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser struct login_settings *set = _set;
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser#ifndef HAVE_SSL
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s",
d24d56d7ee3420bb79238ff84cad07c20cf4757dScott Moser set->ssl);
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#else
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser if (*set->ssl_cert == '\0') {
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser *error_r = "ssl enabled, but ssl_cert not set";
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser return FALSE;
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (*set->ssl_key == '\0') {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser *error_r = "ssl enabled, but ssl_key not set";
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (set->ssl_verify_client_cert && *set->ssl_ca == '\0') {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser *error_r = "ssl_verify_client_cert set, but ssl_ca not";
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return TRUE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser#endif
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser}
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moserstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r)
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser{
cb0c6c020314ee0fea0ce30d209711f7e9c29aaaScott Moser struct login_settings *set = _set;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser set->log_format_elements_split =
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser p_strsplit(pool, set->login_log_format_elements, " ");
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (set->ssl_require_client_cert || set->ssl_username_from_cert) {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser /* if we require valid cert, make sure we also ask for it */
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser set->ssl_verify_client_cert = TRUE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (strcmp(set->ssl, "no") == 0) {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser /* disabled */
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser } else if (strcmp(set->ssl, "yes") == 0) {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (!ssl_settings_check(set, error_r))
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser } else if (strcmp(set->ssl, "required") == 0) {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (!ssl_settings_check(set, error_r))
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser set->disable_plaintext_auth = TRUE;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser } else {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser *error_r = t_strdup_printf("Unknown ssl setting value: %s",
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser set->ssl);
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser return FALSE;
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser }
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser return TRUE;
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser}
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser/* </settings checks> */
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserstatic const struct var_expand_table *
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserlogin_set_var_expand_table(const struct master_service_settings_input *input)
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser{
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser static struct var_expand_table static_tab[] = {
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser { 'l', NULL, "lip" },
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser { 'r', NULL, "rip" },
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser { 'p', NULL, "pid" },
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser { 's', NULL, "service" },
79159a86ddb51071055abd7ee08935bc65b9e7a9Scott Moser { '\0', NULL, NULL }
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser };
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser struct var_expand_table *tab;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser tab = t_malloc(sizeof(static_tab));
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser memcpy(tab, static_tab, sizeof(static_tab));
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser tab[0].value = net_ip2addr(&input->local_ip);
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser tab[1].value = net_ip2addr(&input->remote_ip);
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser tab[2].value = my_pid;
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser tab[3].value = input->service;
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser return tab;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser}
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserstruct login_settings *
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserlogin_settings_read(struct master_service *service, pool_t pool,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser const struct ip_addr *local_ip,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser const struct ip_addr *remote_ip,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser const char *local_host,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser void ***other_settings_r)
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser{
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser struct master_service_settings_input input;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser const char *error;
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser void **sets;
d24d56d7ee3420bb79238ff84cad07c20cf4757dScott Moser unsigned int i;
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser memset(&input, 0, sizeof(input));
fb760f70541c9af728eb2ab0c6175875f7448752Scott Moser input.roots = login_set_roots;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser input.module = login_process_name;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser input.service = login_protocol;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser input.local_host = local_host;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (local_ip != NULL)
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser input.local_ip = *local_ip;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser if (remote_ip != NULL)
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser input.remote_ip = *remote_ip;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser /* this function always clears the previous settings pool. since we're
doing per-connection lookups, we always need to duplicate the
settings using another pool. */
if (master_service_settings_read(service, &input, &error) < 0)
i_fatal("Error reading configuration: %s", error);
sets = master_service_settings_get_others(service);
for (i = 0; sets[i] != NULL; i++) {
sets[i] = settings_dup(input.roots[i], sets[i], pool);
if (!settings_check(input.roots[i], pool, sets[i], &error)) {
const char *name = input.roots[i]->module_name;
i_fatal("settings_check(%s) failed: %s",
name != NULL ? name : "unknown", error);
}
}
settings_var_expand(&login_setting_parser_info, sets[0], pool,
login_set_var_expand_table(&input));
*other_settings_r = sets + 1;
return sets[0];
}