]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20140929
authorWietse Venema <wietse@porcupine.org>
Mon, 29 Sep 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Fri, 3 Oct 2014 14:00:46 +0000 (10:00 -0400)
16 files changed:
postfix/HISTORY
postfix/README_FILES/ADDRESS_VERIFICATION_README
postfix/RELEASE_NOTES
postfix/html/ADDRESS_VERIFICATION_README.html
postfix/html/master.5.html
postfix/html/pipe.8.html
postfix/man/man5/master.5
postfix/man/man8/pipe.8
postfix/proto/ADDRESS_VERIFICATION_README.html
postfix/proto/master
postfix/src/global/attr_override.c
postfix/src/global/attr_override.h
postfix/src/global/mail_version.h
postfix/src/milter/milter.c
postfix/src/pipe/pipe.c
postfix/src/smtpd/smtpd_check.c

index d5bf5e963cf8529d6a273aaa8e72abbdb725c63f..92770b1372146714dd4d93e7000dd39e353a8355 100644 (file)
@@ -20506,3 +20506,18 @@ Apologies for any names omitted.
        non-ASCII cruft into the HTML-ized manpages.  Files:
        html/Makefile.in, proto/Makefile.in, many HTML output
        files.
+
+20140929
+
+       Cleanup: the table-driven code for per-Milter and per-policy
+       overrides now updates arbitrary variables, so that it can also
+       be used for, say, TLS policies. Files: global/attr_override.[hc],
+       smtpd/smtpd_check.c, milter/milter.c.
+
+       Documentation: support for "{ argument with whitespace }"
+       in master(5) and pipe(8). Files: proto/master, src/pipe/pipe.c.
+
+       Documentation: in ADDRES_VERIFY_README, replaced "nearest
+       MTA" with "preferred MTA". The SMTP client was changed years
+       ago to try alternate MXes after a 4XX SMTP server response.
+       File: proto/ADDRES_VERIFY_README.html.
index 7aef096dd97b6218c1bd9099a00bcf6ca4d5464a..cbd171639b3a7d7cd233de17fac3bca6767e78bb 100644 (file)
@@ -41,11 +41,11 @@ Topics covered in this document:
 
 H\bHo\bow\bw a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn w\bwo\bor\brk\bks\bs
 
-A Postfix MTA verifies a sender or recipient address by probing the nearest MTA
-for that address, without actually delivering mail. The nearest MTA could be
-the Postfix MTA itself, or it could be a remote MTA (SMTP interruptus). Probe
-messages are like normal mail, except that they are never delivered, deferred
-or bounced; probe messages are always discarded.
+A Postfix MTA verifies a sender or recipient address by probing the preferred
+MTAs for that address, without actually delivering mail. The preferred MTAs
+could include the Postfix MTA itself, or some remote MTAs (SMTP interruptus).
+Probe messages are like normal mail, except that they are never delivered,
+deferred or bounced; probe messages are always discarded.
 
                                
                                              probe     Postfix
@@ -81,12 +81,11 @@ postconf(5) for details.
 
 L\bLi\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs o\bof\bf a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 
-  * When verifying a remote address, Postfix probes the nearest MTA for that
-    address, without actually delivering mail to it. If the nearest MTA accepts
-    the address, then Postfix assumes that the address is deliverable. In
-    reality, mail for a remote address can bounce AFTER the nearest MTA accepts
-    the recipient address, or AFTER the nearest MTA accepts the message
-    content.
+  * When verifying a remote address, Postfix probes the preferred MTAs for that
+    address, without actually delivering mail. If a preferred MTA accepts the
+    address, then Postfix assumes that the address is deliverable. In reality,
+    mail for a remote address can bounce AFTER a preferred MTA accepts the
+    recipient address, or AFTER a preferred MTA accepts the message content.
 
   * Some sites may blacklist you when you are probing them too often (a probe
     is an SMTP session that does not deliver mail), or when you are probing
@@ -101,10 +100,10 @@ L\bLi\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs o\bof\bf a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\b
     to override mail routing and for possible limitations when you have to do
     this.
 
-  * Postfix assumes that an address is undeliverable when the nearest MTA for
+  * Postfix assumes that an address is undeliverable when a preferred MTA for
     the address rejects the probe, regardless of the reason for rejection
     (client rejected, HELO rejected, MAIL FROM rejected, etc.). Thus, Postfix
-    rejects an address when the nearest MTA for that address rejects mail from
+    rejects an address when a preferred MTA for that address rejects mail from
     your machine for any reason. This is not a limitation, but it is mentioned
     here just in case people believe that it is a limitation.
 
index 24e5a1bd03fe90b24d010ecac176f55efb6cc613..bd18141218b6fa27bdb48a0c4f5cc5bf59a2aff0 100644 (file)
@@ -44,6 +44,8 @@ about build options that are not described in the INSTALL instructions.
 Major changes with snapshot 20140928
 ====================================
 
+Per-Milter settings
+-------------------
 Support for per-Milter settings that override main.cf parameters.
 For details see the section "Advanced policy client configuration"
 in the SMTPD_POLICY_README document.
@@ -62,6 +64,8 @@ content_timeout, default_action, and protocol. These have the same
 names as the corresponding main.cf parameters, without the "milter_"
 prefix.
 
+Per-policy service settings
+---------------------------
 Support for per-policy service settings that override main.cf
 parameters.  For details see the section "Different settings for
 different Milter applications" in the MILTER_README document.
@@ -82,6 +86,21 @@ request_limit, retry_delay, timeout, try_limit. These have the same
 names as the corresponding main.cf parameters, without the
 "smtpd_policy_service_" prefix.
 
+Whitespace in master.cf command-line arguments
+----------------------------------------------
+Support for whitespace in daemon command-line arguments. For details, see
+the "Command name + arguments" section in the master(5) manpage.
+Example:
+
+    smtpd -o { parameter = value containing whitespace } ...
+
+The { ... } form is also available for non-option command-line
+arguments in master.cf, for example:
+
+    pipe ... argv=command { argument containing whitespace } ...
+
+In both cases, whitespace immediately after "{" and before "}"
+is ignored.
 
 Major changes with snapshot 20140921
 ====================================
index 95e73c46204d0c74c74f67cc16505875d2838a3a..7bf7adb810938def351a24eae1a3f51085e186b4 100644 (file)
@@ -75,9 +75,9 @@ verification probes</a>
 <h2><a name="how">How address verification works</a></h2>
 
 <p> A Postfix MTA verifies a sender or recipient address by probing
