]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.12-20260127 master
authorWietse Z Venema <wietse@porcupine.org>
Tue, 27 Jan 2026 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Thu, 29 Jan 2026 16:17:32 +0000 (03:17 +1100)
28 files changed:
postfix/HISTORY
postfix/README_FILES/MYSQL_README
postfix/auxiliary/fix-grep/fix-grep.sh
postfix/html/MYSQL_README.html
postfix/html/mysql_table.5.html
postfix/html/postconf.1.html
postfix/makedefs
postfix/man/man1/postconf.1
postfix/man/man5/mysql_table.5
postfix/mantools/check-spell-history
postfix/proto/MYSQL_README.html
postfix/proto/mysql_table
postfix/proto/stop.double-history
postfix/proto/stop.spell-cc
postfix/proto/stop.spell-history
postfix/proto/stop.spell-proto-html
postfix/src/dns/dns.h
postfix/src/global/mail_version.h
postfix/src/milter/milter8.c
postfix/src/postconf/Makefile.in
postfix/src/postconf/postconf.c
postfix/src/postconf/postconf.h
postfix/src/postconf/postconf_lookup.c
postfix/src/postconf/postconf_master.c
postfix/src/postconf/postconf_user.c
postfix/src/postconf/test91.ref [new file with mode: 0644]
postfix/src/util/mac_expand.c
postfix/src/util/mac_expand.h

index 9a8801222ffbc2b29dffc1d7bc1b6a194c9bf6bc..f0e214b2b825e6d899eb75e5664756b34b743dd4 100644 (file)
@@ -30338,3 +30338,43 @@ Apologies for any names omitted.
 
        Cleanup: unbroke Valgrind tests. Files: postmulti/Makefile.in,
        proxymap/Makefile.in.
+
+       Cleanup: missing "4.7.1" enhanced status code in Milter
+       "shutdown" response. File: milter/milter8.c.
+
+20260119
+
+       Cleanup: change the domain name length limit from 1024 to
+       MAXDNAME (defined in <arpa/nameser.h>) which is 1025. File:
+       src/dns/dns.h.
+
+20260126
+
+       Cleanup: postconf logged errors when a 'raw parameter' $name
+       (such as $smtpd_expansion_filter) appeared in the value of
+       a non-raw parameter. The solution was to selectively disable
+       mac_expand() recursion for 'raw' parameters. Files:
+       util/mac_expand.[hc], postconf/postconf_lookup.c
+
+20260127
+
+       Usability: when building on a Linux system that has no
+       Berkeley DB header file installed, "make makefiles" will
+       now suggest building with -DNO_DB instead. File: makedefs.
+
+       Usability: when building with -DNO_DB, makedefs will now
+       remind the user to override the default_database_type and
+       default_cache_db_type with names other than 'hash' or
+       'btree'. File: makedefs.
+
+       Added notes about MariaDB support, suggested by Otto
+       Kekäläinen. Files: proto/MYSQL_README.html proto/mysql_table.
+
+       Feature: "postconf -PP service/type/parameter" will list
+       parameters that are not set in master.cf. This is useful
+       because the value of such a parameter may depend on some
+       other parameter setting in master.cf. The initial use case
+       is to support tools that scan Postfix configurations for
+       deprecated lookup tables. A typical example is "postconf
+       -PPx '*/*/proxy_read_maps". Files: postconf/postconf.[hc],
+       postconf/postconf_master.c, postconf/Makefile.in.
index 8b8b3b19078140d006e45fedd9d1b9bc989b2898..c2a62797b71ea133ab716e44e281e5d0c0e379b4 100644 (file)
@@ -4,11 +4,15 @@ P\bPo\bos\bst\btf\bfi\bix\bx M\bMy\byS\bSQ\bQL\bL H\bHo\bow\bwt\bto\bo
 
 I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
 
-The Postfix mysql map type allows you to hook up Postfix to a MySQL database.
-This implementation allows for multiple mysql databases: you can use one for a
-virtual(5) table, one for an access(5) table, and one for an aliases(5) table
-if you want. You can specify multiple servers for the same database, so that
-Postfix can switch to a good database server if one goes bad.
+The Postfix mysql map type allows you to hook up Postfix to MySQL or MariaDB
+databases. This implementation allows for multiple databases: you can use one
+for a virtual(5) table, one for an access(5) table, and one for an aliases(5)
+table if you want. You can specify multiple servers for the same database, so
+that Postfix can switch to a good database server if one goes bad.
+
+Even though the component name is 'mysql' in Postfix, MariaDB/MySQL client and
+servers can be used interchangeably as the functionality Postfix relies on is
+available in both. However, the code bases may still diverge in the future.
 
 Busy mail servers using mysql maps will generate lots of concurrent mysql
 clients, so the mysql server(s) should be run with this fact in mind. You can
@@ -30,6 +34,11 @@ obtained from:
 
     https://www.mysql.com/downloads/
 
+Many Linux distributions compile Postfix MySQL support using the equivalent
+client library from MariaDB:
+
+    https://mariadb.org/connector-c/
+
 In order to build Postfix with mysql map support, you will need to add -
 DHAS_MYSQL and -I for the directory containing the mysql headers, and the
 mysqlclient library (and libm) to AUXLIBS_MYSQL, for example:
index 4faf3443e23a8fc3cf90727e6c9668394739ee01..2719861580727da13628931d6c498575a8769039 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # Fix grep -[EF] for systems that require the historical forms egrep
-# and fgrep. Run this script in the top-level Postfix directory as
+# and fgrep. Run this script from the top-level Postfix directory as
 #     sh auxiliary/fix-grep/fix-grep.sh
 
 # Use only historical grep syntax.
index f8ced933068a45508d843fc865b1e57dd19801c7..ff76d68fa3e5016b696da2ac772f58a5cb611209 100644 (file)
@@ -5,7 +5,7 @@
 
 <head>
 
-<title>Postfix MySQL Howto</title>
+<title>Postfix MySQL/MariaDB Howto</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <link rel='stylesheet' type='text/css' href='postfix-doc.css'>
 
 <h2>Introduction</h2>
 
-<p> The Postfix mysql map type allows you to hook up Postfix to a
-MySQL database. This implementation allows for multiple mysql
+<p> The Postfix mysql map type allows you to hook up Postfix to
+MySQL or MariaDB databases. This implementation allows for multiple
 databases: you can use one for a <a href="virtual.5.html">virtual(5)</a> table, one for an
 <a href="access.5.html">access(5)</a> table, and one for an <a href="aliases.5.html">aliases(5)</a> table if you want.  You
 can specify multiple servers for the same database, so that Postfix
 can switch to a good database server if one goes bad.  </p>
 
+<p> Even though the component name is 'mysql' in Postfix, MariaDB/MySQL
+client and servers can be used interchangeably as the functionality
+Postfix relies on is available in both. However, the code bases may
+still diverge in the future. </p>
+
 <p> Busy mail servers using mysql maps will generate lots of
 concurrent mysql clients, so the mysql server(s) should be run with
 this fact in mind.  You can reduce the number of concurrent mysql
@@ -50,6 +55,13 @@ which can be obtained from: </p>
     <p> <a href="https://www.mysql.com/downloads/">https://www.mysql.com/downloads/</a> </p>
 </blockquote>
 
+<p> Many Linux distributions compile Postfix MySQL support using
+the equivalent client library from MariaDB: </p>
+
+<blockquote>
+    <p> <a href="https://mariadb.org/connector-c/">https://mariadb.org/connector-c/</a> </p>
+</blockquote>
+
 <p> In order to build Postfix with mysql map support, you will need to add
 -DHAS_MYSQL and -I for the directory containing the mysql headers, and
 the mysqlclient library (and libm) to <a href="MYSQL_README.html">AUXLIBS_MYSQL</a>, for example: </p>
index 8c8e5588ea0ac391dfff00fee85e6aa534382e08..5fecce71e07276327c81bee50d04d0ed23095eb8 100644 (file)
@@ -8,7 +8,7 @@
 MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
 
 <b><a name="name">NAME</a></b>
-       mysql_table - Postfix MySQL client configuration
+       mysql_table - Postfix MySQL/MariaDB client configuration
 
 <b><a name="synopsis">SYNOPSIS</a></b>
        <b>postmap -q "</b><i>string</i><b>" <a href="mysql_table.5.html">mysql</a>:/etc/postfix/</b><i>filename</i>
@@ -27,49 +27,54 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
        The file /etc/postfix/mysql-aliases.cf has the same format as the Post-
        fix <a href="postconf.5.html">main.cf</a> file, and can specify the parameters described below.
 
