2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-09-01 14:45:32 +00:00

postfix-2.11-20131114

This commit is contained in:
Wietse Venema
2013-11-14 00:00:00 -05:00
committed by Viktor Dukhovni
parent 9aa88be230
commit 897f730f14
40 changed files with 425 additions and 239 deletions

View File

@@ -19069,7 +19069,45 @@ Apologies for any names omitted.
not hurt to do this also for HTML. Files: proto/Makefile.in, not hurt to do this also for HTML. Files: proto/Makefile.in,
proto/MULTI_INSTANCE_README.html. proto/MULTI_INSTANCE_README.html.
20121104 20131104
Feature: ${queue_id} macro support for the pipe(8) delivery Feature: ${queue_id} macro support for the pipe(8) delivery
agent by Andreas Schulze. File: pipe/pipe.c. agent by Andreas Schulze. File: pipe/pipe.c.
20131107
Cleanup: after 16 years the SKIP() and TRIM() macros were
triggering compiler warnings. Files: global/mail_params.c,
smtpstone/smtp-sink.c, util/mac_parse.c, util/split_nameval.c.
20131110
Bugfix (introduced Oct 26 1997): don't clobber errno before
expanding %m. File: util/vbuf_print.c.
20131114
Cleanup: LMDB >= 0.9.10 does not need the MDB_WRITEMAP
workaround to avoid heap memory information leaks. File:
util/dict_lmdb.c.
20131114
Cleanup: Coverity found a harmless memory leak in the
postconf master.cf parser. Reported by Christos Zoulas,
NetBSD. File: postconf/postconf_master.c.
Cleanup: graceful degradation after database open() error.
Several instances of that code introduced a harmless memory
leak, and Coverity complained about one of them (Christos
Zoulas, NetBSD). Instead of adding random code in random
places, restructured dict_foo_open() routines with consistent
code to dispose of memory or file handles. Files: dict_thash.c,
dict_sockmap.c, dict_regexp.c, dict_pcre.c, dict_lmdb.c,
dict_dbm.c, dict_cidr.c, dict_cdb.c.
Cleanup: warning message after canonical/virtal/etc.
table lookup error. Files: cleanup/cleanup_addr.c,
cleanup/cleanup_map11.c, cleanup/cleanup_map1n.c,
cleanup/cleanup_masquerade.c, cleanup/cleanup_message.c,
cleanup/cleanup_milter.c.

View File

@@ -557,10 +557,10 @@ plaintext.
If you must store encrypted passwords, you cannot use the ldapdb auxprop If you must store encrypted passwords, you cannot use the ldapdb auxprop
plugin. Instead, you can use "saslauthd -a ldap" to query the LDAP database plugin. Instead, you can use "saslauthd -a ldap" to query the LDAP database
directly, with appropriate configuration in saslauthd.conf. This may be directly, with appropriate configuration in saslauthd.conf, as described
documented in a later version of this document. You will not be able to use here. You will not be able to use any of the methods that require access to
any of the methods that require access to plaintext passwords, such as the plaintext passwords, such as the shared-secret methods CRAM-MD5 and DIGEST-
shared-secret methods CRAM-MD5 and DIGEST-MD5. MD5.
The ldapdb plugin implements proxy authorization. This means that the ldapdb The ldapdb plugin implements proxy authorization. This means that the ldapdb
plugin uses its own username and password to authenticate with the LDAP server, plugin uses its own username and password to authenticate with the LDAP server,

View File

@@ -1,8 +1,17 @@
Wish list: Wish list:
Un-break "make tests" under src/smtpd.
Make been_here flag BH_FLAG_FOLD configurable for masochists.
Preserve case in smtpd_resolve_addr() and add a structure
member for the case-folded address.
Per SASL account rate limits. Per SASL account rate limits.
Add watchdog timer to postmap/postalias. Watchdog timer to postmap/postalias.
C99 va_copy() support.
Things to do before the stable release: Things to do before the stable release:

View File

@@ -948,8 +948,9 @@ stored as plaintext. </p>
<p> If you must store encrypted passwords, you cannot use the ldapdb <p> If you must store encrypted passwords, you cannot use the ldapdb
auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>" auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
to query the LDAP database directly, with appropriate configuration to query the LDAP database directly, with appropriate configuration
in <code>saslauthd.conf</code>. This may be documented in a later in <code>saslauthd.conf</code>, <a
version of this document. You will not be able to use any of the href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as
described here</a>. You will not be able to use any of the
methods that require access to plaintext passwords, such as the methods that require access to plaintext passwords, such as the
shared-secret methods CRAM-MD5 and DIGEST-MD5. </p> shared-secret methods CRAM-MD5 and DIGEST-MD5. </p>

View File

@@ -98,8 +98,8 @@ MASTER(5) MASTER(5)
trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura- trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura-
tion parameter in <a href="postconf.5.html">main.cf</a>). tion parameter in <a href="postconf.5.html">main.cf</a>).
On Solaris systems the <b>unix</b> type is imple- On Solaris 8 and earlier systems the <b>unix</b>
mented with streams sockets. type is implemented with streams sockets.
<b>fifo</b> The service listens on a FIFO (named pipe) <b>fifo</b> The service listens on a FIFO (named pipe)
and is accessible for local clients only. and is accessible for local clients only.
@@ -119,8 +119,8 @@ MASTER(5) MASTER(5)
trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura- trolled with the <b><a href="postconf.5.html#queue_directory">queue_directory</a></b> configura-
tion parameter in <a href="postconf.5.html">main.cf</a>). tion parameter in <a href="postconf.5.html">main.cf</a>).
On Solaris systems the <b>pass</b> type is imple- On Solaris 8 and earlier systems the <b>pass</b>
mented with streams sockets. type is implemented with streams sockets.
This feature is available as of Postfix ver- This feature is available as of Postfix ver-
sion 2.5. sion 2.5.
@@ -225,8 +225,8 @@ MASTER(5) MASTER(5)
to understand and maintain. At a certain to understand and maintain. At a certain
point, it might be easier to configure mul- point, it might be easier to configure mul-
tiple instances of Postfix, instead of con- tiple instances of Postfix, instead of con-
figuring multiple personalities via mas- figuring multiple personalities via <a href="master.5.html">mas-
ter.cf. ter.cf</a>.
<b>-v</b> Increase the verbose logging level. Specify <b>-v</b> Increase the verbose logging level. Specify
multiple <b>-v</b> options to make a Postfix daemon multiple <b>-v</b> options to make a Postfix daemon

View File

