]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20131114
authorWietse Venema <wietse@porcupine.org>
Thu, 14 Nov 2013 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Fri, 15 Nov 2013 04:30:32 +0000 (23:30 -0500)
40 files changed:
postfix/HISTORY
postfix/README_FILES/SASL_README
postfix/RELEASE_NOTES-2.10 [moved from postfix/RELEASE_NOTES_2.10 with 100% similarity]
postfix/WISHLIST
postfix/html/SASL_README.html
postfix/html/master.5.html
postfix/html/smtp-sink.1.html
postfix/man/man5/master.5
postfix/proto/SASL_README.html
postfix/proto/master
postfix/src/cleanup/cleanup_addr.c
postfix/src/cleanup/cleanup_map11.c
postfix/src/cleanup/cleanup_map1n.c
postfix/src/cleanup/cleanup_masquerade.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/global/mail_params.c
postfix/src/global/mail_version.h
postfix/src/milter/test-milter.c
postfix/src/postconf/postconf_master.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.in
postfix/src/smtpd/smtpd_check.in2
postfix/src/smtpd/smtpd_check.ref
postfix/src/smtpd/smtpd_check.ref2
postfix/src/smtpstone/smtp-sink.c
postfix/src/tls/tls_server.c
postfix/src/util/Makefile.in
postfix/src/util/dict_cdb.c
postfix/src/util/dict_cidr.c
postfix/src/util/dict_dbm.c
postfix/src/util/dict_lmdb.c
postfix/src/util/dict_pcre.c
postfix/src/util/dict_regexp.c
postfix/src/util/dict_sockmap.c
postfix/src/util/dict_thash.c
postfix/src/util/mac_parse.c
postfix/src/util/split_nameval.c
postfix/src/util/vbuf_print.c

index b914324e7aeb718fd103ab8a5d0fe92c1dc82530..cb6cd436a8f8116b9d9a46db50d2d96bff19968f 100644 (file)
@@ -19069,7 +19069,45 @@ Apologies for any names omitted.
        not hurt to do this also for HTML.  Files: proto/Makefile.in,
        proto/MULTI_INSTANCE_README.html.
 
-20121104
+20131104
 
        Feature: ${queue_id} macro support for the pipe(8) delivery
        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.
index 66b9b415d599dcaf5aa5a42cc234da7979dc3613..3f03f30d4aac5d34699cf0cb82b9b1788d8f0736 100644 (file)
@@ -557,10 +557,10 @@ plaintext.
 
     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
-    directly, with appropriate configuration in saslauthd.conf. This may be
-    documented in a later version of this document. You will not be able to use
-    any of the methods that require access to plaintext passwords, such as the
-    shared-secret methods CRAM-MD5 and DIGEST-MD5.
+    directly, with appropriate configuration in saslauthd.conf, as described
+    here. You will not be able to use any of the methods that require access to
+    plaintext passwords, such as the shared-secret methods CRAM-MD5 and DIGEST-
+    MD5.
 
 The ldapdb plugin implements proxy authorization. This means that the ldapdb
 plugin uses its own username and password to authenticate with the LDAP server,
index 5afdd4ed5e2aa82f40829a4118bdce1e7ec0b571..aa77857b81091dd66eaae8b8f934b3991dfcc0c4 100644 (file)
@@ -1,8 +1,17 @@
 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.
 
-       Add watchdog timer to postmap/postalias.
+       Watchdog timer to postmap/postalias.
+
+       C99 va_copy() support.
 
        Things to do before the stable release:
 
index e39391fe7bb234176fd1e4df131ec445ff84ab20..5e75ee5fb2a03180153f26668f6c1f75cbc41264 100644 (file)
@@ -948,8 +948,9 @@ stored as plaintext. </p>
 <p> If you must store encrypted passwords, you cannot use the ldapdb
 auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
 to query the LDAP database directly, with appropriate configuration
-in <code>saslauthd.conf</code>. This may be documented in a later
-version of this document.  You will not be able to use any of the
+in <code>saslauthd.conf</code>, <a
+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
 shared-secret methods CRAM-MD5 and DIGEST-MD5.  </p>
 
index 01cc4ef5a73150ef49f336875d5943136563d505..749de3a879b5ccc265970b5b94d00286375a38da 100644 (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-
                      tion parameter in <a href="postconf.5.html">main.cf</a>).
 
-                     On Solaris systems the <b>unix</b> type  is  imple-
-                     mented with streams sockets.
+                     On Solaris 8 and earlier  systems  the  <b>unix</b>
+                     type is implemented with streams sockets.
 
               <b>fifo</b>   The  service  listens on a FIFO (named pipe)
                      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-
                      tion parameter in <a href="postconf.5.html">main.cf</a>).
 
-                     On  Solaris  systems the <b>pass</b> type is imple-
-                     mented with streams sockets.
+                     On  Solaris  8  and earlier systems the <b>pass</b>
+                     type is implemented with streams sockets.
 
                      This feature is available as of Postfix ver-
                      sion 2.5.
@@ -225,8 +225,8 @@ MASTER(5)                                                            MASTER(5)
                      to  understand  and  maintain.  At a certain
                      point, it might be easier to configure  mul-
                      tiple  instances of Postfix, instead of con-
-                     figuring  multiple  personalities  via  mas-
-                     ter.cf.
+                     figuring  multiple  personalities  via  <a href="master.5.html">mas-
+                     ter.cf</a>.
 
               <b>-v</b>     Increase  the verbose logging level. Specify
                      multiple <b>-v</b> options to make a Postfix daemon
index 18768e9455b4436b042ad85f2ab312e38a6070b8..96f49a0e347c048d69cb7886d5e8c865107d39d1 100644 (file)
@@ -12,7 +12,7 @@ SMTP-SINK(1)                                                      SMTP-SINK(1)
 <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>unix:</b><i>pathname backlog</i>
+       <b>smtp-sink</b> [<i>options</i>] <b>unix:<i></b>pathname backlog</i>
 
 <b>DESCRIPTION</b>
        <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> <i>delay</i>
