From 4ff3cc38f36ffd44fb625072171c8f55550a120d Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sun, 17 Jan 2016 00:00:00 -0500 Subject: [PATCH] postfix-3.1-20160117 --- postfix/HISTORY | 25 ++++ postfix/Makefile.in | 2 +- postfix/html/postconf.1.html | 84 +++++++------ postfix/html/postlog.1.html | 7 +- postfix/html/posttls-finger.1.html | 32 ++--- postfix/man/man1/postconf.1 | 16 ++- postfix/man/man1/postlog.1 | 5 + postfix/man/man5/postconf.5 | 7 ++ postfix/mantools/html2readme | 2 +- postfix/proto/postconf.man.epilog | 7 ++ postfix/src/global/Makefile.in | 13 +- postfix/src/global/mail_version.h | 2 +- postfix/src/global/smtp_reply_footer.c | 151 +++++++++++++++++++---- postfix/src/global/smtp_reply_footer.h | 7 +- postfix/src/global/smtp_reply_footer.ref | 15 +++ postfix/src/postconf/Makefile.in | 43 ++++++- postfix/src/postconf/postconf.c | 33 +++-- postfix/src/postconf/postconf.h | 6 + postfix/src/postconf/postconf_builtin.c | 5 + postfix/src/postconf/postconf_main.c | 21 +++- postfix/src/postconf/postconf_master.c | 35 ++++-- postfix/src/postconf/postconf_service.c | 5 + postfix/src/postconf/test22.ref | 1 + postfix/src/postconf/test25.ref | 1 + postfix/src/postconf/test27.ref | 1 + postfix/src/postconf/test6.ref | 1 + postfix/src/postconf/test60.ref | 8 ++ postfix/src/postconf/test61.ref | 1 + postfix/src/postconf/test62.ref | 8 ++ postfix/src/postconf/test63.ref | 1 + postfix/src/postlog/postlog.c | 5 + postfix/src/tls/tls_misc.c | 2 +- 32 files changed, 442 insertions(+), 110 deletions(-) create mode 100644 postfix/src/global/smtp_reply_footer.ref create mode 100644 postfix/src/postconf/test60.ref create mode 100644 postfix/src/postconf/test61.ref create mode 100644 postfix/src/postconf/test62.ref create mode 100644 postfix/src/postconf/test63.ref diff --git a/postfix/HISTORY b/postfix/HISTORY index 691f05804..c881e8b67 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -22103,3 +22103,28 @@ Apologies for any names omitted. with insecure MX records. Viktor Dukhovni. Files: posttls-finger/posttls-finger.c, smtp/smtp_tls_policy.c, tls/tls.h, tls/tls_client.c, tls/tls_level.c. + +20160108 + + Cleanup: smtp_reply_footer() now restores state in case of + input error; unit tests that cover most if not all error + and non-error cases. Files: global/smtp_reply_footer.c, + global/smtp_reply_footer.ref. + +20160110 + + Bitrot: const-ification for OpenSSL 1.1.0. Viktor Dukhovni. + File: tls/tls_misc.c. + +20160116 + + "postconf -H" support (show names without the =value). + Initial use case: mass reversal of TLS-related main.cf + parameters (postconf -nH | grep _tls_ | xargs postconf -X). + This flag also works with "postconf -F" and "postconf -P". + Added missing documentation that -h works with "postconf + -F" and "postconf -P". Files: postconf.c, postconf.h, + postconf_master.c, postconf_main.c. + + Robustness: force html2text to produce ASCII output. File: + mantools/html2readme. diff --git a/postfix/Makefile.in b/postfix/Makefile.in index 4d978de6c..5ace3a650 100644 --- a/postfix/Makefile.in +++ b/postfix/Makefile.in @@ -13,7 +13,7 @@ DIRS = src/util src/global src/dns src/tls src/xsasl src/master src/milter \ src/posttls-finger MANDIRS = proto man html LIBEXEC = libexec/post-install libexec/postfix-script libexec/postfix-wrapper \ - libexec/postmulti-script libexec/post-install + libexec/postmulti-script PLUGINS = meta/dynamicmaps.cf META = meta/main.cf.proto meta/master.cf.proto meta/postfix-files \ meta/makedefs.out $(PLUGINS) diff --git a/postfix/html/postconf.1.html b/postfix/html/postconf.1.html index 8a4b8503e..1ed022edc 100644 --- a/postfix/html/postconf.1.html +++ b/postfix/html/postconf.1.html @@ -12,7 +12,7 @@ POSTCONF(1) POSTCONF(1) SYNOPSIS Managing main.cf: - postconf [-dfhnopvx] [-c config_dir] [-C class,...] [parameter ...] + postconf [-dfhHnopvx] [-c config_dir] [-C class,...] [parameter ...] postconf [-epv] [-c config_dir] parameter=value ... @@ -32,13 +32,13 @@ POSTCONF(1) POSTCONF(1) Managing master.cf service fields: - postconf -F [-fovx] [-c config_dir] [service[/type[/field]] ...] + postconf -F [-fhHovx] [-c config_dir] [service[/type[/field]] ...] postconf -F [-ev] [-c config_dir] service/type/field=value ... Managing master.cf service parameters: - postconf -P [-fovx] [-c config_dir] [service[/type[/parameter]] ...] + postconf -P [-fhHovx] [-c config_dir] [service[/type[/parameter]] ...] postconf -P [-ev] [-c config_dir] service/type/parameter=value ... @@ -56,48 +56,48 @@ POSTCONF(1) POSTCONF(1) DESCRIPTION By default, the postconf(1) command displays the values of main.cf con- - figuration parameters, and warns about possible mis-typed parameter - names (Postfix 2.9 and later). It can also change main.cf configura- + figuration parameters, and warns about possible mis-typed parameter + names (Postfix 2.9 and later). It can also change main.cf configura- tion parameter values, or display other configuration information about the Postfix mail system. Options: - -a List the available SASL server plug-in types. The SASL plug-in - type is selected with the smtpd_sasl_type configuration parame- + -a List the available SASL server plug-in types. The SASL plug-in + type is selected with the smtpd_sasl_type configuration parame- ter by specifying one of the names listed below. - cyrus This server plug-in is available when Postfix is built + cyrus This server plug-in is available when Postfix is built with Cyrus SASL support. dovecot This server plug-in uses the Dovecot authentication - server, and is available when Postfix is built with any + server, and is available when Postfix is built with any form of SASL support. This feature is available with Postfix 2.3 and later. - -A List the available SASL client plug-in types. The SASL plug-in - type is selected with the smtp_sasl_type or lmtp_sasl_type con- - figuration parameters by specifying one of the names listed + -A List the available SASL client plug-in types. The SASL plug-in + type is selected with the smtp_sasl_type or lmtp_sasl_type con- + figuration parameters by specifying one of the names listed below. - cyrus This client plug-in is available when Postfix is built + cyrus This client plug-in is available when Postfix is built with Cyrus SASL support. This feature is available with Postfix 2.3 and later. -b [template_file] Display the message text that appears at the beginning of deliv- - ery status notification (DSN) messages, replacing $name expres- + ery status notification (DSN) messages, replacing $name expres- sions with actual values as described in bounce(5). To override the built-in templates, specify a template file name - at the end of the postconf(1) command line, or specify a file + at the end of the postconf(1) command line, or specify a file name in main.cf with the bounce_template_file parameter. - To force selection of the built-in templates, specify an empty - template file name on the postconf(1) command line (in shell + To force selection of the built-in templates, specify an empty + template file name on the postconf(1) command line (in shell language: ""). This feature is available with Postfix 2.3 and later. @@ -107,7 +107,7 @@ POSTCONF(1) POSTCONF(1) of the default configuration directory. -C class,... - When displaying main.cf parameters, select only parameters from + When displaying main.cf parameters, select only parameters from the specified class(es): builtin @@ -125,36 +125,36 @@ POSTCONF(1) POSTCONF(1) This feature is available with Postfix 2.9 and later. - -d Print main.cf default parameter settings instead of actual set- - tings. Specify -df to fold long lines for human readability + -d Print main.cf default parameter settings instead of actual set- + tings. Specify -df to fold long lines for human readability (Postfix 2.9 and later). - -e Edit the main.cf configuration file, and update parameter set- - tings with the "name=value" pairs on the postconf(1) command + -e Edit the main.cf configuration file, and update parameter set- + tings with the "name=value" pairs on the postconf(1) command line. - With -M, edit the master.cf configuration file, and replace one - or more service entries with new values as specified with "ser- + With -M, edit the master.cf configuration file, and replace one + or more service entries with new values as specified with "ser- vice/type=value" on the postconf(1) command line. - With -F, edit the master.cf configuration file, and replace one - or more service fields with new values as specied with "ser- - vice/type/field=value" on the postconf(1) command line. Cur- - rently, the "command" field contains the command name and com- + With -F, edit the master.cf configuration file, and replace one + or more service fields with new values as specied with "ser- + vice/type/field=value" on the postconf(1) command line. Cur- + rently, the "command" field contains the command name and com- mand arguments. this may change in the near future, so that the "command" field contains only the command name, and a new "argu- ments" pseudofield contains the command arguments. - With -P, edit the master.cf configuration file, and add or - update one or more service parameter settings (-o parame- - ter=value settings) with new values as specied with "ser- + With -P, edit the master.cf configuration file, and add or + update one or more service parameter settings (-o parame- + ter=value settings) with new values as specied with "ser- vice/type/parameter=value" on the postconf(1) command line. In all cases the file is copied to a temporary file then renamed - into place. Specify quotes to protect special characters and + into place. Specify quotes to protect special characters and whitespace on the postconf(1) command line. - The -e option is no longer needed with Postfix version 2.8 and + The -e option is no longer needed with Postfix version 2.8 and later. -f Fold long lines when printing main.cf or master.cf configuration @@ -166,16 +166,21 @@ POSTCONF(1) POSTCONF(1) and all fields), formatted as one "service/type/field=value" per line. Specify -Ff to fold long lines. - Specify one or more "service/type/field" instances on the post- - conf(1) command line to limit the output to fields of interest. - Trailing parameter name or service type fields that are omitted + Specify one or more "service/type/field" instances on the post- + conf(1) command line to limit the output to fields of interest. + Trailing parameter name or service type fields that are omitted will be handled as "*" wildcard fields. This feature is available with Postfix 2.11 and later. - -h Show parameter or attribute values without the "name = " label + -h Show parameter or attribute values without the "name = " label that normally precedes the value. + -H Show parameter or attribute names without the " = value" that + normally follows the name. + + This feature is available with Postfix 3.1 and later. + -l List the names of all supported mailbox locking methods. Post- fix supports the following methods: @@ -489,5 +494,10 @@ POSTCONF(1) POSTCONF(1) P.O. Box 704 Yorktown Heights, NY 10598, USA + Wietse Venema + Google, Inc. + 111 8th Avenue + New York, NY 10011, USA + POSTCONF(1) diff --git a/postfix/html/postlog.1.html b/postfix/html/postlog.1.html index 514e7f305..10ac93515 100644 --- a/postfix/html/postlog.1.html +++ b/postfix/html/postlog.1.html @@ -4,7 +4,7 @@ Postfix manual - postlog(1)
-POSTLOG(1)                                                          POSTLOG(1)
+POSTLOG(1)                  General Commands Manual                 POSTLOG(1)
 
 NAME
        postlog - Postfix-compatible logging utility
@@ -80,5 +80,10 @@ POSTLOG(1)                                                          POSTLOG(1)
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
+       Wietse Venema
+       Google, Inc.
+       111 8th Avenue
+       New York, NY 10011, USA
+
                                                                     POSTLOG(1)
 
diff --git a/postfix/html/posttls-finger.1.html b/postfix/html/posttls-finger.1.html index 44dbd9eaa..1d99eabc1 100644 --- a/postfix/html/posttls-finger.1.html +++ b/postfix/html/posttls-finger.1.html @@ -4,7 +4,7 @@ Postfix manual - posttls-finger(1)
-POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
+POSTTLS-FINGER(1)           General Commands Manual          POSTTLS-FINGER(1)
 
 NAME
        posttls-finger - Probe the TLS properties of an ESMTP or LMTP server.
@@ -269,28 +269,28 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               reading the remote server's 220 banner.
 
        -T timeout (default: 30)
-              The  SMTP/LMTP command timeout for EHLO/LHLO, STARTTLS and QUIT.
+              The SMTP/LMTP command timeout for EHLO/LHLO, STARTTLS and QUIT.
 
-       -v     Enable verbose Postfix  logging.   Specify  more  than  once  to
+       -v     Enable  verbose  Postfix  logging.   Specify  more  than once to
               increase the level of verbose logging.
 
-       -w     Enable  outgoing  TLS  wrapper  mode, or SMTPS support.  This is
-              typically provided on port 465 by servers  that  are  compatible
-              with  the  ad-hoc SMTP in SSL protocol, rather than the standard
+       -w     Enable outgoing TLS wrapper mode, or  SMTPS  support.   This  is
+              typically  provided  on  port 465 by servers that are compatible
+              with the ad-hoc SMTP in SSL protocol, rather than  the  standard
               STARTTLS protocol.  The destination domain:port should of course
               provide such a service.
 
        [inet:]domain[:port]
               Connect via TCP to domain domain, port port. The default port is
-              smtp (or 24 with LMTP).  With SMTP an MX lookup is performed  to
-              resolve  the  domain to a host, unless the domain is enclosed in
-              [].  If you want to connect to a specific MX host, for  instance
-              mx1.example.com,  specify  [mx1.example.com]  as the destination
+              smtp  (or 24 with LMTP).  With SMTP an MX lookup is performed to
+              resolve the domain to a host, unless the domain is  enclosed  in
+              [].   If you want to connect to a specific MX host, for instance
+              mx1.example.com, specify [mx1.example.com]  as  the  destination
               and example.com as a match argument.  When using DNS, the desti-
-              nation  domain  is assumed fully qualified and no default domain
-              or search suffixes are applied;  you  must  use  fully-qualified
-              names  or  also  enable native host lookups (these don't support
-              dane or dane-only as no DNSSEC validation information is  avail-
+              nation domain is assumed fully qualified and no  default  domain
+              or  search  suffixes  are  applied; you must use fully-qualified
+              names or also enable native host lookups  (these  don't  support
+              dane  or dane-only as no DNSSEC validation information is avail-
               able via native lookups).
 
        unix:pathname
@@ -299,8 +299,8 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
        match ...
               With no match arguments specified, certificate peername matching
               uses the compiled-in default strategies for each security level.
-              If  you specify one or more arguments, these will be used as the
-              list of certificate or public-key digests to match for the  fin-
+              If you specify one or more arguments, these will be used as  the
+              list  of certificate or public-key digests to match for the fin-
               gerprint level, or as the list of DNS names to match in the cer-
               tificate at the verify and secure levels.  If the security level
               is dane, or dane-only the match names are ignored, and hostname,
diff --git a/postfix/man/man1/postconf.1 b/postfix/man/man1/postconf.1
index 9cc1e5e24..ac60f0794 100644
--- a/postfix/man/man1/postconf.1
+++ b/postfix/man/man1/postconf.1
@@ -11,7 +11,7 @@ Postfix configuration utility
 .fi
 \fBManaging main.cf:\fR
 
-\fBpostconf\fR [\fB\-dfhnopvx\fR] [\fB\-c \fIconfig_dir\fR]
+\fBpostconf\fR [\fB\-dfhHnopvx\fR] [\fB\-c \fIconfig_dir\fR]
 [\fB\-C \fIclass,...\fR] [\fIparameter ...\fR]
 
 \fBpostconf\fR [\fB\-epv\fR] [\fB\-c \fIconfig_dir\fR]
@@ -39,7 +39,7 @@ Postfix configuration utility
 
 \fBManaging master.cf service fields:\fR
 
-\fBpostconf\fR \fB\-F\fR [\fB\-fovx\fR] [\fB\-c \fIconfig_dir\fR]
+\fBpostconf\fR \fB\-F\fR [\fB\-fhHovx\fR] [\fB\-c \fIconfig_dir\fR]
 [\fIservice\fR[\fB/\fItype\fR[\fB/\fIfield\fR]]\fI ...\fR]
 
 \fBpostconf\fR \fB\-F\fR [\fB\-ev\fR] [\fB\-c \fIconfig_dir\fR]
@@ -47,7 +47,7 @@ Postfix configuration utility
 
 \fBManaging master.cf service parameters:\fR
 
-\fBpostconf\fR \fB\-P\fR [\fB\-fovx\fR] [\fB\-c \fIconfig_dir\fR]
+\fBpostconf\fR \fB\-P\fR [\fB\-fhHovx\fR] [\fB\-c \fIconfig_dir\fR]
 [\fIservice\fR[\fB/\fItype\fR[\fB/\fIparameter\fR]]\fI ...\fR]
 
 \fBpostconf\fR \fB\-P\fR [\fB\-ev\fR] [\fB\-c \fIconfig_dir\fR]
@@ -203,6 +203,11 @@ This feature is available with Postfix 2.11 and later.
 .IP \fB\-h\fR
 Show parameter or attribute values without the "\fIname\fR
 = " label that normally precedes the value.
+.IP \fB\-H\fR
+Show parameter or attribute names without the " = \fIvalue\fR"
+that normally follows the name.
+
+This feature is available with Postfix 3.1 and later.
 .IP \fB\-l\fR
 List the names of all supported mailbox locking methods.
 Postfix supports the following methods:
@@ -527,3 +532,8 @@ Wietse Venema
 IBM T.J. Watson Research
 P.O. Box 704
 Yorktown Heights, NY 10598, USA
+
+Wietse Venema
+Google, Inc.
+111 8th Avenue
+New York, NY 10011, USA
diff --git a/postfix/man/man1/postlog.1 b/postfix/man/man1/postlog.1
index 8aa798b54..25f55fbc1 100644
--- a/postfix/man/man1/postlog.1
+++ b/postfix/man/man1/postlog.1
@@ -88,3 +88,8 @@ Wietse Venema
 IBM T.J. Watson Research
 P.O. Box 704
 Yorktown Heights, NY 10598, USA
+
+Wietse Venema
+Google, Inc.
+111 8th Avenue
+New York, NY 10011, USA
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 122b49545..8f3666235 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -13346,3 +13346,10 @@ Wietse Venema
 IBM T.J. Watson Research
 P.O. Box 704
 Yorktown Heights, NY 10598, USA
+.sp
+Wietse Venema
+Google, Inc.
+111 8th Avenue
+New York, NY 10011, USA
+.sp
+Viktor Dukhovni
diff --git a/postfix/mantools/html2readme b/postfix/mantools/html2readme
index 6fce9769e..b7d110c5f 100755
--- a/postfix/mantools/html2readme
+++ b/postfix/mantools/html2readme
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-HTML2TEXT="html2text -style pretty -rcfile html2text.rc"
+HTML2TEXT="html2text -ascii -style pretty -rcfile html2text.rc"
 
 #case $# in
 # 0) $HTML2TEXT;;
diff --git a/postfix/proto/postconf.man.epilog b/postfix/proto/postconf.man.epilog
index d6c20b8c4..1392615f3 100644
--- a/postfix/proto/postconf.man.epilog
+++ b/postfix/proto/postconf.man.epilog
@@ -14,3 +14,10 @@ Wietse Venema
 IBM T.J. Watson Research
 P.O. Box 704
 Yorktown Heights, NY 10598, USA
+.sp
+Wietse Venema
+Google, Inc.
+111 8th Avenue
+New York, NY 10011, USA
+.sp
+Viktor Dukhovni
diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in
index cedbed2f6..871e49751 100644
--- a/postfix/src/global/Makefile.in
+++ b/postfix/src/global/Makefile.in
@@ -117,7 +117,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
 	valid_mailhost_addr own_inet_addr header_body_checks \
 	data_redirect addr_match_list safe_ultostr verify_sender_addr \
 	mail_version mail_dict server_acl uxtext mail_parm_split \
-	fold_addr
+	fold_addr smtp_reply_footer
 
 LIBS	= ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
 LIB_DIR	= ../../lib
@@ -373,11 +373,15 @@ mail_parm_split: mail_parm_split.c $(LIB) $(LIBS)
 fold_addr: fold_addr.c $(LIB) $(LIBS)
 	$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
+smtp_reply_footer: smtp_reply_footer.c $(LIB) $(LIBS)
+	$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
 tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
 	xtext_test scache_multi_test ehlo_mask_test \
 	namadr_list_test mail_conf_time_test header_body_checks_tests \
 	mail_version_test server_acl_test resolve_local_test maps_test \
-	safe_ultostr_test mail_parm_split_test fold_addr_test
+	safe_ultostr_test mail_parm_split_test fold_addr_test \
+	smtp_reply_footer_test
 
 mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \
 	mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 mime_garb4
@@ -647,6 +651,11 @@ fold_addr_test: fold_addr fold_addr_test.in fold_addr_test.ref
 	diff fold_addr_test.ref fold_addr_test.tmp
 	rm -f fold_addr_test.tmp
 
+smtp_reply_footer_test: smtp_reply_footer smtp_reply_footer.ref
+	$(SHLIB_ENV) ./smtp_reply_footer >smtp_reply_footer.tmp 2>&1
+	diff smtp_reply_footer.ref smtp_reply_footer.tmp
+	rm -f smtp_reply_footer.tmp
+
 printfck: $(OBJS) $(PROG)
 	rm -rf printfck
 	mkdir printfck
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index de860b1e1..ef709a4ba 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	"20160104"
+#define MAIL_RELEASE_DATE	"20160117"
 #define MAIL_VERSION_NUMBER	"3.1"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/global/smtp_reply_footer.c b/postfix/src/global/smtp_reply_footer.c
index bd306b408..ee3f3bf85 100644
--- a/postfix/src/global/smtp_reply_footer.c
+++ b/postfix/src/global/smtp_reply_footer.c
@@ -10,7 +10,7 @@
 /*					lookup, context)
 /*	VSTRING	*buffer;
 /*	ssize_t	start;
-/*	char	*template;
+/*	const char *template;
 /*	const char *filter;
 /*	const char *(*lookup) (const char *name, void *context);
 /*	void	*context;
@@ -50,8 +50,9 @@
 /* SEE ALSO
 /*	mac_expand(3) macro expansion
 /* DIAGNOSTICS
-/*	smtp_reply_footer() returns 0 upon success, -1 if the
-/*	existing reply text is malformed.
+/*	smtp_reply_footer() returns 0 upon success, -1 if the existing
+/*	reply text is malformed, -2 in the case of a template macro
+/*	parsing error (an undefined macro value is not an error).
 /*
 /*	Fatal errors: memory allocation problem.
 /* LICENSE
@@ -63,6 +64,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
@@ -74,6 +80,7 @@
 /* Utility library. */
 
 #include 
+#include 
 #include 
 
 /* Global library. */
@@ -86,7 +93,7 @@
 #define STR	vstring_str
 
 int     smtp_reply_footer(VSTRING *buffer, ssize_t start,
-			          char *template,
+			          const char *template,
 			          const char *filter,
 			          MAC_EXP_LOOKUP_FN lookup,
 			          void *context)
@@ -95,9 +102,14 @@ int     smtp_reply_footer(VSTRING *buffer, ssize_t start,
     char   *cp;
     char   *next;
     char   *end;
-    ssize_t dsn_len;
+    ssize_t dsn_len;			/* last status code length */
+    ssize_t dsn_offs = -1;		/* last status code offset */
     int     crlf_at_end = 0;
-    ssize_t reply_patch_undo_offs = -1;
+    ssize_t reply_code_offs = -1;	/* last SMTP reply code offset */
+    ssize_t reply_patch_undo_len;	/* length without final CRLF */
+    int     mac_expand_error = 0;
+    int     line_added;
+    char   *saved_template;
 
     /*
      * Sanity check.
@@ -108,15 +120,15 @@ int     smtp_reply_footer(VSTRING *buffer, ssize_t start,
 	msg_panic("%s: empty template", myname);
 
     /*
-     * Scan and patch the original response. If the response is not what we
-     * expect, we stop making changes.
+     * Scan the original response without making changes. If the response is
+     * not what we expect, report an error. Otherwise, remember the offset of
+     * the last SMTP reply code.
      */
     for (cp = STR(buffer) + start, end = cp + strlen(cp);;) {
 	if (!ISDIGIT(cp[0]) || !ISDIGIT(cp[1]) || !ISDIGIT(cp[2])
 	    || (cp[3] != ' ' && cp[3] != '-'))
 	    return (-1);
-	cp[3] = '-';
-	reply_patch_undo_offs = cp + 3 - STR(buffer);
+	reply_code_offs = cp - STR(buffer);
 	if ((next = strstr(cp, "\r\n")) == 0) {
 	    next = end;
 	    break;
@@ -127,53 +139,150 @@ int     smtp_reply_footer(VSTRING *buffer, ssize_t start,
 	    break;
 	}
     }
+    if (reply_code_offs < 0)
+	return (-1);
 
     /*
      * Truncate text after the first null, and truncate the trailing CRLF.
      */
     if (next < vstring_end(buffer))
 	vstring_truncate(buffer, next - STR(buffer));
+    reply_patch_undo_len = VSTRING_LEN(buffer);
 
     /*
      * Append the footer text one line at a time. Caution: before we append
      * parts from the buffer to itself, we must extend the buffer first,
      * otherwise we would have a dangling pointer "read" bug.
+     * 
+     * XXX mac_expand() has no template length argument, so we must
+     * null-terminate the template in the middle.
      */
-    dsn_len = dsn_valid(STR(buffer) + start + 4);
-    for (cp = template, end = cp + strlen(cp);;) {
+    dsn_offs = reply_code_offs + 4;
+    dsn_len = dsn_valid(STR(buffer) + dsn_offs);
+    line_added = 0;
+    saved_template = mystrdup(template);
+    for (cp = saved_template, end = cp + strlen(cp);;) {
 	if ((next = strstr(cp, "\\n")) != 0) {
 	    *next = 0;
 	} else {
 	    next = end;
 	}
-	if (cp == template && strncmp(cp, "\\c", 2) == 0) {
+	if (cp == saved_template && strncmp(cp, "\\c", 2) == 0) {
 	    /* Handle \c at start of template. */
 	    cp += 2;
 	} else {
 	    /* Append a clone of the SMTP reply code. */
 	    vstring_strcat(buffer, "\r\n");
 	    VSTRING_SPACE(buffer, 3);
-	    vstring_strncat(buffer, STR(buffer) + start, 3);
+	    vstring_strncat(buffer, STR(buffer) + reply_code_offs, 3);
 	    vstring_strcat(buffer, next != end ? "-" : " ");
 	    /* Append a clone of the optional enhanced status code. */
 	    if (dsn_len > 0) {
 		VSTRING_SPACE(buffer, dsn_len);
-		vstring_strncat(buffer, STR(buffer) + start + 4, dsn_len);
+		vstring_strncat(buffer, STR(buffer) + dsn_offs, dsn_len);
 		vstring_strcat(buffer, " ");
 	    }
-	    reply_patch_undo_offs = -1;
+	    line_added = 1;
 	}
 	/* Append one line of footer text. */
-	mac_expand(buffer, cp, MAC_EXP_FLAG_APPEND, filter, lookup, context);
+	mac_expand_error = (mac_expand(buffer, cp, MAC_EXP_FLAG_APPEND, filter,
+				       lookup, context) & MAC_PARSE_ERROR);
+	if (mac_expand_error)
+	    break;
 	if (next < end) {
-	    *next = '\\';
 	    cp = next + 2;
 	} else
 	    break;
     }
-    if (reply_patch_undo_offs > 0)
-	STR(buffer)[reply_patch_undo_offs] = ' ';
+    myfree(saved_template);
+    /* Discard appended text after error, or finalize the result. */
+    if (mac_expand_error) {
+	vstring_truncate(buffer, reply_patch_undo_len);
+	VSTRING_TERMINATE(buffer);
+    } else if (line_added > 0) {
+	STR(buffer)[reply_code_offs + 3] = '-';
+    }
+    /* Restore CRLF at end. */
     if (crlf_at_end)
 	vstring_strcat(buffer, "\r\n");
-    return (0);
+    return (mac_expand_error ? -2 : 0);
 }
+
+#ifdef TEST
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct test_case {
+    const char *title;
+    const char *orig_reply;
+    const char *template;
+    const char *filter;
+    int     expected_status;
+    const char *expected_reply;
+};
+
+#define NO_FILTER	((char *) 0)
+#define NO_TEMPLATE	"NO_TEMPLATE"
+#define NO_ERROR	(0)
+#define BAD_SMTP	(-1)
+#define BAD_MACRO	(-2)
+
+static struct test_case test_cases[] = {
+    {"missing reply", "", NO_TEMPLATE, NO_FILTER, BAD_SMTP, 0},
+    {"long smtp_code", "1234 foo", NO_TEMPLATE, NO_FILTER, BAD_SMTP, 0},
+    {"short smtp_code", "12 foo", NO_TEMPLATE, NO_FILTER, BAD_SMTP, 0},
+    {"good+bad smtp_code", "321 foo\r\n1234 foo", NO_TEMPLATE, NO_FILTER, BAD_SMTP, 0},
+    {"1-line no dsn", "550 Foo", "\\c footer", NO_FILTER, NO_ERROR, "550 Foo footer"},
+    {"1-line no dsn", "550 Foo", "Bar", NO_FILTER, NO_ERROR, "550-Foo\r\n550 Bar"},
+    {"2-line no dsn", "550-Foo\r\n550 Bar", "Baz", NO_FILTER, NO_ERROR, "550-Foo\r\n550-Bar\r\n550 Baz"},
+    {"1-line with dsn", "550 5.1.1 Foo", "Bar", NO_FILTER, NO_ERROR, "550-5.1.1 Foo\r\n550 5.1.1 Bar"},
+    {"2-line with dsn", "550-5.1.1 Foo\r\n450 4.1.1 Bar", "Baz", NO_FILTER, NO_ERROR, "550-5.1.1 Foo\r\n450-4.1.1 Bar\r\n450 4.1.1 Baz"},
+    {"bad macro", "220 myhostname", "\\c ${whatever", NO_FILTER, BAD_MACRO, 0},
+    {"bad macroCRLF", "220 myhostname\r\n", "\\c ${whatever", NO_FILTER, BAD_MACRO, 0},
+    {"good macro", "220 myhostname", "\\c $whatever", NO_FILTER, NO_ERROR, "220 myhostname DUMMY"},
+    {"good macroCRLF", "220 myhostname\r\n", "\\c $whatever", NO_FILTER, NO_ERROR, "220 myhostname DUMMY\r\n"},
+    0,
+};
+
+static const char *lookup(const char *name, int unused_mode, void *context)
+{
+    return "DUMMY";
+}
+
+int     main(int argc, char **argv)
+{
+    struct test_case *tp;
+    int     status;
+    VSTRING *buf = vstring_alloc(10);
+    void   *context = 0;
+
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+
+    for (tp = test_cases; tp->title != 0; tp++) {
+	vstring_strcpy(buf, tp->orig_reply);
+	status = smtp_reply_footer(buf, 0, tp->template, tp->filter,
+				   lookup, context);
+	if (status != tp->expected_status) {
+	    msg_warn("test \"%s\": status %d, expected %d",
+		     tp->title, status, tp->expected_status);
+	} else if (status < 0 && strcmp(STR(buf), tp->orig_reply) != 0) {
+	    msg_warn("test \"%s\": result \"%s\", expected \"%s\"",
+		     tp->title, STR(buf), tp->orig_reply);
+	} else if (status == 0 && strcmp(STR(buf), tp->expected_reply) != 0) {
+	    msg_warn("test \"%s\": result \"%s\", expected \"%s\"",
+		     tp->title, STR(buf), tp->expected_reply);
+	} else {
+	    msg_info("test \"%s\": pass", tp->title);
+	}
+    }
+    vstring_free(buf);
+    exit(0);
+}
+
+#endif
diff --git a/postfix/src/global/smtp_reply_footer.h b/postfix/src/global/smtp_reply_footer.h
index c13091a13..ab053a533 100644
--- a/postfix/src/global/smtp_reply_footer.h
+++ b/postfix/src/global/smtp_reply_footer.h
@@ -20,7 +20,7 @@
  /*
   * External interface.
   */
-extern int smtp_reply_footer(VSTRING *, ssize_t, char *, const char *,
+extern int smtp_reply_footer(VSTRING *, ssize_t, const char *, const char *,
 			             MAC_EXP_LOOKUP_FN, void *);
 
 /* LICENSE
@@ -32,6 +32,11 @@ extern int smtp_reply_footer(VSTRING *, ssize_t, char *, const char *,
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 #endif
diff --git a/postfix/src/global/smtp_reply_footer.ref b/postfix/src/global/smtp_reply_footer.ref
new file mode 100644
index 000000000..d7eb5a7b5
--- /dev/null
+++ b/postfix/src/global/smtp_reply_footer.ref
@@ -0,0 +1,15 @@
+./smtp_reply_footer: test "missing reply": pass
+./smtp_reply_footer: test "long smtp_code": pass
+./smtp_reply_footer: test "short smtp_code": pass
+./smtp_reply_footer: test "good+bad smtp_code": pass
+./smtp_reply_footer: test "1-line no dsn": pass
+./smtp_reply_footer: test "1-line no dsn": pass
+./smtp_reply_footer: test "2-line no dsn": pass
+./smtp_reply_footer: test "1-line with dsn": pass
+./smtp_reply_footer: test "2-line with dsn": pass
+./smtp_reply_footer: warning: truncated macro reference: " ${whatever"
+./smtp_reply_footer: test "bad macro": pass
+./smtp_reply_footer: warning: truncated macro reference: " ${whatever"
+./smtp_reply_footer: test "bad macroCRLF": pass
+./smtp_reply_footer: test "good macro": pass
+./smtp_reply_footer: test "good macroCRLF": pass
diff --git a/postfix/src/postconf/Makefile.in b/postfix/src/postconf/Makefile.in
index 186ca86b3..27905a62d 100644
--- a/postfix/src/postconf/Makefile.in
+++ b/postfix/src/postconf/Makefile.in
@@ -49,7 +49,8 @@ tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
 	test22 test23 test24 test25 test26 test27 test28 test29 test30 test4b \
 	test31 test32 test33 test34 test35 test36 test37 test39 test40 test41 \
 	test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
-	test52 test53 test54 test55 test56 test57 test58 test59
+	test52 test53 test54 test55 test56 test57 test58 test59 test60 test61 \
+	test62 test63
 
 root_tests:
 
@@ -805,6 +806,46 @@ test59: $(PROG) test59.ref
 	diff test59.ref test59.tmp
 	rm -f main.cf master.cf test59.tmp
 
+test60: $(PROG) test60.ref
+	rm -f main.cf master.cf
+	touch main.cf master.cf
+	echo foo unix - n n - 0 other >> master.cf
+	echo ' -o always_bcc=bar' >> master.cf
+	touch -t 197101010000 main.cf
+	$(SHLIB_ENV) ./$(PROG) -Fhc. >test60.tmp 2>&1 || true
+	diff test60.ref test60.tmp
+	rm -f main.cf master.cf test60.tmp
+
+test61: $(PROG) test61.ref
+	rm -f main.cf master.cf
+	touch main.cf master.cf
+	echo foo unix - n n - 0 other >> master.cf
+	echo ' -o always_bcc=bar' >> master.cf
+	touch -t 197101010000 main.cf
+	$(SHLIB_ENV) ./$(PROG) -Phc. >test61.tmp 2>&1 || true
+	diff test61.ref test61.tmp
+	rm -f main.cf master.cf test61.tmp
+
+test62: $(PROG) test62.ref
+	rm -f main.cf master.cf
+	touch main.cf master.cf
+	echo foo unix - n n - 0 other >> master.cf
+	echo ' -o always_bcc=bar' >> master.cf
+	touch -t 197101010000 main.cf
+	$(SHLIB_ENV) ./$(PROG) -FHc. >test62.tmp 2>&1 || true
+	diff test62.ref test62.tmp
+	rm -f main.cf master.cf test62.tmp
+
+test63: $(PROG) test63.ref
+	rm -f main.cf master.cf
+	touch main.cf master.cf
+	echo foo unix - n n - 0 other >> master.cf
+	echo ' -o always_bcc=bar' >> master.cf
+	touch -t 197101010000 main.cf
+	$(SHLIB_ENV) ./$(PROG) -PHc. >test63.tmp 2>&1 || true
+	diff test63.ref test63.tmp
+	rm -f main.cf master.cf test63.tmp
+
 printfck: $(OBJS) $(PROG)
 	rm -rf printfck
 	mkdir printfck
diff --git a/postfix/src/postconf/postconf.c b/postfix/src/postconf/postconf.c
index 4107e0a7d..5fccb20db 100644
--- a/postfix/src/postconf/postconf.c
+++ b/postfix/src/postconf/postconf.c
@@ -7,7 +7,7 @@
 /* .fi
 /*	\fBManaging main.cf:\fR
 /*
-/*	\fBpostconf\fR [\fB-dfhnopvx\fR] [\fB-c \fIconfig_dir\fR]
+/*	\fBpostconf\fR [\fB-dfhHnopvx\fR] [\fB-c \fIconfig_dir\fR]
 /*	[\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
 /*
 /*	\fBpostconf\fR [\fB-epv\fR] [\fB-c \fIconfig_dir\fR]
@@ -35,7 +35,7 @@
 /*
 /*	\fBManaging master.cf service fields:\fR
 /*
-/*	\fBpostconf\fR \fB-F\fR [\fB-fovx\fR] [\fB-c \fIconfig_dir\fR]
+/*	\fBpostconf\fR \fB-F\fR [\fB-fhHovx\fR] [\fB-c \fIconfig_dir\fR]
 /*	[\fIservice\fR[\fB/\fItype\fR[\fB/\fIfield\fR]]\fI ...\fR]
 /*
 /*	\fBpostconf\fR \fB-F\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
@@ -43,7 +43,7 @@
 /*
 /*	\fBManaging master.cf service parameters:\fR
 /*
-/*	\fBpostconf\fR \fB-P\fR [\fB-fovx\fR] [\fB-c \fIconfig_dir\fR]
+/*	\fBpostconf\fR \fB-P\fR [\fB-fhHovx\fR] [\fB-c \fIconfig_dir\fR]
 /*	[\fIservice\fR[\fB/\fItype\fR[\fB/\fIparameter\fR]]\fI ...\fR]
 /*
 /*	\fBpostconf\fR \fB-P\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
@@ -197,6 +197,11 @@
 /* .IP \fB-h\fR
 /*	Show parameter or attribute values without the "\fIname\fR
 /*	= " label that normally precedes the value.
+/* .IP \fB-H\fR
+/*	Show parameter or attribute names without the " = \fIvalue\fR"
+/*	that normally follows the name.
+/*
+/*	This feature is available with Postfix 3.1 and later.
 /* .IP \fB-l\fR
 /*	List the names of all supported mailbox locking methods.
 /*	Postfix supports the following methods:
@@ -505,6 +510,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
@@ -572,7 +582,8 @@ static const int pcf_incompat_options[] = {
     PCF_SHOW_EVAL | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
     PCF_MAIN_OVER | PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_COMMENT_OUT \
     |PCF_EDIT_EXCL,
-    PCF_HIDE_NAME | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
+    PCF_HIDE_NAME | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL \
+    |PCF_HIDE_VALUE,
     0,
 };
 
@@ -592,13 +603,14 @@ static const int pcf_compat_options[][2] = {
     {PCF_MAIN_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \
 		      |PCF_FOLD_LINE | PCF_HIDE_NAME | PCF_PARAM_CLASS \
 		      |PCF_SHOW_EVAL | PCF_SHOW_DEFS | PCF_SHOW_NONDEF \
-		      |PCF_MAIN_OVER)},
+		      |PCF_MAIN_OVER | PCF_HIDE_VALUE)},
     {PCF_MASTER_ENTRY, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_COMMENT_OUT \
 			|PCF_FOLD_LINE | PCF_MAIN_OVER | PCF_SHOW_EVAL)},
     {PCF_MASTER_FLD, (PCF_EDIT_CONF | PCF_FOLD_LINE | PCF_HIDE_NAME \
-		      |PCF_MAIN_OVER | PCF_SHOW_EVAL)},
+		      |PCF_MAIN_OVER | PCF_SHOW_EVAL | PCF_HIDE_VALUE)},
     {PCF_MASTER_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_FOLD_LINE \
-			|PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL)},
+			|PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL \
+			|PCF_HIDE_VALUE)},
     /* Modifiers. */
     {PCF_PARAM_CLASS, (PCF_MAIN_PARAM | PCF_SHOW_DEFS | PCF_SHOW_NONDEF)},
     0,
@@ -617,6 +629,7 @@ static const NAME_MASK pcf_compat_names[] = {
     "-f", PCF_FOLD_LINE,
     "-F", PCF_MASTER_FLD,
     "-h", PCF_HIDE_NAME,
+    "-H", PCF_HIDE_VALUE,
     "-l", PCF_SHOW_LOCKS,
     "-m", PCF_SHOW_MAPS,
     "-M", PCF_MASTER_ENTRY,
@@ -646,6 +659,7 @@ static void usage(const char *progname)
 	      " [-f (fold lines)]"
 	      " [-F (master.cf fields)]"
 	      " [-h (no names)]"
+	      " [-H (no values)]"
 	      " [-l (lock types)]"
 	      " [-m (map types)]"
 	      " [-M (master.cf)]"
@@ -749,7 +763,7 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "aAbc:C:deEfFhlmMno:pPtvxX#")) > 0) {
+    while ((ch = GETOPT(argc, argv, "aAbc:C:deEfFhHlmMno:pPtvxX#")) > 0) {
 	switch (ch) {
 	case 'a':
 	    pcf_cmd_mode |= PCF_SHOW_SASL_SERV;
@@ -790,6 +804,9 @@ int     main(int argc, char **argv)
 	case 'h':
 	    pcf_cmd_mode |= PCF_HIDE_NAME;
 	    break;
+	case 'H':
+	    pcf_cmd_mode |= PCF_HIDE_VALUE;
+	    break;
 	case 'l':
 	    pcf_cmd_mode |= PCF_SHOW_LOCKS;
 	    break;
diff --git a/postfix/src/postconf/postconf.h b/postfix/src/postconf/postconf.h
index 60d1749de..06b53d1a8 100644
--- a/postfix/src/postconf/postconf.h
+++ b/postfix/src/postconf/postconf.h
@@ -44,6 +44,7 @@
 #define PCF_MAIN_OVER		(1<<17)	/* override parameter values */
 #define PCF_DUMP_DSN_TEMPL	(1<<18)	/* show bounce templates */
 #define PCF_MASTER_PARAM	(1<<19)	/* manage master.cf -o name=value */
+#define PCF_HIDE_VALUE		(1<<20)	/* hide main.cf/master.cf =value */
 
 #define PCF_DEF_MODE	0
 
@@ -312,4 +313,9 @@ extern void pcf_show_sasl(int);
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
diff --git a/postfix/src/postconf/postconf_builtin.c b/postfix/src/postconf/postconf_builtin.c
index 9b06c25f0..1088433b3 100644
--- a/postfix/src/postconf/postconf_builtin.c
+++ b/postfix/src/postconf/postconf_builtin.c
@@ -30,6 +30,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
diff --git a/postfix/src/postconf/postconf_main.c b/postfix/src/postconf/postconf_main.c
index 31864c2a6..07485f188 100644
--- a/postfix/src/postconf/postconf_main.c
+++ b/postfix/src/postconf/postconf_main.c
@@ -63,6 +63,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
@@ -146,13 +151,17 @@ static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name,
      * or without the name= prefix.
      */
     if (value != 0) {
-	if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0)
-	    value = pcf_expand_parameter_value((VSTRING *) 0, mode, value,
-					       (PCF_MASTER_ENT *) 0);
-	if ((mode & PCF_HIDE_NAME) == 0) {
-	    pcf_print_line(fp, mode, "%s = %s\n", name, value);
+	if (mode & PCF_HIDE_VALUE) {
+	    pcf_print_line(fp, mode, "%s\n", name);
 	} else {
-	    pcf_print_line(fp, mode, "%s\n", value);
+	    if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0)
+		value = pcf_expand_parameter_value((VSTRING *) 0, mode, value,
+						   (PCF_MASTER_ENT *) 0);
+	    if ((mode & PCF_HIDE_NAME) == 0) {
+		pcf_print_line(fp, mode, "%s = %s\n", name, value);
+	    } else {
+		pcf_print_line(fp, mode, "%s\n", value);
+	    }
 	}
 	if (msg_verbose)
 	    vstream_fflush(fp);
diff --git a/postfix/src/postconf/postconf_master.c b/postfix/src/postconf/postconf_master.c
index 4842d1a8e..e6cf4e3b1 100644
--- a/postfix/src/postconf/postconf_master.c
+++ b/postfix/src/postconf/postconf_master.c
@@ -132,6 +132,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
@@ -659,20 +664,24 @@ static void pcf_print_master_field(VSTREAM *fp, int mode,
 	ADD_TEXT(argv[1], strlen(argv[1]));
 	ADD_CHAR(PCF_NAMESP_SEP_STR);
 	ADD_TEXT(pcf_str_field_pattern(field), strlen(pcf_str_field_pattern(field)));
+    }
+    if ((mode & (PCF_HIDE_NAME | PCF_HIDE_VALUE)) == 0) {
 	ADD_TEXT(" = ", 3);
-	if (line_len + strlen(argv[field]) > PCF_LINE_LIMIT) {
+    }
+    if ((mode & PCF_HIDE_VALUE) == 0) {
+	if (line_len > 0 && line_len + strlen(argv[field]) > PCF_LINE_LIMIT) {
 	    vstream_fputs("\n" PCF_INDENT_TEXT, fp);
 	    line_len = PCF_INDENT_LEN;
 	}
+	ADD_TEXT(argv[field], strlen(argv[field]));
     }
-    ADD_TEXT(argv[field], strlen(argv[field]));
 
     /*
      * Format the daemon command-line options and non-option arguments. Here,
      * we have no data-dependent preference for column positions, but we do
      * have argument grouping preferences.
      */
-    if (field == PCF_MASTER_FLD_CMD) {
+    if (field == PCF_MASTER_FLD_CMD && (mode & PCF_HIDE_VALUE) == 0) {
 	in_daemon_options = 1;
 	for (field += 1; (arg = argv[field]) != 0; field++) {
 	    arg_len = strlen(arg);
@@ -853,15 +862,21 @@ static void pcf_print_master_param(VSTREAM *fp, int mode,
 				           const char *param_name,
 				           const char *param_value)
 {
-    if ((mode & PCF_SHOW_EVAL) != 0)
-	param_value = pcf_expand_parameter_value((VSTRING *) 0, mode,
-						 param_value, masterp);
-    if ((mode & PCF_HIDE_NAME) == 0) {
-	pcf_print_line(fp, mode, "%s%c%s = %s\n",
+    if (mode & PCF_HIDE_VALUE) {
+	pcf_print_line(fp, mode, "%s%c%s\n",
 		       masterp->name_space, PCF_NAMESP_SEP_CH,
-		       param_name, param_value);
+		       param_name);
     } else {
-	pcf_print_line(fp, mode, "%s\n", param_value);
+	if ((mode & PCF_SHOW_EVAL) != 0)
+	    param_value = pcf_expand_parameter_value((VSTRING *) 0, mode,
+						     param_value, masterp);
+	if ((mode & PCF_HIDE_NAME) == 0) {
+	    pcf_print_line(fp, mode, "%s%c%s = %s\n",
+			   masterp->name_space, PCF_NAMESP_SEP_CH,
+			   param_name, param_value);
+	} else {
+	    pcf_print_line(fp, mode, "%s\n", param_value);
+	}
     }
     if (msg_verbose)
 	vstream_fflush(fp);
diff --git a/postfix/src/postconf/postconf_service.c b/postfix/src/postconf/postconf_service.c
index 9322c093a..38a4cce64 100644
--- a/postfix/src/postconf/postconf_service.c
+++ b/postfix/src/postconf/postconf_service.c
@@ -28,6 +28,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
diff --git a/postfix/src/postconf/test22.ref b/postfix/src/postconf/test22.ref
index bb1c81e10..1e4629fc2 100644
--- a/postfix/src/postconf/test22.ref
+++ b/postfix/src/postconf/test22.ref
@@ -13,3 +13,4 @@ whatevershebrings_minimum_delivery_slots = $default_minimum_delivery_slots
 whatevershebrings_recipient_limit = $default_recipient_limit
 whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay
 whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit
+whatevershebrings_transport_rate_delay = $default_transport_rate_delay
diff --git a/postfix/src/postconf/test25.ref b/postfix/src/postconf/test25.ref
index bb1c81e10..1e4629fc2 100644
--- a/postfix/src/postconf/test25.ref
+++ b/postfix/src/postconf/test25.ref
@@ -13,3 +13,4 @@ whatevershebrings_minimum_delivery_slots = $default_minimum_delivery_slots
 whatevershebrings_recipient_limit = $default_recipient_limit
 whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay
 whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit
+whatevershebrings_transport_rate_delay = $default_transport_rate_delay
diff --git a/postfix/src/postconf/test27.ref b/postfix/src/postconf/test27.ref
index bb1c81e10..1e4629fc2 100644
--- a/postfix/src/postconf/test27.ref
+++ b/postfix/src/postconf/test27.ref
@@ -13,3 +13,4 @@ whatevershebrings_minimum_delivery_slots = $default_minimum_delivery_slots
 whatevershebrings_recipient_limit = $default_recipient_limit
 whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay
 whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit
+whatevershebrings_transport_rate_delay = $default_transport_rate_delay
diff --git a/postfix/src/postconf/test6.ref b/postfix/src/postconf/test6.ref
index 504c0c32a..55e47f223 100644
--- a/postfix/src/postconf/test6.ref
+++ b/postfix/src/postconf/test6.ref
@@ -14,3 +14,4 @@ whatevershebrings_recipient_limit = $default_recipient_limit
 whatevershebrings_recipient_refill_delay = $default_recipient_refill_delay
 whatevershebrings_recipient_refill_limit = $default_recipient_refill_limit
 whatevershebrings_time_limit = $command_time_limit
+whatevershebrings_transport_rate_delay = $default_transport_rate_delay
diff --git a/postfix/src/postconf/test60.ref b/postfix/src/postconf/test60.ref
new file mode 100644
index 000000000..5a6f3ca57
--- /dev/null
+++ b/postfix/src/postconf/test60.ref
@@ -0,0 +1,8 @@
+foo
+unix
+-
+n
+n
+-
+0
+other -o always_bcc=bar
diff --git a/postfix/src/postconf/test61.ref b/postfix/src/postconf/test61.ref
new file mode 100644
index 000000000..5716ca598
--- /dev/null
+++ b/postfix/src/postconf/test61.ref
@@ -0,0 +1 @@
+bar
diff --git a/postfix/src/postconf/test62.ref b/postfix/src/postconf/test62.ref
new file mode 100644
index 000000000..ffc491318
--- /dev/null
+++ b/postfix/src/postconf/test62.ref
@@ -0,0 +1,8 @@
+foo/unix/service
+foo/unix/type
+foo/unix/private
+foo/unix/unprivileged
+foo/unix/chroot
+foo/unix/wakeup
+foo/unix/process_limit
+foo/unix/command
diff --git a/postfix/src/postconf/test63.ref b/postfix/src/postconf/test63.ref
new file mode 100644
index 000000000..b609d6278
--- /dev/null
+++ b/postfix/src/postconf/test63.ref
@@ -0,0 +1 @@
+foo/unix/always_bcc
diff --git a/postfix/src/postlog/postlog.c b/postfix/src/postlog/postlog.c
index 7403b079c..be1d2850a 100644
--- a/postfix/src/postlog/postlog.c
+++ b/postfix/src/postlog/postlog.c
@@ -72,6 +72,11 @@
 /*	IBM T.J. Watson Research
 /*	P.O. Box 704
 /*	Yorktown Heights, NY 10598, USA
+/*
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
 /*--*/
 
 /* System library. */
diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c
index 330a031db..424d8edde 100644
--- a/postfix/src/tls/tls_misc.c
+++ b/postfix/src/tls/tls_misc.c
@@ -461,7 +461,7 @@ static const char *tls_exclude_missing(SSL_CTX *ctx, VSTRING *buf)
     static ARGV *exclude;		/* Cached */
     SSL    *s = 0;
     ssl_cipher_stack_t *ciphers;
-    SSL_CIPHER *c;
+    const SSL_CIPHER *c;
     const cipher_probe_t *probe;
     int     alg_bits;
     int     num;