@@ -12,7 +12,7 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>SYNOPSIS</b> <b>SYNOPSIS</b>
<b>smtp-sink</b> [<i>options</i>] [<b>inet:</b>][<i>host</i>]:<i>port backlog</i> <b>smtp-sink</b> [<i>options</i>] [<b>inet:</b>][<i>host</i>]:<i>port backlog</i>
<b>smtp-sink</b> [<i>options</i>] <b>unix:</b><i>pathname backlog</i> <b>smtp-sink</b> [<i>options</i>] <b>unix:<i></b>pathname backlog</i>
<b>DESCRIPTION</b> <b>DESCRIPTION</b>
<b>smtp-sink</b> listens on the named host (or address) and port. <b>smtp-sink</b> listens on the named host (or address) and port.
@@ -47,19 +47,19 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-a</b> Do not announce SASL authentication support. <b>-a</b> Do not announce SASL authentication support.
<b>-A</b> <i>delay</i> <b>-A <i></b>delay
Wait <i>delay</i> seconds after responding to DATA, then Wait <i>delay</i> seconds after responding to DATA, then
abort prematurely with a 550 reply status. Do not abort prematurely with a 550 reply status. Do not
read further input from the client; this is an read further input from the client; this is an
attempt to block the client before it sends ".". attempt to block the client before it sends ".".
Specify a zero delay value to abort immediately. Specify a zero delay value to abort immediately.
<b>-b</b> <i>soft-bounce-reply</i> <b>-b <i></b>soft-bounce-reply
Use <i>soft-bounce-reply</i> for soft reject responses. Use <i>soft-bounce-reply</i> for soft reject responses.
The default reply is "450 4.3.0 Error: command The default reply is "450 4.3.0 Error: command
failed". failed".
<b>-B</b> <i>hard-bounce-reply</i> <b>-B <i></b>hard-bounce-reply
Use <i>hard-bounce-reply</i> for hard reject responses. Use <i>hard-bounce-reply</i> for hard reject responses.
The default reply is "500 5.3.0 Error: command The default reply is "500 5.3.0 Error: command
failed". failed".
@@ -70,7 +70,7 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-C</b> Disable XCLIENT support. <b>-C</b> Disable XCLIENT support.
<b>-d</b> <i>dump-template</i> <b>-d <i></b>dump-template
Dump each mail transaction to a single-message file Dump each mail transaction to a single-message file
whose name is created by expanding the <i>dump-tem-</i> whose name is created by expanding the <i>dump-tem-</i>
<i>plate</i> via strftime(3) and appending a pseudo-random <i>plate</i> via strftime(3) and appending a pseudo-random
@@ -83,7 +83,7 @@ SMTP-SINK(1) SMTP-SINK(1)
Note: this option keeps one capture file open for Note: this option keeps one capture file open for
every mail transaction in progress. every mail transaction in progress.
<b>-D</b> <i>dump-template</i> <b>-D <i></b>dump-template
Append mail transactions to a multi-message dump Append mail transactions to a multi-message dump
file whose name is created by expanding the <i>dump-</i> file whose name is created by expanding the <i>dump-</i>
<i>template</i> via strftime(3). If the template contains <i>template</i> via strftime(3). If the template contains
@@ -98,7 +98,7 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-E</b> Do not announce ENHANCEDSTATUSCODES support. <b>-E</b> Do not announce ENHANCEDSTATUSCODES support.
<b>-f</b> <i>command,command,...</i> <b>-f <i></b>command,command,...
Reject the specified commands with a hard (5xx) Reject the specified commands with a hard (5xx)
error code. This option implies <b>-p</b>. error code. This option implies <b>-p</b>.
@@ -110,24 +110,24 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-F</b> Disable XFORWARD support. <b>-F</b> Disable XFORWARD support.
<b>-h</b> <i>hostname</i> <b>-h <i></b>hostname
Use <i>hostname</i> in the SMTP greeting, in the HELO Use <i>hostname</i> in the SMTP greeting, in the HELO
response, and in the EHLO response. The default response, and in the EHLO response. The default
hostname is "smtp-sink". hostname is "smtp-sink".
<b>-L</b> Enable LMTP instead of SMTP. <b>-L</b> Enable LMTP instead of SMTP.
<b>-m</b> <i>count</i> (default: 256) <b>-m <i></b>count</i> (default: 256)
An upper bound on the maximal number of simultane- An upper bound on the maximal number of simultane-
ous connections that <b>smtp-sink</b> will handle. This ous connections that <b>smtp-sink</b> will handle. This
prevents the process from running out of file prevents the process from running out of file
descriptors. Excess connections will stay queued in descriptors. Excess connections will stay queued in
the TCP/IP stack. the TCP/IP stack.
<b>-M</b> <i>count</i> <b>-M <i></b>count
Terminate after receiving <i>count</i> messages. Terminate after receiving <i>count</i> messages.
<b>-n</b> <i>count</i> <b>-n <i></b>count
Terminate after <i>count</i> sessions. Terminate after <i>count</i> sessions.
<b>-p</b> Do not announce support for ESMTP command pipelin- <b>-p</b> Do not announce support for ESMTP command pipelin-
@@ -136,7 +136,7 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-P</b> Change the server greeting so that it appears to <b>-P</b> Change the server greeting so that it appears to
come through a CISCO PIX system. Implies <b>-e</b>. come through a CISCO PIX system. Implies <b>-e</b>.
<b>-q</b> <i>command,command,...</i> <b>-q <i></b>command,command,...
Disconnect (without replying) after receiving one Disconnect (without replying) after receiving one
of the specified commands. of the specified commands.
@@ -146,7 +146,7 @@ SMTP-SINK(1) SMTP-SINK(1)
and use quotes to protect white space from the and use quotes to protect white space from the
shell. Command names are case-insensitive. shell. Command names are case-insensitive.
<b>-Q</b> <i>command,command,...</i> <b>-Q <i></b>command,command,...
Send a 421 reply and disconnect after receiving one Send a 421 reply and disconnect after receiving one
of the specified commands. of the specified commands.
@@ -156,7 +156,7 @@ SMTP-SINK(1) SMTP-SINK(1)
and use quotes to protect white space from the and use quotes to protect white space from the
shell. Command names are case-insensitive. shell. Command names are case-insensitive.
<b>-r</b> <i>command,command,...</i> <b>-r <i></b>command,command,...
Reject the specified commands with a soft (4xx) Reject the specified commands with a soft (4xx)
error code. This option implies <b>-p</b>. error code. This option implies <b>-p</b>.
@@ -166,12 +166,12 @@ SMTP-SINK(1) SMTP-SINK(1)
and use quotes to protect white space from the and use quotes to protect white space from the
shell. Command names are case-insensitive. shell. Command names are case-insensitive.
<b>-R</b> <i>root-directory</i> <b>-R <i></b>root-directory
Change the process root directory to the specified Change the process root directory to the specified
location. This option requires super-user privi- location. This option requires super-user privi-
leges. See also the <b>-u</b> option. leges. See also the <b>-u</b> option.
<b>-s</b> <i>command,command,...</i> <b>-s <i></b>command,command,...
Log the named commands to syslogd. Log the named commands to syslogd.
Examples of commands are CONNECT, HELO, EHLO, LHLO, Examples of commands are CONNECT, HELO, EHLO, LHLO,
@@ -190,16 +190,16 @@ SMTP-SINK(1) SMTP-SINK(1)
tab), \<i>ddd</i> (up to three octal digits) and \\ (the tab), \<i>ddd</i> (up to three octal digits) and \\ (the
backslash character). backslash character).
<b>-t</b> <i>timeout</i> (default: 100) <b>-t <i></b>timeout</i> (default: 100)
Limit the time for receiving a command or sending a Limit the time for receiving a command or sending a
response. The time limit is specified in seconds. response. The time limit is specified in seconds.
<b>-T</b> <i>windowsize</i> <b>-T <i></b>windowsize
Override the default TCP window size. To work Override the default TCP window size. To work
around broken TCP window scaling implementations, around broken TCP window scaling implementations,
specify a value &gt; 0 and &lt; 65536. specify a value &gt; 0 and &lt; 65536.
<b>-u</b> <i>username</i> <b>-u <i></b>username
Switch to the specified user privileges after open- Switch to the specified user privileges after open-
ing the network socket and optionally changing the ing the network socket and optionally changing the
process root directory. This option is required process root directory. This option is required
@@ -208,11 +208,11 @@ SMTP-SINK(1) SMTP-SINK(1)
<b>-v</b> Show the SMTP conversations. <b>-v</b> Show the SMTP conversations.
<b>-w</b> <i>delay</i> <b>-w <i></b>delay
Wait <i>delay</i> seconds before responding to a DATA com- Wait <i>delay</i> seconds before responding to a DATA com-
mand. mand.
<b>-W</b> <i>command:delay[:odds]</i> <b>-W <i></b>command:delay[:odds]
Wait <i>delay</i> seconds before responding to <i>command</i>. Wait <i>delay</i> seconds before responding to <i>command</i>.
If <i>odds</i> is also specified (a number between 1-99 If <i>odds</i> is also specified (a number between 1-99
inclusive), wait for a random multiple of <i>delay</i>. inclusive), wait for a random multiple of <i>delay</i>.
@@ -226,7 +226,7 @@ SMTP-SINK(1) SMTP-SINK(1)
interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be interface) TCP port <i>port</i>. Both <i>host</i> and <i>port</i> may be
specified in numeric or symbolic form. specified in numeric or symbolic form.
<b>unix:</b><i>pathname</i> <b>unix:<i></b>pathname
Listen on the UNIX-domain socket at <i>pathname</i>. Listen on the UNIX-domain socket at <i>pathname</i>.
<i>backlog</i> <i>backlog</i>
@@ -251,45 +251,45 @@ SMTP-SINK(1) SMTP-SINK(1)
The format of the <b>smtp-sink</b> generated headers is as fol- The format of the <b>smtp-sink</b> generated headers is as fol-
lows: lows:
<b>X-Client-Addr:</b> <i>text</i> <b>X-Client-Addr: <i></b>text
The client IP address without enclosing []. An IPv6 The client IP address without enclosing []. An IPv6
address is prefixed with "ipv6:". This record is address is prefixed with "ipv6:". This record is
always present. always present.
<b>X-Client-Proto:</b> <i>text</i> <b>X-Client-Proto: <i></b>text
The client protocol: SMTP, ESMTP or LMTP. This The client protocol: SMTP, ESMTP or LMTP. This
record is always present. record is always present.
<b>X-Helo-Args:</b> <i>text</i> <b>X-Helo-Args: <i></b>text
The arguments of the last HELO or EHLO command The arguments of the last HELO or EHLO command
before this mail delivery transaction. This record before this mail delivery transaction. This record
is present only if the client sent a recognizable is present only if the client sent a recognizable
HELO or EHLO command before the DATA command. HELO or EHLO command before the DATA command.
<b>X-Mail-Args:</b> <i>text</i> <b>X-Mail-Args: <i></b>text
The arguments of the MAIL command that started this The arguments of the MAIL command that started this
mail delivery transaction. This record is present mail delivery transaction. This record is present
exactly once. exactly once.
<b>X-Rcpt-Args:</b> <i>text</i> <b>X-Rcpt-Args: <i></b>text
The arguments of an RCPT command within this mail The arguments of an RCPT command within this mail
delivery transaction. There is one record for each delivery transaction. There is one record for each
RCPT command, and they are in the order as sent by RCPT command, and they are in the order as sent by
the client. the client.
<b>Received:</b> <i>text</i> <b>Received: <i></b>text
A message header for compatibility with mail pro- A message header for compatibility with mail pro-
cessing software. This three-line header marks the cessing software. This three-line header marks the
end of the headers provided by <b>smtp-sink</b>, and is end of the headers provided by <b>smtp-sink</b>, and is
formatted as follows: formatted as follows:
<b>from</b> <i>helo</i> <b>([</b><i>addr</i><b>])</b> <b>from <i></b>helo</i> <b>([<i></b>addr</i><b>])</b>
The HELO or EHLO command argument and client The HELO or EHLO command argument and client
IP address. If the client did not send HELO IP address. If the client did not send HELO
or EHLO, the client IP address is used or EHLO, the client IP address is used
instead. instead.
<b>by</b> <i>host</i> <b>(smtp-sink) with</b> <i>proto</i> <b>id</b> <i>random</i><b>;</b> <b>by <i></b>host</i> <b>(smtp-sink) with <i></b>proto</i> <b>id <i></b>random</i><b>;</b>
The hostname specified with the <b>-h</b> option, The hostname specified with the <b>-h</b> option,
the client protocol (see <b>X-Client-Proto</b> the client protocol (see <b>X-Client-Proto</b>
above), and the pseudo-random portion of the above), and the pseudo-random portion of the

