login-settings.c revision 0266a571e98246e2e1b9dd7fe0301e21e226929a
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "common.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "settings-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "master-service-settings.h"
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#include "login-settings.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainen#include <stddef.h>
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#include <unistd.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#undef DEF
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen#define DEF(type, name) \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { type, #name, offsetof(struct login_settings, name), NULL }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct setting_define login_setting_defines[] = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, login_chroot),
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen DEF(SET_STR, login_trusted_networks),
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen DEF(SET_STR, login_greeting),
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen DEF(SET_STR, login_log_format_elements),
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen DEF(SET_STR, login_log_format),
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen DEF(SET_ENUM, ssl),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_ca_file),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_cert),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_key),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_key_password),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_parameters_file),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_cipher_list),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_STR, ssl_cert_username_field),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, ssl_verify_client_cert),
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen DEF(SET_BOOL, ssl_require_client_cert),
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen DEF(SET_BOOL, ssl_username_from_cert),
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen DEF(SET_BOOL, verbose_ssl),
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen DEF(SET_BOOL, disable_plaintext_auth),
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen DEF(SET_BOOL, verbose_auth),
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen DEF(SET_BOOL, auth_debug),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_BOOL, verbose_proctitle),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen DEF(SET_UINT, login_max_connections),
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen DEF(SET_UINT, mail_max_userip_connections),
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen SETTING_DEFINE_LIST_END
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen};
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic struct login_settings login_default_settings = {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MEMBER(login_chroot) TRUE,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MEMBER(login_trusted_networks) "",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(login_greeting) PACKAGE_NAME" ready.",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(login_log_format_elements) "user=<%u> method=%m rip=%r lip=%l %c",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(login_log_format) "%$: %s",
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(ssl) "yes:no:required",
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MEMBER(ssl_ca_file) "",
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MEMBER(ssl_cert) "",
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen MEMBER(ssl_key) "",
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen MEMBER(ssl_key_password) "",
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MEMBER(ssl_parameters_file) "ssl-parameters.dat",
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MEMBER(ssl_cipher_list) "ALL:!LOW:!SSLv2",
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MEMBER(ssl_cert_username_field) "commonName",
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen MEMBER(ssl_verify_client_cert) FALSE,
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen MEMBER(ssl_require_client_cert) FALSE,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen MEMBER(ssl_username_from_cert) FALSE,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen MEMBER(verbose_ssl) FALSE,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(disable_plaintext_auth) TRUE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(verbose_auth) FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(auth_debug) FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(verbose_proctitle) FALSE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MEMBER(login_max_connections) 256,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen MEMBER(mail_max_userip_connections) 10
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen};
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenstruct setting_parser_info login_setting_parser_info = {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen MEMBER(defines) login_setting_defines,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen MEMBER(defaults) &login_default_settings,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MEMBER(parent) NULL,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MEMBER(dynamic_parsers) NULL,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MEMBER(parent_offset) (size_t)-1,
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen MEMBER(type_offset) (size_t)-1,
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen MEMBER(struct_size) sizeof(struct login_settings),
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen MEMBER(check_func) login_settings_check
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen};
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen/* <settings checks> */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen struct login_settings *set = _set;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen#ifndef HAVE_SSL
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s",
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen set->ssl);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen return FALSE;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen#else
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen if (*set->ssl_cert == '\0') {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen *error_r = "ssl enabled, but ssl_cert not set";
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen return FALSE;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (*set->ssl_key == '\0') {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen *error_r = "ssl enabled, but ssl_key not set";
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return FALSE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (set->ssl_verify_client_cert && *set->ssl_ca_file == '\0') {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *error_r = "ssl_verify_client_cert set, but ssl_ca_file not";
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return FALSE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen#ifndef CONFIG_BINARY
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (*set->ssl_ca_file != '\0' && access(set->ssl_ca_file, R_OK) < 0) {
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen *error_r = t_strdup_printf("ssl_ca_file: access(%s) failed: %m",
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen set->ssl_ca_file);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return FALSE;
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen#endif
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return TRUE;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen#endif
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainenstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen{
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen struct login_settings *set = _set;
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen set->log_format_elements_split =
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen p_strsplit(pool, set->login_log_format_elements, " ");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (set->ssl_require_client_cert || set->ssl_username_from_cert) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* if we require valid cert, make sure we also ask for it */
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen set->ssl_verify_client_cert = TRUE;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (set->login_max_connections < 1) {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen *error_r = "login_max_connections must be at least 1";
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen return FALSE;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen }
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (strcmp(set->ssl, "no") == 0) {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen /* disabled */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen } else if (strcmp(set->ssl, "yes") == 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (!ssl_settings_check(set, error_r))
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return FALSE;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen } else if (strcmp(set->ssl, "required") == 0) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (!ssl_settings_check(set, error_r))
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return FALSE;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen set->disable_plaintext_auth = TRUE;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen } else {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen *error_r = t_strdup_printf("Unknown ssl setting value: %s",
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen set->ssl);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen return FALSE;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen }
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen return TRUE;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen/* </settings checks> */
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenstruct login_settings *
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenlogin_settings_read(struct master_service *service, pool_t pool,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen const struct ip_addr *local_ip,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen const struct ip_addr *remote_ip)
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen{
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen static const struct setting_parser_info *set_roots[] = {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen &login_setting_parser_info,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen NULL
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen };
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen struct master_service_settings_input input;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen const char *error;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen void **sets;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen struct login_settings *set;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen memset(&input, 0, sizeof(input));
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen input.roots = set_roots;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen input.module = "login";
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen input.service = login_protocol;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (local_ip != NULL)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen input.local_ip = *local_ip;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (remote_ip != NULL)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen input.remote_ip = *remote_ip;
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen /* this function always clears the previous settings pool. since we're
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen doing per-connection lookups, we always need to duplicate the
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen settings using another pool. */
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen if (master_service_settings_read(service, &input, &error) < 0)
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen i_fatal("Error reading configuration: %s", error);
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen sets = master_service_settings_get_others(service);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen set = settings_dup(&login_setting_parser_info, sets[0], pool);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (!login_settings_check(set, pool, &error))
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_fatal("login_settings_check() failed: %s", error);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return set;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen