2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-20001029

This commit is contained in:
Wietse Venema
2000-10-29 00:00:00 -05:00
committed by Viktor Dukhovni
parent 273b2bb449
commit 0a906a1db4
28 changed files with 873 additions and 403 deletions

View File

@@ -1,21 +1,68 @@
Purpose of this document Purpose of this document
======================== ========================
This document describes how to build Postfix with Berkeley DB This document describes how to build Postfix with third-party
support on systems that ship without DB library. The canonical Berkeley DB from www.sleepycat.com, or how to choose a specific
third-party source for Berkeley DB is www.sleepycat.com. Berkeley DB version when your system provides multiple implementations.
The information can also be used to build Postfix with a non-default Building Postfix with Sleepycat Berkeley DB
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 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 tidy
% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \ % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB.3.1/include" \
AUXLIBS=/usr/local/BerkeleyDB/lib/libdb.a AUXLIBS=/usr/local/BerkeleyDB.3.1/lib/libdb.a
% make % 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.

View File

@@ -4358,12 +4358,12 @@ Apologies for any names omitted.
the [] or host:port syntax, and there was no way to suppress the [] or host:port syntax, and there was no way to suppress
MX record lookups. Files: smtp/smtp_addr.c, smtp/smtp_connect.c. MX record lookups. Files: smtp/smtp_addr.c, smtp/smtp_connect.c.
Convenience: you can now specify multiple destinations in Convenience: you can now specify multiple SMTP destinations
the relayhost or fallback_relay configuration parameters. in the relayhost or fallback_relay configuration parameters.
The specified destinations will be tried in the specified The specified destinations will be tried in the specified
order. File: smtp/smtp_connect.c. order. File: smtp/smtp_connect.c.
Typographical corrections by Matthias Andree. Many typographical corrections by Matthias Andree.
20001024 20001024
@@ -4380,13 +4380,13 @@ Apologies for any names omitted.
Horror: postmap and postalias (newaliases) silently lose Horror: postmap and postalias (newaliases) silently lose
the file lock while building a lookup table with Berkeley the file lock while building a lookup table with Berkeley
DB 2.x and later on Solaris, HP-UX or IRIX. The result is DB 2.x and later on Solaris, HP-UX, IRIX, and UNIXWARE.
that table lookups fail while the table is being built, so The result is that table lookups fail while the table is
that mail is lost. In order to avoid this misbehavior one being built, so that mail is lost. In order to avoid this
has to use an undocumented feature that is NOT available misbehavior one has to use an undocumented feature that is
with the DB1.85 compatibility interface. Therefore, Postfix NOT available with the DB1.85 compatibility interface.
now supports three Berkeley DB programming interfaces of Therefore, Postfix now supports three Berkeley DB programming
increasing complexity. File: util/dict_db.c. interfaces of increasing complexity. File: util/dict_db.c.
Bugfix: some character manipulations were not portable for Bugfix: some character manipulations were not portable for
signed/unsigned characters. Files: global/quote_821_local.c, 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 begins with "From sender time-stamp". Sendmail silently
ignores such RFC violating garbage, and therefore Postfix ignores such RFC violating garbage, and therefore Postfix
needs to jump another hoop. File: smtpd/smtpd.c. 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.

View 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. substitute for the address Postfix is trying to resolve, e.g.
ldapsource_query_filter = (&(mail=%s)(paid_up=true)) 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) 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. 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) scope (sub)
The LDAP search scope: sub, base, or one. These translate into 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 EXAMPLES
======== ========
Here's a basic example for using LDAP to look up aliases. In main.cf, ALIASES
you have these configuration parameters defined: -------
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 alias_maps = hash:/etc/aliases, ldap:ldapsource
ldapsource_server_host = ldap.my.com 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 maildrops, which will be treated as RFC822 addresses to which the
message will be delivered. message will be delivered.
VIRTUAL DOMAINS/ADDRESSES
-------------------------
If you want to keep information for virtual lookups in your directory, 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 it's only a little more complicated. First you need to make sure Postfix
your virtual mailacceptinggeneralid attributes are fully qualified with knows about the virtual domain. An easy way to do that is to add the
their virtual domains. If you want to designate a directory entry as 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 default user for a virtual domain, just give it an additional
mailacceptinggeneralid (or the equivalent in your directory) of mailacceptinggeneralid (or the equivalent in your directory) of
"@virtual.dom". That's right, no user part. "@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 want to get information for relay_domains out of your directory, If you're using a version of Postfix newer than 19991226, that should do
the simplest way to get it is to add the domain name (without even the it. If not, you also need to add your virtual domains to relay_domains.
'@') as a mailacceptinggeneralid to some recipient in each domain, then Simply add "$virtual_maps" to your relay_domains line. Then you can use
add "$virtual_maps" to your relay_domains line. Then you can use the the same map you use to find virtual recipients to determine if a domain
same map you use to find virtual recipients to determine if a domain is is a valid virtual domain and should be allowed to relay.
a valid virtual domain and should be allowed to relay.
For example, the catchall user for a virtual domain might look like In summary, you might have a catchall user for a virtual domain that
this: looks like this:
dn: cn=defaultrecipient, dc=fake, dc=dom dn: cn=defaultrecipient, dc=fake, dc=dom
objectclass: top objectclass: top
objectclass: rfc822mailgroup objectclass: virtualaccount
cn: defaultrecipient cn: defaultrecipient
owner: uid=root, dc=someserver, dc=isp, dc=dom owner: uid=root, dc=someserver, dc=isp, dc=dom
mailacceptinggeneralid: fake.dom 1 -> mailacceptinggeneralid: fake.dom
mailacceptinggeneralid: @fake.dom 2 -> mailacceptinggeneralid: @fake.dom
maildrop: realuser@real.dom 3 -> maildrop: realuser@real.dom
If you don't necessarily have a catchall user for the domain (i.e. you 1: Postfix knows fake.dom is a valid virtual domain when it looks for
want mail to unknown users in the domain to bounce), and don't want to this and gets something (the maildrop) back.
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 2: This causes any mail for unknown users in fake.dom to go to this entry ...
that map to relay_domains instead of "$virtual_maps". All that's
necessary is that a search for the domain name return something. 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 Other common uses for LDAP lookups include rewriting senders and
recipients with Postfix' canonical lookups, for example in order to make 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 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 - You probably want to make sure that mailacceptinggeneralids are
unique, and that not just anyone can specify theirs as postmaster or unique, and that not just anyone can specify theirs as postmaster or
root, say. root, say.
@@ -266,17 +299,17 @@ contents, please include the applicable bits of some directory entries.
CREDITS CREDITS
======= =======
Support for LDAP was initially written by Prabhat K Singh of VSNL, Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
Bombay, India, and then hideously bloated by John Hensley to support John Hensley: Multiple LDAP sources with more configurable attributes.
multiple sources and more configurable attributes. The caching bits were Carsten Hoeger: Search scope handling.
initially worked out by Prabhat, then munged to support the multiple LaMont Jones: Domain restriction, URL and DN searches, multiple result
sources. attributes.
Mike Mattice: Alias dereferencing control.
Other contributors, of code or direction or dope slaps, include: Hery Rakotoarisoa: Patches for LDAPv3 updating.
Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
Manuel Guesdon Keith Stevenson: RFC 2254 escaping in queries.
Carsten Hoeger Samuel Tardieu: Noticed that searches could include wildcards, prompting
Keith Stevenson the work on RFC 2254 escaping in queries. Spotted a bug
Samuel Tardieu in binding.
And of course Wietse. And of course Wietse.

