]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-20010228-pl02 v20010228-pl02
authorWietse Venema <wietse@porcupine.org>
Mon, 30 Apr 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 15:51:30 +0000 (15:51 +0000)
42 files changed:
postfix/HISTORY
postfix/INSTALL
postfix/INSTALL.sh
postfix/SASL_README
postfix/conf/main.cf
postfix/conf/master.cf
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/master.8.html
postfix/html/pcre_table.5.html
postfix/html/regexp_table.5.html
postfix/html/smtpd.8.html
postfix/man/man5/pcre_table.5
postfix/man/man5/regexp_table.5
postfix/man/man8/master.8
postfix/man/man8/smtpd.8
postfix/proto/pcre_table
postfix/proto/regexp_table
postfix/src/global/mail_version.h
postfix/src/lmtp/lmtp_proto.c
postfix/src/master/Makefile.in
postfix/src/master/master.c
postfix/src/master/master.h
postfix/src/master/master_ent.c
postfix/src/master/master_listen.c
postfix/src/pipe/pipe.c
postfix/src/smtp/smtp_addr.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.in
postfix/src/smtpd/smtpd_check.in3 [new file with mode: 0644]
postfix/src/smtpd/smtpd_check.ref
postfix/src/smtpd/smtpd_check.ref2
postfix/src/util/dict_db.c
postfix/src/util/dict_dbm.c
postfix/src/util/dict_ldap.c
postfix/src/util/dict_mysql.c
postfix/src/util/dict_unix.c

index cae862b274651f8ea98c5eb477b801c356c4f054..f8b7c367cfb9c32da7471cd71fc9ca5b72c6fe62 100644 (file)
@@ -4969,3 +4969,58 @@ Apologies for any names omitted.
        Portability: workaround for missing prototype problem in
        dict_ldap.c. This module should move to the global directory,
        because it depends on Postfix main.cf parameter information.
+
+20010403
+
+       Workaround: the mysql library can return null pointers
+       rather than zero-length strings.
+
+20010404
+
+       Ergonomics: log additional information about the reason
+       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
+
+       Bugfix: 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 recommend to rebuild the table.
+       Files: util/dict_db.c, util/dict_dbm.c.
+
+20010414
+
+       Bugfix: with a non-default inet_interfaces setting, the
+       master ignored host information in master.cf host:port
+       settings.  Fix by Jun-ichiro itojun Hagino @ iijlab.net.
+       Files: master/master.h, master/master_ent.c.
+
+20010426
+
+       Bugfix: the SMTP server did not parse invalid MAIL FROM or
+       RCPT TO addresses such as <first last <user@domain>> the
+       way it was supposed to do.  I thought this was taken care
+       of years ago. File:  smtpd/smtpd.c.
+
+20010427
+
+       Bugfix: smtpd would reject mail instead of replying with
+       a 4xx temporary error code when, for example, an LDAP or
+       mysql server was unavailable. Remotely based on a fix by
+       Robert Kiessling @ de.easynet.net. File: smtpd/smtpd_check.c.
index 427a4528ce8c549b1132753d5b5096e062690dcf..4cf914fe865838b72e178bb402358b2877aed0a1 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
@@ -208,6 +208,10 @@ In order to install or upgrade Postfix:
     # make install              (interactive version, first time install)
     # make install </dev/null   (non-interactive version, for upgrades)
 
+  The non-interactive version needs the /etc/postfix/install.cf
+  file from a previous installation. If the file does not exist,
+  use interactive installation instead.
+
   The INSTALL.sh script offers suggestions for pathnames that you
   can override, either by editing INSTALL.sh or by specifying your
   preferences interactively. INSTALL.sh stores your preferences in
index 1ad76e988fb9c234c512ca38ff2e7eb65a47f949..88a60495d9b0d170532d70ef15c82f7599dabcac 100644 (file)
@@ -166,7 +166,15 @@ test -f $CONFIG_DIRECTORY/main.cf && {
     done
 }
 
-test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf
+test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf || {
+    test -t 0 || {
+       echo Non-interactive install needs the $CONFIG_DIRECTORY/install.cf 1>&2
+       echo file from a previous Postfix installation. 1>&2
+       echo 1>&2
+       echo Use interactive installation instead. 1>&2
+       exit 1
+    }
+}
 
 # Override default settings.
 
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 fb75a55a289fa15194436a41ad301e1d3d9ff83b..03406031852d1d46955fd7b5bac2b33c1b6fa58e 100644 (file)
@@ -374,6 +374,8 @@ mail_owner = postfix
 # localpart), $recipient_delimiter. Specify ${name?value} or
 # ${name:value} to expand value only when $name does (does not) exist.
 #
+# luser_relay works only for the default Postfix local delivery agent.
+#
 # luser_relay = $user@other.host
 # luser_relay = $local@other.host
 # luser_relay = admin+$local
index e00d7c6834977b459a9a35e0d79b10223a68e326..7f3f3038ab8232a8912582b633f31be64397ee00 100644 (file)
@@ -37,6 +37,7 @@
 # Max procs: the maximum number of processes that may execute this
 # service simultaneously. Default is to use a globally configurable
 # limit (the default_process_limit configuration parameter in main.cf).
+# Specify 0 for no process count limit.
 #
 # Command + args: the command to be executed. The command name is
 # relative to the Postfix program directory (pathname is controlled by
index 2c5d43ae21c3b274e5203090b2ee30fd66c46c2b..f511afa52cb2403c58dd3e61291d8ba6b04549c2 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 a635ef679d787e090b01bc2c84afa5f958e30795..7323f3b3c40680c20bc755a4858938c53e48986c 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..eab49fd8776ecda6309204a9109f75c9c398062d 100644 (file)
@@ -125,6 +125,8 @@ home_mailbox =
 # localpart), $recipient_delimiter. Specify ${name?value} or
 # ${name:value} to expand value only when $name does (does not) exist.
 #
+# luser_relay works only for the default Postfix local delivery agent.
+#
 # luser_relay = $user@other.host
 # luser_relay = $local@other.host
 # luser_relay = admin+$local
@@ -219,12 +221,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 14f9e19b2c80aa34479c98021c2a5fbd43123e4e..36485ae50bd8401bef2a03b6d0877845b47f813b 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 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..29435090555d2a0c245236edebe8106fe7de6919 100644 (file)
 
 <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>
 
 <li><a href="#virtual_relay">Postfix refuses mail for virtual
 domains with "relay access denied"</a>
+
+<li><a href="#broken_transport">Mail delivery fails with: "unknown
+mail transport error"</a>
+
 </ul>
 
 <p>
@@ -169,6 +175,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>
@@ -200,6 +209,9 @@ domains with "relay access denied"</a>
 
 <li><a href="#noservice">What does "fatal: unknown service: smtp/tcp" mean?</a>
 
+<li><a href="#broken_transport">Mail delivery fails with: "unknown
+mail transport error"</a>
+
 </ul>
 
 <a name="local_delivery"><h3>Local (non-virtual) delivery</h3>
@@ -232,6 +244,9 @@ distribution list</a>
 
 <li><a href="#noalias">What does "fatal: open database /etc/aliases.db" mean?</a>
 
+<li><a href="#broken_transport">Mail delivery fails with: "unknown
+mail transport error"</a>
+
 </ul>
 
 <a name="mailing_lists"><h3>Mailing lists</h3>
@@ -249,7 +264,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 +281,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>
@@ -941,14 +956,74 @@ delivery agent deals with undeliverable mail.
 
 <a name="noalias"><h3>What does "fatal: open database /etc/aliases.db" mean?</h3></a>
 
-Your aliases database is corrupt or it is missing. Execute the 
-following command as root:
+DB files are maintained by the Berkeley DB library. The above
+message means one of the following things:
+
+<p>
+
+<ul>
+
+<li> The existing file does not have the expected file format.
+The cause is one of the following:
 
 <p>
 
+<ul>
+
+<li>The file was created by Berkeley DB version 1 and you are using
+version 2 or 3 (or vice versa).
+
+<p>
+
+<li> The file was written in "btree" format and Postfix expects
+    "hash" format (or vice versa).
+
+</ul>
+
+<p>
+
+To fix the problem for Postfix execute the following command as root:
+
+<blockquote>
 <pre>
-    newaliases
+    newaliases
 </pre>
+</blockquote>
+
+This creates the aliases.db in the format that Postfix expects.
+
+<p>
+
+<li>Or the problem could be something completely different. If the
+result of running <tt>newaliases</tt> is a zero-length aliases.db
+file, then you probably suffer from the following problem.
+
+<p>
+
+<ul>
+
+<li>Postfix was compiled with #include files for Berkeley DB version
+<i>X</i> and was linked against object library files for Berkeley DB
+version <i>Y</i>, where <i>X</i> and <i>Y</i> are different versions
+of the Berkeley DB library.
+
+</ul>
+
+<p>
+
+The fix for this is to properly install the Berkeley DB library.
+For example, RedHat version 7.0 uses the Berkeley DB version 3
+object library by default, but no /usr/include/db.h file is
+installed by default. In order to correctly build Postfix you
+must install the db3-devel package.
+
+<p>
+
+On a properly installed system, including the file <b>&lt;db.h&gt;</b>
+and linking with <b>-ldb</b> should access files from the same
+Berkeley DB library version.
+
+</ul>
 
 <hr>
 
@@ -1257,6 +1332,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
@@ -1839,6 +1951,36 @@ Instructions are given in the source code distribution, in the
 <b>examples/chroot-setup</b> directory.
 
 </ul>
+
+<hr>
+
+<a name="broken_transport"><h3>Mail delivery fails with: "unknown
+mail transport error"</h3>
+
+This is an opportunity to meet your friends <b>egrep</b> and
+<b>less</b>.  Postfix activity, including progres and failure, is
+logged to a logfile, typically named <b>/var/log/maillog</b>.  To
+find out where Postfix activity is logged on your machine, examine
+the <b>/etc/syslog.conf</b> file.
+
+<p> 
+
+To find out the cause for the "unknown mail transport error", type
+the following command:
+
+<blockquote>
+
+<tt>egrep '(warning|fatal|panic):' /var/log/maillog | less</tt> 
+
+</blockquote>
+
+Pay particular attention to messages that are labeled as <b>fatal</b>
+and <b>panic</b>. These describe catastrophic failures that need
+to be addressed before Postfix is happy.  Problems labeled as
+<b>fatal</b> are fixed by you, by adjusting configuration files,
+file permissions and so on. Problems labeled as <b>panic</b> are
+fixed by the Postfix author, by changing Postfix source code.
+
 <hr>
 
 <a name="root"> <h3>Root's mail is delivered to nobody</h3>
@@ -2416,12 +2558,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 +2571,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 specified in virtual maps.
 
 <hr>
 
@@ -2902,15 +3045,29 @@ that the file name will collide with another queue file.
 <p>
 
 To avoid queue file name collisions when copying queue files,
-restore queue files in the maildrop directory instead.
+restore the incoming, active and deferred queue files under the
+maildrop directory instead.
+
+<p>
+
+As of late 2000, Postfix queues are all hashed (for example, file
+ABCDEF is stored as A/B/ABCDEF), so you need an additional step to
+move files down from their subdirectories.
 
 <p>
 <pre>
     # postfix stop
-    ... restore queue files under the maildrop directory...
+    # cd /var/spool/postfix/maildrop
+    ... restore incoming/active/deferred queue files under the maildrop directory...
+    # find incoming active deferred -type f -exec mv '{}' . ';'
+    # rm -rf incoming active deferred
     # postfix start
 </pre>
 
+While all this is going on, don't submit new mail locally, because
+that could collide with the files you are restoring under the
+maildrop directory.
+
 <p>
 
 When Postfix is started, it will pick up queue files from the
index b1784ea0059691be875081d813e88d440b273b1b..c767d6dc3070cc5bd60e0285189b40b8ce0013b4 100644 (file)
@@ -9,7 +9,7 @@ MASTER(8)                                               MASTER(8)
        master - Postfix master process
 
 <b>SYNOPSIS</b>
-       <b>master</b> [<b>-c</b> <i>config_dir</i>] [<b>-D</b>] [<b>-t</b>] [<b>-v</b>]
+       <b>master</b> [<b>-c</b> <i>config_dir</i>] [<b>-e</b> <i>exit_time</i>] [<b>-D</b>] [<b>-t</b>] [<b>-v</b>]
 
 <b>DESCRIPTION</b>
        The  <b>master</b> daemon is the resident process that runs Post-
@@ -37,6 +37,11 @@ MASTER(8)                                               MASTER(8)
               in the named directory instead of the default  con-
               figuration directory.
 
+       <b>-e</b> <i>exit_time</i>
+              Terminate  the  master process after <i>exit_time</i> sec-
+              onds. Child processes  terminate  at  their  conve-
+              nience.
+
        <b>-D</b>     After  initialization, run a debugger on the master
               process. The debugging command  is  specified  with
               the <b>debugger</b><i>_</i><b>command</b> in the <b>main.cf</b> global configu-
@@ -54,11 +59,6 @@ MASTER(8)                                               MASTER(8)
        Signals:
 
        <b>SIGHUP</b> Upon  receipt  of a <b>HUP</b> signal (e.g., after <b>postfix</b>
-              <b>reload</b>), the master process re-reads its configura-
-              tion  files. If a service has been removed from the
-              <b>master.cf</b> file, its running  processes  are  termi-
-              nated  immediately.   Otherwise,  running processes
-              are allowed to terminate as soon as is  convenient,
 
 
 
@@ -71,6 +71,11 @@ MASTER(8)                                               MASTER(8)
 MASTER(8)                                               MASTER(8)
 
 
+              <b>reload</b>), the master process re-reads its configura-
+              tion  files. If a service has been removed from the
+              <b>master.cf</b> file, its running  processes  are  termi-
+              nated  immediately.   Otherwise,  running processes
+              are allowed to terminate as soon as is  convenient,
               so  that  changes  in configuration settings affect
               only new service requests.
 
@@ -119,11 +124,6 @@ MASTER(8)                                               MASTER(8)
        <b>daemon</b><i>_</i><b>directory</b>
               Directory with Postfix daemon programs.
 
-       <b>queue</b><i>_</i><b>directory</b>
-              Top-level  directory  of the Postfix queue. This is
-              also the root directory of Postfix daemons that run
-              chrooted.
-
 
 
 
@@ -137,6 +137,11 @@ MASTER(8)                                               MASTER(8)
 MASTER(8)                                               MASTER(8)
 
 
+       <b>queue</b><i>_</i><b>directory</b>
+              Top-level  directory  of the Postfix queue. This is
+              also the root directory of Postfix daemons that run
+              chrooted.
+
 <b>Resource</b> <b>controls</b>
        <b>default</b><i>_</i><b>process</b><i>_</i><b>limit</b>
               Default  limit for the number of simultaneous child
@@ -188,11 +193,6 @@ MASTER(8)                                               MASTER(8)
 
 
 
-
-
-
-
-
 
                                                                 3
 
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 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 97ae6d8377baa8d3882d30272d4eb71fbbc0839c..0e96e6860a58c52f721f6293645d20bd025f978a 100644 (file)
@@ -283,7 +283,7 @@ SMTPD(8)                                                 SMTPD(8)
               nasty  relay  loopholes involving trusted backup MX
               hosts.
 
-       <b>restriction</b><i>_</i><b>classes</b>
+       <b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
               Declares the name of zero or more  parameters  that
               contain  a  list  of UCE restrictions. The names of
               these parameters can then be used  instead  of  the
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 ad4f0344406f88ce85b64e2478461f1543cc9f42..7729c2957d3a73b6eddfc52d3b3180b588f7b5aa 100644 (file)
@@ -9,7 +9,8 @@ Postfix master process
 .na
 .nf
 .fi