+       Even  though  the  component  name is 'mysql' in Postfix, MariaDB/MySQL
+       client and servers can be used  interchangeably  as  the  functionality
+       Postfix  relies  on is available in both. However, their code bases may
+       still diverge in the future.
+
 <b><a name="list_membership">LIST MEMBERSHIP</a></b>
-       When  using  SQL  to  store  lists such as $<a href="postconf.5.html#mynetworks">mynetworks</a>, $<a href="postconf.5.html#mydestination">mydestination</a>,
-       $<a href="postconf.5.html#relay_domains">relay_domains</a>, $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>, etc., it is important to  under-
+       When using SQL to store  lists  such  as  $<a href="postconf.5.html#mynetworks">mynetworks</a>,  $<a href="postconf.5.html#mydestination">mydestination</a>,
+       $<a href="postconf.5.html#relay_domains">relay_domains</a>,  $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>, etc., it is important to under-
        stand that the table must store each list member as a separate key. The
-       table lookup verifies the *existence* of the key.  See  "Postfix  lists
+       table  lookup  verifies  the *existence* of the key. See "Postfix lists
        versus tables" in the <a href="DATABASE_README.html">DATABASE_README</a> document for a discussion.
 
-       Do  NOT create tables that return the full list of domains in $<a href="postconf.5.html#mydestination">mydesti</a>-
+       Do NOT create tables that return the full list of domains in  $<a href="postconf.5.html#mydestination">mydesti</a>-
        <a href="postconf.5.html#mydestination">nation</a> or $<a href="postconf.5.html#relay_domains">relay_domains</a> etc., or IP addresses in $<a href="postconf.5.html#mynetworks">mynetworks</a>.
 
        DO create tables with each matching item as a key and with an arbitrary
-       value.  With  SQL databases it is not uncommon to return the key itself
+       value. With SQL databases it is not uncommon to return the  key  itself
        or a constant value.
 
 <b><a name="mysql_parameters">MYSQL PARAMETERS</a></b>
-       <b>hosts</b>  The hosts that Postfix will try to connect to  and  query  from.
+       <b>hosts</b>  The  hosts  that  Postfix will try to connect to and query from.
               Specify <i>unix:</i> for UNIX domain sockets, <i>inet:</i> for TCP connections
               (default).  Examples:
                   hosts = inet:host1.some.domain inet:host2.some.domain:port
                   hosts = host1.some.domain host2.some.domain:port
                   hosts = unix:/file/name
 
-              The hosts are tried in random order, with all  connections  over
+              The  hosts  are tried in random order, with all connections over
               UNIX domain sockets being tried before those over TCP.  The con-
-              nections are automatically closed after being idle for  about  1
+              nections  are  automatically closed after being idle for about 1
               minute, and are re-opened as necessary. Postfix versions 2.0 and
               earlier do not randomize the host order.
 
               NOTE: if you specify localhost as a hostname (even if you prefix
-              it  with  <i>inet:</i>),  MySQL will connect to the default UNIX domain
+              it with <i>inet:</i>), MySQL will connect to the  default  UNIX  domain
               socket.  In order to instruct MySQL to connect to localhost over
               TCP you have to specify
                   hosts = 127.0.0.1
 
-              NOTE:  if  the  <b>hosts</b>  setting  specifies  only one server, this
-              client assumes that the target  is  a  load  balancer  and  will
-              reconnect  immediately after a single failure. With Postfix ver-
+              NOTE: if the <b>hosts</b>  setting  specifies  only  one  server,  this
+              client  assumes  that  the  target  is  a load balancer and will
+              reconnect immediately after a single failure. With Postfix  ver-
               sions 3.9 and earlier, specify the same server twice.
 
        <b>user</b>
 
        <b>password</b>
-              The user name and password to log into the mysql server.   Exam-
+              The  user name and password to log into the mysql server.  Exam-
               ple:
                   user = someone
                   password = some_password
@@ -78,15 +83,15 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
                   dbname = customer_database
 
        <b>charset (default: utf8mb4)</b>
-              The  default  MySQL  client character set; this also implies the
+              The default MySQL client character set; this  also  implies  the
               collation order.
 
-              This parameter is available with Postfix 3.9  and  later.   With
-              earlier  Postfix  versions,  the default was chosen by the MySQL
+              This  parameter  is  available with Postfix 3.9 and later.  With
+              earlier Postfix versions, the default was chosen  by  the  MySQL
               implementation (<b>utf8mb4</b> as of MySQL 8.0, <b>latin1</b> historically).
 
        <b>idle_interval (default: 60)</b>
-              The number of seconds after which an  idle  database  connection
+              The  number  of  seconds after which an idle database connection
               will be closed.
 
               This feature is available in Postfix 3.9 and later.
@@ -95,63 +100,63 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
               The number of seconds that a database connection will be skipped
               after an error.
 
-              NOTE: if the <b>hosts</b>  setting  specifies  only  one  server,  this
-              client  assumes  that  the  target  is  a load balancer and will
-              reconnect immediately after a single failure. With Postfix  ver-
+              NOTE:  if  the  <b>hosts</b>  setting  specifies  only one server, this
+              client assumes that the target  is  a  load  balancer  and  will
+              reconnect  immediately after a single failure. With Postfix ver-
               sions 3.9 and earlier, specify the same server twice.
 
               This feature is available in Postfix 3.9 and later.
 
-       <b>query</b>  The  SQL query template used to search the database, where <b>%s</b> is
-              a substitute for the address Postfix is trying to resolve,  e.g.
+       <b>query</b>  The SQL query template used to search the database, where <b>%s</b>  is
+              a  substitute for the address Postfix is trying to resolve, e.g.
                   query = SELECT replacement FROM aliases WHERE mailbox = '%s'
 
-              By  default,  every  query  must return a result set (instead of
-              storing its results in a table); with "<b>require_result_set =  no</b>"
-              (Postfix  3.2 and later), the absence of a result set is treated
+              By default, every query must return a  result  set  (instead  of
+              storing  its results in a table); with "<b>require_result_set = no</b>"
+              (Postfix 3.2 and later), the absence of a result set is  treated
               as "not found".
 
               This parameter supports the following '%' expansions:
 
               <b>%%</b>     This is replaced by a literal '%' character.
 
-              <b>%s</b>     This is replaced by the input key.  SQL quoting  is  used
-                     to  make  sure that the input key does not add unexpected
+              <b>%s</b>     This  is  replaced by the input key.  SQL quoting is used
+                     to make sure that the input key does not  add  unexpected
                      metacharacters.
 
               <b>%u</b>     When the input key is an address of the form user@domain,
-                     <b>%u</b>  is  replaced  by  the  SQL  quoted  local part of the
-                     address.  Otherwise, <b>%u</b> is replaced by the entire  search
-                     string.   If  the  localpart  is empty, the query is sup-
+                     <b>%u</b> is replaced by  the  SQL  quoted  local  part  of  the
+                     address.   Otherwise, <b>%u</b> is replaced by the entire search
+                     string.  If the localpart is empty,  the  query  is  sup-
                      pressed and returns no results.
 
               <b>%d</b>     When the input key is an address of the form user@domain,
-                     <b>%d</b>  is  replaced  by  the  SQL  quoted domain part of the
-                     address.  Otherwise, the query is suppressed and  returns
+                     <b>%d</b> is replaced by the  SQL  quoted  domain  part  of  the
+                     address.   Otherwise, the query is suppressed and returns
                      no results.
 
               <b>%[SUD]</b> The upper-case equivalents of the above expansions behave
-                     in the <b>query</b> parameter identically  to  their  lower-case
-                     counter-parts.   With  the  <b>result_format</b>  parameter (see
-                     below), they expand the input key rather than the  result
+                     in  the  <b>query</b>  parameter identically to their lower-case
+                     counter-parts.  With  the  <b>result_format</b>  parameter  (see
+                     below),  they expand the input key rather than the result
                      value.
 
-              <b>%[1-9]</b> The  patterns  %1,  %2, ... %9 are replaced by the corre-
-                     sponding most significant component of  the  input  key's
-                     domain.  If  the input key is <i>user@mail.example.com</i>, then
+              <b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced  by  the  corre-
+                     sponding  most  significant  component of the input key's
+                     domain. If the input key is  <i>user@mail.example.com</i>,  then
                      %1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key
-                     is  unqualified or does not have enough domain components
-                     to satisfy all the specified patterns, the query is  sup-
+                     is unqualified or does not have enough domain  components
+                     to  satisfy all the specified patterns, the query is sup-
                      pressed and returns no results.
 
