From acf4faee9202d67da43fc254a42450ea9eb9e5c9 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Fri, 5 May 2000 00:00:00 +0000 Subject: [PATCH] snapshot-20000505 --- postfix/HISTORY | 6 + postfix/Makefile.in | 4 +- postfix/conf/master.cf | 1 + postfix/global/mail_params.h | 54 ++++++ postfix/global/mail_version.h | 2 +- postfix/html/Makefile.in | 7 +- postfix/html/delivering.html | 10 +- postfix/html/lmtp.8.html | 332 ++++++++++++++++++++++++++++++++ postfix/html/smtp.8.html | 32 +-- postfix/lmtp/Makefile.in | 153 +++++++++++++++ postfix/lmtp/fixnames | 5 +- postfix/lmtp/global-patch | 65 ------- postfix/lmtp/lmtp.c | 257 ++++++++---------------- postfix/lmtp/lmtp.h | 33 +--- postfix/lmtp/lmtp_addr.c | 23 ++- postfix/lmtp/lmtp_chat.c | 33 ++-- postfix/lmtp/lmtp_connect.c | 181 ++++------------- postfix/lmtp/lmtp_proto.c | 98 +++++----- postfix/lmtp/lmtp_session.c | 89 ++++----- postfix/lmtp/lmtp_state.c | 19 +- postfix/lmtp/lmtp_trouble.c | 12 +- postfix/lmtp/man-patch | 218 --------------------- postfix/man/Makefile.in | 69 +++---- postfix/man/man8/lmtp.8 | 214 ++++++++++++++++++++ postfix/man/man8/smtp.8 | 1 + postfix/master/multi_server.c | 12 +- postfix/master/single_server.c | 12 +- postfix/master/trigger_server.c | 12 +- postfix/smtp/Makefile.in | 1 - postfix/smtpd/smtpd_chat.c | 4 +- postfix/spawn/Makefile.in | 1 + 31 files changed, 1122 insertions(+), 838 deletions(-) create mode 100644 postfix/html/lmtp.8.html delete mode 100644 postfix/lmtp/global-patch delete mode 100644 postfix/lmtp/man-patch create mode 100644 postfix/man/man8/lmtp.8 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