]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20001029
authorWietse Venema <wietse@porcupine.org>
Sun, 29 Oct 2000 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:26:52 +0000 (06:26 +0000)
28 files changed:
postfix/DB_README
postfix/HISTORY
postfix/LDAP_README
postfix/RELEASE_NOTES
postfix/conf/main.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-smtp.cf
postfix/examples/chroot-setup/LINUX2
postfix/html/faq.html
postfix/html/lmtp.8.html
postfix/html/smtp.8.html
postfix/makedefs
postfix/man/man8/lmtp.8
postfix/man/man8/smtp.8
postfix/src/flush/flush.c
postfix/src/fsstone/fsstone [deleted file]
postfix/src/global/mail_version.h
postfix/src/lmtp/lmtp.c
postfix/src/lmtp/lmtp_connect.c
postfix/src/lmtp/lmtp_proto.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/smtpstone/smtp-source.c
postfix/src/util/dict_db.c
postfix/src/util/dict_ldap.c
postfix/src/util/dict_open.c

index 103fdc1cd5362590c1f0f39d05bafc48e1ec5f59..6f6b3dc2da71812d3e8f45f56fa08ee739bd71c6 100644 (file)
@@ -1,21 +1,68 @@
 Purpose of this document
 ========================
 
-This document describes how to build Postfix with Berkeley DB
-support on systems that ship without DB library. The canonical
-third-party source for Berkeley DB is www.sleepycat.com.
+This document describes how to build Postfix with third-party
+Berkeley DB from www.sleepycat.com, or how to choose a specific
+Berkeley DB version when your system provides multiple implementations.
 
-The information can also be used to build Postfix with a non-default
-Berkeley DB version. However, the file formats of Berkeley DB
-version 2 and later are not compatible with the older Berkeley DB
-version that ships with, for example, 4.4BSD.
+Building Postfix with Sleepycat Berkeley DB
+===========================================
 
-Building Postfix with third-party Berkeley DB support
-=====================================================
+Many commercial UNIXes ship without Berkeley DB support. Examples
+are Solaris, HP-UX, IRIX, UNIXWARE. In order to build Postfix with
+Berkeley DB support you need to download and install the source
+code from www.sleepycat.com.
 
-If you installed the Berkeley DB from Sleepycat, use something like:
+To build Postfix after you installed the Berkeley DB from Sleepycat,
+use something like:
 
     % make tidy
-    % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \
-       AUXLIBS=/usr/local/BerkeleyDB/lib/libdb.a
+    % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB.3.1/include" \
+       AUXLIBS=/usr/local/BerkeleyDB.3.1/lib/libdb.a
     % make
+
+The exact pathnames depend on the DB version that you installed.
+For example, Berkeley DB version 2 installs in /usr/local/BerkeleyDB.
+
+Beware, the file format produced by Berkeley DB version 1 is not
+compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files.
+
+Building Postfix on BSD systems with a specific Berkeley DB version
+===================================================================
+
+Some BSD systems ship with multiple Berkeley DB implementations.
+Normally, Postfix builds with the default DB version that ships
+with the system.
+
+To build Postfix on BSD systems with a specific DB version, use a
+variant of the following commands:
+
+    % make tidy
+    % make makefiles CCARGS=-I/usr/include/db2 AUXLIBS=-ldb2
+    % make
+
+Beware, the file format produced by Berkeley DB version 1 is not
+compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files.
+
+Building Postfix on Linux with a specific Berkeley DB version
+=============================================================
+
+Some Linux systems systems ship with multiple Berkeley DB
+implementations.  Normally, Postfix builds with the default DB
+version that ships with the system.
+
+On Linux, you need to edit the makedefs script in order to specify
+a non-default DB library.
+
+The reason is that the location of the default db.h include file
+changes randomly between vendors and between versions, so that
+Postfix has to choose the file for you.
+
+Beware, the file format produced by Berkeley DB version 1 is not
+compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files.
index f29bd449be00c5153dfa0b07d055f6a4d61b7062..96dceb72f3c5a708042c19a35e2b249507db91b6 100644 (file)
@@ -4358,12 +4358,12 @@ Apologies for any names omitted.
        the [] or host:port syntax, and there was no way to suppress
        MX record lookups. Files: smtp/smtp_addr.c, smtp/smtp_connect.c.
 
-       Convenience: you can now specify multiple destinations in
-       the relayhost or fallback_relay configuration parameters.
+       Convenience: you can now specify multiple SMTP destinations
+       in the relayhost or fallback_relay configuration parameters.
        The specified destinations will be tried in the specified
        order. File:  smtp/smtp_connect.c.
 
-       Typographical corrections by Matthias Andree.
+       Many typographical corrections by Matthias Andree.
 
 20001024
 
@@ -4380,13 +4380,13 @@ Apologies for any names omitted.
 
        Horror:  postmap and postalias (newaliases) silently lose
        the file lock while building a lookup table with Berkeley
-       DB 2.x and later on Solaris, HP-UX or IRIX.  The result is
-       that table lookups fail while the table is being built, so
-       that mail is lost.  In order to avoid this misbehavior one
-       has to use an undocumented feature that is NOT available
-       with the DB1.85 compatibility interface.  Therefore, Postfix
-       now supports three Berkeley DB programming interfaces of
-       increasing complexity. File: util/dict_db.c.
+       DB 2.x and later on Solaris, HP-UX, IRIX, and UNIXWARE.
+       The result is that table lookups fail while the table is
+       being built, so that mail is lost.  In order to avoid this
+       misbehavior one has to use an undocumented feature that is
+       NOT available with the DB1.85 compatibility interface.
+       Therefore, Postfix now supports three Berkeley DB programming
+       interfaces of increasing complexity. File: util/dict_db.c.
 
        Bugfix: some character manipulations were not portable for
        signed/unsigned characters. Files: global/quote_821_local.c,
@@ -4396,3 +4396,25 @@ Apologies for any names omitted.
        begins with "From sender time-stamp". Sendmail silently
        ignores such RFC violating garbage, and therefore Postfix
        needs to jump another hoop.  File: smtpd/smtpd.c.
+
+20001028
+
+       Bugfix: the flush server tried to access config files after
+       going to the chroot jail. Found by Lutz Jaenicke, TU-Cottbus.DE.
+       File: flush/flush.c.
+
+       Update: revised LDAP module from primary maintainer John
+       Hensley, with contributions from many other people. Files:
+       util/dict_ldap.c, LDAP_README.
+
+       Update: LINUX2 chroot setup script by Matthias Andree,
+       uni-dortmund.de.
+
+       Feature: specify unix:/path/name for LMTP connections over
+       UNIX-domain sockets, and specify inet:host or inet:host:port
+       for IPV4. If no unix: or inet: is specified, IPV4 is assumed.
+       File: lmtp/lmtp_connect.c.
+
+       Feature: added UNIX-domain support to the smtpstone test
+       programs in order to test the LMTP client UNIX-domain
+       support.
index 50b020ed1a7ce0522539af2b12171aeeaae1bcc9..9dca5663cc3d7ee99339574b348ea8b7e72890df 100644 (file)
@@ -82,10 +82,22 @@ parameter below, "server_host", would be defined in main.cf as
        substitute for the address Postfix is trying to resolve, e.g.
                ldapsource_query_filter = (&(mail=%s)(paid_up=true))
 
+    domain (No default; you must configure this.)
+       This is a list of domain names, paths to files, or dictionaries.
+       If specified, only lookups ending in a domain on this list will
+       be searched. This can significantly reduce the query load on the 
+       LDAP server.
+               ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains
+
     result_attribute (maildrop)
-       The attribute Postfix will read from any directory entries
+       The attribute(s) Postfix will read from any directory entries
        returned by the lookup, to be resolved to an email address.
-               ldapsource_result_attribute = mailbox
+               ldapsource_result_attribute = mailbox,maildrop
+
+    special_result_attribute (No default)
+       The attribute(s) of directory entries that can contain DNs or URLs.
+       If found, a recursive subsequent search is done using their values.
+               ldapsource_special_result_attribute = member
 
     scope (sub)
         The LDAP search scope: sub, base, or one. These translate into
@@ -147,8 +159,11 @@ configuration routines understand how to deal with quoted strings.
 EXAMPLES
 ========
 
-Here's a basic example for using LDAP to look up aliases. In main.cf,
-you have these configuration parameters defined:
+ALIASES
+-------
+
+Here's a basic example for using LDAP to look up aliases. Assume that in
+main.cf, you have these configuration parameters defined:
 
 alias_maps = hash:/etc/aliases, ldap:ldapsource
 ldapsource_server_host = ldap.my.com
@@ -162,39 +177,52 @@ read the "maildrop" attributes of those found, and build a list of their
 maildrops, which will be treated as RFC822 addresses to which the
 message will be delivered.
 
+VIRTUAL DOMAINS/ADDRESSES
+-------------------------
+
 If you want to keep information for virtual lookups in your directory,
-it's only a little more complicated. You'll want to make sure all of
-your virtual mailacceptinggeneralid attributes are fully qualified with
-their virtual domains. If you want to designate a directory entry as the
+it's only a little more complicated. First you need to make sure Postfix
+knows about the virtual domain. An easy way to do that is to add the
+domain to the mailacceptinggeneralid attribute of some entry in the
+directory. Next you'll want to make sure all of your virtual recipients'
+mailacceptinggeneralid attributes are fully qualified with their virtual
+domains. Finally, if you want to designate a directory entry as the
 default user for a virtual domain, just give it an additional
 mailacceptinggeneralid (or the equivalent in your directory) of