View File

@@ -92,8 +92,8 @@ The service name is a pathname relative to the Postfix
queue directory (pathname controlled with the \fBqueue_directory\fR queue directory (pathname controlled with the \fBqueue_directory\fR
configuration parameter in main.cf). configuration parameter in main.cf).
.sp .sp
On Solaris systems the \fBunix\fR type is implemented with On Solaris 8 and earlier systems the \fBunix\fR type is
streams sockets. implemented with streams sockets.
.IP \fBfifo\fR .IP \fBfifo\fR
The service listens on a FIFO (named pipe) and is accessible The service listens on a FIFO (named pipe) and is accessible
for local clients only. for local clients only.
@@ -110,8 +110,8 @@ The service name is a pathname relative to the Postfix
queue directory (pathname controlled with the \fBqueue_directory\fR queue directory (pathname controlled with the \fBqueue_directory\fR
configuration parameter in main.cf). configuration parameter in main.cf).
.sp .sp
On Solaris systems the \fBpass\fR type is implemented with On Solaris 8 and earlier systems the \fBpass\fR type is
streams sockets. implemented with streams sockets.
This feature is available as of Postfix version 2.5. This feature is available as of Postfix version 2.5.
.RE .RE

View File

@@ -948,8 +948,9 @@ stored as plaintext. </p>
<p> If you must store encrypted passwords, you cannot use the ldapdb <p> If you must store encrypted passwords, you cannot use the ldapdb
auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>" auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
to query the LDAP database directly, with appropriate configuration to query the LDAP database directly, with appropriate configuration
in <code>saslauthd.conf</code>. This may be documented in a later in <code>saslauthd.conf</code>, <a
version of this document. You will not be able to use any of the href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as
described here</a>. You will not be able to use any of the
methods that require access to plaintext passwords, such as the methods that require access to plaintext passwords, such as the
shared-secret methods CRAM-MD5 and DIGEST-MD5. </p> shared-secret methods CRAM-MD5 and DIGEST-MD5. </p>

View File

@@ -86,8 +86,8 @@
# queue directory (pathname controlled with the \fBqueue_directory\fR # queue directory (pathname controlled with the \fBqueue_directory\fR
# configuration parameter in main.cf). # configuration parameter in main.cf).
# .sp # .sp
# On Solaris systems the \fBunix\fR type is implemented with # On Solaris 8 and earlier systems the \fBunix\fR type is
# streams sockets. # implemented with streams sockets.
# .IP \fBfifo\fR # .IP \fBfifo\fR
# The service listens on a FIFO (named pipe) and is accessible # The service listens on a FIFO (named pipe) and is accessible
# for local clients only. # for local clients only.
@@ -104,8 +104,8 @@
# queue directory (pathname controlled with the \fBqueue_directory\fR # queue directory (pathname controlled with the \fBqueue_directory\fR
# configuration parameter in main.cf). # configuration parameter in main.cf).
# .sp # .sp
# On Solaris systems the \fBpass\fR type is implemented with # On Solaris 8 and earlier systems the \fBpass\fR type is
# streams sockets. # implemented with streams sockets.
# #
# This feature is available as of Postfix version 2.5. # This feature is available as of Postfix version 2.5.
# .RE # .RE

View File

@@ -149,7 +149,8 @@ void cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
IGNORE_EXTENSION)) != 0) { IGNORE_EXTENSION)) != 0) {
cleanup_addr_bcc(state, bcc); cleanup_addr_bcc(state, bcc);
} else if (cleanup_send_bcc_maps->error) { } else if (cleanup_send_bcc_maps->error) {
msg_warn("%s: %s lookup problem", msg_warn("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, cleanup_send_bcc_maps->title); state->queue_id, cleanup_send_bcc_maps->title);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} }
@@ -198,7 +199,8 @@ void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
IGNORE_EXTENSION)) != 0) { IGNORE_EXTENSION)) != 0) {
cleanup_addr_bcc(state, bcc); cleanup_addr_bcc(state, bcc);
} else if (cleanup_rcpt_bcc_maps->error) { } else if (cleanup_rcpt_bcc_maps->error) {
msg_warn("%s: %s lookup problem", msg_warn("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, cleanup_rcpt_bcc_maps->title); state->queue_id, cleanup_rcpt_bcc_maps->title);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} }

View File

@@ -120,7 +120,8 @@ int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
if (expand_to_self) if (expand_to_self)
return (did_rewrite); return (did_rewrite);
} else if (maps->error != 0) { } else if (maps->error != 0) {
msg_warn("%s: %s map lookup problem for %s", msg_warn("%s: %s map lookup problem for %s -- "
"message not accepted, try again later",
state->queue_id, maps->title, STR(addr)); state->queue_id, maps->title, STR(addr));
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
return (did_rewrite); return (did_rewrite);
@@ -128,7 +129,8 @@ int cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
return (did_rewrite); return (did_rewrite);
} }
} }
msg_warn("%s: unreasonable %s map nesting for %s", msg_warn("%s: unreasonable %s map nesting for %s -- "
"message not accepted, try again later",
state->queue_id, maps->title, STR(addr)); state->queue_id, maps->title, STR(addr));
return (did_rewrite); return (did_rewrite);
} }

View File

