]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20140618
authorWietse Venema <wietse@porcupine.org>
Wed, 18 Jun 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Thu, 19 Jun 2014 02:27:17 +0000 (22:27 -0400)
42 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/DATABASE_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/conf/access
postfix/conf/header_checks
postfix/html/DATABASE_README.html
postfix/html/access.5.html
postfix/html/header_checks.5.html
postfix/html/pcre_table.5.html
postfix/html/pipe.8.html
postfix/html/postconf.1.html
postfix/html/regexp_table.5.html
postfix/makedefs
postfix/man/man1/postconf.1
postfix/man/man5/access.5
postfix/man/man5/header_checks.5
postfix/man/man5/pcre_table.5
postfix/man/man5/regexp_table.5
postfix/man/man8/pipe.8
postfix/mantools/postlink
postfix/postfix-env.sh [new file with mode: 0644]
postfix/proto/DATABASE_README.html
postfix/proto/access
postfix/proto/header_checks
postfix/proto/pcre_table
postfix/proto/regexp_table
postfix/src/global/dynamicmaps.c
postfix/src/global/mail_version.h
postfix/src/global/pipe_command.c
postfix/src/pipe/pipe.c
postfix/src/postconf/postconf.c
postfix/src/smtpd/smtpd_check.c
postfix/src/tls/tls_server.c
postfix/src/util/Makefile.in
postfix/src/util/dict.h
postfix/src/util/dict_open.c
postfix/src/util/dict_pipe.c [new file with mode: 0644]
postfix/src/util/dict_pipe.h [new file with mode: 0644]
postfix/src/util/dict_random.c [new file with mode: 0644]
postfix/src/util/dict_random.h [new file with mode: 0644]

index 901ccc0fd9b39f647d03b1514b857f8f98635456..c690ce828ff9ef03cb4fce2cc1544ec4fda8fcba 100644 (file)
 -TDICT_PCRE_REGEXP
 -TDICT_PCRE_RULE
 -TDICT_PGSQL
+-TDICT_PIPE
 -TDICT_PROXY
+-TDICT_RAND
+-TDICT_RANDOM
 -TDICT_REGEXP
 -TDICT_REGEXP_EXPAND_CONTEXT
 -TDICT_REGEXP_IF_RULE
 -TDICT_SOCKMAP
 -TDICT_SOCKMAP_REFC_HANDLE
 -TDICT_SQLITE
--TDICT_STACK
 -TDICT_SURROGATE
 -TDICT_TCP
 -TDICT_TEXT
index 87eaa0ec507440365f3c2f519403b674efcc6ae5..14f0b5aae28f540185e0b594de1bf95afcd095c7 100644 (file)
@@ -19875,3 +19875,47 @@ Apologies for any names omitted.
        the "ln -n" option is not universally implemented, so we
        remove the old symlink first.  Problem reported by Viktor.
        File: postfix-install.
+
+20140603
+
+       Cleanup: use the OpenSSL session id accessor (available
+       since OpenSSL 0.9.8 or so) instead of groping a session
+       object directly. Viktor Dukhovni. File: tls_server.c.
+
+20140605
+
+       Feature: the pipe(8) daemon logs some command output after
+       successful delivery as "dsn=2.0.0, status=sent (delivered
+       via XXX service (YYY))" where XXX is the master.cf service
+       name, and YYY is command output. Files: pipe/command.c,
+       pipe.c.
+
+20140613
+
+       Feature: the "pipeline" table implements a table pipeline.
+       Example "pipeline:!type_1:name_1!...!type_n:name_n".  The
+       ASCII character after "pipeline:" will be used as the
+       separator between the lookup tables that follow (do not use
+       space, ",", ":" or non-ASCII).  Each "pipeline:" query is
+       given to the first table.  Each lookup result becomes the
+       query for the next table in the pipeline, and the last table
+       produces the final result.  When any table lookup produces
+       no result, the pipeline produces no result.  Files:
+       dict_pipe.[hc], dict_open.c, postlink, DATABASE_README.html,
+       postconf.c.
+
+20140617
+
+       Feature: the "random" table performs random selection.
+       Example: "random:!result_1!...!result_n". Each table query
+       returns a random choice from the specified results. The
+       ASCII character after "random:" will be used as the separator
+       between the results that follow (do not use space, ",", ":"
+       or non-ASCII).  Files: dict_random.[hc], dict_open.c,
+       postlink, DATABASE_README.html, postconf.c.
+
+20140618
+
+       Cleanup: INFO action in access(5) tables, for consistency
+       with header/body_checks. Viktor Dukhovni.  Files:
+       smtpd/smtpd_check.c, proto/access.
index 06fe6f5be07543aa28f0a59fb535031d4aa0fe79..708d845a33b08114b6fdbbc902f770c980a4675a 100644 (file)
@@ -242,12 +242,26 @@ To find out what database types your Postfix system supports, use the "p\bpo\bos\bs
         A lookup table based on Perl Compatible Regular Expressions. The file
         format is described in pcre_table(5). The lookup table name as used in
         "pcre:table" is the name of the regular expression file.
+    p\bpi\bip\bpe\bel\bli\bin\bne\be (read-only)
+        A pipeline of lookup tables. Example: "p\bpi\bip\bpe\bel\bli\bin\bne\be:\b:!type_1:name_1! ...
+        !type_n:name_n". Each "pipeline:" query is given to the first table.
+        Each lookup result becomes the query for the next table in the
+        pipeline, and the last table produces the final result. When any table
+        lookup produces no result, the pipeline produces no result. The ASCII
+        character after "pipeline:" will be used as the separator between the
+        lookup tables that follow (do not use space, ",", ":" or non-ASCII).
     p\bpg\bgs\bsq\bql\bl (read-only)
         PostgreSQL database client. Configuration details are given in
         pgsql_table(5).
     p\bpr\bro\box\bxy\by
         Postfix proxymap(8) client for shared access to Postfix databases. The
         lookup table name syntax is "proxy:type:table".
+    r\bra\ban\bnd\bdo\bom\bm (read-only)
+        An in-memory table that performs random selection. Example: "r\bra\ban\bnd\bdo\bom\bm:\b:
+        !result_1! ... !result_n". Each table query returns a random choice
+        from the specified results. The ASCII character after "random:" will be
+        used as the separator between the results that follow (do not use
+        space, ",", ":" or non-ASCII).
     r\bre\beg\bge\bex\bxp\bp (read-only)
         A lookup table based on regular expressions. The file format is
         described in regexp_table(5). The lookup table name as used in "regexp:
index 005ecab3b86d03b30a94f8c2d73475be2e15b89e..7db5b309ec7389df0a0cba531d156a5228e54df6 100644 (file)
@@ -33,6 +33,79 @@ Maintainers may also benefit from the makedefs documentation
 (mantools/srctoman - makedefs | nroff -man | less) with information
 about build options that are not described in the INSTALL instructions.
 
+Incompatible changes with snapshot 20140618
+===========================================
+
+The pipe(8) delivery agent will now log a limited amount of command
+output upon successful delivery, and will report that output in
+"SUCCESS" delivery status reports. This is another good reason to
+disable inbound DSN requests at the Internet perimeter.
+
+Major changes with snapshot 20140618
+====================================
+
+This introduces several lookup tables with unusual properties.
+
+random table
+------------
+
+The "random" lookup table performs random selection. This may be
+used to implement load balancing, for example:
+
+/etc/postfix/transport:
+    # Deliver my own domain as usual.
+    example.com :
+    .example.com :
+
+/etc/postfix/main.cf:
+    transport_maps = 
+       # Deliver my own domain as usual.
+       hash:/etc/postfix/transport 
+       # Deliver other domains via randomly-selected relayhosts
+       random:!smtp:smtp0.example.com!smtp:smtp1.example.com
+
+A variant of this can randomly select SMTP clients with different
+smtp_bind_address settings.
+
+The ASCII character after "random:" will be used as the separator
+between the results that follow (do not use space, ",", ":" or
+non-ASCII).
+
+Some future version may support the form random:/path/to/file,
+to load the list of random values, one per line, from a textfile.
+
+To implement different weights, specify lookup results multiple
+times. For example, to choose smtp:smtp1.example.com twice as often
+as smtp:smtp0.example.com, specify smtp:smtp1.example.com twice.
+
+pipeline table
+--------------
+
+As the name suggests, the "pipeline" table implements a pipeline
+of lookup tables. The name of the table specifies the pipeline as
+a sequence of tables. For example, the following prevents SMTP mail
+to system accounts that have "nologin" as their login shell:
+
+    /etc/postfix/main.cf:
+       local_recipient_maps = 
+           pipeline:!unix:passwd.byname!pcre:/etc/postfix/no-nologin.pcre
+           alias_maps
+
+    /etc/postfix/no-nologin.pcre:
+       !/nologin/      whatever
+
+The ASCII character after "pipeline:" will be used as the separator
+between the lookup tables that follow (do not use space, ",", ":"
+or non-ASCII).
+
+Each "pipeline:" query is given to the first table. Each table
+lookup result becomes the query for the next table in the pipeline,
+and the last table produces the final result.  When any table lookup
+produces no result, the entire pipeline produces no result.
+
+Some future version may support the form pipeline:/path/to/file,
+to load the list of lookup tables, one per line, from a textfile.
+
 Incompatible changes with snapshot 20140530
 ===========================================
 
index 8908a5e3e1c79f3cb9f2487d38d39dd1208954f2..cfa02d813e6a03ea916f06920057ff0b91d8fb1e 100644 (file)
@@ -8,6 +8,15 @@ Wish list:
 
        Things to do after the stable release:
 
