summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-04-23 22:41:57 +0200
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-06-24 21:46:58 +0200
commit28d2eab1414ef8d20ff0fde7026aa52fd01ef795 (patch)
treee31bc611e35e65da1acecbbf069aa442af8a5725
parent060cf1e3c9a0a6960b771cdff6f0a5a2ca9b114c (diff)
downloadexim4-28d2eab1414ef8d20ff0fde7026aa52fd01ef795.tar.gz
Do not close the (main)_log, if we do not see a chance to open it again.
The process doing local deliveries runs as an unprivileged user. If this process needs to log failures or warnings (as caused by the is_tainting2() function), it can't re-open the main_log and just exits. (cherry picked from commit 235c7030ee9ee1c1aad507786506a470b580bfe2)
-rw-r--r--src/src/log.c84
-rw-r--r--src/src/transports/appendfile.c11
2 files changed, 52 insertions, 43 deletions
diff --git a/src/src/log.c b/src/src/log.c
index f1051234a..90373adf0 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -701,18 +701,36 @@ return total_written;
}
-
-static void
-set_file_path(void)
+void
+set_file_path(BOOL *multiple)
{
+uschar *s;
int sep = ':'; /* Fixed separator - outside use */
-uschar *t;
-const uschar *tt = US LOG_FILE_PATH;
-while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE)))
+uschar *ss = *log_file_path ? log_file_path : LOG_FILE_PATH;
+
+logging_mode = 0;
+while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE)))
{
- if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue;
- file_path = string_copy(t);
- break;
+ if (Ustrcmp(s, "syslog") == 0)
+ logging_mode |= LOG_MODE_SYSLOG;
+ else if (logging_mode & LOG_MODE_FILE) /* we know a file already */
+ {
+ if (multiple) *multiple = TRUE;
+ }
+ else
+ {
+ logging_mode |= LOG_MODE_FILE;
+
+ /* If a non-empty path is given, use it */
+
+ if (*s)
+ file_path = string_copy(s);
+
+ /* If the path is empty, we want to use the first non-empty, non-
+ syslog item in LOG_FILE_PATH, if there is one, since the value of
+ log_file_path may have been set at runtime. If there is no such item,
+ use the ultimate default in the spool directory. */
+ }
}
}
@@ -720,7 +738,11 @@ while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE)))
void
mainlog_close(void)
{
-if (mainlogfd < 0) return;
+/* avoid closing it if it is closed already or if we do not see a chance
+to open the file mainlog later again */
+if (mainlogfd < 0 /* already closed */
+ || !(geteuid() == 0 || geteuid() == exim_uid))
+ return;
(void)close(mainlogfd);
mainlogfd = -1;
mainlog_inode = 0;
@@ -835,38 +857,7 @@ if (!path_inspected)
/* If nothing has been set, don't waste effort... the default values for the
statics are file_path="" and logging_mode = LOG_MODE_FILE. */
- if (*log_file_path)
- {
- int sep = ':'; /* Fixed separator - outside use */
- uschar *s;
- const uschar *ss = log_file_path;
-
- logging_mode = 0;
- while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE)))
- {
- if (Ustrcmp(s, "syslog") == 0)
- logging_mode |= LOG_MODE_SYSLOG;
- else if (logging_mode & LOG_MODE_FILE)
- multiple = TRUE;
- else
- {
- logging_mode |= LOG_MODE_FILE;
-
- /* If a non-empty path is given, use it */
-
- if (*s)
- file_path = string_copy(s);
-
- /* If the path is empty, we want to use the first non-empty, non-
- syslog item in LOG_FILE_PATH, if there is one, since the value of
- log_file_path may have been set at runtime. If there is no such item,
- use the ultimate default in the spool directory. */
-
- else
- set_file_path(); /* Empty item in log_file_path */
- } /* First non-syslog item in log_file_path */
- } /* Scan of log_file_path */
- }
+ if (*log_file_path) set_file_path(&multiple);
/* If no modes have been selected, it is a major disaster */
@@ -1484,7 +1475,7 @@ if (opts)
resulting in certain setup not having been done. Hack this for now so we
do not segfault; note that nondefault log locations will not work */
-if (!*file_path) set_file_path();
+if (!*file_path) set_file_path(NULL);
open_log(&fd, lt_debug, tag_name);
@@ -1506,5 +1497,12 @@ debug_file = NULL;
unlink_log(lt_debug);
}
+void
+open_logs(const char *m)
+{
+set_file_path(NULL);
+open_log(&mainlogfd, lt_main, 0);
+open_log(&rejectlogfd, lt_reject, 0);
+}
/* End of log.c */
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 139f9a3ef..da2618790 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -174,6 +174,9 @@ Arguments:
Returns: OK, FAIL, or DEFER
*/
+void
+openlogs();
+
static int
appendfile_transport_setup(transport_instance *tblock, address_item *addrlist,
transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg)
@@ -183,6 +186,14 @@ appendfile_transport_options_block *ob =
uschar *q = ob->quota;
double default_value = 0.0;
+addrlist = addrlist; /* Keep picky compilers happy */
+dummy = dummy;
+uid = uid;
+gid = gid;
+
+/* we can't wait until we're not privileged anymore */
+open_logs("appendfile");
+
if (ob->expand_maildir_use_size_file)
ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file,
US"`maildir_use_size_file` in transport", tblock->name);