@@ -112,7 +112,7 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
for (arg = 0; arg < argv->argc; arg++) { for (arg = 0; arg < argv->argc; arg++) {
if (argv->argc > var_virt_expan_limit) { if (argv->argc > var_virt_expan_limit) {
msg_warn("%s: unreasonable %s map expansion size for %s -- " msg_warn("%s: unreasonable %s map expansion size for %s -- "
"deferring delivery", "message not accepted, try again later",
state->queue_id, maps->title, addr); state->queue_id, maps->title, addr);
state->errs |= CLEANUP_STAT_DEFER; state->errs |= CLEANUP_STAT_DEFER;
UPDATE(state->reason, "4.6.0 Alias expansion error"); UPDATE(state->reason, "4.6.0 Alias expansion error");
@@ -128,7 +128,7 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
break; break;
if (count >= var_virt_recur_limit) { if (count >= var_virt_recur_limit) {
msg_warn("%s: unreasonable %s map nesting for %s -- " msg_warn("%s: unreasonable %s map nesting for %s -- "
"deferring delivery", "message not accepted, try again later",
state->queue_id, maps->title, addr); state->queue_id, maps->title, addr);
state->errs |= CLEANUP_STAT_DEFER; state->errs |= CLEANUP_STAT_DEFER;
UPDATE(state->reason, "4.6.0 Alias expansion error"); UPDATE(state->reason, "4.6.0 Alias expansion error");
@@ -157,7 +157,7 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
argv_free(lookup); argv_free(lookup);
} else if (maps->error != 0) { } else if (maps->error != 0) {
msg_warn("%s: %s map lookup problem for %s -- " msg_warn("%s: %s map lookup problem for %s -- "
"deferring delivery", "message not accepted, try again later",
state->queue_id, maps->title, addr); state->queue_id, maps->title, addr);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
UPDATE(state->reason, "4.6.0 Alias expansion error"); UPDATE(state->reason, "4.6.0 Alias expansion error");

View File

@@ -110,7 +110,8 @@ int cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr,
excluded = (string_list_match(cleanup_masq_exceptions, lowercase(name)) != 0); excluded = (string_list_match(cleanup_masq_exceptions, lowercase(name)) != 0);
myfree(name); myfree(name);
if (cleanup_masq_exceptions->error) { if (cleanup_masq_exceptions->error) {
msg_info("%s: %s lookup error -- deferring delivery", msg_info("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, VAR_MASQ_EXCEPTIONS); state->queue_id, VAR_MASQ_EXCEPTIONS);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} }

View File

@@ -499,7 +499,8 @@ static void cleanup_header_callback(void *context, int header_class,
myfree((char *) result); myfree((char *) result);
} }
} else if (checks->error) { } else if (checks->error) {
msg_warn("%s: %s map lookup problem -- deferring delivery", msg_warn("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, checks->title); state->queue_id, checks->title);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} }
@@ -789,7 +790,8 @@ static void cleanup_body_callback(void *context, int type,
return; return;
} }
} else if (cleanup_body_checks->error) { } else if (cleanup_body_checks->error) {
msg_warn("%s: %s map lookup problem -- deferring delivery", msg_warn("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, cleanup_body_checks->title); state->queue_id, cleanup_body_checks->title);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
} }

View File

@@ -392,7 +392,8 @@ static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf)
if (ret == 0) { if (ret == 0) {
return (0); return (0);
} else if (ret == HBC_CHECKS_STAT_ERROR) { } else if (ret == HBC_CHECKS_STAT_ERROR) {
msg_warn("%s: %s lookup error -- deferring delivery", msg_warn("%s: %s map lookup problem -- "
"message not accepted, try again later",
state->queue_id, VAR_MILT_HEAD_CHECKS); state->queue_id, VAR_MILT_HEAD_CHECKS);
state->errs |= CLEANUP_STAT_WRITE; state->errs |= CLEANUP_STAT_WRITE;
return (0); return (0);
@@ -2092,7 +2093,7 @@ void cleanup_milter_emul_rcpt(CLEANUP_STATE *state,
&& cleanup_milter_apply(state, "RCPT", resp) != 0) { && cleanup_milter_apply(state, "RCPT", resp) != 0) {
msg_warn("%s: milter configuration error: can't reject recipient " msg_warn("%s: milter configuration error: can't reject recipient "
"in non-smtpd(8) submission", state->queue_id); "in non-smtpd(8) submission", state->queue_id);
msg_warn("%s: deferring delivery of this message", state->queue_id); msg_warn("%s: message not accepted, try again later", state->queue_id);
CLEANUP_MILTER_SET_REASON(state, "4.3.5 Server configuration error"); CLEANUP_MILTER_SET_REASON(state, "4.3.5 Server configuration error");
state->errs |= CLEANUP_STAT_DEFER; state->errs |= CLEANUP_STAT_DEFER;
} }

View File

@@ -487,14 +487,17 @@ static char *read_param_from_file(const char *path)
/* /*
* Ugly macros to make complex expressions less unreadable. * Ugly macros to make complex expressions less unreadable.
*/ */
#define SKIP(start, var, cond) \ #define SKIP(start, var, cond) do { \
for (var = start; *var && (cond); var++); for (var = start; *var && (cond); var++) \
/* void */; \
} while (0)
#define TRIM(s) { \ #define TRIM(s) do { \
char *p; \ char *p; \
for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--); \ for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--) \
/* void */; \
*p = 0; \ *p = 0; \
} } while (0)
fp = safe_open(path, O_RDONLY, 0, (struct stat *) 0, -1, -1, why); fp = safe_open(path, O_RDONLY, 0, (struct stat *) 0, -1, -1, why);
if (fp == 0) if (fp == 0)

View File

@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20131105" #define MAIL_RELEASE_DATE "20131114"
#define MAIL_VERSION_NUMBER "2.11" #define MAIL_VERSION_NUMBER "2.11"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@@ -31,6 +31,9 @@
/* Terminate after \fIcount\fR connections. /* Terminate after \fIcount\fR connections.
/* .IP "\fB-d\fI level\fR" /* .IP "\fB-d\fI level\fR"
/* Enable libmilter debugging at the specified level. /* Enable libmilter debugging at the specified level.
/* .IP "\fB-D\fI address\fR"
/* Delete the specified recipient address. Multiple -D options
/* are supported.
/* .IP "\fB-f \fIsender\fR /* .IP "\fB-f \fIsender\fR
/* Replace the sender by the specified address. /* Replace the sender by the specified address.
/* .IP "\fB-h \fI'index header-label header-value'\fR" /* .IP "\fB-h \fI'index header-label header-value'\fR"
@@ -159,8 +162,10 @@ static char *body_file;
#endif #endif
#define MAX_RCPT 10 #define MAX_RCPT 10
int rcpt_count = 0; int add_rcpt_count = 0;
char *rcpt_addr[MAX_RCPT]; char *add_rcpt[MAX_RCPT];
int del_rcpt_count = 0;
char *del_rcpt[MAX_RCPT];
static const char *macro_names[] = { static const char *macro_names[] = {
"_", "_",
@@ -354,9 +359,13 @@ static sfsistat test_eom(SMFICTX *ctx)
{ {
int count; int count;
for (count = 0; count < rcpt_count; count++) for (count = 0; count < add_rcpt_count; count++)
if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE) if (smfi_addrcpt(ctx, add_rcpt[count]) == MI_FAILURE)
fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]); fprintf(stderr, "smfi_addrcpt `%s' failed\n", add_rcpt[count]);
for (count = 0; count < del_rcpt_count; count++)
if (smfi_delrcpt(ctx, del_rcpt[count]) == MI_FAILURE)
fprintf(stderr, "smfi_delrcpt `%s' failed\n", del_rcpt[count]);
} }
return (test_reply(ctx, test_eom_reply)); return (test_reply(ctx, test_eom_reply));
} }
@@ -540,17 +549,17 @@ int main(int argc, char **argv)
char *noreply = 0; char *noreply = 0;
const struct noproto_map *np; const struct noproto_map *np;
while ((ch = getopt(argc, argv, "a:A:b:c:C:d:f:h:i:lm:M:n:N:p:rv")) > 0) { while ((ch = getopt(argc, argv, "a:A:b:c:C:d:D:f:h:i:lm:M:n:N:p:rv")) > 0) {
switch (ch) { switch (ch) {
case 'a': case 'a':
action = optarg; action = optarg;
break; break;
case 'A': case 'A':
if (rcpt_count >= MAX_RCPT) { if (add_rcpt_count >= MAX_RCPT) {
fprintf(stderr, "too many -A options\n"); fprintf(stderr, "too many -A options\n");
exit(1); exit(1);
} }
rcpt_addr[rcpt_count++] = optarg; add_rcpt[add_rcpt_count++] = optarg;
break; break;
case 'b': case 'b':
#ifdef SMFIR_REPLBODY #ifdef SMFIR_REPLBODY
@@ -572,6 +581,13 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'D':
if (del_rcpt_count >= MAX_RCPT) {
fprintf(stderr, "too many -D options\n");
exit(1);
}
del_rcpt[del_rcpt_count++] = optarg;
break;
case 'f': case 'f':
#ifdef SMFIR_CHGFROM #ifdef SMFIR_CHGFROM
if (chg_from) { if (chg_from) {

View File

@@ -138,8 +138,10 @@ static const char *parse_master_line(PC_MASTER_ENT *masterp, const char *buf)
#define MASTER_BLANKS " \t\r\n" /* XXX */ #define MASTER_BLANKS " \t\r\n" /* XXX */
argv = argv_split(buf, MASTER_BLANKS); argv = argv_split(buf, MASTER_BLANKS);
if (argv->argc < PC_MASTER_MIN_FIELDS) if (argv->argc < PC_MASTER_MIN_FIELDS) {
argv_free(argv); /* Coverity 201311 */
return ("bad field count"); return ("bad field count");
}
normalize_options(argv); normalize_options(argv);
masterp->name_space = masterp->name_space =
concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0); concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0);

View File

@@ -39,7 +39,7 @@ update: ../../libexec/$(PROG)
cp $(PROG) ../../libexec cp $(PROG) ../../libexec
SMTPD_CHECK_OBJ = smtpd_state.o smtpd_peer.o smtpd_xforward.o smtpd_dsn_fix.o \ SMTPD_CHECK_OBJ = smtpd_state.o smtpd_peer.o smtpd_xforward.o smtpd_dsn_fix.o \
smtpd_resolve.o smtpd_expand.o smtpd_resolve.o smtpd_expand.o smtpd_proxy.o smtpd_haproxy.o
smtpd_token: smtpd_token.c $(LIBS) smtpd_token: smtpd_token.c $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS)

View File

@@ -5044,11 +5044,14 @@ int smtpd_input_transp_mask;
char *var_client_checks = ""; char *var_client_checks = "";
char *var_helo_checks = ""; char *var_helo_checks = "";
char *var_mail_checks = ""; char *var_mail_checks = "";
char *var_relay_checks = "";
char *var_rcpt_checks = ""; char *var_rcpt_checks = "";
char *var_etrn_checks = ""; char *var_etrn_checks = "";
char *var_data_checks = ""; char *var_data_checks = "";
char *var_eod_checks = ""; char *var_eod_checks = "";
char *var_relay_domains = ""; char *var_relay_domains = "";
char *var_smtpd_uproxy_proto = "";
int var_smtpd_uproxy_tmout = 0;
#ifdef USE_TLS #ifdef USE_TLS
char *var_relay_ccerts = ""; char *var_relay_ccerts = "";
@@ -5295,6 +5298,7 @@ static const REST_TABLE rest_table[] = {
"client_restrictions", &client_restrctions, "client_restrictions", &client_restrctions,
"helo_restrictions", &helo_restrctions, "helo_restrictions", &helo_restrctions,
"sender_restrictions", &mail_restrctions, "sender_restrictions", &mail_restrctions,
"relay_restrictions", &relay_restrctions,
"recipient_restrictions", &rcpt_restrctions, "recipient_restrictions", &rcpt_restrctions,
"etrn_restrictions", &etrn_restrctions, "etrn_restrictions", &etrn_restrctions,
0, 0,

View File

@@ -45,13 +45,13 @@ helo 123.123.123.123
# #
sender_restrictions permit_mynetworks,reject_unknown_client sender_restrictions permit_mynetworks,reject_unknown_client
client unknown 131.155.210.17 client unknown 131.155.210.17
mail foo@watson.ibm.com mail foo@ibm.com
client unknown 168.100.189.13 client unknown 168.100.189.13
mail foo@watson.ibm.com mail foo@ibm.com
client foo 123.123.123.123 client foo 123.123.123.123
mail foo@watson.ibm.com mail foo@ibm.com
sender_restrictions reject_unknown_address sender_restrictions reject_unknown_address
mail foo@watson.ibm.com mail foo@ibm.com
mail foo@bad.domain mail foo@bad.domain
sender_restrictions hash:./smtpd_check_access sender_restrictions hash:./smtpd_check_access
mail bad-sender@any.domain mail bad-sender@any.domain
@@ -67,18 +67,18 @@ mail foo@friend.bad.domain
# #
recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains
client unknown 131.155.210.17 client unknown 131.155.210.17
rcpt foo@watson.ibm.com rcpt foo@ibm.com
client unknown 168.100.189.13 client unknown 168.100.189.13
rcpt foo@watson.ibm.com rcpt foo@ibm.com
client foo 123.123.123.123 client foo 123.123.123.123
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
recipient_restrictions check_relay_domains recipient_restrictions check_relay_domains
client foo.porcupine.org 168.100.189.13 client foo.porcupine.org 168.100.189.13
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
client foo 123.123.123.123 client foo 123.123.123.123
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
recipient_restrictions hash:./smtpd_check_access recipient_restrictions hash:./smtpd_check_access
mail bad-sender@any.domain mail bad-sender@any.domain
@@ -98,7 +98,7 @@ client foo 127.0.0.2
# #
recipient_restrictions check_relay_domains recipient_restrictions check_relay_domains
client foo 131.155.210.17 client foo 131.155.210.17
rcpt foo@watson.ibm.com rcpt foo@ibm.com
recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
client foo 131.155.210.17 client foo 131.155.210.17
rcpt foo@porcupine.org rcpt foo@porcupine.org

View File

@@ -37,13 +37,13 @@ helo friend.bad.domain
# #
sender_restrictions permit_mynetworks,reject_unknown_client sender_restrictions permit_mynetworks,reject_unknown_client
client unknown 131.155.210.17 client unknown 131.155.210.17
mail foo@watson.ibm.com mail foo@ibm.com
client unknown 168.100.189.13 client unknown 168.100.189.13
mail foo@watson.ibm.com mail foo@ibm.com
client foo 123.123.123.123 client foo 123.123.123.123
mail foo@watson.ibm.com mail foo@ibm.com
sender_restrictions reject_unknown_address sender_restrictions reject_unknown_address
mail foo@watson.ibm.com mail foo@ibm.com
mail foo@bad.domain mail foo@bad.domain
sender_restrictions check_sender_access,hash:./smtpd_check_access sender_restrictions check_sender_access,hash:./smtpd_check_access
mail bad-sender@any.domain mail bad-sender@any.domain
@@ -59,18 +59,18 @@ mail foo@friend.bad.domain
# #
recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains
client unknown 131.155.210.17 client unknown 131.155.210.17
rcpt foo@watson.ibm.com rcpt foo@ibm.com
client unknown 168.100.189.13 client unknown 168.100.189.13
rcpt foo@watson.ibm.com rcpt foo@ibm.com
client foo 123.123.123.123 client foo 123.123.123.123
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
recipient_restrictions check_relay_domains recipient_restrictions check_relay_domains
client foo.porcupine.org 168.100.189.13 client foo.porcupine.org 168.100.189.13
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
client foo 123.123.123.123 client foo 123.123.123.123
rcpt foo@watson.ibm.com rcpt foo@ibm.com
rcpt foo@porcupine.org rcpt foo@porcupine.org
recipient_restrictions check_recipient_access,hash:./smtpd_check_access recipient_restrictions check_recipient_access,hash:./smtpd_check_access
mail bad-sender@any.domain mail bad-sender@any.domain

View File

@@ -91,20 +91,20 @@ OK
OK OK
>>> client unknown 131.155.210.17 >>> client unknown 131.155.210.17
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
./smtpd_check: <queue id>: reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@watson.ibm.com> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@ibm.com> proto=SMTP helo=<123.123.123.123>
450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17] 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
>>> client unknown 168.100.189.13 >>> client unknown 168.100.189.13
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> sender_restrictions reject_unknown_address >>> sender_restrictions reject_unknown_address
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> mail foo@bad.domain >>> mail foo@bad.domain
./smtpd_check: <queue id>: reject: MAIL from foo[123.123.123.123]: 450 4.1.8 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: MAIL from foo[123.123.123.123]: 450 4.1.8 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain> proto=SMTP helo=<123.123.123.123>
@@ -140,34 +140,34 @@ OK
OK OK
>>> client unknown 131.155.210.17 >>> client unknown 131.155.210.17
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: <queue id>: reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<123.123.123.123>
450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17] 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
>>> client unknown 168.100.189.13 >>> client unknown 168.100.189.13
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: warning: support for restriction "check_relay_domains" will be removed from Postfix; use "reject_unauth_destination" instead ./smtpd_check: warning: support for restriction "check_relay_domains" will be removed from Postfix; use "reject_unauth_destination" instead
./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<123.123.123.123>
554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> recipient_restrictions check_relay_domains >>> recipient_restrictions check_relay_domains
OK OK
>>> client foo.porcupine.org 168.100.189.13 >>> client foo.porcupine.org 168.100.189.13
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
OK OK
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<123.123.123.123>
554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> recipient_restrictions hash:./smtpd_check_access >>> recipient_restrictions hash:./smtpd_check_access
@@ -206,9 +206,9 @@ OK
OK OK
>>> client foo 131.155.210.17 >>> client foo 131.155.210.17
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: <queue id>: reject: RCPT from foo[131.155.210.17]: 554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<123.123.123.123> ./smtpd_check: <queue id>: reject: RCPT from foo[131.155.210.17]: 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<123.123.123.123>
554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied
>>> recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains >>> recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
OK OK
>>> client foo 131.155.210.17 >>> client foo 131.155.210.17

View File

@@ -71,20 +71,20 @@ OK
OK OK
>>> client unknown 131.155.210.17 >>> client unknown 131.155.210.17
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
./smtpd_check: <queue id>: reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@watson.ibm.com> proto=SMTP helo=<friend.bad.domain> ./smtpd_check: <queue id>: reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@ibm.com> proto=SMTP helo=<friend.bad.domain>
450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17] 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
>>> client unknown 168.100.189.13 >>> client unknown 168.100.189.13
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> sender_restrictions reject_unknown_address >>> sender_restrictions reject_unknown_address
OK OK
>>> mail foo@watson.ibm.com >>> mail foo@ibm.com
OK OK
>>> mail foo@bad.domain >>> mail foo@bad.domain
./smtpd_check: <queue id>: reject: MAIL from foo[123.123.123.123]: 450 4.1.8 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain> proto=SMTP helo=<friend.bad.domain> ./smtpd_check: <queue id>: reject: MAIL from foo[123.123.123.123]: 450 4.1.8 <foo@bad.domain>: Sender address rejected: Domain not found; from=<foo@bad.domain> proto=SMTP helo=<friend.bad.domain>
@@ -120,34 +120,34 @@ OK
OK OK
>>> client unknown 131.155.210.17 >>> client unknown 131.155.210.17
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: <queue id>: reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<friend.bad.domain> ./smtpd_check: <queue id>: reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<friend.bad.domain>
450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17] 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
>>> client unknown 168.100.189.13 >>> client unknown 168.100.189.13
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: warning: support for restriction "check_relay_domains" will be removed from Postfix; use "reject_unauth_destination" instead ./smtpd_check: warning: support for restriction "check_relay_domains" will be removed from Postfix; use "reject_unauth_destination" instead
./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<friend.bad.domain> ./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<friend.bad.domain>
554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> recipient_restrictions check_relay_domains >>> recipient_restrictions check_relay_domains
OK OK
>>> client foo.porcupine.org 168.100.189.13 >>> client foo.porcupine.org 168.100.189.13
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
OK OK
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> client foo 123.123.123.123 >>> client foo 123.123.123.123
OK OK
>>> rcpt foo@watson.ibm.com >>> rcpt foo@ibm.com
./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@watson.ibm.com> proto=SMTP helo=<friend.bad.domain> ./smtpd_check: <queue id>: reject: RCPT from foo[123.123.123.123]: 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied; from=<foo@friend.bad.domain> to=<foo@ibm.com> proto=SMTP helo=<friend.bad.domain>
554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied 554 5.7.1 <foo@ibm.com>: Recipient address rejected: Relay access denied
>>> rcpt foo@porcupine.org >>> rcpt foo@porcupine.org
OK OK
>>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access >>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access