-"@virtual.dom". That's right, no user part.
-
-If you want to get information for relay_domains out of your directory,
-the simplest way to get it is to add the domain name (without even the
-'@') as a mailacceptinggeneralid to some recipient in each domain, then
-add "$virtual_maps" to your relay_domains line. Then you can use the
-same map you use to find virtual recipients to determine if a domain is
-a valid virtual domain and should be allowed to relay.
-
-For example, the catchall user for a virtual domain might look like
-this:
-
-   dn: cn=defaultrecipient, dc=fake, dc=dom
-   objectclass: top
-   objectclass: rfc822mailgroup
-   cn: defaultrecipient
-   owner: uid=root, dc=someserver, dc=isp, dc=dom
-   mailacceptinggeneralid: fake.dom
-   mailacceptinggeneralid: @fake.dom
-   maildrop: realuser@real.dom         
-
-If you don't necessarily have a catchall user for the domain (i.e. you
-want mail to unknown users in the domain to bounce), and don't want to
-tag an arbitrary user in the virtual domain, you might define another
-LDAP map that finds your virtual domain's domain object entry, and add
-that map to relay_domains instead of "$virtual_maps". All that's
-necessary is that a search for the domain name return something.
+"@virtual.dom". That's right, no user part. If you don't want a catchall
+user, omit this step and mail to unknown users in the domain will simply
+bounce.
+
+If you're using a version of Postfix newer than 19991226, that should do
+it. If not, you also need to add your virtual domains to relay_domains.
+Simply add "$virtual_maps" to your relay_domains line. Then you can use
+the same map you use to find virtual recipients to determine if a domain
+is a valid virtual domain and should be allowed to relay.
+
+In summary, you might have a catchall user for a virtual domain that
+looks like this:
+
+       dn: cn=defaultrecipient, dc=fake, dc=dom
+       objectclass: top
+       objectclass: virtualaccount
+       cn: defaultrecipient
+       owner: uid=root, dc=someserver, dc=isp, dc=dom
+  1 -> mailacceptinggeneralid: fake.dom
+  2 -> mailacceptinggeneralid: @fake.dom
+  3 -> maildrop: realuser@real.dom         
+
+1: Postfix knows fake.dom is a valid virtual domain when it looks for
+   this and gets something (the maildrop) back.
+
+2: This causes any mail for unknown users in fake.dom to go to this entry ...
+
+3: ... and then to its maildrop.
+
+Normal users might simply have one mailacceptinggeneralid and maildrop,
+e.g. "normaluser@fake.dom" and "normaluser@real.dom".
+
+OTHER USES
+----------
 
 Other common uses for LDAP lookups include rewriting senders and
 recipients with Postfix' canonical lookups, for example in order to make
@@ -204,6 +232,11 @@ instead of "userid@site.dom".
 NOTES AND THINGS TO THINK ABOUT
 ===============================
 
+- The bits of schema and attribute names used in this document are just
+  examples. There's nothing special about them, other than that some are
+  the defaults in the LDAP configuration parameters. You can use
+  whatever schema you like, and configure Postfix accordingly. 
+
 - You probably want to make sure that mailacceptinggeneralids are
   unique, and that not just anyone can specify theirs as postmaster or
   root, say.
@@ -266,17 +299,17 @@ contents, please include the applicable bits of some directory entries.
 CREDITS
 =======
 
-Support for LDAP was initially written by Prabhat K Singh of VSNL,
-Bombay, India, and then hideously bloated by John Hensley to support
-multiple sources and more configurable attributes. The caching bits were
-initially worked out by Prabhat, then munged to support the multiple
-sources. 
-
-Other contributors, of code or direction or dope slaps, include:
-
-Manuel Guesdon
-Carsten Hoeger
-Keith Stevenson
-Samuel Tardieu
+Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
+John Hensley: Multiple LDAP sources with more configurable attributes.
+Carsten Hoeger: Search scope handling. 
+LaMont Jones: Domain restriction, URL and DN searches, multiple result
+              attributes.
+Mike Mattice: Alias dereferencing control.
+Hery Rakotoarisoa: Patches for LDAPv3 updating.
+Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
+Keith Stevenson: RFC 2254 escaping in queries.
+Samuel Tardieu: Noticed that searches could include wildcards, prompting
+                the work on RFC 2254 escaping in queries. Spotted a bug
+                in binding.
 
 And of course Wietse.
index 2f4e9b7f8f63309ddb8f3d0b41180f6881fd5b40..7842ce4d26ed9584e98bba77030df985f6bba72d 100644 (file)
@@ -1,17 +1,45 @@
-Incompatible changes with snapshot-20001027
+Incompatible changes with snapshot-20001029
 ===========================================
 
+If this release does not work for you, you can go back to a previous
+Postfix version without losing your mail, subject to the "incompatible
+changes" listed for previous Postfix releases below.
+
 Berkeley DB support has changed for Solaris, HP-UX, UNIXWARE, IRIX.
-You can no longer use the DB 1.85 compatibility interface, because
-that interface loses the file lock while building a table, so that
-table lookups fail and mail is lost. See the DB_README file for
-instructions on how to build with third-party Berkeley DB support.
+On these systems, Postfix must no longer use DB 1.85 compatibility
+mode, because that mode loses the file lock while building a table,
+so that table lookups fail and mail is lost. See the DB_README file
+for instructions on how to build Postfix with third-party Berkeley
+DB support.
 
 The "fast ETRN" policy configuration has changed. You now specify
 the list of eligible "fast ETRN" domains with the fast_flush_domains
 parameter (default: $relay_domains). In order to disable the feature,
 specify an empty value (fast_flush_domains =).
 
+Major changes with snapshot-20001029
+====================================
+
+This release ships with an updated LDAP client module that has better
+group support by Lamont Jones, and that has several other enhancements.
+Review the LDAP_README file for more information.
+
+The LMTP client can now make connections over UNIX-domain sockets
+in addition to IPV4.  For connections over UNIX-domain sockets,
+specify a transport table entry like:
+
+    domain.name                lmtp:unix:/path/name
+
+IPV4-based servers are still the default. The LMTP_README file
+still needs to be revised to account for this change. This is
+best done by someone who actually uses the Postfix LMTP client.
+
+You can now specify multiple SMTP destinations in the relayhost
+and fallback_relay configuration parameters. The destinations are
+tried in the specified order. Specify host or host:port (perform
+MX record lookups), [host] or [host]:port (no MX record lookups),
+[address] or [address]:port (numerical IP address).
+
 Incompatible changes with snapshot-20001005
 ===========================================
 
index e96e68d541e9e474aae904a0f553f6e44444b400..24274dd5c6cc2481fd84169d5ebae304131bcc71 100644 (file)
@@ -122,9 +122,12 @@ mail_owner = postfix
 # internal DNS uses no MX records, specify the name of the intranet
 # gateway host instead.
 #
-# Specify a domain, host, host:port, [host]:port, [address] or
-# [address]:port.  Use the form [name] to turn off MX lookups. See
-# also the default_transport parameter if you're connected via UUCP.
+# In the case of SMTP, specify a domain, host, host:port, [host]:port,
+# [address] or [address]:port; the form [host] turns off MX lookups.
+# If you specify multiple SMTP destinations, Postfix will try them
+# in the specified order.
+#
+# If you're connected via UUCP, see also the default_transport parameter.
 #
 # relayhost = $mydomain
 # relayhost = gateway.my.domain
index e5b134b36463f5fc3ed930df304c209ed93e7366..9efed230e0492563541b28f891ad938bbc6f057a 100644 (file)
@@ -245,9 +245,12 @@ recipient_delimiter =
 # internal DNS uses no MX records, specify the name of the intranet
 # gateway host instead.
 #
-# Specify a domain, host, host:port, [host]:port, [address] or
-# [address]:port.  Use the form [name] to turn off MX lookups. See
-# also the default_transport parameter if you're connected via UUCP.
+# In the case of SMTP, specify a domain, host, host:port, [host]:port,
+# [address] or [address]:port; the form [host] turns off MX lookups.
+# If you specify multiple SMTP destinations, Postfix will try them
+# in the specified order.
+#
+# If you're connected via UUCP, see also the default_transport parameter.
 #
 # relayhost = $mydomain
 # relayhost = gateway.my.domain
index c0fea6563c0f280c819ad5722377277a07d095bf..2359377f8dd56f920366e746ca0c1f80d2aa3206 100644 (file)
 # By default, mail is bounced when a destination is not found, and
 # delivery is deferred if a destination is unreachable.
 #
+# In the case of SMTP, specify a domain, host, host:port, [host]:port,
+# [address] or [address]:port; the form [host] turns off MX lookups.
+# If you specify multiple SMTP destinations, Postfix will try them
+# in the specified order.
+#
 fallback_relay = 
 
 # The ignore_mx_lookup_error parameter controls what happens when a
index 1d35e1c8ec0636f29d122cfe32302fb06de7f30d..78aaab251ac0658d3927d12a92b5c319f84a9dce 100644 (file)
@@ -1,16 +1,56 @@
-# Setup chroot jail for Linux
+#! /bin/sh
+
+# LINUX2 - shell script to set up a Postfix chroot jail for Linux
+# Tested on SuSE Linux 5.3 (libc5) and 6.4 (glibc2.1)
+
+# Copyright (c) 2000 by Matthias Andree
+# Redistributable unter the MIT-style license that follows:
+# Abstract: "do whatever you want except hold somebody liable or change
+# the copyright information".
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+cond_copy() {
+  # find files as per pattern in $1
+  # if any, copy to directory $2
+  dir=`dirname "$1"`
+  pat=`basename "$1"`
+  lr=`find "$dir" -name "$pat"`
+  if test ! -d "$2" ; then exit 1 ; fi
+  if test "x$lr" != "x" ; then cp -p $1 "$2" ; fi
+} 
 
 set -e
 umask 022
 
 POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
-
 cd ${POSTFIX_DIR}
 
