login-settings.c revision 1358e2c58ce29231485a5cfa454756d429ad3d2c
b9f30617c2c96d54acbc4f85ed17b939c4f28916Timo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen#include "common.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "settings-parser.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "master-service-settings.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "login-settings.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stddef.h>
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <unistd.h>
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
d63b4241643b6014d49ff356f14e0f3ee43068a8Timo Sirainenstatic bool login_settings_check(void *_set, pool_t pool, const char **error_r);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#undef DEF
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#define DEF(type, name) \
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen { type, #name, offsetof(struct login_settings, name), NULL }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic struct setting_define login_setting_defines[] = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, login_chroot),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, login_trusted_networks),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, login_greeting),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, login_log_format_elements),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, login_log_format),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, login_process_per_connection),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, capability_string),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_ENUM, ssl),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_ca_file),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_cert_file),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_key_file),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_key_password),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_parameters_file),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_cipher_list),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_STR, ssl_cert_username_field),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, ssl_verify_client_cert),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, ssl_require_client_cert),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, ssl_username_from_cert),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, verbose_ssl),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, disable_plaintext_auth),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, verbose_auth),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, auth_debug),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_BOOL, verbose_proctitle),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen DEF(SET_UINT, login_max_connections),
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen DEF(SET_UINT, mail_max_userip_connections),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen SETTING_DEFINE_LIST_END
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic struct login_settings login_default_settings = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_chroot) TRUE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_trusted_networks) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_greeting) PACKAGE" ready.",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_log_format_elements) "user=<%u> method=%m rip=%r lip=%l %c",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_log_format) "%$: %s",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(login_process_per_connection) TRUE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(capability_string) NULL,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl) "yes:no:required",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_ca_file) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_cert_file) SSLDIR"/certs/dovecot.pem",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_key_file) SSLDIR"/private/dovecot.pem",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_key_password) "",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_parameters_file) "ssl-parameters.dat",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_cipher_list) "ALL:!LOW:!SSLv2",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_cert_username_field) "commonName",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_verify_client_cert) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_require_client_cert) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(ssl_username_from_cert) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(verbose_ssl) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(disable_plaintext_auth) TRUE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(verbose_auth) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(auth_debug) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(verbose_proctitle) FALSE,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen MEMBER(login_max_connections) 256,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen MEMBER(mail_max_userip_connections) 10
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstruct setting_parser_info login_setting_parser_info = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(defines) login_setting_defines,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(defaults) &login_default_settings,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(parent) NULL,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(dynamic_parsers) NULL,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(parent_offset) (size_t)-1,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen MEMBER(type_offset) (size_t)-1,
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen MEMBER(struct_size) sizeof(struct login_settings),
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen MEMBER(check_func) login_settings_check
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen/* <settings checks> */
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainenstatic int ssl_settings_check(void *_set ATTR_UNUSED, const char **error_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen struct login_settings *set = _set;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#ifndef HAVE_SSL
ce8a6f53ea3ce91b759a54b771e1779564de19a1Timo Sirainen *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s",
ce8a6f53ea3ce91b759a54b771e1779564de19a1Timo Sirainen set->ssl);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#else
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (*set->ssl_cert_file == '\0') {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = "ssl_cert_file not set";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen if (*set->ssl_key_file == '\0') {
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen *error_r = "ssl_key_file not set";
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen return FALSE;
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen }
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen if (set->ssl_verify_client_cert && *set->ssl_ca_file == '\0') {
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen *error_r = "ssl_verify_client_cert set, but ssl_ca_file not";
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen#ifndef CONFIG_BINARY
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen if (access(set->ssl_cert_file, R_OK) < 0) {
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen *error_r = t_strdup_printf("ssl_cert_file: access(%s) failed: %m",
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen set->ssl_cert_file);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (access(set->ssl_key_file, R_OK) < 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = t_strdup_printf("ssl_key_file: access(%s) failed: %m",
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen set->ssl_key_file);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (*set->ssl_ca_file != '\0' && access(set->ssl_ca_file, R_OK) < 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = t_strdup_printf("ssl_ca_file: access(%s) failed: %m",
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen set->ssl_ca_file);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
1cbc0c6372d24168962698c5f4d3e15df8943ebfTimo Sirainen#endif
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#endif
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
d63b4241643b6014d49ff356f14e0f3ee43068a8Timo Sirainenstatic bool login_settings_check(void *_set, pool_t pool ATTR_UNUSED,
d63b4241643b6014d49ff356f14e0f3ee43068a8Timo Sirainen const char **error_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen struct login_settings *set = _set;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen set->log_format_elements_split =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen t_strsplit(set->login_log_format_elements, " ");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (set->ssl_require_client_cert || set->ssl_username_from_cert) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* if we require valid cert, make sure we also ask for it */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen set->ssl_verify_client_cert = TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (set->login_max_connections < 1) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = "login_max_connections must be at least 1";
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return FALSE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (strcmp(set->ssl, "no") == 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen /* disabled */
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen } else if (strcmp(set->ssl, "yes") == 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (!ssl_settings_check(set, error_r))
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return FALSE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen } else if (strcmp(set->ssl, "required") == 0) {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen if (!ssl_settings_check(set, error_r))
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return FALSE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen set->disable_plaintext_auth = TRUE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen } else {
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen *error_r = t_strdup_printf("Unknown ssl setting value: %s",
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen set->ssl);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return FALSE;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen }
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen return TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen/* </settings checks> */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstruct login_settings *login_settings_read(struct master_service *service)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen static const struct setting_parser_info *set_roots[] = {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &login_setting_parser_info,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen NULL
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen };
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct master_service_settings_input input;
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen const char *error;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen void **sets;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen memset(&input, 0, sizeof(input));
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen input.roots = set_roots;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen input.module = "login";
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen input.service = login_protocol;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (master_service_settings_read(service, &input, &error) < 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("Error reading configuration: %s", error);
b215a8a123623782554a83f3025ef4e771bd8f01Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen sets = master_service_settings_get_others(service);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return sets[0];
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}