]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20010414
authorWietse Venema <wietse@porcupine.org>
Sat, 14 Apr 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:14 +0000 (06:27 +0000)
31 files changed:
postfix/HISTORY
postfix/INSTALL
postfix/SASL_README
postfix/conf/postfix-script-nosgid
postfix/conf/postfix-script-sgid
postfix/conf/sample-local.cf
postfix/conf/sample-misc.cf
postfix/html/basic.html
postfix/html/faq.html
postfix/html/pcre_table.5.html
postfix/html/postalias.1.html
postfix/html/postmap.1.html
postfix/html/regexp_table.5.html
postfix/man/man1/postalias.1
postfix/man/man1/postmap.1
postfix/man/man5/pcre_table.5
postfix/man/man5/regexp_table.5
postfix/proto/pcre_table
postfix/proto/regexp_table
postfix/src/global/mail_version.h
postfix/src/master/master.h
postfix/src/master/master_ent.c
postfix/src/postalias/postalias.c
postfix/src/postmap/postmap.c
postfix/src/smtp/smtp_addr.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/dict_db.c
postfix/src/util/dict_dbm.c
postfix/src/util/dict_ldap.c
postfix/src/util/dict_mysql.c

index a3a8eb3ae65aba76133b9fb53f59f4a60d6c831a..b9fd3d3e96dfeaf488594b47759ada92467c5fe4 100644 (file)
@@ -5031,3 +5031,49 @@ Apologies for any names omitted.
        before the server has received the client's data.  Files:
        util/{inet,unix,stream}_trigger.c, util/events.c,
        master/master_trigger.c, postkick/postkick.c.
+
+20010403
+
+       Workaround: the mysql library can return null pointers
+       rather than zero-length strings.
+
+20010404
+
+       Logging: log additional information about why "mail for
+       XXX loops back to myself", when the local machine is the
+       best MX host. File: smtp/smtp_addr.c.
+
+20010406
+
+       Changed some noisy LDAP client warnings into optional
+       logging. LaMont Jones, util/dict_ldap.c.
+
+20010411
+
+       Compatibility: the SMTP server now replies with 550 instead
+       of 503 when it receives the DATA command without having
+       received a valid recipient address. This is needed for the
+       Sendmail client-side pipelining implementation. Problem
+       reported by Lutz Jaenicke. File: smtpd/smtpd.c.
+
+       Cleanup: shut up if chattr fails on Reiserfs and other file
+       systems that do not support the respective attributes.
+       Files: conf/postfix-script-{no,}sgid.
+
+20010413
+
+       Ergonomics: Postfix applications now warn when a DB or DBM
+       file is out of date, and recommends to re-run postmap or
+       postalias. Files: util/dict_db.c, util/dict_dbm.c.
+
+20010414
+
+       Feature: specify a key of "-" to the postmap or postalias
+       -q or -d option, and the keys will be read from standard
+       input, one key per line. Files: postmap/postmap.c,
+       postalias/postalias.c.
+
+       Bugfix: with a non-default inet_interfaces setting, the
+       master daemon ignored host information in explicit host:port
+       settings in master.cf.  Fix by Jun-ichiro itojun Hagino @
+       iijlab.net.  Files: master/master.h, master/master_ent.c.
index 427a4528ce8c549b1132753d5b5096e062690dcf..f75095ad6a9920e3ff46940c4c57264fe9d746ef 100644 (file)
@@ -67,9 +67,9 @@ If your system is supported, it is one of
     Linux RedHat 5.x
     Linux RedHat 6.x
     Linux RedHat 7.x
-    Linux Slackware 3.5
-    Linux Slackware 4.0
-    Linux Slackware 7.0
+    Linux Slackware 3.x
+    Linux Slackware 4.x
+    Linux Slackware 7.x
     Linux SuSE 5.x
     Linux SuSE 6.x
     Linux SuSE 7.x
index 801d4f9afa5eeb43221bee1cc15a674871f5a4d4..a976da9c8ac38b39c985de5762a0049df0ec5932 100644 (file)
@@ -62,14 +62,8 @@ Reportedly, Microsoft Internet Explorer version 5 requires the
 non-standard SASL LOGIN authentication method. To enable this
 authentication method, specify ``./configure --enable-login''.
 
-Older Microsoft SMTP client software implements a non-standard 
-version of the AUTH protocol syntax, and expects that the SMTP
-server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH
-stuff".  To accomodate such clients in addition to conformant
-clients, set "broken_sasl_auth_clients = yes" in the main.cf file.
-
-The Postfix SMTP client is backwards compatible with SMTP servers
-that use the non-standard AUTH protocol syntax.
+If you install the Cyrus SASL libraries as per the default, you
+will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
 
 Building Postfix with SASL authentication support
 =================================================
@@ -94,9 +88,6 @@ otherwise ld.so will not find the SASL shared library:
 Enabling SASL authentication in the Postfix SMTP server
 =======================================================
 
-If you installed the Cyrus SASL libraries as per the default, you
-will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
-
 See conf/sample-auth.cf for examples. 
 
 In order to enable SASL support in the SMTP server:
@@ -141,6 +132,12 @@ EXAMPLE: saslpasswd -c -u `postconf -h myhostname` exampleuser
 To run software chrooted with SASL support is an interesting
 exercise.  It probably is not worth the trouble.
 
+Older Microsoft SMTP client software implements a non-standard 
+version of the AUTH protocol syntax, and expects that the SMTP
+server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH
+stuff".  To accomodate such clients in addition to conformant
+clients, set "broken_sasl_auth_clients = yes" in the main.cf file.
+
 Testing SASL authentication in the Postfix SMTP server
 ======================================================
 
@@ -192,3 +189,8 @@ remote part of an email address).
 The SASL client password file is opened before the SMTP server
 enters the optional chroot jail, so you can keep the file in
 /etc/postfix.
+
+The Postfix SMTP client is backwards compatible with SMTP servers
+that use the non-standard AUTH=stuff... syntax in response to the
+EHLO command.
+
index d102a0e3bcc8fa0de6084b8c6afa2b6e4da044bb..f845366758eeb0ecb32b03105fc9bc7f81090a17 100755 (executable)
@@ -193,7 +193,7 @@ check)
                test -d $dir || {
                        $WARN creating missing Postfix $dir directory
                        mkdir $dir || exit 1
-                       chmod 700 $dir; $CHATTR $dir
+                       chmod 700 $dir; $CHATTR $dir 2>/dev/null
                        chown $mail_owner $dir
                }
        done
index d436e4df33b0033ae05a99169de709d73b607475..53bcf6303733f13dad4f04e204f36706e5ac545d 100755 (executable)
@@ -194,7 +194,7 @@ check)
                test -d $dir || {
                        $WARN creating missing Postfix $dir directory
                        mkdir $dir || exit 1
-                       chmod 700 $dir; $CHATTR $dir
+                       chmod 700 $dir; $CHATTR $dir 2>/dev/null
                        chown $mail_owner $dir
                }
        done
index f8ac3329ab876d0beea1cfd8f566adc9eea5de34..285ac244816d298fa2631f1c06f10b623da460eb 100644 (file)
@@ -219,12 +219,13 @@ local_destination_recipient_limit = 1
 
 # DELIVERED-TO
 #
-# The prepend_delivered_header controls when Postfix should prepend 
-# a Delivered-To: message header.  
+# The prepend_delivered_header controls when the Postfix local delivery
+# agent should prepend a Delivered-To: message header.
 #
-# By default, Postfix prepends a Delivered-To: header when forwarding
-# mail and when delivering to file (mailbox) and command. Turning off
-# the Delivered-To: header when forwarding mail is not recommended.
+# By default, the Postfix local delivery agent prepends a Delivered-To:
+# header when forwarding mail and when delivering to file (mailbox)
+# and command. Turning off the Delivered-To: header when forwarding
+# mail is not recommended.
 #
 # prepend_delivered_header = command, file, forward
 # prepend_delivered_header = forward
index 9f395f898b2e916161e616e6c7aa9d8597070896..6de9867251e057ff823fa9e8129943ac2bd60206 100644 (file)
@@ -99,7 +99,7 @@ hopcount_limit = 50
 # Specify a list of names separated by whitespace or comma.
 #
 # import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS
-import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY
+import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY
 
 # The inet_interfaces parameter specifies the network interface
 # addresses that this mail system receives mail on.  By default,
index 3333296b739fc64615c3978d83815801922c8ec7..7e38a8d6c454cdf33c7d1eb185bbf747aba00db9 100644 (file)
@@ -19,7 +19,7 @@ href="rewrite.html"> Address Manipulation </a>
 
 <h2> Introduction </h2>
 
-Postfix has about 100 configuration parameters that are controlled
+Postfix has several hundred configuration parameters that are controlled
 via the <b>main.cf</b> file.  Fortunately, they have sensible
 default values.  In most cases, you need to configure only two or
 three parameters before you can use the Postfix mail system:
@@ -39,11 +39,11 @@ three parameters before you can use the Postfix mail system:
 </ul>
 
 The default values for many other configuration parameters are
-derived from just these two.
+derived from just these.
 
 <p>
 
-The third parameter of interest controls the amount of mail sent
+The next parameter of interest controls the amount of mail sent
 to the local postmaster:
 
 <ul>
index d6508911367454eea920e38af4bf6d74458c7bbd..6c0b216b042b45157a399e67b0738f4c5453fa80 100644 (file)
@@ -82,6 +82,8 @@
 
 <li><a href="#whoami">sendmail: unable to find out your login name</a>
 
+<li><a href="#paranoid">warning: xxx.xxx.xxx.xxx: address not listed
+for hostname yyy.yyy.yyy</a>
 
 <li><a href="#unknown_virtual_loop">Mail for unknown users in
 virtual domains fails with "mail loops back to myself"</a>
@@ -169,6 +171,9 @@ distribution list</a>
 <li><a href="#numerical_log">Postfix logs SMTP clients as IP
 addresses</a>
 
+<li><a href="#paranoid">warning: xxx.xxx.xxx.xxx: address not listed
+for hostname yyy.yyy.yyy</a>
+
 </ul>
 
 <a name="relaying"><h3>Mail relaying</h3>
@@ -249,7 +254,7 @@ distribution list</a>
 
 <li><a href="#owner-foo">Postfix ignores the owner-list alias</a>
 
-<li><a href="#virtual_command">Commands and mailing lists don't work in Postfix virtual maps</a>
+<li><a href="#virtual_command">Commands, mailing lists, and /file/name destinations don't work in Postfix virtual maps</a>
 
 </ul>
 
@@ -266,7 +271,7 @@ virtual domains fails with "mail loops back to myself"</a>
 <li><a href="#virtual_relay">Postfix refuses mail for virtual
 domains with "relay access denied"</a>
 
-<li><a href="#virtual_command">Commands and mailing lists don't work in Postfix virtual maps</a>
+<li><a href="#virtual_command">Commands, mailing lists, and /file/name destinations don't work in Postfix virtual maps</a>
 
 <li><a href="#domain_mailbox">Receiving a virtual domain in a
 mailbox</a>
@@ -1257,6 +1262,43 @@ directory of the Postfix source code distribution.
 
 <hr>
 
+<a name="paranoid"><h3>warning: xxx.xxx.xxx.xxx: address not listed
+for hostname yyy.yyy.yyy</h3>
+
+Postfix uses hostnames in its junk mail and mail relay controls.
+This means that in theory someone could be motivated to set up
+bogus DNS information, in order to get past your junk mail or mail
+relay controls.
+
+<p>
+
+When Postfix looks up the SMTP client hostname for the SMTP client
+IP address, then Postfix also checks if the SMTP client IP address
+is listed under the SMTP client hostname.
+
+<p>
+
+If the SMTP client IP address is not listed under the SMTP client
+hostname, then Postfix concludes that the SMTP client hostname does
+not belong to the SMTP client IP address, and ignores the SMTP
+client hostname. A warning is logged, so that you can find out why
+an SMTP client is or is not stopped by your junk mail or mail relay
+checks.
+
+<p>
+
+You could contact the people who maintain the SMTP client's DNS
+records, and explain to them that each IP address needs one PTR
+record, and that this one PTR record needs a matching A record.
+
+<p>
+
+Some people read the RFCs such that one IP address can have multiple
+PTR records, but that makes PTR records even less useful than they
+already are. And in any case, having multiple names per IP address
+would only worsen the problem of finding out the "official name"
+of a machine's IP address.
+
 <a name="open_relay"><h3>Help! Postfix is an open relay</h3>
 
 According to some relay checking software, Postfix accepts
@@ -2416,12 +2458,12 @@ virtual</a> manual page.
 
 <hr>
 
-<a name="virtual_command"><h3>Commands and mailing lists don't work
+<a name="virtual_command"><h3>Commands, mailing, and /file/name destinations don't work
 in Postfix virtual maps</h3>
 
 Short reply: specify a Sendmail-style <a href="virtual.5.html">virtual</a>
-domain, and specify the command or mailing list in the local <a
-href="aliases.5.html">aliases</a> file.
+domain, and specify the command, mailing list, or /file/name
+destination in the local <a href="aliases.5.html">aliases</a> file.
 
 <p>
 
@@ -2429,17 +2471,18 @@ Long reply follows.
 
 <p>
 
-Delivering mail to a command is a security-sensitive operation,
-because the command must be executed with the right privileges.
-Only <b>root</b>-privileged software such as the Postfix local
-delivery agent can set the privileges for a command.
+Delivering mail to a file or command is a security-sensitive
+operation, because the operation must be executed with the right
+privileges.  Only <b>root</b>-privileged software such as the
+Postfix local delivery agent can set the privileges for command
+or file delivery.
 
 <p>
 
 For security reasons, Postfix tries to avoid using <b>root</b>
 privileges where possible. In particular, Postfix virtual mapping
 is done by an unprivileged daemon, so there is no secure way to
-execute commands found in virtual maps.
+execute commands or to deliver to files found in virtual maps.
 
 <hr>
 