-\fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
+\fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR]
+[\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
 .SH DESCRIPTION
 .ad
 .fi
@@ -34,6 +35,9 @@ Options:
 .IP "\fB-c \fIconfig_dir\fR"
 Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in
 the named directory instead of the default configuration directory.
+.IP "\fB-e \fIexit_time\fR"
+Terminate the master process after \fIexit_time\fR seconds. Child
+processes terminate at their convenience.
 .IP \fB-D\fR
 After initialization, run a debugger on the master process. The
 debugging command is specified with the \fBdebugger_command\fR in
index c544a890d5c6b67305e1e428bfd811da239acc96..7b5a4ea6e917e384890e8d08736d3e0fdb8f1f0b 100644 (file)
@@ -196,7 +196,7 @@ and what clients may issue \fBETRN\fR commands.
 Allow untrusted clients to specify addresses with sender-specified
 routing.  Enabling this opens up nasty relay loopholes involving
 trusted backup MX hosts.
-.IP \fBrestriction_classes\fR
+.IP \fBsmtpd_restriction_classes\fR
 Declares the name of zero or more parameters that contain a
 list of UCE restrictions. The names of these parameters can
 then be used instead of the restriction lists that they represent.
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 bb9dffda2e8159b04fb33708c0f768857d130795..f74fe87c39c1acb4e1f4b588effeab77628d3659 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Postfix-20010228-pl01"
+#define DEF_MAIL_VERSION       "Postfix-20010228-pl02"
 extern char *var_mail_version;
 
 /* LICENSE
index cd34d7556e4f377290cfbfa7d77bec382b7fa47c..93c40d543ad683032124f449817cd117f6cd4126 100644 (file)
@@ -173,14 +173,12 @@ char   *xfer_states[LMTP_STATE_LAST] = {
 
 int     lmtp_lhlo(LMTP_STATE *state)
 {
-    char   *myname = "lmtp_lhlo";
     LMTP_SESSION *session = state->session;
     LMTP_RESP *resp;
     int     except;
     char   *lines;
     char   *words;
     char   *word;
-    SOCKOPT_SIZE optlen = sizeof(state->sndbufsize);
 
     /*
      * Prepare for disaster.
index 83d6200cc343be094328e4f7b0b48b8509a27dbf..47f3369af078f801cc81ef18271489d350a14503 100644 (file)
@@ -121,6 +121,8 @@ master_ent.o: ../../include/argv.h
 master_ent.o: ../../include/stringops.h
 master_ent.o: ../../include/readlline.h
 master_ent.o: ../../include/inet_addr_list.h
+master_ent.o: ../../include/inet_util.h
+master_ent.o: ../../include/inet_addr_host.h
 master_ent.o: ../../include/mail_proto.h
 master_ent.o: ../../include/iostuff.h
 master_ent.o: ../../include/mail_params.h
index c7dead391fb93e6c1133846fecdc8ac42c4cf2d0..4299424f1cec6717ec756389520f68f372931036 100644 (file)
@@ -5,7 +5,8 @@
 /*     Postfix master process
 /* SYNOPSIS
 /* .fi
-/*     \fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
+/*     \fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR]
+/*             [\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
 /* DESCRIPTION
 /*     The \fBmaster\fR daemon is the resident process that runs Postfix
 /*     daemons on demand: daemons to send or receive messages via the
@@ -28,6 +29,9 @@
 /* .IP "\fB-c \fIconfig_dir\fR"
 /*     Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in
 /*     the named directory instead of the default configuration directory.
+/* .IP "\fB-e \fIexit_time\fR"
+/*     Terminate the master process after \fIexit_time\fR seconds. Child
+/*     processes terminate at their convenience.
 /* .IP \fB-D\fR
 /*     After initialization, run a debugger on the master process. The
 /*     debugging command is specified with the \fBdebugger_command\fR in
 
 #include "master.h"
 
+/* master_exit_event - exit for memory leak testing purposes */
+
+static void master_exit_event(int unused_event, char *unused_context)
+{
+    msg_info("master exit time has arrived");
+    exit(0);
+}
+
+/* main - main program */
+
 int     main(int argc, char **argv)
 {
     static VSTREAM *lock_fp;
@@ -251,12 +265,15 @@ int     main(int argc, char **argv)
     /*
      * Process JCL.
      */
-    while ((ch = GETOPT(argc, argv, "c:Dtv")) > 0) {
+    while ((ch = GETOPT(argc, argv, "c:e:Dtv")) > 0) {
        switch (ch) {
        case 'c':
            if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
                msg_fatal("out of memory");
            break;
+       case 'e':
+           event_request_timer(master_exit_event, (char *) 0, atoi(optarg));
+           break;
        case 'D':
            debug_me = 1;
            break;
@@ -267,7 +284,7 @@ int     main(int argc, char **argv)
            msg_verbose++;
            break;
        default:
-           msg_fatal("usage: %s [-D] [-t] [-v]", argv[0]);
+           msg_fatal("usage: %s [-c config_dir] [-e exit_time] [-D (debug)] [-t (test)] [-v]", argv[0]);
            /* NOTREACHED */
        }
     }
@@ -282,8 +299,7 @@ int     main(int argc, char **argv)
 
     /*
      * Environment import filter, to enforce consistent behavior whether
-     * Postfix is started by hand, or at system boot time. The argument list
-     * specifies what environment parameters to preserve.
+     * Postfix is started by hand, or at system boot time.
      */
     import_env = argv_split(var_import_environ, ", \t\r\n");
     clean_env(import_env->argv);
index 836114aaedce4fac182b952f7990fe60f75a437e..abdfecc720f8005be01afb6a38fde4f4f057d13a 100644 (file)
@@ -24,8 +24,13 @@ typedef struct MASTER_SERV {
     int    *listen_fd;                 /* incoming requests */
     int     listen_fd_count;           /* nr of descriptors */
     union {
-       struct INET_ADDR_LIST *inet;
-    } addr_list;
+       struct {
+           char   *port;               /* inet listen port */
+           struct INET_ADDR_LIST *addr;/* inet listen address */
+       } inet_ep;
+#define MASTER_INET_ADDRLIST(s)        ((s)->endpoint.inet_ep.addr)
+#define MASTER_INET_PORT(s)    ((s)->endpoint.inet_ep.port)
+    } endpoint;
     int     max_proc;                  /* upper bound on # processes */
     char   *path;                      /* command pathname */
     struct ARGV *args;                 /* argument vector */
@@ -45,6 +50,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..3eb824c97513c5cd5b35d7ca40c7625a6bb298a9 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,23 @@ 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) {
-           serv->addr_list.inet = 0;           /* wild-card */
+       atmp = inet_parse(name, &host, &port);
+       if (*host) {
+           serv->flags |= MASTER_FLAG_INETHOST;/* host:port */
+           MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *)
+               mymalloc(sizeof(*MASTER_INET_ADDRLIST(serv)));
+           inet_addr_list_init(MASTER_INET_ADDRLIST(serv));
+           inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
+           serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
+       } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
+           MASTER_INET_ADDRLIST(serv) = 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;
+           MASTER_INET_ADDRLIST(serv) = own_inet_addr_list();  /* virtual */
+           serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
        }
+       MASTER_INET_PORT(serv) = mystrdup(port);
+       myfree(atmp);
     } else if (STR_SAME(transport, MASTER_XPORT_NAME_UNIX)) {
        serv->type = MASTER_SERV_TYPE_UNIX;
        serv->listen_fd_count = 1;
@@ -449,6 +464,12 @@ void    free_master_ent(MASTER_SERV *serv)
     /*
      * Undo what get_master_ent() created.
      */
+    if (serv->flags & MASTER_FLAG_INETHOST) {
+       inet_addr_list_free(MASTER_INET_ADDRLIST(serv));
+       myfree((char *) MASTER_INET_ADDRLIST(serv));
+    }
+    if (serv->type == MASTER_SERV_TYPE_INET)
+       myfree(MASTER_INET_PORT(serv));
     myfree(serv->name);
     myfree(serv->path);
     argv_free(serv->args);
index d7020ac42ab30f6791a21a6e3f60ef69c06506af..c126e357fd6ccd03da8be55ebac5824f2bcf8a33 100644 (file)
@@ -106,15 +106,16 @@ void    master_listen_init(MASTER_SERV *serv)
         * bound to specific interface addresses.
         */
     case MASTER_SERV_TYPE_INET:
-       if (serv->addr_list.inet == 0) {        /* wild-card */
+       if (MASTER_INET_ADDRLIST(serv) == 0) {  /* wild-card */
            serv->listen_fd[0] =
-               inet_listen(serv->name, serv->max_proc > var_proc_limit ?
+               inet_listen(MASTER_INET_PORT(serv),
+                           serv->max_proc > var_proc_limit ?
                            serv->max_proc : var_proc_limit, NON_BLOCKING);
            close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
-       } else {                                /* virtual */
+       } else {                                /* virtual or host:port */
            for (n = 0; n < serv->listen_fd_count; n++) {
-               end_point = concatenate(inet_ntoa(serv->addr_list.inet->addrs[n]),
-                                       ":", serv->name, (char *) 0);
+               end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
+                                  ":", MASTER_INET_PORT(serv), (char *) 0);
                serv->listen_fd[n]
                    = inet_listen(end_point, serv->max_proc > var_proc_limit ?
                             serv->max_proc : var_proc_limit, NON_BLOCKING);
index 79004fb40e064178050af209eea4d3fbb71a6c42..2b1552c60c194d3d4137a48f780213279eb01772 100644 (file)
@@ -315,7 +315,7 @@ static int parse_callback(int type, VSTRING *buf, char *context)
 
 /* expand_argv - expand macros in the argument vector */
 
-static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list, long data_size)
+static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list)
 {
     VSTRING *buf = vstring_alloc(100);
     ARGV   *result;
@@ -710,7 +710,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
     vstring_sprintf(buf, "%ld", (long) request->data_size);
     dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf));
     vstring_free(buf);
-    expanded_argv = expand_argv(attr.command, rcpt_list, request->data_size);
+    expanded_argv = expand_argv(attr.command, rcpt_list);
     export_env = argv_split(var_export_environ, ", \t\r\n");
 
     command_status = pipe_command(request->fp, why,
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..d93043b82fbead1fb4ce8c2a8e5a7b823c2c97ec 100644 (file)
 /*     Allow untrusted clients to specify addresses with sender-specified
 /*     routing.  Enabling this opens up nasty relay loopholes involving
 /*     trusted backup MX hosts.
-/* .IP \fBrestriction_classes\fR
+/* .IP \fBsmtpd_restriction_classes\fR
 /*     Declares the name of zero or more parameters that contain a
 /*     list of UCE restrictions. The names of these parameters can
 /*     then be used instead of the restriction lists that they represent.
@@ -523,6 +523,7 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
     int     naddr;
     int     non_addr;
     char   *err = 0;
+    char   *junk;
 
     /*
      * Special case.
@@ -544,7 +545,13 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
      */
     if (msg_verbose)
        msg_info("%s: input: %s", myname, STR(arg->vstrval));
-    tree = tok822_parse(STR(arg->vstrval));
+    if (STR(arg->vstrval)[0] == '<'
+       && STR(arg->vstrval)[LEN(arg->vstrval) - 1] == '>') {
+       junk = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2);
+       tree = tok822_parse(junk);
+       myfree(junk);
+    } else
+       tree = tok822_parse(STR(arg->vstrval));
 
     /*
      * Find trouble.
@@ -823,9 +830,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..656a652ba66721d6521911fe285127f752252036 100644 (file)
 /*     SMTPD_STATE *state;
 /*     char    *recipient;
 /*
+/*     char    *smtpd_check_rcptmap(state, recipient)
+/*     SMTPD_STATE *state;
+/*     char    *recipient;
+/*
 /*     char    *smtpd_check_etrn(state, destination)
 /*     SMTPD_STATE *state;
 /*     char    *destination;
 /*     Restrictions on the recipient address that is sent with the RCPT
 /*     TO command.
 /* .PP
+/*     smtpd_check_rcptmap() validates the recipient address provided
+/*     with an RCPT TO request. Relevant configuration parameters:
+/* .IP local_recipients_map
+/*     Tables of user names (not addresses) that exist in $mydestination.
+/*     Mail for local users not in these tables is rejected.
+/* .PP
 /*     smtpd_check_etrn() validates the domain name provided with the
 /*     ETRN command, and other client-provided information. Relevant
 /*     configuration parameters:
@@ -565,6 +575,43 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
     return (SMTPD_CHECK_REJECT);
 }
 
+/* reject_dict_retry - reject with temporary failure if dict lookup fails */
+
+static void reject_dict_retry(SMTPD_STATE *state, const char *reply_name)
+{
+    longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_RESOURCE,
+                                       "%d <%s>: Temporary lookup failure",
+                                               451, reply_name));
+}
+
+/* check_maps_find - reject with temporary failure if dict lookup fails */
+
+static const char *check_maps_find(SMTPD_STATE *state, const char *reply_name,
+                                    MAPS *maps, const char *key, int flags)
+{
+    const char *result;
+
+    dict_errno = 0;
+    if ((result = maps_find(maps, key, flags)) == 0
+       && dict_errno == DICT_ERR_RETRY)
+       reject_dict_retry(state, reply_name);
+    return (result);
+}
+
+/* check_mail_addr_find - reject with temporary failure if dict lookup fails */
+
+static const char *check_mail_addr_find(SMTPD_STATE *state, const char *reply_name,
+                                   MAPS *maps, const char *key, char **ext)
+{
+    const char *result;
+
+    dict_errno = 0;
+    if ((result = mail_addr_find(maps, key, ext)) == 0
+       && dict_errno == DICT_ERR_RETRY)
+       reject_dict_retry(state, reply_name);
+    return (result);
+}
+
 /* reject_unknown_client - fail if client hostname is unknown */
 
 static int reject_unknown_client(SMTPD_STATE *state)