+       <b>-A <i></b>delay\e[0m
               Wait  <i>delay</i>  seconds after responding to DATA, then
               abort prematurely with a 550 reply status.  Do  not
               read  further  input  from  the  client; this is an
               attempt to block the client before  it  sends  ".".
               Specify a zero delay value to abort immediately.
 
-       <b>-b</b> <i>soft-bounce-reply</i>
+       <b>-b <i></b>soft-bounce-reply\e[0m
               Use  <i>soft-bounce-reply</i>  for  soft reject responses.
               The default reply  is  "450  4.3.0  Error:  command
               failed".
 
-       <b>-B</b> <i>hard-bounce-reply</i>
+       <b>-B <i></b>hard-bounce-reply\e[0m
               Use  <i>hard-bounce-reply</i>  for  hard reject responses.
               The default reply  is  "500  5.3.0  Error:  command
               failed".
@@ -70,7 +70,7 @@ SMTP-SINK(1)                                                      SMTP-SINK(1)
 
        <b>-C</b>     Disable XCLIENT support.
 
-       <b>-d</b> <i>dump-template</i>
+       <b>-d <i></b>dump-template\e[0m
               Dump each mail transaction to a single-message file
               whose name is created by  expanding  the  <i>dump-tem-</i>
               <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
               every mail transaction in progress.
 
-       <b>-D</b> <i>dump-template</i>
+       <b>-D <i></b>dump-template\e[0m
               Append  mail  transactions  to a multi-message dump
               file whose name is created by expanding  the  <i>dump-</i>
               <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>-f</b> <i>command,command,...</i>
+       <b>-f <i></b>command,command,...\e[0m
               Reject  the  specified  commands  with a hard (5xx)
               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>-h</b> <i>hostname</i>
+       <b>-h <i></b>hostname\e[0m
               Use <i>hostname</i> in the  SMTP  greeting,  in  the  HELO
               response,  and  in  the  EHLO response. The default
               hostname is "smtp-sink".
 
        <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-
               ous  connections  that  <b>smtp-sink</b> will handle. This
               prevents the  process  from  running  out  of  file
               descriptors. Excess connections will stay queued in
               the TCP/IP stack.
 
-       <b>-M</b> <i>count</i>
+       <b>-M <i></b>count\e[0m
               Terminate after receiving <i>count</i> messages.
 
-       <b>-n</b> <i>count</i>
+       <b>-n <i></b>count\e[0m
               Terminate after <i>count</i> sessions.
 
        <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
               come through a CISCO PIX system. Implies <b>-e</b>.
 
-       <b>-q</b> <i>command,command,...</i>
+       <b>-q <i></b>command,command,...\e[0m
               Disconnect (without replying) after  receiving  one
               of the specified commands.
 
@@ -146,7 +146,7 @@ SMTP-SINK(1)                                                      SMTP-SINK(1)
               and use quotes to  protect  white  space  from  the
               shell. Command names are case-insensitive.
 
-       <b>-Q</b> <i>command,command,...</i>
+       <b>-Q <i></b>command,command,...\e[0m
               Send a 421 reply and disconnect after receiving one
               of the specified commands.
 
@@ -156,7 +156,7 @@ SMTP-SINK(1)                                                      SMTP-SINK(1)
               and  use  quotes  to  protect  white space from the
               shell. Command names are case-insensitive.
 
-       <b>-r</b> <i>command,command,...</i>
+       <b>-r <i></b>command,command,...\e[0m
               Reject the specified commands  with  a  soft  (4xx)
               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
               shell. Command names are case-insensitive.
 
-       <b>-R</b> <i>root-directory</i>
+       <b>-R <i></b>root-directory\e[0m
               Change  the process root directory to the specified
               location.  This option requires  super-user  privi-
               leges. See also the <b>-u</b> option.
 
-       <b>-s</b> <i>command,command,...</i>
+       <b>-s <i></b>command,command,...\e[0m
               Log the named commands to syslogd.
 
               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
               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
               response.   The time limit is specified in seconds.
 
-       <b>-T</b> <i>windowsize</i>
+       <b>-T <i></b>windowsize\e[0m
               Override the  default  TCP  window  size.  To  work
               around  broken  TCP window scaling implementations,
               specify a value &gt; 0 and &lt; 65536.
 
-       <b>-u</b> <i>username</i>
+       <b>-u <i></b>username\e[0m
               Switch to the specified user privileges after open-
               ing  the network socket and optionally changing the
               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>-w</b> <i>delay</i>
+       <b>-w <i></b>delay\e[0m
               Wait <i>delay</i> seconds before responding to a DATA com-
               mand.
 
-       <b>-W</b> <i>command:delay[:odds]</i>
+       <b>-W <i></b>command:delay[:odds]\e[0m
               Wait  <i>delay</i>  seconds  before responding to <i>command</i>.
               If <i>odds</i> is also specified (a  number  between  1-99
               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
               specified in numeric or symbolic form.
 
-       <b>unix:</b><i>pathname</i>
+       <b>unix:<i></b>pathname\e[0m
               Listen on the UNIX-domain socket at <i>pathname</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-
        lows:
 
-       <b>X-Client-Addr:</b> <i>text</i>
+       <b>X-Client-Addr: <i></b>text\e[0m
               The client IP address without enclosing []. An IPv6
               address is prefixed with "ipv6:".  This  record  is
               always present.
 
-       <b>X-Client-Proto:</b> <i>text</i>
+       <b>X-Client-Proto: <i></b>text\e[0m
               The  client  protocol:  SMTP,  ESMTP  or LMTP. This
               record is always present.
 
-       <b>X-Helo-Args:</b> <i>text</i>
+       <b>X-Helo-Args: <i></b>text\e[0m
               The arguments of the  last  HELO  or  EHLO  command
               before  this mail delivery transaction. This record
               is present only if the client sent  a  recognizable
               HELO or EHLO command before the DATA command.
 
-       <b>X-Mail-Args:</b> <i>text</i>
+       <b>X-Mail-Args: <i></b>text\e[0m
               The arguments of the MAIL command that started this
               mail delivery transaction. This record  is  present
               exactly once.
 
-       <b>X-Rcpt-Args:</b> <i>text</i>
+       <b>X-Rcpt-Args: <i></b>text\e[0m
               The  arguments  of an RCPT command within this mail
               delivery transaction. There is one record for  each
               RCPT  command, and they are in the order as sent by
               the client.
 
-       <b>Received:</b> <i>text</i>
+       <b>Received: <i></b>text\e[0m
               A message header for compatibility with  mail  pro-
               cessing  software. This three-line header marks the
               end of the headers provided by  <b>smtp-sink</b>,  and  is
               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
                      IP address.  If the client did not send HELO
                      or  EHLO,  the  client  IP  address  is used
                      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   client  protocol  (see  <b>X-Client-Proto</b>
                      above), and the pseudo-random portion of the
index 644ce57ea7a202d413cc1dcdade69ffb484da368..9f31fa5a6497017f33db010364fcf7e8b2d5c87c 100644 (file)
@@ -92,8 +92,8 @@ The service name is a pathname relative to the Postfix
 queue directory (pathname controlled with the \fBqueue_directory\fR
 configuration parameter in main.cf).
 .sp
-On Solaris systems the \fBunix\fR type is implemented with
-streams sockets.
+On Solaris 8 and earlier systems the \fBunix\fR type is
+implemented with streams sockets.
 .IP \fBfifo\fR
 The service listens on a FIFO (named pipe) and is accessible
 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
 configuration parameter in main.cf).
 .sp
-On Solaris systems the \fBpass\fR type is implemented with
-streams sockets.
+On Solaris 8 and earlier systems the \fBpass\fR type is
+implemented with streams sockets.
 
 This feature is available as of Postfix version 2.5.
 .RE
index 1b2511a624d69ff2cb96ef0e8f90d3b732dd4cf4..75363e61a57b94ea5a8a2e09f70bdd3982f90c46 100644 (file)
@@ -948,8 +948,9 @@ stored as plaintext. </p>
 <p> If you must store encrypted passwords, you cannot use the ldapdb
 auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
 to query the LDAP database directly, with appropriate configuration
-in <code>saslauthd.conf</code>. This may be documented in a later
-version of this document.  You will not be able to use any of the
+in <code>saslauthd.conf</code>, <a
+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
 shared-secret methods CRAM-MD5 and DIGEST-MD5.  </p>
 
index acd381caf23ceb49c2de5c33d252301c8dd8c7fd..e392da3f22da83d3bf3055659739128110b8be55 100644 (file)
@@ -86,8 +86,8 @@
 #      queue directory (pathname controlled with the \fBqueue_directory\fR
 #      configuration parameter in main.cf).
 # .sp
-#      On Solaris systems the \fBunix\fR type is implemented with
-#      streams sockets.
+#      On Solaris 8 and earlier systems the \fBunix\fR type is
+#      implemented with streams sockets.
 # .IP \fBfifo\fR
 #      The service listens on a FIFO (named pipe) and is accessible
 #      for local clients only.
 #      queue directory (pathname controlled with the \fBqueue_directory\fR
 #      configuration parameter in main.cf).
 # .sp
-#      On Solaris systems the \fBpass\fR type is implemented with
-#      streams sockets.
+#      On Solaris 8 and earlier systems the \fBpass\fR type is
+#      implemented with streams sockets.
 #
 #      This feature is available as of Postfix version 2.5.
 # .RE
index 233ba37caee8a8b1b67fb036ef12f0f02aeae314..f8e0596c438279938f05b6806b0fc99fde6107e7 100644 (file)
@@ -149,7 +149,8 @@ void    cleanup_addr_sender(CLEANUP_STATE *state, const char *buf)
                                  IGNORE_EXTENSION)) != 0) {
            cleanup_addr_bcc(state, bcc);
        } 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->errs |= CLEANUP_STAT_WRITE;
        }
@@ -198,7 +199,8 @@ void    cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf)
                                  IGNORE_EXTENSION)) != 0) {
            cleanup_addr_bcc(state, bcc);
        } 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->errs |= CLEANUP_STAT_WRITE;
        }
index 626b9ff3acaa15df7f30100e32813d11e9f65a4d..2e892fda0a9800840cc5cf5b05efbf4756568988 100644 (file)
@@ -120,7 +120,8 @@ int     cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
            if (expand_to_self)
                return (did_rewrite);
        } 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->errs |= CLEANUP_STAT_WRITE;
            return (did_rewrite);
@@ -128,7 +129,8 @@ int     cleanup_map11_external(CLEANUP_STATE *state, VSTRING *addr,
            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));
     return (did_rewrite);
 }
index f7088a06b56edf7fa87746879d71d8bf747efbe9..7f9919466e195679569033e812a9af3912b7c490 100644 (file)
@@ -112,7 +112,7 @@ ARGV   *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
     for (arg = 0; arg < argv->argc; arg++) {
        if (argv->argc > var_virt_expan_limit) {
            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->errs |= CLEANUP_STAT_DEFER;
            UPDATE(state->reason, "4.6.0 Alias expansion error");
@@ -128,7 +128,7 @@ ARGV   *cleanup_map1n_internal(CLEANUP_STATE *state, const char *addr,
                break;
            if (count >= var_virt_recur_limit) {
                msg_warn("%s: unreasonable %s map nesting for %s -- "
-                        "deferring delivery",
+                        "message not accepted, try again later",
                         state->queue_id, maps->title, addr);
                state->errs |= CLEANUP_STAT_DEFER;
                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);
            } else if (maps->error != 0) {
                msg_warn("%s: %s map lookup problem for %s -- "
-                        "deferring delivery",
+                        "message not accepted, try again later",
                         state->queue_id, maps->title, addr);
                state->errs |= CLEANUP_STAT_WRITE;
                UPDATE(state->reason, "4.6.0 Alias expansion error");
index 70577da1ebfe60886bd08bcb61c1a5d78c084202..a8540308cfd0a8805e0270d8af64f1b060d761a5 100644 (file)
@@ -110,7 +110,8 @@ int     cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr,
        excluded = (string_list_match(cleanup_masq_exceptions, lowercase(name)) != 0);
        myfree(name);
        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->errs |= CLEANUP_STAT_WRITE;
        }
index ffb5c7e527d74d09655fdf3e914b78d0a5f69c19..aa1fe6c5bbb36f180d19339867258c1674cdd3d2 100644 (file)
@@ -499,7 +499,8 @@ static void cleanup_header_callback(void *context, int header_class,
                myfree((char *) result);
            }
        } 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->errs |= CLEANUP_STAT_WRITE;
        }
@@ -789,7 +790,8 @@ static void cleanup_body_callback(void *context, int type,
                return;
            }
        } 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->errs |= CLEANUP_STAT_WRITE;
        }
index 7616780f5ebd35cfc44e46ec297e1f564c592c67..e6a74e84d881dbe448cdcc340bf24a9673d2188f 100644 (file)
@@ -392,7 +392,8 @@ static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf)
     if (ret == 0) {
        return (0);
     } 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->errs |= CLEANUP_STAT_WRITE;
        return (0);
@@ -2092,7 +2093,7 @@ void    cleanup_milter_emul_rcpt(CLEANUP_STATE *state,
        && cleanup_milter_apply(state, "RCPT", resp) != 0) {
        msg_warn("%s: milter configuration error: can't reject recipient "
                 "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");
        state->errs |= CLEANUP_STAT_DEFER;
     }
index b2ec918d8711e4e32c880b05cb824aec10f6f634..2d919776c050e844a87c35476fcd16c73c10bff9 100644 (file)
@@ -487,14 +487,17 @@ static char *read_param_from_file(const char *path)
     /*
      * Ugly macros to make complex expressions less unreadable.
      */
-#define SKIP(start, var, cond) \
-       for (var = start; *var && (cond); var++);
+#define SKIP(start, var, cond) do { \
+       for (var = start; *var && (cond); var++) \
+           /* void */; \
+    } while (0)
 
-#define TRIM(s) { \
+#define TRIM(s) do { \
        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; \
-    }
+    } while (0)
 
     fp = safe_open(path, O_RDONLY, 0, (struct stat *) 0, -1, -1, why);
     if (fp == 0)
index af0c64ee1a73e118e3057167d1a34a416099ec84..13cd38b5d21e6c81fe7bc41c68286b53f8f46377 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20131105"
+#define MAIL_RELEASE_DATE      "20131114"
 #define MAIL_VERSION_NUMBER    "2.11"
 
 #ifdef SNAPSHOT
index 58e6728f5fd91a7c0248bdd5ea7fad439c8d33f0..26be0f7c222c7ef6ec6bdf2162c9fbc693eb0a94 100644 (file)
@@ -31,6 +31,9 @@
 /*     Terminate after \fIcount\fR connections.
 /* .IP "\fB-d\fI level\fR"
 /*     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
 /*     Replace the sender by the specified address.
 /* .IP "\fB-h \fI'index header-label header-value'\fR"
@@ -159,8 +162,10 @@ static char *body_file;
 #endif
 
 #define MAX_RCPT       10
-int     rcpt_count = 0;
-char   *rcpt_addr[MAX_RCPT];
+int     add_rcpt_count = 0;
+char   *add_rcpt[MAX_RCPT];
+int     del_rcpt_count = 0;
+char   *del_rcpt[MAX_RCPT];
 
 static const char *macro_names[] = {
     "_",
@@ -354,9 +359,13 @@ static sfsistat test_eom(SMFICTX *ctx)
     {
        int     count;
 
-       for (count = 0; count < rcpt_count; count++)
-           if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE)
-               fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]);
+       for (count = 0; count < add_rcpt_count; count++)
+           if (smfi_addrcpt(ctx, add_rcpt[count]) == MI_FAILURE)
+               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));
 }
@@ -540,17 +549,17 @@ int     main(int argc, char **argv)
     char   *noreply = 0;
     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) {
        case 'a':
            action = optarg;
            break;
        case 'A':
-           if (rcpt_count >= MAX_RCPT) {
+           if (add_rcpt_count >= MAX_RCPT) {
                fprintf(stderr, "too many -A options\n");
                exit(1);
            }
-           rcpt_addr[rcpt_count++] = optarg;
+           add_rcpt[add_rcpt_count++] = optarg;
            break;
        case 'b':
 #ifdef SMFIR_REPLBODY
@@ -572,6 +581,13 @@ int     main(int argc, char **argv)
                exit(1);
            }
            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':
 #ifdef SMFIR_CHGFROM
            if (chg_from) {
index e3520bfc72378c6322ed3d7f5f74305e120986c8..9a94ce92faf27b3f2c41b77a25133294d50e5703 100644 (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 */
 
     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");
+    }
     normalize_options(argv);
     masterp->name_space =
        concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0);
index 7376b7b3995c795b9aa068945229b435310c322e..79a44a43b06723c549800396884d177e0d387b5e 100644 (file)
@@ -39,7 +39,7 @@ update: ../../libexec/$(PROG)
        cp $(PROG) ../../libexec
 
 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)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS)
index 4532b67d4797cfdd653e8e74b2bcd7dd9e8cdc2e..8d2bd2d63e06f3530d1c8f7e216f7fa8d887a714 100644 (file)
@@ -5044,11 +5044,14 @@ int     smtpd_input_transp_mask;
 char   *var_client_checks = "";
 char   *var_helo_checks = "";
 char   *var_mail_checks = "";
+char   *var_relay_checks = "";
 char   *var_rcpt_checks = "";
 char   *var_etrn_checks = "";
 char   *var_data_checks = "";
 char   *var_eod_checks = "";
 char   *var_relay_domains = "";
+char   *var_smtpd_uproxy_proto = "";
+int     var_smtpd_uproxy_tmout = 0;
 
 #ifdef USE_TLS
 char   *var_relay_ccerts = "";
@@ -5295,6 +5298,7 @@ static const REST_TABLE rest_table[] = {
     "client_restrictions", &client_restrctions,
     "helo_restrictions", &helo_restrctions,
     "sender_restrictions", &mail_restrctions,
+    "relay_restrictions", &relay_restrctions,
     "recipient_restrictions", &rcpt_restrctions,
     "etrn_restrictions", &etrn_restrctions,
     0,
index 0b5ee32662a6cc1566167bd915de9b789537ec31..980c7f82a8f853970d52280cb52d2a79cef36a34 100644 (file)
@@ -45,13 +45,13 @@ helo 123.123.123.123
 #
 sender_restrictions permit_mynetworks,reject_unknown_client
 client unknown 131.155.210.17
-mail foo@watson.ibm.com
+mail foo@ibm.com
 client unknown 168.100.189.13
-mail foo@watson.ibm.com
+mail foo@ibm.com
 client foo 123.123.123.123
-mail foo@watson.ibm.com
+mail foo@ibm.com
 sender_restrictions reject_unknown_address
-mail foo@watson.ibm.com
+mail foo@ibm.com
 mail foo@bad.domain
 sender_restrictions hash:./smtpd_check_access
 mail bad-sender@any.domain
@@ -67,18 +67,18 @@ mail foo@friend.bad.domain
 #
 recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains
 client unknown 131.155.210.17
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 client unknown 168.100.189.13
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 client foo 123.123.123.123
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 recipient_restrictions check_relay_domains
 client foo.porcupine.org 168.100.189.13
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 client foo 123.123.123.123
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 recipient_restrictions hash:./smtpd_check_access
 mail bad-sender@any.domain
@@ -98,7 +98,7 @@ client foo 127.0.0.2
 #
 recipient_restrictions check_relay_domains
 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
 client foo 131.155.210.17
 rcpt foo@porcupine.org
index f4f3f51e776eeeccbd15c80a3390dc6a949d5716..064cb41b8525ff8fe862fcfbdae97a5518072c62 100644 (file)
@@ -37,13 +37,13 @@ helo friend.bad.domain
 #
 sender_restrictions permit_mynetworks,reject_unknown_client
 client unknown 131.155.210.17
-mail foo@watson.ibm.com
+mail foo@ibm.com
 client unknown 168.100.189.13
-mail foo@watson.ibm.com
+mail foo@ibm.com
 client foo 123.123.123.123
-mail foo@watson.ibm.com
+mail foo@ibm.com
 sender_restrictions reject_unknown_address
-mail foo@watson.ibm.com
+mail foo@ibm.com
 mail foo@bad.domain
 sender_restrictions check_sender_access,hash:./smtpd_check_access
 mail bad-sender@any.domain
@@ -59,18 +59,18 @@ mail foo@friend.bad.domain
 #
 recipient_restrictions permit_mynetworks,reject_unknown_client,check_relay_domains
 client unknown 131.155.210.17
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 client unknown 168.100.189.13
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 client foo 123.123.123.123
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 recipient_restrictions check_relay_domains
 client foo.porcupine.org 168.100.189.13
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 client foo 123.123.123.123
-rcpt foo@watson.ibm.com
+rcpt foo@ibm.com
 rcpt foo@porcupine.org
 recipient_restrictions check_recipient_access,hash:./smtpd_check_access
 mail bad-sender@any.domain
index 898997125243eefef18eb8e2e6cfc9d7409d290e..b85997b6c5b65df9631b5199ad3237c08b93bbbd 100644 (file)
@@ -91,20 +91,20 @@ OK
 OK
 >>> client unknown 131.155.210.17
 OK
->>> mail foo@watson.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>
+>>> 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@ibm.com> proto=SMTP helo=<123.123.123.123>
 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
 >>> client unknown 168.100.189.13
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> client foo 123.123.123.123
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> sender_restrictions reject_unknown_address
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> 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>
@@ -140,34 +140,34 @@ OK
 OK
 >>> client unknown 131.155.210.17
 OK
->>> rcpt foo@watson.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>
+>>> 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@ibm.com> proto=SMTP helo=<123.123.123.123>
 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
 >>> client unknown 168.100.189.13
 OK
->>> rcpt foo@watson.ibm.com
+>>> rcpt foo@ibm.com
 OK
 >>> client foo 123.123.123.123
 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: <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>
-554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
+./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@ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_relay_domains
 OK
 >>> client foo.porcupine.org 168.100.189.13
 OK
->>> rcpt foo@watson.ibm.com
+>>> rcpt foo@ibm.com
 OK
 >>> rcpt foo@porcupine.org
 OK
 >>> client foo 123.123.123.123
 OK
->>> rcpt foo@watson.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>
-554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
+>>> rcpt foo@ibm.com
+./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@ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions hash:./smtpd_check_access
@@ -206,9 +206,9 @@ OK
 OK
 >>> client foo 131.155.210.17
 OK
->>> rcpt foo@watson.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>
-554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
+>>> rcpt foo@ibm.com
+./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@ibm.com>: Recipient address rejected: Relay access denied
 >>> recipient_restrictions check_client_access,hash:./smtpd_check_access,check_relay_domains
 OK
 >>> client foo 131.155.210.17
index 7381b9f6b3ad5bd33c1d3949b8e046945865b041..9322457e3739a734327f9fa8fb04911341350220 100644 (file)
@@ -71,20 +71,20 @@ OK
 OK
 >>> client unknown 131.155.210.17
 OK
->>> mail foo@watson.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>
+>>> 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@ibm.com> proto=SMTP helo=<friend.bad.domain>
 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
 >>> client unknown 168.100.189.13
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> client foo 123.123.123.123
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> sender_restrictions reject_unknown_address
 OK
->>> mail foo@watson.ibm.com
+>>> mail foo@ibm.com
 OK
 >>> 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>
@@ -120,34 +120,34 @@ OK
 OK
 >>> client unknown 131.155.210.17
 OK
->>> rcpt foo@watson.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>
+>>> 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@ibm.com> proto=SMTP helo=<friend.bad.domain>
 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]
 >>> client unknown 168.100.189.13
 OK
->>> rcpt foo@watson.ibm.com
+>>> rcpt foo@ibm.com
 OK
 >>> client foo 123.123.123.123
 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: <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>
-554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
+./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@ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_relay_domains
 OK
 >>> client foo.porcupine.org 168.100.189.13
 OK
->>> rcpt foo@watson.ibm.com
+>>> rcpt foo@ibm.com
 OK
 >>> rcpt foo@porcupine.org
 OK
 >>> client foo 123.123.123.123
 OK
->>> rcpt foo@watson.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>
-554 5.7.1 <foo@watson.ibm.com>: Recipient address rejected: Relay access denied
+>>> rcpt foo@ibm.com
+./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@ibm.com>: Recipient address rejected: Relay access denied
 >>> rcpt foo@porcupine.org
 OK
 >>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access
index 0509e64a71603ef120f2419d5f782e47b99f586c..617fbf915b3c6561b990be39a65d19c64b36b7f3 100644 (file)
@@ -606,7 +606,10 @@ static void mail_cmd_reset(SINK_STATE *state)
 
 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. */
     mail_cmd_reset(state);
index 680046fb1e5725b9292ec2eda2dbc05e6233a7cf..f6de965c25a41e60146f0a2100707bd56512c99a 100644 (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 */
 
+#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[],
                          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);
 }
 
+#endif
+
 /* tls_server_init - initialize the server-side TLS engine */
 
 TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
index 609bd0b7b0d5f866c86ea803c268a2f5cb383224..312be38669b9c10ba8860833b7d99c647f584340 100644 (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 \
        myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
        valid_utf_8 ip_match base32_code msg_rate_delay netstring \
-       vstream
+       vstream timecmp
 
 LIB_DIR        = ../../lib
 INC_DIR        = ../../include
index f79c1353df8f9a0ce0a63f799275287746c5c1e2..c2d1704a8c5e6ea2cbfc46c73f35b40969417153 100644 (file)
@@ -182,11 +182,21 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags)
     char   *cdb_path;
     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);
 
     if ((fd = open(cdb_path, O_RDONLY)) < 0)
-       return (dict_surrogate(DICT_TYPE_CDB, path, O_RDONLY, dict_flags,
-                              "open database %s: %m", cdb_path));
+       DICT_CDBQ_OPEN_RETURN(dict_surrogate(DICT_TYPE_CDB, path,
+                                          O_RDONLY, dict_flags,
+                                        "open database %s: %m", cdb_path));
 
     dict_cdbq = (DICT_CDBQ *) dict_alloc(DICT_TYPE_CDB,
                                         cdb_path, sizeof(*dict_cdbq));
@@ -225,8 +235,7 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags)
     if (dict_flags & DICT_FLAG_FOLD_FIX)
        dict_cdbq->dict.fold_buf = vstring_alloc(10);
 