View 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. Berkeley DB support has changed for Solaris, HP-UX, UNIXWARE, IRIX.
You can no longer use the DB 1.85 compatibility interface, because On these systems, Postfix must no longer use DB 1.85 compatibility
that interface loses the file lock while building a table, so that mode, because that mode loses the file lock while building a table,
table lookups fail and mail is lost. See the DB_README file for so that table lookups fail and mail is lost. See the DB_README file
instructions on how to build with third-party Berkeley DB support. for instructions on how to build Postfix with third-party Berkeley
DB support.
The "fast ETRN" policy configuration has changed. You now specify The "fast ETRN" policy configuration has changed. You now specify
the list of eligible "fast ETRN" domains with the fast_flush_domains the list of eligible "fast ETRN" domains with the fast_flush_domains
parameter (default: $relay_domains). In order to disable the feature, parameter (default: $relay_domains). In order to disable the feature,
specify an empty value (fast_flush_domains =). 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 Incompatible changes with snapshot-20001005
=========================================== ===========================================

View File

@@ -122,9 +122,12 @@ mail_owner = postfix
# internal DNS uses no MX records, specify the name of the intranet # internal DNS uses no MX records, specify the name of the intranet
# gateway host instead. # gateway host instead.
# #
# Specify a domain, host, host:port, [host]:port, [address] or # In the case of SMTP, specify a domain, host, host:port, [host]:port,
# [address]:port. Use the form [name] to turn off MX lookups. See # [address] or [address]:port; the form [host] turns off MX lookups.
# also the default_transport parameter if you're connected via UUCP. # 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 = $mydomain
# relayhost = gateway.my.domain # relayhost = gateway.my.domain

View File

@@ -245,9 +245,12 @@ recipient_delimiter =
# internal DNS uses no MX records, specify the name of the intranet # internal DNS uses no MX records, specify the name of the intranet
# gateway host instead. # gateway host instead.
# #
# Specify a domain, host, host:port, [host]:port, [address] or # In the case of SMTP, specify a domain, host, host:port, [host]:port,
# [address]:port. Use the form [name] to turn off MX lookups. See # [address] or [address]:port; the form [host] turns off MX lookups.
# also the default_transport parameter if you're connected via UUCP. # 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 = $mydomain
# relayhost = gateway.my.domain # relayhost = gateway.my.domain

View File

@@ -24,6 +24,11 @@
# By default, mail is bounced when a destination is not found, and # By default, mail is bounced when a destination is not found, and
# delivery is deferred if a destination is unreachable. # 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 = fallback_relay =
# The ignore_mx_lookup_error parameter controls what happens when a # The ignore_mx_lookup_error parameter controls what happens when a

View 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 set -e
umask 022 umask 022
POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix} POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
cd ${POSTFIX_DIR} cd ${POSTFIX_DIR}
mkdir etc mkdir -p etc lib usr/lib/zoneinfo
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 lib # find localtime (SuSE 5.3 does not have /etc/localtime)
cp /lib/libnss_* lib 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
cond_copy '/lib/libnss_*' lib
cond_copy '/lib/libresolv*' lib

View File

@@ -2592,79 +2592,11 @@ systems.
<p> <p>
In order to build Postfix with <b>db</b> support on UNIX systems 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 that do not have <b>db</b> support out of the box, you can use the
db-1.85 release, or <a href="http://www.sleepycat.com">the current Berkeley DB source code from <a
version</a> which has a db-1.85 compatible interface. href="http://www.sleepycat.com">www.sleepycat.com</a>. See the file
<b>DB_README</b> in the Postfix source code distribution for
<p> instructions on how to build Postfix with Sleepycat's Berkeley DB.
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>
<hr> <hr>