-the nearest
-MTA for that address, without actually delivering mail. The nearest
-MTA could be the Postfix MTA itself, or it could be a remote MTA
+the preferred MTAs
+for that address, without actually delivering mail. The preferred
+MTAs could include the Postfix MTA itself, or some remote MTAs
 (SMTP
 interruptus).  Probe messages are like normal mail, except that
 they are never delivered, deferred or bounced; probe messages are
@@ -198,12 +198,12 @@ details. </p>
 
 <ul>
 
-<li> <p> When verifying a remote address, Postfix probes the nearest
-MTA for that address, without actually delivering mail to it. If
-the nearest MTA accepts the address, then Postfix assumes that the
+<li> <p> When verifying a remote address, Postfix probes the preferred
+MTAs for that address, without actually delivering mail. If
+a preferred MTA accepts the address, then Postfix assumes that the
 address is deliverable. In reality, mail for a remote address can
-bounce AFTER the nearest MTA accepts the recipient address, or AFTER
-the nearest MTA accepts the message content. </p>
+bounce AFTER a preferred MTA accepts the recipient address, or AFTER
+a preferred MTA accepts the message content. </p>
 
 <li> <p> Some sites may blacklist you when you are probing them
 too often (a probe is an SMTP session that does not deliver mail),
@@ -219,10 +219,10 @@ the routing of address verification probes"</a>, for how to override
 mail routing and for possible limitations when you have to do this.
 </p>
 
-<li> <p> Postfix assumes that an address is undeliverable when the
-nearest MTA for the address rejects the probe, regardless of the
+<li> <p> Postfix assumes that an address is undeliverable when a
+preferred MTA for the address rejects the probe, regardless of the
 reason for rejection (client rejected, HELO rejected, MAIL FROM
-rejected, etc.).  Thus, Postfix rejects an address when the nearest
+rejected, etc.).  Thus, Postfix rejects an address when a preferred
 MTA for that address rejects mail from your machine for any reason.
 This is not a limitation, but it is mentioned here just in case
 people believe that it is a limitation. </p>
index 0125a8e98e19272b727f406fae089b5409fe2047..b61a7132dd892fa74bbe6f4fa91e7743d8645012 100644 (file)
@@ -163,31 +163,35 @@ MASTER(5)                                                            MASTER(5)
               The command to be executed.  Characters that are special to  the
               shell  such  as  "&gt;"  or  "|"  have no special meaning here, and
               quotes cannot be used to  protect  arguments  containing  white-
-              space.
+              space.  To  protect  whitespace,  use  "{"  and "}" as described
+              below.
 
-              The  command  name  is  relative to the Postfix daemon directory
-              (pathname is controlled by  the  <b><a href="postconf.5.html#daemon_directory">daemon_directory</a></b>  configuration
+              The command name is relative to  the  Postfix  daemon  directory
+              (pathname  is  controlled  by the <b><a href="postconf.5.html#daemon_directory">daemon_directory</a></b> configuration
               variable).
 
-              The  command  argument syntax for specific commands is specified
+              The command argument syntax for specific commands  is  specified
               in the respective daemon manual page.
 
-              The following command-line options have the same effect for  all
+              The  following command-line options have the same effect for all
               daemon programs:
 
-              <b>-D</b>     Run  the  daemon  under  control by the command specified
+              <b>-D</b>     Run the daemon under control  by  the  command  specified
                      with the <b><a href="postconf.5.html#debugger_command">debugger_command</a></b> variable in the <a href="postconf.5.html">main.cf</a> config-
                      uration file.  See <a href="DEBUG_README.html">DEBUG_README</a> for hints and tips.
 
-              <b>-o</b> <i>name</i>=<i>value</i>
-                     Override  the  named <a href="postconf.5.html">main.cf</a> configuration parameter. The
-                     parameter value can refer to other  parameters  as  <i>$name</i>
-                     etc.,  just like in <a href="postconf.5.html">main.cf</a>.  See <a href="postconf.5.html"><b>postconf</b>(5)</a> for syntax.
+              <b>-o</b> <i>name</i>=<i>value</i> (short form)
 
-                     NOTE 1: do not specify whitespace around the  "="  or  in
-                     parameter  values. To specify a parameter value that con-
-                     tains whitespace, use commas instead of spaces, or  spec-
-                     ify the value in <a href="postconf.5.html">main.cf</a>. Example:
+              <b>-o {</b> <i>name</i> = <i>value</i> <b>}</b> (Postfix 2.12 and later)
+                     Override the named <a href="postconf.5.html">main.cf</a> configuration  parameter.  The
+                     parameter  value  can  refer to other parameters as <i>$name</i>
+                     etc., just like in <a href="postconf.5.html">main.cf</a>.  See <a href="postconf.5.html"><b>postconf</b>(5)</a> for  syntax.
+
+                     NOTE 1: with the "short form" shown above, do not specify
+                     whitespace around the "="  or  in  parameter  values.  To
+                     specify  a  parameter value that contains whitespace, use
+                     commas  instead  of  spaces,  or  specify  the  value  in
+                     <a href="postconf.5.html">main.cf</a>. Example:
 
                      /etc/postfix/<a href="master.5.html">master.cf</a>:
                          submission inet .... smtpd
@@ -206,6 +210,11 @@ MASTER(5)                                                            MASTER(5)
                      options to make a  Postfix  daemon  process  increasingly
                      verbose.
 
+              Other command-line arguments
+                     Specify "{" and "}" around command arguments that contain
+                     whitespace (Postfix 2.12 and later).  Whitespace  immedi-
+                     ately after "{" and before "}" is ignored.
+
 <b>SEE ALSO</b>
        <a href="master.8.html">master(8)</a>, process manager
        <a href="postconf.5.html">postconf(5)</a>, configuration parameters
index 81f7d69d582ded5a4b00f50eda4ba1aa125a223d..3e22d84a271bbf4833f6f39a356f7fc19e2a259c 100644 (file)
@@ -191,20 +191,25 @@ PIPE(8)                                                                PIPE(8)
               out interpretation of shell meta characters by a  shell  command
               interpreter.
 
+              Specify "{" and "}" around command arguments that contain white-
+              space (Postfix 2.12 and later). Whitespace immediately after "{"
+              and before "}" is ignored.
+
               In  the command argument vector, the following macros are recog-
               nized and replaced with corresponding information from the Post-
               fix queue manager delivery request.
 
-              In addition to the form ${<i>name</i>}, the forms $<i>name</i> and $(<i>name</i>) are
-              also recognized.  Specify <b>$$</b> where a single <b>$</b> is wanted.
+              In  addition to the form ${<i>name</i>}, the forms $<i>name</i> and the depre-
+              cated form $(<i>name</i>) are also recognized.  Specify <b>$$</b> where a sin-
+              gle <b>$</b> is wanted.
 
               <b>${client_address}</b>
-                     This macro expands to the remote client network  address.
+                     This  macro expands to the remote client network address.
 
                      This feature is available as of Postfix 2.2.
 
               <b>${client_helo}</b>
-                     This  macro  expands  to  the  remote client HELO command
+                     This macro expands to  the  remote  client  HELO  command
                      parameter.
 
                      This feature is available as of Postfix 2.2.
@@ -215,7 +220,7 @@ PIPE(8)                                                                PIPE(8)
                      This feature is available as of Postfix 2.2.
 
               <b>${client_port}</b>
-                     This macro expands to the remote client TCP port  number.
+                     This  macro expands to the remote client TCP port number.
 
                      This feature is available as of Postfix 2.5.
 
@@ -226,7 +231,7 @@ PIPE(8)                                                                PIPE(8)
 
               <b>${domain}</b>
                      This macro expands to the domain portion of the recipient
-                     address.  For example, with  an  address  <i>user+foo@domain</i>
+                     address.   For  example,  with an address <i>user+foo@domain</i>
                      the domain is <i>domain</i>.
 
                      This information is modified by the <b>h</b> flag for case fold-
@@ -235,12 +240,12 @@ PIPE(8)                                                                PIPE(8)
                      This feature is available as of Postfix 2.5.
 
               <b>${extension}</b>
-                     This macro expands to the extension part of  a  recipient
-                     address.   For  example,  with an address <i>user+foo@domain</i>
+                     This  macro  expands to the extension part of a recipient
+                     address.  For example, with  an  address  <i>user+foo@domain</i>
                      the extension is <i>foo</i>.
 
-                     A  command-line  argument  that   contains   <b>${extension}</b>
-                     expands  into as many command-line arguments as there are
+                     A   command-line   argument  that  contains  <b>${extension}</b>
+                     expands into as many command-line arguments as there  are
                      recipients.
 
                      This information is modified by the <b>u</b> flag for case fold-
@@ -248,11 +253,11 @@ PIPE(8)                                                                PIPE(8)
 
               <b>${mailbox}</b>
                      This macro expands to the complete local part of a recip-
-                     ient   address.    For   example,   with    an    address
+                     ient    address.     For   example,   with   an   address
                      <i>user+foo@domain</i> the mailbox is <i>user+foo</i>.
 
-                     A  command-line argument that contains <b>${mailbox}</b> expands
-                     to as many command-line arguments as  there  are  recipi-
+                     A command-line argument that contains <b>${mailbox}</b>  expands
+                     to  as  many  command-line arguments as there are recipi-
                      ents.
 
                      This information is modified by the <b>u</b> flag for case fold-
@@ -265,11 +270,11 @@ PIPE(8)                                                                PIPE(8)
                      ing.
 
               <b>${original_recipient}</b>
-                     This  macro  expands  to  the  complete recipient address
+                     This macro expands  to  the  complete  recipient  address
                      before any address rewriting or aliasing.
 
-                     A command-line argument that contains  <b>${original_recipi-</b>
-                     <b>ent}</b>  expands  to as many command-line arguments as there
+                     A  command-line argument that contains <b>${original_recipi-</b>
+                     <b>ent}</b> expands to as many command-line arguments  as  there
                      are recipients.
 
                      This information is modified by the <b>hqu</b> flags for quoting
@@ -285,8 +290,8 @@ PIPE(8)                                                                PIPE(8)
               <b>${recipient}</b>
                      This macro expands to the complete recipient address.
 
-                     A   command-line   argument  that  contains  <b>${recipient}</b>
-                     expands to as many command-line arguments  as  there  are
+                     A  command-line  argument  that   contains   <b>${recipient}</b>
+                     expands  to  as  many command-line arguments as there are
                      recipients.
 
                      This information is modified by the <b>hqu</b> flags for quoting
@@ -294,13 +299,13 @@ PIPE(8)                                                                PIPE(8)
 
               <b>${sasl_method}</b>
                      This macro expands to the name of the SASL authentication
-                     mechanism  in  the  AUTH  command  when  the Postfix SMTP
+                     mechanism in the  AUTH  command  when  the  Postfix  SMTP
                      server received the message.
 
                      This feature is available as of Postfix 2.2.
 
               <b>${sasl_sender}</b>
-                     This macro expands to the  SASL  sender  name  (i.e.  the
+                     This  macro  expands  to  the  SASL sender name (i.e. the
                      original submitter as per <a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a>) in the MAIL FROM com-
                      mand when the Postfix SMTP server received the message.
 
@@ -313,25 +318,25 @@ PIPE(8)                                                                PIPE(8)
                      This feature is available as of Postfix 2.2.
 
               <b>${sender}</b>
-                     This  macro  expands  to  the envelope sender address. By
-                     default, the null sender address expands  to  MAILER-DAE-
-                     MON;  this can be changed with the <b>null_sender</b> attribute,
+                     This macro expands to the  envelope  sender  address.  By
+                     default,  the  null sender address expands to MAILER-DAE-
+                     MON; this can be changed with the <b>null_sender</b>  attribute,
                      as described above.
 
                      This information is modified by the <b>q</b> flag for quoting.
 
               <b>${size}</b>
                      This macro expands to Postfix's idea of the message size,
-                     which  is  an approximation of the size of the message as
+                     which is an approximation of the size of the  message  as
                      delivered.
 
               <b>${user}</b>
-                     This macro expands to the username part  of  a  recipient
-                     address.   For  example,  with an address <i>user+foo@domain</i>
+                     This  macro  expands  to the username part of a recipient
+                     address.  For example, with  an  address  <i>user+foo@domain</i>
                      the username part is <i>user</i>.
 
-                     A command-line argument  that  contains  <b>${user}</b>  expands
-                     into  as many command-line arguments as there are recipi-
+                     A  command-line  argument  that  contains <b>${user}</b> expands
+                     into as many command-line arguments as there are  recipi-
                      ents.
 
                      This information is modified by the <b>u</b> flag for case fold-
@@ -341,36 +346,36 @@ PIPE(8)                                                                PIPE(8)
        <a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced status codes)
 
 <b>DIAGNOSTICS</b>
-       Command  exit  status  codes  are  expected  to  follow the conventions
+       Command exit status  codes  are  expected  to  follow  the  conventions
        defined in &lt;<b>sysexits.h</b>&gt;.  Exit status 0 means normal successful comple-
        tion.
 
        In the case of a non-zero exit status, a limited amount of command out-
-       put is logged, and reported in a delivery  status  notification.   When
-       the  output begins with a 4.X.X or 5.X.X enhanced status code, the sta-
-       tus code takes precedence over the non-zero exit status  (Postfix  ver-
+       put  is  logged,  and reported in a delivery status notification.  When
+       the output begins with a 4.X.X or 5.X.X enhanced status code, the  sta-
+       tus  code  takes precedence over the non-zero exit status (Postfix ver-
        sion 2.3 and later).
 
-       After  successful  delivery (zero exit status) a limited amount of com-
-       mand output is logged, and reported in "success" delivery status  noti-
-       fications  (Postfix  2.12 and later).  This command output is not exam-
+       After successful delivery (zero exit status) a limited amount  of  com-
+       mand  output is logged, and reported in "success" delivery status noti-
+       fications (Postfix 2.12 and later).  This command output is  not  exam-
        ined for the presence of an enhanced status code.
 
-       Problems and transactions are logged to <b>syslogd</b>(8).  Corrupted  message
+       Problems  and transactions are logged to <b>syslogd</b>(8).  Corrupted message
        files are marked so that the queue manager can move them to the <b>corrupt</b>
        queue for further inspection.
 
 <b>SECURITY</b>
-       This program needs a dual personality 1) to access the private  Postfix
-       queue  and  IPC  mechanisms, and 2) to execute external commands as the
+       This  program needs a dual personality 1) to access the private Postfix
+       queue and IPC mechanisms, and 2) to execute external  commands  as  the
        specified user. It is therefore security sensitive.
 
 <b>CONFIGURATION PARAMETERS</b>
        Changes to <a href="postconf.5.html"><b>main.cf</b></a> are picked up automatically as <a href="pipe.8.html"><b>pipe</b>(8)</a> processes run