-mkdir etc
-cp /etc/localtime /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
-mkdir -p usr/lib/zoneinfo
-ln -s /etc/localtime usr/lib/zoneinfo
+mkdir -p etc lib usr/lib/zoneinfo
+
+# find localtime (SuSE 5.3 does not have /etc/localtime)
+lt=/etc/localtime
+if test ! -f $lt ; then lt=/usr/lib/zoneinfo/localtime ; fi
+if test ! -f $lt ; then echo "cannot find localtime" ; exit 1 ; fi
+cp -p -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
+cp -p -f /etc/host.conf /etc/hosts /etc/passwd etc
+ln -s -f /etc/localtime usr/lib/zoneinfo
 
-mkdir lib
-cp /lib/libnss_* lib
+cond_copy '/lib/libnss_*' lib
+cond_copy '/lib/libresolv*' lib
\ No newline at end of file
index afaeaefe06d972377f64ac91d11fdaf3e3192eb6..0d54625ab79aafa5676faebca085f513f56024dd 100644 (file)
@@ -2592,79 +2592,11 @@ systems.
 <p>
 
 In order to build Postfix with <b>db</b> support on UNIX systems
-that do not have <b>db</b> support out of the box, you need the
-db-1.85 release, or <a href="http://www.sleepycat.com">the current
-version</a> which has a db-1.85 compatible interface.
-
-<p>
-
-To build with a third-party DB library, use the following commands
-in the Postfix top-level directory.
-On Solaris, the LD_LIBRARY_PATH unset commands may be required to
-avoid linking in the wrong libraries.
-
-<p>
-
-<pre>
-    % LD_LIBRARY_PATH=         (Bourne-shell syntax)
-    % unsetenv LD_LIBRARY_PATH (C-shell syntax)
-    % make tidy
-    % make makefiles CCARGS="-DHAS_DB -DPATH_DB_H='&lt;db_185.h&gt;' -I/some/where/include" AUXLIBS=/some/where/libdb.a
-    % make
-</pre>
-
-<p>
-
-Of course you will have to specify the actual location of the
-include directory and of the object library.
-
-<p>
-
-When building with a third-party DB library you may into one of the
-following problems:
-
-<p>
-
-<ul>
-
-<li> Older DB versions install a file
-<b>/usr/local/include/ndbm.h</b> that is incompatible with
-<b>/usr/include/ndbm.h</b>. Be sure to get rid of the bogus file.
-See the FAQ entry titled "<a href="#dbm_dirfno">Undefined symbols:
-dbm_pagfno, dbm_dirfno etc</a>".
-
-<p>
-
-<li>With Sleepcat DB 3.0.55, the linker will complain that dbopen()
-is not found. To fix, apply the following patch to the DB 3.0.55
-db_185.h include file:
-
-<p>
-<pre>
-*** db_185.h.orig       Tue Mar  7 16:27:32 2000
---- db_185.h    Tue Mar  7 16:27:44 2000
-***************
-*** 166,173 ****
-  #if defined(__cplusplus)
-  extern "C" {
-  #endif
-- #ifdef DB_LIBRARY_COMPATIBILITY_API
-  #define       dbopen  __db185_open
-  DB *__db185_open __P((const char *, int, int, DBTYPE, const void *));
-  #else
-  DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
---- 166,173 ----
-  #if defined(__cplusplus)
-  extern "C" {
-  #endif
-  #define       dbopen  __db185_open
-+ #ifdef DB_LIBRARY_COMPATIBILITY_API
-  DB *__db185_open __P((const char *, int, int, DBTYPE, const void *));
-  #else
-  DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
-</pre>
-
-</ul>
+that do not have <b>db</b> support out of the box, you can use the
+Berkeley DB source code from <a
+href="http://www.sleepycat.com">www.sleepycat.com</a>. See the file
+<b>DB_README</b> in the Postfix source code distribution for
+instructions on how to build Postfix with Sleepycat's Berkeley DB.
 
 <hr>
 
index f25917afa633ed322a1a89be0dfd97cef479fefe..661e570fc1e29b32be3d2fb105bf774dc9055cb8 100644 (file)
@@ -24,14 +24,31 @@ LMTP(8)                                                   LMTP(8)
        problem reports are sent to the <a href="bounce.8.html"><b>bounce</b>(8)</a> or <a href="defer.8.html"><b>defer</b>(8)</a> dae-
        mon as appropriate.
 
-       If no server is given on the command line, the LMTP client
-       connects to  the  destination  specified  in  the  message
-       delivery  request  and  to the TCP port defined as <b>lmtp</b> in
-       <b>services</b>(4).   If  no   such   service   is   found,   the
-       <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>  configuration  parameter  (default value of
-       24) will be used. The LMTP  client  does  not  perform  MX
-       (mail  exchanger) lookups since those are defined only for
-       SMTP.
+       The  LMTP  client connects to the destination specified in
+       the message delivery  request.  The  destination,  usually
+       specified in the Postfix <a href="transport.5.html"><b>transport</b>(5)</a> table, has the form:
+
+       <b>unix</b>:<i>pathname</i>
+              Connect to the UNIX-domain server that is bound  to
+              the   specified   <i>pathname</i>.  If  the  process  runs
+              chrooted, an absolute pathname is interpreted rela-
+              tive to the changed root directory.
+
+       <b>inet</b>:<i>host</i>, <b>inet:</b><i>host</i>:<i>port</i> (symbolic host)
+
+       <b>inet</b>:[<i>addr</i>], <b>inet</b>:[<i>addr</i>]:<i>port</i> (numeric host)
+              Connect to the specified IPV4 TCP port on the spec-
+              ified host. If no port is specified, connect to the
+              port  defined  as  <b>lmtp</b> in <b>services</b>(4).  If no such
+              service is found, the  <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>  configuration
+              parameter (default value of 24) will be used.
+
+              The   LMTP   client   does  not  perform  MX  (mail
+              exchanger) lookups since those are defined only for
+              mail delivery via SMTP.
+
+       If  neither  <b>unix:</b>  nor  <b>inet:</b>  are  specified,  <b>inet:</b>  is
+       assumed.
 
 <b>SECURITY</b>
        The LMTP client is moderately security-sensitive. It talks
@@ -42,6 +59,18 @@ LMTP(8)                                                   LMTP(8)
        <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
        <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
+
+
+
+                                                                1
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
        <a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
 
@@ -59,18 +88,6 @@ LMTP(8)                                                   LMTP(8)
        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. Use the <b>postfix</b> <b>reload</b>
-
-
-
-                                                                1
-
-
-
-
-
-LMTP(8)                                                   LMTP(8)
-
-
        command after a configuration change.
 
 <b>Miscellaneous</b>
@@ -108,6 +125,18 @@ LMTP(8)                                                   LMTP(8)
               The  effectiveness  of  cached  connections will be
               determined by the number of LMTP  servers  in  use,
               and  the  concurrency  limit specified for the LMTP
+
+
+
+                                                                2
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
               client.  Cached connections are closed under any of
               the following conditions:
 
@@ -125,18 +154,6 @@ LMTP(8)                                                   LMTP(8)
 
               <b>o</b>      Upon  the onset of another delivery request,
                      the LMTP server associated with the  current
-
-
-
-                                                                2
-
-
-
-
-
-LMTP(8)                                                   LMTP(8)
-
-
                      session  does  not  respond to the <b>RSET</b> com-
                      mand.
 
@@ -175,6 +192,17 @@ LMTP(8)                                                   LMTP(8)
               LMTP server.  If no connection can be  made  within
               the deadline, the message is deferred.
 
+
+
+                                                                3
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
        <b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b>
               Timeout  in  seconds  for sending the <b>LHLO</b> command,
               and for receiving the server response.
@@ -191,18 +219,6 @@ LMTP(8)                                                   LMTP(8)
               Timeout in seconds for sending  the  <b>DATA</b>  command,
               and for receiving the server response.
 
-
-
-
-                                                                3
-
-
-
-
-
-LMTP(8)                                                   LMTP(8)
-
-
        <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
               Timeout in seconds for sending the message content.
 
@@ -226,7 +242,7 @@ LMTP(8)                                                   LMTP(8)
        <a href="master.8.html">master(8)</a> process manager
        <a href="qmgr.8.html">qmgr(8)</a> queue manager
        services(4) Internet services and aliases
-       spawn(8) auxiliary command spawner
+       <a href="spawn.8.html">spawn(8)</a> auxiliary command spawner
        syslogd(8) system logging
 
 <b>LICENSE</b>
@@ -241,6 +257,18 @@ LMTP(8)                                                   LMTP(8)
 
        Alterations for LMTP by:
        Philip A. Prindeville
+
+
+
+                                                                4
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
        Mirapoint, Inc.
        USA.
 
@@ -260,7 +288,45 @@ LMTP(8)                                                   LMTP(8)
 
 
 
-                                                                4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                5
 
 
 </pre> </body> </html>
index 05e2d06e6131e7f84c10e9e12446630d3cedc172..dc1ea633df8ae80169fe06b0cf159b78aa0a51c8 100644 (file)
@@ -29,6 +29,11 @@ SMTP(8)                                                   SMTP(8)
        preference,  and  connects to each listed address until it
        finds a server that responds.
 
+       When the domain or host is specified as a comma/whitespace
+       separated  list, the SMTP client repeats the above process
+       for  all  destinations  until  it  finds  a  server   that
+       responds.
+
        Once the SMTP client has received the server greeting ban-
        ner, no error will cause it to proceed to the next address
        on the mail exchanger list. Instead, the message is either
@@ -36,7 +41,7 @@ SMTP(8)                                                   SMTP(8)
 
 <b>SECURITY</b>
        The SMTP client is moderately security-sensitive. It talks
-       to SMTP servers and to DNS servers  on  the  network.  The
+       to  SMTP  servers  and  to DNS servers on the network. The
        SMTP client can be run chrooted at fixed low privilege.
 
 <b>STANDARDS</b>
@@ -47,19 +52,14 @@ SMTP(8)                                                   SMTP(8)
        <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
 
 <b>DIAGNOSTICS</b>
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
-       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
-       the  postmaster is notified of bounces, protocol problems,
+       Depending  on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
+       the postmaster is notified of bounces, protocol  problems,
        and of other trouble.
 
-<b>BUGS</b>
-<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
-
 
 
                                                                 1
@@ -71,36 +71,40 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
-       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
+<b>BUGS</b>
+<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
+       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
        command after a configuration change.
 
 <b>Miscellaneous</b>
        <b>best</b><i>_</i><b>mx</b><i>_</i><b>transport</b>
-              Name  of  the  delivery  transport  to use when the
-              local machine is the most-preferred mail  exchanger
-              (by  default,  a  mailer  loop is reported, and the
+              Name of the delivery  transport  to  use  when  the
+              local  machine is the most-preferred mail exchanger
+              (by default, a mailer loop  is  reported,  and  the
               message is bounced).
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Verbose logging  level  increment  for  hosts  that
+              Verbose  logging  level  increment  for  hosts that
               match a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> parameter.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              List  of  domain or network patterns. When a remote
-              host matches a pattern, increase the  verbose  log-
-              ging   level   by   the  amount  specified  in  the
+              List of domain or network patterns. When  a  remote
+              host  matches  a pattern, increase the verbose log-
+              ging  level  by  the  amount   specified   in   the
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
 
        <b>disable</b><i>_</i><b>dns</b><i>_</i><b>lookups</b>
-              Disable DNS lookups. This means that mail  must  be
+              Disable  DNS  lookups. This means that mail must be
               forwarded via a smart relay host.
 
        <b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
-              Recipient    of   protocol/policy/resource/software
+              Recipient   of    protocol/policy/resource/software
               error notices.
 
        <b>fallback</b><i>_</i><b>relay</b>
-              Hosts to hand off mail to if a message  destination
+              Hosts  to hand off mail to if a message destination
               is not found or if a destination is unreachable.
 
        <b>ignore</b><i>_</i><b>mx</b><i>_</i><b>lookup</b><i>_</i><b>error</b>
@@ -110,21 +114,17 @@ SMTP(8)                                                   SMTP(8)
 
        <b>inet</b><i>_</i><b>interfaces</b>
               The network interface addresses that this mail sys-
-              tem receives mail on. When any of  those  addresses
+              tem  receives  mail on. When any of those addresses
               appears in the list of mail exchangers for a remote
-              destination, the list is truncated  to  avoid  mail
+              destination,  the  list  is truncated to avoid mail
               delivery loops.
 
        <b>notify</b><i>_</i><b>classes</b>
-              When  this  parameter  includes the <b>protocol</b> class,
-              send mail to the  postmaster  with  transcripts  of
+              When this parameter includes  the  <b>protocol</b>  class,
+              send  mail  to  the  postmaster with transcripts of
               SMTP sessions with protocol errors.
 
-       <b>smtp</b><i>_</i><b>always</b><i>_</i><b>send</b><i>_</i><b>ehlo</b>
-              Always send EHLO at the start of a connection.
 
-       <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
-              Skip  servers that greet us with a 4xx status code.
 
 
 
@@ -137,26 +137,32 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+       <b>smtp</b><i>_</i><b>always</b><i>_</i><b>send</b><i>_</i><b>ehlo</b>
+              Always send EHLO at the start of a connection.
+
+       <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
+              Skip servers that greet us with a 4xx status  code.
+
        <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>5xx</b><i>_</i><b>greeting</b>
-              Skip servers that greet us with a 5xx status  code.
+              Skip  servers that greet us with a 5xx status code.
 
        <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>quit</b><i>_</i><b>response</b>
-              Do  not  wait for the server response after sending
+              Do not wait for the server response  after  sending
               QUIT.
 
        <b>smtp</b><i>_</i><b>bind</b><i>_</i><b>address</b>
-              Numerical network address to bind to when making  a
+              Numerical  network address to bind to when making a
               connection.
 
 <b>Authentication</b> <b>controls</b>
        <b>smtp</b><i>_</i><b>enable</b><i>_</i><b>sasl</b><i>_</i><b>auth</b>
-              Enable  per-session  authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
-              (SASL).  By default, Postfix is built without  SASL
+              Enable per-session authentication as per  <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC  2554</a>
+              (SASL).   By default, Postfix is built without SASL
               support.
 
        <b>smtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b>
               Lookup tables with per-host or domain <i>name</i>:<i>password</i>
-              entries.  No entry for a host means no  attempt  to
+              entries.   No  entry for a host means no attempt to
               authenticate.
 
        <b>smtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
@@ -180,17 +186,11 @@ SMTP(8)                                                   SMTP(8)
 <b>Resource</b> <b>controls</b>
        <b>smtp</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
-              destination.  The default limit is taken  from  the
+              destination.   The  default limit is taken from the
               <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
 
        <b>smtp</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Limit  the  number of recipients per message deliv-
-              ery.   The  default  limit  is   taken   from   the
-              <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
-
-<b>Timeout</b> <b>controls</b>
-       <b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
-              Timeout in seconds for completing a TCP connection.
+              Limit  the  number  of   recipients   per   message
 
 
 
@@ -203,24 +203,30 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+              delivery.   The  default  limit  is  taken from the
+              <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+
+<b>Timeout</b> <b>controls</b>
+       <b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
+              Timeout in seconds for completing a TCP connection.
               When no connection can be made within the deadline,
-              the  SMTP client tries the next address on the mail
+              the SMTP client tries the next address on the  mail
               exchanger list.
 
        <b>smtp</b><i>_</i><b>helo</b><i>_</i><b>timeout</b>
-              Timeout in seconds for receiving the SMTP  greeting
+              Timeout  in seconds for receiving the SMTP greeting
               banner.  When the server drops the connection with-
-              out sending a greeting banner, or when it sends  no
+              out  sending a greeting banner, or when it sends no
               greeting  banner  within  the  deadline,  the  SMTP
               client tries the next address on the mail exchanger
               list.
 
        <b>smtp</b><i>_</i><b>helo</b><i>_</i><b>timeout</b>
-              Timeout  in  seconds  for sending the <b>HELO</b> command,
+              Timeout in seconds for sending  the  <b>HELO</b>  command,
               and for receiving the server response.
 
        <b>smtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b>
-              Timeout in seconds for sending the <b>MAIL</b>  <b>FROM</b>  com-
+              Timeout  in  seconds for sending the <b>MAIL</b> <b>FROM</b> com-
               mand, and for receiving the server response.
 
        <b>smtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b>
@@ -228,7 +234,7 @@ SMTP(8)                                                   SMTP(8)
               and for receiving the server response.
 
        <b>smtp</b><i>_</i><b>data</b><i>_</i><b>init</b><i>_</i><b>timeout</b>
-              Timeout in seconds for sending  the  <b>DATA</b>  command,
+              Timeout  in  seconds  for sending the <b>DATA</b> command,
               and for receiving the server response.
 
        <b>smtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
@@ -237,11 +243,11 @@ SMTP(8)                                                   SMTP(8)
        <b>smtp</b><i>_</i><b>data</b><i>_</i><b>done</b><i>_</i><b>timeout</b>
               Timeout in seconds for sending the "<b>.</b>" command, and
               for receiving the server response. When no response
-              is received, a warning is logged that the mail  may
+              is  received, a warning is logged that the mail may
               be delivered multiple times.
 
        <b>smtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b>
-              Timeout  in  seconds  for sending the <b>QUIT</b> command,
+              Timeout in seconds for sending  the  <b>QUIT</b>  command,
               and for receiving the server response.
 
 <b>SEE</b> <b>ALSO</b>
@@ -250,13 +256,7 @@ SMTP(8)                                                   SMTP(8)
        <a href="qmgr.8.html">qmgr(8)</a> queue manager
        syslogd(8) system logging
 
-<b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
-       software.
 
-<b>AUTHOR(S)</b>
-       Wietse Venema
-       IBM T.J. Watson Research
 
 
 
@@ -269,6 +269,13 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+<b>LICENSE</b>
+       The  Secure  Mailer  license must be distributed with this
+       software.
+
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       IBM T.J. Watson Research
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
@@ -311,13 +318,6 @@ SMTP(8)                                                   SMTP(8)
 
 
 
-
-
-
-
-
-
-
 
 
 
index baacc13c417a090fc26dadb22fb7dde096122067..e8e5625c62231a076497ccadf007099892512321 100644 (file)
@@ -159,18 +159,12 @@ case "$SYSTEM.$RELEASE" in
                *)      echo "Unknown AIX version: `uname -v`." 1>&2; exit 1;;
                esac;;
     Linux.2*)  SYSTYPE=LINUX2
-               if [ -f /usr/lib/libdb-3.1.a ]
+               # Postfix no longer needs DB 1.85 compatibility
+               if [ ! -f /usr/include/db.h -a -f /usr/include/db/db.h ]
                then
-                   CCARGS="$CCARGS -I/usr/include/db3"
-                   SYSLIBS="$SYSLIBS -ldb-3.1"
-               else
-                   if [ -f /usr/include/db/db.h ]
-                   then
-                       CCARGS="$CCARGS -I/usr/include/db"
-                   fi
-                   test -f /usr/lib/libdb.a && SYSLIBS="$SYSLIBS -ldb"
+                   CCARGS="$CCARGS -I/usr/include/db"
                fi
-               for name in nsl resolv
+               for name in db nsl resolv
                do
                    test -f /usr/lib/lib$name.a && SYSLIBS="$SYSLIBS -l$name"
                done
@@ -192,9 +186,6 @@ HP-UX.A.09.*)       SYSTYPE=HPUX9
                    CCARGS="$CCARGS -DHAS_DB"
                    SYSLIBS="$SYSLIBS -ldb"
                fi
-               if [ -f /usr/include/db_185.h ]; then
-                   CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
-               fi
                ;;
 HP-UX.B.10.*)  SYSTYPE=HPUX10
                CCARGS="$CCARGS `nm /usr/lib/libc.a 2>/dev/null |
@@ -203,9 +194,6 @@ HP-UX.B.10.*)       SYSTYPE=HPUX10
                    CCARGS="$CCARGS -DHAS_DB"
                    SYSLIBS=-ldb
                fi
-               if [ -f /usr/include/db_185.h ]; then
-                   CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
-               fi
                ;;
 HP-UX.B.11.*)  SYSTYPE=HPUX11
                SYSLIBS=-lnsl
@@ -213,9 +201,6 @@ HP-UX.B.11.*)       SYSTYPE=HPUX11
                    CCARGS="$CCARGS -DHAS_DB"
                    SYSLIBS="$SYSLIBS -ldb"
                fi
-               if [ -f /usr/include/db_185.h ]; then
-                   CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
-               fi
                ;;
 ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
                RANLIB=echo
index 4d981bb9fb569429a887c644aaeacd0969ebe99f..8af70aa5263a84887dbf07632cc5d35cfeb70f9a 100644 (file)
@@ -23,12 +23,26 @@ as finished, or it informs the queue manager that delivery should
 be tried again at a later time. Delivery problem reports are sent
 to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
 
