From 897f730f141e8b89ecbb617f59ff4486096ce53d Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Thu, 14 Nov 2013 00:00:00 -0500 Subject: [PATCH] postfix-2.11-20131114 --- postfix/HISTORY | 40 ++++++++++++- postfix/README_FILES/SASL_README | 8 +-- ...{RELEASE_NOTES_2.10 => RELEASE_NOTES-2.10} | 0 postfix/WISHLIST | 11 +++- postfix/html/SASL_README.html | 5 +- postfix/html/master.5.html | 12 ++-- postfix/html/smtp-sink.1.html | 60 +++++++++---------- postfix/man/man5/master.5 | 8 +-- postfix/proto/SASL_README.html | 5 +- postfix/proto/master | 8 +-- postfix/src/cleanup/cleanup_addr.c | 6 +- postfix/src/cleanup/cleanup_map11.c | 6 +- postfix/src/cleanup/cleanup_map1n.c | 6 +- postfix/src/cleanup/cleanup_masquerade.c | 3 +- postfix/src/cleanup/cleanup_message.c | 6 +- postfix/src/cleanup/cleanup_milter.c | 5 +- postfix/src/global/mail_params.c | 13 ++-- postfix/src/global/mail_version.h | 2 +- postfix/src/milter/test-milter.c | 32 +++++++--- postfix/src/postconf/postconf_master.c | 4 +- postfix/src/smtpd/Makefile.in | 2 +- postfix/src/smtpd/smtpd_check.c | 4 ++ postfix/src/smtpd/smtpd_check.in | 20 +++---- postfix/src/smtpd/smtpd_check.in2 | 18 +++--- postfix/src/smtpd/smtpd_check.ref | 36 +++++------ postfix/src/smtpd/smtpd_check.ref2 | 30 +++++----- postfix/src/smtpstone/smtp-sink.c | 5 +- postfix/src/tls/tls_server.c | 6 ++ postfix/src/util/Makefile.in | 2 +- postfix/src/util/dict_cdb.c | 38 +++++++++--- postfix/src/util/dict_cidr.c | 45 +++++++------- postfix/src/util/dict_dbm.c | 29 ++++++--- postfix/src/util/dict_lmdb.c | 27 ++++++--- postfix/src/util/dict_pcre.c | 33 ++++++---- postfix/src/util/dict_regexp.c | 36 ++++++----- postfix/src/util/dict_sockmap.c | 41 +++++++------ postfix/src/util/dict_thash.c | 30 +++++++--- postfix/src/util/mac_parse.c | 6 +- postfix/src/util/split_nameval.c | 13 ++-- postfix/src/util/vbuf_print.c | 3 +- 40 files changed, 425 insertions(+), 239 deletions(-) rename postfix/{RELEASE_NOTES_2.10 => RELEASE_NOTES-2.10} (100%) diff --git a/postfix/HISTORY b/postfix/HISTORY index b914324e7..cb6cd436a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -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. diff --git a/postfix/README_FILES/SASL_README b/postfix/README_FILES/SASL_README index 66b9b415d..3f03f30d4 100644 --- a/postfix/README_FILES/SASL_README +++ b/postfix/README_FILES/SASL_README @@ -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, diff --git a/postfix/RELEASE_NOTES_2.10 b/postfix/RELEASE_NOTES-2.10 similarity index 100% rename from postfix/RELEASE_NOTES_2.10 rename to postfix/RELEASE_NOTES-2.10 diff --git a/postfix/WISHLIST b/postfix/WISHLIST index 5afdd4ed5..aa77857b8 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -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: diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html index e39391fe7..5e75ee5fb 100644 --- a/postfix/html/SASL_README.html +++ b/postfix/html/SASL_README.html @@ -948,8 +948,9 @@ stored as 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 +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.

diff --git a/postfix/html/master.5.html b/postfix/html/master.5.html index 01cc4ef5a..749de3a87 100644 --- a/postfix/html/master.5.html +++ b/postfix/html/master.5.html @@ -98,8 +98,8 @@ MASTER(5) MASTER(5) trolled with the queue_directory configura- tion parameter in main.cf). - On Solaris systems the unix type is imple- - mented with streams sockets. + On Solaris 8 and earlier systems the unix + type is implemented with streams sockets. fifo 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 queue_directory configura- tion parameter in main.cf). - On Solaris systems the pass type is imple- - mented with streams sockets. + On Solaris 8 and earlier systems the pass + 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 mas- + ter.cf. -v Increase the verbose logging level. Specify multiple -v options to make a Postfix daemon diff --git a/postfix/html/smtp-sink.1.html b/postfix/html/smtp-sink.1.html index 18768e945..96f49a0e3 100644 --- a/postfix/html/smtp-sink.1.html +++ b/postfix/html/smtp-sink.1.html @@ -12,7 +12,7 @@ SMTP-SINK(1) SMTP-SINK(1) SYNOPSIS smtp-sink [options] [inet:][host]:port backlog - smtp-sink [options] unix:pathname backlog + smtp-sink [options] unix:pathname backlog DESCRIPTION smtp-sink listens on the named host (or address) and port. @@ -47,19 +47,19 @@ SMTP-SINK(1) SMTP-SINK(1) -a Do not announce SASL authentication support. - -A delay + -A delay Wait delay 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 soft-bounce-reply + -b soft-bounce-reply Use soft-bounce-reply for soft reject responses. The default reply is "450 4.3.0 Error: command failed". - -B hard-bounce-reply + -B hard-bounce-reply Use hard-bounce-reply 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) -C Disable XCLIENT support. - -d dump-template + -d dump-template Dump each mail transaction to a single-message file whose name is created by expanding the dump-tem- plate 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. - -D dump-template + -D dump-template Append mail transactions to a multi-message dump file whose name is created by expanding the dump- template via strftime(3). If the template contains @@ -98,7 +98,7 @@ SMTP-SINK(1) SMTP-SINK(1) -E Do not announce ENHANCEDSTATUSCODES support. - -f command,command,... + -f command,command,... Reject the specified commands with a hard (5xx) error code. This option implies -p. @@ -110,24 +110,24 @@ SMTP-SINK(1) SMTP-SINK(1) -F Disable XFORWARD support. - -h hostname + -h hostname Use hostname in the SMTP greeting, in the HELO response, and in the EHLO response. The default hostname is "smtp-sink". -L Enable LMTP instead of SMTP. - -m count (default: 256) + -m count (default: 256) An upper bound on the maximal number of simultane- ous connections that smtp-sink will handle. This prevents the process from running out of file descriptors. Excess connections will stay queued in the TCP/IP stack. - -M count + -M count Terminate after receiving count messages. - -n count + -n count Terminate after count sessions. -p Do not announce support for ESMTP command pipelin- @@ -136,7 +136,7 @@ SMTP-SINK(1) SMTP-SINK(1) -P Change the server greeting so that it appears to come through a CISCO PIX system. Implies -e. - -q command,command,... + -q command,command,... 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. - -Q command,command,... + -Q command,command,... 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. - -r command,command,... + -r command,command,... Reject the specified commands with a soft (4xx) error code. This option implies -p. @@ -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. - -R root-directory + -R root-directory Change the process root directory to the specified location. This option requires super-user privi- leges. See also the -u option. - -s command,command,... + -s command,command,... 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), \ddd (up to three octal digits) and \\ (the backslash character). - -t timeout (default: 100) + -t timeout (default: 100) Limit the time for receiving a command or sending a response. The time limit is specified in seconds. - -T windowsize + -T windowsize Override the default TCP window size. To work around broken TCP window scaling implementations, specify a value > 0 and < 65536. - -u username + -u username 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) -v Show the SMTP conversations. - -w delay + -w delay Wait delay seconds before responding to a DATA com- mand. - -W command:delay[:odds] + -W command:delay[:odds] Wait delay seconds before responding to command. If odds is also specified (a number between 1-99 inclusive), wait for a random multiple of delay. @@ -226,7 +226,7 @@ SMTP-SINK(1) SMTP-SINK(1) interface) TCP port port. Both host and port may be specified in numeric or symbolic form. - unix:pathname + unix:pathname Listen on the UNIX-domain socket at pathname. backlog @@ -251,45 +251,45 @@ SMTP-SINK(1) SMTP-SINK(1) The format of the smtp-sink generated headers is as fol- lows: - X-Client-Addr: text + X-Client-Addr: text The client IP address without enclosing []. An IPv6 address is prefixed with "ipv6:". This record is always present. - X-Client-Proto: text + X-Client-Proto: text The client protocol: SMTP, ESMTP or LMTP. This record is always present. - X-Helo-Args: text + X-Helo-Args: text 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. - X-Mail-Args: text + X-Mail-Args: text The arguments of the MAIL command that started this mail delivery transaction. This record is present exactly once. - X-Rcpt-Args: text + X-Rcpt-Args: text 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. - Received: text + Received: text A message header for compatibility with mail pro- cessing software. This three-line header marks the end of the headers provided by smtp-sink, and is formatted as follows: - from helo ([addr]) + from helo ([addr]) 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. - by host (smtp-sink) with proto id random; + by host (smtp-sink) with proto id random; The hostname specified with the -h option, the client protocol (see X-Client-Proto above), and the pseudo-random portion of the diff --git a/postfix/man/man5/master.5 b/postfix/man/man5/master.5 index 644ce57ea..9f31fa5a6 100644 --- a/postfix/man/man5/master.5 +++ b/postfix/man/man5/master.5 @@ -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 diff --git a/postfix/proto/SASL_README.html b/postfix/proto/SASL_README.html index 1b2511a62..75363e61a 100644 --- a/postfix/proto/SASL_README.html +++ b/postfix/proto/SASL_README.html @@ -948,8 +948,9 @@ stored as 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 +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.