@@ -769,7 +816,7 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
     return (SMTPD_CHECK_DUNNO);
 }
 
-static int permit_auth_destination(char *recipient);
+static int permit_auth_destination(SMTPD_STATE *state, char *recipient);
 
 /* check_relay_domains - OK/FAIL for message relaying */
 
@@ -790,7 +837,7 @@ static int check_relay_domains(SMTPD_STATE *state, char *recipient,
     /*
      * Permit authorized destinations.
      */
-    if (permit_auth_destination(recipient) == SMTPD_CHECK_OK)
+    if (permit_auth_destination(state, recipient) == SMTPD_CHECK_OK)
        return (SMTPD_CHECK_OK);
 
     /*
@@ -803,7 +850,7 @@ static int check_relay_domains(SMTPD_STATE *state, char *recipient,
 
 /* permit_auth_destination - OK for message relaying */
 
-static int permit_auth_destination(char *recipient)
+static int permit_auth_destination(SMTPD_STATE *state, char *recipient)
 {
     char   *myname = "permit_auth_destination";
     char   *domain;
@@ -830,7 +877,8 @@ static int permit_auth_destination(char *recipient)
      * virtual_maps.
      */
     if (resolve_local(domain)
-       || (*var_virtual_maps && maps_find(virtual_maps, domain, 0)))
+       || (*var_virtual_maps
+           && check_maps_find(state, recipient, virtual_maps, domain, 0)))
        return (SMTPD_CHECK_OK);
 
     /*
@@ -863,7 +911,7 @@ static int reject_unauth_destination(SMTPD_STATE *state, char *recipient)
     /*
      * Skip authorized destination.
      */
-    if (permit_auth_destination(recipient) == SMTPD_CHECK_OK)
+    if (permit_auth_destination(state, recipient) == SMTPD_CHECK_OK)
        return (SMTPD_CHECK_DUNNO);
 
     /*
@@ -936,7 +984,7 @@ static int has_my_addr(char *host)
 
 /* permit_mx_backup - permit use of me as MX backup for recipient domain */
 
-static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
+static int permit_mx_backup(SMTPD_STATE *state, const char *recipient)
 {
     char   *myname = "permit_mx_backup";
     char   *domain;
@@ -963,7 +1011,8 @@ static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient)
        return (SMTPD_CHECK_OK);
     domain += 1;
     if (resolve_local(domain)
-       || (*var_virtual_maps && maps_find(virtual_maps, domain, 0)))
+       || (*var_virtual_maps
+           && check_maps_find(state, recipient, virtual_maps, domain, 0)))
        return (SMTPD_CHECK_OK);
 
     if (msg_verbose)