-    myfree(cdb_path);
-    return (&dict_cdbq->dict);
+    DICT_CDBQ_OPEN_RETURN(DICT_DEBUG (&dict_cdbq->dict));
 }
 
 /* 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;
     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);
     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 (;;) {
        if ((fd = open(tmp_path, O_RDWR | O_CREAT, 0644)) < 0)
-           return (dict_surrogate(DICT_TYPE_CDB, path, O_RDWR, dict_flags,
-                                  "open database %s: %m", tmp_path));
+           DICT_CDBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_CDB, path,
+                                                O_RDWR, dict_flags,
+                                                "open database %s: %m",
+                                                tmp_path));
        if (fstat(fd, &st0) < 0)
            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->cdb_path = cdb_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.status = (st1.st_uid != 0);
     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)
        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 */
index 7aecb2f250fdab7870965e9159a74a3fb0396961..76577fcb392adc0bd4f2414cec4fdfd9ae461589 100644 (file)
@@ -165,34 +165,47 @@ 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_CIDR *dict_cidr;
-    VSTREAM *map_fp;
+    VSTREAM *map_fp = 0;
     struct stat st;
-    VSTRING *line_buffer;
-    VSTRING *why;
+    VSTRING *line_buffer = 0;
+    VSTRING *why = 0;
     DICT_CIDR_ENTRY *rule;
     DICT_CIDR_ENTRY *last_rule = 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.
      */
     if (open_flags != O_RDONLY)