+       Don't accept AUTH or other features that are not announced
+       in the EHLO response.
+
+       Per-Milter error action.
+
+       Suggested at Mailserver conference: Postscreen RDNS-based
+       reputation (but this introduces dependency on random DNS
+       servers).
+
        Discourage the use of "after 220" tests in POSTSCREEN_README
        and the documentation of individual parameter settings.
 
index cadc57d650278f21cccffe88a7c2169e8a512e5e..e3a94de15b549f4518b20c74e6b1132892f15db3 100644 (file)
 # 
 #               This feature is available in Postfix 2.1 and later.
 # 
+#        INFO optional text...
+#               Log an informational record with the optional text,
+#               together with client information and if  available,
+#               with  helo, sender, recipient and protocol informa-
+#               tion.
+# 
+#               This feature  is  available  in  Postfix  2.12  and
+#               later.
+# 
 #        WARN optional text...
 #               Log a warning with the optional text, together with
 #               client information and  if  available,  with  helo,
index 490e214c7252cb350217c75e07f9a850c121373b..b68e148f8b927d187a55cd947d90734ab0f3f7a4 100644 (file)
 # 
 #        if /pattern/flags
 # 
-#        endif  Match the input string against the patterns between
-#               if  and endif, if and only if the same input string
-#               also matches /pattern/. The if..endif can nest.
+#        endif  If the input string matches /pattern/,  then  match
+#               that  input  string against the patterns between if
+#               and endif.  The if..endif can nest.
 # 
 #               Note: do not prepend whitespace to patterns  inside
 #               if..endif.
 # 
 #        if !/pattern/flags
 # 
-#        endif  Match the input string against the patterns between
-#               if and endif, if and only if the same input  string
-#               does not match /pattern/. The if..endif can nest.
+#        endif  If  the input string does not match /pattern/, then
+#               match  that  input  string  against  the   patterns
+#               between if and endif. The if..endif can nest.
 # 
 #        blank lines and comments
 #               Empty  lines and whitespace-only lines are ignored,
index 2bc86d2aa69f7062310129f51342971e5d661617..06e909430680c339e4e8bf4db205628fd3bd901f 100644 (file)
@@ -362,6 +362,17 @@ The file format is described in <a href="pcre_table.5.html">pcre_table(5)</a>. T
 name as used in "<a href="pcre_table.5.html">pcre</a>:table" is the name of the regular expression
 file.  </dd>
 
+<dt> <b>pipeline</b> (read-only) </dt>
+
+<dd> A pipeline of lookup tables. Example:
+"<b><a href="DATABASE_README.html#types">pipeline</a>:</b><i>!type_1:name_1! ... !type_n:name_n</i>".  Each
+"<a href="DATABASE_README.html#types">pipeline</a>:" query is given to the first table.  Each lookup result
+becomes the query for the next table in the pipeline, and the last
+table produces the final result.  When any table lookup produces
+no result, the pipeline produces no result.  The ASCII character
+after "<a href="DATABASE_README.html#types">pipeline</a>:" will be used as the separator between the lookup
+tables that follow (do not use space, ",", ":" or non-ASCII).  </dd>
+
 <dt> <b>pgsql</b> (read-only) </dt>
 
 <dd> PostgreSQL database client.  Configuration details are given
@@ -373,6 +384,15 @@ in <a href="pgsql_table.5.html">pgsql_table(5)</a>. </dd>
 databases. The lookup table name syntax is "<a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html">type:table</a>".
 </dd>
 
+<dt> <b>random</b> (read-only) </dt>
+
+<dd> An in-memory table that performs random selection.  Example:
+"<b><a href="DATABASE_README.html#types">random</a>:</b><i>!result_1! ... !result_n</i>". Each table query
+returns a random choice from the specified results. The ASCII
+character after "<a href="DATABASE_README.html#types">random</a>:" will be used as the separator between the
+results that follow (do not use space, ",", ":" or non-ASCII).
+</dd>
+
 <dt> <b>regexp</b> (read-only) </dt>
 
 <dd> A lookup table based on regular expressions. The file format
index 29a68b96c4ce6b79c45cdc951d1a9c8b06ed4738..2b4dcd3a43d09ee4191360d89e057629a9cf8184 100644 (file)
@@ -333,6 +333,13 @@ ACCESS(5)                                                            ACCESS(5)
 
               This feature is available in Postfix 2.1 and later.
 
+       <b>INFO</b> <i>optional text...</i>
+              Log an informational record with  the  optional  text,  together
+              with  client  information  and  if available, with helo, sender,
+              recipient and protocol information.
+
+              This feature is available in Postfix 2.12 and later.
+
        <b>WARN</b> <i>optional text...</i>
               Log a warning with  the  optional  text,  together  with  client
               information  and  if available, with helo, sender, recipient and
index 6f1e86fc5067d8eae6fd737100ced8374eb0272b..ce7272a6402b890d06d57457eabccdd98d02b286 100644 (file)
@@ -124,17 +124,17 @@ HEADER_CHECKS(5)                                              HEADER_CHECKS(5)
 
        <b>if /</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match  the  input  string  against  the  patterns between <b>if</b> and
-              <b>endif</b>, if and only if the same input string also  matches  /<i>pat-</i>
-              <i>tern</i>/. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If  the  input  string  matches /<i>pattern</i>/, then match that input
+              string against the patterns between <b>if</b> and <b>endif</b>.  The <b>if</b>..<b>endif</b>
+              can nest.
 
               Note: do not prepend whitespace to patterns inside <b>if</b>..<b>endif</b>.
 
        <b>if !/</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match  the  input  string  against  the  patterns between <b>if</b> and
-              <b>endif</b>, if and only if the same input string does <b>not</b> match /<i>pat-</i>
-              <i>tern</i>/. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If  the  input  string does not match /<i>pattern</i>/, then match that
+              input string against the patterns  between  <b>if</b>  and  <b>endif</b>.  The
+              <b>if</b>..<b>endif</b> can nest.
 
        blank lines and comments
               Empty  lines and whitespace-only lines are ignored, as are lines
index e686a7324bb612895e050f5cf7e9c83d1d4f81d3..3689ff2e54c5cb3ecec5d6c784fe257c31ae54ae 100644 (file)
@@ -48,9 +48,9 @@ PCRE_TABLE(5)                                                    PCRE_TABLE(5)
 
        <b>if /</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match the input string  against  the  patterns  between  <b>if</b>  and
-              <b>endif</b>,  if  and only if that same input string also matches <i>pat-</i>
-              <i>tern</i>. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If the input string matches /<i>pattern</i>/,  then  match  that  input
+              string against the patterns between <b>if</b> and <b>endif</b>.  The <b>if</b>..<b>endif</b>
+              can nest.
 
               Note: do not prepend whitespace to patterns inside <b>if</b>..<b>endif</b>.
 
@@ -58,9 +58,9 @@ PCRE_TABLE(5)                                                    PCRE_TABLE(5)
 
        <b>if !/</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match the input string  against  the  patterns  between  <b>if</b>  and
-              <b>endif</b>, if and only if that same input string does <b>not</b> match <i>pat-</i>
-              <i>tern</i>. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If the input string does not match /<i>pattern</i>/,  then  match  that
+              input  string  against  the  patterns  between <b>if</b> and <b>endif</b>. The
+              <b>if</b>..<b>endif</b> can nest.
 
               Note: do not prepend whitespace to patterns inside <b>if</b>..<b>endif</b>.
 
index 8c21f4c7e3c8ab8d9930b8cf540441392642d006..81f7d69d582ded5a4b00f50eda4ba1aa125a223d 100644 (file)
@@ -346,26 +346,31 @@ PIPE(8)                                                                PIPE(8)
        tion.
 
        In the case of a non-zero exit status, a limited amount of command out-
-       put is reported in an delivery status notification.   When  the  output
-       begins  with  a  4.X.X  or  5.X.X enhanced status code, the status code
-       takes precedence over the non-zero exit status (Postfix version 2.3 and
-       later).
+       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).
 
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Corrupted message
+       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
        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>
@@ -374,51 +379,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>
@@ -435,22 +440,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 aa16a13a45f48c759b33e6fd96c463e13f3d4ef0..f5969b7539e8aa055a4706e64a5bf5593a2ccd9f 100644 (file)
@@ -253,27 +253,46 @@ POSTCONF(1)                                                        POSTCONF(1)
                      PostgreSQL   database   client.   This  is  described  in
                      <a href="pgsql_table.5.html"><b>pgsql_table</b>(5)</a>.
 
+              <b>pipeline</b> (read-only)
+                     A   pipeline   of   lookup   tables.    Example:   "<b><a href="DATABASE_README.html#types">pipe-</b>
+                     <b>line</a>:</b><i>!type</i><b>_</b><i>1:name</i><b>_</b><i>1!   ...  !type</i><b>_</b><i>n:name</i><b>_</b><i>n</i>".  Each "<a href="DATABASE_README.html#types">pipe-
+                     line</a>:" query is given to the first  table.   Each  lookup
+                     result  becomes the query for the next table in the pipe-
+                     line, and the last table produces the final result.  When
+                     any  table  lookup  produces no result, the pipeline pro-
+                     duces no result. The ASCII  character  after  "<a href="DATABASE_README.html#types">pipeline</a>:"
+                     will  be  used as the separator between the lookup tables
+                     that follow (do not use space, ",", ":" or non-ASCII).
+
               <b>proxy</b>  Postfix <a href="proxymap.8.html"><b>proxymap</b>(8)</a> client for shared access  to  Postfix
                      databases. The table name syntax is <i>type</i><b>:</b><i>name</i>.
 