View 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- 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. mon as appropriate.
If no server is given on the command line, the LMTP client The LMTP client connects to the destination specified in
connects to the destination specified in the message the message delivery request. The destination, usually
delivery request and to the TCP port defined as <b>lmtp</b> in specified in the Postfix <a href="transport.5.html"><b>transport</b>(5)</a> table, has the form:
<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 <b>unix</b>:<i>pathname</i>
24) will be used. The LMTP client does not perform MX Connect to the UNIX-domain server that is bound to
(mail exchanger) lookups since those are defined only for the specified <i>pathname</i>. If the process runs
SMTP. 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> <b>SECURITY</b>
The LMTP client is moderately security-sensitive. It talks 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/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/rfc1651.html">RFC 1651</a> (SMTP service extensions)
<a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration) <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/rfc2033.html">RFC 2033</a> (LMTP protocol)
<a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining) <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 The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax 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> details and for default values. Use the <b>postfix</b> <b>reload</b>
1
LMTP(8) LMTP(8)
command after a configuration change. command after a configuration change.
<b>Miscellaneous</b> <b>Miscellaneous</b>
@@ -108,6 +125,18 @@ LMTP(8) LMTP(8)
The effectiveness of cached connections will be The effectiveness of cached connections will be
determined by the number of LMTP servers in use, determined by the number of LMTP servers in use,
and the concurrency limit specified for the LMTP and the concurrency limit specified for the LMTP
2
LMTP(8) LMTP(8)
client. Cached connections are closed under any of client. Cached connections are closed under any of
the following conditions: the following conditions:
@@ -125,18 +154,6 @@ LMTP(8) LMTP(8)
<b>o</b> Upon the onset of another delivery request, <b>o</b> Upon the onset of another delivery request,
the LMTP server associated with the current the LMTP server associated with the current
2
LMTP(8) LMTP(8)
session does not respond to the <b>RSET</b> com- session does not respond to the <b>RSET</b> com-
mand. mand.
@@ -175,6 +192,17 @@ LMTP(8) LMTP(8)
LMTP server. If no connection can be made within LMTP server. If no connection can be made within
the deadline, the message is deferred. the deadline, the message is deferred.
3
LMTP(8) LMTP(8)
<b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b> <b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b>
Timeout in seconds for sending the <b>LHLO</b> command, Timeout in seconds for sending the <b>LHLO</b> command,
and for receiving the server response. and for receiving the server response.
@@ -191,18 +219,6 @@ LMTP(8) LMTP(8)
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. 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> <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. 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="master.8.html">master(8)</a> process manager
<a href="qmgr.8.html">qmgr(8)</a> queue manager <a href="qmgr.8.html">qmgr(8)</a> queue manager
services(4) Internet services and aliases 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 syslogd(8) system logging
<b>LICENSE</b> <b>LICENSE</b>
@@ -241,6 +257,18 @@ LMTP(8) LMTP(8)
Alterations for LMTP by: Alterations for LMTP by:
Philip A. Prindeville Philip A. Prindeville
4
LMTP(8) LMTP(8)
Mirapoint, Inc. Mirapoint, Inc.
USA. USA.
@@ -260,7 +288,45 @@ LMTP(8) LMTP(8)
4
5
</pre> </body> </html> </pre> </body> </html>

View File

@@ -29,6 +29,11 @@ SMTP(8) SMTP(8)
preference, and connects to each listed address until it preference, and connects to each listed address until it
finds a server that responds. 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- Once the SMTP client has received the server greeting ban-
ner, no error will cause it to proceed to the next address ner, no error will cause it to proceed to the next address
on the mail exchanger list. Instead, the message is either on the mail exchanger list. Instead, the message is either
@@ -36,7 +41,7 @@ SMTP(8) SMTP(8)
<b>SECURITY</b> <b>SECURITY</b>
The SMTP client is moderately security-sensitive. It talks 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. SMTP client can be run chrooted at fixed low privilege.
<b>STANDARDS</b> <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) <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
<b>DIAGNOSTICS</b> <b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Cor- Problems and transactions are logged to <b>syslogd</b>(8). Cor-
rupted message files are marked so that the queue manager rupted message files are marked so that the queue manager
can move them to the <b>corrupt</b> queue for further inspection. 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, Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
the postmaster is notified of bounces, protocol problems, the postmaster is notified of bounces, protocol problems,
and of other trouble. 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 1
@@ -71,36 +71,40 @@ SMTP(8) SMTP(8)
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. command after a configuration change.
<b>Miscellaneous</b> <b>Miscellaneous</b>
<b>best</b><i>_</i><b>mx</b><i>_</i><b>transport</b> <b>best</b><i>_</i><b>mx</b><i>_</i><b>transport</b>
Name of the delivery transport to use when the Name of the delivery transport to use when the
local machine is the most-preferred mail exchanger local machine is the most-preferred mail exchanger
(by default, a mailer loop is reported, and the (by default, a mailer loop is reported, and the
message is bounced). message is bounced).
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> <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. 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> <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
List of domain or network patterns. When a remote List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log- host matches a pattern, increase the verbose log-
ging level by the amount specified in the ging level by the amount specified in the
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter. <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> <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. forwarded via a smart relay host.
<b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b> <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. error notices.
<b>fallback</b><i>_</i><b>relay</b> <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. 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> <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> <b>inet</b><i>_</i><b>interfaces</b>
The network interface addresses that this mail sys- 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 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. delivery loops.
<b>notify</b><i>_</i><b>classes</b> <b>notify</b><i>_</i><b>classes</b>
When this parameter includes the <b>protocol</b> class, When this parameter includes the <b>protocol</b> class,
send mail to the postmaster with transcripts of send mail to the postmaster with transcripts of
SMTP sessions with protocol errors. 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) 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> <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> <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. QUIT.
<b>smtp</b><i>_</i><b>bind</b><i>_</i><b>address</b> <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. connection.
<b>Authentication</b> <b>controls</b> <b>Authentication</b> <b>controls</b>
<b>smtp</b><i>_</i><b>enable</b><i>_</i><b>sasl</b><i>_</i><b>auth</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> 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 (SASL). By default, Postfix is built without SASL
support. support.
<b>smtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b> <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> 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. authenticate.
<b>smtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b> <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>Resource</b> <b>controls</b>
<b>smtp</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</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 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>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> <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- Limit the number of recipients per message
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.
@@ -203,24 +203,30 @@ SMTP(8) SMTP(8)
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, 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. exchanger list.
<b>smtp</b><i>_</i><b>helo</b><i>_</i><b>timeout</b> <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- 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 greeting banner within the deadline, the SMTP
client tries the next address on the mail exchanger client tries the next address on the mail exchanger
list. list.
<b>smtp</b><i>_</i><b>helo</b><i>_</i><b>timeout</b> <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. and for receiving the server response.
<b>smtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b> <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. mand, and for receiving the server response.
<b>smtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b> <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. and for receiving the server response.
<b>smtp</b><i>_</i><b>data</b><i>_</i><b>init</b><i>_</i><b>timeout</b> <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. and for receiving the server response.
<b>smtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b> <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> <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 Timeout in seconds for sending the "<b>.</b>" command, and
for receiving the server response. When no response 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. be delivered multiple times.
<b>smtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b> <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. and for receiving the server response.
<b>SEE</b> <b>ALSO</b> <b>SEE</b> <b>ALSO</b>
@@ -250,13 +256,7 @@ SMTP(8) SMTP(8)
<a href="qmgr.8.html">qmgr(8)</a> queue manager <a href="qmgr.8.html">qmgr(8)</a> queue manager
syslogd(8) system logging 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) 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 P.O. Box 704
Yorktown Heights, NY 10598, USA Yorktown Heights, NY 10598, USA
@@ -311,13 +318,6 @@ SMTP(8) SMTP(8)