View File

@@ -606,7 +606,10 @@ static void mail_cmd_reset(SINK_STATE *state)
static void ehlo_response(SINK_STATE *state, const char *args) static void ehlo_response(SINK_STATE *state, const char *args)
{ {
#define SKIP(cp, cond) for (/* void */; *cp && (cond); cp++) #define SKIP(cp, cond) do { \
for (/* void */; *cp && (cond); cp++) \
/* void */; \
} while (0)
/* EHLO aborts a mail transaction in progress. */ /* EHLO aborts a mail transaction in progress. */
mail_cmd_reset(state); mail_cmd_reset(state);

View File

@@ -284,6 +284,10 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session)
/* ticket_cb - configure tls session ticket encrypt/decrypt context */ /* ticket_cb - configure tls session ticket encrypt/decrypt context */
#if defined(SSL_OP_NO_TICKET) \
&& !defined(OPENSSL_NO_TLSEXT) \
&& OPENSSL_VERSION_NUMBER >= 0x0090808fL
static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[], static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
EVP_CIPHER_CTX * ctx, HMAC_CTX * hctx, int create) EVP_CIPHER_CTX * ctx, HMAC_CTX * hctx, int create)
{ {
@@ -317,6 +321,8 @@ static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
return (TLS_TKT_ACCEPT); return (TLS_TKT_ACCEPT);
} }
#endif
/* tls_server_init - initialize the server-side TLS engine */ /* tls_server_init - initialize the server-side TLS engine */
TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props) TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)