-       for  only a limited amount of time. Use the command "<b>postfix reload</b>" to
+       for only a limited amount of time. Use the command "<b>postfix reload</b>"  to
        speed up a change.
 
-       The text below provides only a parameter summary. See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for
+       The  text  below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
        more details including examples.
 
 <b>RESOURCE AND RATE CONTROLS</b>
@@ -379,51 +384,51 @@ PIPE(8)                                                                PIPE(8)
        <b><a href="postconf.5.html#transport_destination_concurrency_limit"><i>transport</i>_destination_concurrency_limit</a>   ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
               Limit the number of parallel deliveries to the same destination,
-              for delivery via the named <i>transport</i>.  The limit is enforced  by
+              for  delivery via the named <i>transport</i>.  The limit is enforced by
               the Postfix queue manager.
 
        <b><a href="postconf.5.html#transport_destination_recipient_limit"><i>transport</i>_destination_recipient_limit</a>     ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipi</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">ent_limit</a>)</b>
-              Limit  the number of recipients per message delivery, for deliv-
+              Limit the number of recipients per message delivery, for  deliv-
               ery via the named <i>transport</i>.  The limit is enforced by the Post-
               fix queue manager.
 
        <b><a href="postconf.5.html#transport_time_limit"><i>transport</i>_time_limit</a> ($<a href="postconf.5.html#command_time_limit">command_time_limit</a>)</b>
-              Limit  the  time  for delivery to external command, for delivery
-              via the named <i>transport</i>.  The limit  is  enforced  by  the  pipe
+              Limit the time for delivery to external  command,  for  delivery
+              via  the  named  <i>transport</i>.   The  limit is enforced by the pipe
               delivery agent.
 
-              Postfix  2.4  and later support a suffix that specifies the time
-              unit: s (seconds), m (minutes), h (hours), d (days), w  (weeks).
+              Postfix 2.4 and later support a suffix that specifies  the  time
+              unit:  s (seconds), m (minutes), h (hours), d (days), w (weeks).
               The default time unit is seconds.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process  may  take  to  handle  a
+              How  much  time  a  Postfix  daemon process may take to handle a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The  maximal  number of digits after the decimal point when log-
+              The maximal number of digits after the decimal point  when  log-
               ging sub-second delay values.
 
        <b><a href="postconf.5.html#export_environment">export_environment</a> (see 'postconf -d' output)</b>
-              The list of environment variables that a  Postfix  process  will
+              The  list  of  environment variables that a Postfix process will
               export to non-Postfix processes.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The  time  limit  for  sending  or receiving information over an
+              The time limit for sending  or  receiving  information  over  an
               internal communication channel.
 
        <b><a href="postconf.5.html#mail_owner">mail_owner</a> (postfix)</b>
-              The UNIX system account that owns the  Postfix  queue  and  most
+              The  UNIX  system  account  that owns the Postfix queue and most
               Postfix daemon processes.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The  maximum  amount of time that an idle Postfix daemon process
+              The maximum amount of time that an idle Postfix  daemon  process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -440,22 +445,22 @@ PIPE(8)                                                                PIPE(8)
               The location of the Postfix top-level queue directory.
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
-              The set of characters that can separate a  user  name  from  its
-              extension  (example: user+foo), or a .forward file name from its
+              The  set  of  characters  that can separate a user name from its
+              extension (example: user+foo), or a .forward file name from  its
               extension (example: .forward+foo).
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The mail system name that is prepended to the  process  name  in
-              syslog  records,  so  that  "smtpd" becomes, for example, "post-
+              The  mail  system  name that is prepended to the process name in
+              syslog records, so that "smtpd"  becomes,  for  example,  "post-
               fix/smtpd".
 
        Available in Postfix version 2.12 and later:
 
        <b><a href="postconf.5.html#pipe_delivery_status_filter">pipe_delivery_status_filter</a> ($<a href="postconf.5.html#default_delivery_status_filter">default_delivery_status_filter</a>)</b>
-              Optional filter for the <a href="pipe.8.html"><b>pipe</b>(8)</a> delivery  agent  to  change  the
+              Optional  filter  for  the  <a href="pipe.8.html"><b>pipe</b>(8)</a> delivery agent to change the
               delivery status code or explanatory text of successful or unsuc-
               cessful deliveries.
 
index 9f31fa5a6497017f33db010364fcf7e8b2d5c87c..882893ca8fb27a8d6a5687f4eb12d489fce31ae6 100644 (file)
@@ -165,7 +165,8 @@ changed.
 The command to be executed.  Characters that are special
 to the shell such as ">" or "|" have no special meaning
 here, and quotes cannot be used to protect arguments
-containing whitespace.
+containing whitespace. To protect whitespace, use "{"
+and "}" as described below.
 .sp
 The command name is relative to the Postfix daemon directory
 (pathname is controlled by the \fBdaemon_directory\fR
@@ -181,13 +182,15 @@ all daemon programs:
 Run the daemon under control by the command specified with
 the \fBdebugger_command\fR variable in the main.cf
 configuration file.  See DEBUG_README for hints and tips.
-.IP "\fB-o \fIname\fR=\fIvalue\fR"
+.IP "\fB-o \fIname\fR=\fIvalue\fR (short form)"
+.IP "\fB-o { \fIname\fR = \fIvalue\fB }\fR (Postfix 2.12 and later)"
 Override the named main.cf configuration parameter. The
 parameter value can refer to other parameters as \fI$name\fR
 etc., just like in main.cf.  See \fBpostconf\fR(5) for
 syntax.
 .sp
-NOTE 1: do not specify whitespace around the "=" or in
+NOTE 1: with the "short form" shown above, do not specify
+whitespace around the "=" or in
 parameter values. To specify a parameter value that contains
 whitespace, use commas instead of spaces, or specify the
 value in main.cf. Example:
@@ -209,6 +212,10 @@ personalities via master.cf.
 .IP \fB-v\fR
 Increase the verbose logging level. Specify multiple \fB-v\fR
 options to make a Postfix daemon process increasingly verbose.
+.IP "Other command-line arguments"
+Specify "{" and "}" around command arguments that contain
+whitespace (Postfix 2.12 and later). Whitespace immediately
+after "{" and before "}" is ignored.
 .SH "SEE ALSO"
 .na
 .nf
index 8d6eb3a2e34d8fb441b5b2a6acb40b47fff6cede..41ef3f20fb65cfc1d7fdd6850a7de0c8cc29e771 100644 (file)
@@ -199,13 +199,17 @@ last command attribute.
 The command is executed directly, i.e. without interpretation of
 shell meta characters by a shell command interpreter.
 .sp
+Specify "{" and "}" around command arguments that contain
+whitespace (Postfix 2.12 and later). Whitespace immediately
+after "{" and before "}" is ignored.
+.sp
 In the command argument vector, the following macros are recognized
 and replaced with corresponding information from the Postfix queue
 manager delivery request.
 .sp
 In addition to the form ${\fIname\fR}, the forms $\fIname\fR and
-$(\fIname\fR) are also recognized.  Specify \fB$$\fR where a single
-\fB$\fR is wanted.
+the deprecated form $(\fIname\fR) are also recognized.
+Specify \fB$$\fR where a single \fB$\fR is wanted.
 .RS
 .IP \fB${client_address}\fR
 This macro expands to the remote client network address.
index c62ee75e62ff2d958dcd1227c65e61dfa825bb70..b36cef29b408d67373f5015e5da1a9896dd0aea5 100644 (file)
@@ -75,9 +75,9 @@ verification probes</a>
 <h2><a name="how">How address verification works</a></h2>
 
 <p> A Postfix MTA verifies a sender or recipient address by probing
-the nearest
-MTA for that address, without actually delivering mail. The nearest
-MTA could be the Postfix MTA itself, or it could be a remote MTA
+the preferred MTAs
+for that address, without actually delivering mail. The preferred
+MTAs could include the Postfix MTA itself, or some remote MTAs
 (SMTP
 interruptus).  Probe messages are like normal mail, except that
 they are never delivered, deferred or bounced; probe messages are
@@ -198,12 +198,12 @@ details. </p>
 
 <ul>
 
-<li> <p> When verifying a remote address, Postfix probes the nearest
-MTA for that address, without actually delivering mail to it. If
-the nearest MTA accepts the address, then Postfix assumes that the
+<li> <p> When verifying a remote address, Postfix probes the preferred
+MTAs for that address, without actually delivering mail. If
+a preferred MTA accepts the address, then Postfix assumes that the
 address is deliverable. In reality, mail for a remote address can
-bounce AFTER the nearest MTA accepts the recipient address, or AFTER
-the nearest MTA accepts the message content. </p>
+bounce AFTER a preferred MTA accepts the recipient address, or AFTER
+a preferred MTA accepts the message content. </p>
 
 <li> <p> Some sites may blacklist you when you are probing them
 too often (a probe is an SMTP session that does not deliver mail),
@@ -219,10 +219,10 @@ the routing of address verification probes"</a>, for how to override
 mail routing and for possible limitations when you have to do this.
 </p>
 
-<li> <p> Postfix assumes that an address is undeliverable when the
-nearest MTA for the address rejects the probe, regardless of the
+<li> <p> Postfix assumes that an address is undeliverable when a
+preferred MTA for the address rejects the probe, regardless of the
 reason for rejection (client rejected, HELO rejected, MAIL FROM
-rejected, etc.).  Thus, Postfix rejects an address when the nearest
+rejected, etc.).  Thus, Postfix rejects an address when a preferred
 MTA for that address rejects mail from your machine for any reason.
 This is not a limitation, but it is mentioned here just in case
 people believe that it is a limitation. </p>
index e392da3f22da83d3bf3055659739128110b8be55..cc14916c6e7fddf866ab5ba3894a79d68b690c47 100644 (file)
 #      The command to be executed.  Characters that are special
 #      to the shell such as ">" or "|" have no special meaning
 #      here, and quotes cannot be used to protect arguments
-#      containing whitespace.
+#      containing whitespace. To protect whitespace, use "{"
+#      and "}" as described below.
 # .sp
 #      The command name is relative to the Postfix daemon directory
 #      (pathname is controlled by the \fBdaemon_directory\fR
 #      Run the daemon under control by the command specified with
 #      the \fBdebugger_command\fR variable in the main.cf
 #      configuration file.  See DEBUG_README for hints and tips.
-# .IP "\fB-o \fIname\fR=\fIvalue\fR"
+# .IP "\fB-o \fIname\fR=\fIvalue\fR (short form)"
+# .IP "\fB-o { \fIname\fR = \fIvalue\fB }\fR (Postfix 2.12 and later)"
 #      Override the named main.cf configuration parameter. The
 #      parameter value can refer to other parameters as \fI$name\fR
 #      etc., just like in main.cf.  See \fBpostconf\fR(5) for
 #      syntax.
 # .sp
-#      NOTE 1: do not specify whitespace around the "=" or in
+#      NOTE 1: with the "short form" shown above, do not specify
+#      whitespace around the "=" or in
 #      parameter values. To specify a parameter value that contains
 #      whitespace, use commas instead of spaces, or specify the
 #      value in main.cf. Example:
 # .IP \fB-v\fR
 #      Increase the verbose logging level. Specify multiple \fB-v\fR
 #      options to make a Postfix daemon process increasingly verbose.