-       return (dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags,
-                              "%s:%s map requires O_RDONLY access mode",
-                              DICT_TYPE_CIDR, mapname));
+       DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname,
+                                            open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                            DICT_TYPE_CIDR, mapname));
 
     /*
      * Open the configuration file.
      */
     if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
-       return (dict_surrogate(DICT_TYPE_CIDR, mapname, open_flags, dict_flags,
-                              "open %s: %m", mapname));
+       DICT_CIDR_OPEN_RETURN(dict_surrogate(DICT_TYPE_CIDR, mapname,
+                                            open_flags, dict_flags,
+                                            "open %s: %m", mapname));
     if (fstat(vstream_fileno(map_fp), &st) < 0)
        msg_fatal("fstat %s: %m", mapname);
 
-    /*
-     * No early returns without memory leaks.
-     */
     line_buffer = 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;
     }
 
-    /*
-     * 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));
+    DICT_CIDR_OPEN_RETURN(DICT_DEBUG (&dict_cidr->dict));
 }
index 37e14639f49ed963cfd0d4143469050c5baf7f6e..a1f25ffb6be471c79a3cace9687c55483e7fb1c0 100644 (file)
@@ -414,9 +414,19 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
     DICT_DBM *dict_dbm;
     struct stat st;
     DBM    *dbm;
-    char   *dbm_path;
+    char   *dbm_path = 0;
     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
      * 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) {
        dbm_path = concatenate(path, ".dir", (char *) 0);
        if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
-           return (dict_surrogate(DICT_TYPE_DBM, path, open_flags, dict_flags,
-                                  "open database %s: %m", dbm_path));
+           DICT_DBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_DBM, path,
+                                               open_flags, dict_flags,
+                                               "open database %s: %m",
+                                               dbm_path));
        if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
            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.
      */
     if ((dbm = dbm_open((char *) path, open_flags, 0644)) == 0)