-              The  <b>domain</b>  parameter  described below limits the input keys to
-              addresses in matching domains.  When  the  <b>domain</b>  parameter  is
+              The <b>domain</b> parameter described below limits the  input  keys  to
+              addresses  in  matching  domains.  When  the <b>domain</b> parameter is
               non-empty, SQL queries for unqualified addresses or addresses in
               non-matching domains are suppressed and return no results.
 
-              This parameter is available with Postfix 2.2. In prior  releases
-              the   SQL   query   was  built  from  the  separate  parameters:
-              <b>select_field</b>, <b>table</b>, <b>where_field</b> and <b>additional_conditions</b>.  The
+              This  parameter is available with Postfix 2.2. In prior releases
+              the  SQL  query  was  built  from   the   separate   parameters:
+              <b>select_field</b>,  <b>table</b>, <b>where_field</b> and <b>additional_conditions</b>. The
               mapping from the old parameters to the equivalent query is:
 
                   SELECT [<b>select_field</b>]
@@ -159,50 +164,50 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
                   WHERE [<b>where_field</b>] = '%s'
                         [<b>additional_conditions</b>]
 
-              The  '%s'  in  the  <b>WHERE</b>  clause  expands to the escaped search
-              string.  With Postfix 2.2 these legacy parameters  are  used  if
+              The '%s' in the <b>WHERE</b>  clause  expands  to  the  escaped  search
+              string.   With  Postfix  2.2 these legacy parameters are used if
               the <b>query</b> parameter is not specified.
 
               NOTE: DO NOT put quotes around the query parameter.
 
        <b>result_format (default: %s</b>)
               Format template applied to result attributes. Most commonly used
-              to append (or prepend) text to the result. This  parameter  sup-
+              to  append  (or prepend) text to the result. This parameter sup-
               ports the following '%' expansions:
 
               <b>%%</b>     This is replaced by a literal '%' character.
 
-              <b>%s</b>     This  is  replaced  by the value of the result attribute.
+              <b>%s</b>     This is replaced by the value of  the  result  attribute.
                      When result is empty it is skipped.
 
               <b>%u</b>     When the result attribute value is an address of the form
-                     user@domain,  <b>%u</b>  is  replaced  by  the local part of the
-                     address. When the result has an  empty  localpart  it  is
+                     user@domain, <b>%u</b> is replaced by  the  local  part  of  the
+                     address.  When  the  result  has an empty localpart it is
                      skipped.
 
-              <b>%d</b>     When  a  result attribute value is an address of the form
-                     user@domain, <b>%d</b> is replaced by the  domain  part  of  the
-                     attribute  value.  When  the  result is unqualified it is
+              <b>%d</b>     When a result attribute value is an address of  the  form
+                     user@domain,  <b>%d</b>  is  replaced  by the domain part of the
+                     attribute value. When the result  is  unqualified  it  is
                      skipped.
 
               <b>%[SUD1-9]</b>
-                     The upper-case and decimal digit  expansions  interpolate
-                     the  parts of the input key rather than the result. Their
-                     behavior is identical to that described with  <b>query</b>,  and
-                     in  fact  because  the  input  key  is  known in advance,
-                     queries whose key does not contain  all  the  information
-                     specified  in  the  result  template  are  suppressed and
+                     The  upper-case  and decimal digit expansions interpolate
+                     the parts of the input key rather than the result.  Their
+                     behavior  is  identical to that described with <b>query</b>, and
+                     in fact because  the  input  key  is  known  in  advance,
+                     queries  whose  key  does not contain all the information
+                     specified in  the  result  template  are  suppressed  and
                      return no results.
 
               For example, using "result_format = <a href="smtp.8.html">smtp</a>:[%s]" allows one to use
               a mailHost attribute as the basis of a <a href="transport.5.html">transport(5)</a> table. After
-              applying the result format, multiple values are concatenated  as
+              applying  the result format, multiple values are concatenated as
               comma  separated  strings.  The  expansion_limit  and  parameter
-              explained below allows one to restrict the number of  values  in
+              explained  below  allows one to restrict the number of values in
               the result, which is especially useful for maps that must return
               at most one value.
 
-              The default value <b>%s</b> specifies that each result value should  be
+              The  default value <b>%s</b> specifies that each result value should be
               used as is.
 
               This parameter is available with Postfix 2.2 and later.
@@ -210,15 +215,15 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
               NOTE: DO NOT put quotes around the result format!
 
        <b>domain (default: no domain list)</b>
-              This  is a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
+              This is a list of domain names, paths to files, or  "<a href="DATABASE_README.html">type:table</a>"
               databases. When specified, only fully qualified search keys with
-              a  *non-empty*  localpart and a matching domain are eligible for
+              a *non-empty* localpart and a matching domain are  eligible  for
               lookup:  'user'  lookups,  bare  domain  lookups  and  "@domain"
-              lookups  are  not  performed.  This can significantly reduce the
+              lookups are not performed. This  can  significantly  reduce  the
               query load on the MySQL server.
                   domain = postfix.org, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
 
-              It is best not to use SQL to store the domains eligible for  SQL
+              It  is best not to use SQL to store the domains eligible for SQL
               lookups.
 
               This parameter is available with Postfix 2.2 and later.
@@ -227,43 +232,43 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
               the input keys are always unqualified.
 
        <b>expansion_limit (default: 0)</b>
