master-service-settings.c revision 4307c886579381dbb1897ea1388ae6978c96f560
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "array.h"
c12c5dbeda9c819648c0a814f436bc66f8963b2eTimo Sirainen#include "abspath.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "istream.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "write-full.h"
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen#include "str.h"
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen#include "eacces-error.h"
50349cd047ca9e7c100cbeb70acfe26672649959Timo Sirainen#include "env-util.h"
bb308de9d25db75528605eb733a418c996d416adTimo Sirainen#include "execv-const.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "settings-parser.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service-private.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service-settings.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stddef.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdlib.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <unistd.h>
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen#include <time.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include <sys/stat.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define DOVECOT_CONFIG_BIN_PATH BINDIR"/doveconf"
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen#define DOVECOT_CONFIG_SOCKET_PATH PKG_RUNDIR"/config"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen#define CONFIG_READ_TIMEOUT_SECS 10
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen#define CONFIG_HANDSHAKE "VERSION\tconfig\t2\t0\n"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#undef DEF
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define DEF(type, name) \
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { type, #name, offsetof(struct master_service_settings, name), NULL }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenstatic bool
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenmaster_service_settings_check(void *_set, pool_t pool, const char **error_r);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainenstatic const struct setting_define master_service_setting_defines[] = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen DEF(SET_STR, log_path),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen DEF(SET_STR, info_log_path),
f5e1d3d6b34ec152aa1ff15c7bd3d3552e9227eaTimo Sirainen DEF(SET_STR, debug_log_path),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen DEF(SET_STR, log_timestamp),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen DEF(SET_STR, syslog_facility),
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen DEF(SET_SIZE, config_cache_size),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen DEF(SET_BOOL, version_ignore),
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen DEF(SET_BOOL, shutdown_clients),
e2bdca8201e4aa1cd31332ffbdd4c6eef9151d5eTimo Sirainen DEF(SET_BOOL, verbose_proctitle),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen SETTING_DEFINE_LIST_END
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainenstatic const struct master_service_settings master_service_default_settings = {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen .log_path = "syslog",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .info_log_path = "",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .debug_log_path = "",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .log_timestamp = DEFAULT_FAILURE_STAMP_FORMAT,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .syslog_facility = "mail",
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen .config_cache_size = 1024*1024,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .version_ignore = FALSE,
e2bdca8201e4aa1cd31332ffbdd4c6eef9151d5eTimo Sirainen .shutdown_clients = TRUE,
e2bdca8201e4aa1cd31332ffbdd4c6eef9151d5eTimo Sirainen .verbose_proctitle = FALSE
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainenconst struct setting_parser_info master_service_setting_parser_info = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .module_name = "master",
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .defines = master_service_setting_defines,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .defaults = &master_service_default_settings,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .type_offset = (size_t)-1,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .struct_size = sizeof(struct master_service_settings),
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen .parent_offset = (size_t)-1,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen .check_func = master_service_settings_check
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen/* <settings checks> */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenstatic bool
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenmaster_service_settings_check(void *_set, pool_t pool ATTR_UNUSED,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen const char **error_r ATTR_UNUSED)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen{
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen struct master_service_settings *set = _set;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (*set->log_path == '\0') {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen /* default to syslog logging */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen set->log_path = "syslog";
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen return TRUE;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen}
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen/* </settings checks> */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void ATTR_NORETURN
e75ff6a1854ee9befb751d14023bd5fa756fbf3bTimo Sirainenmaster_service_exec_config(struct master_service *service,
e75ff6a1854ee9befb751d14023bd5fa756fbf3bTimo Sirainen const struct master_service_settings_input *input)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
e1237f7e7f978e23c86cf51b69742291c316f75cTimo Sirainen const char **conf_argv, *binary_path = service->argv[0];
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen const char *home = NULL, *user = NULL;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen unsigned int i, argv_max_count;
d41ebbd7ae8cfe36a570c644dd7c9c55073fbb20Timo Sirainen
e1237f7e7f978e23c86cf51b69742291c316f75cTimo Sirainen (void)t_binary_abspath(&binary_path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if (!service->keep_environment && !input->preserve_environment) {
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if (input->preserve_home)
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen home = getenv("HOME");
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if (input->preserve_user)
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen user = getenv("USER");
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen master_service_env_clean();
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if (home != NULL)
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen env_put(t_strconcat("HOME=", home, NULL));
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if (user != NULL)
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen env_put(t_strconcat("USER=", user, NULL));
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen }
50349cd047ca9e7c100cbeb70acfe26672649959Timo Sirainen if (input->use_sysexits)
50349cd047ca9e7c100cbeb70acfe26672649959Timo Sirainen env_put("USE_SYSEXITS=1");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* @UNSAFE */
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen i = 0;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen argv_max_count = 9 + (service->argc + 1) + 1;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv = t_new(const char *, argv_max_count);
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = DOVECOT_CONFIG_BIN_PATH;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = "-f";
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = t_strconcat("service=", service->name, NULL);
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = "-c";
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = service->config_path;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen if (input->module != NULL) {
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = "-m";
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = input->module;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen }
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen if (input->parse_full_config)
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = "-p";
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = "-e";
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen conf_argv[i++] = binary_path;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen memcpy(conf_argv+i, service->argv + 1,
d41ebbd7ae8cfe36a570c644dd7c9c55073fbb20Timo Sirainen (service->argc) * sizeof(conf_argv[0]));
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen i += service->argc;
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen
8d173ad4d740a8a1c584328718325feea62201c8Timo Sirainen i_assert(i < argv_max_count);
bb308de9d25db75528605eb733a418c996d416adTimo Sirainen execv_const(conf_argv[0], conf_argv);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainenstatic void
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainenconfig_exec_fallback(struct master_service *service,
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen const struct master_service_settings_input *input)
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen{
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen const char *path;
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen struct stat st;
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen
47fa3865933c9c57da7c6076fa4d7807614ff56dTimo Sirainen if (input->never_exec)
47fa3865933c9c57da7c6076fa4d7807614ff56dTimo Sirainen return;
47fa3865933c9c57da7c6076fa4d7807614ff56dTimo Sirainen
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen path = input->config_path != NULL ? input->config_path :
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen master_service_get_config_path(service);
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen if (stat(path, &st) == 0 &&
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen !S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode)) {
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen /* it's a file, not a socket/pipe */
e75ff6a1854ee9befb751d14023bd5fa756fbf3bTimo Sirainen master_service_exec_config(service, input);
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen }
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen}
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainenmaster_service_open_config(struct master_service *service,
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen const struct master_service_settings_input *input,
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen const char **path_r, const char **error_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen struct stat st;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen const char *path;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen int fd;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen *path_r = path = input->config_path != NULL ? input->config_path :
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen master_service_get_config_path(service);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen if (service->config_fd != -1 && input->config_path == NULL) {
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen /* use the already opened config socket */
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen fd = service->config_fd;
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen service->config_fd = -1;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen return fd;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen }
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen if (service->config_path_is_default && input->config_path == NULL) {
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen /* first try to connect to the default config socket.
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen configuration may contain secrets, so in default config
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen this fails because the socket is 0600. it's useful for
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen developers though. :) */
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen fd = net_connect_unix(DOVECOT_CONFIG_SOCKET_PATH);
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen if (fd >= 0) {
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen *path_r = DOVECOT_CONFIG_SOCKET_PATH;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen net_set_nonblock(fd, FALSE);
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen return fd;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen /* fallback to executing doveconf */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen if (stat(path, &st) < 0) {
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen *error_r = errno == EACCES ? eacces_error_get("stat", path) :
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen t_strdup_printf("stat(%s) failed: %m", path);
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen return -1;
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen }
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen
73fed8af5e20022bdef8620bb074507755ec2c5eTimo Sirainen if (!S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode)) {
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen /* it's not an UNIX socket, don't even try to connect */
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen fd = -1;
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen errno = ENOTSOCK;
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen } else {
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen fd = net_connect_unix_with_retries(path, 1000);
5ea5c79ca3f6012095bd5e9b2251e6dd5f614a8dTimo Sirainen }
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen if (fd < 0) {
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen *error_r = t_strdup_printf("net_connect_unix(%s) failed: %m",
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen path);
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen config_exec_fallback(service, input);
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen return -1;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen }
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen net_set_nonblock(fd, FALSE);
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen return fd;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen}
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainenstatic void
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainenconfig_build_request(string_t *str,
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen const struct master_service_settings_input *input)
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen{
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_append(str, "REQ");
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (input->module != NULL)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_printfa(str, "\tmodule=%s", input->module);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (input->service != NULL)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_printfa(str, "\tservice=%s", input->service);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (input->username != NULL)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_printfa(str, "\tuser=%s", input->username);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (input->local_ip.family != 0)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_printfa(str, "\tlip=%s", net_ip2addr(&input->local_ip));
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (input->remote_ip.family != 0)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_printfa(str, "\trip=%s", net_ip2addr(&input->remote_ip));
41942258112e4131de96b6a4399c1a8ac83a23cbTimo Sirainen if (input->local_name != NULL)
41942258112e4131de96b6a4399c1a8ac83a23cbTimo Sirainen str_printfa(str, "\tlname=%s", input->local_name);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_append_c(str, '\n');
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen}
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainenstatic int
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainenconfig_send_request(const struct master_service_settings_input *input,
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen int fd, const char *path, const char **error_r)
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen{
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen int ret;
b8efab7ea8876c0a33a73ee0d08eddada31320f8Timo Sirainen
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen T_BEGIN {
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen string_t *str;
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen str = t_str_new(128);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen str_append(str, CONFIG_HANDSHAKE);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen config_build_request(str, input);
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen ret = write_full(fd, str_data(str), str_len(str));
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen } T_END;
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen if (ret < 0) {
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen *error_r = t_strdup_printf("write_full(%s) failed: %m", path);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen return 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenstatic int
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenmaster_service_apply_config_overrides(struct master_service *service,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen struct setting_parser_context *parser,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const char **error_r)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen{
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const char *const *overrides;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen unsigned int i, count;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen overrides = array_get(&service->config_overrides, &count);
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen for (i = 0; i < count; i++) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (settings_parse_line(parser, overrides[i]) < 0) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen *error_r = t_strdup_printf(
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen "Invalid -o parameter %s: %s", overrides[i],
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen settings_parser_get_error(parser));
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen return -1;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen }
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen settings_parse_set_key_expandeded(parser, service->set_pool,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen t_strcut(overrides[i], '='));
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen }
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen return 0;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen}
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstatic int
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainenconfig_read_reply_header(struct istream *istream, const char *path, pool_t pool,
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen const struct master_service_settings_input *input,
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen struct master_service_settings_output *output_r,
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen const char **error_r)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen{
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const char *line;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ssize_t ret;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen while ((ret = i_stream_read(istream)) > 0) {
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen line = i_stream_next_line(istream);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (line != NULL)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen break;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen if (ret <= 0) {
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen if (ret == 0)
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen return 1;
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen *error_r = istream->stream_errno != 0 ?
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen t_strdup_printf("read(%s) failed: %m", path) :
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen t_strdup_printf("read(%s) failed: EOF", path);
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen return -1;
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen T_BEGIN {
3c296d819c54e21ce05c3d2eeeedc79be42ac593Timo Sirainen const char *const *arg = t_strsplit_tab(line);
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen ARRAY_TYPE(const_string) services;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen p_array_init(&services, pool, 8);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen for (; *arg != NULL; arg++) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (strcmp(*arg, "service-uses-local") == 0)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen output_r->service_uses_local = TRUE;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen else if (strcmp(*arg, "service-uses-remote") == 0)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen output_r->service_uses_remote = TRUE;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (strcmp(*arg, "used-local") == 0)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen output_r->used_local = TRUE;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen else if (strcmp(*arg, "used-remote") == 0)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen output_r->used_remote = TRUE;
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen else if (strncmp(*arg, "service=", 8) == 0) {
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen const char *name = p_strdup(pool, *arg + 8);
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen array_append(&services, &name, 1);
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen }
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen }
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen if (input->service == NULL) {
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&services);
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen output_r->specific_services = array_idx(&services, 0);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen } T_END;
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen return 0;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen}
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint master_service_settings_read(struct master_service *service,
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen const struct master_service_settings_input *input,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_output *output_r,
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ARRAY_DEFINE(all_roots, const struct setting_parser_info *);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct setting_parser_info *tmp_root;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct setting_parser_context *parser;
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen struct istream *istream;
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen const char *path = NULL, *error;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen void **sets;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret, fd = -1;
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen time_t now, timeout;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen memset(output_r, 0, sizeof(*output_r));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen if (getenv("DOVECONF_ENV") == NULL &&
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) {
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen fd = master_service_open_config(service, input, &path, error_r);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return -1;
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen if (config_send_request(input, fd, path, error_r) < 0) {
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen i_close_fd(&fd);
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen config_exec_fallback(service, input);
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen return -1;
a03b4fe1a887d187d0dbcd961e9d5127f7c5bf2aTimo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen if (service->set_pool != NULL) {
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen if (service->set_parser != NULL)
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen settings_parser_deinit(&service->set_parser);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p_clear(service->set_pool);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen } else {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen service->set_pool =
e774b2f08b0909382ddc3d2869ae7e3b97205184Timo Sirainen pool_alloconly_create("master service settings", 8192);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p_array_init(&all_roots, service->set_pool, 8);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen tmp_root = &master_service_setting_parser_info;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen array_append(&all_roots, &tmp_root, 1);
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen if (input->roots != NULL) {
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen for (i = 0; input->roots[i] != NULL; i++)
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen array_append(&all_roots, &input->roots[i], 1);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen parser = settings_parser_init_list(service->set_pool,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen array_idx(&all_roots, 0), array_count(&all_roots),
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (fd != -1) {
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen istream = i_stream_create_fd(fd, (size_t)-1, FALSE);
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen now = time(NULL);
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen timeout = now + CONFIG_READ_TIMEOUT_SECS;
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen do {
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen alarm(timeout - now);
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen ret = config_read_reply_header(istream, path,
194755bdfb97c07ca8b9df071099f68947b971e3Timo Sirainen service->set_pool, input,
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen output_r, error_r);
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen if (ret == 0) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ret = settings_parse_stream_read(parser,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen istream);
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen if (ret < 0)
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen *error_r = settings_parser_get_error(parser);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen alarm(0);
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen if (ret <= 0)
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen break;
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen /* most likely timed out, but just in case some other
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen signal was delivered early check if we need to
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen continue */
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen now = time(NULL);
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen } while (now < timeout);
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen i_stream_unref(&istream);
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen
27ca0e561c70933da8834e57f967dee9b41896baTimo Sirainen if (ret != 0) {
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen if (ret > 0) {
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen *error_r = t_strdup_printf(
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen "Timeout reading config from %s", path);
a7a316bc6cbd7c89bf01ac091a2e9fc2d514f1a0Timo Sirainen }
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen i_close_fd(&fd);
4a7863c531a27498830004ca2ead2eb53812ed79Timo Sirainen config_exec_fallback(service, input);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return -1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen if ((service->flags & MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN) != 0 &&
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen service->config_fd == -1 && input->config_path == NULL)
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen service->config_fd = fd;
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen else
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen i_close_fd(&fd);
a88696bd63b2ce0f7b02ee3352e4bf739497352aTimo Sirainen }
a88696bd63b2ce0f7b02ee3352e4bf739497352aTimo Sirainen
a88696bd63b2ce0f7b02ee3352e4bf739497352aTimo Sirainen if (fd == -1 || service->keep_environment) {
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen if (settings_parse_environ(parser) < 0) {
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen *error_r = settings_parser_get_error(parser);
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen return -1;
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen }
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (array_is_created(&service->config_overrides)) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (master_service_apply_config_overrides(service, parser,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen error_r) < 0)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen return -1;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen }
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen
8c4b2e0734326ef8e534f25e8ee78ace1fc22d15Timo Sirainen if (!settings_parser_check(parser, service->set_pool, &error)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("Invalid settings: %s", error);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sets = settings_parser_get_list(parser);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen service->set = sets[0];
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen service->set_parser = parser;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (service->set->version_ignore &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* running standalone. we want to ignore plugin versions. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen service->version_string = NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (service->set->shutdown_clients)
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen master_service_set_die_with_master(master_service, TRUE);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* if we change any settings afterwards, they're in expanded form.
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen especially all settings from userdb are already expanded. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen settings_parse_set_expanded(service->set_parser, TRUE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainenint master_service_settings_read_simple(struct master_service *service,
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen const struct setting_parser_info **roots,
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen const char **error_r)
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen{
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen struct master_service_settings_input input;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_output output;
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen memset(&input, 0, sizeof(input));
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen input.roots = roots;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen input.module = service->name;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen return master_service_settings_read(service, &input, &output, error_r);
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen}
44aac2d461b4cb8e05e8c07f2f209372997a8719Timo Sirainen
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainenpool_t master_service_settings_detach(struct master_service *service)
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen{
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen pool_t pool = service->set_pool;
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen settings_parser_deinit(&service->set_parser);
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen service->set_pool = NULL;
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen return pool;
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen}
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst struct master_service_settings *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaster_service_settings_get(struct master_service *service)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen void **sets;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sets = settings_parser_get_list(service->set_parser);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return sets[0];
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid **master_service_settings_get_others(struct master_service *service)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return settings_parser_get_list(service->set_parser) + 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainenstruct setting_parser_context *
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainenmaster_service_get_settings_parser(struct master_service *service)
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainen{
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainen return service->set_parser;
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainen}
35d87d75ac84ac6aee86c3a1b0dccf627b21457fTimo Sirainen
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainenint master_service_set(struct master_service *service, const char *line)
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen{
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen return settings_parse_line(service->set_parser, line);
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen}
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainenbool master_service_set_has_config_override(struct master_service *service,
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen const char *key)
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen{
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen const char *const *override, *key_root;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen bool ret;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen if (!array_is_created(&service->config_overrides))
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen return FALSE;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen key_root = settings_parse_unalias(service->set_parser, key);
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen if (key_root == NULL)
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen key_root = key;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen array_foreach(&service->config_overrides, override) {
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen T_BEGIN {
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen const char *okey, *okey_root;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen okey = t_strcut(*override, '=');
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen okey_root = settings_parse_unalias(service->set_parser,
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen okey);
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen if (okey_root == NULL)
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen okey_root = okey;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen ret = strcmp(okey_root, key_root) == 0;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen } T_END;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen if (ret)
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen return TRUE;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen }
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen return FALSE;
61f45f55439e542d8645d1851cb56ffc36cd10f6Timo Sirainen}