-       return (dict_surrogate(DICT_TYPE_DBM, path, open_flags, dict_flags,
-                              "open database %s.{dir,pag}: %m", path));
+       DICT_DBM_OPEN_RETURN(dict_surrogate(DICT_TYPE_DBM, path,
+                                           open_flags, dict_flags,
+                                           "open database %s.{dir,pag}: %m",
+                                           path));
 
     if (dict_flags & DICT_FLAG_LOCK) {
        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->val_buf = 0;
 
-    if ((dict_flags & DICT_FLAG_LOCK))
-       myfree(dbm_path);
-
-    return (DICT_DEBUG (&dict_dbm->dict));
+    DICT_DBM_OPEN_RETURN(DICT_DEBUG (&dict_dbm->dict));
 }
 
 #endif
index 3b9987d7f453d5134ad119b54d032955c1f5a4f4..2dd36f6ea3ae3098c207165b048b91ff5ad967a2 100644 (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     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);
 
     /*
@@ -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
      * MDB_WRITEMAP which disables the use of malloc() in LMDB. However, that
      * does not address several disclosures of stack memory. Other Postfix
-     * databases do not need this workaround: those databases are maintained
-     * by Postfix daemon processes, and are accessible only by the postfix
-     * user.
+     * databases are maintained by Postfix daemon processes, and are
+     * accessible only by the postfix 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)
        mdb_flags |= MDB_WRITEMAP;
+#endif
 
     /*
      * 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) {
        dict = dict_surrogate(DICT_TYPE_LMDB, path, open_flags, dict_flags,
                    "open database %s: %s", mdb_path, mdb_strerror(status));
-       myfree(mdb_path);
-       return (dict);
+       DICT_LMDB_OPEN_RETURN(dict);
     }
 
     /*
@@ -682,9 +695,7 @@ DICT   *dict_lmdb_open(const char *path, int open_flags, int dict_flags)
      */
     dict_lmdb->slmdb = slmdb;
 