diff --git a/postfix/proto/master b/postfix/proto/master index acd381caf..e392da3f2 100644 --- a/postfix/proto/master +++ b/postfix/proto/master @@ -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. @@ -104,8 +104,8 @@ # 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 diff --git a/postfix/src/cleanup/cleanup_addr.c b/postfix/src/cleanup/cleanup_addr.c index 233ba37ca..f8e0596c4 100644 --- a/postfix/src/cleanup/cleanup_addr.c +++ b/postfix/src/cleanup/cleanup_addr.c @@ -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; } diff --git a/postfix/src/cleanup/cleanup_map11.c b/postfix/src/cleanup/cleanup_map11.c index 626b9ff3a..2e892fda0 100644 --- a/postfix/src/cleanup/cleanup_map11.c +++ b/postfix/src/cleanup/cleanup_map11.c @@ -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); } diff --git a/postfix/src/cleanup/cleanup_map1n.c b/postfix/src/cleanup/cleanup_map1n.c index f7088a06b..7f9919466 100644 --- a/postfix/src/cleanup/cleanup_map1n.c +++ b/postfix/src/cleanup/cleanup_map1n.c @@ -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"); diff --git a/postfix/src/cleanup/cleanup_masquerade.c b/postfix/src/cleanup/cleanup_masquerade.c index 70577da1e..a8540308c 100644 --- a/postfix/src/cleanup/cleanup_masquerade.c +++ b/postfix/src/cleanup/cleanup_masquerade.c @@ -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; } diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index ffb5c7e52..aa1fe6c5b 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -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; } diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index 7616780f5..e6a74e84d 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -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; } diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index b2ec918d8..2d919776c 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -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) diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index af0c64ee1..13cd38b5d 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 diff --git a/postfix/src/milter/test-milter.c b/postfix/src/milter/test-milter.c index 58e6728f5..26be0f7c2 100644 --- a/postfix/src/milter/test-milter.c +++ b/postfix/src/milter/test-milter.c @@ -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) { diff --git a/postfix/src/postconf/postconf_master.c b/postfix/src/postconf/postconf_master.c index e3520bfc7..9a94ce92f 100644 --- a/postfix/src/postconf/postconf_master.c +++ b/postfix/src/postconf/postconf_master.c @@ -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); diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 7376b7b39..79a44a43b 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -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) diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 4532b67d4..8d2bd2d63 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -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, diff --git a/postfix/src/smtpd/smtpd_check.in b/postfix/src/smtpd/smtpd_check.in index 0b5ee3266..980c7f82a 100644 --- a/postfix/src/smtpd/smtpd_check.in +++ b/postfix/src/smtpd/smtpd_check.in @@ -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 diff --git a/postfix/src/smtpd/smtpd_check.in2 b/postfix/src/smtpd/smtpd_check.in2 index f4f3f51e7..064cb41b8 100644 --- a/postfix/src/smtpd/smtpd_check.in2 +++ b/postfix/src/smtpd/smtpd_check.in2 @@ -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 diff --git a/postfix/src/smtpd/smtpd_check.ref b/postfix/src/smtpd/smtpd_check.ref index 898997125..b85997b6c 100644 --- a/postfix/src/smtpd/smtpd_check.ref +++ b/postfix/src/smtpd/smtpd_check.ref @@ -91,20 +91,20 @@ OK OK >>> client unknown 131.155.210.17 OK ->>> mail foo@watson.ibm.com -./smtpd_check: : reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= proto=SMTP helo=<123.123.123.123> +>>> mail foo@ibm.com +./smtpd_check: : reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= 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: : reject: MAIL from foo[123.123.123.123]: 450 4.1.8 : Sender address rejected: Domain not found; from= 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: : reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= to= proto=SMTP helo=<123.123.123.123> +>>> rcpt foo@ibm.com +./smtpd_check: : reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= to= 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: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> -554 5.7.1 : Recipient address rejected: Relay access denied +./smtpd_check: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> +554 5.7.1 : 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: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> -554 5.7.1 : Recipient address rejected: Relay access denied +>>> rcpt foo@ibm.com +./smtpd_check: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> +554 5.7.1 : 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: : reject: RCPT from foo[131.155.210.17]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> -554 5.7.1 : Recipient address rejected: Relay access denied +>>> rcpt foo@ibm.com +./smtpd_check: : reject: RCPT from foo[131.155.210.17]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo=<123.123.123.123> +554 5.7.1 : 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 diff --git a/postfix/src/smtpd/smtpd_check.ref2 b/postfix/src/smtpd/smtpd_check.ref2 index 7381b9f6b..9322457e3 100644 --- a/postfix/src/smtpd/smtpd_check.ref2 +++ b/postfix/src/smtpd/smtpd_check.ref2 @@ -71,20 +71,20 @@ OK OK >>> client unknown 131.155.210.17 OK ->>> mail foo@watson.ibm.com -./smtpd_check: : reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= proto=SMTP helo= +>>> mail foo@ibm.com +./smtpd_check: : reject: MAIL from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= proto=SMTP helo= 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: : reject: MAIL from foo[123.123.123.123]: 450 4.1.8 : Sender address rejected: Domain not found; from= proto=SMTP helo= @@ -120,34 +120,34 @@ OK OK >>> client unknown 131.155.210.17 OK ->>> rcpt foo@watson.ibm.com -./smtpd_check: : reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= to= proto=SMTP helo= +>>> rcpt foo@ibm.com +./smtpd_check: : reject: RCPT from unknown[131.155.210.17]: 450 4.7.1 Client host rejected: cannot find your hostname, [131.155.210.17]; from= to= proto=SMTP helo= 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: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo= -554 5.7.1 : Recipient address rejected: Relay access denied +./smtpd_check: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo= +554 5.7.1 : 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: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo= -554 5.7.1 : Recipient address rejected: Relay access denied +>>> rcpt foo@ibm.com +./smtpd_check: : reject: RCPT from foo[123.123.123.123]: 554 5.7.1 : Recipient address rejected: Relay access denied; from= to= proto=SMTP helo= +554 5.7.1 : Recipient address rejected: Relay access denied >>> rcpt foo@porcupine.org OK >>> recipient_restrictions check_recipient_access,hash:./smtpd_check_access diff --git a/postfix/src/smtpstone/smtp-sink.c b/postfix/src/smtpstone/smtp-sink.c index 0509e64a7..617fbf915 100644 --- a/postfix/src/smtpstone/smtp-sink.c +++ b/postfix/src/smtpstone/smtp-sink.c @@ -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); diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c index 680046fb1..f6de965c2 100644 --- a/postfix/src/tls/tls_server.c +++ b/postfix/src/tls/tls_server.c @@ -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) diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 609bd0b7b..312be3866 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -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 diff --git a/postfix/src/util/dict_cdb.c b/postfix/src/util/dict_cdb.c index f79c1353d..c2d1704a8 100644 --- a/postfix/src/util/dict_cdb.c +++ b/postfix/src/util/dict_cdb.c @@ -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 */ diff --git a/postfix/src/util/dict_cidr.c b/postfix/src/util/dict_cidr.c index 7aecb2f25..76577fcb3 100644 --- a/postfix/src/util/dict_cidr.c +++ b/postfix/src/util/dict_cidr.c @@ -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)); } diff --git a/postfix/src/util/dict_dbm.c b/postfix/src/util/dict_dbm.c index 37e14639f..a1f25ffb6 100644 --- a/postfix/src/util/dict_dbm.c +++ b/postfix/src/util/dict_dbm.c @@ -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 diff --git a/postfix/src/util/dict_lmdb.c b/postfix/src/util/dict_lmdb.c index 3b9987d7f..2dd36f6ea 100644 --- a/postfix/src/util/dict_lmdb.c +++ b/postfix/src/util/dict_lmdb.c @@ -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 diff --git a/postfix/src/util/dict_pcre.c b/postfix/src/util/dict_pcre.c index 3ae2104b9..3f1833868 100644 --- a/postfix/src/util/dict_pcre.c +++ b/postfix/src/util/dict_pcre.c @@ -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 */ diff --git a/postfix/src/util/dict_regexp.c b/postfix/src/util/dict_regexp.c index 14275089b..d64157882 100644 --- a/postfix/src/util/dict_regexp.c +++ b/postfix/src/util/dict_regexp.c @@ -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 diff --git a/postfix/src/util/dict_sockmap.c b/postfix/src/util/dict_sockmap.c index f177066bd..f06209ee2 100644 --- a/postfix/src/util/dict_sockmap.c +++ b/postfix/src/util/dict_sockmap.c @@ -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)); } diff --git a/postfix/src/util/dict_thash.c b/postfix/src/util/dict_thash.c index 6eac13ff6..bd4af6ce6 100644 --- a/postfix/src/util/dict_thash.c +++ b/postfix/src/util/dict_thash.c @@ -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)); } diff --git a/postfix/src/util/mac_parse.c b/postfix/src/util/mac_parse.c index c6c91551d..3d4941e2b 100644 --- a/postfix/src/util/mac_parse.c +++ b/postfix/src/util/mac_parse.c @@ -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); diff --git a/postfix/src/util/split_nameval.c b/postfix/src/util/split_nameval.c index f3e519bad..0359f1a13 100644 --- a/postfix/src/util/split_nameval.c +++ b/postfix/src/util/split_nameval.c @@ -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) diff --git a/postfix/src/util/vbuf_print.c b/postfix/src/util/vbuf_print.c index 8b9878d33..1acda0f89 100644 --- a/postfix/src/util/vbuf_print.c +++ b/postfix/src/util/vbuf_print.c @@ -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))