+# .IP "Other command-line arguments"
+#      Specify "{" and "}" around command arguments that contain
+#      whitespace (Postfix 2.12 and later). Whitespace immediately
+#      after "{" and before "}" is ignored.
 # SEE ALSO
 #      master(8), process manager
 #      postconf(5), configuration parameters
index 4cc19c930271b8590e0c134c760d9dae3f80540a..57f0aa11156da91edbc4d1cfa471c83bd3b2fc5d 100644 (file)
 /*     See mystrtok(3) for description. Typical values are
 /*     ", \\t\\r\\n" and "{}", respectively.
 /* .PP
-/*     The parens argument is followed by a list of (key, value,
-/*     value) argument triples. Each key may appear only once.
-/*     The list must be terminated with ATTR_OVER_END.  The following
+/*     The parens argument is followed by a list of (key, value)
+/*     argument pairs. Each key may appear only once.  The list
+/*     must be terminated with ATTR_OVER_END.  The following
 /*     describes the keys and the expected values.
-/* .IP "ATTR_OVER_STR_TABLE, const ATTR_OVER_STR *, CONST_CHAR_STAR *"
+/* .IP "ATTR_OVER_STR_TABLE, const ATTR_OVER_STR *
 /*     The second argument specifies a null-terminated table with
-/*     attribute names and their range limits which should be the
-/*     same as for the corresponding main.cf parameters.  The
-/*     third argument specifies a parallel table with assignment
-/*     targets. The result strings are NOT copied.
-/* .IP "ATTR_OVER_TIME_TABLE, const ATTR_OVER_TIME *, int *"
+/*     attribute names, assignment targets, and range limits which
+/*     should be the same as for the corresponding main.cf parameters.
+/* .IP "ATTR_OVER_TIME_TABLE, const ATTR_OVER_TIME *
 /*     The second argument specifies a null-terminated table with
 /*     attribute names, their default time units (leading digits
-/*     are skipped), and their range limits which should be the
-/*     same as for the corresponding main.cf parameters.  The
-/*     third argument specifies a parallel table with assignment
-/*     targets.
-/* .IP "ATTR_OVER_INT_TABLE, const ATTR_OVER_INT *, int *"
+/*     are skipped), assignment targets, and range limits which
+/*     should be the same as for the corresponding main.cf parameters.
+/* .IP "ATTR_OVER_INT_TABLE, const ATTR_OVER_INT *
 /*     The second argument specifies a null-terminated table with
-/*     attribute names and their range limits which should be the
-/*     same as for the corresponding main.cf parameters.  The
-/*     third argument specifies a parallel table with assignment
-/*     targets.
-/* BUGS
-/*     Parallel tables may be inelegant, but the alternative (static
-/*     allocation of target variables) is worse.
+/*     attribute names, assignment targets, and range limits which
+/*     should be the same as for the corresponding main.cf parameters.
 /* SEE ALSO
 /*     mystrtok(3), safe tokenizer
 /*     extpar(3), extract text from parentheses
@@ -106,9 +97,6 @@ void    attr_override(char *cp, const char *sep, const char *parens,...)
     const ATTR_OVER_INT *int_table = 0;
     const ATTR_OVER_STR *str_table = 0;
     const ATTR_OVER_TIME *time_table = 0;
-    int    *int_tgts = 0;
-    CONST_CHAR_STAR *str_tgts = 0;
-    int    *time_tgts = 0;
 
     /*
      * Get the lookup tables and assignment targets.
@@ -120,19 +108,16 @@ void    attr_override(char *cp, const char *sep, const char *parens,...)
            if (int_table)
                msg_panic("%s: multiple ATTR_OVER_INT_TABLE", myname);
            int_table = va_arg(ap, const ATTR_OVER_INT *);
-           int_tgts = va_arg(ap, int *);
            break;
        case ATTR_OVER_STR_TABLE:
            if (str_table)
                msg_panic("%s: multiple ATTR_OVER_STR_TABLE", myname);
            str_table = va_arg(ap, const ATTR_OVER_STR *);
-           str_tgts = va_arg(ap, CONST_CHAR_STAR *);
            break;
        case ATTR_OVER_TIME_TABLE:
            if (time_table)
                msg_panic("%s: multiple ATTR_OVER_TIME_TABLE", myname);
            time_table = va_arg(ap, const ATTR_OVER_TIME *);
-           time_tgts = va_arg(ap, int *);
            break;
        default:
            msg_panic("%s: unknown argument type: %d", myname, idx);
@@ -173,7 +158,7 @@ void    attr_override(char *cp, const char *sep, const char *parens,...)
            if (strcmp(sp->name, key) != 0)
                continue;
            check_mail_conf_str(sp->name, value, sp->min, sp->max);
-           str_tgts[sp - str_table] = value;
+           sp->target[0] = value;
            found = 1;
        }
        for (ip = int_table; ip != 0 && found == 0 && ip->name != 0; ip++) {
@@ -186,7 +171,7 @@ void    attr_override(char *cp, const char *sep, const char *parens,...)
                || longval != int_val)
                msg_fatal("bad numerical configuration: %s = %s", key, value);
            check_mail_conf_int(key, int_val, ip->min, ip->max);
-           int_tgts[ip - int_table] = int_val;
+           ip->target[0] = int_val;
            found = 1;
        }
        for (tp = time_table; tp != 0 && found == 0 && tp->name != 0; tp++) {
@@ -196,7 +181,7 @@ void    attr_override(char *cp, const char *sep, const char *parens,...)
            if (conv_time(value, &int_val, def_unit) == 0)
                msg_fatal("%s: bad time value or unit: %s", key, value);
            check_mail_conf_time(key, int_val, tp->min, tp->max);
-           time_tgts[tp - time_table] = int_val;
+           tp->target[0] = int_val;
            found = 1;
        }
        if (found == 0)
index e04df1040f6b7808ed3996fe1c0fda337af0bd40..7da63b5afe90084af271fb244ca1a9faca2095e2 100644 (file)
@@ -20,6 +20,7 @@ typedef const char *CONST_CHAR_STAR;
 
 typedef struct {
     const char *name;
+    CONST_CHAR_STAR *target;
     int     min;
     int     max;
 } ATTR_OVER_STR;
@@ -27,12 +28,14 @@ typedef struct {
 typedef struct {
     const char *name;
     const char *defval;
+    int    *target;
     int     min;
     int     max;
 } ATTR_OVER_TIME;
 
 typedef struct {
     const char *name;
+    int    *target;
     int     min;
     int     max;
 } ATTR_OVER_INT;
index d922e226257c56952c9fd24684f8d34574bba91a..eb4fb97ae72696f7c167540818bb58a46581ec06 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20140928"
+#define MAIL_RELEASE_DATE      "20140929"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index 78bad8dc8890a439a3e7611bd568165818207e13..addd436df03e99988ae7cee1ef68c61a9833d6e0 100644 (file)
@@ -538,28 +538,28 @@ void    milter_disc_event(MILTERS *milters)
   * Table-driven parsing of main.cf parameter overrides for specific Milters.
   * We derive the override names from the corresponding main.cf parameter
   * names by skipping the redundant "milter_" prefix.
-  * 
-  * To avoid ugly static allocation of assignment targets, we use stack-based
-  * parallel arrays which is less inelegant.
   */
-static const ATTR_OVER_TIME time_table[] = {
-    7 + VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, 1, 0,
-    7 + VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, 1, 0,
-    7 + VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, 1, 0,
+static ATTR_OVER_TIME time_table[] = {
+    7 + VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, 0, 1, 0,
+    7 + VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, 0, 1, 0,
+    7 + VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, 0, 1, 0,
     0,
 };
-static const ATTR_OVER_STR str_table[] = {
-    7 + VAR_MILT_PROTOCOL, 1, 0,
-    7 + VAR_MILT_DEF_ACTION, 1, 0,
+static ATTR_OVER_STR str_table[] = {
+    7 + VAR_MILT_PROTOCOL, 0, 1, 0,
+    7 + VAR_MILT_DEF_ACTION, 0, 1, 0,
     0,
 };
 
-#define conn_timeout_override  time_tgts[0]
-#define cmd_timeout_override   time_tgts[1]
-#define msg_timeout_override   time_tgts[2]
+#define link_override_table_to_variable(table, var) \
+       do { table[var##_offset].target = &var; } while (0)
 
-#define        protocol_override       str_tgts[0]
-#define        action_override         str_tgts[1]
+#define my_conn_timeout_offset 0
+#define my_cmd_timeout_offset  1
+#define my_msg_timeout_offset  2
+
+#define        my_protocol_offset      0
+#define        my_def_action_offset    1
 
 /* milter_new - create milter list */
 
@@ -578,8 +578,20 @@ MILTERS *milter_new(const char *names,
     MILTER *milter;
     const char *sep = ", \t\r\n";
     const char *parens = "{}";
-    int     time_tgts[sizeof(time_table) / sizeof(time_table[0])];
-    const char *str_tgts[sizeof(str_table) / sizeof(str_table[0])];
+    int     my_conn_timeout;
+    int     my_cmd_timeout;
+    int     my_msg_timeout;
+    const char *my_protocol;
+    const char *my_def_action;
+
+    /*
+     * Initialize.
+     */
+    link_override_table_to_variable(time_table, my_conn_timeout);
+    link_override_table_to_variable(time_table, my_cmd_timeout);
+    link_override_table_to_variable(time_table, my_msg_timeout);
+    link_override_table_to_variable(str_table, my_protocol);
+    link_override_table_to_variable(str_table, my_def_action);
 
     /*
      * Parse the milter list.
@@ -588,7 +600,6 @@ MILTERS *milter_new(const char *names,
     if (names != 0 && *names != 0) {
        char   *saved_names = mystrdup(names);
        char   *cp = saved_names;
-       char   *name_override;
        char   *op;
        char   *err;
 
@@ -596,34 +607,25 @@ MILTERS *milter_new(const char *names,
         * Instantiate Milters, allowing for per-Milter overrides.
         */
        while ((name = mystrtokq(&cp, sep, parens)) != 0) {
+           my_conn_timeout = conn_timeout;
+           my_cmd_timeout = cmd_timeout;
+           my_msg_timeout = msg_timeout;
+           my_protocol = protocol;
+           my_def_action = def_action;
            if (name[0] == '{') {               /* } */
                op = name;
                if ((err = extpar(&op, parens, EXPAR_FLAG_NONE)) != 0)
                    msg_fatal("milter service syntax error: %s", err);
-               if ((name_override = mystrtok(&op, sep)) == 0) {
-                   msg_fatal("empty milter definition: \"%s\"", name);
-               } else {
-                   conn_timeout_override = conn_timeout;
-                   cmd_timeout_override = cmd_timeout;
-                   msg_timeout_override = msg_timeout;
-                   protocol_override = protocol;
-                   action_override = def_action;
-                   attr_override(op, sep, parens,
-                                 ATTR_OVER_STR_TABLE, str_table, str_tgts,
-                               ATTR_OVER_TIME_TABLE, time_table, time_tgts,
-                                 0);
-                   milter = milter8_create(name_override,
-                                           conn_timeout_override,
-                                           cmd_timeout_override,
-                                           msg_timeout_override,
-                                           protocol_override,
-                                           action_override, milters);
-               }
-           } else {
-               milter = milter8_create(name, conn_timeout, cmd_timeout,
-                                       msg_timeout, protocol, def_action,
-                                       milters);
+               if ((name = mystrtok(&op, sep)) == 0)
+                   msg_fatal("empty milter definition: \"%s\"", names);
+               attr_override(op, sep, parens,
+                             ATTR_OVER_STR_TABLE, str_table,
+                             ATTR_OVER_TIME_TABLE, time_table,
+                             0);
            }
+           milter = milter8_create(name, my_conn_timeout, my_cmd_timeout,
+                                   my_msg_timeout, my_protocol,
+                                   my_def_action, milters);
            if (head == 0) {
                head = milter;
            } else {
index b255da87692ba575396e34cc1ee8e77097d46d04..8baa662ed9255e0f0ddb8a7eb01ed15dd45dcd81 100644 (file)
 /*     The command is executed directly, i.e. without interpretation of
 /*     shell meta characters by a shell command interpreter.
 /* .sp
+/*     Specify "{" and "}" around command arguments that contain
+/*     whitespace (Postfix 2.12 and later). Whitespace immediately
+/*     after "{" and before "}" is ignored.
+/* .sp
 /*     In the command argument vector, the following macros are recognized
 /*     and replaced with corresponding information from the Postfix queue
 /*     manager delivery request.
 /* .sp
 /*     In addition to the form ${\fIname\fR}, the forms $\fIname\fR and
-/*     $(\fIname\fR) are also recognized.  Specify \fB$$\fR where a single
-/*     \fB$\fR is wanted.
+/*     the deprecated form $(\fIname\fR) are also recognized.
+/*     Specify \fB$$\fR where a single \fB$\fR is wanted.
 /* .RS
 /* .IP \fB${client_address}\fR
 /*     This macro expands to the remote client network address.
index 4392f0455e4288b42c99563779366bec38e1061c..94a06e0a1e7e9f4fc8a82d36062c387b69b7b2c7 100644 (file)
@@ -468,36 +468,36 @@ typedef struct {
   * Table-driven parsing of main.cf parameter overrides for specific policy
   * clients. We derive the override names from the corresponding main.cf
   * parameter names by skipping the redundant "smtpd_policy_service_" prefix.
-  * 
-  * To avoid ugly static allocation of assignment targets, we use stack-based
-  * parallel arrays which is less inelegant.
   */
-static const ATTR_OVER_TIME time_table[] = {
-    21 + VAR_SMTPD_POLICY_TMOUT, DEF_SMTPD_POLICY_TMOUT, 1, 0,
-    21 + VAR_SMTPD_POLICY_IDLE, DEF_SMTPD_POLICY_IDLE, 1, 0,
-    21 + VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, 1, 0,
-    21 + VAR_SMTPD_POLICY_TRY_DELAY, DEF_SMTPD_POLICY_TRY_DELAY, 1, 0,
+static ATTR_OVER_TIME time_table[] = {
+    21 + VAR_SMTPD_POLICY_TMOUT, DEF_SMTPD_POLICY_TMOUT, 0, 1, 0,
+    21 + VAR_SMTPD_POLICY_IDLE, DEF_SMTPD_POLICY_IDLE, 0, 1, 0,
+    21 + VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, 0, 1, 0,
+    21 + VAR_SMTPD_POLICY_TRY_DELAY, DEF_SMTPD_POLICY_TRY_DELAY, 0, 1, 0,
     0,
 };
-static const ATTR_OVER_INT int_table[] = {
-    21 + VAR_SMTPD_POLICY_REQ_LIMIT, 0, 0,
-    21 + VAR_SMTPD_POLICY_TRY_LIMIT, 1, 0,
+static ATTR_OVER_INT int_table[] = {
+    21 + VAR_SMTPD_POLICY_REQ_LIMIT, 0, 0, 0,
+    21 + VAR_SMTPD_POLICY_TRY_LIMIT, 0, 1, 0,
     0,
 };
-static const ATTR_OVER_STR str_table[] = {
-    21 + VAR_SMTPD_POLICY_DEF_ACTION, 1, 0,
+static ATTR_OVER_STR str_table[] = {
+    21 + VAR_SMTPD_POLICY_DEF_ACTION, 0, 1, 0,
     0,
 };
 
-#define smtpd_policy_tmout     time_tgts[0]
-#define smtpd_policy_idle      time_tgts[1]
-#define smtpd_policy_ttl       time_tgts[2]
-#define smtpd_policy_try_delay time_tgts[3]
+#define link_override_table_to_variable(table, var) \
+       do { table[var##_offset].target = &var; } while (0)
+
+#define smtpd_policy_tmout_offset      0
+#define smtpd_policy_idle_offset       1
+#define smtpd_policy_ttl_offset                2
+#define smtpd_policy_try_delay_offset  3
 
-#define smtpd_policy_req_limit int_tgts[0]
-#define smtpd_policy_try_limit int_tgts[1]
+#define smtpd_policy_req_limit_offset  0
+#define smtpd_policy_try_limit_offset  1
 
-#define smtpd_policy_def_action        str_tgts[0]
+#define smtpd_policy_def_action_offset 0
 
 /* policy_client_register - register policy service endpoint */
 
@@ -511,9 +511,6 @@ static void policy_client_register(const char *name)
     const char *sep = ", \t\r\n";
     const char *parens = "{}";
     char   *err;
-    int     time_tgts[sizeof(time_table) / sizeof(time_table[0])];
-    int     int_tgts[sizeof(int_table) / sizeof(int_table[0])];
-    const char *str_tgts[sizeof(str_table) / sizeof(str_table[0])];
 
     if (policy_clnt_table == 0)
        policy_clnt_table = htable_create(1);
@@ -523,13 +520,21 @@ static void policy_client_register(const char *name)
        /*
         * Allow per-service overrides for main.cf global settings.
         */
-       smtpd_policy_tmout = var_smtpd_policy_tmout;
-       smtpd_policy_idle = var_smtpd_policy_idle;
-       smtpd_policy_ttl = var_smtpd_policy_ttl;
-       smtpd_policy_req_limit = var_smtpd_policy_req_limit;
-       smtpd_policy_try_limit = var_smtpd_policy_try_limit;
-       smtpd_policy_try_delay = var_smtpd_policy_try_delay;
-       smtpd_policy_def_action = var_smtpd_policy_def_action;
+       int     smtpd_policy_tmout = var_smtpd_policy_tmout;
+       int     smtpd_policy_idle = var_smtpd_policy_idle;
+       int     smtpd_policy_ttl = var_smtpd_policy_ttl;
+       int     smtpd_policy_try_delay = var_smtpd_policy_try_delay;
+       int     smtpd_policy_req_limit = var_smtpd_policy_req_limit;
+       int     smtpd_policy_try_limit = var_smtpd_policy_try_limit;
+       const char *smtpd_policy_def_action = var_smtpd_policy_def_action;
+
+       link_override_table_to_variable(time_table, smtpd_policy_tmout);
+       link_override_table_to_variable(time_table, smtpd_policy_idle);
+       link_override_table_to_variable(time_table, smtpd_policy_ttl);
+       link_override_table_to_variable(time_table, smtpd_policy_try_delay);
+       link_override_table_to_variable(int_table, smtpd_policy_req_limit);
+       link_override_table_to_variable(int_table, smtpd_policy_try_limit);
+       link_override_table_to_variable(str_table, smtpd_policy_def_action);
 
        if (*name == '{') {                     /* } */
            cp = saved_name = mystrdup(name);
@@ -538,16 +543,14 @@ static void policy_client_register(const char *name)
            if ((policy_name = mystrtok(&cp, sep)) == 0)
                msg_fatal("empty policy service: \"%s\"", name);
            attr_override(cp, sep, parens,
-                         ATTR_OVER_TIME_TABLE, time_table, time_tgts,
-                         ATTR_OVER_INT_TABLE, int_table, int_tgts,
-                         ATTR_OVER_STR_TABLE, str_table, str_tgts,
+                         ATTR_OVER_TIME_TABLE, time_table,
+                         ATTR_OVER_INT_TABLE, int_table,
+                         ATTR_OVER_STR_TABLE, str_table,
                          0);
        } else {
            policy_name = name;
        }
-#if 0
        if (msg_verbose)
-#endif
            msg_info("%s: name=\"%s\" default_action=\"%s\" max_idle=%d "
                     "max_ttl=%d request_limit=%d retry_delay=%d "
                     "timeout=%d try_limit=%d",