View File

@@ -115,7 +115,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \ unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \ myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
valid_utf_8 ip_match base32_code msg_rate_delay netstring \ valid_utf_8 ip_match base32_code msg_rate_delay netstring \
vstream vstream timecmp
LIB_DIR = ../../lib LIB_DIR = ../../lib
INC_DIR = ../../include INC_DIR = ../../include

View File

@@ -182,10 +182,20 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags)
char *cdb_path; char *cdb_path;
int fd; int fd;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_CDBQ_OPEN_RETURN(d) { \
DICT *__d = (d); \
myfree(cdb_path); \
return (__d); \
} while (0)
cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0); cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0);
if ((fd = open(cdb_path, O_RDONLY)) < 0) if ((fd = open(cdb_path, O_RDONLY)) < 0)
return (dict_surrogate(DICT_TYPE_CDB, path, O_RDONLY, dict_flags, DICT_CDBQ_OPEN_RETURN(dict_surrogate(DICT_TYPE_CDB, path,
O_RDONLY, dict_flags,
"open database %s: %m", cdb_path)); "open database %s: %m", cdb_path));
dict_cdbq = (DICT_CDBQ *) dict_alloc(DICT_TYPE_CDB, dict_cdbq = (DICT_CDBQ *) dict_alloc(DICT_TYPE_CDB,
@@ -225,8 +235,7 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags)
if (dict_flags & DICT_FLAG_FOLD_FIX) if (dict_flags & DICT_FLAG_FOLD_FIX)
dict_cdbq->dict.fold_buf = vstring_alloc(10); dict_cdbq->dict.fold_buf = vstring_alloc(10);
myfree(cdb_path); DICT_CDBQ_OPEN_RETURN(DICT_DEBUG (&dict_cdbq->dict));
return (&dict_cdbq->dict);
} }
/* dict_cdbm_update - add database entry, create mode */ /* dict_cdbm_update - add database entry, create mode */
@@ -330,6 +339,18 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
int fd; int fd;
struct stat st0, st1; struct stat st0, st1;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_CDBM_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (cdb_path) \
myfree(cdb_path); \
if (tmp_path) \
myfree(tmp_path); \
return (__d); \
} while (0)
cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0); cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0);
tmp_path = concatenate(path, CDB_TMP_SUFFIX, (char *) 0); tmp_path = concatenate(path, CDB_TMP_SUFFIX, (char *) 0);
@@ -342,8 +363,10 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
*/ */
for (;;) { for (;;) {
if ((fd = open(tmp_path, O_RDWR | O_CREAT, 0644)) < 0) if ((fd = open(tmp_path, O_RDWR | O_CREAT, 0644)) < 0)
return (dict_surrogate(DICT_TYPE_CDB, path, O_RDWR, dict_flags, DICT_CDBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_CDB, path,
"open database %s: %m", tmp_path)); O_RDWR, dict_flags,
"open database %s: %m",
tmp_path));
if (fstat(fd, &st0) < 0) if (fstat(fd, &st0) < 0)
msg_fatal("fstat(%s): %m", tmp_path); msg_fatal("fstat(%s): %m", tmp_path);
@@ -383,6 +406,7 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
dict_cdbm->dict.update = dict_cdbm_update; dict_cdbm->dict.update = dict_cdbm_update;
dict_cdbm->cdb_path = cdb_path; dict_cdbm->cdb_path = cdb_path;
dict_cdbm->tmp_path = tmp_path; dict_cdbm->tmp_path = tmp_path;
cdb_path = tmp_path = 0; /* DICT_CDBM_OPEN_RETURN() */
dict_cdbm->dict.owner.uid = st1.st_uid; dict_cdbm->dict.owner.uid = st1.st_uid;
dict_cdbm->dict.owner.status = (st1.st_uid != 0); dict_cdbm->dict.owner.status = (st1.st_uid != 0);
close_on_exec(fd, CLOSE_ON_EXEC); close_on_exec(fd, CLOSE_ON_EXEC);
@@ -400,7 +424,7 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
if (dict_flags & DICT_FLAG_FOLD_FIX) if (dict_flags & DICT_FLAG_FOLD_FIX)
dict_cdbm->dict.fold_buf = vstring_alloc(10); dict_cdbm->dict.fold_buf = vstring_alloc(10);
return (&dict_cdbm->dict); DICT_CDBM_OPEN_RETURN(DICT_DEBUG (&dict_cdbm->dict));
} }
/* dict_cdb_open - open data base for query mode or create mode */ /* dict_cdb_open - open data base for query mode or create mode */

View File

@@ -165,19 +165,34 @@ static DICT_CIDR_ENTRY *dict_cidr_parse_rule(char *p, VSTRING *why)
DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags) DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags)
{ {
DICT_CIDR *dict_cidr; DICT_CIDR *dict_cidr;
VSTREAM *map_fp; VSTREAM *map_fp = 0;
struct stat st; struct stat st;
VSTRING *line_buffer; VSTRING *line_buffer = 0;
VSTRING *why; VSTRING *why = 0;
DICT_CIDR_ENTRY *rule; DICT_CIDR_ENTRY *rule;
DICT_CIDR_ENTRY *last_rule = 0; DICT_CIDR_ENTRY *last_rule = 0;
int lineno = 0; int lineno = 0;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_CIDR_OPEN_RETURN(d) do { \
DICT *__d = (d); \
if (map_fp != 0 && vstream_fclose(map_fp)) \
msg_fatal("cidr map %s: read error: %m", mapname); \
if (line_buffer != 0) \
vstring_free(line_buffer); \
if (why != 0) \
vstring_free(why); \
return (__d); \
} while (0)
/* /*
* Sanity checks. * Sanity checks.
*/ */
if (open_flags != O_RDONLY) if (open_flags != O_RDONLY)
return (dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags, DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname,
open_flags, dict_flags,
"%s:%s map requires O_RDONLY access mode", "%s:%s map requires O_RDONLY access mode",
DICT_TYPE_CIDR, mapname)); DICT_TYPE_CIDR, mapname));
@@ -185,14 +200,12 @@ DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags)
* Open the configuration file. * Open the configuration file.
*/ */
if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0) if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
return (dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags, DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname,
open_flags, dict_flags,
"open %s: %m", mapname)); "open %s: %m", mapname));
if (fstat(vstream_fileno(map_fp), &st) < 0) if (fstat(vstream_fileno(map_fp), &st) < 0)
msg_fatal("fstat %s: %m", mapname); msg_fatal("fstat %s: %m", mapname);
/*
* No early returns without memory leaks.
*/
line_buffer = vstring_alloc(100); line_buffer = vstring_alloc(100);
why = vstring_alloc(100); why = vstring_alloc(100);
@@ -224,13 +237,5 @@ DICT *dict_cidr_open(const char *mapname, int open_flags, int dict_flags)
last_rule = rule; last_rule = rule;
} }
/* DICT_CIDR_OPEN_RETURN(DICT_DEBUG (&dict_cidr->dict));
* Clean up.
*/
if (vstream_fclose(map_fp))
msg_fatal("cidr map %s: read error: %m", mapname);
vstring_free(line_buffer);
vstring_free(why);
return (DICT_DEBUG (&dict_cidr->dict));
} }

View File