-    myfree(mdb_path);
-
-    return (DICT_DEBUG (&dict_lmdb->dict));
+    DICT_LMDB_OPEN_RETURN(DICT_DEBUG (&dict_lmdb->dict));
 }
 
 #endif
index 3ae2104b9624d3942c4dc6ef341384485c5cf850..3f183386848b278ca8f149e2607f36d70c83affd 100644 (file)
@@ -807,29 +807,43 @@ 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_PCRE *dict_pcre;
-    VSTREAM *map_fp;
+    VSTREAM *map_fp = 0;
     struct stat st;
-    VSTRING *line_buffer;
+    VSTRING *line_buffer = 0;
     DICT_PCRE_RULE *last_rule = 0;
     DICT_PCRE_RULE *rule;
     int     lineno = 0;
     int     nesting = 0;
     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.
      */
     if (open_flags != O_RDONLY)
-       return (dict_surrogate(DICT_TYPE_PCRE, mapname, open_flags, dict_flags,
-                              "%s:%s map requires O_RDONLY access mode",
-                              DICT_TYPE_PCRE, mapname));
+       DICT_PCRE_OPEN_RETURN(dict_surrogate(DICT_TYPE_PCRE, mapname,
+                                            open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                            DICT_TYPE_PCRE, mapname));
 
     /*
      * Open the configuration file.
      */
     if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
-       return (dict_surrogate(DICT_TYPE_PCRE, mapname, open_flags, dict_flags,
-                              "open %s: %m", mapname));
+       DICT_PCRE_OPEN_RETURN(dict_surrogate(DICT_TYPE_PCRE, mapname,
+                                            open_flags, dict_flags,
+                                            "open %s: %m", mapname));
     if (fstat(vstream_fileno(map_fp), &st) < 0)
        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",
                 mapname, lineno);
 
-    vstring_free(line_buffer);
-    vstream_fclose(map_fp);
-
-    return (DICT_DEBUG (&dict_pcre->dict));
+    DICT_PCRE_OPEN_RETURN(DICT_DEBUG (&dict_pcre->dict));
 }
 
 #endif                                 /* HAS_PCRE */
index 14275089b792bc90b3018e71050c71f820c7ef69..d6415788272cad88b1b5c1071c39bada55791a70 100644 (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_REGEXP *dict_regexp;
-    VSTREAM *map_fp;
+    VSTREAM *map_fp = 0;
     struct stat st;
-    VSTRING *line_buffer;
+    VSTRING *line_buffer = 0;
     DICT_REGEXP_RULE *rule;
     DICT_REGEXP_RULE *last_rule = 0;
     int     lineno = 0;
@@ -748,20 +748,34 @@ DICT   *dict_regexp_open(const char *mapname, int open_flags, int dict_flags)
     int     nesting = 0;
     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.
      */
     if (open_flags != O_RDONLY)
-       return (dict_surrogate(DICT_TYPE_REGEXP, mapname, open_flags, dict_flags,
-                              "%s:%s map requires O_RDONLY access mode",
-                              DICT_TYPE_REGEXP, mapname));
+       DICT_REGEXP_OPEN_RETURN(dict_surrogate(DICT_TYPE_REGEXP,
+                                           mapname, open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                              DICT_TYPE_REGEXP, mapname));
 
     /*
      * Open the configuration file.
      */
     if ((map_fp = vstream_fopen(mapname, O_RDONLY, 0)) == 0)
-       return (dict_surrogate(DICT_TYPE_REGEXP, mapname, open_flags, dict_flags,
-                              "open %s: %m", mapname));
+       DICT_REGEXP_OPEN_RETURN(dict_surrogate(DICT_TYPE_REGEXP, mapname,
+                                              open_flags, dict_flags,
+                                              "open %s: %m", mapname));
     if (fstat(vstream_fileno(map_fp), &st) < 0)
        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 =
            (regmatch_t *) mymalloc(sizeof(regmatch_t) * (max_sub + 1));
 
-    /*
-     * Clean up.
-     */
-    vstring_free(line_buffer);
-    vstream_fclose(map_fp);
-
-    return (DICT_DEBUG (&dict_regexp->dict));
+    DICT_REGEXP_OPEN_RETURN(DICT_DEBUG (&dict_regexp->dict));
 }
 
 #endif
index f177066bd0280ed287e74d749eeaf6ebe220674e..f06209ee27c9a69e6dd481e9582ac0b6bfeb2246 100644 (file)
@@ -309,34 +309,44 @@ static void dict_sockmap_close(DICT *dict)
 DICT   *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
 {
     DICT_SOCKMAP *dp;
-    char   *saved_name;
+    char   *saved_name = 0;
     char   *sockmap;
     DICT_SOCKMAP_REFC_HANDLE *ref_handle;
     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.
      */
     if (open_flags != O_RDONLY)
-       return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
-                              open_flags, dict_flags,
-                              "%s:%s map requires O_RDONLY access mode",
-                              DICT_TYPE_SOCKMAP, mapname));
+       DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
+                                          open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                          DICT_TYPE_SOCKMAP, mapname));
     if (dict_flags & DICT_FLAG_NO_UNAUTH)