-              A limit on the total number of result elements  returned  (as  a
+              A  limit  on  the total number of result elements returned (as a
               comma separated list) by a lookup against the map.  A setting of
-              zero disables the limit. Lookups fail with a temporary error  if
-              the  limit  is  exceeded.   Setting  the limit to 1 ensures that
+              zero  disables the limit. Lookups fail with a temporary error if
+              the limit is exceeded.  Setting the  limit  to  1  ensures  that
               lookups do not return multiple values.
 
        <b>option_file</b>
-              Read options from the given file instead of the  default  my.cnf
-              location.  This  reads  options  from the <b>[client]</b> option group,
+              Read  options  from the given file instead of the default my.cnf
+              location. This reads options from  the  <b>[client]</b>  option  group,
               optionally  followed  by  options  from  the  group  given  with
               <b>option_group</b>.
 
               This parameter is available with Postfix 2.11 and later.
 
        <b>option_group (default: Postfix</b> &gt;<b>=3.2: client,</b> &lt;<b>= 3.1: empty)</b>
-              Read  options  from  the  given group of the mysql options file,
+              Read options from the given group of  the  mysql  options  file,
               after reading options from the <b>[client]</b> group.
 
-              Postfix 3.2 and later read <b>[client]</b>  option  group  settings  by
-              default.  To  disable  this  specify  no <b>option_file</b> and specify
+              Postfix  3.2  and  later  read <b>[client]</b> option group settings by
+              default. To disable this  specify  no  <b>option_file</b>  and  specify
               "<b>option_group =</b>" (i.e. an empty value).
 
-              Postfix 3.1 and earlier don't read <b>[client]</b>  option  group  set-
-              tings  unless  a non-empty <b>option_file</b> or <b>option_group</b> value are
+              Postfix  3.1  and  earlier don't read <b>[client]</b> option group set-
+              tings unless a non-empty <b>option_file</b> or <b>option_group</b>  value  are
               specified. To enable this, specify, for example, "<b>option_group =</b>
               <b>client</b>".
 
               This parameter is available with Postfix 2.11 and later.
 
        <b>require_result_set (default: yes)</b>
-              If  "<b>yes</b>",  require  that  every query returns a result set.  If
+              If "<b>yes</b>", require that every query returns  a  result  set.   If
               "<b>no</b>", treat the absence of a result set as "not found".
 
               This parameter is available with Postfix 3.2 and later.
 
 <b><a name="tls-related_settings">TLS-RELATED SETTINGS</a></b>
-       See      <a href="https://dev.mysql.com/doc/c-api/en/mysql-options.html">https://dev.mysql.com/doc/c-api/en/mysql-options.html</a>       or
+       See       <a href="https://dev.mysql.com/doc/c-api/en/mysql-options.html">https://dev.mysql.com/doc/c-api/en/mysql-options.html</a>      or
        <a href="https://mariadb.com/kb/en/mysql_optionsv/">https://mariadb.com/kb/en/mysql_optionsv/</a> for details of the underlying
        MYSQL_OPT_SSL_* features.
 
@@ -273,19 +278,19 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
               This parameter is available with Postfix 2.11 and later.
 
        <b>tls_key_file</b>
-              File containing the private key corresponding to  <b>tls_cert_file</b>.
+              File  containing the private key corresponding to <b>tls_cert_file</b>.
 
               This parameter is available with Postfix 2.11 and later.
 
        <b>tls_CAfile</b>
-              File  containing  X509 certificates for all of the Certification
-              Authorities the client will recognize.   Takes  precedence  over
+              File containing X509 certificates for all of  the  Certification
+              Authorities  the  client  will recognize.  Takes precedence over
               <b>tls_CApath</b>.
 
               This parameter is available with Postfix 2.11 and later.
 
        <b>tls_CApath</b>
-              Directory  containing  X509 Certification Authority certificates
+              Directory containing X509 Certification  Authority  certificates
               in separate individual files.
 
               This parameter is available with Postfix 2.11 and later.
@@ -296,13 +301,13 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
               This parameter is available with Postfix 2.11 and later.
 
        <b>tls_verify_cert (default: no)</b>
-              Verify that the server's name matches the  common  name  in  the
+              Verify  that  the  server's  name matches the common name in the
               certificate.
 
               This parameter is available with Postfix 2.11 and later.
 
 <b><a name="using_mysql_stored_procedures">USING MYSQL STORED PROCEDURES</a></b>
-       Postfix  3.2  and  later  support calling a stored procedure instead of
+       Postfix 3.2 and later support calling a  stored  procedure  instead  of
        using a SELECT statement in the query, e.g.
 
            <b>query</b> = CALL lookup('%s')
@@ -310,17 +315,17 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
        The previously described '%' expansions can be used in the parameter(s)
        to the stored procedure.
 
-       By  default, every stored procedure call must return a result set, i.e.
-       every code path must execute a SELECT statement that returns  a  result
+       By default, every stored procedure call must return a result set,  i.e.
+       every  code  path must execute a SELECT statement that returns a result
        set   (instead   of   storing   its   results   in   a   table).   With
-       "<b>require_result_set = no</b>", the absence of a result set  is  treated  as
+       "<b>require_result_set  =  no</b>",  the absence of a result set is treated as
        "not found".
 
-       A  stored  procedure  must  not  return multiple result sets.  That is,
-       there must be no code path that  executes  multiple  SELECT  statements
+       A stored procedure must not return  multiple  result  sets.   That  is,
+       there  must  be  no  code path that executes multiple SELECT statements
        that return a result (instead of storing their results in a table).
 
-       The  following  is  an example of a stored procedure returning a single
+       The following is an example of a stored procedure  returning  a  single
        result set:
 
        CREATE [DEFINER=`user`@`host`] PROCEDURE
@@ -332,26 +337,26 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
            END
 
 <b>OBSOLETE MAIN.CF PARAMETERS</b>
-       For compatibility with other Postfix lookup  tables,  MySQL  parameters
-       can  also be defined in <a href="postconf.5.html">main.cf</a>.  In order to do that, specify as MySQL
-       source a name that doesn't begin with a slash  or  a  dot.   The  MySQL
-       parameters  will then be accessible as the name you've given the source
-       in its definition, an underscore, and the name of the  parameter.   For
-       example,  if  the  map is specified as "<a href="mysql_table.5.html">mysql</a>:<i>mysqlname</i>", the parameter
+       For  compatibility  with  other Postfix lookup tables, MySQL parameters
+       can also be defined in <a href="postconf.5.html">main.cf</a>.  In order to do that, specify as  MySQL
+       source  a  name  that  doesn't  begin with a slash or a dot.  The MySQL
+       parameters will then be accessible as the name you've given the  source
+       in  its  definition, an underscore, and the name of the parameter.  For
+       example, if the map is specified as  "<a href="mysql_table.5.html">mysql</a>:<i>mysqlname</i>",  the  parameter
        "hosts" would be defined in <a href="postconf.5.html">main.cf</a> as "<i>mysqlname</i>_hosts".
 
-       Note: with this form, the passwords for the MySQL sources  are  written
-       in  <a href="postconf.5.html">main.cf</a>,  which  is normally world-readable.  Support for this form
+       Note:  with  this form, the passwords for the MySQL sources are written
+       in <a href="postconf.5.html">main.cf</a>, which is normally world-readable.  Support  for  this  form
        will be removed in a future Postfix version.
 
 <b><a name="obsolete_query_interface">OBSOLETE QUERY INTERFACE</a></b>
-       This section describes an interface that is deprecated  as  of  Postfix
-       2.2.  It  is  replaced  by  the  more general <b>query</b> interface described
-       above. If  the  <b>query</b>  parameter  is  defined,  the  legacy  parameters
-       described  here  ignored.   Please  migrate to the new interface as the
+       This  section  describes  an interface that is deprecated as of Postfix
+       2.2. It is replaced by  the  more  general  <b>query</b>  interface  described
+       above.  If  the  <b>query</b>  parameter  is  defined,  the  legacy parameters
+       described here ignored.  Please migrate to the  new  interface  as  the
        legacy interface may be removed in a future release.
 
-       The following parameters can be used  to  fill  in  a  SELECT  template
+       The  following  parameters  can  be  used  to fill in a SELECT template
        statement of the form:
 
            SELECT [<b>select_field</b>]
@@ -360,7 +365,7 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
                  [<b>additional_conditions</b>]
 
        The specifier %s is replaced by the search string, and is escaped so if
-       it contains single quotes or other odd characters, it will not cause  a
+       it  contains single quotes or other odd characters, it will not cause a
        parse error, or worse, a security problem.
 
        <b>select_field</b>
index 9fe7e2704ab2aa7ed5f96ec90c853303fbd67df5..c8320cdbf097540c9832faf76df174f2521fa80a 100644 (file)
@@ -448,6 +448,10 @@ POSTCONF(1)                                                        POSTCONF(1)
               vices  and  all  parameters), formatted as "<i>service/type/parame-</i>
               <i>ter=value</i>", one per line.  Specify <b>-Pf</b> to fold long lines.
 
+              Specify multiple <b>-P</b> options to also list service parameters that
+              are not set in <a href="master.5.html">master.cf</a>. This is useful with <b>-x</b> to evaluate the
+              impact of <a href="master.5.html">master.cf</a> overrides on other parameter settings.
+
               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
index 5a8becff0b43be203561836eb23ce841a1389a21..605fc9663d75dc3267835f379fa34a779359fb1f 100644 (file)
@@ -577,6 +577,7 @@ case "$SYSTEM.$RELEASE" in
                        # by including <db.h> and by linking with -ldb
                        echo "No <db.h> include file found." 1>&2
                        echo "Install the appropriate db*-devel package first." 1>&2
+                       echo "Alternatively, build with CCARGS=\"-NO_DB ...\"" 1>&2
                        exit 1
                    fi
                    SYSLIBS="-ldb"
@@ -657,6 +658,7 @@ EOF
                        # by including <db.h> and by linking with -ldb
                        echo "No <db.h> include file found." 1>&2
                        echo "Install the appropriate db*-devel package first." 1>&2
+                       echo "Alternatively, build with CCARGS=\"-NO_DB ...\"" 1>&2
                        exit 1
                    fi
                    SYSLIBS="-ldb"
@@ -695,6 +697,7 @@ EOF
                        # by including <db.h> and by linking with -ldb
                        echo "No <db.h> include file found." 1>&2
                        echo "Install the appropriate db*-devel package first." 1>&2
+                       echo "Alternatively, build with CCARGS=\"-NO_DB ...\"" 1>&2
                        exit 1
                    fi
                    SYSLIBS="-ldb"
@@ -1323,6 +1326,80 @@ do
     done; exit 1) || error "invalid option '$opt' in POSTFIX_INSTALL_OPTS"
 done
 