@@ -414,9 +414,19 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
DICT_DBM *dict_dbm; DICT_DBM *dict_dbm;
struct stat st; struct stat st;
DBM *dbm; DBM *dbm;
char *dbm_path; char *dbm_path = 0;
int lock_fd; int lock_fd;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_DBM_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (dbm_path != 0) \
myfree(dbm_path); \
return (__d); \
} while (0)
/* /*
* Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in
* the time domain) locking while accessing individual database records. * the time domain) locking while accessing individual database records.
@@ -427,8 +437,10 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
if (dict_flags & DICT_FLAG_LOCK) { if (dict_flags & DICT_FLAG_LOCK) {
dbm_path = concatenate(path, ".dir", (char *) 0); dbm_path = concatenate(path, ".dir", (char *) 0);
if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0) if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
return (dict_surrogate(DICT_TYPE_DBM, path, open_flags, dict_flags, DICT_DBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_DBM, path,
"open database %s: %m", dbm_path)); open_flags, dict_flags,
"open database %s: %m",
dbm_path));
if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0) if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
msg_fatal("shared-lock database %s for open: %m", dbm_path); msg_fatal("shared-lock database %s for open: %m", dbm_path);
} }
@@ -437,8 +449,10 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
* XXX SunOS 5.x has no const in dbm_open() prototype. * XXX SunOS 5.x has no const in dbm_open() prototype.
*/ */
if ((dbm = dbm_open((char *) path, open_flags, 0644)) == 0) if ((dbm = dbm_open((char *) path, open_flags, 0644)) == 0)
return (dict_surrogate(DICT_TYPE_DBM, path, open_flags, dict_flags, DICT_DBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_DBM, path,
"open database %s.{dir,pag}: %m", path)); open_flags, dict_flags,
"open database %s.{dir,pag}: %m",
path));
if (dict_flags & DICT_FLAG_LOCK) { if (dict_flags & DICT_FLAG_LOCK) {
if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0) if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
@@ -483,10 +497,7 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
dict_dbm->key_buf = 0; dict_dbm->key_buf = 0;
dict_dbm->val_buf = 0; dict_dbm->val_buf = 0;
if ((dict_flags & DICT_FLAG_LOCK)) DICT_DBM_OPEN_RETURN(DICT_DEBUG (&dict_dbm->dict));
myfree(dbm_path);
return (DICT_DEBUG (&dict_dbm->dict));
} }
#endif #endif

View File

@@ -548,6 +548,15 @@ DICT *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
int mdb_flags, slmdb_flags, status; int mdb_flags, slmdb_flags, status;
int db_fd; int db_fd;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_LMDB_OPEN_RETURN(d) { \
DICT *__d = (d); \
myfree(mdb_path); \
return (__d); \
} while (0)
mdb_path = concatenate(path, "." DICT_TYPE_LMDB, (char *) 0); mdb_path = concatenate(path, "." DICT_TYPE_LMDB, (char *) 0);
/* /*
@@ -583,12 +592,17 @@ DICT *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
* As a workaround the postmap(1) and postalias(1) commands turn on * As a workaround the postmap(1) and postalias(1) commands turn on
* MDB_WRITEMAP which disables the use of malloc() in LMDB. However, that * MDB_WRITEMAP which disables the use of malloc() in LMDB. However, that
* does not address several disclosures of stack memory. Other Postfix * does not address several disclosures of stack memory. Other Postfix
* databases do not need this workaround: those databases are maintained * databases are maintained by Postfix daemon processes, and are
* by Postfix daemon processes, and are accessible only by the postfix * accessible only by the postfix user.
* user. *
* LMDB 0.9.10 by default does not write uninitialized heap memory to file
* (specify MDB_NOMEMINIT to revert that change). We use the MDB_WRITEMAP
* workaround for older LMDB versions.
*/ */
#ifndef MDB_NOMEMINIT
if (dict_flags & DICT_FLAG_WORLD_READ) if (dict_flags & DICT_FLAG_WORLD_READ)
mdb_flags |= MDB_WRITEMAP; mdb_flags |= MDB_WRITEMAP;
#endif
/* /*
* Gracefully handle most database open errors. * Gracefully handle most database open errors.
@@ -599,8 +613,7 @@ DICT *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
slmdb_flags)) != 0) { slmdb_flags)) != 0) {
dict = dict_surrogate(DICT_TYPE_LMDB, path, open_flags, dict_flags, dict = dict_surrogate(DICT_TYPE_LMDB, path, open_flags, dict_flags,
"open database %s: %s", mdb_path, mdb_strerror(status)); "open database %s: %s", mdb_path, mdb_strerror(status));
myfree(mdb_path); DICT_LMDB_OPEN_RETURN(dict);
return (dict);
} }
/* /*
@@ -682,9 +695,7 @@ DICT *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
*/ */
dict_lmdb->slmdb = slmdb; dict_lmdb->slmdb = slmdb;
myfree(mdb_path); DICT_LMDB_OPEN_RETURN(DICT_DEBUG (&dict_lmdb->dict));
return (DICT_DEBUG (&dict_lmdb->dict));
} }
#endif #endif

View File

@@ -807,20 +807,33 @@ static DICT_PCRE_RULE *dict_pcre_parse_rule(const char *mapname, int lineno,
DICT *dict_pcre_open(const char *mapname, int open_flags, int dict_flags) DICT *dict_pcre_open(const char *mapname, int open_flags, int dict_flags)
{ {
DICT_PCRE *dict_pcre; DICT_PCRE *dict_pcre;
VSTREAM *map_fp; VSTREAM *map_fp = 0;
struct stat st; struct stat st;
VSTRING *line_buffer; VSTRING *line_buffer = 0;
DICT_PCRE_RULE *last_rule = 0; DICT_PCRE_RULE *last_rule = 0;
DICT_PCRE_RULE *rule; DICT_PCRE_RULE *rule;
int lineno = 0; int lineno = 0;
int nesting = 0; int nesting = 0;
char *p; char *p;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_PCRE_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (map_fp != 0) \
vstream_fclose(map_fp); \
if (line_buffer != 0) \
vstring_free(line_buffer); \
return (__d); \
} while (0)
/* /*
* Sanity checks. * Sanity checks.
*/ */
if (open_flags != O_RDONLY) if (open_flags != O_RDONLY)
return (dict_surrogate(DICT_TYPE_PCRE, mapname, open_flags, dict_flags, DICT_PCRE_OPEN_RETURN(dict_surrogate(DICT_TYPE_PCRE, mapname,
open_flags, dict_flags,
"%s:%s map requires O_RDONLY access mode", "%s:%s map requires O_RDONLY access mode",
DICT_TYPE_PCRE, mapname)); DICT_TYPE_PCRE, mapname));
@@ -828,7 +841,8 @@ DICT *dict_pcre_open(const char *mapname, int open_flags, int dict_flags)
* Open the configuration file. * Open the configuration file.
*/ */
if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0) if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
return (dict_surrogate(DICT_TYPE_PCRE, mapname, open_flags, dict_flags, DICT_PCRE_OPEN_RETURN(dict_surrogate(DICT_TYPE_PCRE, mapname,
open_flags, dict_flags,
"open %s: %m", mapname)); "open %s: %m", mapname));
if (fstat(vstream_fileno(map_fp), &st) < 0) if (fstat(vstream_fileno(map_fp), &st) < 0)
msg_fatal("fstat %s: %m", mapname); msg_fatal("fstat %s: %m", mapname);
@@ -880,10 +894,7 @@ DICT *dict_pcre_open(const char *mapname, int open_flags, int dict_flags)
msg_warn("pcre map %s, line %d: more IFs than ENDIFs", msg_warn("pcre map %s, line %d: more IFs than ENDIFs",
mapname, lineno); mapname, lineno);
vstring_free(line_buffer); DICT_PCRE_OPEN_RETURN(DICT_DEBUG (&dict_pcre->dict));
vstream_fclose(map_fp);
return (DICT_DEBUG (&dict_pcre->dict));
} }
#endif /* HAS_PCRE */ #endif /* HAS_PCRE */

View File

@@ -738,9 +738,9 @@ static DICT_REGEXP_RULE *dict_regexp_parseline(const char *mapname, int lineno,
DICT *dict_regexp_open(const char *mapname, int open_flags, int dict_flags) DICT *dict_regexp_open(const char *mapname, int open_flags, int dict_flags)
{ {
DICT_REGEXP *dict_regexp; DICT_REGEXP *dict_regexp;
VSTREAM *map_fp; VSTREAM *map_fp = 0;
struct stat st; struct stat st;
VSTRING *line_buffer; VSTRING *line_buffer = 0;
DICT_REGEXP_RULE *rule; DICT_REGEXP_RULE *rule;
DICT_REGEXP_RULE *last_rule = 0; DICT_REGEXP_RULE *last_rule = 0;
int lineno = 0; int lineno = 0;
@@ -748,11 +748,24 @@ DICT *dict_regexp_open(const char *mapname, int open_flags, int dict_flags)
int nesting = 0; int nesting = 0;
char *p; char *p;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_REGEXP_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (line_buffer != 0) \
vstring_free(line_buffer); \
if (map_fp != 0) \
vstream_fclose(map_fp); \
return (__d); \
} while (0)
/* /*
* Sanity checks. * Sanity checks.
*/ */
if (open_flags != O_RDONLY) if (open_flags != O_RDONLY)
return (dict_surrogate(DICT_TYPE_REGEXP, mapname, open_flags, dict_flags, DICT_REGEXP_OPEN_RETURN(dict_surrogate(DICT_TYPE_REGEXP,
mapname, open_flags, dict_flags,
"%s:%s map requires O_RDONLY access mode", "%s:%s map requires O_RDONLY access mode",
DICT_TYPE_REGEXP, mapname)); DICT_TYPE_REGEXP, mapname));
@@ -760,7 +773,8 @@ DICT *dict_regexp_open(const char *mapname, int open_flags, int dict_flags)
* Open the configuration file. * Open the configuration file.
*/ */
if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0) if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
return (dict_surrogate(DICT_TYPE_REGEXP, mapname, open_flags, dict_flags, DICT_REGEXP_OPEN_RETURN(dict_surrogate(DICT_TYPE_REGEXP, mapname,
open_flags, dict_flags,
"open %s: %m", mapname)); "open %s: %m", mapname));
if (fstat(vstream_fileno(map_fp), &st) < 0) if (fstat(vstream_fileno(map_fp), &st) < 0)
msg_fatal("fstat %s: %m", mapname); msg_fatal("fstat %s: %m", mapname);
@@ -818,13 +832,7 @@ DICT *dict_regexp_open(const char *mapname, int open_flags, int dict_flags)
dict_regexp->pmatch = dict_regexp->pmatch =
(regmatch_t *) mymalloc(sizeof(regmatch_t) * (max_sub + 1)); (regmatch_t *) mymalloc(sizeof(regmatch_t) * (max_sub + 1));
/* DICT_REGEXP_OPEN_RETURN(DICT_DEBUG (&dict_regexp->dict));
* Clean up.
*/
vstring_free(line_buffer);
vstream_fclose(map_fp);
return (DICT_DEBUG (&dict_regexp->dict));
} }
#endif #endif

