diff --git a/postfix/HISTORY b/postfix/HISTORY
index 055ee7b09..78ebaa492 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -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.
diff --git a/postfix/Makefile.in b/postfix/Makefile.in
index dcaddeb99..af831c767 100644
--- a/postfix/Makefile.in
+++ b/postfix/Makefile.in
@@ -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
diff --git a/postfix/conf/master.cf b/postfix/conf/master.cf
index 399d59093..34e222855 100644
--- a/postfix/conf/master.cf
+++ b/postfix/conf/master.cf
@@ -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
diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h
index 22b8c6d96..d5a73e7a8 100644
--- a/postfix/global/mail_params.h
+++ b/postfix/global/mail_params.h
@@ -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.
diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h
index 24fb39cc1..28b522ed2 100644
--- a/postfix/global/mail_version.h
+++ b/postfix/global/mail_version.h
@@ -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
diff --git a/postfix/html/Makefile.in b/postfix/html/Makefile.in
index 963766110..63f98693a 100644
--- a/postfix/html/Makefile.in
+++ b/postfix/html/Makefile.in
@@ -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 >$@
diff --git a/postfix/html/delivering.html b/postfix/html/delivering.html
index 12036a192..a39b603af 100644
--- a/postfix/html/delivering.html
+++ b/postfix/html/delivering.html
@@ -39,11 +39,11 @@ click on the icon in the upper left-hand corner of this page.
The queue manager is the heart of
the Postfix mail system. It contacts the local,
-smtp, or pipe
-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.
+smtp, lmtp, or
+pipe 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.
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html
new file mode 100644
index 000000000..1313f10ca
--- /dev/null
+++ b/postfix/html/lmtp.8.html
@@ -0,0 +1,332 @@
+
+
+
+
+LMTP(8) LMTP(8)
+
+
+NAME
+ lmtp - Postfix local delivery via LMTP
+
+SYNOPSIS
+ lmtp [generic Postfix daemon options] [server attributes...]
+
+DESCRIPTION
+ 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
+ master(8) 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 bounce(8) or defer(8) 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 lmtp in
+ services(4). If no such service is found, the
+ lmtp_tcp_port 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.
+
+SERVER ATTRIBUTE SYNTAX
+ The server attributes are given in the master.cf file at
+ the end of a service definition. The syntax is as fol-
+ lows:
+
+ server=host
+
+ server=host:port
+
+ server=[ipaddr]
+
+ server=[ipaddr]:port
+ Connect to the specified host or IP address and TCP
+ port (default: the lmtp port as specified in the
+ services database).
+
+
+SECURITY
+ 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.
+
+STANDARDS
+ RFC 821 (SMTP protocol)
+ RFC 1651 (SMTP service extensions)
+ RFC 1870 (Message Size Declaration)
+
+
+
+ 1
+
+
+
+
+
+LMTP(8) LMTP(8)
+
+
+ RFC 2033 (LMTP protocol)
+ RFC 2197 (Pipelining)
+
+DIAGNOSTICS
+ Problems and transactions are logged to syslogd(8). Cor-
+ rupted message files are marked so that the queue manager
+ can move them to the corrupt queue for further inspection.
+
+ Depending on the setting of the notify_classes parameter,
+ the postmaster is notified of bounces, protocol problems,
+ and of other trouble.
+
+BUGS
+CONFIGURATION PARAMETERS
+ The following main.cf parameters are especially relevant
+ to this program. See the Postfix main.cf file for syntax
+ details and for default values. Use the postfix reload
+ command after a configuration change.
+
+Miscellaneous
+ debug_peer_level
+ Verbose logging level increment for hosts that
+ match a pattern in the debug_peer_list parameter.
+
+ debug_peer_list
+ 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
+ debug_peer_level parameter.
+
+ error_notice_recipient
+ Recipient of protocol/policy/resource/software
+ error notices.
+
+ notify_classes
+ When this parameter includes the protocol class,
+ send mail to the postmaster with transcripts of
+ LMTP sessions with protocol errors.
+
+ lmtp_skip_quit_response
+ Do not wait for the server response after sending
+ QUIT.
+
+ lmtp_tcp_port
+ The TCP port to be used when connecting to a LMTP
+ server. Used as backup if the lmtp service is not
+ found in services(4).
+
+Resource controls
+ lmtp_cache_connection
+ 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:
+
+ o The LMTP client idle time limit is reached.
+ This limit is specified with the Postfix
+ max_idle configuration parameter.
+
+ o A delivery request specifies a different
+ destination than the one currently cached.
+
+ o The per-process limit on the number of
+ delivery requests is reached. This limit is
+ specified with the Postfix max_use configu-
+ ration parameter.
+
+ o Upon the onset of another delivery request,
+ the LMTP server associated with the current
+ session does not respond to the RSET com-
+ mand.
+
+ transport_destination_concurrency_limit
+ Limit the number of parallel deliveries to the same
+ destination via this mail delivery transport.
+ transport is the name of the service as specified
+ in the master.cf file. The default limit is taken
+ from the default_destination_concurrency_limit
+ parameter.
+
+ transport_destination_recipient_limit
+ Limit the number of recipients per message delivery
+ via this mail delivery transport. transport is the
+ name of the service as specified in the master.cf
+ file. The default limit is taken from the
+ default_destination_recipient_limit 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.
+
+Timeout controls
+ lmtp_connect_timeout
+ 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)
+
+
+ lmtp_lhlo_timeout
+ Timeout in seconds for sending the LHLO command,
+ and for receiving the server response.
+
+ lmtp_mail_timeout
+ Timeout in seconds for sending the MAIL FROM com-
+ mand, and for receiving the server response.
+
+ lmtp_rcpt_timeout
+ Timeout in seconds for sending the RCPT TO command,
+ and for receiving the server response.
+
+ lmtp_data_init_timeout
+ Timeout in seconds for sending the DATA command,
+ and for receiving the server response.
+
+ lmtp_data_xfer_timeout
+ Timeout in seconds for sending the message content.
+
+ lmtp_data_done_timeout
+ Timeout in seconds for sending the "." command, and
+ for receiving the server response. When no response
+ is received, a warning is logged that the mail may
+ be delivered multiple times.
+
+ lmtp_rset_timeout
+ Timeout in seconds for sending the RSET command,
+ and for receiving the server response.
+
+ lmtp_quit_timeout
+ Timeout in seconds for sending the QUIT command,
+ and for receiving the server response.
+
+SEE ALSO
+ 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
+
+LICENSE
+ The Secure Mailer license must be distributed with this
+ software.
+
+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
+
+
+
+ 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
+
+
+
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index 13b77d672..46c25fe23 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -147,11 +147,12 @@ SMTP(8) SMTP(8)
Authentication controls
smtp_enable_sasl_auth
Enable per-session authentication as per RFC 2554
- (SASL).
+ (SASL). By default, Postfix is built without SASL
+ support.
smtp_sasl_password_maps
- Lookup tables with per-host name:password entries.
- No entry for a host means no attempt to authenti-
+ Lookup tables with per-host name:password entries.
+ No entry for a host means no attempt to authenti-
cate.
smtp_sasl_security_options
@@ -175,25 +176,24 @@ SMTP(8) SMTP(8)
Resource controls
smtp_destination_concurrency_limit
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
default_destination_concurrency_limit parameter.
smtp_destination_recipient_limit
- 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
default_destination_recipient_limit parameter.
Timeout controls
smtp_connect_timeout
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)
smtp_helo_timeout
- 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.
smtp_helo_timeout
- Timeout in seconds for sending the HELO command,
+ Timeout in seconds for sending the HELO command,
and for receiving the server response.
smtp_mail_timeout
- Timeout in seconds for sending the MAIL FROM com-
+ Timeout in seconds for sending the MAIL FROM com-
mand, and for receiving the server response.
smtp_rcpt_timeout
@@ -224,7 +224,7 @@ SMTP(8) SMTP(8)
and for receiving the server response.
smtp_data_init_timeout
- Timeout in seconds for sending the DATA command,
+ Timeout in seconds for sending the DATA command,
and for receiving the server response.
smtp_data_xfer_timeout
@@ -233,11 +233,11 @@ SMTP(8) SMTP(8)
smtp_data_done_timeout
Timeout in seconds for sending the "." 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.
smtp_quit_timeout
- Timeout in seconds for sending the QUIT command,
+ Timeout in seconds for sending the QUIT command,
and for receiving the server response.
SEE ALSO
@@ -247,7 +247,7 @@ SMTP(8) SMTP(8)
syslogd(8) system logging
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/lmtp/Makefile.in b/postfix/lmtp/Makefile.in
index 60c904e2d..a342037b0 100644
--- a/postfix/lmtp/Makefile.in
+++ b/postfix/lmtp/Makefile.in
@@ -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
diff --git a/postfix/lmtp/fixnames b/postfix/lmtp/fixnames
index e6545ff75..e19e59011 100644
--- a/postfix/lmtp/fixnames
+++ b/postfix/lmtp/fixnames
@@ -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
' $*
diff --git a/postfix/lmtp/global-patch b/postfix/lmtp/global-patch
deleted file mode 100644
index cf604b93b..000000000
--- a/postfix/lmtp/global-patch
+++ /dev/null
@@ -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.
- */
diff --git a/postfix/lmtp/lmtp.c b/postfix/lmtp/lmtp.c
index 3ed78e830..34cf6f240 100644
--- a/postfix/lmtp/lmtp.c
+++ b/postfix/lmtp/lmtp.c
@@ -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
#include
#include
+#include
/* 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);
diff --git a/postfix/lmtp/lmtp.h b/postfix/lmtp/lmtp.h
index b93d53e9f..04faa6e8b 100644
--- a/postfix/lmtp/lmtp.h
+++ b/postfix/lmtp/lmtp.h
@@ -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
diff --git a/postfix/lmtp/lmtp_addr.c b/postfix/lmtp/lmtp_addr.c
index 69c49a510..72bc77db3 100644
--- a/postfix/lmtp/lmtp_addr.c
+++ b/postfix/lmtp/lmtp_addr.c
@@ -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);
}
-
diff --git a/postfix/lmtp/lmtp_chat.c b/postfix/lmtp/lmtp_chat.c
index 097169b76..9fd23f2bf 100644
--- a/postfix/lmtp/lmtp_chat.c
+++ b/postfix/lmtp/lmtp_chat.c
@@ -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, "");
diff --git a/postfix/lmtp/lmtp_connect.c b/postfix/lmtp/lmtp_connect.c
index dcf5733ec..28d64e953 100644
--- a/postfix/lmtp/lmtp_connect.c
+++ b/postfix/lmtp/lmtp_connect.c
@@ -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
#include
#include
-#include
#include
#include
#include
@@ -88,7 +86,7 @@
/* Global library. */
#include
-#include
+#include
/* 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);
}
-
diff --git a/postfix/lmtp/lmtp_proto.c b/postfix/lmtp/lmtp_proto.c
index 76ae3805a..e4396bf8a 100644
--- a/postfix/lmtp/lmtp_proto.c
+++ b/postfix/lmtp/lmtp_proto.c
@@ -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)
{
diff --git a/postfix/lmtp/lmtp_session.c b/postfix/lmtp/lmtp_session.c
index 80471dff0..3f08533b5 100644
--- a/postfix/lmtp/lmtp_session.c
+++ b/postfix/lmtp/lmtp_session.c
@@ -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
#include
+#include
+
+/* Global library. */
+
+#include
/* 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;
-}
-
diff --git a/postfix/lmtp/lmtp_state.c b/postfix/lmtp/lmtp_state.c
index c52bfb94f..c0ae6a45b 100644
--- a/postfix/lmtp/lmtp_state.c
+++ b/postfix/lmtp/lmtp_state.c
@@ -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);
}
diff --git a/postfix/lmtp/lmtp_trouble.c b/postfix/lmtp/lmtp_trouble.c
index 9a13b69d1..713e4d89b 100644
--- a/postfix/lmtp/lmtp_trouble.c
+++ b/postfix/lmtp/lmtp_trouble.c
@@ -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));
}
diff --git a/postfix/lmtp/man-patch b/postfix/lmtp/man-patch
deleted file mode 100644
index 551002f16..000000000
--- a/postfix/lmtp/man-patch
+++ /dev/null
@@ -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 - $? >$@
diff --git a/postfix/man/Makefile.in b/postfix/man/Makefile.in
index 008206c8b..235143125 100644
--- a/postfix/man/Makefile.in
+++ b/postfix/man/Makefile.in
@@ -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 - $? >$@
diff --git a/postfix/man/man8/lmtp.8 b/postfix/man/man8/lmtp.8
new file mode 100644
index 000000000..294234e2b
--- /dev/null
+++ b/postfix/man/man8/lmtp.8
@@ -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
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index c3f53dd80..b69e90b5c 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -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.
diff --git a/postfix/master/multi_server.c b/postfix/master/multi_server.c
index fb87793fd..7f12ae301 100644
--- a/postfix/master/multi_server.c
+++ b/postfix/master/multi_server.c
@@ -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++) {
diff --git a/postfix/master/single_server.c b/postfix/master/single_server.c
index 70424a95f..fc39204a9 100644
--- a/postfix/master/single_server.c
+++ b/postfix/master/single_server.c
@@ -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++) {
diff --git a/postfix/master/trigger_server.c b/postfix/master/trigger_server.c
index 340977f4c..3a1b9d89b 100644
--- a/postfix/master/trigger_server.c
+++ b/postfix/master/trigger_server.c
@@ -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++) {
diff --git a/postfix/smtp/Makefile.in b/postfix/smtp/Makefile.in
index d35b6a382..f5afaf01a 100644
--- a/postfix/smtp/Makefile.in
+++ b/postfix/smtp/Makefile.in
@@ -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
diff --git a/postfix/smtpd/smtpd_chat.c b/postfix/smtpd/smtpd_chat.c
index 95d9d9b11..cd1009b25 100644
--- a/postfix/smtpd/smtpd_chat.c
+++ b/postfix/smtpd/smtpd_chat.c
@@ -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);
}
diff --git a/postfix/spawn/Makefile.in b/postfix/spawn/Makefile.in
index d535d6df0..536edc19d 100644
--- a/postfix/spawn/Makefile.in
+++ b/postfix/spawn/Makefile.in
@@ -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