2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

snapshot-20000505

This commit is contained in:
Wietse Venema 2000-05-05 00:00:00 +00:00
parent 2e7745be77
commit acf4faee92
31 changed files with 1122 additions and 838 deletions

View File

@ -3879,3 +3879,9 @@ Apologies for any names omitted.
Cleaned up the smtp_stream module further and got rid of
the global state that limited the use of this module to
one stream per process. Files: global/smtp_stream.[hc].
20000505
Bugfix: flush output in-between tarpit delays, in case the
client causes many, many, errors. Found by Lamont Jones,
HP. File: smtpd/smtpd_chat.c.

View File

@ -2,9 +2,9 @@ SHELL = /bin/sh
WARN = -Wmissing-prototypes
OPTS = "CC=$(CC)"
DIRS = util global dns master postfix smtpstone sendmail error \
pickup cleanup smtpd local trivial-rewrite qmgr smtp bounce pipe \
pickup cleanup smtpd local lmtp trivial-rewrite qmgr smtp bounce pipe \
showq postalias postcat postconf postdrop postkick postlock postlog \
postmap postsuper # base64 spawn proto man html
postmap postsuper spawn # base64 proto man html
default: update

View File

@ -70,6 +70,7 @@ smtp unix - - n - - smtp
showq unix n - n - - showq
error unix - - n - - error
local unix - n n - - local
lmtp unix - - n - - lmtp server=localhost
cyrus unix - n n - - pipe
flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
uucp unix - n n - - pipe

View File