-       return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
-                              open_flags, dict_flags,
+       DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
+                                          open_flags, dict_flags,
                     "%s:%s map is not allowed for security-sensitive data",
-                              DICT_TYPE_SOCKMAP, mapname));
+                                          DICT_TYPE_SOCKMAP, mapname));
 
     /*
      * Separate the socketmap name from the socketmap server name.
      */
     saved_name = mystrdup(mapname);
     if ((sockmap = split_at_right(saved_name, ':')) == 0)
-       return (dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
-                              open_flags, dict_flags,
-                              "%s requires server:socketmap argument",
-                              DICT_TYPE_SOCKMAP));
+       DICT_SOCKMAP_OPEN_RETURN(dict_surrogate(DICT_TYPE_SOCKMAP, mapname,
+                                          open_flags, dict_flags,
+                                   "%s requires server:socketmap argument",
+                                          DICT_TYPE_SOCKMAP));
 
     /*
      * Use one reference-counted client handle for all socketmaps with the
@@ -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. */
     dp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
 
-    /*
-     * Clean up.
-     */
-    myfree(saved_name);
-
-    return (DICT_DEBUG (&dp->dict));
+    DICT_SOCKMAP_OPEN_RETURN(DICT_DEBUG (&dp->dict));
 }
index 6eac13ff66d6c411451b34a93b3eb0da2d70800d..bd4af6ce6ccf3c099fceabf2030a69b43e880cc4 100644 (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_THASH *dict_thash;
-    VSTREAM *fp;
+    VSTREAM *fp = 0;
     struct stat st;
     time_t  before;
     time_t  after;
@@ -156,13 +156,26 @@ DICT   *dict_thash_open(const char *path, int open_flags, int dict_flags)
     HTABLE *table;
     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.
      */
     if (open_flags != O_RDONLY)
-       return (dict_surrogate(DICT_TYPE_THASH, path, open_flags, dict_flags,
-                              "%s:%s map requires O_RDONLY access mode",
-                              DICT_TYPE_THASH, path));
+       DICT_THASH_OPEN_RETURN(dict_surrogate(DICT_TYPE_THASH, path,
+                                             open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                             DICT_TYPE_THASH, path));
 
     /*
      * Read the flat text file into in-memory hash. Read the file again if it
@@ -170,8 +183,9 @@ DICT   *dict_thash_open(const char *path, int open_flags, int dict_flags)
      */
     for (before = time((time_t *) 0); /* see below */ ; before = after) {
        if ((fp = vstream_fopen(path, open_flags, 0644)) == 0) {
-           return (dict_surrogate(DICT_TYPE_THASH, path, open_flags, dict_flags,
-                                  "open database %s: %m", path));
+           DICT_THASH_OPEN_RETURN(dict_surrogate(DICT_TYPE_THASH, path,
+                                                 open_flags, dict_flags,
+                                            "open database %s: %m", path));
        }
        if (line_buffer == 0)
            line_buffer = vstring_alloc(100);
@@ -240,6 +254,7 @@ DICT   *dict_thash_open(const char *path, int open_flags, int dict_flags)
            msg_fatal("fstat %s: %m", path);
        if (vstream_fclose(fp))
            msg_fatal("read %s: %m", path);
+       fp = 0;                                 /* DICT_THASH_OPEN_RETURN() */
        after = time((time_t *) 0);
        if (st.st_mtime < before - 1 || st.st_mtime > after)
            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);
        doze(300000);
     }
-    vstring_free(line_buffer);
 
     /*
      * 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.status = (st.st_uid != 0);
 
-    return (DICT_DEBUG (&dict_thash->dict));
+    DICT_THASH_OPEN_RETURN(DICT_DEBUG (&dict_thash->dict));
 }
index c6c91551d25cf6e0702b8af5383fedb67d26d06e..3d4941e2bda307bd08a954614a80d3e8eb6a66b9 100644 (file)
@@ -94,8 +94,10 @@ int     mac_parse(const char *value, MAC_PARSE_FN action, char *context)
     int     level;
     int     status = 0;
 
-#define SKIP(start, var, cond) \
-        for (var = start; *var && (cond); var++);
+#define SKIP(start, var, cond) do { \
+        for (var = start; *var && (cond); var++) \
+           /* void */; \
+    } while (0)
 
     if (msg_verbose > 1)
        msg_info("%s: %s", myname, value);
index f3e519bad1e7d5954c9f5968f5f87f79c241a59e..0359f1a13aa11a60345aea4727655764cd7062ee 100644 (file)
@@ -68,14 +68,17 @@ const char *split_nameval(char *buf, char **name, char **value)
     /*
      * Ugly macros to make complex expressions less unreadable.
      */
-#define SKIP(start, var, cond) \
-       for (var = start; *var && (cond); var++);
+#define SKIP(start, var, cond) do { \
+       for (var = start; *var && (cond); var++) \
+           /* void */; \
+    } while (0)
 
-#define TRIM(s) { \
+#define TRIM(s) do { \
        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; \
-    }
+    } while (0)
 
     SKIP(buf, np, ISSPACE(*np));               /* find name begin */
     if (*np == 0)
index 8b9878d33a799552c8ff138e41e69f2c2695abd3..1acda0f89474e8965fa9d6bf7932b925afe1096b 100644 (file)
@@ -125,6 +125,7 @@ VBUF   *vbuf_print(VBUF *bp, const char *format, va_list ap)
     unsigned long_flag;                        /* long or plain integer */
     int     ch;
     char   *s;
+    int     saved_errno = errno;       /* VBUF_SPACE() may clobber it */
 
     /*
      * Assume that format strings are short.
@@ -241,7 +242,7 @@ VBUF   *vbuf_print(VBUF *bp, const char *format, va_list ap)
                VBUF_SKIP(bp);
                break;
            case 'm':
-               VBUF_STRCAT(bp, strerror(errno));
+               VBUF_STRCAT(bp, strerror(saved_errno));
                break;
            case 'p':
                if (VBUF_SPACE(bp, (width > prec ? width : prec) + PTR_SPACE))