summaryrefslogtreecommitdiffstats
path: root/debian/patches/75_23-Do-not-close-the-main-_log-if-we-do-not-see-a-chance.patch
blob: 12d91633c4bb9467c639540110366d51aff01182 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
From 235c7030ee9ee1c1aad507786506a470b580bfe2 Mon Sep 17 00:00:00 2001
From: "Heiko Schlittermann (HS12-RIPE)" <hs@schlittermann.de>
Date: Fri, 23 Apr 2021 22:41:57 +0200
Subject: [PATCH 23/23] 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.
---
 src/log.c                   | 84 ++++++++++++++++-----------------
 src/transports/appendfile.c |  6 +++
 2 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/src/log.c b/src/log.c
index 7ef7074ec..c2ef698e7 100644
--- a/src/log.c
+++ b/src/log.c
@@ -646,18 +646,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. */
+    }
   }
 }
 
@@ -665,7 +683,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;
@@ -780,38 +802,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 */
 
@@ -1431,7 +1422,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);
 
@@ -1453,5 +1444,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/transports/appendfile.c b/src/transports/appendfile.c
index 6772b338b..706af6dde 100644
--- a/src/transports/appendfile.c
+++ b/src/transports/appendfile.c
@@ -217,6 +217,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)
@@ -231,6 +234,9 @@ 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);
-- 
2.30.2