View File

@@ -159,18 +159,12 @@ case "$SYSTEM.$RELEASE" in
*) echo "Unknown AIX version: `uname -v`." 1>&2; exit 1;; *) echo "Unknown AIX version: `uname -v`." 1>&2; exit 1;;
esac;; esac;;
Linux.2*) SYSTYPE=LINUX2 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 then
CCARGS="$CCARGS -I/usr/include/db3" CCARGS="$CCARGS -I/usr/include/db"
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"
fi fi
for name in nsl resolv for name in db nsl resolv
do do
test -f /usr/lib/lib$name.a && SYSLIBS="$SYSLIBS -l$name" test -f /usr/lib/lib$name.a && SYSLIBS="$SYSLIBS -l$name"
done done
@@ -192,9 +186,6 @@ HP-UX.A.09.*) SYSTYPE=HPUX9
CCARGS="$CCARGS -DHAS_DB" CCARGS="$CCARGS -DHAS_DB"
SYSLIBS="$SYSLIBS -ldb" SYSLIBS="$SYSLIBS -ldb"
fi fi
if [ -f /usr/include/db_185.h ]; then
CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
fi
;; ;;
HP-UX.B.10.*) SYSTYPE=HPUX10 HP-UX.B.10.*) SYSTYPE=HPUX10
CCARGS="$CCARGS `nm /usr/lib/libc.a 2>/dev/null | CCARGS="$CCARGS `nm /usr/lib/libc.a 2>/dev/null |
@@ -203,9 +194,6 @@ HP-UX.B.10.*) SYSTYPE=HPUX10
CCARGS="$CCARGS -DHAS_DB" CCARGS="$CCARGS -DHAS_DB"
SYSLIBS=-ldb SYSLIBS=-ldb
fi fi
if [ -f /usr/include/db_185.h ]; then
CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
fi
;; ;;
HP-UX.B.11.*) SYSTYPE=HPUX11 HP-UX.B.11.*) SYSTYPE=HPUX11
SYSLIBS=-lnsl SYSLIBS=-lnsl
@@ -213,9 +201,6 @@ HP-UX.B.11.*) SYSTYPE=HPUX11
CCARGS="$CCARGS -DHAS_DB" CCARGS="$CCARGS -DHAS_DB"
SYSLIBS="$SYSLIBS -ldb" SYSLIBS="$SYSLIBS -ldb"
fi fi
if [ -f /usr/include/db_185.h ]; then
CCARGS="$CCARGS -DPATH_DB_H='<db_185.h>'"
fi
;; ;;
ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
RANLIB=echo RANLIB=echo

View 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 be tried again at a later time. Delivery problem reports are sent
to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate. 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 The LMTP client connects to the destination specified in the message
to the destination specified in the message delivery request and to delivery request. The destination, usually specified in the Postfix
the TCP port defined as \fBlmtp\fR in \fBservices\fR(4). If no such \fBtransport\fR(5) table, has the form:
service is found, the \fBlmtp_tcp_port\fR configuration parameter .IP \fBunix\fR:\fIpathname\fR
(default value of 24) will be used. The LMTP client does not perform Connect to the UNIX-domain server that is bound to the specified
MX (mail exchanger) lookups since those are defined only for SMTP. \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 .SH SECURITY
.na .na
.nf .nf

View 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 the destination host, sorts the list by preference, and connects
to each listed address until it finds a server that responds. 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 Once the SMTP client has received the server greeting banner, no
error will cause it to proceed to the next address on the mail error will cause it to proceed to the next address on the mail
exchanger list. Instead, the message is either bounced, or its exchanger list. Instead, the message is either bounced, or its

View File

@@ -189,9 +189,6 @@ static DOMAIN_LIST *flush_domains;
static int flush_policy_ok(const char *site) 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)); 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); 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 */ /* main - pass control to the single-threaded skeleton */
int main(int argc, char **argv) int main(int argc, char **argv)
@@ -509,5 +513,6 @@ int main(int argc, char **argv)
single_server_main(argc, argv, flush_service, single_server_main(argc, argv, flush_service,
MAIL_SERVER_TIME_TABLE, time_table, MAIL_SERVER_TIME_TABLE, time_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
0); 0);
} }

Binary file not shown.

View File

@@ -15,7 +15,7 @@
* Version of this program. * Version of this program.
*/ */
#define VAR_MAIL_VERSION "mail_version" #define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-20001028" #define DEF_MAIL_VERSION "Snapshot-20001029"
extern char *var_mail_version; extern char *var_mail_version;
/* LICENSE /* LICENSE

View File

@@ -17,12 +17,26 @@
/* be tried again at a later time. Delivery problem reports are sent /* be tried again at a later time. Delivery problem reports are sent
/* to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate. /* 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 /* The LMTP client connects to the destination specified in the message
/* to the destination specified in the message delivery request and to /* delivery request. The destination, usually specified in the Postfix
/* the TCP port defined as \fBlmtp\fR in \fBservices\fR(4). If no such /* \fBtransport\fR(5) table, has the form:
/* service is found, the \fBlmtp_tcp_port\fR configuration parameter /* .IP \fBunix\fR:\fIpathname\fR
/* (default value of 24) will be used. The LMTP client does not perform /* Connect to the UNIX-domain server that is bound to the specified
/* MX (mail exchanger) lookups since those are defined only for SMTP. /* \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 /* SECURITY
/* .ad /* .ad
/* .fi /* .fi

View File

@@ -1,6 +1,6 @@
/*++ /*++
/* NAME /* NAME
/* lmtp_connect_inet 3 /* lmtp_connect 3
/* SUMMARY /* SUMMARY
/* connect to LMTP server /* connect to LMTP server
/* SYNOPSIS /* SYNOPSIS
@@ -12,13 +12,22 @@
/* DESCRIPTION /* DESCRIPTION
/* This module implements LMTP connection management. /* 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. /* The destination is either a host name or a numeric address.
/* Symbolic or numeric service port information may be appended, /* Symbolic or numeric service port information may be appended,
/* separated by a colon (":"). /* separated by a colon (":").
/* /*
/* Numerical address information should always be quoted with `[]'. /* Numerical address information should always be quoted with `[]'.
/* .PP
/* When no transport is specified, "inet" is assumed.
/* DIAGNOSTICS /* DIAGNOSTICS
/* This routine either returns an LMTP_SESSION pointer, or /* This routine either returns an LMTP_SESSION pointer, or
/* returns a null pointer and set the \fIlmtp_errno\fR /* returns a null pointer and set the \fIlmtp_errno\fR
@@ -58,6 +67,7 @@
#include <sys_defs.h> #include <sys_defs.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
@@ -97,6 +107,58 @@
#include "lmtp.h" #include "lmtp.h"
#include "lmtp_addr.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 */ /* lmtp_connect_addr - connect to explicit address */
static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port, 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"; char *myname = "lmtp_connect_addr";
struct sockaddr_in sin; struct sockaddr_in sin;
int sock; int sock;
int conn_stat;
int saved_errno;
VSTREAM *stream;
int ch;
/* /*
* Sanity checks. * Sanity checks.
@@ -137,19 +195,35 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
if (msg_verbose) if (msg_verbose)
msg_info("%s: trying: %s[%s] port %d...", msg_info("%s: trying: %s[%s] port %d...",
myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port)); 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) { if (var_lmtp_conn_tmout > 0) {
non_blocking(sock, NON_BLOCKING); non_blocking(sock, NON_BLOCKING);
conn_stat = timed_connect(sock, (struct sockaddr *) & sin, conn_stat = timed_connect(sock, sa, len, var_lmtp_conn_tmout);
sizeof(sin), var_lmtp_conn_tmout);
saved_errno = errno; saved_errno = errno;
non_blocking(sock, BLOCKING); non_blocking(sock, BLOCKING);
errno = saved_errno; errno = saved_errno;
} else { } else {
conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin)); conn_stat = connect(sock, sa, len);
} }
if (conn_stat < 0) { if (conn_stat < 0) {
vstring_sprintf(why, "connect to %s[%s]: %m", vstring_sprintf(why, "connect to %s[%s]: %m",
addr->name, inet_ntoa(sin.sin_addr)); name, addr);
lmtp_errno = LMTP_RETRY; lmtp_errno = LMTP_RETRY;
close(sock); close(sock);
return (0); 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) { if (read_wait(sock, var_lmtp_lhlo_tmout) < 0) {
vstring_sprintf(why, "connect to %s[%s]: read timeout", vstring_sprintf(why, "connect to %s[%s]: read timeout",
addr->name, inet_ntoa(sin.sin_addr)); name, addr);
lmtp_errno = LMTP_RETRY; lmtp_errno = LMTP_RETRY;
close(sock); close(sock);
return (0); return (0);
@@ -172,7 +246,7 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
stream = vstream_fdopen(sock, O_RDWR); stream = vstream_fdopen(sock, O_RDWR);
if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) { if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
vstring_sprintf(why, "connect to %s[%s]: server dropped connection", vstring_sprintf(why, "connect to %s[%s]: server dropped connection",
addr->name, inet_ntoa(sin.sin_addr)); name, addr);
lmtp_errno = LMTP_RETRY; lmtp_errno = LMTP_RETRY;
vstream_fclose(stream); vstream_fclose(stream);
return (0); return (0);
@@ -184,13 +258,12 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
*/ */
if (ch == '4' || ch == '5') { if (ch == '4' || ch == '5') {
vstring_sprintf(why, "connect to %s[%s]: server refused mail service", vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
addr->name, inet_ntoa(sin.sin_addr)); name, addr);
lmtp_errno = LMTP_RETRY; lmtp_errno = LMTP_RETRY;
vstream_fclose(stream); vstream_fclose(stream);
return (0); return (0);
} }
return (lmtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr), return (lmtp_session_alloc(stream, name, addr, destination));
destination));
} }
/* lmtp_connect_host - direct connection to host */ /* 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 */ /* lmtp_parse_destination - parse destination */
static char *lmtp_parse_destination(const char *destination, char *def_service, 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 *myname = "lmtp_parse_destination";
char *buf = mystrdup(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) LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
{ {
char *myname = "lmtp_connect_inet"; char *myname = "lmtp_connect";
LMTP_SESSION *session; LMTP_SESSION *session;
char *dest_buf; char *dest_buf;
char *host; char *host;
@@ -281,7 +354,15 @@ LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
/* /*
* Connect to the LMTP server. * 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, dest_buf = lmtp_parse_destination(destination, def_service,
&host, &port); &host, &port);
if (msg_verbose) if (msg_verbose)

View File

@@ -246,11 +246,9 @@ int lmtp_lhlo(LMTP_STATE *state)
* because they benefit little from pipelining. * because they benefit little from pipelining.
*/ */
if (state->features & LMTP_FEATURE_PIPELINING) { if (state->features & LMTP_FEATURE_PIPELINING) {
if (getsockopt(vstream_fileno(state->session->stream), SOL_SOCKET, state->sndbufsize = 4 * 1024;
SO_SNDBUF, (char *) &state->sndbufsize, &optlen) < 0)
msg_fatal("%s: getsockopt: %m", myname);
if (msg_verbose) 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); state->sndbufsize);
} else } else
state->sndbufsize = 0; state->sndbufsize = 0;

View File

@@ -21,6 +21,10 @@
/* the destination host, sorts the list by preference, and connects /* the destination host, sorts the list by preference, and connects
/* to each listed address until it finds a server that responds. /* 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 /* Once the SMTP client has received the server greeting banner, no
/* error will cause it to proceed to the next address on the mail /* error will cause it to proceed to the next address on the mail
/* exchanger list. Instead, the message is either bounced, or its /* exchanger list. Instead, the message is either bounced, or its

View File

@@ -401,7 +401,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why)
*/ */
cp = save = concatenate(destination, " ", var_fallback_relay, (char *) 0); 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. * Parse the destination. Default is to use the SMTP port.

View File

@@ -353,6 +353,13 @@ char *smtpd_path;
#define STR(x) vstring_str(x) #define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(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 */ /* collapse_args - put arguments together again */
static void collapse_args(int argc, SMTPD_TOKEN *argv) 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"); smtpd_chat_reply(state, "501 Syntax: HELO hostname");
return (-1); return (-1);
} }
if (state->helo_name != 0) { if (state->helo_name != 0)
myfree(state->helo_name); helo_reset(state);
state->helo_name = 0;
}
if (argc > 2) if (argc > 2)
collapse_args(argc - 1, argv + 1); collapse_args(argc - 1, argv + 1);
if (SMTPD_STAND_ALONE(state) == 0 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"); smtpd_chat_reply(state, "501 Syntax: EHLO hostname");
return (-1); return (-1);
} }
if (state->helo_name != 0) { if (state->helo_name != 0)
myfree(state->helo_name); helo_reset(state);
state->helo_name = 0; #if 0
} mail_reset(state);
rcpt_reset(state);
#endif
if (argc > 2) if (argc > 2)
collapse_args(argc - 1, argv + 1); collapse_args(argc - 1, argv + 1);
if (SMTPD_STAND_ALONE(state) == 0 if (SMTPD_STAND_ALONE(state) == 0

View File

@@ -4,12 +4,19 @@
/* SUMMARY /* SUMMARY
/* multi-threaded SMTP/LMTP test server /* multi-threaded SMTP/LMTP test server
/* SYNOPSIS /* 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 /* DESCRIPTION
/* \fIsmtp-sink\fR listens on the named host (or address) and port. /* \fIsmtp-sink\fR listens on the named host (or address) and port.
/* It takes SMTP messages from the network and throws them away. /* It takes SMTP messages from the network and throws them away.
/* The purpose is to measure SMTP client performance, not protocol /* The purpose is to measure SMTP client performance, not protocol
/* compliance. /* 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. /* This program is the complement of the \fIsmtp-source\fR program.
/* .IP -c /* .IP -c
/* Display a running counter that is updated whenever an SMTP /* Display a running counter that is updated whenever an SMTP
@@ -392,7 +399,13 @@ int main(int argc, char **argv)
*/ */
buffer = vstring_alloc(1024); buffer = vstring_alloc(1024);
var_myhostname = "smtp-sink"; 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. * Start the event handler.

View File

@@ -4,12 +4,16 @@
/* SUMMARY /* SUMMARY
/* multi-threaded SMTP test generator /* multi-threaded SMTP test generator
/* SYNOPSIS /* 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 /* DESCRIPTION
/* smtp-source connects to the named host and port (default 25) /* smtp-source connects to the named host and port (default 25)
/* and sends one or more little messages to it, either sequentially /* and sends one or more little messages to it, either sequentially
/* or in parallel. The program speaks either SMTP (default) or /* 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: /* Options:
/* .IP -c /* .IP -c
@@ -64,6 +68,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/un.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@@ -131,6 +136,10 @@ static const char *var_myhostname;
static int session_count; static int session_count;
static int message_count = 1; static int message_count = 1;
static struct sockaddr_in sin; 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 int recipients = 1;
static char *defaddr; static char *defaddr;
static char *recipient; 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 * retrieving it later with getsockopt(). We can't use MSG_PEEK to
* distinguish between server disconnect and connection refused. * 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"); msg_fatal("socket: %m");
(void) non_blocking(fd, NON_BLOCKING); (void) non_blocking(fd, NON_BLOCKING);
session->stream = vstream_fdopen(fd, O_RDWR); session->stream = vstream_fdopen(fd, O_RDWR);
event_enable_write(fd, connect_done, (char *) session); event_enable_write(fd, connect_done, (char *) session);
smtp_timeout_setup(session->stream, var_timeout); smtp_timeout_setup(session->stream, var_timeout);
if (connect(fd, (struct sockaddr *) & sin, sizeof(sin)) < 0 if (connect(fd, sa, sa_len) < 0 && errno != EINPROGRESS)
&& errno != EINPROGRESS)
fail_connect(session); fail_connect(session);
} }
@@ -739,6 +747,8 @@ int main(int argc, char **argv)
SESSION *session; SESSION *session;
char *host; char *host;
char *port; char *port;
char *path;
int path_len;
int sessions = 1; int sessions = 1;
int ch; int ch;
int i; int i;
@@ -813,8 +823,6 @@ int main(int argc, char **argv)
} }
if (argc - optind != 1) if (argc - optind != 1)
usage(argv[0]); usage(argv[0]);
if ((port = split_at(host = argv[optind], ':')) == 0)
port = "smtp";
if (random_delay > 0) if (random_delay > 0)
srand(getpid()); srand(getpid());
@@ -822,10 +830,31 @@ int main(int argc, char **argv)
/* /*
* Translate endpoint address to internal form. * Translate endpoint address to internal form.
*/ */
memset((char *) &sin, 0, sizeof(sin)); if (strncmp(argv[optind], "unix:", 5) == 0) {
sin.sin_family = AF_INET; path = argv[optind] + 5;
sin.sin_addr.s_addr = find_inet_addr(host); path_len = strlen(path);
sin.sin_port = find_inet_port(port, "tcp"); 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 * Make sure the SMTP server cannot run us out of memory by sending

View File

@@ -82,6 +82,10 @@
#define DONT_CLOBBER DB_NOOVERWRITE #define DONT_CLOBBER DB_NOOVERWRITE
#endif #endif
#ifndef DB_FCNTL_LOCKING
#define DB_FCNTL_LOCKING 0
#endif
/* Utility library. */ /* Utility library. */
#include "msg.h" #include "msg.h"
@@ -399,6 +403,8 @@ static void dict_db_close(DICT *dict)
{ {
DICT_DB *dict_db = (DICT_DB *) 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) if (DICT_DB_CLOSE(dict_db->db) < 0)
msg_fatal("close database %s: %m", dict_db->path); msg_fatal("close database %s: %m", dict_db->path);
myfree(dict_db->path); myfree(dict_db->path);

View File

@@ -1,4 +1,3 @@
/*++ /*++
/* NAME /* NAME
/* dict_ldap 3 /* dict_ldap 3
@@ -32,14 +31,20 @@
/* The port the LDAP server listens on. /* The port the LDAP server listens on.
/* .IP \fIldapsource_\fRsearch_base /* .IP \fIldapsource_\fRsearch_base
/* The LDAP search base, for example: \fIO=organization name, C=country\fR. /* 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 /* .IP \fIldapsource_\fRtimeout
/* Deadline for LDAP open() and LDAP search() . /* Deadline for LDAP open() and LDAP search() .
/* .IP \fIldapsource_\fRquery_filter /* .IP \fIldapsource_\fRquery_filter
/* The filter used to search for directory entries, for example /* The filter used to search for directory entries, for example
/* \fI(mailacceptinggeneralid=%s)\fR. /* \fI(mailacceptinggeneralid=%s)\fR.
/* .IP \fIldapsource_\fRresult_attribute /* .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. /* 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 /* .IP \fIldapsource_\fRscope
/* LDAP search scope: sub, base, or one. /* LDAP search scope: sub, base, or one.
/* .IP \fIldapsource_\fRbind /* .IP \fIldapsource_\fRbind
@@ -70,7 +75,7 @@
/* Yorktown Heights, NY 10532, USA /* Yorktown Heights, NY 10532, USA
/* /*
/* John Hensley /* John Hensley
/* roll@ic.net /* john@sunislelodge.com
/* /*
/*--*/ /*--*/
@@ -90,6 +95,8 @@
/* Utility library. */ /* Utility library. */
#include "match_list.h"
#include "match_ops.h"
#include "msg.h" #include "msg.h"
#include "mymalloc.h" #include "mymalloc.h"
#include "vstring.h" #include "vstring.h"
@@ -107,8 +114,10 @@ typedef struct {
int server_port; int server_port;
int scope; int scope;
char *search_base; char *search_base;
MATCH_LIST *domain;
char *query_filter; char *query_filter;
char *result_attribute; ARGV *result_attributes;
int num_attributes; /* rest of list is DN's. */
int bind; int bind;
char *bind_dn; char *bind_dn;
char *bind_pw; 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 * 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; dict_ldap->ld->ld_deref = dict_ldap->dereference;
#endif
/* /*
* If this server requires a bind, do so. Thanks to Sam Tardieu for * 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); 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 */ /* dict_ldap_lookup - find database entry */
static const char *dict_ldap_lookup(DICT *dict, const char *name) static const char *dict_ldap_lookup(DICT *dict, const char *name)
{ {
char *myname = "dict_ldap_lookup"; char *myname = "dict_ldap_lookup";
DICT_LDAP *dict_ldap = (DICT_LDAP *) dict; DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
static VSTRING *result;
LDAPMessage *res = 0; LDAPMessage *res = 0;
LDAPMessage *entry = 0; static VSTRING *result;
struct timeval tv; struct timeval tv;
VSTRING *escaped_name = 0, VSTRING *escaped_name = 0,
*filter_buf = 0; *filter_buf = 0;
char *result_attributes[1],
**attr_values;
long i = 0;
int rc = 0; int rc = 0;
char *sub, char *sub,
*end; *end;
dict_errno = 0; 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. * Initialize the result holder.
*/ */
@@ -255,9 +379,6 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
result = vstring_alloc(2); result = vstring_alloc(2);
vstring_strcpy(result, ""); vstring_strcpy(result, "");
if (msg_verbose)
msg_info("%s: In dict_ldap_lookup", myname);
/* /*
* Connect to the LDAP server, if necessary. * 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, msg_info("%s: Searching with filter %s", myname,
vstring_str(filter_buf)); 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, if ((rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
dict_ldap->scope, dict_ldap->scope,
vstring_str(filter_buf), vstring_str(filter_buf),
result_attributes, dict_ldap->result_attributes->argv,
0, &tv, &res)) == LDAP_SUCCESS) { 0, &tv, &res)) == LDAP_SUCCESS) {
/* /*
* Search worked; extract the requested result_attribute. * Search worked; extract the requested result_attribute.
*/ */
if (msg_verbose)
msg_info("%s: Search found %d match(es)", myname, dict_ldap_get_values(dict_ldap, res, result);
ldap_count_entries(dict_ldap->ld, res));
/* /*
* 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)) {
/* #if (LDAP_API_VERSION >= 2000)
* And each entry could have multiple attributes. ldap_get_option(dict_ldap->ld, LDAP_OPT_ERROR_NUMBER, &rc);
*/ if (rc != LDAP_SUCCESS && rc != LDAP_DECODING_ERROR)
attr_values = ldap_get_values(dict_ldap->ld, entry, msg_warn("%s: Had some trouble with entries returned by search: %s", myname, ldap_err2string(rc));
dict_ldap->result_attribute); #else
if (attr_values == NULL) { if (dict_ldap->ld->ld_errno != LDAP_SUCCESS &&
msg_warn("%s: Entry doesn't have any values for %s", dict_ldap->ld->ld_errno != LDAP_DECODING_ERROR)
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)
msg_warn msg_warn
("%s: Had some trouble with entries returned by search: %s", ("%s: Had some trouble with entries returned by search: %s",
myname, ldap_err2string(dict_ldap->ld->ld_errno)); myname, ldap_err2string(dict_ldap->ld->ld_errno));
#endif
if (msg_verbose) if (msg_verbose)
msg_info("%s: Search returned %s", myname, msg_info("%s: Search returned %s", myname,
VSTRING_LEN(result) > VSTRING_LEN(result) >
@@ -454,7 +554,11 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
if (filter_buf != 0) if (filter_buf != 0)
vstring_free(filter_buf); 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 */ /* 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->ldapsource);
myfree(dict_ldap->server_host); myfree(dict_ldap->server_host);
myfree(dict_ldap->search_base); myfree(dict_ldap->search_base);
match_list_free(dict_ldap->domain);
myfree(dict_ldap->query_filter); 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_dn);
myfree(dict_ldap->bind_pw); myfree(dict_ldap->bind_pw);
myfree((char *) dict_ldap); 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"; char *myname = "dict_ldap_open";
DICT_LDAP *dict_ldap; DICT_LDAP *dict_ldap;
VSTRING *config_param; VSTRING *config_param;
int rc = 0; char *domainlist;
char *scope; char *scope;
char *attr;
dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap)); dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap));
dict_ldap->dict.lookup = dict_ldap_lookup; 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), msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->search_base); 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 * 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); dict_ldap->query_filter);
vstring_sprintf(config_param, "%s_result_attribute", ldapsource); vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
dict_ldap->result_attribute = attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
mystrdup((char *) get_mail_conf_str(vstring_str(config_param), "maildrop", 0, 0));
"maildrop", 0, 0));
if (msg_verbose) if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
dict_ldap->result_attribute); 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 * 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), dict_ldap->cache_expiry = get_mail_conf_int(vstring_str(config_param),
30, 0, 0); 30, 0, 0);
if (msg_verbose) 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); 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), dict_ldap->cache_size = get_mail_conf_int(vstring_str(config_param),
32768, 0, 0); 32768, 0, 0);
if (msg_verbose) 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); dict_ldap->cache_size);
/* /*
@@ -698,3 +828,4 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
} }
#endif #endif

View File

@@ -181,7 +181,7 @@ typedef struct {
static DICT_OPEN_INFO dict_open_info[] = { static DICT_OPEN_INFO dict_open_info[] = {
"environ", dict_env_open, "environ", dict_env_open,
"unix", dict_unix_open, "unix", dict_unix_open,
#if 1 #if 0
"tcp", dict_tcp_open, "tcp", dict_tcp_open,
#endif #endif
#ifdef HAS_DBM #ifdef HAS_DBM