index d27e0bb449fe6eb368ea60dffda1a9e2b98ab442..b04bc607b741dc9c2e68f3d21453090459024028 100644 (file)
@@ -47,13 +47,13 @@ PCRE_TABLE(5)                                       PCRE_TABLE(5)
        is `U', which makes matching ungreedy (see PCRE documenta-
        tion and source for more info).
 
-       Each  pattern is applied to the entire string being looked
-       up.  Depending on  the  application,  that  string  is  an
-       entire client hostname, an entire client IP address, or an
-       entire mail address.  Thus, no  parent  domain  or  parent
-       network search is done, and <i>user@domain</i> mail addresses are
-       not broken up  into  their  <i>user</i>  and  <i>domain</i>  constituent
-       parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
+       Each  pattern  is applied to the entire lookup key string.
+       Depending on the application, that  string  is  an  entire
+       client hostname, an entire client IP address, or an entire
+       mail address.  Thus, no parent domain  or  parent  network
+       search  is  done,  and  <i>user@domain</i> mail addresses are not
+       broken up into their <i>user</i> and  <i>domain</i>  constituent  parts,
+       nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Patterns  are  applied  in  the  order as specified in the
        table, until a pattern is found that  matches  the  search
@@ -71,11 +71,11 @@ PCRE_TABLE(5)                                       PCRE_TABLE(5)
 PCRE_TABLE(5)                                       PCRE_TABLE(5)
 
 
-       Substitution of sub-strings from the matched expression is
-       possible using  the  conventional  perl  syntax  ($1,  $2,
-       etc.). The macros in the replacement string may need to be
-       written as ${n} or $(n) if they aren't followed by whites-
-       pace.
+       Substitution  of  substrings  from  the matched expression
+       into the result string is possible using the  conventional
+       perl  syntax  ($1,  $2,  etc.).   The macros in the result
+       string may need to be written as  ${n}  or  $(n)  if  they
+       aren't followed by whitespace.
 
 <b>EXAMPLES</b>
        # Protect your outgoing majordomo exploders
index 4d6e097bb92a84f8de8756e91ada1a8c7430696f..329e173f61cefb69590826c5027e92ec1172cf88 100644 (file)
@@ -37,28 +37,28 @@ POSTALIAS(1)                                         POSTALIAS(1)
               directory.
 
        <b>-d</b> <i>key</i> Search the specified maps for <i>key</i>  and  remove  one
-              entry  per map.  The exit status is non-zero if the
-              requested information was not found.
+              entry  per  map.   The exit status is zero when the
+              requested information was found.
 
-       <b>-i</b>     Incremental mode. Read entries from standard  input
+              If a key value of <b>-</b> is specified, the program reads
+              key values from the standard input stream. The exit
+              status is zero when at least one of  the  requested
+              keys was found.
+
+       <b>-i</b>     Incremental  mode. Read entries from standard input
               and  do  not  truncate  an  existing  database.  By
-              default, <b>postalias</b> creates a new database from  the
+              default,  <b>postalias</b> creates a new database from the
               entries in <b>file</b><i>_</i><b>name</b>.
 
-       <b>-n</b>     Don't  include  the terminating null character that
-              terminates lookup  keys  and  values.  By  default,
-              Postfix  does  whatever is the default for the host
+       <b>-n</b>     Don't include the terminating null  character  that
+              terminates  lookup  keys  and  values.  By default,
+              Postfix does whatever is the default for  the  host
               operating system.
 
-       <b>-q</b> <i>key</i> Search the specified maps for  <i>key</i>  and  print  the
-              first  value  found  on the standard output stream.
-              The exit status is non-zero if the requested infor-
-              mation was not found.
-
-       <b>-r</b>     When  updating a table, do not warn about duplicate
-              entries; silently replace them.
-
-       <b>-v</b>     Enable  verbose  logging  for  debugging  purposes.
+       <b>-q</b> <i>key</i> Search  the  specified  maps  for <i>key</i> and print the
+              first value found on the  standard  output  stream.
+              The exit status is zero when the requested informa-
+              tion was found.
 
 
 
@@ -71,10 +71,20 @@ POSTALIAS(1)                                         POSTALIAS(1)
 POSTALIAS(1)                                         POSTALIAS(1)
 
 
-              Multiple  <b>-v</b> options make the software increasingly
+              If a key value of <b>-</b> is specified, the program reads
+              key  values  from  the  standard  input  stream and
+              prints one line of <i>key:</i> <i>value</i> output for  each  key
+              that  was  found.  The  exit status is zero when at
+              least one of the requested keys was found.
+
+       <b>-r</b>     When updating a table, do not warn about  duplicate
+              entries; silently replace them.
+
+       <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
+              tiple <b>-v</b> options  make  the  software  increasingly
               verbose.
 
-       <b>-w</b>     When updating a table, do not warn about  duplicate
+       <b>-w</b>     When  updating a table, do not warn about duplicate
               entries; silently ignore them.
 
        Arguments:
@@ -82,68 +92,67 @@ POSTALIAS(1)                                         POSTALIAS(1)
        <i>file_type</i>
               The type of database to be produced.
 
-              <b>btree</b>  The   output   is   a   btree   file,  named
-                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
+              <b>btree</b>  The  output   is   a   btree   file,   named
+                     <i>file_name</i><b>.db</b>.   This  is  available  only on
                      systems with support for <b>db</b> databases.
 
-              <b>dbm</b>    The  output  consists  of  two  files, named
-                     <i>file_name</i><b>.pag</b> and  <i>file_name</i><b>.dir</b>.   This  is
-                     available  only  on systems with support for
+              <b>dbm</b>    The output  consists  of  two  files,  named
+                     <i>file_name</i><b>.pag</b>  and  <i>file_name</i><b>.dir</b>.   This is
+                     available only on systems with  support  for
                      <b>dbm</b> databases.
 
-              <b>hash</b>   The  output  is   a   hashed   file,   named
-                     <i>file_name</i><b>.db</b>.   This  is  available  only on
+              <b>hash</b>   The   output   is   a   hashed  file,  named
+                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
                      systems with support for <b>db</b> databases.
 
-              When no <i>file_type</i> is specified, the  software  uses
-              the  database  type specified via the <b>database</b><i>_</i><b>type</b>
-              configuration parameter.   The  default  value  for
+              When  no  <i>file_type</i> is specified, the software uses
+              the database type specified via  the  <b>database</b><i>_</i><b>type</b>
+              configuration  parameter.   The  default  value for
               this parameter depends on the host environment.
 
        <i>file_name</i>
-              The  name  of  the  alias database source file when
+              The name of the alias  database  source  file  when
               rebuilding a database.
 
 <b>DIAGNOSTICS</b>
-       Problems are logged to the standard error stream. No  out-
+       Problems  are logged to the standard error stream. No out-
        put means no problems were detected. Duplicate entries are
        skipped and are flagged with a warning.
 
        <b>postalias</b> terminates with zero exit status in case of suc-
-       cess  (including  successful <b>postmap</b> <b>-q</b> lookup) and termi-
+       cess (including successful <b>postmap</b> <b>-q</b> lookup)  and  termi-
        nates with non-zero exit status in case of failure.
 
 <b>BUGS</b>
-       The "delete key" support is limited to one  delete  opera-
-       tion per command invocation.
+       The   "delete  key"  support  is  limited  to  one  delete
 
-<b>ENVIRONMENT</b>
-       <b>MAIL</b><i>_</i><b>CONFIG</b>
-              Directory with Postfix configuration files.
 
-       <b>MAIL</b><i>_</i><b>VERBOSE</b>
-              Enable verbose logging for debugging purposes.
 
+                                                                2
 
 
 
 
-                                                                2
-
 
+POSTALIAS(1)                                         POSTALIAS(1)
 
 
+       operation per command invocation.
 
-POSTALIAS(1)                                         POSTALIAS(1)
+<b>ENVIRONMENT</b>
+       <b>MAIL</b><i>_</i><b>CONFIG</b>
+              Directory with Postfix configuration files.
 
+       <b>MAIL</b><i>_</i><b>VERBOSE</b>
+              Enable verbose logging for debugging purposes.
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
        details and for default values.
 
        <b>database</b><i>_</i><b>type</b>
-              Default  alias database type. On many UNIX systems,
+              Default alias database type. On many UNIX  systems,
               the default type is either <b>dbm</b> or <b>hash</b>.
 
 <b>STANDARDS</b>
@@ -154,7 +163,7 @@ POSTALIAS(1)                                         POSTALIAS(1)
        <a href="sendmail.1.html">sendmail(1)</a> mail posting and compatibility interface.
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
@@ -175,15 +184,6 @@ POSTALIAS(1)                                         POSTALIAS(1)
 
 
 
-
-
-
-
-
-
-
-
-
 
 
 
index 77833681c9d00f26edda53ff9366216144223bd2..5b541d105f42b3c18f56e1bcfcb6bfed0af85f5e 100644 (file)
@@ -56,8 +56,8 @@ POSTMAP(1)                                             POSTMAP(1)
               directory.
 
        <b>-d</b> <i>key</i> Search  the  specified  maps for <i>key</i> and remove one
-              entry per map.  The exit status is non-zero if  the
-              requested information was not found.
+              entry per map.  The exit status is  zero  when  the
+              requested information was found.
 
 
 
@@ -71,29 +71,40 @@ POSTMAP(1)                                             POSTMAP(1)
 POSTMAP(1)                                             POSTMAP(1)
 
 
-       <b>-i</b>     Incremental  mode. Read entries from standard input
+              If a key value of <b>-</b> is specified, the program reads
+              key values from the standard input stream. The exit
+              status  is  zero when at least one of the requested
+              keys was found.
+
+       <b>-i</b>     Incremental mode. Read entries from standard  input
               and  do  not  truncate  an  existing  database.  By
-              default,  <b>postmap</b>  creates  a new database from the
+              default, <b>postmap</b> creates a new  database  from  the
               entries in <b>file</b><i>_</i><b>name</b>.
 
-       <b>-n</b>     Don't include the terminating null  character  that
-              terminates  lookup  keys  and  values.  By default,
-              Postfix does whatever is the default for  the  host
+       <b>-n</b>     Don't  include  the terminating null character that
+              terminates lookup  keys  and  values.  By  default,
+              Postfix  does  whatever is the default for the host
               operating system.
 
-       <b>-q</b> <i>key</i> Search  the  specified  maps  for <i>key</i> and print the
-              first value found on the  standard  output  stream.
-              The exit status is non-zero if the requested infor-
-              mation was not found.
+       <b>-q</b> <i>key</i> Search the specified maps for  <i>key</i>  and  print  the
+              first  value  found  on the standard output stream.
+              The exit status is zero when the requested informa-
+              tion was found.
+
+              If a key value of <b>-</b> is specified, the program reads
+              key values  from  the  standard  input  stream  and
+              prints  one  line  of <i>key</i> <i>value</i> output for each key
+              that was found. The exit status  is  zero  when  at
+              least one of the requested keys was found.
 
-       <b>-r</b>     When updating a table, do not warn about  duplicate
+       <b>-r</b>     When  updating a table, do not warn about duplicate
               entries; silently replace them.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple <b>-v</b> options  make  the  software  increasingly
+              tiple  <b>-v</b>  options  make  the software increasingly
               verbose.
 
-       <b>-w</b>     When  updating a table, do not warn about duplicate
+       <b>-w</b>     When updating a table, do not warn about  duplicate
               entries; silently ignore them.
 
        Arguments:
@@ -101,30 +112,19 @@ POSTMAP(1)                                             POSTMAP(1)
        <i>file_type</i>
               The type of database to be produced.
 
-              <b>btree</b>  The output  file  is  a  btree  file,  named
-                     <i>file_name</i><b>.db</b>.   This  is  available  only on
+              <b>btree</b>  The  output  file  is  a  btree  file, named
+                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
                      systems with support for <b>db</b> databases.
 
-              <b>dbm</b>    The output  consists  of  two  files,  named
-                     <i>file_name</i><b>.pag</b>  and  <i>file_name</i><b>.dir</b>.   This is
-                     available only on systems with  support  for
+              <b>dbm</b>    The  output  consists  of  two  files, named
+                     <i>file_name</i><b>.pag</b> and  <i>file_name</i><b>.dir</b>.   This  is
+                     available  only  on systems with support for
                      <b>dbm</b> databases.
 
-              <b>hash</b>   The  output  file  is  a  hashed file, named
-                     <i>file_name</i><b>.db</b>.  This  is  available  only  on
+              <b>hash</b>   The output file  is  a  hashed  file,  named
+                     <i>file_name</i><b>.db</b>.   This  is  available  only on
                      systems with support for <b>db</b> databases.
 
-              When  no  <i>file_type</i> is specified, the software uses
-              the database type specified via  the  <b>database</b><i>_</i><b>type</b>
-              configuration parameter.
-
-       <i>file_name</i>
-              The  name  of  the  lookup  table  source file when
-              rebuilding a database.
-
-<b>DIAGNOSTICS</b>
-       Problems and transactions are logged to the standard error
-       stream. No output means no problems. Duplicate entries are
 
 
 
@@ -137,14 +137,25 @@ POSTMAP(1)                                             POSTMAP(1)
 POSTMAP(1)                                             POSTMAP(1)
 
 
+              When no <i>file_type</i> is specified, the  software  uses
+              the  database  type specified via the <b>database</b><i>_</i><b>type</b>
+              configuration parameter.
+
+       <i>file_name</i>
+              The name of  the  lookup  table  source  file  when
+              rebuilding a database.
+
+<b>DIAGNOSTICS</b>
+       Problems and transactions are logged to the standard error
+       stream. No output means no problems. Duplicate entries are
        skipped and are flagged with a warning.
 
-       <b>postmap</b> terminates with zero exit status in case  of  suc-
-       cess  (including  successful <b>postmap</b> <b>-q</b> lookup) and termi-
+       <b>postmap</b>  terminates  with zero exit status in case of suc-
+       cess (including successful <b>postmap</b> <b>-q</b> lookup)  and  termi-
        nates with non-zero exit status in case of failure.
 
 <b>BUGS</b>
-       The "delete key" support is limited to one  delete  opera-
+       The  "delete  key" support is limited to one delete opera-
        tion per command invocation.
 
 <b>ENVIRONMENT</b>
@@ -156,12 +167,12 @@ POSTMAP(1)                                             POSTMAP(1)
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
        <b>database</b><i>_</i><b>type</b>
-              Default  output  database  type.  On many UNIX sys-
-              tems, the default database type is either  <b>hash</b>  or
+              Default output database type.  On  many  UNIX  sys-
+              tems,  the  default database type is either <b>hash</b> or
               <b>dbm</b>.
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
@@ -178,17 +189,6 @@ POSTMAP(1)                                             POSTMAP(1)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
 
 
 
index ad38289d12fe33f2c610857494559cc234d1ca87..3487c922c6b171a5ef113ad4604f4b983b422465 100644 (file)
@@ -50,13 +50,13 @@ REGEXP_TABLE(5)                                   REGEXP_TABLE(5)
        Other flags are `x' (disable extended expression  syntax),
        and `m' (enable multi-line mode).
 
-       Each  pattern is applied to the entire string being looked
-       up.  Depending on  the  application,  that  string  is  an
-       entire client hostname, an entire client IP address, or an
-       entire mail address.  Thus, no  parent  domain  or  parent
-       network search is done, and <i>user@domain</i> mail addresses are
-       not broken up  into  their  <i>user</i>  and  <i>domain</i>  constituent
-       parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
+       Each  pattern  is applied to the entire lookup key string.
+       Depending on the application, that  string  is  an  entire
+       client hostname, an entire client IP address, or an entire
+       mail address.  Thus, no parent domain  or  parent  network
+       search  is  done,  and  <i>user@domain</i> mail addresses are not
+       broken up into their <i>user</i> and  <i>domain</i>  constituent  parts,
+       nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Patterns  are  applied  in  the  order as specified in the
 
@@ -74,10 +74,10 @@ REGEXP_TABLE(5)                                   REGEXP_TABLE(5)
        table, until a pattern is found that  matches  the  search
        string.
 
-       Substitution of sub-strings from the matched expression is
-       possible using $1, $2, etc.. The macros in the replacement
-       string  may  need  to  be  written as ${n} or $(n) if they
-       aren't followed by whitespace.
+       Substitution  of  substrings  from  the matched expression
+       into the result string is possible using $1, $2, etc.. The
+       macros in the result string may need to be written as ${n}
+       or $(n) if they aren't followed by whitespace.
 
 <b>EXAMPLES</b>
        # Disallow sender-specified routing. This is a must if you relay mail
index 5637bbef447b15c9c3a487c74cb2e5be20ed0e94..1e8b32833fa335fc46026cfc01698c5225091179 100644 (file)
@@ -35,7 +35,11 @@ Read the \fBmain.cf\fR configuration file in the named directory
 instead of the default configuration directory.
 .IP "\fB-d \fIkey\fR"
 Search the specified maps for \fIkey\fR and remove one entry per map.
-The exit status is non-zero if the requested information was not found.
+The exit status is zero when the requested information was found.
+
+If a key value of \fB-\fR is specified, the program reads key
+values from the standard input stream. The exit status is zero
+when at least one of the requested keys was found.
 .IP \fB-i\fR
 Incremental mode. Read entries from standard input and do not
 truncate an existing database. By default, \fBpostalias\fR creates
@@ -46,8 +50,13 @@ keys and values. By default, Postfix does whatever is the default for
 the host operating system.
 .IP "\fB-q \fIkey\fR"
 Search the specified maps for \fIkey\fR and print the first value
-found on the standard output stream. The exit status is non-zero
-if the requested information was not found.
+found on the standard output stream. The exit status is zero
+when the requested information was found.
+
+If a key value of \fB-\fR is specified, the program reads key
+values from the standard input stream and prints one line of
+\fIkey: value\fR output for each key that was found. The exit
+status is zero when at least one of the requested keys was found.
 .IP \fB-r\fR
 When updating a table, do not warn about duplicate entries; silently
 replace them.
index bdcd3bf16e5594ba6bf1bd39341be20a119909c7..2f0b9c6c158bfedb6a9f97aaa42d65ebd59bb92a 100644 (file)
@@ -53,7 +53,11 @@ Read the \fBmain.cf\fR configuration file in the named directory
 instead of the default configuration directory.
 .IP "\fB-d \fIkey\fR"
 Search the specified maps for \fIkey\fR and remove one entry per map.
-The exit status is non-zero if the requested information was not found.
+The exit status is zero when the requested information was found.
+
+If a key value of \fB-\fR is specified, the program reads key
+values from the standard input stream. The exit status is zero
+when at least one of the requested keys was found.
 .IP \fB-i\fR
 Incremental mode. Read entries from standard input and do not
 truncate an existing database. By default, \fBpostmap\fR creates
@@ -64,8 +68,13 @@ keys and values. By default, Postfix does whatever is the default for
 the host operating system.
 .IP "\fB-q \fIkey\fR"
 Search the specified maps for \fIkey\fR and print the first value
-found on the standard output stream. The exit status is non-zero
-if the requested information was not found.
+found on the standard output stream. The exit status is zero
+when the requested information was found.
+
+If a key value of \fB-\fR is specified, the program reads key
+values from the standard input stream and prints one line of
+\fIkey value\fR output for each key that was found. The exit
+status is zero when at least one of the requested keys was found.
 .IP \fB-r\fR
 When updating a table, do not warn about duplicate entries; silently
 replace them.
index 51d59c1ee1de56e7d0d42b5cea9803da2a980b33..85244230543cb51aa31e6d3a39203acac3c34e95 100644 (file)
@@ -41,7 +41,7 @@ are supported, but the only other useful one is `U', which makes
 matching ungreedy (see PCRE documentation and source for more
 info).
 
