From 3de973a29de6852d61ba9bf1845835d08ca5a5ab Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Wed, 2 Mar 2016 22:07:45 +0100 Subject: [PATCH] Delay chdir(/) until we opened the main config --- doc/doc-docbook/spec.xfpt | 2 -- src/src/exim.c | 13 ++++++------- src/src/readconf.c | 17 +++++++++-------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 799104ec4..c61d7a2e8 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -3487,8 +3487,6 @@ name, but it can be a colon-separated list of names. In this case, the first file that exists is used. Failure to open an existing file stops Exim from proceeding any further along the list, and an error is generated. -The file names need to be absolute names. - When this option is used by a caller other than root, and the list is different from the compiled-in list, Exim gives up its root privilege immediately, and runs with the real and effective uid and gid set to those of the caller. diff --git a/src/src/exim.c b/src/src/exim.c index d6f2d4aac..02fda6756 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -3741,17 +3741,16 @@ if (running_in_test_harness) smtputf8_advertise_hosts = NULL; /* Read the main runtime configuration data; this gives up if there is a failure. It leaves the configuration file open so that the subsequent -configuration data for delivery can be read if needed. */ +configuration data for delivery can be read if needed. -/* To be safe: change the working directory to /. */ -if (Uchdir("/") < 0) - { - perror("exim: chdir `/': "); - exit(EXIT_FAILURE); - } +NOTE: immediatly after opening the configuration file we change the working +directory to "/"! Later we change to $spool_directory. We do it there, because +during readconf_main() some expansion takes place already. */ readconf_main(); +/* Now in directory "/" */ + if (cleanup_environment() == FALSE) log_write(0, LOG_PANIC_DIE, "Can't cleanup environment"); diff --git a/src/src/readconf.c b/src/src/readconf.c index 3654f19d1..1119651f0 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -3049,14 +3049,6 @@ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) != NULL) { - /* To avoid confusion: Exim changes to / at the very beginning and - * and to $spool_directory later. */ - if (filename[0] != '/') - { - fprintf(stderr, "-C %s: only absolute names are allowed\n", filename); - exit(EXIT_FAILURE); - } - /* Cut out all the fancy processing unless specifically wanted */ #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID) @@ -3110,6 +3102,15 @@ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) if (config_file != NULL || errno != ENOENT) break; } +/* Now, once we found and opened our configuration file, we change the directory +to a safe place. Later we change to $spool_directory. */ + +if (Uchdir("/") < 0) + { + perror("exim: chdir `/': "); + exit(EXIT_FAILURE); + } + /* On success, save the name for verification; config_filename is used when logging configuration errors (it changes for .included files) whereas config_main_filename is the name shown by -bP. Failure to open a configuration -- 2.25.1