+              <b>random</b> (read-only)
+                     An  in-memory table that performs random selection. Exam-
+                     ple: "<b><a href="DATABASE_README.html#types">random</a>:</b><i>!result</i><b>_</b><i>1! ... !result</i><b>_</b><i>n</i>". Each table  query
+                     returns  a  random choice from the specified results. The
+                     ASCII character after "<a href="DATABASE_README.html#types">random</a>:" will be used as the sepa-
+                     rator  between the results that follow (do not use space,
+                     ",", ":" or non-ASCII).
+
               <b>regexp</b> (read-only)
-                     A  lookup  table  based  on regular expressions. The file
+                     A lookup table based on  regular  expressions.  The  file
                      format is described in <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a>.
 
               <b>sdbm</b>   An indexed file type based on hashing.  Available on sys-
                      tems with support for SDBM databases.
 
               <b>socketmap</b> (read-only)
-                     Sendmail-style   socketmap  client.  The  table  name  is
-                     <b>inet</b>:<i>host</i>:<i>port</i>:<i>name</i> for a TCP/IP  server,  or  <b>unix</b>:<i>path-</i>
-                     <i>name</i>:<i>name</i>  for a UNIX-domain server. This is described in
+                     Sendmail-style  socketmap  client.  The  table  name   is
+                     <b>inet</b>:<i>host</i>:<i>port</i>:<i>name</i>  for  a  TCP/IP server, or <b>unix</b>:<i>path-</i>
+                     <i>name</i>:<i>name</i> for a UNIX-domain server. This is described  in
                      <a href="socketmap_table.5.html"><b>socketmap_table</b>(5)</a>.
 
               <b>sqlite</b> (read-only)
                      SQLite database. This is described in <a href="sqlite_table.5.html"><b>sqlite_table</b>(5)</a>.
 
               <b>static</b> (read-only)
-                     A table that always returns its name  as  lookup  result.
+                     A  table  that  always returns its name as lookup result.
                      For example, <b><a href="DATABASE_README.html#types">static</a>:foobar</b> always returns the string <b>foo-</b>
                      <b>bar</b> as lookup result.
 
@@ -281,48 +300,48 @@ POSTCONF(1)                                                        POSTCONF(1)
                      TCP/IP client. The protocol is described in <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
 
               <b>texthash</b> (read-only)
-                     Produces  similar results as <a href="DATABASE_README.html#types">hash</a>: files, except that you
-                     don't need to run the <a href="postmap.1.html"><b>postmap</b>(1)</a> command before  you  can
-                     use  the  file, and that it does not detect changes after
+                     Produces similar results as <a href="DATABASE_README.html#types">hash</a>: files, except that  you
+                     don't  need  to run the <a href="postmap.1.html"><b>postmap</b>(1)</a> command before you can
+                     use the file, and that it does not detect  changes  after
                      the file is read.
 
               <b>unix</b> (read-only)
-                     A limited view of the UNIX authentication  database.  The
+                     A  limited  view of the UNIX authentication database. The
                      following tables are implemented:
 
                      <b>unix:passwd.byname</b>
-                            The  table  is the UNIX password database. The key
-                            is a login name.  The result is  a  password  file
+                            The table is the UNIX password database.  The  key
+                            is  a  login  name.  The result is a password file
                             entry in <b>passwd</b>(5) format.
 
                      <b>unix:group.byname</b>
                             The table is the UNIX group database. The key is a
-                            group name.  The result is a group file  entry  in
+                            group  name.   The result is a group file entry in
                             <b>group</b>(5) format.
 
-              Other  table types may exist depending on how Postfix was built.
+              Other table types may exist depending on how Postfix was  built.
 
-       <b>-M</b>     Show <a href="master.5.html"><b>master.cf</b></a> file contents instead of <a href="postconf.5.html"><b>main.cf</b></a>  file  contents.
+       <b>-M</b>     Show  <a href="master.5.html"><b>master.cf</b></a>  file contents instead of <a href="postconf.5.html"><b>main.cf</b></a> file contents.
               Specify <b>-Mf</b> to fold long lines for human readability.
 
               Specify zero or more arguments, each with a <i>service-name</i> or <i>ser-</i>