-Each pattern is applied to the entire string being looked up.
+Each pattern is applied to the entire lookup key string.
 Depending on the application, that string is an entire client
 hostname, an entire client IP address, or an entire mail address.
 Thus, no parent domain or parent network search is done, and
@@ -52,9 +52,9 @@ broken up into \fIuser\fR and \fIfoo\fR.
 Patterns are applied in the order as specified in the table, until a
 pattern is found that matches the search string.
 
-Substitution of sub-strings from the matched expression is
-possible using the conventional perl syntax ($1, $2, etc.). The
-macros in the replacement string may need to be written as ${n}
+Substitution of substrings from the matched expression into the result
+string is possible using the conventional perl syntax ($1, $2, etc.).
+The macros in the result string may need to be written as ${n}
 or $(n) if they aren't followed by whitespace.
 .SH EXAMPLES
 .na
index c9a9c60b2d04da2908c325926a8b5c0c37adb367..efea3ef73e5fb26947e8fc75468b3b5dbda45b15 100644 (file)
@@ -43,7 +43,7 @@ the second slash with an `i' flag will reverse this. Other flags
 are `x' (disable extended expression syntax), and `m' (enable
 multi-line mode).
 
-Each pattern is applied to the entire string being looked up.
+Each pattern is applied to the entire lookup key string.
 Depending on the application, that string is an entire client
 hostname, an entire client IP address, or an entire mail address.
 Thus, no parent domain or parent network search is done, and
