From: Timo Sirainen Date: Tue, 29 Nov 2022 18:48:44 +0000 (+0200) Subject: lib-master: Execute doveconf with -F parameter as the config fallback X-Git-Tag: 2.4.0~3082 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9280367fdb767d9248dd9a3713519ee3cdad6b3f;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Execute doveconf with -F parameter as the config fallback This changes settings to be read via a fd instead of environment. As a side effect, this fixes a bug where if the settings output was larger than 128 kB in Linux, exec() would fail with "Argument list too long". lib-master preserves support for reading settings from environment for a few more commits, because the log process uses it to read its settings. --- diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index c78013e964..6772c4ed5f 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -210,35 +210,10 @@ master_service_exec_config(struct master_service *service, t_array_init(&conf_argv, 11 + (service->argc + 1) + 1); strarr_push(&conf_argv, DOVECOT_CONFIG_BIN_PATH); - if (input->service != NULL) { - strarr_push(&conf_argv, "-f"); - strarr_push(&conf_argv, - t_strconcat("service=", input->service, NULL)); - } strarr_push(&conf_argv, "-c"); strarr_push(&conf_argv, service->config_path); - if (input->module != NULL) { - strarr_push(&conf_argv, "-m"); - strarr_push(&conf_argv, input->module); - } - if (input->extra_modules != NULL) { - for (unsigned int i = 0; input->extra_modules[i] != NULL; i++) { - strarr_push(&conf_argv, "-m"); - strarr_push(&conf_argv, input->extra_modules[i]); - } - } - if ((service->flags & MASTER_SERVICE_FLAG_DISABLE_SSL_SET) == 0 && - (input->module != NULL || input->extra_modules != NULL)) { - strarr_push(&conf_argv, "-m"); - if (service->want_ssl_server) - strarr_push(&conf_argv, "ssl-server"); - else - strarr_push(&conf_argv, "ssl"); - } - if (input->parse_full_config) - strarr_push(&conf_argv, "-p"); - strarr_push(&conf_argv, "-e"); + strarr_push(&conf_argv, "-F"); strarr_push(&conf_argv, binary_path); array_append(&conf_argv, (const char *const *)service->argv + 1, service->argc); @@ -405,6 +380,7 @@ void master_service_config_socket_try_open(struct master_service *service) ignore it later on. (unfortunately there isn't a master_service_*() call where this function would be better called.) */ if (getenv("DOVECONF_ENV") != NULL || + getenv(DOVECOT_CONFIG_FD_ENV) != NULL || (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) != 0) return; @@ -521,15 +497,25 @@ int master_service_settings_read(struct master_service *service, const struct setting_parser_info *tmp_root; struct setting_parser_context *parser; struct istream *istream; - const char *path = NULL, *error; + const char *path = NULL, *value, *error; unsigned int i; int ret, fd = -1; - bool use_environment, retry; + bool use_environment = FALSE, retry; i_zero(output_r); - if (getenv("DOVECONF_ENV") == NULL && - (service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) { + value = getenv(DOVECOT_CONFIG_FD_ENV); + if (value != NULL) { + /* doveconf -F parameter already executed us back. + The configuration is in DOVECOT_CONFIG_FD. */ + if (str_to_int(value, &fd) < 0 || fd < 0) + i_fatal("Invalid "DOVECOT_CONFIG_FD_ENV": %s", value); + } else if (getenv("DOVECONF_ENV") != NULL) { + use_environment = (service->flags & + MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0; + } else if ((service->flags & MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0) { + /* Open config via socket if possible. If it doesn't work, + execute doveconf -F. */ retry = service->config_fd != -1; for (;;) { fd = master_service_open_config(service, input, @@ -596,6 +582,10 @@ int master_service_settings_read(struct master_service *service, i_stream_unref(&istream); if (ret < 0) { + if (getenv(DOVECOT_CONFIG_FD_ENV) != NULL) { + i_fatal("Failed to read config from fd %d: %s", + fd, *error_r); + } i_close_fd(&fd); config_exec_fallback(service, input, error_r); settings_parser_unref(&parser); @@ -604,14 +594,12 @@ int master_service_settings_read(struct master_service *service, } if ((service->flags & MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN) != 0 && - service->config_fd == -1 && input->config_path == NULL) + service->config_fd == -1 && input->config_path == NULL && + getenv(DOVECOT_CONFIG_FD_ENV) == NULL) service->config_fd = fd; else i_close_fd(&fd); - use_environment = FALSE; - } else { - use_environment = (service->flags & - MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS) == 0; + env_remove(DOVECOT_CONFIG_FD_ENV); } event_unref(&event);