@ -670,6 +670,60 @@ extern char *var_smtp_sasl_opts;
#define PERMIT_SASL_AUTH "permit_sasl_authenticated"
/*
* LMTP client. Timeouts inspired by RFC 1123. The LMTP recipient limit
* determines how many recipient addresses the LMTP client sends along with
* each message. Unfortunately, some mailers misbehave and disconnect (smap)
* when given more recipients than they are willing to handle.
*/
#define VAR_LMTP_TCP_PORT "lmtp_tcp_port"
#define DEF_LMTP_TCP_PORT 24
extern int var_lmtp_tcp_port;
#define VAR_LMTP_CACHE_CONN "lmtp_cache_connection"
#define DEF_LMTP_CACHE_CONN 1
extern bool var_lmtp_cache_conn;
#define VAR_LMTP_SKIP_QUIT_RESP "lmtp_skip_quit_response"
#define DEF_LMTP_SKIP_QUIT_RESP 0
extern bool var_lmtp_skip_quit_resp;
#define VAR_LMTP_CONN_TMOUT "lmtp_connect_timeout"
#define DEF_LMTP_CONN_TMOUT 0
extern int var_lmtp_conn_tmout;
#define VAR_LMTP_RSET_TMOUT "lmtp_rset_timeout"
#define DEF_LMTP_RSET_TMOUT 300
extern int var_lmtp_rset_tmout;
#define VAR_LMTP_LHLO_TMOUT "lmtp_lhlo_timeout"
#define DEF_LMTP_LHLO_TMOUT 300
extern int var_lmtp_lhlo_tmout;
#define VAR_LMTP_MAIL_TMOUT "lmtp_mail_timeout"
#define DEF_LMTP_MAIL_TMOUT 300
extern int var_lmtp_mail_tmout;
#define VAR_LMTP_RCPT_TMOUT "lmtp_rcpt_timeout"
#define DEF_LMTP_RCPT_TMOUT 300
extern int var_lmtp_rcpt_tmout;
#define VAR_LMTP_DATA0_TMOUT "lmtp_data_init_timeout"
#define DEF_LMTP_DATA0_TMOUT 120
extern int var_lmtp_data0_tmout;
#define VAR_LMTP_DATA1_TMOUT "lmtp_data_xfer_timeout"
#define DEF_LMTP_DATA1_TMOUT 180
extern int var_lmtp_data1_tmout;
#define VAR_LMTP_DATA2_TMOUT "lmtp_data_done_timeout"
#define DEF_LMTP_DATA2_TMOUT 600
extern int var_lmtp_data2_tmout;
#define VAR_LMTP_QUIT_TMOUT "lmtp_quit_timeout"
#define DEF_LMTP_QUIT_TMOUT 300
extern int var_lmtp_quit_tmout;
/*
* Cleanup service. Header info that exceeds $header_size_limit bytes forces
* the start of the message body.

View File

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

View File

@ -3,8 +3,8 @@ SHELL = /bin/sh
# For now, just hard-coded rules for daemons, commands, config files.
DAEMONS = bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
master.8.html pickup.8.html pipe.8.html qmgr.8.html showq.8.html \
smtp.8.html smtpd.8.html trivial-rewrite.8.html
lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html
COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
postlog.1.html postdrop.1.html postmap.1.html sendmail.1.html \
@ -38,6 +38,9 @@ error.8.html: ../error/error.c
cleanup.8.html: ../cleanup/cleanup.c
srctoman $? | nroff -man | man2html | postlink >$@
lmtp.8.html: ../lmtp/lmtp.c
srctoman $? | nroff -man | man2html | postlink >$@
local.8.html: ../local/local.c
srctoman $? | nroff -man | man2html | postlink >$@

View File

@ -39,11 +39,11 @@ click on the icon in the upper left-hand corner of this page.
<li>The <a href="qmgr.8.html">queue manager</a> is the heart of
the Postfix mail system. It contacts the <a href="local.8.html">local</a>,
<a href="smtp.8.html">smtp</a>, or <a href="pipe.8.html">pipe</a>
delivery agents, and sends a delivery request with queue file
pathname information, the message sender address, the host to
deliver to if the destination is remote, and one or more message
recipient addresses.
<a href="smtp.8.html">smtp</a>, <a href="lmtp.8.html">lmtp</a>, or
<a href="pipe.8.html">pipe</a> delivery agents, and sends a delivery
request with queue file pathname information, the message sender
address, the host to deliver to if the destination is remote, and
one or more message recipient addresses.
<p>

332
postfix/html/lmtp.8.html Normal file
View File

@ -0,0 +1,332 @@
<html> <head> </head> <body> <pre>
LMTP(8) LMTP(8)
<b>NAME</b>
lmtp - Postfix local delivery via LMTP
<b>SYNOPSIS</b>
<b>lmtp</b> [generic Postfix daemon options] [server attributes...]
<b>DESCRIPTION</b>
The LMTP client processes message delivery requests from
the queue manager. Each request specifies a queue file, a
sender address, a domain or host to deliver to, and recip-
ient information. This program expects to be run from the
<a href="master.8.html"><b>master</b>(8)</a> process manager.
The LMTP client updates the queue file and marks recipi-
ents 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 <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.
<b>SERVER</b> <b>ATTRIBUTE</b> <b>SYNTAX</b>
The server attributes are given in the <b>master.cf</b> file at
the end of a service definition. The syntax is as fol-
lows:
<b>server=</b><i>host</i>
<b>server=</b><i>host</i><b>:</b><i>port</i>
<b>server=[</b><i>ipaddr</i><b>]</b>
<b>server=[</b><i>ipaddr</i><b>]:</b><i>port</i>
Connect to the specified host or IP address and TCP
port (default: the <b>lmtp</b> port as specified in the
<b>services</b> database).
<b>SECURITY</b>
The LMTP client is moderately security-sensitive. It talks
to LMTP servers and to DNS servers on the network. The
LMTP client can be run chrooted at fixed low privilege.
<b>STANDARDS</b>
<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)
<b>DIAGNOSTICS</b>
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,
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
details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>Miscellaneous</b>
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
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
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
<b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
Recipient of protocol/policy/resource/software
error notices.
<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
LMTP sessions with protocol errors.
<b>lmtp</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
QUIT.
<b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>
The TCP port to be used when connecting to a LMTP
server. Used as backup if the <b>lmtp</b> service is not
found in <b>services</b>(4).
<b>Resource</b> <b>controls</b>
<b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
Should we cache the connection to the LMTP server?
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:
<b>o</b> The LMTP client idle time limit is reached.
This limit is specified with the Postfix
<b>max</b><i>_</i><b>idle</b> configuration parameter.
<b>o</b> A delivery request specifies a different
destination than the one currently cached.
<b>o</b> The per-process limit on the number of
delivery requests is reached. This limit is
specified with the Postfix <b>max</b><i>_</i><b>use</b> configu-
ration parameter.
<b>o</b> Upon the onset of another delivery request,
the LMTP server associated with the current
session does not respond to the <b>RSET</b> com-
mand.
<i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
Limit the number of parallel deliveries to the same
destination via this mail delivery transport.
<i>transport</i> is the name of the service as specified
in the <b>master.cf</b> file. 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.
<i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
Limit the number of recipients per message delivery
via this mail delivery transport. <i>transport</i> is the
name of the service as specified in the <b>master.cf</b>
file. 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.
This parameter becomes significant if the LMTP
client is used for local delivery. Some LMTP
servers can optimize delivery of the same message
to multiple recipients. The default limit for local
mail delivery is 1.
Setting this parameter to 0 will lead to an
unbounded number of recipients per delivery. How-
ever, this could be risky since it may make the
machine vulnerable to running out of resources if
messages are encountered with an inordinate number
of recipients. Exercise care when setting this
parameter.
<b>Timeout</b> <b>controls</b>
<b>lmtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
Timeout in seconds for opening a connection to the
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.
<b>lmtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b>
Timeout in seconds for sending the <b>MAIL</b> <b>FROM</b> com-
mand, and for receiving the server response.
<b>lmtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b>
Timeout in seconds for sending the <b>RCPT</b> <b>TO</b> command,
and for receiving the server response.
<b>lmtp</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,
and for receiving the server response.
<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.
<b>lmtp</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
be delivered multiple times.
<b>lmtp</b><i>_</i><b>rset</b><i>_</i><b>timeout</b>
Timeout in seconds for sending the <b>RSET</b> command,
and for receiving the server response.
<b>lmtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b>
Timeout in seconds for sending the <b>QUIT</b> command,
and for receiving the server response.
<b>SEE</b> <b>ALSO</b>
<a href="bounce.8.html">bounce(8)</a> non-delivery status reports
<a href="local.8.html">local(8)</a> local mail delivery
<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
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
P.O. Box 704
Yorktown Heights, NY 10598, USA
Alterations for LMTP by:
Philip A. Prindeville
4
LMTP(8) LMTP(8)
Mirapoint, Inc.
USA.
Additional work on LMTP by:
Amos Gouaux
University of Texas at Dallas
P.O. Box 830688, MC34
Richardson, TX 75083, USA
5
</pre> </body> </html>

View File

@ -147,11 +147,12 @@ SMTP(8) SMTP(8)
<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).
(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 <i>name</i>:<i>password</i> entries.
No entry for a host means no attempt to authenti-
Lookup tables with per-host <i>name</i>:<i>password</i> entries.
No entry for a host means no attempt to authenti-
cate.
<b>smtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
@ -175,25 +176,24 @@ 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
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.
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.
3
@ -204,19 +204,19 @@ SMTP(8) SMTP(8)
<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>
@ -224,7 +224,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>
@ -233,11 +233,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>
@ -247,7 +247,7 @@ SMTP(8) SMTP(8)
syslogd(8) system logging
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@ -59,3 +59,156 @@ depend: $(MAKES)
@make -f Makefile.in Makefile
# do not edit below this line - it is generated by 'make depend'
lmtp.o: lmtp.c
lmtp.o: ../include/sys_defs.h
lmtp.o: ../include/dict.h
lmtp.o: ../include/vstream.h
lmtp.o: ../include/vbuf.h
lmtp.o: ../include/binattr.h
lmtp.o: ../include/argv.h
lmtp.o: ../include/msg.h
lmtp.o: ../include/mymalloc.h
lmtp.o: ../include/name_mask.h
lmtp.o: ../include/split_at.h
lmtp.o: ../include/deliver_request.h
lmtp.o: ../include/vstring.h
lmtp.o: ../include/recipient_list.h
lmtp.o: ../include/mail_queue.h
lmtp.o: ../include/mail_params.h
lmtp.o: ../include/mail_conf.h
lmtp.o: ../include/debug_peer.h
lmtp.o: ../include/mail_error.h
lmtp.o: ../include/mail_server.h
lmtp.o: lmtp.h
lmtp_addr.o: lmtp_addr.c
lmtp_addr.o: ../include/sys_defs.h
lmtp_addr.o: ../include/msg.h
lmtp_addr.o: ../include/vstring.h
lmtp_addr.o: ../include/vbuf.h
lmtp_addr.o: ../include/mymalloc.h
lmtp_addr.o: ../include/inet_addr_list.h
lmtp_addr.o: ../include/stringops.h
lmtp_addr.o: ../include/mail_params.h
lmtp_addr.o: ../include/own_inet_addr.h
lmtp_addr.o: ../include/dns.h
lmtp_addr.o: lmtp.h
lmtp_addr.o: ../include/vstream.h
lmtp_addr.o: ../include/binattr.h
lmtp_addr.o: ../include/argv.h
lmtp_addr.o: ../include/deliver_request.h
lmtp_addr.o: ../include/recipient_list.h
lmtp_addr.o: lmtp_addr.h
lmtp_chat.o: lmtp_chat.c
lmtp_chat.o: ../include/sys_defs.h
lmtp_chat.o: ../include/msg.h
lmtp_chat.o: ../include/vstring.h
lmtp_chat.o: ../include/vbuf.h
lmtp_chat.o: ../include/vstream.h
lmtp_chat.o: ../include/binattr.h
lmtp_chat.o: ../include/argv.h
lmtp_chat.o: ../include/stringops.h
lmtp_chat.o: ../include/line_wrap.h
lmtp_chat.o: ../include/mymalloc.h
lmtp_chat.o: ../include/recipient_list.h
lmtp_chat.o: ../include/deliver_request.h
lmtp_chat.o: ../include/smtp_stream.h
lmtp_chat.o: ../include/mail_params.h
lmtp_chat.o: ../include/mail_addr.h
lmtp_chat.o: ../include/post_mail.h
lmtp_chat.o: ../include/cleanup_user.h
lmtp_chat.o: lmtp.h
lmtp_connect.o: lmtp_connect.c
lmtp_connect.o: ../include/sys_defs.h
lmtp_connect.o: ../include/msg.h
lmtp_connect.o: ../include/vstream.h
lmtp_connect.o: ../include/vbuf.h
lmtp_connect.o: ../include/binattr.h
lmtp_connect.o: ../include/vstring.h
lmtp_connect.o: ../include/split_at.h
lmtp_connect.o: ../include/mymalloc.h
lmtp_connect.o: ../include/iostuff.h
lmtp_connect.o: ../include/timed_connect.h
lmtp_connect.o: ../include/stringops.h
lmtp_connect.o: ../include/mail_params.h
lmtp_connect.o: ../include/mail_proto.h
lmtp_connect.o: ../include/dns.h
lmtp_connect.o: lmtp.h
lmtp_connect.o: ../include/argv.h
lmtp_connect.o: ../include/deliver_request.h
lmtp_connect.o: ../include/recipient_list.h
lmtp_connect.o: lmtp_addr.h
lmtp_proto.o: lmtp_proto.c
lmtp_proto.o: ../include/sys_defs.h
lmtp_proto.o: ../include/msg.h
lmtp_proto.o: ../include/vstring.h
lmtp_proto.o: ../include/vbuf.h
lmtp_proto.o: ../include/vstream.h
lmtp_proto.o: ../include/binattr.h
lmtp_proto.o: ../include/vstring_vstream.h
lmtp_proto.o: ../include/stringops.h
lmtp_proto.o: ../include/mymalloc.h
lmtp_proto.o: ../include/mail_params.h
lmtp_proto.o: ../include/smtp_stream.h
lmtp_proto.o: ../include/mail_queue.h
lmtp_proto.o: ../include/recipient_list.h
lmtp_proto.o: ../include/deliver_request.h
lmtp_proto.o: ../include/deliver_completed.h
lmtp_proto.o: ../include/defer.h
lmtp_proto.o: ../include/bounce.h
lmtp_proto.o: ../include/sent.h
lmtp_proto.o: ../include/record.h
lmtp_proto.o: ../include/rec_type.h
lmtp_proto.o: ../include/off_cvt.h
lmtp_proto.o: ../include/mark_corrupt.h
lmtp_proto.o: lmtp.h
lmtp_proto.o: ../include/argv.h
lmtp_proto.o: quote_821_local.h
lmtp_session.o: lmtp_session.c
lmtp_session.o: ../include/sys_defs.h
lmtp_session.o: ../include/mymalloc.h
lmtp_session.o: ../include/vstream.h
lmtp_session.o: ../include/vbuf.h
lmtp_session.o: ../include/binattr.h
lmtp_session.o: ../include/debug_peer.h
lmtp_session.o: lmtp.h
lmtp_session.o: ../include/vstring.h
lmtp_session.o: ../include/argv.h
lmtp_session.o: ../include/deliver_request.h
lmtp_session.o: ../include/recipient_list.h
lmtp_state.o: lmtp_state.c
lmtp_state.o: ../include/sys_defs.h
lmtp_state.o: ../include/mymalloc.h
lmtp_state.o: ../include/vstring.h
lmtp_state.o: ../include/vbuf.h
lmtp_state.o: ../include/vstream.h
lmtp_state.o: ../include/binattr.h
lmtp_state.o: ../include/config.h
lmtp_state.o: ../include/mail_conf.h
lmtp_state.o: lmtp.h
lmtp_state.o: ../include/argv.h
lmtp_state.o: ../include/deliver_request.h
lmtp_state.o: ../include/recipient_list.h
lmtp_trouble.o: lmtp_trouble.c
lmtp_trouble.o: ../include/sys_defs.h
lmtp_trouble.o: ../include/msg.h
lmtp_trouble.o: ../include/vstring.h
lmtp_trouble.o: ../include/vbuf.h
lmtp_trouble.o: ../include/stringops.h
lmtp_trouble.o: ../include/mymalloc.h
lmtp_trouble.o: ../include/smtp_stream.h
lmtp_trouble.o: ../include/vstream.h
lmtp_trouble.o: ../include/binattr.h
lmtp_trouble.o: ../include/deliver_request.h
lmtp_trouble.o: ../include/recipient_list.h
lmtp_trouble.o: ../include/deliver_completed.h
lmtp_trouble.o: ../include/bounce.h
lmtp_trouble.o: ../include/defer.h
lmtp_trouble.o: ../include/mail_error.h
lmtp_trouble.o: ../include/name_mask.h
lmtp_trouble.o: lmtp.h
lmtp_trouble.o: ../include/argv.h
quote_821_local.o: quote_821_local.c
quote_821_local.o: ../include/sys_defs.h
quote_821_local.o: ../include/vstring.h
quote_821_local.o: ../include/vbuf.h
quote_821_local.o: quote_821_local.h

View File

@ -1,5 +1,4 @@
sed '
s/LMTP/SMTP/g
s/lmtp/smtp/g
s/host/namaddr/g
s/SMTP/LMTP/g
s/smtp/lmtp/g
' $*

View File

@ -1,65 +0,0 @@
*** ../../orig/global/mail_params.h Thu Jan 27 20:05:29 2000
--- global/mail_params.h Wed Feb 23 01:26:01 2000
***************
*** 624,629 ****
--- 624,683 ----
extern int var_smtpd_err_sleep;
/*
+ * LMTP client. Timeouts inspired by RFC 1123. The LMTP recipient limit
+ * determines how many recipient addresses the LMTP client sends along with
+ * each message. Unfortunately, some mailers misbehave and disconnect (smap)
+ * when given more recipients than they are willing to handle.
+ */
+ #define VAR_LMTP_TCP_PORT "lmtp_tcp_port"
+ #define DEF_LMTP_TCP_PORT 24
+ extern int var_lmtp_tcp_port;
+
+ #define VAR_LMTP_CACHE_CONN "lmtp_cache_connection"
+ #define DEF_LMTP_CACHE_CONN 1
+ extern bool var_lmtp_cache_conn;
+
+ #define VAR_LMTP_SKIP_QUIT_RESP "lmtp_skip_quit_response"
+ #define DEF_LMTP_SKIP_QUIT_RESP 0
+ extern bool var_lmtp_skip_quit_resp;
+
+ #define VAR_LMTP_CONN_TMOUT "lmtp_connect_timeout"
+ #define DEF_LMTP_CONN_TMOUT 0
+ extern int var_lmtp_conn_tmout;
+
+ #define VAR_LMTP_RSET_TMOUT "lmtp_rset_timeout"
+ #define DEF_LMTP_RSET_TMOUT 300
+ extern int var_lmtp_rset_tmout;
+
+ #define VAR_LMTP_LHLO_TMOUT "lmtp_lhlo_timeout"
+ #define DEF_LMTP_LHLO_TMOUT 300
+ extern int var_lmtp_lhlo_tmout;
+
+ #define VAR_LMTP_MAIL_TMOUT "lmtp_mail_timeout"
+ #define DEF_LMTP_MAIL_TMOUT 300
+ extern int var_lmtp_mail_tmout;
+
+ #define VAR_LMTP_RCPT_TMOUT "lmtp_rcpt_timeout"
+ #define DEF_LMTP_RCPT_TMOUT 300
+ extern int var_lmtp_rcpt_tmout;
+
+ #define VAR_LMTP_DATA0_TMOUT "lmtp_data_init_timeout"
+ #define DEF_LMTP_DATA0_TMOUT 120
+ extern int var_lmtp_data0_tmout;
+
+ #define VAR_LMTP_DATA1_TMOUT "lmtp_data_xfer_timeout"
+ #define DEF_LMTP_DATA1_TMOUT 180
+ extern int var_lmtp_data1_tmout;
+
+ #define VAR_LMTP_DATA2_TMOUT "lmtp_data_done_timeout"
+ #define DEF_LMTP_DATA2_TMOUT 600
+ extern int var_lmtp_data2_tmout;
+
+ #define VAR_LMTP_QUIT_TMOUT "lmtp_quit_timeout"
+ #define DEF_LMTP_QUIT_TMOUT 300
+ extern int var_lmtp_quit_tmout;
+
+ /*
* Cleanup service. Header info that exceeds $header_size_limit bytes forces
* the start of the message body.
*/