@@ -54,8 +54,8 @@ broken up into \fIuser\fR and \fIfoo\fR.
 Patterns are applied in the order as specified in the table, until a
 pattern is found that matches the search string.
 
-Substitution of sub-strings from the matched expression is
-possible using $1, $2, etc.. The macros in the replacement string
+Substitution of substrings from the matched expression into the result
+string is possible using $1, $2, etc.. The macros in the result string
 may need to be written as ${n} or $(n) if they aren't followed
 by whitespace.
 .SH EXAMPLES
index 9ad5b9d901097731d7436506bc99309d8767a0a3..7f71dcc8e44e4b3d45988041d0f90d27c3c079ec 100644 (file)
@@ -35,7 +35,7 @@
 #      matching ungreedy (see PCRE documentation and source for more
 #      info).
 #
-#      Each pattern is applied to the entire string being looked up.
+#      Each pattern is applied to the entire lookup key string.
 #      Depending on the application, that string is an entire client
 #      hostname, an entire client IP address, or an entire mail address.
 #      Thus, no parent domain or parent network search is done, and
@@ -46,9 +46,9 @@
 #      Patterns are applied in the order as specified in the table, until a
 #      pattern is found that matches the search string.
 #
-#      Substitution of sub-strings from the matched expression is
-#      possible using the conventional perl syntax ($1, $2, etc.). The
-#      macros in the replacement string may need to be written as ${n}
+#      Substitution of substrings from the matched expression into the result
+#      string is possible using the conventional perl syntax ($1, $2, etc.).
+#      The macros in the result string may need to be written as ${n}
 #      or $(n) if they aren't followed by whitespace.
 # EXAMPLES
 #      # Protect your outgoing majordomo exploders
index c65e215dec450448f221b6763b0eb8655064e652..bf4539404850d001e15216e00ed131746a7a1198 100644 (file)
@@ -37,7 +37,7 @@
 #      are `x' (disable extended expression syntax), and `m' (enable
 #      multi-line mode).
 #
-#      Each pattern is applied to the entire string being looked up.
+#      Each pattern is applied to the entire lookup key string.
 #      Depending on the application, that string is an entire client
 #      hostname, an entire client IP address, or an entire mail address.
 #      Thus, no parent domain or parent network search is done, and
@@ -48,8 +48,8 @@
 #      Patterns are applied in the order as specified in the table, until a
 #      pattern is found that matches the search string.
 #
-#      Substitution of sub-strings from the matched expression is
-#      possible using $1, $2, etc.. The macros in the replacement string
+#      Substitution of substrings from the matched expression into the result
+#      string is possible using $1, $2, etc.. The macros in the result string
 #      may need to be written as ${n} or $(n) if they aren't followed
 #      by whitespace.
 # EXAMPLES