+# If -DNO_DB is specified then 'hash' and 'btree' will be unavailable.
+
+check_no_db_overrides()
+{
+    trap 'rm -f makedefs.test makedefs.test.[co]' 0 1 2 3 15
+        cat src/util/sys_defs.h >makedefs.test.c
+        cat >>makedefs.test.c <<'EOF'
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+int     main(void)
+{
+    struct def_info {
+       const char *mac_name;
+       const char *parm_name;
+       const char *def_type;
+       const char *problem;
+    };
+    struct def_info def_infos[] = {
+       {"DEF_DB_TYPE", "default_database_type", DEF_DB_TYPE},
+       {"DEF_CACHE_DB_TYPE", "default_cache_db_type", DEF_CACHE_DB_TYPE},
+    };
+    const char *bdb_types[] = {"hash", "btree"};
+    struct def_info *pdef_info;
+    const char *const * pbdb_type;
+    const char *three_bs = "\\\\\\";
+    int     status = 0;
+
+    for (pdef_info = def_infos; pdef_info < def_infos + 2; pdef_info++) {
+       for (pbdb_type = bdb_types; pbdb_type < bdb_types + 2; pbdb_type++) {
+           if (strcmp(pdef_info->def_type, *pbdb_type) == 0) {
+               pdef_info->problem = *pbdb_type;
+               status = 1;
+           }
+       }
+    }
+    if (status != 0) {
+       fprintf(stderr, "\nBuilding with -DNO_DB, but at least one default "
+               "setting still\nrequires 'hash' or 'btree':\n");
+       for (pdef_info = def_infos; pdef_info < def_infos + 2; pdef_info++) {
+           if (pdef_info->problem) {
+               fprintf(stderr, "  %s=%s\n", pdef_info->parm_name,
+                       pdef_info->problem);
+           }
+       }
+       fprintf(stderr, "\nTo fix, specify types other than 'hash' or 'btree', "
+                       "for example:\n  make makefiles ... \\\n    ");
+       for (pdef_info = def_infos; pdef_info < def_infos + 2; pdef_info++) {
+           if (pdef_info->problem) {
+               fprintf(stderr, " %s=lmdb", pdef_info->parm_name);
+           }
+       }
+       fprintf(stderr, " ...\n\nOr, using older syntax:\n");
+       fprintf(stderr, "  make makefiles ... \\\n    CCARGS=\"$CCARGS -DNO_DB");
+       for (pdef_info = def_infos; pdef_info < def_infos + 2; pdef_info++) {
+           if (pdef_info->problem) {
+               fprintf(stderr, " -D%s=%s\"lmdb%s\"",
+                       pdef_info->mac_name, three_bs, three_bs);
+           }
+       }
+       fprintf(stderr, " ...\" ...\n\n");
+    }
+    exit(status);
+}
+EOF
+    eval ${CC-gcc} ${CCARGS} -D$SYSTYPE -o makedefs.test makedefs.test.c || exit 1
+    ./makedefs.test || exit 1
+    rm -f makedefs.test makedefs.test.[co]
+}
+
+case "$CCARGS" in
+ *-DNO_DB*) check_no_db_overrides || exit 1;;
+esac
+
 # Finally...
 
 sed 's/   */ /g' <<EOF
index bcc3111a6d79a34bb90090fe00ee38a612f8392a..f118bbed356cf75fa8528fccb476947d0425ea4a 100644 (file)
@@ -471,6 +471,11 @@ all services and all parameters), formatted as
 "\fIservice/type/parameter=value\fR", one per line.  Specify
 \fB\-Pf\fR to fold long lines.
 
+Specify multiple \fB\-P\fR options to also list service parameters
+that are not set in master.cf. This is useful with \fB\-x\fR to
+evaluate the impact of master.cf overrides on other parameter
+settings.
+
 Specify one or more "\fIservice/type/parameter\fR" instances
 on the \fBpostconf\fR(1) command line to limit the output
 to parameters of interest.  Trailing parameter name or
index 3cca85eb23acd6feebd619045a4ab7ecb9c1dc9d..20244ec30325588038f5956a3958c8e597a887cd 100644 (file)
@@ -4,7 +4,7 @@
 .SH NAME
 mysql_table
 \-
-Postfix MySQL client configuration
+Postfix MySQL/MariaDB client configuration
 .SH "SYNOPSIS"
 .na
 .nf
@@ -28,6 +28,11 @@ table in main.cf, for example:
 The file /etc/postfix/mysql\-aliases.cf has the same format as
 the Postfix main.cf file, and can specify the parameters
 described below.
+
+Even though the component name is 'mysql' in Postfix,
+MariaDB/MySQL client and servers can be used interchangeably as
+the functionality Postfix relies on is available in both. However,
+their code bases may still diverge in the future.
 .SH "LIST MEMBERSHIP"
 .na
 .nf
index 3119be8c218c49573ba7eff11f48820ccddc4f3f..76223f09eaaac0fffda942c0b331cb2284d7e5a5 100755 (executable)
@@ -2,7 +2,8 @@
 
 # Spellchecks text in the HISTORY file, starting with 2022.
 
-LANG=C; export LANG
+#LANG=C; export LANG
+LANG=en_US.UTF-8; export LANG
 
 sed '1,/^2022/d' HISTORY | spell | grep -F -vxf proto/stop | \
        grep -F -vxf proto/stop.spell-cc | \
index e948b26ab4406e52624e2b60c2a05f103a3f5132..46603b15c28ff6a0a7d70c4d45cb32c26655b29c 100644 (file)
@@ -5,7 +5,7 @@
 
 <head>
 
-<title>Postfix MySQL Howto</title>
+<title>Postfix MySQL/MariaDB Howto</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <link rel='stylesheet' type='text/css' href='postfix-doc.css'>
 
 <h2>Introduction</h2>
 
-<p> The Postfix mysql map type allows you to hook up Postfix to a
-MySQL database. This implementation allows for multiple mysql
+<p> The Postfix mysql map type allows you to hook up Postfix to
+MySQL or MariaDB databases. This implementation allows for multiple
 databases: you can use one for a virtual(5) table, one for an
 access(5) table, and one for an aliases(5) table if you want.  You
 can specify multiple servers for the same database, so that Postfix
 can switch to a good database server if one goes bad.  </p>
 
+<p> Even though the component name is 'mysql' in Postfix, MariaDB/MySQL
+client and servers can be used interchangeably as the functionality
+Postfix relies on is available in both. However, the code bases may
+still diverge in the future. </p>
+
 <p> Busy mail servers using mysql maps will generate lots of
 concurrent mysql clients, so the mysql server(s) should be run with
 this fact in mind.  You can reduce the number of concurrent mysql
@@ -50,6 +55,13 @@ which can be obtained from: </p>
     <p> https://www.mysql.com/downloads/ </p>
 </blockquote>
 
+<p> Many Linux distributions compile Postfix MySQL support using
+the equivalent client library from MariaDB: </p>
+
+<blockquote>
+    <p> https://mariadb.org/connector-c/ </p>
+</blockquote>
+
 <p> In order to build Postfix with mysql map support, you will need to add
 -DHAS_MYSQL and -I for the directory containing the mysql headers, and
 the mysqlclient library (and libm) to AUXLIBS_MYSQL, for example: </p>
index d93d405a80041d7aa9e7eb3990984d37239970e0..278a14689634bf4e4fdf825a1a493b84efaaefd4 100644 (file)
@@ -2,7 +2,7 @@
 # NAME
 #      mysql_table 5
 # SUMMARY
-#      Postfix MySQL client configuration
+#      Postfix MySQL/MariaDB client configuration
 # SYNOPSIS
 #      \fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/\fIfilename\fR
 #
 #      The file /etc/postfix/mysql-aliases.cf has the same format as
 #      the Postfix main.cf file, and can specify the parameters
 #      described below.
+#
+#      Even though the component name is 'mysql' in Postfix,
+#      MariaDB/MySQL client and servers can be used interchangeably as
+#      the functionality Postfix relies on is available in both. However,
+#      their code bases may still diverge in the future.
 # LIST MEMBERSHIP
 # .ad
 # .fi
index 17fbca92cdf8087d24b303ae1d41aea19a959342..b6a2c6f60551cd291d0707b9f78690ffe8b84225 100644 (file)
@@ -218,3 +218,6 @@ proto  proto socketmap_table qmqpd qmqpd c tls tls_misc c
  default value with a lookup table File proxymap proxymap c 
  in file name and in restriction_classes File proxymap proxymap c
  proxymap proxymap c
+ src dns dns h 
+ postconf postconf hc postconf postconf_master c 
+ PPx proxy_read_maps Files postconf postconf hc 
index b4af84a6f27c490bfdfd26afd0f3891a3d56c609..57e7c41b616caf38e59576de980f5c3cbbddb92a 100644 (file)
@@ -1890,3 +1890,4 @@ dfhHjnopqvx
 fhHjoqvx
 joqvx
 ajRv
+allparams
index 4d200d5ba87b8068497ef1984725e48c87482414..b119d41794d0f878c385f9b5af220c5a6eebc66d 100644 (file)
@@ -121,3 +121,9 @@ jl
 Ankit
 Kulkarni
 Wordsmithing