View File

@ -17,61 +17,23 @@
/* be tried again at a later time. Delivery problem reports are sent
/* to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
/*
/* There are two basic modes of operation for the LMTP client:
/* .IP \(bu
/* Communication with a local LMTP server via UNIX domain sockets.
/* .IP \(bu
/* Communication with a (possibly remote) LMTP server via
/* Internet sockets.
/* .PP
/* If no server attributes are specified, the LMTP client will contact
/* the destination host derived from the message delivery request using
/* 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.
/*
/* In order to use a local LMTP server, this LMTP server will need to
/* be specified via the server attributes described in the following
/* section. Typically, the LMTP client would also be configured as the
/* \fBlocal\fR delivery agent in the \fBmaster.cf\fR file.
/* (default value of 24) will be used. The LMTP client does not perform
/* MX (mail exchanger) lookups since those are defined only for SMTP.
/* SERVER ATTRIBUTE SYNTAX
/* .ad
/* .fi
/* The server attributes are given in the \fBmaster.cf\fR file at
/* the end of a service definition. The syntax is as follows:
/* .IP "\fBserv\fR=\fItype\fR:\fIserver\fR"
/* The LMTP server to connect to for final delivery. The \fItype\fR
/* portion can be either \fBunix\fR or \fBinet\fR. The \fIserver\fR
/* portion is the path or address of the LMTP server, depending on the
/* value of \fItype\fR, as shown below:
/* .RS
/* .IP "\fBserv=unix:\fR\fIclass\fR\fB/\fR\fIservname\fR"
/* This specifies that the local LMTP server \fIservname\fR should be
/* contacted for final delivery. Both \fIclass\fR (either \fBpublic\fR
/* or \fBprivate\fR) and \fIservname\fR correspond to the LMTP server
/* entry in the \fBmaster.cf\fR file. This LMTP server will likely
/* be defined as a \fBspawn\fR(8) service.
/* .IP "\fBserv=inet:"
/* If nothing follows the \fBinet:\fR type specifier, a connection will
/* be attempted to the destination host indicated in the delivery request.
/* This simplest case is identical to defining the LMTP client without
/* any server attributes at all.
/* .IP "\fBserv=inet:\fR\fIaddress\fR"
/* In this case, an Internet socket will be made to the server
/* specified by \fIaddress\fR. The connection will use a destination
/* port as described in the previous section.
/* .IP "\fBserv=inet:\fR\fIaddress\fR\fB:\fR\fIport\fR"
/* Connect to the LMTP server at \fIaddress\fR, but this time use port
/* \fIport\fR instead of the default \fBlmtp\fR port.
/* .IP "\fBserv=inet:[\fR\fIipaddr\fR\fB]\fR"
/* The LMTP server to contact is specified using an Internet address
/* in the "dot notation". That is, the numeric IP address rather
/* than the DNS name for the server. The default \fBlmtp\fR port
/* is used.
/* .IP "\fBserv=inet:[\fR\fIipaddr\fR\fB]:\fR\fIport\fR"
/* The LMTP server to contact is specified using the numeric IP address,
/* at the port specified.
/* .RE
/* .IP "\fBserver=\fR\fIhost\fR"
/* .IP "\fBserver=\fR\fIhost\fR\fB:\fR\fIport\fR"
/* .IP "\fBserver=[\fR\fIipaddr\fR\fB]\fR"
/* .IP "\fBserver=[\fR\fIipaddr\fR\fB]:\fR\fIport\fR"
/* Connect to the specified host or IP address and TCP port (default: the
/* \fBlmtp\fR port as specified in the \fBservices\fR database).
/* .PP
/* SECURITY
/* .ad
@ -80,10 +42,10 @@
/* servers and to DNS servers on the network. The LMTP client can be
/* run chrooted at fixed low privilege.
/* STANDARDS
/* RFC 2033 (LMTP protocol)
/* RFC 821 (SMTP protocol)
/* RFC 1651 (SMTP service extensions)
/* RFC 1870 (Message Size Declaration)
/* RFC 2033 (LMTP protocol)
/* RFC 2197 (Pipelining)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
@ -131,38 +93,38 @@
/* Cached connections are closed under any of the following conditions:
/* .RS
/* .IP \(bu
/* The idle timeout for the LMTP client is reached. This limit is
/* enforced by \fBmaster\fR(8).
/* The LMTP client idle time limit is reached. This limit is specified
/* with the Postfix \fBmax_idle\fR configuration parameter.
/* .IP \(bu
/* A message request to a different destination than the one currently
/* cached.
/* A delivery request specifies a different destination than the one
/* currently cached.
/* .IP \(bu
/* The maximum number of requests per session is reached. This limit is
/* enforced by \fBmaster\fR(8).
/* The per-process limit on the number of delivery requests is reached.
/* This limit is specified with the Postfix \fBmax_use\fR configuration
/* parameter.
/* .IP \(bu
/* Upon the onset of another delivery request, the LMTP server associated
/* with the current session does not respond to the \fBRSET\fR command.
/* .RE
/* .IP \fBlmtp_destination_concurrency_limit\fR
/* Limit the number of parallel deliveries to the same destination.
/* .IP \fItransport_\fBdestination_concurrency_limit\fR
/* Limit the number of parallel deliveries to the same destination
/* via this mail delivery transport. \fItransport\fR is the name
/* of the service as specified in the \fBmaster.cf\fR file.
/* The default limit is taken from the
/* \fBdefault_destination_concurrency_limit\fR parameter.
/* .IP \fBlmtp_destination_recipient_limit\fR
/* Limit the number of recipients per message delivery.
/* The default limit is taken from the
/* \fBdefault_destination_recipient_limit\fR parameter.
/* .IP \fBlocal_destination_recipient_limit\fR
/* Limit the number of recipients per message delivery.
/* .IP \fItransport_\fBdestination_recipient_limit\fR
/* Limit the number of recipients per message delivery via this mail
/* delivery transport. \fItransport\fR is the name
/* of the service as specified in the \fBmaster.cf\fR file.
/* The default limit is taken from the
/* \fBdefault_destination_recipient_limit\fR parameter.
/*
/* This parameter becomes significant if the LMTP client is used
/* for local delivery. Some LMTP servers can optimize final delivery
/* if multiple recipients are allowed. Therefore, it may be advantageous
/* to set this to some number greater than one, depending on the capabilities
/* of the machine.
/* for local delivery. Some LMTP servers can optimize delivery of
/* the same message to multiple recipients. The default limit for
/* local mail delivery is 1.
/*
/* Setting this parameter to 0 will lead to an unlimited number of
/* Setting this parameter to 0 will lead to an unbounded number of
/* recipients per delivery. However, this could be risky since it may
/* make the machine vulnerable to running out of resources if messages
/* are encountered with an inordinate number of recipients. Exercise
@ -245,6 +207,7 @@
#include <argv.h>
#include <mymalloc.h>
#include <name_mask.h>
#include <split_at.h>
/* Global library. */
@ -295,23 +258,11 @@ char *var_error_rcpt;
int lmtp_errno;
static LMTP_STATE *state = 0;
/* get_service_attr - get command-line attributes */
static LMTP_ATTR *get_service_attr(char **argv)
static void get_service_attr(LMTP_STATE *state, char **argv)
{
char *myname = "get_service_attr";
LMTP_ATTR *attr = (LMTP_ATTR *) mymalloc(sizeof(*attr));
char *type;
char *dest;
char *name;
/*
* Initialize.
*/
attr->type = 0;
attr->class = "";
attr->name = "";
/*
* Iterate over the command-line attribute list.
@ -322,73 +273,37 @@ static LMTP_ATTR *get_service_attr(char **argv)
for ( /* void */ ; *argv != 0; argv++) {
/*
* Are we configured to speak to a particular LMTP server?
* Connect to a fixed LMTP server.
*/
if (strncasecmp("serv=", *argv, sizeof("serv=") - 1) == 0) {
type = *argv + sizeof("serv=") - 1;
if ((dest = split_at(type, ':')) == 0) /* XXX clobbers argv */
msg_fatal("%s: invalid serv= arguments: %s", myname, *argv);
/*
* What kind of socket connection are we to make?
*/
if (strcasecmp("unix", type) == 0) {
attr->type = LMTP_SERV_TYPE_UNIX;
attr->class = dest;
if ((name = split_at(dest, '/')) == 0) /* XXX clobbers argv */
msg_fatal("%s: invalid serv= arguments: %s", myname, *argv);
attr->name = name;
} else if (strcasecmp("inet", type) == 0) {
attr->type = LMTP_SERV_TYPE_INET;
attr->name = dest;
} else
msg_fatal("%s: invalid serv= arguments: %s", myname, *argv);
break;
if (strncasecmp("server=", *argv, sizeof("server=") - 1) == 0) {
state->fixed_dest = *argv + sizeof("server=") - 1;
if (state->fixed_dest[0] == 0)
msg_fatal("invalid destination: %s", *argv);
}
/*
* Bad.
*/
else
msg_fatal("%s: unknown attribute name: %s", myname, *argv);
msg_fatal("unknown attribute name: %s", *argv);
}
/*
* Give the poor tester a clue of what is going on.
*/
if (msg_verbose)
msg_info("%s: type %d, class \"%s\", name \"%s\".", myname,
attr->type, attr->class, attr->name);
return (attr);
}
/* deliver_message - deliver message with extreme prejudice */
static int deliver_message(DELIVER_REQUEST *request, char **argv)
static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
{
char *myname = "deliver_message";
static LMTP_ATTR *attr = 0;
char *destination;
VSTRING *why;
int result;
/*
* Macro for readability. We're going to the same destination if the
* destination was specified on the command line (attr->name is not
* null), or if the destination of the current session is the same as
* request->nexthop.
*/
#define SAME_DESTINATION() \
(*(attr)->name \
|| strcasecmp(state->session->destination, request->nexthop) == 0)
if (msg_verbose)
msg_info("%s: from %s", myname, request->sender);
/*
* Sanity checks.
*/
if (attr == 0)
attr = get_service_attr(argv);
if (request->rcpt_list.len <= 0)
msg_fatal("%s: recipient count: %d", myname, request->rcpt_list.len);
@ -397,14 +312,16 @@ static int deliver_message(DELIVER_REQUEST *request, char **argv)
* we can produce understandable diagnostics when something goes wrong
* many levels below. The alternative would be to make everything global.
*
* Note: `state' is global (to this file) so that we can close a cached
* connection via the MAIL_SERVER_EXIT function (cleanup). The alloc for
* `state' is performed in the MAIL_SERVER_PRE_INIT function (pre_init).
* Note: `state' was made global (to this file) so that we can cache
* connections and so that we can close a cached connection via the
* MAIL_SERVER_EXIT function (cleanup). The alloc for `state' is
* performed in the MAIL_SERVER_PRE_INIT function (pre_init).
*
*/
why = vstring_alloc(100);
state->request = request;
state->src = request->fp;
destination = state->fixed_dest ? state->fixed_dest : request->nexthop;
/*
* See if we can reuse an existing connection.
@ -412,29 +329,29 @@ static int deliver_message(DELIVER_REQUEST *request, char **argv)
if (state->session != 0) {
/*
* Session already exists from a previous delivery. If we're not
* going to the same destination as before, disconnect and establish
* a connection to the specified destination.
* Disconnect if we're going to a different destination. Discard
* transcript and status information from sending QUIT.
*/
if (!SAME_DESTINATION()) {
if (strcasecmp(state->session->dest, destination) != 0) {
lmtp_quit(state);
lmtp_chat_reset(state);
lmtp_session_reset(state);
debug_peer_restore();
state->session = lmtp_session_free(state->session);
}
/*
* Probe the session by sending RSET. If the connection is broken,
* clean up our side of the connection.
* Disconnect if RSET can't be sent over an existing connection.
* Discard transcript and status information from sending RSET.
*/
else if (lmtp_rset(state) != 0) {
lmtp_chat_reset(state);
lmtp_session_reset(state);
debug_peer_restore();
state->session = lmtp_session_free(state->session);
}
/*
* Ready to go with another load.
* Ready to go with another load. The reuse counter is logged for
* statistical analysis purposes. Given the Postfix architecture,
* connection cacheing makes sense only for dedicated transports.
* Logging the reuse count can help to convince people.
*/
else {
++state->reuse;
@ -445,56 +362,51 @@ static int deliver_message(DELIVER_REQUEST *request, char **argv)
}
/*
* If no LMTP session exists, establish one.
* See if we need to establish an LMTP connection.
*/
if (state->session == 0) {
/*
* Bounce or defer the recipients if no connection can be made.
*/
state->session = lmtp_connect(attr, request, why);
if (state->session == 0) {
if ((state->session = lmtp_connect(destination, why)) == 0) {
lmtp_site_fail(state, lmtp_errno == LMTP_RETRY ? 450 : 550,
"%s", vstring_str(why));
}
/*
* Further check connection by sending the LHLO greeting. If we
* cannot talk LMTP to this destination give up, at least for now.
* Bounce or defer the recipients if the LMTP handshake fails.
*/
else {
debug_peer_check(state->session->host, state->session->addr);
if (lmtp_lhlo(state) != 0) {
lmtp_session_reset(state);
debug_peer_restore();
}
else if (lmtp_lhlo(state) != 0) {
state->session = lmtp_session_free(state->session);
}
/*
* Congratulations. We just established a new LMTP connection.
*/
else
state->reuse = 0;
}
/*
* If a session exists, deliver this message to all requested recipients.
*
*/
if (state->session != 0)
lmtp_xfer(state);
/*
* At the end, notify the postmaster of any protocol errors.
* Optionally, notify the postmaster of problems.
*/
if (state->history != 0
&& (state->error_mask
& name_mask(mail_error_masks, var_notify_classes)))
&& (state->error_mask & name_mask(mail_error_masks, var_notify_classes)))
lmtp_chat_notify(state);
/*
* Disconnect if we're not cacheing connections.
* Disconnect if we're not cacheing connections. The pipelined protocol
* state machine knows to send QUIT as appropriate.
*/
if (!var_lmtp_cache_conn && state->session != 0) {
lmtp_quit(state);
lmtp_session_reset(state);
debug_peer_restore();
}
if (!var_lmtp_cache_conn && state->session != 0)
state->session = lmtp_session_free(state->session);
/*
* Clean up.
@ -527,33 +439,36 @@ static void lmtp_service(VSTREAM *client_stream, char *unused_service, char **ar
}
}
/* post_init - post-jail initialization */
static void post_init(char *unused_name, char **argv)
{
state = lmtp_state_alloc();
get_service_attr(state, argv);
}
/* pre_init - pre-jail initialization */
static void pre_init(char *unused_name, char **unused_argv)
{
debug_peer_init();
state = lmtp_state_alloc();
}
/* cleanup - close any open connections, etc. */
static void cleanup()
static void cleanup(void)
{
if (state == 0)
return;
if (state->session != 0) {
lmtp_quit(state);
lmtp_chat_reset(state);
lmtp_session_free(state->session);
debug_peer_restore();
state->session = lmtp_session_free(state->session);
if (msg_verbose)
msg_info("cleanup: just closed down session");
}
lmtp_state_free(state);
}
/* pre_accept - see if tables have changed
/* pre_accept - see if tables have changed */
static void pre_accept(char *unused_name, char **unused_argv)
{
@ -564,10 +479,7 @@ static void pre_accept(char *unused_name, char **unused_argv)
}
}
/*
main - pass control to the single-threaded skeleton
*/
/* main - pass control to the single-threaded skeleton */
int main(int argc, char **argv)
{
@ -602,6 +514,7 @@ int main(int argc, char **argv)
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_PRE_INIT, pre_init,
MAIL_SERVER_POST_INIT, post_init,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
MAIL_SERVER_EXIT, cleanup,
0);

View File

@ -38,6 +38,7 @@ typedef struct LMTP_STATE {
int sndbufsize; /* total window size */
int sndbuffree; /* remaining window */
int reuse; /* connection being reused */
char *fixed_dest; /* fixed remote server */
} LMTP_STATE;
#define LMTP_FEATURE_ESMTP (1<<0)
@ -50,42 +51,24 @@ typedef struct LMTP_STATE {
*/
extern int lmtp_errno; /* XXX can we get rid of this? */
/*
* Structure for connection to LMTP server.
*/
typedef struct LMTP_ATTR {
int type; /* UNIX-domain, INET, etc. */
char *class; /* class ("public" or "private") */
char *name; /* service endpoint name */
} LMTP_ATTR;
/*
* Service types.
*/
#define LMTP_SERV_TYPE_UNIX 1 /* AF_UNIX domain socket */
#define LMTP_SERV_TYPE_INET 2 /* AF_INET domain socket */
/*
* lmtp_session.c
*/
typedef struct LMTP_SESSION {
VSTREAM *stream; /* network connection */
char *host; /* mail exchanger */
char *addr; /* mail exchanger */
char *destination; /* domain originally sent to */
int type; /* type of connection */
char *host; /* mail exchanger, name */
char *addr; /* mail exchanger, address */
char *namaddr; /* mail exchanger, for logging */
char *dest; /* remote endpoint name */
} LMTP_SESSION;
extern LMTP_SESSION *lmtp_session_alloc(VSTREAM *, char *, char *);
extern void lmtp_session_free(LMTP_SESSION *);
extern void lmtp_session_reset(LMTP_STATE *);
extern LMTP_SESSION *lmtp_session_alloc(VSTREAM *, const char *, const char *, const char *);
extern LMTP_SESSION *lmtp_session_free(LMTP_SESSION *);
/*
* lmtp_connect.c
*/
extern LMTP_SESSION *lmtp_connect(LMTP_ATTR *, DELIVER_REQUEST *request, VSTRING *);
extern LMTP_SESSION *lmtp_connect_host(char *, unsigned, VSTRING *);
extern LMTP_SESSION *lmtp_connect_local(const char *, const char *, VSTRING *);
extern LMTP_SESSION *lmtp_connect(const char *, VSTRING *);
/*
* lmtp_proto.c

View File

@ -18,8 +18,8 @@
/* host. The host can be specified as a numerical Internet network
/* address, or as a symbolic host name.
/*
/* Fortunately, we don't have to worry about MX records because
/* those are for SMTP servers, not LMTP servers.
/* Fortunately, we don't have to worry about MX records because
/* those are for SMTP servers, not LMTP servers.
/*
/* Results from lmtp_host_addr() are destroyed by dns_rr_free(),
/* including null lists.
@ -43,16 +43,16 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/*--*/
/* System library. */
@ -199,4 +199,3 @@ DNS_RR *lmtp_host_addr(char *host, VSTRING *why)
lmtp_print_addr(host, addr_list);
return (addr_list);
}

View File

@ -46,6 +46,8 @@
/* lmtp_chat_reset() resets the transaction log. This is
/* typically done at the beginning or end of an LMTP session,
/* or within a session to discard non-error information.
/* In addition, lmtp_chat_reset() resets the per-session error
/* status bits and flags.
/* DIAGNOSTICS
/* Fatal errors: memory allocation problem, server response exceeds
/* configurable limit.
@ -63,16 +65,16 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/*--*/
/* System library. */
@ -118,7 +120,6 @@ void lmtp_chat_reset(LMTP_STATE *state)
argv_free(state->history);
state->history = 0;
}
/* What's status without history? */
state->status = 0;
state->error_mask = 0;
@ -157,7 +158,7 @@ void lmtp_chat_cmd(LMTP_STATE *state, char *fmt,...)
* program is trying to do.
*/
if (msg_verbose)
msg_info("> %s: %s", session->host, STR(state->buffer));
msg_info("> %s: %s", session->namaddr, STR(state->buffer));
/*
* Send the command to the LMTP server.
@ -192,9 +193,9 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
cp = printable(STR(state->buffer), '?');
if (last_char != '\n')
msg_warn("%s: response longer than %d: %.30s...",
session->host, var_line_limit, cp);
session->namaddr, var_line_limit, cp);
if (msg_verbose)
msg_info("< %s: %s", session->host, cp);
msg_info("< %s: %s", session->namaddr, cp);
while (ISDIGIT(*cp))
cp++;
rdata.code = (cp - STR(state->buffer) == 3 ?
@ -261,7 +262,7 @@ void lmtp_chat_notify(LMTP_STATE *state)
#define INDENT 4
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
var_error_rcpt,
NULL_CLEANUP_FLAGS, "NOTICE");
if (notice == 0) {
msg_warn("postmaster notify: %m");
@ -271,9 +272,9 @@ void lmtp_chat_notify(LMTP_STATE *state)
mail_addr_mail_daemon());
post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
post_mail_fprintf(notice, "Subject: %s LMTP client: errors from %s",
var_mail_name, session->host);
var_mail_name, session->namaddr);
post_mail_fputs(notice, "");
post_mail_fprintf(notice, "Unexpected response from %s.", session->host);
post_mail_fprintf(notice, "Unexpected response from %s.", session->namaddr);
post_mail_fputs(notice, "");
post_mail_fputs(notice, "Transcript of session follows.");
post_mail_fputs(notice, "");

View File

@ -1,6 +1,6 @@
/*++
/* NAME
/* lmtp_connect 3
/* lmtp_connect_inet 3
/* SUMMARY
/* connect to LMTP server
/* SYNOPSIS
@ -19,7 +19,6 @@
/* separated by a colon (":").
/*
/* Numerical address information should always be quoted with `[]'.
/*
/* DIAGNOSTICS
/* This routine either returns an LMTP_SESSION pointer, or
/* returns a null pointer and set the \fIlmtp_errno\fR
@ -43,16 +42,16 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/*--*/
/* System library. */
@ -80,7 +79,6 @@
#include <vstring.h>
#include <split_at.h>
#include <mymalloc.h>
#include <inet_addr_list.h>
#include <iostuff.h>
#include <timed_connect.h>
#include <stringops.h>
@ -88,7 +86,7 @@
/* Global library. */
#include <mail_params.h>
#include <own_inet_addr.h>
#include <mail_proto.h>
/* DNS library. */
@ -102,17 +100,15 @@
/* lmtp_connect_addr - connect to explicit address */
static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
VSTRING *why)
const char *destination, VSTRING *why)
{
char *myname = "lmtp_connect_addr";
struct sockaddr_in sin;
int sock;
INET_ADDR_LIST *addr_list;
int conn_stat;
int saved_errno;
VSTREAM *stream;
int ch;
unsigned long inaddr;
/*
* Sanity checks.
@ -132,21 +128,6 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
msg_fatal("%s: socket: %m", myname);
/* do we still need this if? */
addr_list = own_inet_addr_list();
if (addr_list->used == 1) {
sin.sin_port = 0;
memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
inaddr = ntohl(sin.sin_addr.s_addr);
if (!IN_CLASSA(inaddr)
|| !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
if (msg_verbose)
msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
}
}
/*
* Connect to the LMTP server.
*/
@ -196,24 +177,26 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
vstream_fclose(stream);
return (0);
}
vstream_ungetc(stream, ch);
/*
* Skip this host if it sends a 4xx greeting.
* Skip this host if it sends a 4xx or 5xx greeting.
*/
if (ch == '4') {
if (ch == '4' || ch == '5') {
vstring_sprintf(why, "connect to %s[%s]: server refused mail service",
addr->name, inet_ntoa(sin.sin_addr));
lmtp_errno = LMTP_RETRY;
vstream_fclose(stream);
return (0);
}
vstream_ungetc(stream, ch);
return (lmtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr)));
return (lmtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr),
destination));
}
/* lmtp_connect_host - direct connection to host */
LMTP_SESSION *lmtp_connect_host(char *host, unsigned port, VSTRING *why)
static LMTP_SESSION *lmtp_connect_host(char *host, unsigned port,
const char *destination, VSTRING *why)
{
LMTP_SESSION *session = 0;
DNS_RR *addr_list;
@ -226,7 +209,7 @@ LMTP_SESSION *lmtp_connect_host(char *host, unsigned port, VSTRING *why)
*/
addr_list = lmtp_host_addr(host, why);
for (addr = addr_list; addr; addr = addr->next) {
if ((session = lmtp_connect_addr(addr, port, why)) != 0) {
if ((session = lmtp_connect_addr(addr, port, destination, why)) != 0) {
break;
}
}
@ -236,8 +219,8 @@ LMTP_SESSION *lmtp_connect_host(char *host, unsigned port, VSTRING *why)
/* lmtp_parse_destination - parse destination */
static char *lmtp_parse_destination(char *destination, char *def_service,
char **hostp, unsigned *portp)
static char *lmtp_parse_destination(const char *destination, char *def_service,
char **hostp, unsigned *portp)
{
char *myname = "lmtp_parse_destination";
char *buf = mystrdup(destination);
@ -272,80 +255,24 @@ static char *lmtp_parse_destination(char *destination, char *def_service,
*hostp = host;
/*
* Convert service to port number, network byte order.
* Convert service to port number, network byte order. Since most folks
* aren't going to have lmtp defined as a service, use a default value
* instead of just blowing up.
*/
if ((port = atoi(service)) != 0) {
if ((port = atoi(service)) != 0)
*portp = htons(port);
} else {
/*
* Since most folks aren't going to have lmtp defined as a service,
* use a default value instead of just blowing up.
*/
if ((sp = getservbyname(service, protocol)) == 0)
*portp = htons(var_lmtp_tcp_port);
else
*portp = sp->s_port;
}
else if ((sp = getservbyname(service, protocol)) != 0)
*portp = sp->s_port;
else
*portp = htons(var_lmtp_tcp_port);
return (buf);
}
/* lmtp_connect_local - local connect to unix domain socket */
LMTP_SESSION *lmtp_connect_local(const char *class, const char *name, VSTRING *why)
{
char *myname = "lmtp_connect_local";
VSTREAM *stream;
int ch;
/*
* Connect to the LMTP server.
*/
if (msg_verbose)
msg_info("%s: trying: %s/%s...", myname, class, name);
if ((stream = mail_connect_wait(class, name)) == 0) {
vstring_sprintf(why, "connect to %s: connection failed.", name);
lmtp_errno = LMTP_RETRY;
return (0);
}
/*
* Skip this process if it takes no action within some time limit.
*/
if (read_wait(vstream_fileno(stream), var_lmtp_lhlo_tmout) < 0) {
vstring_sprintf(why, "connect to %s: read timeout", name);
lmtp_errno = LMTP_RETRY;
vstream_fclose(stream);
return (0);
}
/*
* Skip this process if it disconnects without talking to us.
*/
if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
vstring_sprintf(why, "connect to %s: server dropped connection", name);
lmtp_errno = LMTP_RETRY;
vstream_fclose(stream);
return (0);
}
/*
* Skip this host if it sends a 4xx greeting.
*/
if (ch == '4') {
vstring_sprintf(why, "connect to %s: server refused mail service", name);
lmtp_errno = LMTP_RETRY;
vstream_fclose(stream);
return (0);
}
vstream_ungetc(stream, ch);
return (lmtp_session_alloc(stream, name, ""));
}
/* lmtp_connect - establish LMTP connection */
LMTP_SESSION *lmtp_connect(LMTP_ATTR *attr, DELIVER_REQUEST *request, VSTRING *why)
LMTP_SESSION *lmtp_connect(const char *destination, VSTRING *why)
{
char *myname = "lmtp_connect";
char *myname = "lmtp_connect_inet";
LMTP_SESSION *session;
char *dest_buf;
char *host;
@ -353,43 +280,13 @@ LMTP_SESSION *lmtp_connect(LMTP_ATTR *attr, DELIVER_REQUEST *request, VSTRING *w
char *def_service = "lmtp"; /* XXX configurable? */
/*
* Are we connecting to a local or inet socket?
* Connect to the LMTP server.
*/
if (attr->type == LMTP_SERV_TYPE_UNIX) {
/*
* Connect to local LMTP server.
*/
if (msg_verbose)
msg_info("%s: connecting to %s", myname, attr->name);
session = lmtp_connect_local(attr->class, attr->name, why);
if (session != 0) {
session->destination = mystrdup(attr->name);
session->type = attr->type;
}
} else {
/*
* Connect to LMTP server via inet socket, but where?
*/
if (!*(attr)->name) {
if (msg_verbose)
msg_info("%s: attr->name not set; using request->nexthop", myname);
attr->name = request->nexthop;
}
dest_buf = lmtp_parse_destination(attr->name, def_service,
&host, &port);
/*
* Now that the inet LMTP server has been determined, connect to it.
*/
if (msg_verbose)
msg_info("%s: connecting to %s port %d", myname, host, ntohs(port));
session = lmtp_connect_host(host, port, why);
if (session != 0) {
session->destination = mystrdup(attr->name);
session->type = attr->type;
}
myfree(dest_buf);
}
dest_buf = lmtp_parse_destination(destination, def_service,
&host, &port);
if (msg_verbose)
msg_info("%s: connecting to %s port %d", myname, host, ntohs(port));
session = lmtp_connect_host(host, port, destination, why);
myfree(dest_buf);
return (session);
}

View File

@ -23,15 +23,16 @@
/* lmtp_lhlo() performs the initial handshake with the LMTP server.
/*
/* lmtp_xfer() sends message envelope information followed by the
/* message data, but does not finish the conversation. These operations
/* are combined in one function, in order to implement LMTP pipelining.
/* message data and sends QUIT when connection cacheing is disabled.
/* These operations are combined in one function, in order to implement
/* LMTP pipelining.
/* Recipients are marked as "done" in the mail queue file when
/* bounced or delivered. The message delivery status is updated
/* accordingly.
/*
/* lmtp_rset() sends an RSET command and waits for the response.
/* lmtp_rset() sends a lone RSET command and waits for the response.
/*
/* lmtp_quit() sends a QUIT command and waits for the response.
/* lmtp_quit() sends a lone QUIT command and waits for the response.
/* DIAGNOSTICS
/* lmtp_lhlo(), lmtp_xfer(), lmtp_rset() and lmtp_quit() return 0 in
/* case of success, -1 in case of failure. For lmtp_xfer(), lmtp_rset()
@ -122,19 +123,18 @@
/*
* Sender and receiver state. A session does not necessarily go through a
* linear progression, but states are guaranteed to not jump backwards.
* Normal sessions go from MAIL->RCPT->DATA->DOT->LAST. The states MAIL,
* RCPT, and DATA may also be followed by ABORT->LAST.
* Normal sessions go from MAIL->RCPT->DATA->DOT->QUIT->LAST. The states
* MAIL, RCPT, and DATA may also be followed by ABORT->QUIT->LAST.
*
* In order to support connection cacheing, no QUIT is send at the end of mail
* delivery. Instead, at the start of the next mail delivery, the client
* sends RSET to find out if the server is still there, and sends QUIT only
* when closing a connection. The RSET and QUIT commands are sent all by
* themselves in non-pipelining mode. The respective state transitions are
* RSET->LAST and QUIT->LAST.
* When connection cacheing is turned on, the transition diagram changes as
* follows. Before sending mail over an existing connection, the client
* sends a lone RSET command to find out if the connection still works. The
* client sends QUIT only when closing a connection. The respective state
* transitions are RSET->LAST and QUIT->LAST.
*
* For the sake of code reuse, the non-pipelined RSET and QUIT commands are
* sent by the same code that implements command pipelining, so that we can
* borrow from the existing code for exception handling and error reporting.
* For the sake of code reuse, the non-pipelined RSET command is sent by the
* same code that implements command pipelining, so that we can borrow from
* the existing code for exception handling and error reporting.
*
*/
#define LMTP_STATE_MAIL 0
@ -172,13 +172,11 @@ int lmtp_lhlo(LMTP_STATE *state)
{
char *myname = "lmtp_lhlo";
LMTP_SESSION *session = state->session;
DELIVER_REQUEST *request = state->request;
LMTP_RESP *resp;
int except;
char *lines;
char *words;
char *word;
int n;
SOCKOPT_SIZE optlen = sizeof(state->sndbufsize);
/*
@ -194,15 +192,7 @@ int lmtp_lhlo(LMTP_STATE *state)
if (((resp = lmtp_chat_resp(state))->code / 100) != 2)
return (lmtp_site_fail(state, resp->code,
"%s refused to talk to me: %s",
session->host, translit(resp->str, "\n", " ")));
/*
* See if we are talking to ourself. This should not be possible with the
* way we implement DNS lookups. However, people are known to sometimes
* screw up the naming service. And, mailer loops are still possible when
* our own mailer routing tables are mis-configured.
*/
words = resp->str;
session->namaddr, translit(resp->str, "\n", " ")));
/*
* Return the compliment.
@ -211,7 +201,7 @@ int lmtp_lhlo(LMTP_STATE *state)
if ((resp = lmtp_chat_resp(state))->code / 100 != 2)
return (lmtp_site_fail(state, resp->code,
"%s refused to talk to me: %s",
session->host,
session->namaddr,
translit(resp->str, "\n", " ")));
/*
@ -249,10 +239,11 @@ int lmtp_lhlo(LMTP_STATE *state)
* to be aware of application-level buffering by the vstream module,
* which is limited to a couple kbytes.
*
* Don't worry about command pipelining for local connections.
* XXX Apparently, the getsockopt() call causes trouble with UNIX-domain
* sockets. Don't worry about command pipelining for local connections,
* because they benefit little from pipelining.
*/
if (state->features & LMTP_FEATURE_PIPELINING
&& state->session->type != LMTP_SERV_TYPE_UNIX) {
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);
@ -261,7 +252,6 @@ int lmtp_lhlo(LMTP_STATE *state)
state->sndbufsize);
} else
state->sndbufsize = 0;
state->sndbuffree = state->sndbufsize;
return (0);
}
@ -287,11 +277,12 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
int except;
int rec_type;
int prev_type = 0;
int sndbuffree;
int mail_from_rejected;
int recv_dot;
/*
* Macros for readability. XXX Isn't LMTP supposed to be case
* Macros for readability. XXX Aren't LMTP addresses supposed to be case
* insensitive?
*/
#define REWRITE_ADDRESS(addr) do { \
@ -336,6 +327,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
recv_state = send_state = init_state;
next_rcpt = send_rcpt = recv_rcpt = recv_dot = 0;
mail_from_rejected = 0;
sndbuffree = state->sndbufsize;
while (recv_state != LMTP_STATE_LAST) {
@ -389,7 +381,8 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
*/
case LMTP_STATE_DOT:
vstring_strcpy(next_command, ".");
next_state = LMTP_STATE_LAST;
next_state = var_lmtp_cache_conn ?
LMTP_STATE_LAST : LMTP_STATE_QUIT;
break;
/*
@ -400,9 +393,10 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
msg_panic("%s: sender abort state", myname);
/*
* Build the RSET command. XXX This command does not belong here
* because it will be sent in non-pipelining mode. But having it
* here means that we can reuse existing code for error handling.
* Build the RSET command. This command does not really belong
* here because it is always sent without pipelining, but having
* it here means that we can reuse a lot of error handling code
* that already exists.
*/
case LMTP_STATE_RSET:
vstring_strcpy(next_command, "RSET");
@ -410,9 +404,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
break;
/*
* Build the QUIT command. XXX This command does not belong here
* because it will be sent in non-pipelining mode. But having it
* here means that we can reuse existing code for error handling.
* Build the QUIT command.
*/
case LMTP_STATE_QUIT:
vstring_strcpy(next_command, "QUIT");
@ -433,8 +425,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
* automatically flush buffered output when reading new data.
*/
if (SENDER_IN_WAIT_STATE
|| (SENDER_IS_AHEAD
&& VSTRING_LEN(next_command) + 2 > state->sndbuffree)) {
|| (SENDER_IS_AHEAD && VSTRING_LEN(next_command) + 2 > sndbuffree)) {
while (SENDER_IS_AHEAD) {
/*
@ -469,7 +460,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
case LMTP_STATE_MAIL:
if (resp->code / 100 != 2) {
lmtp_mesg_fail(state, resp->code,
"%s said: %s", session->host,
"%s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
mail_from_rejected = 1;
}
@ -493,7 +484,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
survivors[nrcpt++] = recv_rcpt;
} else {
lmtp_rcpt_fail(state, resp->code, rcpt,
"%s said: %s", session->host,
"%s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
rcpt->offset = 0; /* in case deferred */
}
@ -511,7 +502,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
if (resp->code / 100 != 3) {
if (nrcpt > 0)
lmtp_mesg_fail(state, resp->code,
"%s said: %s", session->host,
"%s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
nrcpt = -1;
}
@ -533,14 +524,14 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
if (resp->code / 100 == 2) {
if (rcpt->offset) {
sent(request->queue_id, rcpt->address,
session->host, request->arrival_time,
session->namaddr, request->arrival_time,
"%s", resp->str);
deliver_completed(state->src, rcpt->offset);
rcpt->offset = 0;
}
} else {
lmtp_rcpt_fail(state, resp->code, rcpt,
"%s said: %s", session->host,
"%s said: %s", session->namaddr,
translit(resp->str, "\n", " "));
rcpt->offset = 0; /* in case deferred */
}
@ -554,7 +545,8 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
if (++recv_dot >= nrcpt) {
if (msg_verbose)
msg_info("%s: finished . command", myname);
recv_state = LMTP_STATE_LAST;
recv_state = var_lmtp_cache_conn ?
LMTP_STATE_LAST : LMTP_STATE_QUIT;
}
break;
@ -562,7 +554,8 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
* Ignore the RSET response.
*/
case LMTP_STATE_ABORT:
recv_state = LMTP_STATE_LAST;
recv_state = var_lmtp_cache_conn ?
LMTP_STATE_LAST : LMTP_STATE_QUIT;
break;
/*
@ -585,7 +578,7 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
* At this point, the sender and receiver are fully synchronized,
* so that the entire TCP send buffer becomes available again.
*/
state->sndbuffree = state->sndbufsize;
sndbuffree = state->sndbufsize;
/*
* We know the server response to every command that was sent.
@ -600,7 +593,8 @@ static int lmtp_loop(LMTP_STATE *state, int init_state)
send_state = recv_state = LMTP_STATE_ABORT;
send_rcpt = recv_rcpt = 0;
vstring_strcpy(next_command, "RSET");
next_state = LMTP_STATE_LAST;
next_state = var_lmtp_cache_conn ?
LMTP_STATE_LAST : LMTP_STATE_QUIT;
next_rcpt = 0;
}
}
@ -671,14 +665,14 @@ int lmtp_xfer(LMTP_STATE *state)
return (lmtp_loop(state, LMTP_STATE_MAIL));
}
/* lmtp_rset - reset dialog with peer */
/* lmtp_rset - send a lone RSET command */
int lmtp_rset(LMTP_STATE *state)
{
return (lmtp_loop(state, LMTP_STATE_RSET));
}
/* lmtp_quit - say goodbye to peer */
/* lmtp_quit - send a lone QUIT command */
int lmtp_quit(LMTP_STATE *state)
{

View File

@ -6,48 +6,54 @@
/* SYNOPSIS
/* #include "lmtp.h"
/*
/* LMTP_SESSION *lmtp_session_alloc(stream, host, addr)
/* LMTP_SESSION *lmtp_session_alloc(stream, host, addr, dest, type)
/* VSTREAM *stream;
/* char *host;
/* char *addr;
/* const char *host;
/* const char *addr;
/* const char *dest;
/* int type;
/*
/* void lmtp_session_free(session)
/* LMTP_SESSION *lmtp_session_free(session)
/* LMTP_SESSION *session;
/*
/* void lmtp_session_reset(state)
/* LMTP_STATE *state;
/* DESCRIPTION
/* This module maintains information about connections, including
/* per-peer debugging.
/*
/* lmtp_session_alloc() allocates memory for an LMTP_SESSION structure
/* and initializes it with the given stream and host name and address
/* information. The host name and address strings are copied. The code
/* assumes that the stream is connected to the "best" alternative.
/* information. The host name and address strings are copied.
/* The type argument specifies the transport type. The dest argument
/* specifies a string-valued name for the remote endpoint.
/* If the peer name or address matches the debug-peer_list configuration
/* parameter, the debugging level is incremented by the amount specified
/* in the debug_peer_level parameter.
/*
/* lmtp_session_free() destroys an LMTP_SESSION structure and its
/* members, making memory available for reuse.
/*
/* lmtp_session_reset() is just a little helper to make sure everything
/* is set to zero after the session has been freed. This means I don't
/* have to keep repeating the same chunks of code for cached connections.
/* members, making memory available for reuse. The result value is
/* convenient null pointer. The debugging level is restored to the
/* value prior to the lmtp_session_alloc() call.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* SEE ALSO
/* debug_peer(3), increase logging for selected peers
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/*--*/
/* System library. */
@ -58,6 +64,11 @@
#include <mymalloc.h>
#include <vstream.h>
#include <stringops.h>
/* Global library. */
#include <debug_peer.h>
/* Application-specific. */
@ -65,7 +76,8 @@
/* lmtp_session_alloc - allocate and initialize LMTP_SESSION structure */
LMTP_SESSION *lmtp_session_alloc(VSTREAM *stream, char *host, char *addr)
LMTP_SESSION *lmtp_session_alloc(VSTREAM *stream, const char *host,
const char *addr, const char *dest)
{
LMTP_SESSION *session;
@ -73,33 +85,22 @@ LMTP_SESSION *lmtp_session_alloc(VSTREAM *stream, char *host, char *addr)
session->stream = stream;
session->host = mystrdup(host);
session->addr = mystrdup(addr);
session->destination = 0;
session->namaddr = concatenate(host, "[", addr, "]", (char *) 0);
session->dest = mystrdup(dest);
debug_peer_check(host, addr);
return (session);
}
/* lmtp_session_free - destroy LMTP_SESSION structure and contents */
void lmtp_session_free(LMTP_SESSION *session)
LMTP_SESSION *lmtp_session_free(LMTP_SESSION *session)
{
if (vstream_ispipe(session->stream))
vstream_pclose(session->stream);
else
vstream_fclose(session->stream);
debug_peer_restore();
vstream_fclose(session->stream);
myfree(session->host);
myfree(session->addr);
if (session->destination)
myfree(session->destination);
myfree(session->namaddr);
myfree(session->dest);
myfree((char *) session);
return (0);
}
/* lmtp_session_reset - clean things up so a new session can be created */
void lmtp_session_reset(LMTP_STATE *state)
{
if (state->session) {
lmtp_session_free(state->session);
state->session = 0;
}
state->reuse = 0;
}

View File

@ -29,16 +29,16 @@
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/* Alterations for LMTP by:
/* Philip A. Prindeville
/* Mirapoint, Inc.
/* USA.
/*
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/* Additional work on LMTP by:
/* Amos Gouaux
/* University of Texas at Dallas
/* P.O. Box 830688, MC34
/* Richardson, TX 75083, USA
/*--*/
/* System library. */
@ -78,6 +78,7 @@ LMTP_STATE *lmtp_state_alloc(void)
state->sndbufsize = 0;
state->sndbuffree = 0;
state->reuse = 0;
state->fixed_dest = 0;
return (state);
}

View File

@ -179,7 +179,7 @@ int lmtp_site_fail(LMTP_STATE *state, int code, char *format,...)
continue;
status = (soft_error ? defer_append : bounce_append)
(KEEP, request->queue_id, rcpt->address,
session ? session->host : "none",
session ? session->namaddr : "none",
request->arrival_time, "%s", vstring_str(why));
if (status == 0) {
deliver_completed(state->src, rcpt->offset);
@ -226,7 +226,7 @@ int lmtp_mesg_fail(LMTP_STATE *state, int code, char *format,...)
continue;
status = (LMTP_SOFT(code) ? defer_append : bounce_append)
(KEEP, request->queue_id, rcpt->address,
session->host, request->arrival_time,
session->namaddr, request->arrival_time,
"%s", vstring_str(why));
if (status == 0) {
deliver_completed(state->src, rcpt->offset);
@ -259,7 +259,7 @@ void lmtp_rcpt_fail(LMTP_STATE *state, int code, RECIPIENT *rcpt,
*/
va_start(ap, format);
status = (LMTP_SOFT(code) ? vdefer_append : vbounce_append)
(KEEP, request->queue_id, rcpt->address, session->host,
(KEEP, request->queue_id, rcpt->address, session->namaddr,
request->arrival_time, format, ap);
va_end(ap);
if (status == 0) {
@ -288,11 +288,11 @@ int lmtp_stream_except(LMTP_STATE *state, int code, char *description)
msg_panic("lmtp_stream_except: unknown exception %d", code);
case SMTP_ERR_EOF:
vstring_sprintf(why, "lost connection with %s while %s",
session->host, description);
session->namaddr, description);
break;
case SMTP_ERR_TIME:
vstring_sprintf(why, "conversation with %s timed out while %s",
session->host, description);
session->namaddr, description);
break;
}
@ -305,7 +305,7 @@ int lmtp_stream_except(LMTP_STATE *state, int code, char *description)
if (rcpt->offset == 0)
continue;
state->status |= defer_append(KEEP, request->queue_id,
rcpt->address, session->host,
rcpt->address, session->namaddr,
request->arrival_time,
"%s", vstring_str(why));
}

View File

@ -1,218 +0,0 @@
*** ../../orig/man/Makefile.in Thu Jun 24 18:39:22 1999
--- man/Makefile.in Fri Feb 25 16:35:53 2000
***************
*** 2,8 ****
DAEMONS = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 man8/showq.8 \
! man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8
COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
--- 2,8 ----
DAEMONS = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 man8/showq.8 \
! man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 man8/lmtp.8
COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
***************
*** 24,99 ****
rm -f $(DAEMONS) $(COMMANDS) $(CONFIG)
man8/bounce.8: ../bounce/bounce.c
! srctoman $? >$@
man8/defer.8:
echo .so man8/bounce.8 >$@
man8/cleanup.8: ../cleanup/cleanup.c
! srctoman $? >$@
man8/error.8: ../error/error.c
! srctoman $? >$@
man8/local.8: ../local/local.c
! srctoman $? >$@
man8/master.8: ../master/master.c
! srctoman $? >$@
man8/pickup.8: ../pickup/pickup.c
! srctoman $? >$@
man8/pipe.8: ../pipe/pipe.c
! srctoman $? >$@
man8/qmgr.8: ../qmgr/qmgr.c
! srctoman $? >$@
man8/showq.8: ../showq/showq.c
! srctoman $? >$@
man8/smtp.8: ../smtp/smtp.c
! srctoman $? >$@
man8/smtpd.8: ../smtpd/smtpd.c
! srctoman $? >$@
man8/trivial-rewrite.8: ../trivial-rewrite/trivial-rewrite.c
! srctoman $? >$@
man1/postalias.1: ../postalias/postalias.c
! srctoman $? >$@
man1/postcat.1: ../postcat/postcat.c
! srctoman $? >$@
man1/postconf.1: ../postconf/postconf.c
! srctoman $? >$@
man1/postdrop.1: ../postdrop/postdrop.c
! srctoman $? >$@
man1/postfix.1: ../postfix/postfix.c
! srctoman $? >$@
man1/postkick.1: ../postkick/postkick.c
! srctoman $? >$@
man1/postlock.1: ../postlock/postlock.c
! srctoman $? >$@
man1/postlog.1: ../postlog/postlog.c
! srctoman $? >$@
man1/postmap.1: ../postmap/postmap.c
! srctoman $? >$@
man1/postsuper.1: ../postsuper/postsuper.c
! srctoman $? >$@
man1/sendmail.1: ../sendmail/sendmail.c
! srctoman $? >$@
man1/mailq.1:
echo .so man1/sendmail.1 >$@
--- 24,102 ----
rm -f $(DAEMONS) $(COMMANDS) $(CONFIG)
man8/bounce.8: ../bounce/bounce.c
! ../mantools/srctoman $? >$@
man8/defer.8:
echo .so man8/bounce.8 >$@
man8/cleanup.8: ../cleanup/cleanup.c
! ../mantools/srctoman $? >$@
man8/error.8: ../error/error.c
! ../mantools/srctoman $? >$@
man8/local.8: ../local/local.c
! ../mantools/srctoman $? >$@
man8/master.8: ../master/master.c
! ../mantools/srctoman $? >$@
man8/pickup.8: ../pickup/pickup.c
! ../mantools/srctoman $? >$@
man8/pipe.8: ../pipe/pipe.c
! ../mantools/srctoman $? >$@
man8/qmgr.8: ../qmgr/qmgr.c
! ../mantools/srctoman $? >$@
man8/showq.8: ../showq/showq.c
! ../mantools/srctoman $? >$@
man8/smtp.8: ../smtp/smtp.c
! ../mantools/srctoman $? >$@
man8/smtpd.8: ../smtpd/smtpd.c
! ../mantools/srctoman $? >$@
man8/trivial-rewrite.8: ../trivial-rewrite/trivial-rewrite.c
! ../mantools/srctoman $? >$@
+ man8/lmtp.8: ../lmtp/lmtp.c
+ ../mantools/srctoman $? >$@
+
man1/postalias.1: ../postalias/postalias.c
! ../mantools/srctoman $? >$@
man1/postcat.1: ../postcat/postcat.c
! ../mantools/srctoman $? >$@
man1/postconf.1: ../postconf/postconf.c
! ../mantools/srctoman $? >$@
man1/postdrop.1: ../postdrop/postdrop.c
! ../mantools/srctoman $? >$@
man1/postfix.1: ../postfix/postfix.c
! ../mantools/srctoman $? >$@
man1/postkick.1: ../postkick/postkick.c
! ../mantools/srctoman $? >$@
man1/postlock.1: ../postlock/postlock.c
! ../mantools/srctoman $? >$@
man1/postlog.1: ../postlog/postlog.c
! ../mantools/srctoman $? >$@
man1/postmap.1: ../postmap/postmap.c
! ../mantools/srctoman $? >$@
man1/postsuper.1: ../postsuper/postsuper.c
! ../mantools/srctoman $? >$@
man1/sendmail.1: ../sendmail/sendmail.c
! ../mantools/srctoman $? >$@
man1/mailq.1:
echo .so man1/sendmail.1 >$@
***************
*** 102,120 ****
echo .so man1/sendmail.1 >$@
man5/access.5: ../conf/access
! srctoman - $? >$@
man5/aliases.5: ../conf/aliases
! srctoman - $? >$@
man5/canonical.5: ../conf/canonical
! srctoman - $? >$@
man5/relocated.5: ../conf/relocated
! srctoman - $? >$@
man5/transport.5: ../conf/transport
! srctoman - $? >$@
man5/virtual.5: ../conf/virtual
! srctoman - $? >$@
--- 105,123 ----
echo .so man1/sendmail.1 >$@
man5/access.5: ../conf/access
! ../mantools/srctoman - $? >$@
man5/aliases.5: ../conf/aliases
! ../mantools/srctoman - $? >$@
man5/canonical.5: ../conf/canonical
! ../mantools/srctoman - $? >$@
man5/relocated.5: ../conf/relocated
! ../mantools/srctoman - $? >$@
man5/transport.5: ../conf/transport
! ../mantools/srctoman - $? >$@
man5/virtual.5: ../conf/virtual
! ../mantools/srctoman - $? >$@

View File

@ -3,8 +3,8 @@ SHELL = /bin/sh
# For now, just hard-coded rules for daemons, commands, config files.
DAEMONS = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 man8/showq.8 \
man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8
man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8
COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
@ -26,76 +26,79 @@ clobber:
rm -f $(DAEMONS) $(COMMANDS) $(CONFIG)
man8/bounce.8: ../bounce/bounce.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/defer.8:
echo .so man8/bounce.8 >$@
man8/cleanup.8: ../cleanup/cleanup.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/error.8: ../error/error.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/local.8: ../local/local.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/lmtp.8: ../lmtp/lmtp.c
../mantools/srctoman $? >$@
man8/master.8: ../master/master.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/pickup.8: ../pickup/pickup.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/pipe.8: ../pipe/pipe.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/qmgr.8: ../qmgr/qmgr.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/showq.8: ../showq/showq.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/smtp.8: ../smtp/smtp.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/smtpd.8: ../smtpd/smtpd.c
srctoman $? >$@
../mantools/srctoman $? >$@
man8/trivial-rewrite.8: ../trivial-rewrite/trivial-rewrite.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postalias.1: ../postalias/postalias.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postcat.1: ../postcat/postcat.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postconf.1: ../postconf/postconf.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postdrop.1: ../postdrop/postdrop.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postfix.1: ../postfix/postfix.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postkick.1: ../postkick/postkick.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postlock.1: ../postlock/postlock.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postlog.1: ../postlog/postlog.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postmap.1: ../postmap/postmap.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/postsuper.1: ../postsuper/postsuper.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/sendmail.1: ../sendmail/sendmail.c
srctoman $? >$@
../mantools/srctoman $? >$@
man1/mailq.1:
echo .so man1/sendmail.1 >$@
@ -104,25 +107,25 @@ man1/newaliases.1:
echo .so man1/sendmail.1 >$@
man5/access.5: ../proto/access
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/aliases.5: ../proto/aliases
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/canonical.5: ../proto/canonical
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/pcre_table.5: ../proto/pcre_table
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/regexp_table.5: ../proto/regexp_table
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/relocated.5: ../proto/relocated
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/transport.5: ../proto/transport
srctoman - $? >$@
../mantools/srctoman - $? >$@
man5/virtual.5: ../proto/virtual
srctoman - $? >$@
../mantools/srctoman - $? >$@

214
postfix/man/man8/lmtp.8 Normal file
View File

@ -0,0 +1,214 @@
.TH LMTP 8
.ad
.fi
.SH NAME
lmtp
\-
Postfix local delivery via LMTP
.SH SYNOPSIS
.na
.nf
\fBlmtp\fR [generic Postfix daemon options] [server attributes...]
.SH DESCRIPTION
.ad
.fi
The LMTP client processes message delivery requests from
the queue manager. Each request specifies a queue file, a sender
address, a domain or host to deliver to, and recipient information.
This program expects to be run from the \fBmaster\fR(8) process
manager.
The LMTP client updates the queue file and marks recipients
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.
.SH SERVER ATTRIBUTE SYNTAX
.na
.nf
.ad
.fi
The server attributes are given in the \fBmaster.cf\fR file at
the end of a service definition. The syntax is as follows:
.IP "\fBserver=\fR\fIhost\fR"
.IP "\fBserver=\fR\fIhost\fR\fB:\fR\fIport\fR"
.IP "\fBserver=[\fR\fIipaddr\fR\fB]\fR"
.IP "\fBserver=[\fR\fIipaddr\fR\fB]:\fR\fIport\fR"
Connect to the specified host or IP address and TCP port (default: the
\fBlmtp\fR port as specified in the \fBservices\fR database).
.PP
.SH SECURITY
.na
.nf
.ad
.fi
The LMTP client is moderately security-sensitive. It talks to LMTP
servers and to DNS servers on the network. The LMTP client can be
run chrooted at fixed low privilege.
.SH STANDARDS
.na
.nf
RFC 821 (SMTP protocol)
RFC 1651 (SMTP service extensions)
RFC 1870 (Message Size Declaration)
RFC 2033 (LMTP protocol)
RFC 2197 (Pipelining)
.SH DIAGNOSTICS
.ad
.fi
Problems and transactions are logged to \fBsyslogd\fR(8).
Corrupted message files are marked so that the queue manager can
move them to the \fBcorrupt\fR queue for further inspection.
Depending on the setting of the \fBnotify_classes\fR parameter,
the postmaster is notified of bounces, protocol problems, and of
other trouble.
.SH BUGS
.ad
.fi
.SH CONFIGURATION PARAMETERS
.na
.nf
.ad
.fi
The following \fBmain.cf\fR parameters are especially relevant to
this program. See the Postfix \fBmain.cf\fR file for syntax details
and for default values. Use the \fBpostfix reload\fR command after
a configuration change.
.SH Miscellaneous
.ad
.fi
.IP \fBdebug_peer_level\fR
Verbose logging level increment for hosts that match a
pattern in the \fBdebug_peer_list\fR parameter.
.IP \fBdebug_peer_list\fR
List of domain or network patterns. When a remote host matches
a pattern, increase the verbose logging level by the amount
specified in the \fBdebug_peer_level\fR parameter.
.IP \fBerror_notice_recipient\fR
Recipient of protocol/policy/resource/software error notices.
.IP \fBnotify_classes\fR
When this parameter includes the \fBprotocol\fR class, send mail to the
postmaster with transcripts of LMTP sessions with protocol errors.
.IP \fBlmtp_skip_quit_response\fR
Do not wait for the server response after sending QUIT.
.IP \fBlmtp_tcp_port\fR
The TCP port to be used when connecting to a LMTP server. Used as
backup if the \fBlmtp\fR service is not found in \fBservices\fR(4).
.SH "Resource controls"
.ad
.fi
.IP \fBlmtp_cache_connection\fR
Should we cache the connection to the LMTP server? The effectiveness
of cached connections will be determined by the number of LMTP servers
in use, and the concurrency limit specified for the LMTP client.
Cached connections are closed under any of the following conditions:
.RS
.IP \(bu
The LMTP client idle time limit is reached. This limit is specified
with the Postfix \fBmax_idle\fR configuration parameter.
.IP \(bu
A delivery request specifies a different destination than the one
currently cached.
.IP \(bu
The per-process limit on the number of delivery requests is reached.
This limit is specified with the Postfix \fBmax_use\fR configuration
parameter.
.IP \(bu
Upon the onset of another delivery request, the LMTP server associated
with the current session does not respond to the \fBRSET\fR command.
.RE
.IP \fItransport_\fBdestination_concurrency_limit\fR
Limit the number of parallel deliveries to the same destination
via this mail delivery transport. \fItransport\fR is the name
of the service as specified in the \fBmaster.cf\fR file.
The default limit is taken from the
\fBdefault_destination_concurrency_limit\fR parameter.
.IP \fItransport_\fBdestination_recipient_limit\fR
Limit the number of recipients per message delivery via this mail
delivery transport. \fItransport\fR is the name
of the service as specified in the \fBmaster.cf\fR file.
The default limit is taken from the
\fBdefault_destination_recipient_limit\fR parameter.
This parameter becomes significant if the LMTP client is used
for local delivery. Some LMTP servers can optimize delivery of
the same message to multiple recipients. The default limit for
local mail delivery is 1.
Setting this parameter to 0 will lead to an unbounded number of
recipients per delivery. However, this could be risky since it may
make the machine vulnerable to running out of resources if messages
are encountered with an inordinate number of recipients. Exercise
care when setting this parameter.
.SH "Timeout controls"
.ad
.fi
.IP \fBlmtp_connect_timeout\fR
Timeout in seconds for opening a connection to the LMTP server.
If no connection can be made within the deadline, the message
is deferred.
.IP \fBlmtp_lhlo_timeout\fR
Timeout in seconds for sending the \fBLHLO\fR command, and for
receiving the server response.
.IP \fBlmtp_mail_timeout\fR
Timeout in seconds for sending the \fBMAIL FROM\fR command, and for
receiving the server response.
.IP \fBlmtp_rcpt_timeout\fR
Timeout in seconds for sending the \fBRCPT TO\fR command, and for
receiving the server response.
.IP \fBlmtp_data_init_timeout\fR
Timeout in seconds for sending the \fBDATA\fR command, and for
receiving the server response.
.IP \fBlmtp_data_xfer_timeout\fR
Timeout in seconds for sending the message content.
.IP \fBlmtp_data_done_timeout\fR
Timeout in seconds for sending the "\fB.\fR" command, and for
receiving the server response. When no response is received, a
warning is logged that the mail may be delivered multiple times.
.IP \fBlmtp_rset_timeout\fR
Timeout in seconds for sending the \fBRSET\fR command, and for
receiving the server response.
.IP \fBlmtp_quit_timeout\fR
Timeout in seconds for sending the \fBQUIT\fR command, and for
receiving the server response.
.SH SEE ALSO
.na
.nf
bounce(8) non-delivery status reports
local(8) local mail delivery
master(8) process manager
qmgr(8) queue manager
services(4) Internet services and aliases
spawn(8) auxiliary command spawner
syslogd(8) system logging
.SH LICENSE
.na
.nf
.ad
.fi
The Secure Mailer license must be distributed with this software.
.SH AUTHOR(S)
.na
.nf
Wietse Venema
IBM T.J. Watson Research
P.O. Box 704
Yorktown Heights, NY 10598, USA
Alterations for LMTP by:
Philip A. Prindeville
Mirapoint, Inc.
USA.
Additional work on LMTP by:
Amos Gouaux
University of Texas at Dallas
P.O. Box 830688, MC34
Richardson, TX 75083, USA

View File

@ -113,6 +113,7 @@ Do not wait for the server response after sending QUIT.
.SH "Authentication controls"
.IP \fBsmtp_enable_sasl_auth\fR
Enable per-session authentication as per RFC 2554 (SASL).
By default, Postfix is built without SASL support.
.IP \fBsmtp_sasl_password_maps\fR
Lookup tables with per-host \fIname\fR:\fIpassword\fR entries.
No entry for a host means no attempt to authenticate.

View File

@ -532,6 +532,13 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
vstring_free(why);
}
/*
* Set up call-back info.
*/
multi_server_service = service;
multi_server_name = service_name;
multi_server_argv = argv + optind;
/*
* Run pre-jail initialization.
*/
@ -562,7 +569,7 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
VSTREAM_CTL_DOUBLE,
VSTREAM_CTL_WRITE_FD, STDOUT_FILENO,
VSTREAM_CTL_END);
service(stream, service_name, argv + optind);
service(stream, multi_server_name, multi_server_argv);
vstream_fflush(stream);
multi_server_exit();
}
@ -573,9 +580,6 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
* no-one has been talking to us for a configurable amount of time, or
* when the master process terminated abnormally.
*/
multi_server_service = service;
multi_server_name = service_name;
multi_server_argv = argv + optind;
if (var_idle_limit > 0)
event_request_timer(multi_server_timeout, (char *) 0, var_idle_limit);
for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++) {

View File

@ -504,6 +504,13 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
vstring_free(why);
}
/*
* Set up call-back info.
*/
single_server_service = service;
single_server_name = service_name;
single_server_argv = argv + optind;
/*
* Run pre-jail initialization.
*/
@ -534,7 +541,7 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
VSTREAM_CTL_DOUBLE,
VSTREAM_CTL_WRITE_FD, STDOUT_FILENO,
VSTREAM_CTL_END);
service(stream, service_name, argv + optind);
service(stream, single_server_name, single_server_argv);
vstream_fflush(stream);
single_server_exit();
}
@ -545,9 +552,6 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
* no-one has been talking to us for a configurable amount of time, or
* when the master process terminated abnormally.
*/
single_server_service = service;
single_server_name = service_name;
single_server_argv = argv + optind;
if (var_idle_limit > 0)
event_request_timer(single_server_timeout, (char *) 0, var_idle_limit);
for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++) {

View File

@ -519,6 +519,13 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
vstring_free(why);
}
/*
* Set up call-back info.
*/
trigger_server_service = service;
trigger_server_name = service_name;
trigger_server_argv = argv + optind;
/*
* Run pre-jail initialization.
*/
@ -546,7 +553,7 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
if (stream != 0) {
if ((len = read(vstream_fileno(stream), buf, sizeof(buf))) <= 0)
msg_fatal("read: %m");
service(buf, len, service_name, argv + optind);
service(buf, len, trigger_server_name, trigger_server_argv);
vstream_fflush(stream);
trigger_server_exit();
}
@ -557,9 +564,6 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
* no-one has been talking to us for a configurable amount of time, or
* when the master process terminated abnormally.
*/
trigger_server_service = service;
trigger_server_name = service_name;
trigger_server_argv = argv + optind;
if (var_idle_limit > 0)
event_request_timer(trigger_server_timeout, (char *) 0, var_idle_limit);
for (fd = MASTER_LISTEN_FD; fd < MASTER_LISTEN_FD + socket_count; fd++) {

View File

@ -89,7 +89,6 @@ smtp.o: ../include/mail_error.h
smtp.o: ../include/deliver_pass.h
smtp.o: ../include/mail_proto.h
smtp.o: ../include/iostuff.h
smtp.o: ../include/smtp_stream.h
smtp.o: ../include/mail_server.h
smtp.o: smtp.h
smtp.o: smtp_sasl.h

View File

@ -149,9 +149,9 @@ void smtpd_chat_reply(SMTPD_STATE *state, char *format,...)
* errors within a session.
*/
if (state->error_count > var_smtpd_soft_erlim)
sleep(state->error_count);
sleep(state->error_count), vstream_fflush(state->client);
else if (STR(state->buffer)[0] == '4' || STR(state->buffer)[0] == '5')
sleep(var_smtpd_err_sleep);
sleep(var_smtpd_err_sleep), vstream_fflush(state->client);
smtp_fputs(STR(state->buffer), LEN(state->buffer), state->client);
}

View File

@ -60,6 +60,7 @@ spawn.o: ../include/argv.h
spawn.o: ../include/dict.h
spawn.o: ../include/vstream.h
spawn.o: ../include/vbuf.h
spawn.o: ../include/binattr.h
spawn.o: ../include/mymalloc.h
spawn.o: ../include/spawn_command.h
spawn.o: ../include/split_at.h