-If no server is given on the command line, the LMTP client connects
-to the destination specified in the message delivery request and to
-the TCP port defined as \fBlmtp\fR in \fBservices\fR(4).  If no such
-service is found, the \fBlmtp_tcp_port\fR configuration parameter
-(default value of 24) will be used. The LMTP client does not perform
-MX (mail exchanger) lookups since those are defined only for SMTP.
+The LMTP client connects to the destination specified in the message
+delivery request. The destination, usually specified in the Postfix
+\fBtransport\fR(5) table, has the form:
+.IP \fBunix\fR:\fIpathname\fR
+Connect to the UNIX-domain server that is bound to the specified
+\fIpathname\fR. If the process runs chrooted, an absolute pathname
+is interpreted relative to the changed root directory.
+.IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
+.IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
+Connect to the specified IPV4 TCP port on the specified host. If no
+port is specified, connect to the port defined as \fBlmtp\fR in
+\fBservices\fR(4).
+If no such service is found, the \fBlmtp_tcp_port\fR configuration
+parameter (default value of 24) will be used.
+
+The LMTP client does not perform MX (mail exchanger) lookups since
+those are defined only for mail delivery via SMTP.
+.PP
+If neither \fBunix:\fR nor \fBinet:\fR are specified, \fBinet:\fR
+is assumed.
 .SH SECURITY
 .na
 .nf
index bcf367a204424793eb0a4302799a9f337f3d628a..35553290a140983c55e189d1c717ad2bb0a03764 100644 (file)
@@ -27,6 +27,10 @@ The SMTP client looks up a list of mail exchanger addresses for
 the destination host, sorts the list by preference, and connects
 to each listed address until it finds a server that responds.
 
+When the domain or host is specified as a comma/whitespace
+separated list, the SMTP client repeats the above process
+for all destinations until it finds a server that responds.
+
 Once the SMTP client has received the server greeting banner, no
 error will cause it to proceed to the next address on the mail
 exchanger list. Instead, the message is either bounced, or its
index bbc2ff0e62e488208da52575f4f383c043a4931b..724341f4663f53c0ede2815d13df1a3ed48153ea 100644 (file)
@@ -189,9 +189,6 @@ static DOMAIN_LIST *flush_domains;
 
 static int flush_policy_ok(const char *site)
 {
-    if (flush_domains == 0)
-       flush_domains = domain_list_init(var_fflush_domains);
-
     return (domain_list_match(flush_domains, site));
 }
 
@@ -497,6 +494,13 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
        vstring_free(queue_id);
 }
 
+/* pre_jail_init - pre-jail initialization */
+
+static void pre_jail_init(char *unused_name, char **unused_argv)
+{
+    flush_domains = domain_list_init(var_fflush_domains);
+}
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -509,5 +513,6 @@ int     main(int argc, char **argv)
 
     single_server_main(argc, argv, flush_service,
                       MAIL_SERVER_TIME_TABLE, time_table,
+                      MAIL_SERVER_PRE_INIT, pre_jail_init,
                       0);
 }
diff --git a/postfix/src/fsstone/fsstone b/postfix/src/fsstone/fsstone
deleted file mode 100755 (executable)
index cd33f1c..0000000
Binary files a/postfix/src/fsstone/fsstone and /dev/null differ
index 88662d95e00599610b046aa46dfcd0dfff8bd093..c919efe231494c772f474479b03d1f69c8105ebc 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20001028"
+#define DEF_MAIL_VERSION       "Snapshot-20001029"
 extern char *var_mail_version;
 
 /* LICENSE
index 485c976dd96154116e8d51275d506127874cb6ca..6dd99c6855473522b4debcf0c84f47d4436c6af9 100644 (file)
 /*     be tried again at a later time. Delivery problem reports are sent
 /*     to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
 /*
-/*     If no server is given on the command line, the LMTP client connects
-/*     to the destination specified in the message delivery request and to
-/*     the TCP port defined as \fBlmtp\fR in \fBservices\fR(4).  If no such
-/*     service is found, the \fBlmtp_tcp_port\fR configuration parameter
-/*     (default value of 24) will be used. The LMTP client does not perform
-/*     MX (mail exchanger) lookups since those are defined only for SMTP.
+/*     The LMTP client connects to the destination specified in the message
+/*     delivery request. The destination, usually specified in the Postfix
+/*     \fBtransport\fR(5) table, has the form:
+/* .IP \fBunix\fR:\fIpathname\fR
+/*     Connect to the UNIX-domain server that is bound to the specified
+/*     \fIpathname\fR. If the process runs chrooted, an absolute pathname
+/*     is interpreted relative to the changed root directory.
+/* .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
+/* .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
+/*     Connect to the specified IPV4 TCP port on the specified host. If no
+/*     port is specified, connect to the port defined as \fBlmtp\fR in
+/*     \fBservices\fR(4).
+/*     If no such service is found, the \fBlmtp_tcp_port\fR configuration
+/*     parameter (default value of 24) will be used.
+/*
+/*     The LMTP client does not perform MX (mail exchanger) lookups since
+/*     those are defined only for mail delivery via SMTP.
+/* .PP
+/*     If neither \fBunix:\fR nor \fBinet:\fR are specified, \fBinet:\fR
+/*     is assumed.
 /* SECURITY
 /* .ad
 /* .fi
index 28d64e953b4c2dc4bcbcdbaf0d2dd483aafe99b0..9d80e3666844c165a62388c6db62759baa8ed130 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 /* NAME
-/*     lmtp_connect_inet 3
+/*     lmtp_connect 3
 /* SUMMARY
 /*     connect to LMTP server
 /* SYNOPSIS
 /* DESCRIPTION
 /*     This module implements LMTP connection management.
 /*
-/*     lmtp_connect() attempts to establish an LMTP session with a host.
+/*     lmtp_connect() attempts to establish an LMTP session.
 /*
+/*     The destination is one of the following:
+/* .IP unix:address
+/*     Connect to a UNIX-domain service. The destination is a pathname.
+/*     Beware: UNIX-domain sockets are flakey on Solaris, at last up to
+/*     and including Solaris 7.0.
+/* .IP inet:address
+/*     Connect to an IPV4 service.
 /*     The destination is either a host name or a numeric address.
 /*     Symbolic or numeric service port information may be appended,
 /*     separated by a colon (":").
 /*
 /*     Numerical address information should always be quoted with `[]'.
+/* .PP
+/*     When no transport is specified, "inet" is assumed.
 /* DIAGNOSTICS
 /*     This routine either returns an LMTP_SESSION pointer, or
 /*     returns a null pointer and set the \fIlmtp_errno\fR
@@ -58,6 +67,7 @@
 
 #include <sys_defs.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include "lmtp.h"
 #include "lmtp_addr.h"
 
+ /*
+  * Forward declaration.
+  */
+static LMTP_SESSION *lmtp_connect_sock(int, struct sockaddr *, int,
+                                              const char *, const char *,
+                                              const char *, VSTRING *);
+
+/* lmtp_connect_unix - connect to UNIX-domain address */
+
+static LMTP_SESSION *lmtp_connect_unix(const char *addr, VSTRING *why)
+{
+#undef sun
+    char   *myname = "lmtp_connect_unix";
+    struct sockaddr_un sun;
+    int     len = strlen(addr);
+    int     sock;
+
+    /*
+     * Sanity checks.
+     */
+    if (len >= (int) sizeof(sun.sun_path)) {
+       msg_warn("unix-domain name too long: %s", addr);
+       lmtp_errno = LMTP_RETRY;
+       return (0);
+    }
+
+    /*
+     * Initialize.
+     */
+    memset((char *) &sun, 0, sizeof(sun));
+    sun.sun_family = AF_UNIX;
+#ifdef HAS_SUN_LEN
+    sun.sun_len = len + 1;
+#endif
+    memcpy(sun.sun_path, addr, len + 1);
+
+    /*
+     * Create a client socket.
+     */
+    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+       msg_fatal("%s: socket: %m", myname);
+
+    /*
+     * Connect to the LMTP server.
+     */
+    if (msg_verbose)
+       msg_info("%s: trying: %s...", myname, addr);
+
+    return (lmtp_connect_sock(sock, (struct sockaddr *) & sun, sizeof(sun),
+                             addr, addr, addr, why));
+}
+
 /* lmtp_connect_addr - connect to explicit address */
 
 static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
@@ -105,10 +167,6 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
     char   *myname = "lmtp_connect_addr";
     struct sockaddr_in sin;
     int     sock;
-    int     conn_stat;
-    int     saved_errno;
-    VSTREAM *stream;
-    int     ch;
 
     /*
      * Sanity checks.
@@ -137,19 +195,35 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
     if (msg_verbose)
        msg_info("%s: trying: %s[%s] port %d...",
                 myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
+
+    return (lmtp_connect_sock(sock, (struct sockaddr *) & sin, sizeof(sin),
+                             addr->name, inet_ntoa(sin.sin_addr),
+                             destination, why));
+}
+
+/* lmtp_connect_sock - connect a socket over some transport */
+
+static LMTP_SESSION *lmtp_connect_sock(int sock, struct sockaddr * sa, int len,
+                                        const char *name, const char *addr,
+                                     const char *destination, VSTRING *why)
+{
+    int     conn_stat;
+    int     saved_errno;
+    VSTREAM *stream;
+    int     ch;
+
     if (var_lmtp_conn_tmout > 0) {
        non_blocking(sock, NON_BLOCKING);
-       conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
-                                 sizeof(sin), var_lmtp_conn_tmout);
+       conn_stat = timed_connect(sock, sa, len, var_lmtp_conn_tmout);
        saved_errno = errno;
        non_blocking(sock, BLOCKING);
        errno = saved_errno;
     } else {
-       conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
+       conn_stat = connect(sock, sa, len);
     }
     if (conn_stat < 0) {
        vstring_sprintf(why, "connect to %s[%s]: %m",
-                       addr->name, inet_ntoa(sin.sin_addr));
+                       name, addr);
        lmtp_errno = LMTP_RETRY;
        close(sock);
        return (0);
@@ -160,7 +234,7 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
      */
     if (read_wait(sock, var_lmtp_lhlo_tmout) < 0) {
        vstring_sprintf(why, "connect to %s[%s]: read timeout",
-                       addr->name, inet_ntoa(sin.sin_addr));
+                       name, addr);
        lmtp_errno = LMTP_RETRY;
        close(sock);
        return (0);
@@ -172,7 +246,7 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
     stream = vstream_fdopen(sock, O_RDWR);
     if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
        vstring_sprintf(why, "connect to %s[%s]: server dropped connection",
-                       addr->name, inet_ntoa(sin.sin_addr));
+                       name, addr);
        lmtp_errno = LMTP_RETRY;
        vstream_fclose(stream);
        return (0);
@@ -184,13 +258,12 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
      */
     if (ch == '4' || ch == '5') {
        vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
-                       addr->name, inet_ntoa(sin.sin_addr));
+                       name, addr);
        lmtp_errno = LMTP_RETRY;
        vstream_fclose(stream);
        return (0);
     }
-    return (lmtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr),
-                              destination));
+    return (lmtp_session_alloc(stream, name, addr, destination));
 }
 
 /* lmtp_connect_host - direct connection to host */