+Fusté
+Kekäläinen
+MAXDNAME
+unbroke
+PPx
+unbroke
index 77069db6b4b202b3a0145b4dfbe904117739cd34..cd491eb9540050d3531c14694e441cb69579982e 100644 (file)
@@ -404,3 +404,4 @@ nocertmatch
 noencryption
 nomatch
 nostarttls
+mariadb
index aeec149e9152f28971c311967d1fc22b74d15a60..6d8c6b25b58a53e74764bbae5e64d8a54b2b8956 100644 (file)
@@ -334,7 +334,7 @@ extern int dns_get_h_errno(void);
  /*
   * How long can a DNS name or single text value be?
   */
-#define DNS_NAME_LEN   1024
+#define DNS_NAME_LEN   MAXDNAME        /* From <arpa/nameser.h */
 
  /*
   * dns_rr_filter.c.
index 3a6ca89f82ae6decc6961471f55fe3b01760db19..568a09333fdaa08b48e5e95c2f98704f2ea2299f 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      "20260111"
+#define MAIL_RELEASE_DATE      "20260127"
 #define MAIL_VERSION_NUMBER    "3.12"
 
 #ifdef SNAPSHOT
index 05bd1e1c7ae838bfb90133738d6e53b61638d151..02e3ca3cd00c7a3fcb9246a1f01025c24923ea9f 100644 (file)
@@ -560,7 +560,7 @@ static int milter8_comm_error(MILTER8 *milter)
     } else if (strcasecmp(milter->def_action, "tempfail") == 0) {
        reply = "451 4.7.1 Service unavailable - try again later";
     } else if (strcasecmp(milter->def_action, "shutdown") == 0) {
-       reply = "421 Service unavailable - try again later";
+       reply = "421 4.7.1 Service unavailable - try again later";
     } else if (strcasecmp(milter->def_action, "quarantine") == 0) {
        reply = "Hdefault_action";
     } else {
index 75a6f428f2a378c9de4855f73d2454236bb71298..8ac6499d9137901449f8e4646410070d6f379ef7 100644 (file)
@@ -28,7 +28,7 @@ LIBS  = ../../lib/libxsasl.a \
        ../../lib/lib$(LIB_PREFIX)dns$(LIB_SUFFIX) \
        ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
        ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
-HTABLE_FIX = NORANDOMIZE=1
+HTABLE_FIX = NORANDOMIZE=1 LD_PRELOAD=../../lib/nosleep.so
 
 .c.o:; $(CC) $(CFLAGS) -c $*.c
 
@@ -56,9 +56,10 @@ tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
        test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
        test52 test53 test54 test55 test56 test57 test58 test59 test60 test61 \
        test62 test63 test64 test65 test66 test67 test68 test69 test70 test71 \
-       test72 test73 test74 test75 test76 test78 test79 json_tests
+       test72 test73 test74 test75 test76 test78 test79 json_tests80-90 \
+       test91 test92
 
-json_tests: test80 test81 test82 test83 test84 test85 test86 test87
+json_tests80-90: test80 test81 test82 test83 test84 test85 test86 test87
 
 root_tests:
 
@@ -1254,6 +1255,45 @@ test87: $(PROG) test87.ref
        diff test87.ref test87.tmp
        rm -f main.cf master.cf test87.tmp
 
+# postconf -PP will list parameters not set in master.cf.
+test91: $(PROG) test91.ref
+       rm -f main.cf master.cf test91.tmp
+       touch main.cf master.cf test91.tmp
+       #echo 'foo/unix/proxymap = foo_map' >> test91.tmp
+       #echo 'bar/unix/proxymap = bar_map' >> test91.tmp
+       #echo 'baz/unix/proxymap = baz_map' >> test91.tmp
+       echo 'foo_proxy_write_maps=foo_map' >> main.cf
+       echo 'bar_proxy_write_maps=bar_map' >> main.cf
+       echo 'proxy_write_maps=baz_map' >> main.cf
+       touch -t 197601010000 main.cf
+       echo foo unix - n n - 0 foo >> master.cf
+       echo ' -o proxy_write_maps=$$foo_proxy_write_maps' >> master.cf
+       echo bar unix - n n - 0 bar >> master.cf
+       echo ' -o proxy_write_maps=$$bar_proxy_write_maps' >> master.cf
+       echo baz unix - n n - 0 baz >> master.cf
+       touch -t 197601010000 master.cf
+       $(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -xPPc. \
+           '*/*/proxy_write_maps' >test91.tmp 2>&1
+       diff test91.ref test91.tmp
+       rm -f main.cf master.cf test91.tmp
+
+# postconf -PP will list the same parameters as "postconf", but it does
+# that once for every master.cf service, and will show the settings that
+# are in effect for that service.
+test92: $(PROG)
+       rm -f main.cf master.cf test92.tmp
+       touch main.cf master.cf test92.tmp
+       touch -t 197601010000 main.cf
+       echo foo unix - n n - 0 foo >> master.cf
+       touch -t 197601010000 master.cf
+       $(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c. | \
+           grep -E -v '^(process_id|process_name|service_name) =' >test92.tmp
+       $(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -PPc. | \
+           sed 's;foo/unix/;;' | \
+           grep -E -v '^(process_id|process_name|service_name) =' | \
+           diff test92.tmp -
+       rm -f main.cf master.cf test92.tmp
+
 tidy:  clean
 
 depend: $(MAKES)
index c53ca4a9a310dddb074fb5728af2f9f029f2f400..5b1b5f02705316c58f04073f277d957b9b33e17d 100644 (file)
 /*     "\fIservice/type/parameter=value\fR", one per line.  Specify
 /*     \fB-Pf\fR to fold long lines.
 /*
+/*     Specify multiple \fB-P\fR options to also list service parameters
+/*     that are not set in master.cf. This is useful with \fB-x\fR to
+/*     evaluate the impact of master.cf overrides on other parameter
+/*     settings.
+/*
 /*     Specify one or more "\fIservice/type/parameter\fR" instances
 /*     on the \fBpostconf\fR(1) command line to limit the output
 /*     to parameters of interest.  Trailing parameter name or
@@ -673,6 +678,7 @@ static const int pcf_incompat_options[] = {
     |PCF_SHOW_LOCKS | PCF_SHOW_MAPS | PCF_DUMP_DSN_TEMPL | PCF_MAIN_PARAM \
     |PCF_MASTER_ENTRY | PCF_MASTER_FLD | PCF_MASTER_PARAM | PCF_SHOW_TLS,
     /* Modifiers. */
+    PCF_MASTER_PP | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
     PCF_SHOW_DEFS | PCF_EDIT_CONF | PCF_SHOW_NONDEF | PCF_COMMENT_OUT \
     |PCF_EDIT_EXCL,
     PCF_FOLD_LINE | PCF_EDIT_CONF | PCF_COMMENT_OUT | PCF_EDIT_EXCL,
@@ -710,7 +716,10 @@ static const int pcf_compat_options[][2] = {
                      |PCF_SHOW_JSON)},
     {PCF_MASTER_PARAM, (PCF_EDIT_CONF | PCF_EDIT_EXCL | PCF_FOLD_LINE \
                        |PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL \
-                       |PCF_HIDE_VALUE | PCF_SHOW_JSON)},
+                       |PCF_HIDE_VALUE | PCF_SHOW_JSON | PCF_MASTER_PP)},
+    {PCF_MASTER_PP, (PCF_FOLD_LINE \
+                    |PCF_HIDE_NAME | PCF_MAIN_OVER | PCF_SHOW_EVAL \
+                    |PCF_HIDE_VALUE | PCF_SHOW_JSON | PCF_MASTER_PARAM)},
     {PCF_SHOW_JSON, (PCF_MAIN_PARAM | PCF_MASTER_ENTRY | PCF_MASTER_FLD \
                     |PCF_MASTER_PARAM | PCF_MAIN_OVER | PCF_SHOW_EVAL \
                     |PCF_SHOW_NONDEF | PCF_SHOW_DEFS)},
@@ -746,6 +755,7 @@ static const NAME_MASK pcf_compat_names[] = {
     "-x", PCF_SHOW_EVAL,
     "-X", PCF_EDIT_EXCL,
     "-#", PCF_COMMENT_OUT,
+    "-PP", PCF_MASTER_PP,
     0,
 };
 
@@ -947,7 +957,10 @@ int     main(int argc, char **argv)
            pcf_cmd_mode |= PCF_MAIN_PARAM;
            break;
        case 'P':
