Prereq: "3.3.0"
diff -ur --new-file /var/tmp/postfix-3.3.0/src/global/mail_version.h ./src/global/mail_version.h
--- /var/tmp/postfix-3.3.0/src/global/mail_version.h 2018-02-21 19:17:21.000000000 -0500
+++ ./src/global/mail_version.h 2018-05-19 16:14:35.000000000 -0400
@@ -20,8 +20,8 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20180221"
-#define MAIL_VERSION_NUMBER "3.3.0"
+#define MAIL_RELEASE_DATE "20180519"
+#define MAIL_VERSION_NUMBER "3.3.1"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
diff -ur --new-file /var/tmp/postfix-3.3.0/HISTORY ./HISTORY
--- /var/tmp/postfix-3.3.0/HISTORY 2018-02-19 11:29:00.000000000 -0500
+++ ./HISTORY 2018-05-19 16:13:44.000000000 -0400
@@ -23334,3 +23334,33 @@
built-in or service-defined parameters for ldap, *sql, etc.
database names. Problem reported by Christian Rößner. Files:
postconf/postconf_user.c.
+
+20180306
+
+ Bugfix (introduced: 19990302): when luser_relay specifies
+ a non-existent local address, the luser_relay feature becomes
+ a black hole. Reported by Jørgen Thomsen. File: local/unknown.c.
+
+20180422
+
+ Bugfix (introduced: Postfix 2.8): missing tls_server_start()
+ error propagation in tlsproxy(8) resulting in segfault after
+ TLS handshake error. Found during code maintenance. File:
+ tlsproxy/tlsproxy.c.
+
+20180509
+
+ Bugfix (introduced: 20170617): postconf(1) command segfault
+ if unable to open a Postfix database configuration file due
+ to a file permission error. Report by Andreas Hasenack, fix
+ by Viktor Dukhovni. File: postconf/postconf_dbms.c.
+
+20180519
+
+ Cleanup: Postfix did not support running as a PID=1 process,
+ which complicated Postfix management in containers. The
+ "postfix start-fg" command will now run the Postfix master
+ daemon as a PID=1 process if possible. Thanks to inputs
+ from Andreas Schulze, Eray Aslan, and Viktor Dukhovni.
+ Files: postfix/postfix.c, master/master.c, master/master.h,
+ master/master_sig.c, conf/postfix-script.
diff -ur --new-file /var/tmp/postfix-3.3.0/conf/postfix-script ./conf/postfix-script
--- /var/tmp/postfix-3.3.0/conf/postfix-script 2017-12-27 17:30:27.000000000 -0500
+++ ./conf/postfix-script 2018-05-19 10:17:23.000000000 -0400
@@ -150,11 +150,16 @@
;;
start-fg)
# Foreground start-up is incompatible with multi-instance mode.
- # We can't use "exec $daemon_directory/master" here: that would
- # break process group management, and "postfix stop" would kill
- # too many processes.
+ # Use "exec $daemon_directory/master" only if PID == 1.
+ # Otherwise, doing so would break process group management,
+ # and "postfix stop" would kill too many processes.
case $instances in
- "") $daemon_directory/master
+ "") case $$ in
+ 1) exec $daemon_directory/master -i
+ $FATAL "cannot start-fg the master daemon"
+ exit 1;;
+ *) $daemon_directory/master;;
+ esac
;;
*) $FATAL "start-fg does not support multi_instance_directories"
exit 1
diff -ur --new-file /var/tmp/postfix-3.3.0/html/master.8.html ./html/master.8.html
--- /var/tmp/postfix-3.3.0/html/master.8.html 2018-01-14 11:48:37.000000000 -0500
+++ ./html/master.8.html 2018-05-19 15:48:33.000000000 -0400
@@ -10,7 +10,7 @@
master - Postfix master process
SYNOPSIS
- master [-Ddtvw] [-c config_dir] [-e exit_time]
+ master [-Dditvw] [-c config_dir] [-e exit_time]
DESCRIPTION
The master(8) daemon is the resident process that runs Postfix daemons
@@ -47,6 +47,11 @@
Terminate the master process after exit_time seconds. Child pro-
cesses terminate at their convenience.
+ -i Enable init mode: do not attempt to become a session or process
+ group leader; and to force termination, set an explicit signal
+ handler instead of relying on the default signal action. This
+ mode is allowed only if the process ID equals 1.
+
-t Test mode. Return a zero exit status when the master.pid lock
file does not exist or when that file is not locked. This is
evidence that the master(8) daemon is not running.
diff -ur --new-file /var/tmp/postfix-3.3.0/html/postfix.1.html ./html/postfix.1.html
--- /var/tmp/postfix-3.3.0/html/postfix.1.html 2018-02-11 10:17:59.000000000 -0500
+++ ./html/postfix.1.html 2018-05-19 15:47:30.000000000 -0400
@@ -37,13 +37,14 @@
check described above.
start-fg
- Like start, but keep the master daemon running in the fore-
- ground. This requires that multi-instance support is disabled
- (i.e. the multi_instance_directories parameter value must be
- empty). When running Postfix inside a container, mount the con-
- tainer host's /dev/log socket inside the container (example:
- "docker run -v /dev/log:/dev/log ...") and specify a distinct
- Postfix "syslog_name" prefix that identifies logging from the
+ Like start, but keep the master(8) daemon running in the fore-
+ ground, and enable master(8) "init" mode when running as PID 1.
+ This command requires that multi-instance support is disabled
+ (i.e. the multi_instance_directories parameter value must be
+ empty). When running Postfix inside a container, mount the con-
+ tainer host's /dev/log socket inside the container (example:
+ "docker run -v /dev/log:/dev/log ...") and specify a distinct
+ Postfix "syslog_name" prefix that identifies logging from the
Postfix instance.
stop Stop the Postfix mail system in an orderly fashion. If possible,
diff -ur --new-file /var/tmp/postfix-3.3.0/man/man1/postfix.1 ./man/man1/postfix.1
--- /var/tmp/postfix-3.3.0/man/man1/postfix.1 2018-02-11 10:17:59.000000000 -0500
+++ ./man/man1/postfix.1 2018-05-19 15:45:33.000000000 -0400
@@ -38,8 +38,10 @@
Start the Postfix mail system. This also runs the configuration
check described above.
.IP \fBstart\-fg\fR
-Like \fBstart\fR, but keep the master daemon running in the
-foreground. This requires that multi\-instance support is
+Like \fBstart\fR, but keep the \fBmaster\fR(8) daemon running
+in the foreground, and enable \fBmaster\fR(8) "init" mode
+when running as PID 1.
+This command requires that multi\-instance support is
disabled (i.e. the multi_instance_directories parameter
value must be empty). When running Postfix inside a container,
mount the container host's /dev/log socket inside the
diff -ur --new-file /var/tmp/postfix-3.3.0/man/man8/master.8 ./man/man8/master.8
--- /var/tmp/postfix-3.3.0/man/man8/master.8 2018-01-14 11:48:35.000000000 -0500
+++ ./man/man8/master.8 2018-05-19 15:45:33.000000000 -0400
@@ -8,7 +8,7 @@
.SH "SYNOPSIS"
.na
.nf
-\fBmaster\fR [\fB\-Ddtvw\fR] [\fB\-c \fIconfig_dir\fR] [\fB\-e \fIexit_time\fR]
+\fBmaster\fR [\fB\-Dditvw\fR] [\fB\-c \fIconfig_dir\fR] [\fB\-e \fIexit_time\fR]
.SH DESCRIPTION
.ad
.fi
@@ -43,6 +43,12 @@
.IP "\fB\-e \fIexit_time\fR"
Terminate the master process after \fIexit_time\fR seconds. Child
processes terminate at their convenience.
+.IP \fB\-i\fR
+Enable \fBinit\fR mode: do not attempt to become a session
+or process group leader; and to force termination, set an
+explicit signal handler instead of relying on the default
+signal action. This mode is allowed only if the process ID
+equals 1.
.IP \fB\-t\fR
Test mode. Return a zero exit status when the \fBmaster.pid\fR lock
file does not exist or when that file is not locked. This is evidence
diff -ur --new-file /var/tmp/postfix-3.3.0/src/local/unknown.c ./src/local/unknown.c
--- /var/tmp/postfix-3.3.0/src/local/unknown.c 2015-01-11 15:30:20.000000000 -0500
+++ ./src/local/unknown.c 2018-03-06 19:29:36.000000000 -0500
@@ -73,11 +73,14 @@
#include
#include
#include
+#include
/* Application-specific. */
#include "local.h"
+#define STREQ(x,y) (strcasecmp((x),(y)) == 0)
+
/* deliver_unknown - delivery for unknown recipients */
int deliver_unknown(LOCAL_STATE state, USER_ATTR usr_attr)
@@ -85,6 +88,7 @@
const char *myname = "deliver_unknown";
int status;
VSTRING *expand_luser;
+ VSTRING *canon_luser;
static MAPS *transp_maps;
const char *map_transport;
@@ -139,8 +143,20 @@
if (*var_luser_relay) {
state.msg_attr.unmatched = 0;
expand_luser = vstring_alloc(100);
+ canon_luser = vstring_alloc(100);
local_expand(expand_luser, var_luser_relay, &state, &usr_attr, (void *) 0);
- status = deliver_resolve_addr(state, usr_attr, STR(expand_luser));
+ /* In case luser_relay specifies a domain-less address. */
+ canon_addr_external(canon_luser, vstring_str(expand_luser));
+ /* Assumes that the address resolver won't change the address. */
+ if (STREQ(vstring_str(canon_luser), state.msg_attr.rcpt.address)) {
+ dsb_simple(state.msg_attr.why, "5.1.1",
+ "unknown user: \"%s\"", state.msg_attr.user);
+ status = bounce_append(BOUNCE_FLAGS(state.request),
+ BOUNCE_ATTR(state.msg_attr));
+ } else {
+ status = deliver_resolve_addr(state, usr_attr, STR(expand_luser));
+ }
+ vstring_free(canon_luser);
vstring_free(expand_luser);
return (status);
}
@@ -149,8 +165,6 @@
* If no alias was found for a required reserved name, toss the message
* into the bit bucket, and issue a warning instead.
*/
-#define STREQ(x,y) (strcasecmp(x,y) == 0)
-
if (STREQ(state.msg_attr.user, MAIL_ADDR_MAIL_DAEMON)
|| STREQ(state.msg_attr.user, MAIL_ADDR_POSTMASTER)) {
msg_warn("required alias not found: %s", state.msg_attr.user);
diff -ur --new-file /var/tmp/postfix-3.3.0/src/master/master.c ./src/master/master.c
--- /var/tmp/postfix-3.3.0/src/master/master.c 2018-01-14 11:48:25.000000000 -0500
+++ ./src/master/master.c 2018-05-19 15:16:11.000000000 -0400
@@ -4,7 +4,7 @@
/* SUMMARY
/* Postfix master process
/* SYNOPSIS
-/* \fBmaster\fR [\fB-Ddtvw\fR] [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR]
+/* \fBmaster\fR [\fB-Dditvw\fR] [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR]
/* DESCRIPTION
/* The \fBmaster\fR(8) daemon is the resident process that runs Postfix
/* daemons on demand: daemons to send or receive messages via the
@@ -37,6 +37,12 @@
/* .IP "\fB-e \fIexit_time\fR"
/* Terminate the master process after \fIexit_time\fR seconds. Child
/* processes terminate at their convenience.
+/* .IP \fB-i\fR
+/* Enable \fBinit\fR mode: do not attempt to become a session
+/* or process group leader; and to force termination, set an
+/* explicit signal handler instead of relying on the default
+/* signal action. This mode is allowed only if the process ID
+/* equals 1.
/* .IP \fB-t\fR
/* Test mode. Return a zero exit status when the \fBmaster.pid\fR lock
/* file does not exist or when that file is not locked. This is evidence
@@ -229,6 +235,7 @@
#include "master.h"
int master_detach = 1;
+int init_mode = 0;
/* master_exit_event - exit for memory leak testing purposes */
@@ -334,7 +341,7 @@
/*
* Process JCL.
*/
- while ((ch = GETOPT(argc, argv, "c:Dde:tvw")) > 0) {
+ while ((ch = GETOPT(argc, argv, "c:Dde:itvw")) > 0) {
switch (ch) {
case 'c':
if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
@@ -346,6 +353,11 @@
case 'e':
event_request_timer(master_exit_event, (void *) 0, atoi(optarg));
break;
+ case 'i':
+ if (getpid() != 1)
+ msg_fatal("-i is allowed only for PID 1 process");
+ init_mode = 1;
+ break;
case 'D':
debug_me = 1;
break;
@@ -375,6 +387,8 @@
*/
if (test_lock && wait_flag)
msg_fatal("the -t and -w options cannot be used together");
+ if (init_mode && (debug_me || !master_detach || wait_flag))
+ msg_fatal("the -i option cannot be used with -D, -d, or -w");
/*
* Run a foreground monitor process that returns an exit status of 0 when
@@ -403,7 +417,8 @@
* all MTA processes cleanly. Give up if we can't separate from our
* parent process. We're not supposed to blow away the parent.
*/
- if (debug_me == 0 && master_detach != 0 && setsid() == -1 && getsid(0) != getpid())
+ if (init_mode == 0 && debug_me == 0 && master_detach != 0
+ && setsid() == -1 && getsid(0) != getpid())
msg_fatal("unable to set session and process group ID: %m");
/*
diff -ur --new-file /var/tmp/postfix-3.3.0/src/master/master.h ./src/master/master.h
--- /var/tmp/postfix-3.3.0/src/master/master.h 2012-03-06 17:06:35.000000000 -0500
+++ ./src/master/master.h 2018-04-04 18:59:07.000000000 -0400
@@ -109,6 +109,7 @@
* master.c
*/
extern int master_detach;
+extern int init_mode;
/*
* master_ent.c
diff -ur --new-file /var/tmp/postfix-3.3.0/src/master/master_sig.c ./src/master/master_sig.c
--- /var/tmp/postfix-3.3.0/src/master/master_sig.c 2014-12-06 20:35:33.000000000 -0500
+++ ./src/master/master_sig.c 2018-05-19 10:47:08.000000000 -0400
@@ -200,6 +200,15 @@
msg_info("terminating on signal %d", sig);
/*
+ * Undocumented: when a process runs with PID 1, Linux won't deliver a
+ * signal unless the process specifies a handler (i.e. SIG_DFL is treated
+ * as SIG_IGN).
+ */
+ if (init_mode)
+ /* Don't call exit() from a signal handler. */
+ _exit(0);
+
+ /*
* Deliver the signal to ourselves and clean up. XXX We're running as a
* signal handler and really should not be doing complicated things...
*/
diff -ur --new-file /var/tmp/postfix-3.3.0/src/postconf/postconf_dbms.c ./src/postconf/postconf_dbms.c
--- /var/tmp/postfix-3.3.0/src/postconf/postconf_dbms.c 2018-02-18 20:48:47.000000000 -0500
+++ ./src/postconf/postconf_dbms.c 2018-05-09 01:17:49.000000000 -0400
@@ -174,10 +174,10 @@
*/
dict = dict_ht_open(dict_spec, O_CREAT | O_RDWR, 0);
dict_register(dict_spec, dict);
- if ((fp = vstream_fopen(cf_file, O_RDONLY, 0)) == 0
- && errno != EACCES) {
- msg_warn("open \"%s\" configuration \"%s\": %m",
- dp->db_type, cf_file);
+ if ((fp = vstream_fopen(cf_file, O_RDONLY, 0)) == 0) {
+ if (errno != EACCES)
+ msg_warn("open \"%s\" configuration \"%s\": %m",
+ dp->db_type, cf_file);
myfree(dict_spec);
return;
}
diff -ur --new-file /var/tmp/postfix-3.3.0/src/postfix/postfix.c ./src/postfix/postfix.c
--- /var/tmp/postfix-3.3.0/src/postfix/postfix.c 2018-02-11 10:17:58.000000000 -0500
+++ ./src/postfix/postfix.c 2018-05-19 11:13:16.000000000 -0400
@@ -32,8 +32,10 @@
/* Start the Postfix mail system. This also runs the configuration
/* check described above.
/* .IP \fBstart-fg\fR
-/* Like \fBstart\fR, but keep the master daemon running in the
-/* foreground. This requires that multi-instance support is
+/* Like \fBstart\fR, but keep the \fBmaster\fR(8) daemon running
+/* in the foreground, and enable \fBmaster\fR(8) "init" mode
+/* when running as PID 1.
+/* This command requires that multi-instance support is
/* disabled (i.e. the multi_instance_directories parameter
/* value must be empty). When running Postfix inside a container,
/* mount the container host's /dev/log socket inside the
diff -ur --new-file /var/tmp/postfix-3.3.0/src/tlsproxy/tlsproxy.c ./src/tlsproxy/tlsproxy.c
--- /var/tmp/postfix-3.3.0/src/tlsproxy/tlsproxy.c 2018-01-14 11:48:25.000000000 -0500
+++ ./src/tlsproxy/tlsproxy.c 2018-05-19 08:02:00.000000000 -0400
@@ -663,7 +663,7 @@
/* tlsp_start_tls - turn on TLS or force disconnect */
-static void tlsp_start_tls(TLSP_STATE *state)
+static int tlsp_start_tls(TLSP_STATE *state)
{
TLS_SERVER_START_PROPS props;
static char *cipher_grade;
@@ -716,7 +716,7 @@
if (state->tls_context == 0) {
tlsp_state_free(state);
- return;
+ return (-1);
}
/*
@@ -729,6 +729,7 @@
* XXX Do we care about certificate verification results? Not as long as
* postscreen(8) doesn't actually receive email.
*/
+ return (0);
}
/* tlsp_get_fd_event - receive final postscreen(8) hand-off information */
@@ -776,7 +777,8 @@
* Perform the TLS layer before-handshake initialization. We perform the
* remainder after the TLS handshake completes.
*/
- tlsp_start_tls(state);
+ if (tlsp_start_tls(state) < 0)
+ return;
/*
* Trigger the initial proxy server I/Os.
diff -ur --new-file /var/tmp/postfix-3.3.0/src/util/killme_after.c ./src/util/killme_after.c
--- /var/tmp/postfix-3.3.0/src/util/killme_after.c 2006-12-05 09:35:35.000000000 -0500
+++ ./src/util/killme_after.c 2018-05-19 14:59:59.000000000 -0400
@@ -46,11 +46,17 @@
* Schedule an ALARM signal, and make sure the signal will be delivered
* even if we are being called from a signal handler and SIGALRM delivery
* is blocked.
+ *
+ * Undocumented: when a process runs with PID 1, Linux won't deliver a
+ * signal unless the process specifies a handler (i.e. SIG_DFL is treated
+ * as SIG_IGN). Conveniently, _exit() can be used directly as a signal
+ * handler. This changes the wait status that a parent would see, but in
+ * the case of "init" mode on Linux, no-one would care.
*/
alarm(0);
sigemptyset(&sig_action.sa_mask);
sig_action.sa_flags = 0;
- sig_action.sa_handler = SIG_DFL;
+ sig_action.sa_handler = (getpid() == 1 ? _exit : SIG_DFL);
sigaction(SIGALRM, &sig_action, (struct sigaction *) 0);
alarm(seconds);
sigaddset(&sig_action.sa_mask, SIGALRM);