index 5110c725119c19f52eff3cf245c8de84486d10ee..00d9089389f00d020bccc7b7f2cc4676ff0bcead 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20010329"
+#define DEF_MAIL_VERSION       "Snapshot-20010414"
 extern char *var_mail_version;
 
 /* LICENSE
index 836114aaedce4fac182b952f7990fe60f75a437e..bb32b956e4e228f8dc72dfaa5796a5af376d6a2f 100644 (file)
@@ -45,6 +45,7 @@ typedef struct MASTER_SERV {
 #define MASTER_FLAG_THROTTLE   (1<<0)  /* we're having trouble */
 #define MASTER_FLAG_MARK       (1<<1)  /* garbage collection support */
 #define MASTER_FLAG_CONDWAKE   (1<<2)  /* wake up if actually used */
+#define MASTER_FLAG_INETHOST   (1<<3)  /* endpoint name specifies host */
 
 #define MASTER_THROTTLED(f)    ((f)->flags & MASTER_FLAG_THROTTLE)
 
index 1069e10f8a491fe00302deeeff82f72acf0bcbd0..fd05bc2b6e39a95fd00b8565b8be58621aa74c12 100644 (file)
@@ -84,6 +84,8 @@
 #include <stringops.h>
 #include <readlline.h>
 #include <inet_addr_list.h>
+#include <inet_util.h>
+#include <inet_addr_host.h>
 
 /* Global library. */
 
@@ -222,6 +224,8 @@ MASTER_SERV *get_master_ent()
     MASTER_SERV *serv;
     char   *cp;
     char   *name;
+    char   *host;
+    char   *port;
     char   *transport;
     int     private;
     int     unprivileged;              /* passed on to child */
@@ -229,6 +233,7 @@ MASTER_SERV *get_master_ent()
     char   *command;
     int     n;
     char   *bufp;
+    char   *atmp;
 
     if (master_fp == 0)
        msg_panic("get_master_ent: config file not open");
@@ -270,13 +275,22 @@ MASTER_SERV *get_master_ent()
     transport = get_str_ent(&bufp, "transport type", (char *) 0);
     if (STR_SAME(transport, MASTER_XPORT_NAME_INET)) {
        serv->type = MASTER_SERV_TYPE_INET;
-       if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
+       atmp = inet_parse(name, &host, &port);
+       if (host && *host) {
+           serv->flags |= MASTER_FLAG_INETHOST;
+           serv->addr_list.inet =
+               (INET_ADDR_LIST *) mymalloc(sizeof(*serv->addr_list_buf.inet));
+           inet_addr_list_init(serv->addr_list.inet);
+           inet_addr_host(serv->addr_list.inet, host);
+           serv->listen_fd_count = serv->addr_list.inet->used;
+       } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
            serv->addr_list.inet = 0;           /* wild-card */
            serv->listen_fd_count = 1;
        } else {
            serv->addr_list.inet = own_inet_addr_list();        /* virtual */
            serv->listen_fd_count = serv->addr_list.inet->used;
        }
+       myfree(atmp);
     } else if (STR_SAME(transport, MASTER_XPORT_NAME_UNIX)) {
        serv->type = MASTER_SERV_TYPE_UNIX;
        serv->listen_fd_count = 1;
@@ -449,6 +463,8 @@ void    free_master_ent(MASTER_SERV *serv)
     /*
      * Undo what get_master_ent() created.
      */
+    if (serv->flags & MASTER_FLAG_INETHOST)
+       inet_addr_list_free(serv->addr_list.inet);
     myfree(serv->name);
     myfree(serv->path);
     argv_free(serv->args);
index 0fe46f910f511913a4449ab90d983f8b56f251a2..22125480968a0265f1d87c0b5512b4100ff66bac 100644 (file)
 /*     instead of the default configuration directory.
 /* .IP "\fB-d \fIkey\fR"
 /*     Search the specified maps for \fIkey\fR and remove one entry per map.
-/*     The exit status is non-zero if the requested information was not found.
+/*     The exit status is zero when the requested information was found.
+/*
+/*     If a key value of \fB-\fR is specified, the program reads key
+/*     values from the standard input stream. The exit status is zero
+/*     when at least one of the requested keys was found.
 /* .IP \fB-i\fR
 /*     Incremental mode. Read entries from standard input and do not
 /*     truncate an existing database. By default, \fBpostalias\fR creates
 /*     the host operating system.
 /* .IP "\fB-q \fIkey\fR"
 /*     Search the specified maps for \fIkey\fR and print the first value
-/*     found on the standard output stream. The exit status is non-zero
-/*     if the requested information was not found.
+/*     found on the standard output stream. The exit status is zero
+/*     when the requested information was found.
+/*
+/*     If a key value of \fB-\fR is specified, the program reads key
+/*     values from the standard input stream and prints one line of
+/*     \fIkey: value\fR output for each key that was found. The exit
+/*     status is zero when at least one of the requested keys was found.
 /* .IP \fB-r\fR
 /*     When updating a table, do not warn about duplicate entries; silently
 /*     replace them.
 #include <stringops.h>
 #include <split_at.h>
 #include <get_hostname.h>
+#include <vstring_vstream.h>
 
 /* Global library. */
 
@@ -306,6 +316,62 @@ static void postalias(char *map_type, char *path_name,
        vstream_fclose(source_fp);
 }
 
+/* postalias_queries - apply multiple requests from stdin */
+
+static int postalias_queries(VSTREAM *in, char **maps, const int map_count)
+{
+    int     found = 0;
+    VSTRING *keybuf = vstring_alloc(100);
+    DICT  **dicts;
+    const char *map_name;
+    const char *value;
+    int     n;
+
+    /*
+     * Sanity check.
+     */
+    if (map_count <= 0)
+       msg_panic("postalias_queries: bad map count");
+
+    /*
+     * Prepare to open maps lazily.
+     */
+    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
+    for (n = 0; n < map_count; n++)
+       dicts[n] = 0;
+
+    /*
+     * Perform all queries. Open maps on the fly, to avoid opening unecessary
+     * maps.
+     */
+    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
+       for (n = 0; n < map_count; n++) {
+           if (dicts[n] == 0)
+               dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+                  dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) :
+               dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK));
+           if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
+               vstream_printf("%s:     %s\n", STR(keybuf), value);
+               found = 1;
+               break;
+           }
+       }
+    }
+    if (found)
+       vstream_fflush(VSTREAM_OUT);
+
+    /*
+     * Cleanup.
+     */
+    for (n = 0; n < map_count; n++)
+       if (dicts[n])
+           dict_close(dicts[n]);
+    myfree((char *) dicts);
+    vstring_free(keybuf);
+
+    return (found);
+}
+
 /* postalias_query - query a map and print the result to stdout */
 
 static int postalias_query(const char *map_type, const char *map_name,
@@ -323,6 +389,50 @@ static int postalias_query(const char *map_type, const char *map_name,
     return (value != 0);
 }
 
+/* postalias_deletes - apply multiple requests from stdin */
+
+static int postalias_deletes(VSTREAM *in, char **maps, const int map_count)
+{
+    int     found = 0;
+    VSTRING *keybuf = vstring_alloc(100);
+    DICT  **dicts;
+    const char *map_name;
+    int     n;
+
+    /*
+     * Sanity check.
+     */
+    if (map_count <= 0)
+       msg_panic("postalias_deletes: bad map count");
+
+    /*
+     * Open maps ahead of time.
+     */
+    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
+    for (n = 0; n < map_count; n++)
+       dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+                   dict_open3(maps[n], map_name, O_RDWR, DICT_FLAG_LOCK) :
+                 dict_open3(var_db_type, maps[n], O_RDWR, DICT_FLAG_LOCK));
+
+    /*
+     * Perform all requests.
+     */
+    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF)
+       for (n = 0; n < map_count; n++)
+           found |= (dict_del(dicts[n], STR(keybuf)) == 0);
+
+    /*
+     * Cleanup.
+     */
+    for (n = 0; n < map_count; n++)
+       if (dicts[n])
+           dict_close(dicts[n]);
+    myfree((char *) dicts);
+    vstring_free(keybuf);
+
+    return (found);
+}
+
 /* postalias_delete - delete a key value pair from a map */
 
 static int postalias_delete(const char *map_type, const char *map_name,
@@ -331,10 +441,6 @@ static int postalias_delete(const char *map_type, const char *map_name,
     DICT   *dict;
     int     status;
 
-    /*
-     * XXX This must be generalized to multi-key (read from stdin) and
-     * multi-map (given on command line) updates.
-     */
     dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK);
     status = dict_del(dict, key);
     dict_close(dict);
@@ -447,6 +553,8 @@ int     main(int argc, char **argv)
     if (delkey) {                              /* remove entry */
        if (optind + 1 > argc)
            usage(argv[0]);
+       if (strcmp(delkey, "-") == 0)
+           exit(postalias_deletes(VSTREAM_IN, argv + optind, argc - optind) == 0);
        found = 0;
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
@@ -460,6 +568,8 @@ int     main(int argc, char **argv)
     } else if (query) {                                /* query map(s) */
        if (optind + 1 > argc)
            usage(argv[0]);
+       if (strcmp(query, "-") == 0)
+           exit(postalias_queries(VSTREAM_IN, argv + optind, argc - optind) == 0);
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
                found = postalias_query(argv[optind], path_name, query);
index f82edfb1443bd1e16d36c12d0194d8e246b3f731..aac5b1f695ad5885af25710bb46d716a851dcfa9 100644 (file)
 /*     instead of the default configuration directory.
 /* .IP "\fB-d \fIkey\fR"
 /*     Search the specified maps for \fIkey\fR and remove one entry per map.
-/*     The exit status is non-zero if the requested information was not found.
+/*     The exit status is zero when the requested information was found.
+/*
+/*     If a key value of \fB-\fR is specified, the program reads key
+/*     values from the standard input stream. The exit status is zero
+/*     when at least one of the requested keys was found.
 /* .IP \fB-i\fR
 /*     Incremental mode. Read entries from standard input and do not
 /*     truncate an existing database. By default, \fBpostmap\fR creates
 /*     the host operating system.
 /* .IP "\fB-q \fIkey\fR"
 /*     Search the specified maps for \fIkey\fR and print the first value
-/*     found on the standard output stream. The exit status is non-zero
-/*     if the requested information was not found.
+/*     found on the standard output stream. The exit status is zero
+/*     when the requested information was found.
+/*
+/*     If a key value of \fB-\fR is specified, the program reads key
+/*     values from the standard input stream and prints one line of
+/*     \fIkey value\fR output for each key that was found. The exit
+/*     status is zero when at least one of the requested keys was found.
 /* .IP \fB-r\fR
 /*     When updating a table, do not warn about duplicate entries; silently
 /*     replace them.
 #include <readlline.h>
 #include <stringops.h>
 #include <split_at.h>
+#include <vstring_vstream.h>
 
 /* Global library. */
 
@@ -253,6 +263,62 @@ static void postmap(char *map_type, char *path_name,
        vstream_fclose(source_fp);
 }
 
+/* postmap_queries - apply multiple requests from stdin */
+
+static int postmap_queries(VSTREAM *in, char **maps, const int map_count)
+{
+    int     found = 0;
+    VSTRING *keybuf = vstring_alloc(100);
+    DICT  **dicts;
+    const char *map_name;
+    const char *value;
+    int     n;
+
+    /*
+     * Sanity check.
+     */
+    if (map_count <= 0)
+       msg_panic("postmap_queries: bad map count");
+
+    /*
+     * Prepare to open maps lazily.
+     */
+    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
+    for (n = 0; n < map_count; n++)
+       dicts[n] = 0;
+
+    /*
+     * Perform all queries. Open maps on the fly, to avoid opening unecessary
+     * maps.
+     */
+    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) {
+       for (n = 0; n < map_count; n++) {
+           if (dicts[n] == 0)
+               dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+                  dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) :
+               dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK));
+           if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
+               vstream_printf("%s      %s\n", STR(keybuf), value);
+               found = 1;
+               break;
+           }
+       }
+    }
+    if (found)
+       vstream_fflush(VSTREAM_OUT);
+
+    /*
+     * Cleanup.
+     */
+    for (n = 0; n < map_count; n++)
+       if (dicts[n])
+           dict_close(dicts[n]);
+    myfree((char *) dicts);
+    vstring_free(keybuf);
+
+    return (found);
+}
+
 /* postmap_query - query a map and print the result to stdout */
 
 static int postmap_query(const char *map_type, const char *map_name,
@@ -270,6 +336,50 @@ static int postmap_query(const char *map_type, const char *map_name,
     return (value != 0);
 }
 
+/* postmap_deletes - apply multiple requests from stdin */
+
+static int postmap_deletes(VSTREAM *in, char **maps, const int map_count)
+{
+    int     found = 0;
+    VSTRING *keybuf = vstring_alloc(100);
+    DICT  **dicts;
+    const char *map_name;
+    int     n;
+
+    /*
+     * Sanity check.
+     */
+    if (map_count <= 0)
+       msg_panic("postmap_deletes: bad map count");
+
+    /*
+     * Open maps ahead of time.
+     */
+    dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count);
+    for (n = 0; n < map_count; n++)
+       dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ?
+                   dict_open3(maps[n], map_name, O_RDWR, DICT_FLAG_LOCK) :
+                 dict_open3(var_db_type, maps[n], O_RDWR, DICT_FLAG_LOCK));
+
+    /*
+     * Perform all requests.
+     */
+    while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF)
+       for (n = 0; n < map_count; n++)
+           found |= (dict_del(dicts[n], STR(keybuf)) == 0);
+
+    /*
+     * Cleanup.
+     */
+    for (n = 0; n < map_count; n++)
+       if (dicts[n])
+           dict_close(dicts[n]);
+    myfree((char *) dicts);
+    vstring_free(keybuf);
+
+    return (found);
+}
+
 /* postmap_delete - delete a (key, value) pair from a map */
 
 static int postmap_delete(const char *map_type, const char *map_name,
@@ -278,10 +388,6 @@ static int postmap_delete(const char *map_type, const char *map_name,
     DICT   *dict;
     int     status;
 
-    /*
-     * XXX This must be generalized to multi-key (read from stdin) and
-     * multi-map (given on command line) updates.
-     */
     dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK);
     status = dict_del(dict, key);
     dict_close(dict);
@@ -394,6 +500,8 @@ int     main(int argc, char **argv)
     if (delkey) {                              /* remove entry */
        if (optind + 1 > argc)
            usage(argv[0]);
+       if (strcmp(delkey, "-") == 0)
+           exit(postmap_deletes(VSTREAM_IN, argv + optind, argc - optind) == 0);
        found = 0;
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
@@ -407,6 +515,8 @@ int     main(int argc, char **argv)
     } else if (query) {                                /* query map(s) */
        if (optind + 1 > argc)
            usage(argv[0]);
+       if (strcmp(query, "-") == 0)
+           exit(postmap_queries(VSTREAM_IN, argv + optind, argc - optind) == 0);
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
                found = postmap_query(argv[optind], path_name, query);
index c9109fa3a4b53644e48811f8878c3800db62e284..2a6a9d12ab2965121e27a99877e53a4e893035e4 100644 (file)
@@ -354,6 +354,8 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
                } else if (*var_bestmx_transp != 0) {   /* we're best MX */
                    smtp_errno = SMTP_OK;
                } else {
+                   msg_warn("mailer loop: best MX host for %s is local",
+                            name);
                    vstring_sprintf(why, "mail for %s loops back to myself",
                                    name);
                    smtp_errno = SMTP_FAIL;
index 3de90461a521916b24cbbdb2ddee02727840de80..6822cd1a47a68a3cda29c1932c5dfa7cdf5b8cc8 100644 (file)
@@ -823,9 +823,12 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
      * error.
      */
     if (state->rcpt_count == 0) {
-       if (state->cleanup == 0)
+       if (state->cleanup == 0) {
            state->error_mask |= MAIL_ERROR_PROTOCOL;
-       smtpd_chat_reply(state, "503 Error: need RCPT command");
+           smtpd_chat_reply(state, "503 Error: need RCPT command");
+       } else {
+           smtpd_chat_reply(state, "550 Error: no valid recipients");
+       }
        return (-1);
     }
     if (argc != 1) {
index 32187d3f71cd4dd18ce11280abbe7c55ef8f03bd..aaac7988e2e5d4bdf259a323e8a7f351fceb5dbe 100644 (file)
@@ -1440,6 +1440,14 @@ static int reject_maps_rbl(SMTPD_STATE *state)
     if (msg_verbose)
        msg_info("%s: %s", myname, state->addr);
 
+    /*
+     * IPv4 only for now
+     */
+#ifdef INET6
+    if (inet_pton(AF_INET, state->addr, &a) != 1)
+       return SMTPD_CHECK_DUNNO;
+#endif
+
     /*
      * Build the constant part of the RBL query: the reverse client address.
      */
index 02b72baf47aee50ef2aeaf249f968089c3b93b12..69518e10f8a835ce9c49133ddd31bcf3925217ec 100644 (file)
@@ -439,6 +439,13 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
 
     db_path = concatenate(path, ".db", (char *) 0);
 
+    /*
+     * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in
+     * the time domain) locking while accessing individual database records.
+     * 
+     * Programs such as postmap/postalias use their own large-grained (in the
+     * time domain) locks while rewriting the entire file.
+     */
     if (dict_flags & DICT_FLAG_LOCK) {
        if ((lock_fd = open(db_path, open_flags, 0644)) < 0)
            msg_fatal("open database %s: %m", db_path);
@@ -517,13 +524,24 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
     if (fstat(dict_db->dict.fd, &st) < 0)
        msg_fatal("dict_db_open: fstat: %m");
     dict_db->dict.mtime = st.st_mtime;
+
+    /*
+     * Warn if the source file is newer than the indexed file, except when
+     * the source file changed only seconds ago.
+     */
+    if ((dict_flags & DICT_FLAG_LOCK) != 0
+       && stat(path, &st) == 0
+       && st.st_mtime > dict_db->dict.mtime
+       && st.st_mtime < time((time_t *) 0) - 100)
+       msg_warn("database %s is older than source file %s", db_path, path);
+
     close_on_exec(dict_db->dict.fd, CLOSE_ON_EXEC);
     dict_db->dict.flags = dict_flags | DICT_FLAG_FIXED;
     if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
        dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
     dict_db->db = db;
     myfree(db_path);
-    return (DICT_DEBUG(&dict_db->dict));
+    return (DICT_DEBUG (&dict_db->dict));
 }
 
 /* dict_hash_open - create association with data base */
index 6f3a5611ad73a348a07b1e4bab71f1594fe95d2d..575d5eb54c9aa2e4bf34e38816050dc1218c5523 100644 (file)
@@ -371,6 +371,13 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
     char   *dbm_path;
     int     lock_fd;
 
+    /*
+     * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in
+     * the time domain) locking while accessing individual database records.
+     * 
+     * Programs such as postmap/postalias use their own large-grained (in the
+     * time domain) locks while rewriting the entire file.
+     */
     if (dict_flags & DICT_FLAG_LOCK) {
        dbm_path = concatenate(path, ".pag", (char *) 0);
        if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
@@ -390,7 +397,6 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
            msg_fatal("unlock database %s for open: %m", dbm_path);
        if (close(lock_fd) < 0)
            msg_fatal("close database %s: %m", dbm_path);
-       myfree(dbm_path);
     }
     dict_dbm = (DICT_DBM *) dict_alloc(DICT_TYPE_DBM, path, sizeof(*dict_dbm));
     dict_dbm->dict.lookup = dict_dbm_lookup;
@@ -402,6 +408,17 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
     if (fstat(dict_dbm->dict.fd, &st) < 0)
        msg_fatal("dict_dbm_open: fstat: %m");
     dict_dbm->dict.mtime = st.st_mtime;
+
+    /*
+     * Warn if the source file is newer than the indexed file, except when
+     * the source file changed only seconds ago.
+     */
+    if ((dict_flags & DICT_FLAG_LOCK) != 0
+       && stat(path, &st) == 0
+       && st.st_mtime > dict_dbm->dict.mtime
+       && st.st_mtime < time((time_t *) 0) - 100)
+       msg_warn("database %s is older than source file %s", dbm_path, path);
+
     close_on_exec(dbm_pagfno(dbm), CLOSE_ON_EXEC);
     close_on_exec(dbm_dirfno(dbm), CLOSE_ON_EXEC);
     dict_dbm->dict.flags = dict_flags | DICT_FLAG_FIXED;
@@ -409,7 +426,10 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
        dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
     dict_dbm->dbm = dbm;
 
-    return (DICT_DEBUG(&dict_dbm->dict));
+    if ((dict_flags & DICT_FLAG_LOCK))
+       myfree(dbm_path);
+
+    return (DICT_DEBUG (&dict_dbm->dict));
 }
 
 #endif
index fc3a802137dad034cf621f8ca7cc81f32682f75d..44b121d81271e0e51487e727e133e354a836613e 100644 (file)
@@ -297,7 +297,8 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
         entry = ldap_next_entry(dict_ldap->ld, entry)) {
        attr = ldap_first_attribute(dict_ldap->ld, entry, &ber);
        if (attr == NULL) {
-           msg_warn("%s: no attributes found", myname);
+           if (msg_verbose)
+               msg_info("%s: no attributes found", myname);
            continue;
        }
        for (; attr != NULL;
@@ -305,8 +306,9 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
 
            vals = ldap_get_values(dict_ldap->ld, entry, attr);
            if (vals == NULL) {
-               msg_warn("%s: Entry doesn't have any values for %s",
-                        myname, attr);
+               if (msg_verbose)
+                   msg_info("%s: Entry doesn't have any values for %s",
+                            myname, attr);
                continue;
            }
            for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
index d16c90c85bef0c57b5f6b71f1bf1b9fecfb19c7d..28fc70156390c76bab9b76068f25c863caf4a702 100644 (file)
@@ -201,6 +201,12 @@ static const char *dict_mysql_lookup(DICT *dict, const char *name)
        if (i > 0)
            vstring_strcat(result, ",");
        for (j = 0; j < mysql_num_fields(query_res); j++) {
+           if (row[j] == 0) {
+               if (msg_verbose > 1)
+                   msg_info("dict_mysql_lookup: null field #%d row #%d", j, i);
+               mysql_free_result(query_res);
+               return (0);
+           }
            if (j > 0)
                vstring_strcat(result, ",");
            vstring_strcat(result, row[j]);