-           pcf_cmd_mode |= PCF_MASTER_PARAM;
+           if (pcf_cmd_mode & PCF_MASTER_PARAM)
+               pcf_cmd_mode |= PCF_MASTER_PP;
+           else
+               pcf_cmd_mode |= PCF_MASTER_PARAM;
            break;
        case 'q':
            pcf_cmd_mode &= ~(PCF_WARN_UNUSED_DEPRECATED);
@@ -1074,8 +1087,8 @@ int     main(int argc, char **argv)
            pcf_show_master_fields(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
                                   argv + optind);
        else if (pcf_cmd_mode & PCF_MASTER_PARAM)
-           pcf_show_master_params(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
-                                  argv + optind);
+           pcf_show_master_params(VSTREAM_OUT, pcf_cmd_mode, param_class,
+                                  argc - optind, argv + optind);
        else
            pcf_show_master_entries(VSTREAM_OUT, pcf_cmd_mode, argc - optind,
                                    argv + optind);
index 9415f6f6c98df6dee36356492d67d841c4224997..6ee26262e7b8fdee36bd6dc9887f697c492723ea 100644 (file)
@@ -48,6 +48,7 @@
 #define PCF_SHOW_TLS           (1<<21) /* TLS support introspection */
 #define PCF_WARN_UNUSED_DEPRECATED (1<<22)     /* As the name says */
 #define PCF_SHOW_JSON          (1 << 23)       /* JSON output */
+#define PCF_MASTER_PP          (1<<24) /* multiple -P */
 
 #define PCF_DEF_MODE   (PCF_WARN_UNUSED_DEPRECATED)
 
@@ -202,7 +203,7 @@ extern void pcf_print_master_entry(VSTREAM *, int, PCF_MASTER_ENT *);
 extern void pcf_free_master_entry(PCF_MASTER_ENT *);
 extern void pcf_show_master_fields(VSTREAM *, int, int, char **);
 extern void pcf_edit_master_field(PCF_MASTER_ENT *, int, const char *);
-extern void pcf_show_master_params(VSTREAM *, int, int, char **);
+extern void pcf_show_master_params(VSTREAM *, int, int, int, char **);
 extern void pcf_edit_master_param(PCF_MASTER_ENT *, int, const char *, const char *);
 
 #define PCF_WARN_ON_OPEN_ERROR 0
index 5185681e72d03e1820a1ce08d3581a932f97d00d..18e3e16efb69308bea0950649b03ff5ae1a5e935 100644 (file)
@@ -152,6 +152,17 @@ static const char *pcf_lookup_parameter_value_wrapper(const char *key,
                                       (PCF_PARAM_NODE *) 0));
 }
 
+/* pcf_dont_parse_parameter_value - disable recursion for raw parameters */
+
+static bool pcf_dont_parse_parameter_value(const char *key, void *unused_context)
+{
+    PCF_PARAM_NODE *node;
+
+    /* Only built-in parameters can be 'raw'. No need to inspect local_scope. */
+    return ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, key)) != 0
+           && PCF_RAW_PARAMETER(node));
+}
+
 /* pcf_expand_parameter_value - expand $name in parameter value */
 
 char   *pcf_expand_parameter_value(VSTRING *buf, int mode, const char *value,
@@ -180,8 +191,9 @@ char   *pcf_expand_parameter_value(VSTRING *buf, int mode, const char *value,
 
     eval_ctx.mode = (mode & ~PCF_SHOW_NONDEF);
     eval_ctx.local_scope = local_scope;
-    status = mac_expand(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER,
-                   pcf_lookup_parameter_value_wrapper, (void *) &eval_ctx);
+    status = mac_expand7(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER,
+                        pcf_lookup_parameter_value_wrapper,
+                        pcf_dont_parse_parameter_value, (void *) &eval_ctx);
     if (status & MAC_PARSE_ERROR)
        msg_fatal("macro processing error");
     if (msg_verbose > 1) {
index 48061a10637d6590c222726689a39152230d5120..0be59f2fbab0f14a29ea65b3e1d45250f772e959 100644 (file)
 /*     int     field;
 /*     const char *new_value;
 /*
-/*     void    pcf_show_master_params(fp, mode, argc, **param_filters)
+/*     void    pcf_show_master_params(fp, mode, param_class, argc, **param_filters)
 /*     VSTREAM *fp;
 /*     int     mode;
+/*     int     param_class;
 /*     int     argc;
 /*     char    **param_filters;
 /*
@@ -63,7 +64,9 @@
 /*     or multi-column attribute.
 /*
 /*     pcf_show_master_params() writes name/type/parameter=value
-/*     records to the specified stream.
+/*     records to the specified stream. Like show_parameters(),
+/*     this may list either selected parameters, or all parameters that
+/*     match the param_class argument.
 /*
 /*     pcf_edit_master_param() updates, removes or adds the named
 /*     parameter in a master.cf entry (the remove request ignores
@@ -1106,14 +1109,69 @@ static int pcf_sort_argv_cb(const void *a, const void *b)
     return (strcmp(*(char **) a, *(char **) b));
 }
 
+/* merge_main_master_parameters - all parameters as sen by this service */
+
+static DICT *merge_main_master_parameters(int mode, PCF_MASTER_ENT *masterp,
+                                                 int param_class)
+{
+    DICT   *dict;
+    PCF_PARAM_INFO **main_list;
+    PCF_PARAM_INFO **main_ht;
+    const char *dict_spec = "merged_dict";
+    const char *param_name;
+    const char *param_value;
+    int     how;
+
+    /*
+     * With -PP, use the merged main/master.cf settings instead of
+     * masterp->allparams (the master.cf settings for this service).
+     */
+    dict = dict_ht_open(dict_spec, O_CREAT | O_RDWR, 0);
+    dict_register(dict_spec, dict);
+
+    /*
+     * For each parameter in the main.cf namespace, look up its effective
+     * value (from master.cf or main.cf, or use the default).
+     */
+    main_list = PCF_PARAM_TABLE_LIST(pcf_param_table);
+    for (main_ht = main_list; *main_ht; main_ht++) {
+       param_name = PCF_PARAM_INFO_NAME(*main_ht);
+       if (param_class && !(PCF_PARAM_INFO_NODE(*main_ht)->flags & param_class))
+           continue;
+       if ((param_value =
+            pcf_lookup_parameter_value(mode, param_name, masterp,
+                                       PCF_PARAM_INFO_NODE(*main_ht))) == 0)
+           msg_panic("%s: parameter name not found: %s", __func__, param_name);
+       dict->update(dict, param_name, param_value);
+    }
+    myfree((void *) main_list);
+
+    /*
+     * Add master.cf settings with service-specific custom names. Skip
+     * settings that were already copied in the above loop.
+     */
+    if (masterp->all_params) {
+       DICT   *all_params = masterp->all_params;
+
+       for (how = DICT_SEQ_FUN_FIRST;
+            all_params->sequence(all_params, how, &param_name,
+                                 &param_value) == 0;
+            how = DICT_SEQ_FUN_NEXT) {
+           if (dict->lookup(dict, param_name) == 0)
+               dict->update(dict, param_name, param_value);
+       }
+    }
+    return (dict);
+}
+
 /* pcf_show_master_any_param - show any parameter in master.cf service entry */
 
 static void pcf_show_master_any_param(VSTREAM *fp, int mode,
-                                             PCF_MASTER_ENT *masterp)
+                                             PCF_MASTER_ENT *masterp,
+                                             DICT *dict)
 {
     const char *myname = "pcf_show_master_any_param";
     ARGV   *argv = argv_alloc(10);
-    DICT   *dict = masterp->all_params;
     const char *param_name;
     const char *param_value;
     int     param_count = 0;
@@ -1152,7 +1210,8 @@ static void pcf_show_master_any_param(VSTREAM *fp, int mode,
 
 /* pcf_show_master_params - show master.cf params */
 
-void    pcf_show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
+void    pcf_show_master_params(VSTREAM *fp, int mode, int param_class,
+                                      int argc, char **argv)
 {
     PCF_MASTER_ENT *masterp;
     PCF_MASTER_FLD_REQ *field_reqs;
@@ -1181,14 +1240,20 @@ void    pcf_show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
      * Iterate over the master table.
      */
     for (masterp = pcf_master_table; masterp->argv != 0; masterp++) {
-       if ((dict = masterp->all_params) != 0) {
+       if (mode & PCF_MASTER_PP) {
+           dict = merge_main_master_parameters(mode, masterp,
+                                               argc > 0 ? 0 : param_class);
+       } else {
+           dict = masterp->all_params;
+       }
+       if (dict != 0) {
            if (argc > 0) {
                for (req = field_reqs; req < field_reqs + argc; req++) {
                    if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
                                                  masterp->argv->argv[0],
                                                  masterp->argv->argv[1])) {
                        if (PCF_IS_MAGIC_PARAM_PATTERN(req->param_pattern)) {
-                           pcf_show_master_any_param(fp, mode, masterp);
+                           pcf_show_master_any_param(fp, mode, masterp, dict);
                            req->match_count += 1;
                        } else if ((param_value = dict_get(dict,
                                                req->param_pattern)) != 0) {
@@ -1200,9 +1265,11 @@ void    pcf_show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
                    }
                }
            } else {
-               pcf_show_master_any_param(fp, mode, masterp);
+               pcf_show_master_any_param(fp, mode, masterp, dict);
            }
        }
+       if (mode & PCF_MASTER_PP)
+           dict_close(dict);
     }
 
     /*
index 46f4d61807df5b18fc0d33c03174a72314aebe0a..fdaf8442de63a8cdc3ced4af9c16c203c6017c01 100644 (file)
@@ -108,6 +108,7 @@ static HTABLE *pcf_rest_class_table;
     PCF_PARAM_CTX _ctx; \
     _ctx.local_scope = (scope); \
     _ctx.param_class = (class); \
+    /* No MAC_EXP_FLAG_RECURSE, therefore no need for DONT_PARSE feature. */ \
     (void) mac_expand(NO_SCAN_RESULT, (value), MAC_EXP_FLAG_SCAN, \
            NO_SCAN_FILTER, pcf_flag_user_parameter_wrapper, (void *) &_ctx); \
 } while (0)
diff --git a/postfix/src/postconf/test91.ref b/postfix/src/postconf/test91.ref
new file mode 100644 (file)
index 0000000..26f354d
--- /dev/null
@@ -0,0 +1,3 @@
+foo/unix/proxy_write_maps = foo_map
+bar/unix/proxy_write_maps = bar_map
+baz/unix/proxy_write_maps = baz_map
index c3afed605e0f24cbb6a8e9d83e57b3b108b54738..a00612bf5e3200445a6a0e7fbeb9e8c8850e4ee4 100644 (file)
@@ -6,14 +6,24 @@
 /* SYNOPSIS
 /*     #include <mac_expand.h>
 /*
-/*     int     mac_expand(result, pattern, flags, filter, lookup, context)
+/*     int     mac_expand7(result, pattern, flags, filter, lookup,
+/*                             dont_expand, context)
 /*     VSTRING *result;
 /*     const char *pattern;
 /*     int     flags;
 /*     const char *filter;
 /*     const char *lookup(const char *key, int mode, void *context)
+/*     const bool dont_parse(const char *key, void *context)
 /*     void *context;
 /* AUXILIARY FUNCTIONS
+/*     int     mac_expand(result, pattern, flags, filter, lookup, context)
+/*     VSTRING *result;
+/*     const char *pattern;
+/*     int     flags;
+/*     const char *filter;
+/*     const char *lookup(const char *key, int mode, void *context)
+/*     void *context;
+/*
 /*     typedef MAC_EXP_OP_RES (*MAC_EXPAND_RELOP_FN) (
 /*     const char *left,
 /*     int     tok_val,
 /*     or MAC_EXP_MODE_USE to use the value of the named attribute,
 /*     and the caller context that was given to mac_expand(). A null
 /*     result value means that the requested attribute was not defined.
+/* .IP don_parse
+/*     An optional function that disables the MAC_EXP_FLAG_RECURSE
+/*     feature with lookup() results for a specific attribute. Arguments
+/*     are: the attribute name, and the caller context that was given
+/*     to mac_expand(). Specify null to disable this feature.
 /* .IP context
-/*     Caller context that is passed on to the attribute lookup routine.
+/*     Caller context that is passed on to the attribute lookup and
+/*     don_parse routines.
 /* .PP
 /*     mac_expand_add_relop() registers a function that implements
 /*     support for custom relational operators. Custom operator names
@@ -220,6 +236,7 @@ typedef struct {
     int     flags;                     /* features */
     const char *filter;                        /* character filter */
     MAC_EXP_LOOKUP_FN lookup;          /* lookup routine */
+    MAC_EXP_DONT_PARSE_FN dont_parse;  /* veto routine */
     void   *context;                   /* caller context */
     int     status;                    /* findings */
     int     level;                     /* nesting level */
@@ -657,6 +674,7 @@ static int mac_expand_callback(int type, VSTRING *buf, void *ptr)
     ssize_t tmp_len;
     const char *res_iftrue;
     const char *res_iffalse;
+    int     dont_parse = false;
 
     /*
      * Sanity check.
@@ -735,6 +753,8 @@ static int mac_expand_callback(int type, VSTRING *buf, void *ptr)
             * Look up the named parameter. Todo: allow the lookup function
             * to specify if the result is safe for $name expansion.
             */
+           if (mc->dont_parse)
+               dont_parse = mc->dont_parse(start, mc->context);
            lookup = mc->lookup(start, lookup_mode, mc->context);
        }
 
@@ -789,7 +809,7 @@ static int mac_expand_callback(int type, VSTRING *buf, void *ptr)
                mc->status |= MAC_PARSE_UNDEF;
            } else if (*lookup == 0 || (mc->flags & MAC_EXP_FLAG_SCAN)) {
                 /* void */ ;
-           } else if (mc->flags & MAC_EXP_FLAG_RECURSE) {
+           } else if ((mc->flags & MAC_EXP_FLAG_RECURSE) && !dont_parse) {
                vstring_strcpy(buf, lookup);
                mc->status |= mac_parse(vstring_str(buf), mac_expand_callback,
                                        (void *) mc);
@@ -821,12 +841,29 @@ static int mac_expand_callback(int type, VSTRING *buf, void *ptr)
     return (mc->status);
 }
 
+ /*
+  * ABI compatibility wrapper.
+  */
+#undef mac_expand
+int     mac_expand(VSTRING *, const char *, int, const char *,
+                          MAC_EXP_LOOKUP_FN, void *);
+
 /* mac_expand - expand $name instances */
 
 int     mac_expand(VSTRING *result, const char *pattern, int flags,
                           const char *filter,
                           MAC_EXP_LOOKUP_FN lookup, void *context)
 {
+    return (mac_expand7(result, pattern, flags, filter, lookup,
+                       (MAC_EXP_DONT_PARSE_FN) 0, context));
+}
+
+int     mac_expand7(VSTRING *result, const char *pattern, int flags,
+                           const char *filter,
+                           MAC_EXP_LOOKUP_FN lookup,
+                           MAC_EXP_DONT_PARSE_FN dont_parse, void *context)
+{
+
     MAC_EXP_CONTEXT mc;
     int     status;
 
@@ -837,6 +874,7 @@ int     mac_expand(VSTRING *result, const char *pattern, int flags,
     mc.flags = flags;
     mc.filter = filter;
     mc.lookup = lookup;
+    mc.dont_parse = dont_parse;
     mc.context = context;
     mc.status = 0;
     mc.level = 0;
index 70954e602d22e06c6f4afcb2ec78afec480ef761..17adb9d9c77bb655ef767539fbed60e41b23f092 100644 (file)
@@ -57,13 +57,18 @@ extern MAC_EXP_OP_RES mac_exp_op_res_bool[2];
 #define MAC_EXP_MODE_USE       (1)
 
 typedef const char *(*MAC_EXP_LOOKUP_FN) (const char *, int, void *);
+typedef bool(*MAC_EXP_DONT_PARSE_FN) (const char *, void *);
 typedef MAC_EXP_OP_RES(*MAC_EXPAND_RELOP_FN) (const char *, int, const char *);
 typedef int (*MAC_EXPAND_NAMED_FN) (VSTRING *, const char *);
 
-extern int mac_expand(VSTRING *, const char *, int, const char *, MAC_EXP_LOOKUP_FN, void *);
+extern int mac_expand7(VSTRING *, const char *, int, const char *, MAC_EXP_LOOKUP_FN, MAC_EXP_DONT_PARSE_FN, void *);
 extern void mac_expand_add_relop(int *, const char *, MAC_EXPAND_RELOP_FN);
 extern void mac_expand_add_named_fn(const char *, MAC_EXPAND_NAMED_FN);
 
+#define mac_expand(res, pat, flags, filter, lookup, ctx) \
+    mac_expand7((res), (pat), (flags), (filter), (lookup), \
+       (MAC_EXP_DONT_PARSE_FN) 0, (ctx))
+
 /* LICENSE
 /* .ad
 /* .fi