@@ -220,7 +293,7 @@ static LMTP_SESSION *lmtp_connect_host(char *host, unsigned port,
 /* lmtp_parse_destination - parse destination */
 
 static char *lmtp_parse_destination(const char *destination, char *def_service,
-                                             char **hostp, unsigned *portp)
+                                           char **hostp, unsigned *portp)
 {
     char   *myname = "lmtp_parse_destination";
     char   *buf = mystrdup(destination);
@@ -272,7 +345,7 @@ static char *lmtp_parse_destination(const char *destination, char *def_service,
 
 LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
 {
-    char   *myname = "lmtp_connect_inet";
+    char   *myname = "lmtp_connect";
     LMTP_SESSION *session;
     char   *dest_buf;
     char   *host;
@@ -281,7 +354,15 @@ LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
 
     /*
      * Connect to the LMTP server.
+     * 
+     * XXX Ad-hoc transport parsing and connection management. Some or all
+     * should be moved away to a reusable library routine so that every
+     * program benefits from it.
      */
+    if (strncmp(destination, "unix:", 5) == 0)
+       return (lmtp_connect_unix(destination + 5, why));
+    if (strncmp(destination, "inet:", 5) == 0)
+       destination += 5;
     dest_buf = lmtp_parse_destination(destination, def_service,
                                      &host, &port);
     if (msg_verbose)
index ae16b03855dbe138d5d98ad89f4f0321ae91e0b0..93ed07dd0836554e5391009ae5cfe4a7d83d0e4e 100644 (file)
@@ -246,11 +246,9 @@ int     lmtp_lhlo(LMTP_STATE *state)
      * because they benefit little from pipelining.
      */
     if (state->features & LMTP_FEATURE_PIPELINING) {
-       if (getsockopt(vstream_fileno(state->session->stream), SOL_SOCKET,
-                      SO_SNDBUF, (char *) &state->sndbufsize, &optlen) < 0)
-           msg_fatal("%s: getsockopt: %m", myname);
+       state->sndbufsize = 4 * 1024;
        if (msg_verbose)
-           msg_info("Using LMTP PIPELINING, TCP send buffer size is %d",
+           msg_info("Using LMTP PIPELINING, send buffer size is %d",
                     state->sndbufsize);
     } else
        state->sndbufsize = 0;
index d9d54357e852b83a56273251fc4b6ef0fde5f915..59017b1dc3c3e3c52bc285fc64bc46f85a66f5d6 100644 (file)
 /*     the destination host, sorts the list by preference, and connects
 /*     to each listed address until it finds a server that responds.
 /*
+/*     When the domain or host is specified as a comma/whitespace
+/*     separated list, the SMTP client repeats the above process
+/*     for all destinations until it finds a server that responds.
+/*
 /*     Once the SMTP client has received the server greeting banner, no
 /*     error will cause it to proceed to the next address on the mail
 /*     exchanger list. Instead, the message is either bounced, or its
index f037c594deb4b9aafe0f19f2433199aac6140059..d8017f230cbb5b72274f231e38343ecacdc1e4a9 100644 (file)
@@ -401,7 +401,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why)
      */
     cp = save = concatenate(destination, " ", var_fallback_relay, (char *) 0);
 
-    while ((dest = mystrtok(&cp, " \t\r\n")) != 0) {
+    while ((dest = mystrtok(&cp, ", \t\r\n")) != 0) {
 
        /*
         * Parse the destination. Default is to use the SMTP port.
index aacdd522974001d11cbbe41a2cdb1c78d853d21e..29e49cf86fd1a8e2df0e622907e50f41830a054f 100644 (file)
@@ -353,6 +353,13 @@ char   *smtpd_path;
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
 
+ /*
+  * Forward declarations.
+  */
+static void helo_reset(SMTPD_STATE *);
+static void mail_reset(SMTPD_STATE *);
+static void rcpt_reset(SMTPD_STATE *);
+
 /* collapse_args - put arguments together again */
 
 static void collapse_args(int argc, SMTPD_TOKEN *argv)
@@ -377,10 +384,8 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "501 Syntax: HELO hostname");
        return (-1);
     }
-    if (state->helo_name != 0) {
-       myfree(state->helo_name);
-       state->helo_name = 0;
-    }
+    if (state->helo_name != 0)
+       helo_reset(state);
     if (argc > 2)
        collapse_args(argc - 1, argv + 1);
     if (SMTPD_STAND_ALONE(state) == 0
@@ -406,10 +411,12 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "501 Syntax: EHLO hostname");
        return (-1);
     }
-    if (state->helo_name != 0) {
-       myfree(state->helo_name);
-       state->helo_name = 0;
-    }
+    if (state->helo_name != 0)
+       helo_reset(state);
+#if 0
+    mail_reset(state);
+    rcpt_reset(state);
+#endif
     if (argc > 2)
        collapse_args(argc - 1, argv + 1);
     if (SMTPD_STAND_ALONE(state) == 0
index 701fdf05f85ec638b284f04554e0091fe7367f91..cac69ba836e46f49e532bfbb3b3b8d34fcdfcf85 100644 (file)
@@ -4,12 +4,19 @@
 /* SUMMARY
 /*     multi-threaded SMTP/LMTP test server
 /* SYNOPSIS
-/*     smtp-sink [-cLpv] [-w delay] [host]:port backlog
+/* .fi
+/*     \fBsmtp-sink\fR [\fB-cLpv\fR] [\fB-w \fIdelay\fR] 
+/*     [\fBinet:\fR][\fIhost\fR]:\fIport\fR \fIbacklog\fR
+/*
+/*     \fBsmtp-sink\fR [\fB-cLpv\fR] [\fB-w \fIdelay\fR] 
+/*     \fBunix:\fR\fIpathname\fR \fIbacklog\fR
 /* DESCRIPTION
 /*     \fIsmtp-sink\fR listens on the named host (or address) and port.
 /*     It takes SMTP messages from the network and throws them away.
 /*     The purpose is to measure SMTP client performance, not protocol
 /*     compliance.
+/*     Connections can be accepted on IPV4 endpoints or UNIX-domain sockets.
+/*     IPV4 is the default.
 /*     This program is the complement of the \fIsmtp-source\fR program.
 /* .IP -c
 /*     Display a running counter that is updated whenever an SMTP
@@ -392,7 +399,13 @@ int     main(int argc, char **argv)
      */
     buffer = vstring_alloc(1024);
     var_myhostname = "smtp-sink";
-    sock = inet_listen(argv[optind], backlog, BLOCKING);
+    if (strncmp(argv[optind], "unix:", 5) == 0) {
+       sock = unix_listen(argv[optind] + 5, backlog, BLOCKING);
+    } else {
+       if (strncmp(argv[optind], "inet:", 5) == 0)
+           argv[optind] += 5;
+       sock = inet_listen(argv[optind], backlog, BLOCKING);
+    }
 
     /*
      * Start the event handler.
index 0fc1ae8f3c43a2050b977169639616cf5a9a96e6..c5d9dbcc7c24ab30f71ddde039d0b3d9edb84eb3 100644 (file)
@@ -4,12 +4,16 @@
 /* SUMMARY
 /*     multi-threaded SMTP test generator
 /* SYNOPSIS
-/*     smtp-source [options] host[:port]
+/* .fi
+/*     \fBsmtp-source\fR [\fIoptions\fR] [\fBinet:\fR]\fIhost\fR[:\fIport\fR]
+/*
+/*     \fBsmtp-source\fR [\fIoptions\fR] \fBunix:\fIpathname\fR
 /* DESCRIPTION
 /*     smtp-source connects to the named host and port (default 25)
 /*     and sends one or more little messages to it, either sequentially
 /*     or in parallel. The program speaks either SMTP (default) or
-/*     LMTP.
+/*     LMTP. Connections can be made to UNIX-domain and IPV4 servers.
+/*     IPV4 is the default.
 /*
 /*     Options:
 /* .IP -c
@@ -64,6 +68,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <netinet/in.h>
+#include <sys/un.h>
 #include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
@@ -131,6 +136,10 @@ static const char *var_myhostname;
 static int session_count;
 static int message_count = 1;
 static struct sockaddr_in sin;
+#undef sun
+static struct sockaddr_un sun;
+static struct sockaddr *sa;
+static int sa_len;
 static int recipients = 1;
 static char *defaddr;
 static char *recipient;
@@ -383,14 +392,13 @@ static void start_connect(SESSION *session)
      * retrieving it later with getsockopt(). We can't use MSG_PEEK to
      * distinguish between server disconnect and connection refused.
      */
-    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    if ((fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
        msg_fatal("socket: %m");
     (void) non_blocking(fd, NON_BLOCKING);
     session->stream = vstream_fdopen(fd, O_RDWR);
     event_enable_write(fd, connect_done, (char *) session);
     smtp_timeout_setup(session->stream, var_timeout);
-    if (connect(fd, (struct sockaddr *) & sin, sizeof(sin)) < 0
-       && errno != EINPROGRESS)
+    if (connect(fd, sa, sa_len) < 0 && errno != EINPROGRESS)
        fail_connect(session);
 }
 
@@ -739,6 +747,8 @@ int     main(int argc, char **argv)
     SESSION *session;
     char   *host;
     char   *port;
+    char   *path;
+    int     path_len;
     int     sessions = 1;
     int     ch;
     int     i;
@@ -813,8 +823,6 @@ int     main(int argc, char **argv)
     }
     if (argc - optind != 1)
        usage(argv[0]);
-    if ((port = split_at(host = argv[optind], ':')) == 0)
-       port = "smtp";
 
     if (random_delay > 0)
        srand(getpid());
@@ -822,10 +830,31 @@ int     main(int argc, char **argv)
     /*
      * Translate endpoint address to internal form.
      */
-    memset((char *) &sin, 0, sizeof(sin));
-    sin.sin_family = AF_INET;
-    sin.sin_addr.s_addr = find_inet_addr(host);
-    sin.sin_port = find_inet_port(port, "tcp");
+    if (strncmp(argv[optind], "unix:", 5) == 0) {
+       path = argv[optind] + 5;
+       path_len = strlen(path);
+       if (path_len >= (int) sizeof(sun.sun_path))
+           msg_fatal("unix-domain name too long: %s", path);
+       memset((char *) &sun, 0, sizeof(sun));
+       sun.sun_family = AF_UNIX;
+#ifdef HAS_SUN_LEN
+       sun.sun_len = path_len + 1;
+#endif
+       memcpy(sun.sun_path, path, path_len);
+       sa = (struct sockaddr *) & sun;
+       sa_len = sizeof(sun);
+    } else {
+       if (strncmp(argv[optind], "inet:", 5) == 0)
+           argv[optind] += 5;
+       if ((port = split_at(host = argv[optind], ':')) == 0)
+           port = "smtp";
+       memset((char *) &sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = find_inet_addr(host);
+       sin.sin_port = find_inet_port(port, "tcp");
+       sa = (struct sockaddr *) & sin;
+       sa_len = sizeof(sin);
+    }
 
     /*
      * Make sure the SMTP server cannot run us out of memory by sending
index 1207402bc767d380c54823ee1c10d7b2c57b7445..9044045752463749ad2f5e591d0323a1e51787dd 100644 (file)
 #define DONT_CLOBBER                   DB_NOOVERWRITE
 #endif
 
+#ifndef DB_FCNTL_LOCKING
+#define DB_FCNTL_LOCKING               0
+#endif
+
 /* Utility library. */
 
 #include "msg.h"
@@ -399,6 +403,8 @@ static void dict_db_close(DICT *dict)
 {
     DICT_DB *dict_db = (DICT_DB *) dict;
 
+    if (DICT_DB_SYNC(dict_db->db, 0) < 0)
+       msg_fatal("flush database %s: %m", dict_db->path);
     if (DICT_DB_CLOSE(dict_db->db) < 0)
        msg_fatal("close database %s: %m", dict_db->path);
     myfree(dict_db->path);
index e0cf2440cd14770d12d4ba6d49cdc5326aea3a71..250a1e646eb026b25c928e8b383b54cfd4f7f010 100644 (file)
@@ -1,4 +1,3 @@
-
 /*++
 /* NAME
 /*     dict_ldap 3
 /*     The port the LDAP server listens on.
 /* .IP \fIldapsource_\fRsearch_base
 /*     The LDAP search base, for example: \fIO=organization name, C=country\fR.
+/* .IP \fIldapsource_\fRdomain
+/*     If specified, only lookups ending in this value will be queried.
+/*      This can significantly reduce the query load on the LDAP server.
 /* .IP \fIldapsource_\fRtimeout
 /*     Deadline for LDAP open() and LDAP search() .
 /* .IP \fIldapsource_\fRquery_filter
 /*     The filter used to search for directory entries, for example
 /*     \fI(mailacceptinggeneralid=%s)\fR.
 /* .IP \fIldapsource_\fRresult_attribute
-/*     The attribute returned by the search, in which to find
+/*     The attribute(s) returned by the search, in which to find
 /*     RFC822 addresses, for example \fImaildrop\fR.
+/* .IP \fIldapsource_\fRspecial_result_attribute
+/*     The attribute(s) of directory entries that can contain DNs or URLs.
+/*      If found, a recursive subsequent search is done using their values.
 /* .IP \fIldapsource_\fRscope
 /*     LDAP search scope: sub, base, or one.
 /* .IP \fIldapsource_\fRbind
@@ -70,7 +75,7 @@
 /*     Yorktown Heights, NY 10532, USA
 /*
 /*     John Hensley
-/*     roll@ic.net
+/*     john@sunislelodge.com
 /*
 /*--*/
 
@@ -90,6 +95,8 @@
 
 /* Utility library. */
 
+#include "match_list.h"
+#include "match_ops.h"
 #include "msg.h"
 #include "mymalloc.h"
 #include "vstring.h"
@@ -107,8 +114,10 @@ typedef struct {
     int     server_port;
     int     scope;
     char   *search_base;
+    MATCH_LIST *domain;
     char   *query_filter;
-    char   *result_attribute;
+    ARGV   *result_attributes;
+    int     num_attributes;            /* rest of list is DN's. */
     int     bind;
     char   *bind_dn;
     char   *bind_pw;
@@ -170,9 +179,13 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
 
     /*
      * Configure alias dereferencing for this connection. Thanks to Mike
-     * Mattice for this.
+     * Mattice for this, and to Hery Rakotoarisoa for the v3 update.
      */
+#if (LDAP_API_VERSION >= 2000)
+    ldap_set_option(dict_ldap->ld, LDAP_OPT_DEREF, &(dict_ldap->dereference));
+#else
     dict_ldap->ld->ld_deref = dict_ldap->dereference;
+#endif
 
     /*
      * If this server requires a bind, do so. Thanks to Sam Tardieu for
@@ -227,27 +240,138 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
     return (0);
 }
 
+/*
+ * dict_ldap_get_values: for each entry returned by a search, get the values
+ * of all its attributes. Recurses to resolve any DN or URL values found.
+ *
+ * This and the rest of the handling of multiple attributes, DNs and URLs
+ * are thanks to LaMont Jones.
+ */
+static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
+                                        VSTRING * result)
+{
+    long    i = 0;
+    int     rc = 0;
+    LDAPMessage *resloop = 0;
+    LDAPMessage *entry = 0;
+    BerElement *ber;
+    char  **vals;
+    char   *attr;
+    char   *myname = "dict_ldap_get_values";
+    struct timeval tv;
+
+    tv.tv_sec = dict_ldap->timeout;
+    tv.tv_usec = 0;
+
+    if (msg_verbose)
+       msg_info("%s: Search found %d match(es)", myname,
+                ldap_count_entries(dict_ldap->ld, res));
+
+    for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL;
+        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);
+           continue;
+       }
+       for (; attr != NULL;
+            attr = ldap_next_attribute(dict_ldap->ld, entry, ber)) {
+
+           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);
+               continue;
+           }
+           for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
+               if (strcasecmp(dict_ldap->result_attributes->argv[i],
+                              attr) == 0) {
+                   if (msg_verbose)
+                       msg_info("%s: search returned value(s) for requested result attribute %s", myname, attr);
+                   break;
+               }
+           }
+
+           /*
+            * Append each returned address to the result list, possibly
+            * recursing (for dn or url attributes).
+            */
+           if (i < dict_ldap->num_attributes) {
+               for (i = 0; vals[i] != NULL; i++) {
+                   if (VSTRING_LEN(result) > 0)
+                       vstring_strcat(result, ",");
+                   vstring_strcat(result, vals[i]);
+               }
+           } else if (dict_ldap->result_attributes->argv[i]) {
+               for (i = 0; vals[i] != NULL; i++) {
+                   if (ldap_is_ldap_url(vals[i])) {
+                       if (msg_verbose)
+                           msg_info("%s: looking up URL %s", myname,
+                                    vals[i]);
+                       rc = ldap_url_search_st(dict_ldap->ld, vals[i],
+                                               0, &tv, &resloop);
+                   } else {
+                       if (msg_verbose)
+                           msg_info("%s: looking up DN %s", myname, vals[i]);
+                       rc = ldap_search_st(dict_ldap->ld, vals[i],
+                                           LDAP_SCOPE_BASE, "objectclass=*",
+                                        dict_ldap->result_attributes->argv,
+                                           0, &tv, &resloop);
+                   }
+                   if (rc == LDAP_SUCCESS)
+                       dict_ldap_get_values(dict_ldap, resloop, result);
+                   else {
+                       msg_warn("%s: search error %d: %s ", myname, rc,
+                                ldap_err2string(rc));
+                       dict_errno = DICT_ERR_RETRY;
+                   }
+                   if (resloop != 0)
+                       ldap_msgfree(resloop);
+               }
+           }
+           ldap_value_free(vals);
+       }
+    }
+    if (msg_verbose)
+       msg_info("%s: Leaving %s", myname, myname);
+}
+
 /* dict_ldap_lookup - find database entry */
 
 static const char *dict_ldap_lookup(DICT *dict, const char *name)
 {
     char   *myname = "dict_ldap_lookup";
     DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
-    static VSTRING *result;
     LDAPMessage *res = 0;
-    LDAPMessage *entry = 0;
+    static VSTRING *result;
     struct timeval tv;
     VSTRING *escaped_name = 0,
            *filter_buf = 0;
-    char   *result_attributes[1],
-          **attr_values;
-    long    i = 0;
     int     rc = 0;
     char   *sub,
            *end;
 
     dict_errno = 0;
 
+    if (msg_verbose)
+       msg_info("%s: In dict_ldap_lookup", myname);
+
+    /*
+     * If they specified a domain list for this map, then only search for
+     * addresses in domains on the list. This can significantly reduce the
+     * load on the LDAP server.
+     */
+    if (dict_ldap->domain) {
+       if (strrchr(name, '@') != 0) {
+           if (match_list_match(dict_ldap->domain, (char *) strrchr(name, '@') + 1) == 0) {
+               if (msg_verbose)
+                   msg_info("%s: domain of %s not found in domain list", myname,
+                            name);
+               return (0);
+           }
+       }
+    }
+
     /*
      * Initialize the result holder.
      */
@@ -255,9 +379,6 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
        result = vstring_alloc(2);
     vstring_strcpy(result, "");
 
-    if (msg_verbose)
-       msg_info("%s: In dict_ldap_lookup", myname);
-
     /*
      * Connect to the LDAP server, if necessary.
      */
@@ -371,56 +492,35 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
        msg_info("%s: Searching with filter %s", myname,
                 vstring_str(filter_buf));
 
-    /*
-     * Put result_attribute in an array, so the search can return only that
-     * attribute and not the entire entry.
-     */
-    result_attributes[0] = dict_ldap->result_attribute;
-
     if ((rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
                             dict_ldap->scope,
                             vstring_str(filter_buf),
-                            result_attributes,
+                            dict_ldap->result_attributes->argv,
                             0, &tv, &res)) == LDAP_SUCCESS) {
 
        /*
         * Search worked; extract the requested result_attribute.
         */
-       if (msg_verbose)
-           msg_info("%s: Search found %d match(es)", myname,
-                    ldap_count_entries(dict_ldap->ld, res));
+
+       dict_ldap_get_values(dict_ldap, res, result);
 
        /*
-        * There could have been lots of hits.
+        * OpenLDAP's ldap_next_attribute returns a bogus
+        * LDAP_DECODING_ERROR; I'm ignoring that for now.
         */
-       for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL;
-            entry = ldap_next_entry(dict_ldap->ld, entry)) {
-
-           /*
-            * And each entry could have multiple attributes.
-            */
-           attr_values = ldap_get_values(dict_ldap->ld, entry,
-                                         dict_ldap->result_attribute);
-           if (attr_values == NULL) {
-               msg_warn("%s: Entry doesn't have any values for %s",
-                        myname, dict_ldap->result_attribute);
-               continue;
-           }
 
-           /*
-            * Append each returned address to the result list.
-            */
-           for (i = 0; attr_values[i] != NULL; i++) {
-               if (VSTRING_LEN(result) > 0)
-                   vstring_strcat(result, ",");
-               vstring_strcat(result, attr_values[i]);
-           }
-           ldap_value_free(attr_values);
-       }
-       if (dict_ldap->ld->ld_errno != LDAP_SUCCESS)
+#if (LDAP_API_VERSION >= 2000)
+       ldap_get_option(dict_ldap->ld, LDAP_OPT_ERROR_NUMBER, &rc);
+       if (rc != LDAP_SUCCESS && rc != LDAP_DECODING_ERROR)
+           msg_warn("%s: Had some trouble with entries returned by search: %s", myname, ldap_err2string(rc));
+#else
+       if (dict_ldap->ld->ld_errno != LDAP_SUCCESS &&
+           dict_ldap->ld->ld_errno != LDAP_DECODING_ERROR)
            msg_warn
                ("%s: Had some trouble with entries returned by search: %s",
                 myname, ldap_err2string(dict_ldap->ld->ld_errno));