@@ -1104,7 +1153,8 @@ static int reject_unknown_address(SMTPD_STATE *state, char *addr,
        return (SMTPD_CHECK_DUNNO);
     domain += 1;
     if (resolve_local(domain)
-       || (*var_virtual_maps && maps_find(virtual_maps, domain, 0)))
+       || (*var_virtual_maps
+           && check_maps_find(state, reply_name, virtual_maps, domain, 0)))
        return (SMTPD_CHECK_DUNNO);
     if (domain[0] == '#')
        return (SMTPD_CHECK_DUNNO);
@@ -1440,6 +1490,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.
      */
@@ -1656,7 +1714,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
                status = permit_mx_backup(state, state->recipient);
        } else if (strcasecmp(name, PERMIT_AUTH_DEST) == 0) {
            if (state->recipient)
-               status = permit_auth_destination(state->recipient);
+               status = permit_auth_destination(state, state->recipient);
        } else if (strcasecmp(name, REJECT_UNAUTH_DEST) == 0) {
            if (state->recipient)
                status = reject_unauth_destination(state, state->recipient);
@@ -1925,6 +1983,7 @@ char   *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
     char   *myname = "smtpd_check_rcptmap";
     char   *saved_recipient;
     char   *domain;
+    int     status;
 
     /*
      * XXX This module does a lot of unnecessary guessing. This functionality
@@ -1940,6 +1999,13 @@ char   *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
      */
     SMTPD_CHECK_PUSH(saved_recipient, state->recipient, recipient);
 
+    /*
+     * Return here in case of serious trouble.
+     */
+    if ((status = setjmp(smtpd_check_buf)) != 0)
+       SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ?
+                               STR(error_text) : 0);
+
     /*
      * Resolve the address.
      */
@@ -1958,12 +2024,13 @@ char   *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
            SMTPD_CHECK_RCPT_RETURN(0);
 
 #define NOMATCH(map, rcpt) \
-    (mail_addr_find(map, rcpt, (char **) 0) == 0 && dict_errno == 0)
+    (check_mail_addr_find(state, recipient, map, rcpt, (char **) 0) == 0)
 
     /*
      * Reject mail to unknown addresses in Postfix-style virtual domains.
      */
-    if (*var_virtual_maps && maps_find(virtual_maps, domain, 0)) {
+    if (*var_virtual_maps
+       && (check_maps_find(state, recipient, virtual_maps, domain, 0))) {
        if (NOMATCH(rcpt_canon_maps, STR(reply.recipient))
            && NOMATCH(canonical_maps, STR(reply.recipient))
            && NOMATCH(relocated_maps, STR(reply.recipient))
@@ -2067,8 +2134,10 @@ char   *var_notify_classes = "";
   * String-valued configuration parameters.
   */
 char   *var_maps_rbl_domains;
+char   *var_myorigin;
 char   *var_mydest;
 char   *var_inet_interfaces;
+char   *var_rcpt_delim;
 char   *var_rest_classes;
 char   *var_alias_maps;
 char   *var_rcpt_canon_maps;
@@ -2085,8 +2154,10 @@ typedef struct {
 
 static STRING_TABLE string_table[] = {
     VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains,
+    VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin,
     VAR_MYDEST, DEF_MYDEST, &var_mydest,
     VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces,
+    VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim,
     VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes,
     VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps,
     VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps,
@@ -2250,6 +2321,33 @@ void    resolve_clnt_init(RESOLVE_REPLY *reply)
     reply->recipient = vstring_alloc(100);
 }
 
+#ifdef USE_SASL_AUTH
+
+bool    var_smtpd_sasl_enable = 0;
+
+/* smtpd_sasl_connect - stub */
+
+void    smtpd_sasl_connect(SMTPD_STATE *state)
+{
+    msg_panic("smtpd_sasl_connect was called");
+}
+
+/* smtpd_sasl_disconnect - stub */
+
+void    smtpd_sasl_disconnect(SMTPD_STATE *state)
+{
+    msg_panic("smtpd_sasl_disconnect was called");
+}
+
+/* permit_sasl_auth - stub */
+
+int     permit_sasl_auth(SMTPD_STATE *state, int ifyes, int ifnot)
+{
+    return (ifnot);
+}
+
+#endif
+
 /* canon_addr_internal - stub */
 
 VSTRING *canon_addr_internal(VSTRING *result, const char *addr)
@@ -2362,7 +2460,31 @@ main(int argc, char **argv)
            /*
             * Try config settings.
             */
+#define UPDATE_MAPS(ptr, var, val, lock) \
+       { if (ptr) maps_free(ptr); ptr = maps_create(var, val, lock); }
+
        case 2:
+           if (strcasecmp(args->argv[0], "virtual_maps") == 0) {
+               UPDATE_STRING(var_virtual_maps, args->argv[1]);
+               UPDATE_MAPS(virtual_maps, VAR_VIRTUAL_MAPS,
+                           var_virtual_maps, DICT_FLAG_LOCK);
+               resp = 0;
+               break;
+           }
+           if (strcasecmp(args->argv[0], "local_recipient_maps") == 0) {
+               UPDATE_STRING(var_local_rcpt_maps, args->argv[1]);
+               UPDATE_MAPS(local_rcpt_maps, VAR_LOCAL_RCPT_MAPS,
+                           var_local_rcpt_maps, DICT_FLAG_LOCK);
+               resp = 0;
+               break;
+           }
+           if (strcasecmp(args->argv[0], "canonical_maps") == 0) {
+               UPDATE_STRING(var_canonical_maps, args->argv[1]);
+               UPDATE_MAPS(canonical_maps, VAR_CANONICAL_MAPS,
+                           var_canonical_maps, DICT_FLAG_LOCK);
+               resp = 0;
+               break;
+           }
            if (strcasecmp(args->argv[0], "mynetworks") == 0) {
                namadr_list_free(mynetworks);
                mynetworks = namadr_list_init(args->argv[1]);
@@ -2400,7 +2522,8 @@ main(int argc, char **argv)
                UPDATE_STRING(state.sender, args->argv[1]);
            } else if (strcasecmp(args->argv[0], "rcpt") == 0) {
                state.where = "RCPT";
-               resp = smtpd_check_rcpt(&state, args->argv[1]);
+               (resp = smtpd_check_rcpt(&state, args->argv[1]))
+                   || (resp = smtpd_check_rcptmap(&state, args->argv[1]));
            }
            break;
 
index 02e11e9e9e568fbce9b7e91509caf97151ec6cdc..f7c3cdd709d0e8bfda7f642f6837c708128a53d6 100644 (file)
@@ -111,12 +111,12 @@ rcpt foo@porcupine.org
 #
 # MX backup
 #
-mydestination spike.porcupine.org,localhost.porcupine.org
-inet_interfaces 168.100.189.2,127.0.0.1
-recipient_restrictions permit_mx_backup,reject
-rcpt wietse@wzv.win.tue.nl
-rcpt wietse@trouble.org
-rcpt wietse@porcupine.org
+#mydestination spike.porcupine.org,localhost.porcupine.org
+#inet_interfaces 168.100.189.2,127.0.0.1
+#recipient_restrictions permit_mx_backup,reject
+#rcpt wietse@wzv.win.tue.nl
+#rcpt wietse@trouble.org
+#rcpt wietse@porcupine.org
 #
 # Deferred restrictions
 #
diff --git a/postfix/src/smtpd/smtpd_check.in3 b/postfix/src/smtpd/smtpd_check.in3
new file mode 100644 (file)
index 0000000..4d2dedb
--- /dev/null
@@ -0,0 +1,27 @@
+#msg_verbose 1
+smtpd_delay_reject 0
+mynetworks 127.0.0.0/8,168.100.189.0/28
+relay_domains porcupine.org
+local_recipient_maps unix:passwd.byname
+client unknown 131.155.210.17
+canonical_maps tcp:localhost:200
+#
+recipient_restrictions permit
+rcpt no.such.user@[127.0.0.1]
+#
+virtual_maps tcp:localhost:100
+#
+recipient_restrictions permit_mx_backup
+rcpt wietse@nowhere1.com
+#
+recipient_restrictions check_relay_domains
+rcpt wietse@nowhere2.com
+#
+recipient_restrictions reject_unknown_recipient_domain
+rcpt wietse@nowhere3.com
+#
+recipient_restrictions permit_auth_destination
+rcpt wietse@nowhere4.com
+#
+recipient_restrictions reject_unauth_destination
+rcpt wietse@nowhere5.com
index b631b3c86bdf47616d22c02813702753c5f1e351..b63c3f7054554efe9be72e275e2d6b59e10a9eed 100644 (file)
@@ -47,8 +47,6 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> helo foo.
-./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
-./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
 ./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <foo.>: Helo command rejected: Host not found
 450 <foo.>: Helo command rejected: Host not found
 >>> helo foo
@@ -66,9 +64,6 @@ OK
 >>> helo_restrictions reject_invalid_hostname,reject_unknown_hostname
 OK
 >>> helo 123.123.123.123
-./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
-./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
-./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
 ./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <123.123.123.123>: Helo command rejected: Host not found
 450 <123.123.123.123>: Helo command rejected: Host not found
 >>> helo_restrictions permit_naked_ip_address,reject_invalid_hostname,reject_unknown_hostname
@@ -186,8 +181,8 @@ OK
 >>> client spike.porcupine.org 168.100.189.2
 OK
 >>> client foo 127.0.0.2
-./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
-554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
+./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
+554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
 >>> #
 >>> # Hybrids
 >>> #
@@ -215,7 +210,6 @@ OK
 ./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <bad.domain>: Helo command rejected: match bad.domain; from=<foo@friend.bad.domain> to=<foo@porcupine.org>
 554 <bad.domain>: Helo command rejected: match bad.domain
 >>> helo 131.155.210.17
-./smtpd_check: warning: valid_hostname: numeric hostname: 131.155.210.17
 OK
 >>> rcpt foo@porcupine.org
 OK
@@ -234,19 +228,12 @@ OK
 >>> #
 >>> # MX backup
 >>> #
->>> mydestination spike.porcupine.org,localhost.porcupine.org
-OK
->>> inet_interfaces 168.100.189.2,127.0.0.1
-OK
->>> recipient_restrictions permit_mx_backup,reject
-OK
->>> rcpt wietse@wzv.win.tue.nl
-OK
->>> rcpt wietse@trouble.org
-./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <wietse@trouble.org>: Recipient address rejected: Access denied; from=<foo@friend.bad.domain> to=<wietse@trouble.org>
-554 <wietse@trouble.org>: Recipient address rejected: Access denied
->>> rcpt wietse@porcupine.org
-OK
+>>> #mydestination spike.porcupine.org,localhost.porcupine.org
+>>> #inet_interfaces 168.100.189.2,127.0.0.1
+>>> #recipient_restrictions permit_mx_backup,reject
+>>> #rcpt wietse@wzv.win.tue.nl
+>>> #rcpt wietse@trouble.org
+>>> #rcpt wietse@porcupine.org
 >>> #
 >>> # Deferred restrictions
 >>> #
@@ -316,68 +303,52 @@ OK
 >>> helo [1.2.3.4]
 OK
 >>> helo [321.255.255.255]
-./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[321.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[321.255.255.255]>: Helo command rejected: invalid ip address
 >>> helo [0.255.255.255]
-./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[0.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[0.255.255.255]>: Helo command rejected: invalid ip address
 >>> helo [1.2.3.321]
-./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.321]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[1.2.3.321]>: Helo command rejected: invalid ip address
 >>> helo [1.2.3]
-./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[1.2.3]>: Helo command rejected: invalid ip address
 >>> helo [1.2.3.4.5]
-./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address
 >>> helo [1..2.3.4]
-./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1..2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[1..2.3.4]>: Helo command rejected: invalid ip address
 >>> helo [.1.2.3.4]
-./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[.1.2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[.1.2.3.4]>: Helo command rejected: invalid ip address
 >>> helo [1.2.3.4.5.]
-./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address; from=<foo>
 501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address
 >>> helo 1.2.3.4
 OK
 >>> helo 321.255.255.255
-./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <321.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
 501 <321.255.255.255>: Helo command rejected: invalid ip address
 >>> helo 0.255.255.255
-./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <0.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
 501 <0.255.255.255>: Helo command rejected: invalid ip address
 >>> helo 1.2.3.321
-./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.321>: Helo command rejected: invalid ip address; from=<foo>
 501 <1.2.3.321>: Helo command rejected: invalid ip address
 >>> helo 1.2.3
-./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3>: Helo command rejected: invalid ip address; from=<foo>
 501 <1.2.3>: Helo command rejected: invalid ip address
 >>> helo 1.2.3.4.5
-./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5>: Helo command rejected: invalid ip address; from=<foo>
 501 <1.2.3.4.5>: Helo command rejected: invalid ip address
 >>> helo 1..2.3.4
-./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1..2.3.4>: Helo command rejected: invalid ip address; from=<foo>
 501 <1..2.3.4>: Helo command rejected: invalid ip address
 >>> helo .1.2.3.4
-./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <.1.2.3.4>: Helo command rejected: invalid ip address; from=<foo>
 501 <.1.2.3.4>: Helo command rejected: invalid ip address
 >>> helo 1.2.3.4.5.
-./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
 ./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5.>: Helo command rejected: invalid ip address; from=<foo>
 501 <1.2.3.4.5.>: Helo command rejected: invalid ip address
index 155cb6104d1c7a38b4c8b534d70eb7aa98f9de1f..c8d014f6000a2013ba125cd0f53188be04513864 100644 (file)
@@ -47,8 +47,6 @@ OK
 >>> client foo 123.123.123.123
 OK
 >>> helo foo.
-./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
-./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
 ./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <foo.>: Helo command rejected: Host not found
 450 <foo.>: Helo command rejected: Host not found
 >>> helo foo
@@ -174,8 +172,8 @@ OK
 >>> client spike.porcupine.org 168.100.189.2
 OK
 >>> client foo 127.0.0.2
-./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
-554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
+./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
+554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
 >>> #
 >>> # unknown sender/recipient domain
 >>> #
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]);
index 1409746c6d9a7a8ce1ca2c451dd99889e321e798..44834c36fb5111dc8727b404fa8ee5a677e06fa3 100644 (file)
@@ -112,8 +112,6 @@ static const char *dict_unix_getgrnam(DICT *unused_dict, const char *key)
 
 static void dict_unix_close(DICT *dict)
 {
-    DICT_UNIX *dict_unix = (DICT_UNIX *) dict;
-
     dict_free(dict);
 }