-              <i>vice-name/service-type</i> pair, where  <i>service-name</i>  is  the  first
-              field  of  a  <a href="master.5.html">master.cf</a>  entry and <i>service-type</i> is one of (<b>inet</b>,
+              <i>vice-name/service-type</i>  pair,  where  <i>service-name</i>  is the first
+              field of a <a href="master.5.html">master.cf</a> entry and <i>service-type</i>  is  one  of  (<b>inet</b>,
               <b>unix</b>, <b>fifo</b>, or <b>pass</b>).
 
-              If <i>service-name</i> or <i>service-name/service-type</i> is specified,  only
-              the  matching  <a href="master.5.html">master.cf</a>  entries  will  be output. For example,
-              "<b>postconf -Mf smtp</b>" will output all services named  "smtp",  and
-              "<b>postconf  -Mf smtp/inet</b>" will output only the smtp service that
-              listens on the network.  Trailing service type fields  that  are
+              If  <i>service-name</i> or <i>service-name/service-type</i> is specified, only
+              the matching <a href="master.5.html">master.cf</a> entries  will  be  output.  For  example,
+              "<b>postconf  -Mf  smtp</b>" will output all services named "smtp", and
+              "<b>postconf -Mf smtp/inet</b>" will output only the smtp service  that
+              listens  on  the network.  Trailing service type fields that are
               omitted will be handled as "*" wildcard fields.
 
               This feature is available with Postfix 2.9 and later. The syntax
-              was changed from "<i>name.type</i>" to "<i>name/type</i>",  and  "*"  wildcard
+              was  changed  from  "<i>name.type</i>" to "<i>name/type</i>", and "*" wildcard
               support was added with Postfix 2.11.
 
        <b>-n</b>     Show only configuration parameters that have explicit <i>name=value</i>
-              settings in <a href="postconf.5.html"><b>main.cf</b></a>.  Specify <b>-nf</b> to fold long lines  for  human
+              settings  in  <a href="postconf.5.html"><b>main.cf</b></a>.  Specify <b>-nf</b> to fold long lines for human
               readability (Postfix 2.9 and later).
 
        <b>-o</b> <i>name=value</i>
@@ -334,50 +353,50 @@ POSTCONF(1)                                                        POSTCONF(1)
 
               This feature is available with Postfix 2.11 and later.
 
-       <b>-P</b>     Show  <a href="master.5.html"><b>master.cf</b></a>  service parameter settings (by default all ser-
+       <b>-P</b>     Show <a href="master.5.html"><b>master.cf</b></a> service parameter settings (by default  all  ser-
               vices   and   all   parameters).    formatted   as   one   "<i>ser-</i>
-              <i>vice/type/parameter=value</i>"  per  line.  Specify <b>-Pf</b> to fold long
+              <i>vice/type/parameter=value</i>" per line.  Specify <b>-Pf</b> to  fold  long
               lines.
 
-              Specify one or more "<i>service/type/parameter</i>"  instances  on  the
-              <a href="postconf.1.html"><b>postconf</b>(1)</a>  command  line  to limit the output to parameters of
-              interest.  Trailing parameter name or service type  fields  that
+              Specify  one  or  more "<i>service/type/parameter</i>" instances on the
+              <a href="postconf.1.html"><b>postconf</b>(1)</a> command line to limit the output  to  parameters  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.
 
        <b>-t</b> [<i>template</i><b>_</b><i>file</i>]
-              Display  the templates for text that appears at the beginning of
-              delivery status notification (DSN) messages,  without  expanding
+              Display the templates for text that appears at the beginning  of
+              delivery  status  notification (DSN) messages, without expanding
               $<b>name</b> expressions.
 
               To override the built-in templates, specify a template file name
-              at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line, or  specify  a  file
+              at  the  end  of the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line, or specify a file
               name in <a href="postconf.5.html"><b>main.cf</b></a> with the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.
 
-              To  force  selection of the built-in templates, specify an empty
-              template file name on the <a href="postconf.1.html"><b>postconf</b>(1)</a>  command  line  (in  shell
+              To force selection of the built-in templates, specify  an  empty
+              template  file  name  on  the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line (in shell
               language: "").
 
               This feature is available with Postfix 2.3 and later.
 
-       <b>-v</b>     Enable  verbose  logging  for  debugging  purposes.  Multiple <b>-v</b>
+       <b>-v</b>     Enable verbose  logging  for  debugging  purposes.  Multiple  <b>-v</b>
               options make the software increasingly verbose.
 
-       <b>-x</b>     Expand <i>$name</i> in  <a href="postconf.5.html"><b>main.cf</b></a>  or  <a href="master.5.html"><b>master.cf</b></a>  parameter  values.  The
+       <b>-x</b>     Expand  <i>$name</i>  in  <a href="postconf.5.html"><b>main.cf</b></a>  or  <a href="master.5.html"><b>master.cf</b></a>  parameter values. The
               expansion is recursive.
 
               This feature is available with Postfix 2.10 and later.
 
-       <b>-X</b>     Edit  the  <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove the parameters
+       <b>-X</b>     Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove  the  parameters
               named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.  Specify a list of param-
               eter names, not "<i>name=value</i>" pairs.
 
-              With  <b>-M</b>,  edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and remove one
-              or more service entries as specified with "<i>service/type</i>" on  the
+              With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and  remove  one
+              or  more service entries as specified with "<i>service/type</i>" on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              With  <b>-P</b>,  edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and remove one
+              With <b>-P</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and  remove  one
               or more service parameter settings (-o parameter=value settings)
               as specied with "<i>service/type/parameter</i>" on the <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
               mand line.
@@ -386,10 +405,10 @@ POSTCONF(1)                                                        POSTCONF(1)
               into place.  Specify quotes to protect special characters on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform  the  reverse  opera-
+              There  is  no  <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse opera-
               tion.
 
-              This  feature is available with Postfix 2.10 and later.  Support
+              This feature is available with Postfix 2.10 and later.   Support
               for -M and -P was added with Postfix 2.11.
 
        <b>-#</b>     Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and comment out the parame-
@@ -397,18 +416,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               eters revert to their default values.  Specify a list of parame-
               ter names, not "<i>name=value</i>" pairs.
 
-              With  <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and comment out
-              one or more service entries as specified with "<i>service/type</i>"  on
+              With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and comment  out
+              one  or more service entries as specified with "<i>service/type</i>" on
               the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
               In all cases the file is copied to a temporary file then renamed
               into place.  Specify quotes to protect special characters on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              There  is  no  <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse opera-
+              There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform  the  reverse  opera-
               tion.
 
-              This feature is available with Postfix 2.6  and  later.  Support
+              This  feature  is  available with Postfix 2.6 and later. Support
               for -M was added with Postfix 2.11.
 
 <b>DIAGNOSTICS</b>
@@ -419,18 +438,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               Directory with Postfix configuration files.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to  this  pro-
        gram.
 
-       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><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#bounce_template_file">bounce_template_file</a> (empty)</b>
-              Pathname of a configuration file with bounce message  templates.
+              Pathname  of a configuration file with bounce message templates.
 
 <b>FILES</b>
        /etc/postfix/<a href="postconf.5.html">main.cf</a>, Postfix configuration parameters
index 0b154e3c0e72a6ae8209c3a21bc26004f05f9192..90a1d3af254c76d74d1ea7730594fb2d6e5ffdd7 100644 (file)
@@ -48,9 +48,9 @@ REGEXP_TABLE(5)                                                REGEXP_TABLE(5)
 
        <b>if /</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match the input string  against  the  patterns  between  <b>if</b>  and
-              <b>endif</b>,  if  and only if that same input string also matches <i>pat-</i>
-              <i>tern</i>. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If the input string matches /<i>pattern</i>/,  then  match  that  input
+              string against the patterns between <b>if</b> and <b>endif</b>.  The <b>if</b>..<b>endif</b>
+              can nest.
 
               Note: do not prepend whitespace to patterns inside <b>if</b>..<b>endif</b>.
 
@@ -58,9 +58,9 @@ REGEXP_TABLE(5)                                                REGEXP_TABLE(5)
 
        <b>if !/</b><i>pattern</i><b>/</b><i>flags</i>
 
-       <b>endif</b>  Match the input string  against  the  patterns  between  <b>if</b>  and
-              <b>endif</b>, if and only if that same input string does <b>not</b> match <i>pat-</i>
-              <i>tern</i>. The <b>if</b>..<b>endif</b> can nest.
+       <b>endif</b>  If the input string does not match /<i>pattern</i>/,  then  match  that
+              input  string  against  the  patterns  between <b>if</b> and <b>endif</b>. The
+              <b>if</b>..<b>endif</b> can nest.
 
               Note: do not prepend whitespace to patterns inside <b>if</b>..<b>endif</b>.
 
index c9b721945e8e728e1d828ddcc3ac3802f81e57e2..58bb9eca9ac8100a6ef1b144c99925e649f752c6 100644 (file)
@@ -4,17 +4,20 @@
 # NAME
 #      makedefs 1
 # SUMMARY
-#      makefile configuration utility
+#      Postfix makefile configuration utility
 # SYNOPSIS
 #      \fBmake makefiles \fIname=value...\fR
 # DESCRIPTION
 #      The \fBmakedefs\fR command identifies the compilation
-#      environment, and emits macro definitions on the standard output
-#      stream that can be prepended to template Makefiles.
+#      environment, and emits macro definitions on the standard
+#      output stream that can be prepended to template Makefiles.
+#      These macros implement an internal interface and are subject
+#      to change without notice.
 #
 #      Default settings can be overruled by specifying them as
-#      environment variables. Use quotes if variables contain
-#      whitespace or shell meta characters.
+#      environment variables (or as name=value pairs on the "make"
+#      command line). Use quotes if variables contain whitespace
+#      or shell meta characters.
 # .IP \fBAUXLIBS=\fIobject_library...\fR
 #      Specifies one or more non-default object libraries. Postfix
 #      2,12 and later specify some of their database library
 # .IP \fBshared=no\fR
 #      Enable (disable) Postfix builds with shared libraries
 #      typically named $shlib_directory/libpostfix-*.so.*.
+#
+#      This feature was introduced with Postfix 2.12.
 # .IP \fBdynamicmaps=yes\fR
 # .IP \fBdynamicmaps=no\fR
 #      Enable (disable) Postfix builds with the configuration file
-#      $plugin_directory/dynamicmaps.cf for dynamically-loadable
+#      $plugin_directory/dynamicmaps.cf and dynamically-loadable
 #      database plugins typically named postfix-*.so.*.  The setting
 #      "dynamicmaps=yes" implicitly enables Postfix shared libraries.
+#
+#      This feature was introduced with Postfix 2.12.
 # .IP \fIinstallation_parameter\fB=\fIvalue\fR...
 #      Override the compiled-in default value of the specified
 #      installation parameter(s). The following parameters are
 #
 #      See the postconf(5) manpage for a description of these
 #      parameters.
+#
+#      This feature was introduced with Postfix 2.12.
 # .IP \fBSHLIB_VERSION=\fIversion\fR
 #      Specifies a non-default shared-library version for Postfix
 #      libraries and database plugins.  By default, the version
 #      equals the default value for the $mail_version parameter.
+#
+#      This feature was introduced with Postfix 2.12.
 # .IP \fBWARN=\fIwarning_flags\fR
 #      Specifies non-default gcc compiler warning options for use when
 #      "make" is invoked in a source subdirectory only.
@@ -904,8 +915,7 @@ DEFINED_MAP_TYPES=`
        { for (n = 1; n <= NF; n++)
              if ($n ~ /^-dhas_/)
                  if (seen[name = substr($n, 7)]++ == 0)
-                     names = name " " names }
-       END { print names }
+                     printf(" %s", name) }
 '`
 
 # Propagate AUXLIBS_FOO or merge them into global AUXLIBS (i.e. SYSLIBS).
index 07784d596a4ab6920c2a751574014489a0c92cc4..ec7d2db2cfec49d92da178a2068a306ac2840fcd 100644 (file)
@@ -273,9 +273,26 @@ The file format is described in \fBpcre_table\fR(5).
 .IP "\fBpgsql\fR (read-only)"
 PostgreSQL database client. This is described in
 \fBpgsql_table\fR(5).
+.IP "\fBpipeline\fR (read-only)"
+A pipeline of lookup tables.  Example:
+"\fBpipeline:\fI!type_1:name_1!  ... !type_n:name_n\fR".
+Each "pipeline:" query is given to the first table.  Each
+lookup result becomes the query for the next table in the
+pipeline, and the last table produces the final result.
+When any table lookup produces no result, the pipeline
+produces no result. The ASCII character after "pipeline:"
+will be used as the separator between the lookup tables
+that follow (do not use space, ",", ":" or non-ASCII).
 .IP "\fBproxy\fR"
 Postfix \fBproxymap\fR(8) client for shared access to Postfix
 databases. The table name syntax is \fItype\fB:\fIname\fR.
+.IP "\fBrandom\fR (read-only)"
+An in-memory table that performs random selection. Example:
+"\fBrandom:\fI!result_1! ... !result_n\fR". Each table query
+returns a random choice from the specified results. The
+ASCII character after "random:" will be used as the separator
+between the results that follow (do not use space, ",", ":"
+or non-ASCII).
 .IP "\fBregexp\fR (read-only)"
 A lookup table based on regular expressions. The file format
 is described in \fBregexp_table\fR(5).
index c1f45ae5872dbb908e409034a28b3e42e44db1d4..24eb89b6d67c8b2f53d30e78585ca1a53363be6d 100644 (file)
@@ -341,6 +341,12 @@ Note: this action overrides the FILTER action, and currently affects
 all recipients of the message.
 .sp
 This feature is available in Postfix 2.1 and later.
+.IP "\fBINFO \fIoptional text...\fR
+Log an informational record with the optional text, together
+with client information and if available, with helo, sender,
+recipient and protocol information.
+.sp
+This feature is available in Postfix 2.12 and later.
 .IP "\fBWARN \fIoptional text...\fR
 Log a warning with the optional text, together with client information
 and if available, with helo, sender, recipient and protocol information.
index 6976eb915efcdcf2ecdde638122b685dd3890202..f5419fbf05b9a9645013850b4c7b01a53b5d44f8 100644 (file)
@@ -136,18 +136,17 @@ When /\fIpattern\fR/ does \fBnot\fR match the input string,
 execute the corresponding \fIaction\fR.
 .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if the same input string also
-matches /\fIpattern\fR/. The \fBif\fR..\fBendif\fR can nest.
+If the input string matches /\fIpattern\fR/, then match that
+input string against the patterns between \fBif\fR and
+\fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 .sp
 Note: do not prepend whitespace to patterns inside
 \fBif\fR..\fBendif\fR.
 .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if the same input string does
-\fBnot\fR match /\fIpattern\fR/. The \fBif\fR..\fBendif\fR
-can nest.
+If the input string does not match /\fIpattern\fR/, then
+match that input string against the patterns between \fBif\fR
+and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 .IP "blank lines and comments"
 Empty lines and whitespace-only lines are ignored, as
 are lines whose first non-whitespace character is a `#'.
index 2a4333059fbb260b1a3f8e5f97c41ad742ee0b8d..c70cc6f5379817e5d6806c23e62ce769a1eb8df1 100644 (file)
@@ -50,9 +50,9 @@ When \fIpattern\fR does \fBnot\fR match the input string, use
 the corresponding \fIresult\fR value.
 .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if that same input string also matches
-\fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+If the input string matches /\fIpattern\fR/, then match that
+input string against the patterns between \fBif\fR and
+\fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 .sp
 Note: do not prepend whitespace to patterns inside
 \fBif\fR..\fBendif\fR.
@@ -60,9 +60,9 @@ Note: do not prepend whitespace to patterns inside
 This feature is available in Postfix 2.1 and later.
 .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if that same input string does \fBnot\fR
-match \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+If the input string does not match /\fIpattern\fR/, then
+match that input string against the patterns between \fBif\fR
+and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 .sp
 Note: do not prepend whitespace to patterns inside
 \fBif\fR..\fBendif\fR.
index ba7fe3f5ec288c235d3bcbee9fee1157f8c0623e..2d3385e814751c7292a43dfd4177b3282258231b 100644 (file)
@@ -50,9 +50,9 @@ When \fIpattern\fR does \fBnot\fR match the input string,
 use the corresponding \fIresult\fR value.
 .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if that same input string also
-matches \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+If the input string matches /\fIpattern\fR/, then match that
+input string against the patterns between \fBif\fR and
+\fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 .sp
 Note: do not prepend whitespace to patterns inside
 \fBif\fR..\fBendif\fR.
@@ -60,9 +60,9 @@ Note: do not prepend whitespace to patterns inside
 This feature is available in Postfix 2.1 and later.
 .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 .IP "\fBendif\fR"
-Match the input string against the patterns between \fBif\fR
-and \fBendif\fR, if and only if that same input string does
-\fBnot\fR match \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+If the input string does not match /\fIpattern\fR/, then
+match that input string against the patterns between \fBif\fR
+and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 .sp
 Note: do not prepend whitespace to patterns inside
 \fBif\fR..\fBendif\fR.
index a3754d2917da210b311249f07d9ade5a5d6ba885..8d6eb3a2e34d8fb441b5b2a6acb40b47fff6cede 100644 (file)
@@ -330,10 +330,16 @@ follow the conventions defined in <\fBsysexits.h\fR>.
 Exit status 0 means normal successful completion.
 
 In the case of a non-zero exit status, a limited amount of
-command output is reported in an delivery status notification.
-When the output begins with a 4.X.X or 5.X.X enhanced status
-code, the status code takes precedence over the non-zero
-exit status (Postfix version 2.3 and later).
+command output 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 status code takes precedence over
+the non-zero exit status (Postfix version 2.3 and later).
+
+After successful delivery (zero exit status) a limited
+amount of command output is logged, and reported in "success"
+delivery status notifications (Postfix 2.12 and later).
+This command output is not examined for the presence of an
+enhanced status code.
 
 Problems and transactions are logged to \fBsyslogd\fR(8).
 Corrupted message files are marked so that the queue manager
index 72181e65d45b2a34a07fa8b1691ec6811b0fff44..5622e5d9b00186c2fa22dead5b4512989c444d27 100755 (executable)
@@ -1114,7 +1114,9 @@ while (<>) {
     s/\b(nisplus):/<a href="nisplus_table.5.html">$1<\/a>:/g;
     s/\b(pcre):/<a href="pcre_table.5.html">$1<\/a>:/g;
     s/\b(pgsql):/<a href="pgsql_table.5.html">$1<\/a>:/g;
+    s;\b(pipe[-</bB>]*\n*[ <bB>]*line):;<a href="DATABASE_README.html#types">$1<\/a>:;g;
     s/\b(proxy):/<a href="proxymap.8.html">$1<\/a>:/g;
+    s/\b(random):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
     s/\b(regexp):/<a href="regexp_table.5.html">$1<\/a>:/g;
     s/\b(sdbm):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
     s/\b(socketmap):/<a href="socketmap_table.html">$1<\/a>:/g;
diff --git a/postfix/postfix-env.sh b/postfix/postfix-env.sh
new file mode 100644 (file)
index 0000000..2d1d63d
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Run a program with the new libraries, not the installed ones.
+
+export LD_LIBRARY_PATH
+LD_LIBRARY_PATH=`pwd`/lib
+
+"$@"
index dcc895d6e5377b4053bf2ade0fe89efbb4c150fb..c21396db386fec997a509d32aba930c7f1330a1f 100644 (file)
@@ -362,6 +362,17 @@ The file format is described in pcre_table(5). The lookup table
 name as used in "pcre:table" is the name of the regular expression
 file.  </dd>
 
+<dt> <b>pipeline</b> (read-only) </dt>
+
+<dd> A pipeline of lookup tables. Example:
+"<b>pipeline:</b><i>!type_1:name_1! ... !type_n:name_n</i>".  Each
+"pipeline:" query is given to the first table.  Each lookup result
+becomes the query for the next table in the pipeline, and the last
+table produces the final result.  When any table lookup produces
+no result, the pipeline produces no result.  The ASCII character
+after "pipeline:" will be used as the separator between the lookup
+tables that follow (do not use space, ",", ":" or non-ASCII).  </dd>
+
 <dt> <b>pgsql</b> (read-only) </dt>
 
 <dd> PostgreSQL database client.  Configuration details are given
@@ -373,6 +384,15 @@ in pgsql_table(5). </dd>
 databases. The lookup table name syntax is "proxy:type:table".
 </dd>
 
+<dt> <b>random</b> (read-only) </dt>
+
+<dd> An in-memory table that performs random selection.  Example:
+"<b>random:</b><i>!result_1! ... !result_n</i>". Each table query
+returns a random choice from the specified results. The ASCII
+character after "random:" will be used as the separator between the
+results that follow (do not use space, ",", ":" or non-ASCII).
+</dd>
+
 <dt> <b>regexp</b> (read-only) </dt>
 
 <dd> A lookup table based on regular expressions. The file format
index 12b56a378269048f4ff87712c3d79457ae3e57e9..7b3c2eb67d27e2a6699b0a24eb4981f1961adc60 100644 (file)
 #      all recipients of the message.
 # .sp
 #      This feature is available in Postfix 2.1 and later.
+# .IP "\fBINFO \fIoptional text...\fR
+#      Log an informational record with the optional text, together
+#      with client information and if available, with helo, sender,
+#      recipient and protocol information.
+# .sp
+#      This feature is available in Postfix 2.12 and later.
 # .IP "\fBWARN \fIoptional text...\fR
 #      Log a warning with the optional text, together with client information
 #      and if available, with helo, sender, recipient and protocol information.
index 015d3a3754936b5a64aa433be344794a87fc8a32..c4c5b628e0429a70ccd55345154611841332f352 100644 (file)
 #      execute the corresponding \fIaction\fR.
 # .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#      Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if the same input string also
-#      matches /\fIpattern\fR/. The \fBif\fR..\fBendif\fR can nest.
+#      If the input string matches /\fIpattern\fR/, then match that
+#      input string against the patterns between \fBif\fR and
+#      \fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 # .sp
 #      Note: do not prepend whitespace to patterns inside
 #      \fBif\fR..\fBendif\fR.
 # .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#      Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if the same input string does
-#      \fBnot\fR match /\fIpattern\fR/. The \fBif\fR..\fBendif\fR
-#      can nest.
+#      If the input string does not match /\fIpattern\fR/, then
+#      match that input string against the patterns between \fBif\fR
+#      and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 # .IP "blank lines and comments"
 #      Empty lines and whitespace-only lines are ignored, as
 #      are lines whose first non-whitespace character is a `#'.
index 56ddcb94b6ec0df3dc424a79b077755bb79d376f..0afeb346e23e8b7571c09bda5972e9fceaa4c00f 100644 (file)
@@ -40,9 +40,9 @@
 #      the corresponding \fIresult\fR value.
 # .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#      Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if that same input string also matches
-#      \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+#      If the input string matches /\fIpattern\fR/, then match that
+#      input string against the patterns between \fBif\fR and
+#      \fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 # .sp
 #      Note: do not prepend whitespace to patterns inside
 #      \fBif\fR..\fBendif\fR.
@@ -50,9 +50,9 @@
 #      This feature is available in Postfix 2.1 and later.
 # .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#      Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if that same input string does \fBnot\fR
-#      match \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+#      If the input string does not match /\fIpattern\fR/, then
+#      match that input string against the patterns between \fBif\fR
+#      and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 # .sp
 #      Note: do not prepend whitespace to patterns inside
 #      \fBif\fR..\fBendif\fR.
index 49b3d50ece8734a3c1ce5fb43643c4def4d44ba0..b448ff101fe06adc652a7e907ae7e559a6269716 100644 (file)
@@ -40,9 +40,9 @@
 #      use the corresponding \fIresult\fR value.
 # .IP "\fBif /\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#       Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if that same input string also
-#      matches \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+#      If the input string matches /\fIpattern\fR/, then match that
+#      input string against the patterns between \fBif\fR and
+#      \fBendif\fR.  The \fBif\fR..\fBendif\fR can nest.
 # .sp
 #       Note: do not prepend whitespace to patterns inside
 #      \fBif\fR..\fBendif\fR.
@@ -50,9 +50,9 @@
 #      This feature is available in Postfix 2.1 and later.
 # .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
 # .IP "\fBendif\fR"
-#       Match the input string against the patterns between \fBif\fR
-#      and \fBendif\fR, if and only if that same input string does
-#      \fBnot\fR match \fIpattern\fR. The \fBif\fR..\fBendif\fR can nest.
+#      If the input string does not match /\fIpattern\fR/, then
+#      match that input string against the patterns between \fBif\fR
+#      and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
 # .sp
 #       Note: do not prepend whitespace to patterns inside
 #      \fBif\fR..\fBendif\fR.
index e5bb34a528c3f8fa66741477a3fa32f5d6d276ba..54466162010a8f3113e388eca62e27ec41869fa5 100644 (file)
@@ -240,7 +240,7 @@ static void dymap_entry_free(char *ptr)
 
 /* dymap_read_conf - read dynamicmaps.cf-like file */
 
-static void dymap_read_conf(const char *path, const char *base)
+static void dymap_read_conf(const char *path, const char *path_base)
 {
     VSTREAM *fp;
     VSTRING *buf;
@@ -274,7 +274,7 @@ static void dymap_read_conf(const char *path, const char *base)
                    msg_fatal("%s, line %d: unsupported syntax \"%s\"",
                              path, linenum, argv->argv[0]);
                if (argv->argv[1][0] != '/') {
-                   cp = concatenate(base, "/", argv->argv[1], (char *) 0);
+                   cp = concatenate(path_base, "/", argv->argv[1], (char *) 0);
                    argv_replace_one(argv, 1, cp);
                    myfree(cp);
                }
index ab7894a61cdd4aadde28972263ae204e1a730917..bd2583373730cbc748072a3b7ec25a4155ea759f 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      "20140531"
+#define MAIL_RELEASE_DATE      "20140618"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index 9c4d8b8cfada3a3ca20ad53d43c827164aec5241..aac532c532fde4d07cd07bfb9f948708b7545e37 100644 (file)
@@ -26,7 +26,8 @@
 /*     An open message queue file, positioned at the start of the actual
 /*     message content.
 /* .IP why
-/*     Delivery status information.
+/*     Delivery status information. The reason attribute may contain
+/*     a limited portion of command output, among other free text.
 /* .IP key
 /*     Specifies what value will follow. pipe_command() takes a list
 /*     of (key, value) arguments, terminated by PIPE_CMD_END. The
@@ -675,6 +676,7 @@ int     pipe_command(VSTREAM *src, DSN_BUF *why,...)
            vstring_sprintf_append(why->reason, ": \"%s\"", args.command);
            return (PIPE_STAT_BOUNCE);
        } else {
+           vstring_strcpy(why->reason, log_buf);
            return (PIPE_STAT_OK);
        }
     }
index 954fecfaf50d68a73b78aea126406fc977ec9d52..b255da87692ba575396e34cc1ee8e77097d46d04 100644 (file)
 /*     Exit status 0 means normal successful completion.
 /*
 /*     In the case of a non-zero exit status, a limited amount of
-/*     command output is reported in an delivery status notification.
-/*     When the output begins with a 4.X.X or 5.X.X enhanced status
-/*     code, the status code takes precedence over the non-zero
-/*     exit status (Postfix version 2.3 and later).
+/*     command output 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 status code takes precedence over
+/*     the non-zero exit status (Postfix version 2.3 and later).
+/*
+/*     After successful delivery (zero exit status) a limited
+/*     amount of command output is logged, and reported in "success"
+/*     delivery status notifications (Postfix 2.12 and later).
+/*     This command output is not examined for the presence of an
+/*     enhanced status code.
 /*
 /*     Problems and transactions are logged to \fBsyslogd\fR(8).
 /*     Corrupted message files are marked so that the queue manager
@@ -1008,6 +1014,7 @@ static int eval_command_status(int command_status, char *service,
     int     status;
     int     result = 0;
     int     n;
+    char   *saved_text;
 
     /*
      * Depending on the result, bounce or defer the message, and mark the
@@ -1015,9 +1022,21 @@ static int eval_command_status(int command_status, char *service,
      */
     switch (command_status) {
     case PIPE_STAT_OK:
+       /* Save the command output before dsb_update() clobbers it. */
+       vstring_truncate(why->reason, trimblanks(STR(why->reason),
+                             VSTRING_LEN(why->reason)) - STR(why->reason));
+       if (VSTRING_LEN(why->reason) > 0) {
+           VSTRING_TERMINATE(why->reason);
+           saved_text =
+               vstring_export(vstring_sprintf(
+                                   vstring_alloc(VSTRING_LEN(why->reason)),
+                                           " (%.100s)", STR(why->reason)));
+       } else
+           saved_text = mystrdup("");          /* uses shared R/O storage */
        dsb_update(why, "2.0.0", (attr->flags & PIPE_OPT_FINAL_DELIVERY) ?
                   "delivered" : "relayed", DSB_SKIP_RMTA, DSB_SKIP_REPLY,
-                  "delivered via %s service", service);
+                  "delivered via %s service%s", service, saved_text);
+       myfree(saved_text);
        (void) DSN_FROM_DSN_BUF(why);
        for (n = 0; n < request->rcpt_list.len; n++) {
            rcpt = request->rcpt_list.info + n;
index 973628ee840ae797dc0eaf34fb819b6c9e6a1480..127de63e11b2fdccee41a54efc2202b61929eaaa 100644 (file)
 /* .IP "\fBpgsql\fR (read-only)"
 /*     PostgreSQL database client. This is described in
 /*     \fBpgsql_table\fR(5).
+/* .IP "\fBpipeline\fR (read-only)"
+/*     A pipeline of lookup tables.  Example:
+/*     "\fBpipeline:\fI!type_1:name_1!  ... !type_n:name_n\fR".
+/*     Each "pipeline:" query is given to the first table.  Each
+/*     lookup result becomes the query for the next table in the
+/*     pipeline, and the last table produces the final result.
+/*     When any table lookup produces no result, the pipeline
+/*     produces no result. The ASCII character after "pipeline:"
+/*     will be used as the separator between the lookup tables
+/*     that follow (do not use space, ",", ":" or non-ASCII).
 /* .IP "\fBproxy\fR"
 /*     Postfix \fBproxymap\fR(8) client for shared access to Postfix
 /*     databases. The table name syntax is \fItype\fB:\fIname\fR.
+/* .IP "\fBrandom\fR (read-only)"
+/*     An in-memory table that performs random selection. Example:
+/*     "\fBrandom:\fI!result_1! ... !result_n\fR". Each table query
+/*     returns a random choice from the specified results. The
+/*     ASCII character after "random:" will be used as the separator
+/*     between the results that follow (do not use space, ",", ":"
+/*     or non-ASCII).
 /* .IP "\fBregexp\fR (read-only)"
 /*     A lookup table based on regular expressions. The file format
 /*     is described in \fBregexp_table\fR(5).
index 715d82e3330654a982a38d98d0e85862aba5c68a..930f47567cf0ebe6fd147599ffe0c42d518d9f3b 100644 (file)
@@ -2128,6 +2128,14 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
        vstream_longjmp(state->client, SMTP_ERR_QUIET);
     }
 
+    /*
+     * INFO. Text is optional.
+     */
+    if (STREQUAL(value, "INFO", cmd_len)) {
+       log_whatsup(state, "info", cmd_text);
+       return (SMTPD_CHECK_DUNNO);
+    }
+
     /*
      * WARN. Text is optional.
      */
index 3a18cdc8e212ea825a0914d02f38bb7bf76f103b..f6b2835499a189b0c4b095455d18ef2468929911 100644 (file)
   */
 static const char server_session_id_context[] = "Postfix/TLS";
 
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+#define GET_SID(s, v, lptr)    ((v) = SSL_SESSION_get_id((s), (lptr)))
+
+#else                                  /* Older OpenSSL releases */
+#define GET_SID(s, v, lptr) \
+    do { (v) = (s)->session_id; *(lptr) = (s)->session_id_length; } while (0)
+
+#endif                                 /* OPENSSL_VERSION_NUMBER */
+
 /* get_server_session_cb - callback to retrieve session from server cache */
 
 static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id,
@@ -221,14 +230,16 @@ static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext)
 {
     VSTRING *cache_id;
     SSL_SESSION *session = SSL_get_session(TLScontext->con);
+    const unsigned char *sid;
+    unsigned int sid_length;
 
     SSL_CTX_remove_session(ctx, session);
 
     if (TLScontext->cache_type == 0)
        return;
 
-    GEN_CACHE_ID(cache_id, session->session_id, session->session_id_length,
-                TLScontext->serverid);
+    GET_SID(session, sid, &sid_length);
+    GEN_CACHE_ID(cache_id, sid, sid_length, TLScontext->serverid);
 
     if (TLScontext->log_mask & TLS_LOG_CACHE)
        msg_info("%s: remove session %s from %s cache", TLScontext->namaddr,
@@ -246,12 +257,14 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session)
     VSTRING *cache_id;
     TLS_SESS_STATE *TLScontext;
     VSTRING *session_data;
+    const unsigned char *sid;
+    unsigned int sid_length;
 
     if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0)
        msg_panic("%s: null TLScontext in new session callback", myname);
 
-    GEN_CACHE_ID(cache_id, session->session_id, session->session_id_length,
-                TLScontext->serverid);
+    GET_SID(session, sid, &sid_length);
+    GEN_CACHE_ID(cache_id, sid, sid_length, TLScontext->serverid);
 
     if (TLScontext->log_mask & TLS_LOG_CACHE)
        msg_info("%s: save session %s to %s cache", TLScontext->namaddr,
index d9c332bccca45550a02d38d86c449e72197c14b6..f32f8f07e3bd8ed926bb992cda9bf75224cc0ff1 100644 (file)
@@ -37,7 +37,7 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        ip_match.c nbbio.c base32_code.c dict_test.c \
        dict_fail.c msg_rate_delay.c dict_surrogate.c warn_stat.c \
        dict_sockmap.c line_number.c recv_pass_attr.c pass_accept.c \
-       poll_fd.c timecmp.c slmdb.c
+       poll_fd.c timecmp.c slmdb.c dict_pipe.c dict_random.c
 OBJS   = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
        attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -76,7 +76,7 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        ip_match.o nbbio.o base32_code.o dict_test.o \
        dict_fail.o msg_rate_delay.o dict_surrogate.o warn_stat.o \
        dict_sockmap.o line_number.o recv_pass_attr.o pass_accept.o \
-       poll_fd.o timecmp.o $(NON_PLUGIN_MAP_OBJ)
+       poll_fd.o timecmp.o $(NON_PLUGIN_MAP_OBJ) dict_pipe.o dict_random.o
 # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
 # When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
 # otherwise it sets the PLUGIN_* macros.
@@ -104,7 +104,7 @@ HDRS        = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
        edit_file.h dict_cache.h dict_thash.h ip_match.h nbbio.h base32_code.h \
        dict_fail.h warn_stat.h dict_sockmap.h line_number.h timecmp.h \
-       slmdb.h compat_va_copy.h
+       slmdb.h compat_va_copy.h dict_pipe.h dict_random.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 DEFS   = -I. -D$(SYSTYPE)
@@ -1093,9 +1093,11 @@ dict_open.o: dict_nis.h
 dict_open.o: dict_nisplus.h
 dict_open.o: dict_open.c
 dict_open.o: dict_pcre.h
+dict_open.o: dict_random.h
 dict_open.o: dict_regexp.h
 dict_open.o: dict_sdbm.h
 dict_open.o: dict_sockmap.h
+dict_open.o: dict_pipe.h
 dict_open.o: dict_static.h
 dict_open.o: dict_tcp.h
 dict_open.o: dict_thash.h
@@ -1126,6 +1128,18 @@ dict_pcre.o: vbuf.h
 dict_pcre.o: vstream.h
 dict_pcre.o: vstring.h
 dict_pcre.o: warn_stat.h
+dict_random.o: argv.h
+dict_random.o: dict.h
+dict_random.o: dict_random.c
+dict_random.o: dict_random.h
+dict_random.o: msg.h
+dict_random.o: myflock.h
+dict_random.o: mymalloc.h
+dict_random.o: myrand.h
+dict_random.o: sys_defs.h
+dict_random.o: vbuf.h
+dict_random.o: vstream.h
+dict_random.o: vstring.h
 dict_regexp.o: argv.h
 dict_regexp.o: dict.h
 dict_regexp.o: dict_regexp.c
@@ -1173,6 +1187,19 @@ dict_sockmap.o: sys_defs.h
 dict_sockmap.o: vbuf.h
 dict_sockmap.o: vstream.h
 dict_sockmap.o: vstring.h
+dict_pipe.o: argv.h
+dict_pipe.o: dict.h
+dict_pipe.o: dict_pipe.c
+dict_pipe.o: dict_pipe.h
+dict_pipe.o: htable.h
+dict_pipe.o: msg.h
+dict_pipe.o: myflock.h
+dict_pipe.o: mymalloc.h
+dict_pipe.o: stringops.h
+dict_pipe.o: sys_defs.h
+dict_pipe.o: vbuf.h
+dict_pipe.o: vstream.h
+dict_pipe.o: vstring.h
 dict_static.o: argv.h
 dict_static.o: dict.h
 dict_static.o: dict_static.c
@@ -1213,6 +1240,7 @@ dict_tcp.o: vstring.h
 dict_tcp.o: vstring_vstream.h
 dict_test.o: argv.h
 dict_test.o: dict.h
+dict_test.o: dict_lmdb.h
 dict_test.o: dict_test.c
 dict_test.o: msg.h
 dict_test.o: msg_vstream.h
@@ -1486,8 +1514,6 @@ load_file.o: vbuf.h
 load_file.o: vstream.h
 load_file.o: warn_stat.h
 load_lib.o: load_lib.c
-load_lib.o: load_lib.h
-load_lib.o: msg.h
 load_lib.o: sys_defs.h
 lowercase.o: lowercase.c
 lowercase.o: stringops.h
index e7a1d4d19604c9abc22781181e6432bbbeff7247..db73624fffd452fcca07d11ce1fe1632514836d5 100644 (file)
@@ -43,6 +43,16 @@ typedef struct DICT_OWNER {
 #define DICT_OWNER_TRUSTED     (!1)    /* ex: root-owned config file */
 #define DICT_OWNER_UNTRUSTED   (!0)    /* ex: non-root config file */
 
+#define DICT_OWNER_AGGREGATE(dst, src) do { \
+       if ((src).status == DICT_OWNER_UNKNOWN) { \
+           (dst).status = (src).status; \
+           (dst).uid = ~0; \
+       } else if ((src).status == DICT_OWNER_UNTRUSTED) { \
+           (dst).status = (src).status; \
+           (dst).uid = ~0; \
+       } \
+    } while (0)
+
  /*
   * Generic dictionary interface - in reality, a dictionary extends this
   * structure with private members to maintain internal state.
index 4408061ab4fab04de11ccacbb2293b284ede15bd..d5ed9ce2fcf95f25e0e10cc6df7a915e47de76bf 100644 (file)
 #include <dict_thash.h>
 #include <dict_sockmap.h>
 #include <dict_fail.h>
+#include <dict_pipe.h>
+#include <dict_random.h>
 #include <stringops.h>
 #include <split_at.h>
 #include <htable.h>
@@ -340,6 +342,8 @@ static const DICT_OPEN_INFO dict_open_info[] = {
     DICT_TYPE_THASH, dict_thash_open,
     DICT_TYPE_SOCKMAP, dict_sockmap_open,
     DICT_TYPE_FAIL, dict_fail_open,
+    DICT_TYPE_PIPE, dict_pipe_open,
+    DICT_TYPE_RANDOM, dict_random_open,
 #ifndef USE_DYNAMIC_MAPS
 #ifdef HAS_PCRE
     DICT_TYPE_PCRE, dict_pcre_open,
diff --git a/postfix/src/util/dict_pipe.c b/postfix/src/util/dict_pipe.c
new file mode 100644 (file)
index 0000000..de8f086
--- /dev/null
@@ -0,0 +1,195 @@
+/*++
+/* NAME
+/*     dict_pipe 3
+/* SUMMARY
+/*     dictionary manager interface for pipelined tables
+/* SYNOPSIS
+/*     #include <dict_pipe.h>
+/*
+/*     DICT    *dict_pipe_open(name, open_flags, dict_flags)
+/*     const char *name;
+/*     int     open_flags;
+/*     int     dict_flags;
+/* DESCRIPTION
+/*     dict_pipe_open() opens a pipeline of one or more tables.
+/*     Example: "\fBpipeline:\fI!type_1:name_1! ... !type_n:name_n\fR".
+/*
+/*     Each "pipeline:" query is given to the first table.  Each
+/*     lookup result becomes the query for the next table in the
+/*     pipeline, and the last table produces the final result.
+/*     When any table lookup produces no result, the pipeline
+/*     produces no result.
+/*
+/*     The ASCII character after "pipeline:" will be used as the
+/*     separator between the lookup tables that follow (do not use
+/*     space, ",", ":" or non-ASCII).
+/*
+/*     The open_flags and dict_flags arguments are passed on to
+/*     the underlying dictionaries.
+/* SEE ALSO
+/*     dict(3) generic dictionary manager
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include "mymalloc.h"
+#include "htable.h"
+#include "dict.h"
+#include "dict_pipe.h"
+#include "stringops.h"
+#include "vstring.h"
+
+/* Application-specific. */
+
+typedef struct {
+    DICT    dict;                      /* generic members */
+    ARGV   *map_pipe;                  /* pipelined tables */
+    VSTRING *qr_buf;                   /* query/reply buffer */
+} DICT_PIPE;
+
+#define STR(x) vstring_str(x)
+
+/* dict_pipe_lookup - search pipelined tables */
+
+static const char *dict_pipe_lookup(DICT *dict, const char *query)
+{
+    const char myname[] = "dict_pipe_lookup";
+    DICT_PIPE *dict_pipe = (DICT_PIPE *) dict;
+    DICT   *map;
+    char  **cpp;
+    char   *dict_type_name;
+    const char *result = 0;
+
+    vstring_strcpy(dict_pipe->qr_buf, query);
+    for (cpp = dict_pipe->map_pipe->argv; (dict_type_name = *cpp) != 0; cpp++) {
+       if ((map = dict_handle(dict_type_name)) == 0)
+           msg_panic("%s: dictionary \"%s\" not found", myname, dict_type_name);
+       if ((result = dict_get(map, STR(dict_pipe->qr_buf))) == 0)
+           DICT_ERR_VAL_RETURN(dict, map->error, result);
+       vstring_strcpy(dict_pipe->qr_buf, result);
+    }
+    DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, STR(dict_pipe->qr_buf));
+}
+
+/* dict_pipe_close - disassociate from pipelined tables */
+
+static void dict_pipe_close(DICT *dict)
+{
+    DICT_PIPE *dict_pipe = (DICT_PIPE *) dict;
+    char  **cpp;
+    char   *dict_type_name;
+
+    for (cpp = dict_pipe->map_pipe->argv; (dict_type_name = *cpp) != 0; cpp++)
+       dict_unregister(dict_type_name);
+    argv_free(dict_pipe->map_pipe);
+    vstring_free(dict_pipe->qr_buf);
+    dict_free(dict);
+}
+
+/* dict_pipe_open - open pipelined tables */
+
+DICT   *dict_pipe_open(const char *name, int open_flags, int dict_flags)
+{
+    const char myname[] = "dict_pipe_open";
+    DICT_PIPE *dict_pipe;
+    char   *saved_name = 0;
+    char   *dict_type_name;
+    ARGV   *argv = 0;
+    char  **cpp;
+    DICT   *dict;
+    int     match_flags = 0;
+    struct DICT_OWNER aggr_owner;
+    char    delim[2];
+
+    /*
+     * Clarity first. Let the optimizer worry about redundant code.
+     */
+#define DICT_PIPE_RETURN(x) do { \
+           if (saved_name != 0) \
+               myfree(saved_name); \
+           if (argv != 0) \
+               argv_free(argv); \
+           return (x); \
+       } while (0)
+
+    /*
+     * Sanity checks.
+     */
+    if (open_flags != O_RDONLY)
+       DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name,
+                                       open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                       DICT_TYPE_PIPE, name));
+    if (name[0] == ':')
+       DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name,
+                                       open_flags, dict_flags,
+                              "invalid list delimiter \"%c\" in \"%s:%s\"",
+                                       name[0], DICT_TYPE_PIPE, name));
+
+    /*
+     * Split the table name on the user-specified delimiter.
+     */
+    delim[0] = name[0];                                /* XXX ASCII delimiter */
+    delim[1] = 0;
+    saved_name = mystrdup(name + 1);           /* XXX ASCII delimiter */
+    if (*saved_name == 0)
+       DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name,
+                                       open_flags, dict_flags,
+                     "bad syntax: \"%s:%s\"; need \"%s:%stype:name%s...\"",
+                                       DICT_TYPE_PIPE, name,
+                                       DICT_TYPE_PIPE, delim, delim));
+
+    /*
+     * The least-trusted table in the pipeline determines the over-all trust
+     * level. The first table determines the pattern-matching flags.
+     */
+    aggr_owner.status = DICT_OWNER_TRUSTED;
+    aggr_owner.uid = 0;
+    argv = argv_split(saved_name, delim);
+    for (cpp = argv->argv; (dict_type_name = *cpp) != 0; cpp++) {
+       if (msg_verbose)
+           msg_info("%s: %s", myname, dict_type_name);
+       if (strchr(dict_type_name, ':') == 0)
+           DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name,
+                                           open_flags, dict_flags,
+                                        "bad syntax: \"%s\" in \"%s:%s\"; "
+                                           "need \"type:name\"",
+                                           dict_type_name, DICT_TYPE_PIPE,
+                                           name));
+       if ((dict = dict_handle(dict_type_name)) == 0)
+           dict = dict_open(dict_type_name, open_flags, dict_flags);
+       dict_register(dict_type_name, dict);
+       DICT_OWNER_AGGREGATE(aggr_owner, dict->owner);
+       if (cpp == argv->argv)
+           match_flags = dict->flags & (DICT_FLAG_FIXED | DICT_FLAG_PATTERN);
+    }
+
+    /*
+     * Bundle up the result.
+     */
+    dict_pipe =
+       (DICT_PIPE *) dict_alloc(DICT_TYPE_PIPE, name, sizeof(*dict_pipe));
+    dict_pipe->dict.lookup = dict_pipe_lookup;
+    dict_pipe->dict.close = dict_pipe_close;
+    dict_pipe->dict.flags = dict_flags | match_flags;
+    dict_pipe->dict.owner = aggr_owner;
+    dict_pipe->qr_buf = vstring_alloc(100);
+    dict_pipe->map_pipe = argv;
+    argv = 0;
+    DICT_PIPE_RETURN(DICT_DEBUG (&dict_pipe->dict));
+}
diff --git a/postfix/src/util/dict_pipe.h b/postfix/src/util/dict_pipe.h
new file mode 100644 (file)
index 0000000..442fd4a
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _DICT_PIPE_H_INCLUDED_
+#define _DICT_PIPE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_pipe 3h
+/* SUMMARY
+/*     dictionary manager interface for pipelined tables
+/* SYNOPSIS
+/*     #include <dict_pipe.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_PIPE "pipeline"
+
+extern DICT *dict_pipe_open(const char *, int, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/util/dict_random.c b/postfix/src/util/dict_random.c
new file mode 100644 (file)
index 0000000..e085b20
--- /dev/null
@@ -0,0 +1,129 @@
+/*++
+/* NAME
+/*     dict_random 3
+/* SUMMARY
+/*     dictionary manager interface for randomized tables
+/* SYNOPSIS
+/*     #include <dict_random.h>
+/*
+/*     DICT    *dict_random_open(name, open_flags, dict_flags)
+/*     const char *name;
+/*     int     open_flags;
+/*     int     dict_flags;
+/* DESCRIPTION
+/*     dict_random_open() opens an in-memory, read-only, table.
+/*     Example: "\fBrandom:\fI!result_1! ... !result_n\fR".
+/*
+/*     Each table query returns a random choice from the specified
+/*     results. Other table access methods are not supported.
+/*
+/*     The ASCII character after "random:" will be used as the
+/*     separator between the results that follow (do not use space,
+/*     ",", ":" or non-ASCII).
+/* SEE ALSO
+/*     dict(3) generic dictionary manager
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <myrand.h>
+#include <dict_random.h>
+
+/* Application-specific. */
+
+typedef struct {
+    DICT    dict;                      /* generic members */
+    ARGV   *replies;                   /* reply values */
+} DICT_RANDOM;
+
+#define STR(x) vstring_str(x)
+
+/* dict_random_lookup - find randomized-table entry */
+
+static const char *dict_random_lookup(DICT *dict, const char *unused_query)
+{
+    DICT_RANDOM *dict_random = (DICT_RANDOM *) dict;
+
+    DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE,
+        dict_random->replies->argv[myrand() % dict_random->replies->argc]);
+}
+
+/* dict_random_close - disassociate from randomized table */
+
+static void dict_random_close(DICT *dict)
+{
+    DICT_RANDOM *dict_random = (DICT_RANDOM *) dict;
+
+    argv_free(dict_random->replies);
+    dict_free(dict);
+}
+
+/* dict_random_open - open a randomized table */
+
+DICT   *dict_random_open(const char *name, int open_flags, int dict_flags)
+{
+    DICT_RANDOM *dict_random;
+    char   *saved_name = 0;
+    char    delim[2];
+
+    /*
+     * Clarity first. Let the optimizer worry about redundant code.
+     */
+#define DICT_RANDOM_RETURN(x) do { \
+       if (saved_name != 0) \
+           myfree(saved_name); \
+       return (x); \
+    } while (0)
+
+    /*
+     * Sanity checks.
+     */
+    if (open_flags != O_RDONLY)
+       DICT_RANDOM_RETURN(dict_surrogate(DICT_TYPE_RANDOM, name,
+                                         open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                         DICT_TYPE_RANDOM, name));
+
+    /*
+     * Split the name on the user-specified delimiter.
+     */
+    delim[0] = name[0];                                /* XXX ASCII delimiter */
+    delim[1] = 0;
+    saved_name = mystrdup(name + 1);           /* XXX ASCII delimiter */
+    if (*saved_name == 0)
+       DICT_RANDOM_RETURN(dict_surrogate(DICT_TYPE_RANDOM, name,
+                                         open_flags, dict_flags,
+                         "bad syntax: \"%s:%s\"; need \"%s:%svalue%s...\"",
+                                         DICT_TYPE_RANDOM, name,
+                                         DICT_TYPE_RANDOM, delim, delim));
+
+    /*
+     * Bundle up the result.
+     */
+    dict_random =
+       (DICT_RANDOM *) dict_alloc(DICT_TYPE_RANDOM, name, sizeof(*dict_random));
+    dict_random->dict.lookup = dict_random_lookup;
+    dict_random->dict.close = dict_random_close;
+    dict_random->dict.flags = dict_flags | DICT_FLAG_PATTERN;
+    dict_random->replies = argv_split(saved_name, delim);
+    dict_random->dict.owner.status = DICT_OWNER_TRUSTED;
+    dict_random->dict.owner.uid = 0;
+
+    DICT_RANDOM_RETURN(DICT_DEBUG(&dict_random->dict));
+}
diff --git a/postfix/src/util/dict_random.h b/postfix/src/util/dict_random.h
new file mode 100644 (file)
index 0000000..374f853
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _DICT_RANDOM_H_INCLUDED_
+#define _DICT_RANDOM_H_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_random 3h
+/* SUMMARY
+/*     dictionary manager interface for ramdomized tables
+/* SYNOPSIS
+/*     #include <dict_random.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_RANDOM       "random"
+
+extern DICT *dict_random_open(const char *, int, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif