login-settings.c revision 97db4761382024093f441e4bc78ba8b6a056504d
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen#include "common.h"
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen#include "settings-parser.h"
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen#include "master-service-settings.h"
dd3ccdbb29dad006f7781ea138a5ba39727963c4Timo Sirainen#include "login-settings.h"
a338794c56fc9674121e262fcb67c3dc1da31436Timo Sirainen
419be6cd72f6e11705576bbba683b29c32eaa762Timo Sirainen#include <stddef.h>
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen#include <unistd.h>
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
dd3ccdbb29dad006f7781ea138a5ba39727963c4Timo Sirainenstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
c4390dad33b03dd51ba2a475f550347c86ebdb9aTimo Sirainen
dd3ccdbb29dad006f7781ea138a5ba39727963c4Timo Sirainen#undef DEF
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen#define DEF(type, name) \
6b6011c2242e470b41316f92512b282b5e306dacTimo Sirainen { type, #name, offsetof(struct login_settings, name), NULL }
18458233e89c8467e30d8b93b1823128f26bc174Timo Sirainen
ffaa309c211897ab875bbe0b093bc7e709bb1e5dTimo Sirainenstatic struct setting_define login_setting_defines[] = {
a566d9f8797dd66b4d5432a20ab2b9f7c8f76102Timo Sirainen DEF(SET_BOOL, login_chroot),
42abccd9b2a5a4190bd3c14ec2dcc10d51c0f491Timo Sirainen DEF(SET_STR, login_trusted_networks),
c2ebc8f28b5504f280cd5d4adfe57ed70f9a7d83Timo Sirainen DEF(SET_STR, login_greeting),
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen DEF(SET_STR, login_log_format_elements),
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen DEF(SET_STR, login_log_format),
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen DEF(SET_BOOL, login_process_per_connection),
c2ebc8f28b5504f280cd5d4adfe57ed70f9a7d83Timo Sirainen DEF(SET_STR, capability_string),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_ENUM, ssl),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_STR, ssl_ca_file),
458acd7b39c84bae0d18c36ff9ddff9a49b4ae4aTimo Sirainen DEF(SET_STR, ssl_cert),
78a5b3e697af5db96fe0dffed600b0d6370bb8e5Timo Sirainen DEF(SET_STR, ssl_key),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_STR, ssl_key_password),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_STR, ssl_parameters_file),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_STR, ssl_cipher_list),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_STR, ssl_cert_username_field),
c2ebc8f28b5504f280cd5d4adfe57ed70f9a7d83Timo Sirainen DEF(SET_BOOL, ssl_verify_client_cert),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_BOOL, ssl_require_client_cert),
c2ebc8f28b5504f280cd5d4adfe57ed70f9a7d83Timo Sirainen DEF(SET_BOOL, ssl_username_from_cert),
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen DEF(SET_BOOL, verbose_ssl),
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen DEF(SET_BOOL, disable_plaintext_auth),
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_BOOL, verbose_auth),
a50f8b9c6196b0f0bb0a7aac3ae9c12b1c42b93bTimo Sirainen DEF(SET_BOOL, auth_debug),
eed0a07ecb946ec9d021f5b413fb33eb36e135fdTimo Sirainen DEF(SET_BOOL, verbose_proctitle),
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen DEF(SET_UINT, login_max_connections),
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen DEF(SET_UINT, mail_max_userip_connections),
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen SETTING_DEFINE_LIST_END
89502bb187e8285b2a155559894ca80374ac3ae7Timo Sirainen};
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainenstatic struct login_settings login_default_settings = {
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_chroot) TRUE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_trusted_networks) "",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_greeting) PACKAGE_NAME" ready.",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_log_format_elements) "user=<%u> method=%m rip=%r lip=%l %c",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_log_format) "%$: %s",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(login_process_per_connection) TRUE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(capability_string) NULL,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl) "yes:no:required",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_ca_file) "",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_cert) "",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_key) "",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_key_password) "",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_parameters_file) "ssl-parameters.dat",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_cipher_list) "ALL:!LOW:!SSLv2",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_cert_username_field) "commonName",
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_verify_client_cert) FALSE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_require_client_cert) FALSE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(ssl_username_from_cert) FALSE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(verbose_ssl) FALSE,
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen
d65cc3312d3126d34b51ae8eccd6b48215d50029Timo Sirainen MEMBER(disable_plaintext_auth) TRUE,
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen MEMBER(verbose_auth) FALSE,
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen MEMBER(auth_debug) FALSE,
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen MEMBER(verbose_proctitle) FALSE,
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen
b015d3d3af5b1c0fd526f31d78229bf9f633db56Timo Sirainen MEMBER(login_max_connections) 256,
a566d9f8797dd66b4d5432a20ab2b9f7c8f76102Timo Sirainen MEMBER(mail_max_userip_connections) 10
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen};
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainenstruct setting_parser_info login_setting_parser_info = {
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen MEMBER(defines) login_setting_defines,
fcd443a32b01c4da131f36649d5a5fa5f8452dcfTimo Sirainen MEMBER(defaults) &login_default_settings,
fcd443a32b01c4da131f36649d5a5fa5f8452dcfTimo Sirainen
d65cc3312d3126d34b51ae8eccd6b48215d50029Timo Sirainen MEMBER(parent) NULL,
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen MEMBER(dynamic_parsers) NULL,
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen MEMBER(parent_offset) (size_t)-1,
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen MEMBER(type_offset) (size_t)-1,
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen MEMBER(struct_size) sizeof(struct login_settings),
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen MEMBER(check_func) login_settings_check
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen};
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen/* <settings checks> */
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainenstatic int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r)
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen{
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen struct login_settings *set = _set;
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen#ifndef HAVE_SSL
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s",
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen set->ssl);
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen return FALSE;
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen#else
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen if (*set->ssl_cert == '\0') {
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen *error_r = "ssl enabled, but ssl_cert not set";
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen return FALSE;
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen }
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen if (*set->ssl_key == '\0') {
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen *error_r = "ssl enabled, but ssl_key not set";
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen return FALSE;
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen }
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen if (set->ssl_verify_client_cert && *set->ssl_ca_file == '\0') {
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen *error_r = "ssl_verify_client_cert set, but ssl_ca_file not";
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen return FALSE;
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen }
4fbf59562594dbbbe037f8d4c480dbf88f3fc708Timo Sirainen
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen#ifndef CONFIG_BINARY
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (*set->ssl_ca_file != '\0' && access(set->ssl_ca_file, R_OK) < 0) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen *error_r = t_strdup_printf("ssl_ca_file: access(%s) failed: %m",
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen set->ssl_ca_file);
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen return FALSE;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen }
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen#endif
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen return TRUE;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen#endif
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen}
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainenstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r)
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen{
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen struct login_settings *set = _set;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen set->log_format_elements_split =
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen p_strsplit(pool, set->login_log_format_elements, " ");
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (set->ssl_require_client_cert || set->ssl_username_from_cert) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen /* if we require valid cert, make sure we also ask for it */
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen set->ssl_verify_client_cert = TRUE;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen }
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (set->login_max_connections < 1) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen *error_r = "login_max_connections must be at least 1";
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen return FALSE;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen }
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (strcmp(set->ssl, "no") == 0) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen /* disabled */
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen } else if (strcmp(set->ssl, "yes") == 0) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (!ssl_settings_check(set, error_r))
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen return FALSE;
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen } else if (strcmp(set->ssl, "required") == 0) {
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen if (!ssl_settings_check(set, error_r))
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen return FALSE;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen set->disable_plaintext_auth = TRUE;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen } else {
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen *error_r = t_strdup_printf("Unknown ssl setting value: %s",
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen set->ssl);
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen return FALSE;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen }
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen return TRUE;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen}
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen/* </settings checks> */
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainenstruct login_settings *
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainenlogin_settings_read(struct master_service *service, pool_t pool,
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen const struct ip_addr *local_ip,
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen const struct ip_addr *remote_ip)
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen{
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen static const struct setting_parser_info *set_roots[] = {
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen &login_setting_parser_info,
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen NULL
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen };
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen struct master_service_settings_input input;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen const char *error;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen void **sets;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen struct login_settings *set;
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen memset(&input, 0, sizeof(input));
38f624b427aa8b6fad3765e6efd97c85a7f97a09Timo Sirainen input.roots = set_roots;
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen input.module = "login";
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen input.service = login_protocol;
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen if (local_ip != NULL)
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen input.local_ip = *local_ip;
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen if (remote_ip != NULL)
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen input.remote_ip = *remote_ip;
6de95f63d4590814354fa5e35e92946c58d4562eTimo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen /* this function always clears the previous settings pool. since we're
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen doing per-connection lookups, we always need to duplicate the
65514ab6ccc1889e1667211fddb0cca4b51017dfTimo Sirainen settings using another pool. */
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen if (master_service_settings_read(service, &input, &error) < 0)
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen i_fatal("Error reading configuration: %s", error);
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen sets = master_service_settings_get_others(service);
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen set = settings_dup(&login_setting_parser_info, sets[0], pool);
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen if (!login_settings_check(set, pool, &error))
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen i_fatal("login_settings_check() failed: %s", error);
e5b06a21b5f857d7037fd6ff41ba3bd449d1232aTimo Sirainen return set;
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen}
315ce5be539bfe8bc7777ab0654499c49583cea2Timo Sirainen