+#endif
+
        if (msg_verbose)
            msg_info("%s: Search returned %s", myname,
                     VSTRING_LEN(result) >
@@ -454,7 +554,11 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
     if (filter_buf != 0)
        vstring_free(filter_buf);
 
-    return (VSTRING_LEN(result) > 0 ? vstring_str(result) : 0);
+    /*
+     * If we had an error, return nothing, Otherwise, return the result, if
+     * any.
+     */
+    return (VSTRING_LEN(result) > 0 && !dict_errno ? vstring_str(result) : 0);
 }
 
 /* dict_ldap_update - add or update database entry */
@@ -478,8 +582,9 @@ static void dict_ldap_close(DICT *dict)
     myfree(dict_ldap->ldapsource);
     myfree(dict_ldap->server_host);
     myfree(dict_ldap->search_base);
+    match_list_free(dict_ldap->domain);
     myfree(dict_ldap->query_filter);
-    myfree(dict_ldap->result_attribute);
+    argv_free(dict_ldap->result_attributes);
     myfree(dict_ldap->bind_dn);
     myfree(dict_ldap->bind_pw);
     myfree((char *) dict_ldap);
@@ -492,8 +597,9 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     char   *myname = "dict_ldap_open";
     DICT_LDAP *dict_ldap;
     VSTRING *config_param;
-    int     rc = 0;
+    char   *domainlist;
     char   *scope;
+    char   *attr;
 
     dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap));
     dict_ldap->dict.lookup = dict_ldap_lookup;
@@ -566,6 +672,20 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
        msg_info("%s: %s is %s", myname, vstring_str(config_param),
                 dict_ldap->search_base);
 
+    vstring_sprintf(config_param, "%s_domain", ldapsource);
+    domainlist =
+       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
+                                           "", 0, 0));
+    if (domainlist) {
+       dict_ldap->domain = match_list_init(domainlist, 1, match_string);
+       if (dict_ldap->domain == NULL)
+           msg_warn("%s: domain match list creation using \"%s\" failed, will continue without it", myname, domainlist);
+       if (msg_verbose)
+           msg_info("%s: domain list created using \"%s\"", myname,
+                    domainlist);
+       myfree(domainlist);
+    }
+
     /*
      * get configured value of "ldapsource_timeout"; default to 10 seconds
      * 
@@ -589,12 +709,22 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
                 dict_ldap->query_filter);
 
     vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
-    dict_ldap->result_attribute =
-       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                           "maildrop", 0, 0));
+    attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
+                                              "maildrop", 0, 0));
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
-                dict_ldap->result_attribute);
+       msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
+    dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
+    dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
+
+    vstring_sprintf(config_param, "%s_special_result_attribute", ldapsource);
+    attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
+                                              "", 0, 0));
+    if (msg_verbose)
+       msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);
+
+    if (*attr) {
+       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
+    }
 
     /*
      * get configured value of "ldapsource_bind"; default to true
@@ -646,7 +776,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     dict_ldap->cache_expiry = get_mail_conf_int(vstring_str(config_param),
                                                30, 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s is %ld", myname, vstring_str(config_param),
                 dict_ldap->cache_expiry);
 
     /*
@@ -656,7 +786,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     dict_ldap->cache_size = get_mail_conf_int(vstring_str(config_param),
                                              32768, 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s is %ld", myname, vstring_str(config_param),
                 dict_ldap->cache_size);
 
     /*
@@ -698,3 +828,4 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
 }
 
 #endif
+
index ff09aad7a44203b020b1d5541696cb3ebb05064f..454b28719de2706db1d82d6f681cd51c8ea268bb 100644 (file)
@@ -181,7 +181,7 @@ typedef struct {
 static DICT_OPEN_INFO dict_open_info[] = {
     "environ", dict_env_open,
     "unix", dict_unix_open,
-#if 1
+#if 0
     "tcp", dict_tcp_open,
 #endif
 #ifdef HAS_DBM