View File

@@ -309,21 +309,31 @@ static void dict_sockmap_close(DICT *dict)
DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags) DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
{ {
DICT_SOCKMAP *dp; DICT_SOCKMAP *dp;
char *saved_name; char *saved_name = 0;
char *sockmap; char *sockmap;
DICT_SOCKMAP_REFC_HANDLE *ref_handle; DICT_SOCKMAP_REFC_HANDLE *ref_handle;
HTABLE_INFO *client_info; HTABLE_INFO *client_info;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_SOCKMAP_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (saved_name != 0) \
myfree(saved_name); \
return (__d); \
} while (0)
/* /*
* Sanity checks. * Sanity checks.
*/ */
if (open_flags != O_RDONLY) if (open_flags != O_RDONLY)
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname, DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
open_flags, dict_flags, open_flags, dict_flags,
"%s:%s map requires O_RDONLY access mode", "%s:%s map requires O_RDONLY access mode",
DICT_TYPE_SOCKMAP, mapname)); DICT_TYPE_SOCKMAP, mapname));
if (dict_flags & DICT_FLAG_NO_UNAUTH) if (dict_flags & DICT_FLAG_NO_UNAUTH)
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname, DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
open_flags, dict_flags, open_flags, dict_flags,
"%s:%s map is not allowed for security-sensitive data", "%s:%s map is not allowed for security-sensitive data",
DICT_TYPE_SOCKMAP, mapname)); DICT_TYPE_SOCKMAP, mapname));
@@ -333,7 +343,7 @@ DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
*/ */
saved_name = mystrdup(mapname); saved_name = mystrdup(mapname);
if ((sockmap = split_at_right(saved_name, ':')) == 0) if ((sockmap = split_at_right(saved_name, ':')) == 0)
return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname, DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
open_flags, dict_flags, open_flags, dict_flags,
"%s requires server:socketmap argument", "%s requires server:socketmap argument",
DICT_TYPE_SOCKMAP)); DICT_TYPE_SOCKMAP));
@@ -370,10 +380,5 @@ DICT *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
/* Don't look up parent domains or network superblocks. */ /* Don't look up parent domains or network superblocks. */
dp->dict.flags = dict_flags | DICT_FLAG_PATTERN; dp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
/* DICT_SOCKMAP_OPEN_RETURN(DICT_DEBUG (&dp->dict));
* Clean up.
*/
myfree(saved_name);
return (DICT_DEBUG (&dp->dict));
} }

View File

@@ -145,7 +145,7 @@ static void dict_thash_close(DICT *dict)
DICT *dict_thash_open(const char *path, int open_flags, int dict_flags) DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
{ {
DICT_THASH *dict_thash; DICT_THASH *dict_thash;
VSTREAM *fp; VSTREAM *fp = 0;
struct stat st; struct stat st;
time_t before; time_t before;
time_t after; time_t after;
@@ -156,11 +156,24 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
HTABLE *table; HTABLE *table;
HTABLE_INFO *ht; HTABLE_INFO *ht;
/*
* Let the optimizer worry about eliminating redundant code.
*/
#define DICT_THASH_OPEN_RETURN(d) { \
DICT *__d = (d); \
if (fp != 0) \
vstream_fclose(fp); \
if (line_buffer != 0) \
vstring_free(line_buffer); \
return (__d); \
} while (0)
/* /*
* Sanity checks. * Sanity checks.
*/ */
if (open_flags != O_RDONLY) if (open_flags != O_RDONLY)
return (dict_surrogate(DICT_TYPE_THASH, path, open_flags, dict_flags, DICT_THASH_OPEN_RETURN(dict_surrogate(DICT_TYPE_THASH, path,
open_flags, dict_flags,
"%s:%s map requires O_RDONLY access mode", "%s:%s map requires O_RDONLY access mode",
DICT_TYPE_THASH, path)); DICT_TYPE_THASH, path));
@@ -170,7 +183,8 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
*/ */
for (before = time((time_t *) 0); /* see below */ ; before = after) { for (before = time((time_t *) 0); /* see below */ ; before = after) {
if ((fp = vstream_fopen(path, open_flags, 0644)) == 0) { if ((fp = vstream_fopen(path, open_flags, 0644)) == 0) {
return (dict_surrogate(DICT_TYPE_THASH, path, open_flags, dict_flags, DICT_THASH_OPEN_RETURN(dict_surrogate(DICT_TYPE_THASH, path,
open_flags, dict_flags,
"open database %s: %m", path)); "open database %s: %m", path));
} }
if (line_buffer == 0) if (line_buffer == 0)
@@ -240,6 +254,7 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
msg_fatal("fstat %s: %m", path); msg_fatal("fstat %s: %m", path);
if (vstream_fclose(fp)) if (vstream_fclose(fp))
msg_fatal("read %s: %m", path); msg_fatal("read %s: %m", path);
fp = 0; /* DICT_THASH_OPEN_RETURN() */
after = time((time_t *) 0); after = time((time_t *) 0);
if (st.st_mtime < before - 1 || st.st_mtime > after) if (st.st_mtime < before - 1 || st.st_mtime > after)
break; break;
@@ -252,7 +267,6 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
msg_info("pausing to let file %s cool down", path); msg_info("pausing to let file %s cool down", path);
doze(300000); doze(300000);
} }
vstring_free(line_buffer);
/* /*
* Create the in-memory table. * Create the in-memory table.
@@ -270,5 +284,5 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags)
dict_thash->dict.owner.uid = st.st_uid; dict_thash->dict.owner.uid = st.st_uid;
dict_thash->dict.owner.status = (st.st_uid != 0); dict_thash->dict.owner.status = (st.st_uid != 0);
return (DICT_DEBUG (&dict_thash->dict)); DICT_THASH_OPEN_RETURN(DICT_DEBUG (&dict_thash->dict));
} }

View File

@@ -94,8 +94,10 @@ int mac_parse(const char *value, MAC_PARSE_FN action, char *context)
int level; int level;
int status = 0; int status = 0;
#define SKIP(start, var, cond) \ #define SKIP(start, var, cond) do { \
for (var = start; *var && (cond); var++); for (var = start; *var && (cond); var++) \
/* void */; \
} while (0)
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: %s", myname, value); msg_info("%s: %s", myname, value);

View File

@@ -68,14 +68,17 @@ const char *split_nameval(char *buf, char **name, char **value)
/* /*
* Ugly macros to make complex expressions less unreadable. * Ugly macros to make complex expressions less unreadable.
*/ */
#define SKIP(start, var, cond) \ #define SKIP(start, var, cond) do { \
for (var = start; *var && (cond); var++); for (var = start; *var && (cond); var++) \
/* void */; \
} while (0)
#define TRIM(s) { \ #define TRIM(s) do { \
char *p; \ char *p; \
for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--); \ for (p = (s) + strlen(s); p > (s) && ISSPACE(p[-1]); p--) \
/* void */; \
*p = 0; \ *p = 0; \
} } while (0)
SKIP(buf, np, ISSPACE(*np)); /* find name begin */ SKIP(buf, np, ISSPACE(*np)); /* find name begin */
if (*np == 0) if (*np == 0)

View File

@@ -125,6 +125,7 @@ VBUF *vbuf_print(VBUF *bp, const char *format, va_list ap)
unsigned long_flag; /* long or plain integer */ unsigned long_flag; /* long or plain integer */
int ch; int ch;
char *s; char *s;
int saved_errno = errno; /* VBUF_SPACE() may clobber it */
/* /*
* Assume that format strings are short. * Assume that format strings are short.
@@ -241,7 +242,7 @@ VBUF *vbuf_print(VBUF *bp, const char *format, va_list ap)
VBUF_SKIP(bp); VBUF_SKIP(bp);
break; break;
case 'm': case 'm':
VBUF_STRCAT(bp, strerror(errno)); VBUF_STRCAT(bp, strerror(saved_errno));
break; break;
case 'p': case 'p':
if (VBUF_SPACE(bp, (width > prec ? width : prec) + PTR_SPACE)) if (VBUF_SPACE(bp, (width > prec ? width : prec) + PTR_SPACE))