]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3-20051208
authorWietse Venema <wietse@porcupine.org>
Thu, 8 Dec 2005 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:31:52 +0000 (06:31 +0000)
68 files changed:
postfix/HISTORY
postfix/Makefile.in
postfix/RELEASE_NOTES
postfix/conf/postfix-files
postfix/html/Makefile.in
postfix/html/lmtp.8.html [changed from file to symlink]
postfix/html/postconf.5.html
postfix/html/postfix-manuals.html
postfix/html/postfix.1.html
postfix/html/postsuper.1.html
postfix/html/smtp.8.html
postfix/makedefs
postfix/man/Makefile.in
postfix/man/man1/postfix.1
postfix/man/man1/postsuper.1
postfix/man/man5/postconf.5
postfix/man/man8/lmtp.8
postfix/man/man8/smtp.8
postfix/mantools/postlink
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/deliver_pass.c
postfix/src/global/deliver_request.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/scache.h
postfix/src/global/scache_clnt.c
postfix/src/lmtp/.indent.pro [deleted symlink]
postfix/src/lmtp/.printfck [deleted file]
postfix/src/lmtp/Makefile.in [deleted file]
postfix/src/lmtp/lmtp.c [deleted file]
postfix/src/lmtp/lmtp.h [deleted file]
postfix/src/lmtp/lmtp_addr.c [deleted file]
postfix/src/lmtp/lmtp_addr.h [deleted file]
postfix/src/lmtp/lmtp_chat.c [deleted file]
postfix/src/lmtp/lmtp_connect.c [deleted file]
postfix/src/lmtp/lmtp_dsn.c [deleted file]
postfix/src/lmtp/lmtp_proto.c [deleted file]
postfix/src/lmtp/lmtp_rcpt.c [deleted file]
postfix/src/lmtp/lmtp_sasl.h [deleted file]
postfix/src/lmtp/lmtp_sasl_glue.c [deleted file]
postfix/src/lmtp/lmtp_sasl_proto.c [deleted file]
postfix/src/lmtp/lmtp_session.c [deleted file]
postfix/src/lmtp/lmtp_state.c [deleted file]
postfix/src/lmtp/lmtp_trouble.c [deleted file]
postfix/src/postfix/postfix.c
postfix/src/postsuper/postsuper.c
postfix/src/scache/scache.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/lmtp_params.c [new file with mode: 0644]
postfix/src/smtp/smtp-only [new file with mode: 0644]
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_dsn.c
postfix/src/smtp/smtp_params.c [new file with mode: 0644]
postfix/src/smtp/smtp_proto.c
postfix/src/smtp/smtp_reuse.c
postfix/src/smtp/smtp_reuse.h
postfix/src/smtp/smtp_sasl_glue.c
postfix/src/smtp/smtp_state.c
postfix/src/smtpstone/qmqp-sink.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/util/Makefile.in
postfix/src/util/attr_clnt.c
postfix/src/util/auto_clnt.c
postfix/src/util/auto_clnt.h
postfix/src/util/unix_connect.c

index 7966419ea92639dfba99cac71e598785fa7eac0e..a80b68ad87aae732ed4eec14325a6d560738358b 100644 (file)
@@ -11492,6 +11492,57 @@ Apologies for any names omitted.
        Bugfix: the 20051128 code move for "smtpd_end_of_data_restrictions"
        broke "postsuper -r".
 
+20051202-3
+
+       Cleanup: the SMTP client now also implements the LMTP
+       protocol.  Files: smtp/smtp.c, smtp/smtp_connect.c,
+       smtp/smtp_proto.c, smtp/smtp_dsn.c, smtp_state.c,
+       smtp_sasl_glue.c.
+
+       As before, the LMTP behavior is controlled with parameters
+       named lmtp_xxx instead of smtp_xxx.  However there are now
+       a lot more lmtp_xxx parameters :-) With few exceptions, all
+       SMTP features are now also available with LMTP. The exceptions
+       are related to the HELO and EHLO commands, which exist in
+       SMTP only. There are equivalent LHLO command parameters
+       where it makes sense.
+
+20051206
+
+       SMTP+LMTP client connection management code rewritten to
+       support UNIX-domain socket connections.
+
+20051207
+
+       Bugfix: race condition in the connection caching protocol,
+       found while adding connection caching for UNIX-domain sockets
+       (used for LMTP delivery).  This was introduced with the
+       20050706 workaround, and may the same problem that Jussi
+       Silvennoinen experienced (in Postfix 2.2.6) with SMTP after
+       an upgrade.  Files: scache/scache.c.
+
+       Bugfix: smtp-sink and qmqp-sink didn't ignore SIGPIPE.
+
+20051208
+
+       Robustness: reduced timeouts in the connection caching
+       client, so that a malfunctioning service does not prevent
+       mail delivery. This uses similar code that already exists
+       for the anvil(8) client and the tlsmgr(8) client. Files:
+       global/scache_clnt.c, smtp/smtp.c.
+
+       To make reduced connection caching client timeouts possible,
+       connection management was moved from the attr_clnt(3) module
+       to the auto_clnt(3) module where it belongs. The auto_clnt(3)
+       module is now a full alternative for the clnt_stream(3)
+       module. Files: util/auto_clnt.c, util/attr_clnt.c.
+
+       Bugfix: the best_mx_transport, mailbox_transport and
+       fallback_transport features did not write a per-recipient
+       defer logfile record when the target delivery agent was
+       broken.  This the analog of queue manager bugfix 20051119.
+       Files: global/deliver_pass.c.
+       
 Open problems:
 
        "postsuper -r" no longer resets the message arrival time,
index 6ff54224df0d52e58fb0bfdf138bbbc0789f7c07..a5a7ecdd4076c79a38de740b6c66ab0a82170b86 100644 (file)
@@ -3,7 +3,7 @@ WARN    = -Wmissing-prototypes -Wformat
 OPTS   = 'CC=$(CC)'
 DIRS   = src/util src/global src/dns src/tls src/master src/postfix src/smtpstone \
        src/sendmail src/error src/pickup src/cleanup src/smtpd src/local \
-       src/lmtp src/trivial-rewrite src/qmgr src/oqmgr src/smtp src/bounce \
+       src/trivial-rewrite src/qmgr src/oqmgr src/smtp src/bounce \
        src/pipe src/showq src/postalias src/postcat src/postconf src/postdrop \
        src/postkick src/postlock src/postlog src/postmap src/postqueue \
        src/postsuper src/qmqpd src/spawn src/flush src/verify \
index d3ff5ff4322fd0fc27d43adfc3d4a4abcae94a07..c479bb59423be023ad5df98013b362cf65f82d4e 100644 (file)
@@ -17,6 +17,27 @@ Incompatibility with Postfix 2.1 and earlier
 If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2
 before proceeding.
 
+Incompatibility with snapshot 20051208
+======================================
+
+The fallback_relay feature is renamed to smtp_fallback_relay, to
+make clear that the combined SMTP+LMTP client uses this setting
+only for SMTP deliveries. The old name still works.
+
+The LMTP client now reports the server as "myhostname[/path/name]".
+With the real server hostname in delivery status reports, the
+information will be more useful.
+
+Major changes with snapshot 20051208
+====================================
+
+The SMTP client now implements the LMTP protocol.  Most but not all
+smtp_xxx parameters have an lmtp_xxx "ghost" parameter.  This means
+there are lot of new LMTP features, including support for TLS and
+for the shared connection cache. There are no lmtp_xxx "ghost"
+parameters for the HELO or EHLO commands, because those commands
+exist only in SMTP.
+
 Incompatibility with snapshot 20051202
 ======================================
 
index ee99c10ee01676cf91cd7343ab7945a6f9840347..118988a13291b3a990af6ee2ade3947e02ae6937 100644 (file)
@@ -67,7 +67,7 @@ $daemon_directory/cleanup:f:root:-:755
 $daemon_directory/discard:f:root:-:755
 $daemon_directory/error:f:root:-:755
 $daemon_directory/flush:f:root:-:755
-$daemon_directory/lmtp:f:root:-:755
+#$daemon_directory/lmtp:f:root:-:755
 $daemon_directory/local:f:root:-:755
 $daemon_directory/master:f:root:-:755
 $daemon_directory/oqmgr:f:root:-:755
@@ -86,6 +86,7 @@ $daemon_directory/trivial-rewrite:f:root:-:755
 $daemon_directory/verify:f:root:-:755
 $daemon_directory/virtual:f:root:-:755
 $daemon_directory/nqmgr:h:$daemon_directory/qmgr
+$daemon_directory/lmtp:h:$daemon_directory/smtp
 $command_directory/postalias:f:root:-:755
 $command_directory/postcat:f:root:-:755
 $command_directory/postconf:f:root:-:755
index 2f8100480e8b8dbc83086e9d5733376539e88d4d..77702414674eb503a9445c6b252304e07d5e3d5c 100644 (file)
@@ -68,9 +68,9 @@ scache.8.html: ../src/scache/scache.c
        PATH=../mantools:$$PATH; \
        srctoman $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
 
-lmtp.8.html: ../src/lmtp/lmtp.c
-       PATH=../mantools:$$PATH; \
-       srctoman $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
+lmtp.8.html: smtp.8.html
+       rm -f $@
+       ln -s $? $@
 
 local.8.html: ../src/local/local.c
        PATH=../mantools:$$PATH; \
@@ -192,7 +192,6 @@ sendmail.1.html: ../src/sendmail/sendmail.c
        srctoman $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
 
 mailq.1.html: sendmail.1.html
-       PATH=../mantools:$$PATH; \
        rm -f $@
        ln -s $? $@
 
deleted file mode 100644 (file)
index a8b4ab2cdf90cb08f2daf1e1263586898979989c..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,305 +0,0 @@
-<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
-        "http://www.w3.org/TR/html4/loose.dtd">
-<html> <head>
-<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
-<title> Postfix manual - lmtp(8) </title>
-</head> <body> <pre>
-LMTP(8)                                                                LMTP(8)
-
-<b>NAME</b>
-       lmtp - Postfix local delivery via LMTP
-
-<b>SYNOPSIS</b>
-       <b>lmtp</b> [generic Postfix daemon options]
-
-<b>DESCRIPTION</b>
-       The  LMTP  client processes message delivery requests from
-       the queue manager. Each request specifies a queue file,  a
-       sender address, a domain or host to deliver to, and recip-
-       ient information.  This program expects to be run from the
-       <a href="master.8.html"><b>master</b>(8)</a> process manager.
-
-       The  LMTP  client updates the queue file and marks recipi-
-       ents as finished, or it informs  the  queue  manager  that
-       delivery  should  be tried again at a later time. Delivery
-       status reports are sent  to  the  <a href="bounce.8.html"><b>bounce</b>(8)</a>,  <a href="defer.8.html"><b>defer</b>(8)</a>  or
-       <a href="trace.8.html"><b>trace</b>(8)</a> daemon as appropriate.
-
-       The  LMTP  client connects to the destination specified in
-       the message delivery  request.  The  destination,  usually
-       specified in the Postfix <a href="transport.5.html"><b>transport</b>(5)</a> table, has the form:
-
-       <b>unix</b>:<i>pathname</i>
-              Connect to the local  UNIX-domain  server  that  is
-              bound  to  the  specified  <i>pathname</i>. If the process
-              runs chrooted, an absolute pathname is  interpreted
-              relative to the changed root directory.
-
-       <b>inet</b>:<i>host</i>, <b>inet:</b><i>host</i>:<i>port</i> (symbolic host)
-
-       <b>inet</b>:[<i>addr</i>], <b>inet</b>:[<i>addr</i>]:<i>port</i> (numeric host)
-              Connect to the specified IPV4 TCP port on the spec-
-              ified local or remote host. If no  port  is  speci-
-              fied,  connect  to the port defined as <b>lmtp</b> in <b>ser-</b>
-              <b>vices</b>(4).   If  no  such  service  is  found,   the
-              <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a></b>   configuration   parameter  (default
-              value of 24) will be used.
-
-              The  LMTP  client  does  not   perform   MX   (mail
-              exchanger) lookups since those are defined only for
-              mail delivery via SMTP.
-
-       If  neither  <b>unix:</b>  nor  <b>inet:</b>  are  specified,  <b>inet:</b>  is
-       assumed.
-
-<b>SECURITY</b>
-       The LMTP client is moderately security-sensitive. It talks
-       to LMTP servers and to DNS servers  on  the  network.  The
-       LMTP client can be run chrooted at fixed low privilege.
-
-<b>STANDARDS</b>
-       <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
-       <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
-       <a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
-       <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
-       <a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
-       <a href="http://www.faqs.org/rfcs/rfc2034.html">RFC 2034</a> (Enhanced Status codes)
-       <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
-       <a href="http://www.faqs.org/rfcs/rfc2821.html">RFC 2821</a> (SMTP protocol)
-       <a href="http://www.faqs.org/rfcs/rfc2920.html">RFC 2920</a> (SMTP Pipelining)
-       <a href="http://www.faqs.org/rfcs/rfc3463.html">RFC 3463</a> (Enhanced Status codes)
-
-<b>DIAGNOSTICS</b>
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
-       can move them to the <b>corrupt</b> queue for further inspection.
-
-       Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b>  parameter,
-       the  postmaster is notified of bounces, protocol problems,
-       and of other trouble.
-
-<b>CONFIGURATION PARAMETERS</b>
-       Changes to <b>main.cf</b> are picked up automatically, as <a href="lmtp.8.html"><b>lmtp</b>(8)</a>
-       processes  run  for only a limited amount of time. Use the
-       command "<b>postfix reload</b>" to speed up a change.
-
-       The text below provides  only  a  parameter  summary.  See
-       <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
-
-<b>COMPATIBILITY CONTROLS</b>
-       <b><a href="postconf.5.html#lmtp_skip_quit_response">lmtp_skip_quit_response</a> (no)</b>
-              Wait for the response to the LMTP QUIT command.
-
-<b>TROUBLE SHOOTING CONTROLS</b>
-       <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The  increment  in  verbose  logging  level  when a
-              remote client or server matches a  pattern  in  the
-              <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
-
-       <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of remote client or server hostname
-              or network address patterns that cause the  verbose
-              logging  level  to increase by the amount specified
-              in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
-
-       <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The recipient  of  postmaster  notifications  about
-              mail  delivery  problems that are caused by policy,
-              resource, software or protocol errors.
-
-       <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
-              The list of error classes that are reported to  the
-              postmaster.
-
-<b>EXTERNAL CONTENT INSPECTION CONTROLS</b>
-       Available in Postfix version 2.1 and later:
-
-       <b><a href="postconf.5.html#lmtp_send_xforward_command">lmtp_send_xforward_command</a> (no)</b>
-              Send  an  XFORWARD  command to the LMTP server when
-              the LMTP LHLO server  response  announces  XFORWARD
-              support.
-
-<b>SASL AUTHENTICATION CONTROLS</b>
-       <b><a href="postconf.5.html#lmtp_sasl_auth_enable">lmtp_sasl_auth_enable</a> (no)</b>
-              Enable  SASL  authentication  in  the  Postfix LMTP
-              client.
-
-       <b><a href="postconf.5.html#lmtp_sasl_password_maps">lmtp_sasl_password_maps</a> (empty)</b>
-              Optional LMTP client lookup tables with  one  user-
-              name:password entry per host or domain.
-
-       <b><a href="postconf.5.html#lmtp_sasl_security_options">lmtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
-              What  authentication  mechanisms  the  Postfix LMTP
-              client is allowed to use.
-
-<b>RESOURCE AND RATE CONTROLS</b>
-       In the text below, <i>transport</i> is the name of the service as
-       specified in the <b>master.cf</b> file.
-
-       <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep Postfix LMTP client connections open for up to
-              $<a href="postconf.5.html#max_idle">max_idle</a> seconds.
-
-       <i>transport</i><b>_destination_concurrency_limit ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destina</a>-</b>
-       <b><a href="postconf.5.html#default_destination_concurrency_limit">tion_concurrency_limit</a>)</b>
-              Limit the number of parallel deliveries to the same
-              destination via this mail delivery transport.
-
-       <i>transport</i><b>_destination_recipient_limit   ($<a href="postconf.5.html#default_destination_recipient_limit">default_destina</a>-</b>
-       <b><a href="postconf.5.html#default_destination_recipient_limit">tion_recipient_limit</a>)</b>
-              Limit the number of recipients per message delivery
-              via this mail delivery transport.
-
-              This parameter  becomes  significant  if  the  LMTP
-              client  is  used  for  local  delivery.   Some LMTP
-              servers can optimize delivery of the  same  message
-              to multiple recipients. The default limit for local
-              mail delivery is 1.
-
-              Setting  this  parameter  to  0  will  lead  to  an
-              unbounded  number of recipients per delivery.  How-
-              ever, this could be risky since  it  may  make  the
-              machine  vulnerable  to running out of resources if
-              messages are encountered with an inordinate  number
-              of  recipients.   Exercise  care  when setting this
-              parameter.
-
-       <b><a href="postconf.5.html#lmtp_connect_timeout">lmtp_connect_timeout</a> (0s)</b>
-              The LMTP client time limit  for  completing  a  TCP
-              connection,  or  zero  (use  the  operating  system
-              built-in time limit).
-
-       <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
-              The LMTP client time limit for receiving  the  LMTP
-              greeting banner.
-
-       <b><a href="postconf.5.html#lmtp_xforward_timeout">lmtp_xforward_timeout</a> (300s)</b>
-              The LMTP client time limit for sending the XFORWARD
-              command, and for receiving the server response.
-
-       <b><a href="postconf.5.html#lmtp_mail_timeout">lmtp_mail_timeout</a> (300s)</b>
-              The LMTP client time limit  for  sending  the  MAIL
-              FROM   command,   and   for  receiving  the  server
-              response.
-
-       <b><a href="postconf.5.html#lmtp_rcpt_timeout">lmtp_rcpt_timeout</a> (300s)</b>
-              The LMTP client time limit for sending the RCPT  TO
-              command, and for receiving the server response.
-
-       <b><a href="postconf.5.html#lmtp_data_init_timeout">lmtp_data_init_timeout</a> (120s)</b>
-              The  LMTP  client  time  limit for sending the LMTP
-              DATA  command,  and  for   receiving   the   server
-              response.
-
-       <b><a href="postconf.5.html#lmtp_data_xfer_timeout">lmtp_data_xfer_timeout</a> (180s)</b>
-              The  LMTP  client  time  limit for sending the LMTP
-              message content.
-
-       <b><a href="postconf.5.html#lmtp_data_done_timeout">lmtp_data_done_timeout</a> (600s)</b>
-              The LMTP client time limit  for  sending  the  LMTP
-              ".", and for receiving the server response.
-
-       <b><a href="postconf.5.html#lmtp_rset_timeout">lmtp_rset_timeout</a> (20s)</b>
-              The  LMTP  client  time  limit for sending the RSET
-              command, and for receiving the server response.
-
-       <b><a href="postconf.5.html#lmtp_quit_timeout">lmtp_quit_timeout</a> (300s)</b>
-              The LMTP client time limit  for  sending  the  QUIT
-              command, and for receiving the server response.
-
-<b>MISCELLANEOUS CONTROLS</b>
-       <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
-              master.cf configuration files.
-
-       <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process may take  to
-              handle  a  request  before  it  is  terminated by a
-              built-in watchdog timer.
-
-       <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number  of  digits  after  the  decimal
-              point when logging sub-second delay values.
-
-       <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
-              Disable  DNS  lookups  in the Postfix SMTP and LMTP
-              clients.
-
-       <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The time limit for sending or receiving information
-              over an internal communication channel.
-
-       <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
-              The  default  TCP port that the Postfix LMTP client
-              connects to.
-
-       <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time  that  an  idle  Postfix
-              daemon  process  waits for the next service request
-              before exiting.
-
-       <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
-              The maximal number of connection requests before  a
-              Postfix daemon process terminates.
-
-       <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The  process  ID  of  a  Postfix  command or daemon
-              process.
-
-       <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The process name of a  Postfix  command  or  daemon
-              process.
-
-       <b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
-              The  location of the Postfix top-level queue direc-
-              tory.
-
-       <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
-              The syslog facility of Postfix logging.
-
-       <b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
-              becomes, for example, "postfix/smtpd".
-
-<b>SEE ALSO</b>
-       <a href="bounce.8.html">bounce(8)</a>, delivery status reports
-       <a href="qmgr.8.html">qmgr(8)</a>, queue manager
-       <a href="postconf.5.html">postconf(5)</a>, configuration parameters
-       <a href="master.5.html">master(5)</a>, generic daemon options
-       services(4), Internet services and aliases
-       <a href="master.8.html">master(8)</a>, process manager
-       syslogd(8), system logging
-
-<b>README FILES</b>
-       <a href="LMTP_README.html">LMTP_README</a>, Postfix LMTP client howto
-       <a href="VIRTUAL_README.html">VIRTUAL_README</a>, virtual delivery agent howto
-
-<b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
-       software.
-
-<b>AUTHOR(S)</b>
-       Wietse Venema
-       IBM T.J. Watson Research
-       P.O. Box 704
-       Yorktown Heights, NY 10598, USA
-
-       Modifications for LMTP by:
-       Philip A. Prindeville
-       Mirapoint, Inc.
-       USA.
-
-       SASL support originally by:
-       Till Franke
-       SuSE Rhein/Main AG
-       65760 Eschborn, Germany
-
-       Additional work on LMTP by:
-       Amos Gouaux
-       University of Texas at Dallas
-       P.O. Box 830688, MC34
-       Richardson, TX 75083, USA
-
-                                                                       LMTP(8)
-</pre> </body> </html>
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..6ec40f8f3bd56658ec7fe5abcd171d3928f3905f
--- /dev/null
@@ -0,0 +1 @@
+smtp.8.html
\ No newline at end of file
index fa2eef1fd95cfd6feb15592b7a648d42b00e3acc..6f314d737e8e880e0339011831323c52a5aad102 100644 (file)
@@ -893,6 +893,14 @@ a "<a href="DATABASE_README.html">type:table</a>" lookup table is matched when a
 (the lookup result is ignored).  Continue long lines by starting the
 next line with whitespace.  </p>
 
+<p>
+Example:
+</p>
+
+<pre>
+<a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> = !www, static:all
+</pre>
+
 <p>
 This feature is available in Postfix 2.2 and later.
 </p>
@@ -1366,6 +1374,17 @@ requires that the directory is listed with the <a href="postconf.5.html#alternat
 parameter in the default main.cf file.  </p>
 
 
+</DD>
+
+<DT><b><a name="connection_cache_protocol_timeout">connection_cache_protocol_timeout</a>
+(default: 5s)</b></DT><DD>
+
+<p> Time limit for connection cache connect, send or receive
+operations.  The time limit is enforced in the client. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="connection_cache_service">connection_cache_service</a>
@@ -2299,11 +2318,12 @@ This feature was removed in Postfix version 2.1.
 
 <p>
 Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable.  </p>
+found or that are unreachable. With Postfix 2.3 this parameter
+is renamed to smtp_fallback_relay. </p>
 
 <p>
 By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred if a destination is unreachable.
+not found, and delivery is deferred when a destination is unreachable.
 </p>
 
 <p> The fallback relays must be SMTP destinations. Specify a domain,
@@ -2311,7 +2331,8 @@ host, host:port, [host]:port, [address] or [address]:port; the form
 [host] turns off MX lookups.  If you specify multiple SMTP
 destinations, Postfix will try them in the specified order.  </p>
 
-<p> Note: do not use the <a href="postconf.5.html#fallback_relay">fallback_relay</a> feature when relaying mail
+<p> Note: before Postfix 2.2, do not use the <a href="postconf.5.html#fallback_relay">fallback_relay</a> feature
+when relaying mail
 for a backup or primary MX domain. Mail would loop between the
 Postfix MX host and the <a href="postconf.5.html#fallback_relay">fallback_relay</a> host when the final destination
 is unavailable. </p>
@@ -2328,7 +2349,8 @@ as the right-hand side for backup or primary MX domain entries.
 
 </ul>
 
-<p> These are default settings in Postfix version 2.2 and later.
+<p> Postfix version 2.2 and later will not use the <a href="postconf.5.html#fallback_relay">fallback_relay</a> feature
+for destinations that it is MX host for.
 </p>
 
 
@@ -2984,6 +3006,28 @@ This feature is available in Postfix 2.1 and later.
 this length; upon delivery, long lines are reconstructed.  </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_bind_address">lmtp_bind_address</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_bind_address6">lmtp_bind_address6</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_cache_connection">lmtp_cache_connection</a>
@@ -3051,6 +3095,39 @@ Example:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="lmtp_connection_cache_destinations">lmtp_connection_cache_destinations</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_connection_cache_on_demand">lmtp_connection_cache_on_demand</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_connection_reuse_time_limit">lmtp_connection_reuse_time_limit</a>
+(default: 300s)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_data_done_timeout">lmtp_data_done_timeout</a>
@@ -3100,6 +3177,17 @@ The default time unit is s (seconds).
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_defer_if_no_mx_address_found">lmtp_defer_if_no_mx_address_found</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_defer_if_no_mx_address_found">smtp_defer_if_no_mx_address_found</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_destination_concurrency_limit">lmtp_destination_concurrency_limit</a>
@@ -3128,20 +3216,127 @@ concurrency per recipient.  </p>
 
 </DD>
 
-<DT><b><a name="lmtp_lhlo_timeout">lmtp_lhlo_timeout</a>
-(default: 300s)</b></DT><DD>
+<DT><b><a name="lmtp_discard_lhlo_keyword_address_maps">lmtp_discard_lhlo_keyword_address_maps</a>
+(default: empty)</b></DT><DD>
+
+<p> Lookup tables, indexed by the remote LMTP server address, with
+case insensitive lists of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server. See lmtp_discard_lhlo_keywords for
+details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
 
-<p> The LMTP client time limit for receiving the LMTP greeting
-banner.  When the server drops the connection without sending a
-greeting banner, or when it sends no greeting banner within the
-deadline, the LMTP client tries the next address on the mail
-exchanger list.  </p>
+
+</DD>
+
+<DT><b><a name="lmtp_discard_lhlo_keywords">lmtp_discard_lhlo_keywords</a>
+(default: $<a href="postconf.5.html#myhostname">myhostname</a>)</b></DT><DD>
+
+<p> A case insensitive list of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
+this action from being logged. </p>
+
+<li> <p> Use the lmtp_discard_lhlo_keyword_address_maps feature to
+discard LHLO keywords selectively. </p>
+
+</ul>
+
+
+</DD>
+
+<DT><b><a name="lmtp_enforce_tls">lmtp_enforce_tls</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_generic_maps">lmtp_generic_maps</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_host_lookup">lmtp_host_lookup</a>
+(default: dns)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_lhlo_name">lmtp_lhlo_name</a>
+(default: $<a href="postconf.5.html#myhostname">myhostname</a>)</b></DT><DD>
 
 <p>
-Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
-The default time unit is s (seconds).
+The hostname to send in the LMTP LHLO command.
+</p>
+
+<p>
+The default value is the machine hostname.  Specify a hostname or
+[ip.add.re.ss].
 </p>
 
+<p>
+This information can be specified in the main.cf file for all LMTP
+clients, or it can be specified in the master.cf file for a specific
+client, for example:
+</p>
+
+<pre>
+  /etc/postfix/master.cf:
+        mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com
+</pre>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_lhlo_timeout">lmtp_lhlo_timeout</a>
+(default: 300s)</b></DT><DD>
+
+<p> The LMTP client time limit for sending the LHLO command, and
+for receiving the initial server response. </p>
+
+<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks).  The default time unit is s (seconds).  </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_line_length_limit">lmtp_line_length_limit</a>
+(default: 990)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_line_length_limit">smtp_line_length_limit</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
 
 </DD>
 
@@ -3159,6 +3354,50 @@ The default time unit is s (seconds).
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_mx_address_limit">lmtp_mx_address_limit</a>
+(default: 5)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_mx_session_limit">lmtp_mx_session_limit</a>
+(default: 2)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_pix_workaround_delay_time">lmtp_pix_workaround_delay_time</a>
+(default: 10s)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_pix_workaround_delay_time">smtp_pix_workaround_delay_time</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_pix_workaround_threshold_time">lmtp_pix_workaround_threshold_time</a>
+(default: 500s)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_pix_workaround_threshold_time">smtp_pix_workaround_threshold_time</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_quit_timeout">lmtp_quit_timeout</a>
@@ -3175,6 +3414,28 @@ The default time unit is s (seconds).
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_quote_rfc821_envelope">lmtp_quote_rfc821_envelope</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_quote_rfc821_envelope">smtp_quote_rfc821_envelope</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_randomize_addresses">lmtp_randomize_addresses</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_randomize_addresses">smtp_randomize_addresses</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_rcpt_timeout">lmtp_rcpt_timeout</a>
@@ -3217,6 +3478,17 @@ Enable SASL authentication in the Postfix LMTP client.
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_sasl_mechanism_filter">lmtp_sasl_mechanism_filter</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_sasl_password_maps">lmtp_sasl_password_maps</a>
@@ -3272,6 +3544,17 @@ Example:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="lmtp_sasl_tls_security_options">lmtp_sasl_tls_security_options</a>
+(default: $var_lmtp_sasl_opts)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_security_options</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_send_xforward_command">lmtp_send_xforward_command</a>
@@ -3292,6 +3575,28 @@ This feature is available in Postfix 2.1 and later.
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_sender_dependent_authentication">lmtp_sender_dependent_authentication</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_skip_5xx_greeting">lmtp_skip_5xx_greeting</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_skip_quit_response">lmtp_skip_quit_response</a>
@@ -3302,6 +3607,17 @@ Wait for the response to the LMTP QUIT command.
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_starttls_timeout">lmtp_starttls_timeout</a>
+(default: 300s)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_starttls_timeout">smtp_starttls_timeout</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_tcp_port">lmtp_tcp_port</a>
@@ -3312,6 +3628,61 @@ The default TCP port that the Postfix LMTP client connects to.
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_tls_enforce_peername">lmtp_tls_enforce_peername</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_tls_note_starttls_offer">lmtp_tls_note_starttls_offer</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_note_starttls_offer">smtp_tls_note_starttls_offer</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_tls_per_site">lmtp_tls_per_site</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_tls_scert_verifydepth">lmtp_tls_scert_verifydepth</a>
+(default: 5)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_scert_verifydepth">smtp_tls_scert_verifydepth</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_use_tls">lmtp_use_tls</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_xforward_timeout">lmtp_xforward_timeout</a>
@@ -5786,7 +6157,7 @@ Example:
 
 <p> A sender-dependent override for the global <a href="postconf.5.html#relayhost">relayhost</a> parameter
 setting. The tables are searched by the sender address and by the
-sender @domain. This information is overruled with <a href="postconf.5.html#relay_transport">relay_transport</a>,
+@domain. This information is overruled with <a href="postconf.5.html#relay_transport">relay_transport</a>,
 <a href="postconf.5.html#default_transport">default_transport</a> and with the <a href="transport.5.html">transport(5)</a> table. </p>
 
 <p>
@@ -5994,6 +6365,9 @@ IP address),
 [] or non-default TCP port), as specified in main.cf or in the
 transport map,
 
+<li> if mail is sent via a UNIX-domain socket: a pathname (without
+the unix: prefix),
+
 <li> a /file/name with domain names and/or <a href="postconf.5.html#relayhost">relay host</a> names as
 defined above,
 
@@ -6267,6 +6641,31 @@ provide valid server certificates.  Typical use is for clients that
 send all their email to a dedicated mailhub.  </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_fallback_relay">smtp_fallback_relay</a>
+(default: $<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b></DT><DD>
+
+<p>
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable. With Postfix 2.2 and earlier this
+parameter is called <a href="postconf.5.html#fallback_relay">fallback_relay</a>.  </p>
+
+<p>
+By default, mail is returned to the sender when a destination is
+not found, and delivery is deferred when a destination is unreachable.
+</p>
+
+<p> The fallback relays must be SMTP destinations. Specify a domain,
+host, host:port, [host]:port, [address] or [address]:port; the form
+[host] turns off MX lookups.  If you specify multiple SMTP
+destinations, Postfix will try them in the specified order.  </p>
+
+<p> To prevent mailer loops between MX hosts and fall-back hosts,
+Postfix version 2.3 and later will not use the smtp_fallback_relay
+feature for destinations that it is MX host for. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_generic_maps">smtp_generic_maps</a>
index ed013d06f3b9a5aff3cc4f085e6e35892bc68594..ac25aab95fa9648f120621ad9130c7a8f6150ba4 100644 (file)
@@ -182,8 +182,6 @@ the following convention:  </p>
 
 <li> <a href="flush.8.html">flush(8)</a>, Postfix fast ETRN service 
 
-<li> <a href="lmtp.8.html">lmtp(8)</a>, Postfix LMTP client 
-
 <li> <a href="local.8.html">local(8)</a>, Postfix local delivery agent 
 
 <li> <a href="master.8.html">master(8)</a>, Postfix master daemon 
@@ -204,7 +202,7 @@ the following convention:  </p>
 
 <li> <a href="showq.8.html">showq(8)</a>, list Postfix mail queue 
 
-<li> <a href="smtp.8.html">smtp(8)</a>, Postfix SMTP client 
+<li> <a href="smtp.8.html">smtp(8)</a>, <a href="lmtp.8.html">lmtp(8)</a>, Postfix SMTP+LMTP client 
 
 <li> <a href="smtpd.8.html">smtpd(8)</a>, Postfix SMTP server 
 
index 7dbcdf40fa49f86ee68b9db2973c95f994714929..fb225222e134b076e706eae3a6b72ec1a1fd3151 100644 (file)
@@ -244,7 +244,6 @@ POSTFIX(1)                                                          POSTFIX(1)
        <a href="discard.8.html">discard(8)</a>, Postfix discard delivery agent
        <a href="error.8.html">error(8)</a>, Postfix error delivery agent
        <a href="flush.8.html">flush(8)</a>, Postfix fast ETRN service
-       <a href="lmtp.8.html">lmtp(8)</a>, Postfix LMTP client
        <a href="local.8.html">local(8)</a>, Postfix local delivery agent
        <a href="master.8.html">master(8)</a>, Postfix master daemon
        <a href="qmgr.8.html">oqmgr(8)</a>, old Postfix queue manager
@@ -255,7 +254,7 @@ POSTFIX(1)                                                          POSTFIX(1)
        <a href="qmqpd.8.html">qmqpd(8)</a>, Postfix QMQP server
        <a href="scache.8.html">scache(8)</a>, Postfix connection cache manager
        <a href="showq.8.html">showq(8)</a>, list Postfix mail queue
-       <a href="smtp.8.html">smtp(8)</a>, Postfix SMTP client
+       <a href="smtp.8.html">smtp(8)</a>, <a href="lmtp.8.html">lmtp(8)</a>, Postfix SMTP+LMTP client
        <a href="smtpd.8.html">smtpd(8)</a>, Postfix SMTP server
        <a href="spawn.8.html">spawn(8)</a>, run non-Postfix server
        <a href="tlsmgr.8.html">tlsmgr(8)</a>, Postfix TLS cache and randomness manager
@@ -284,5 +283,20 @@ POSTFIX(1)                                                          POSTFIX(1)
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
+       SASL support originally by:
+       Till Franke
+       SuSE Rhein/Main AG
+       65760 Eschborn, Germany
+
+       LMTP support originally by:
+       Philip A. Prindeville
+       Mirapoint, Inc.
+       USA.
+
+       Amos Gouaux
+       University of Texas at Dallas
+       P.O. Box 830688, MC34
+       Richardson, TX 75083, USA
+
                                                                     POSTFIX(1)
 </pre> </body> </html>
index b0bfc515481ffe686b1300c3ec81169fc6fa4269..28e5cc5d95b836962f616b9342b2b6c810ad54fb 100644 (file)
@@ -45,136 +45,137 @@ POSTSUPER(1)                                                      POSTSUPER(1)
               delete  all  mail  with   exactly   one   recipient
               <b>user@example.com</b>:
 
-              mailq | tail +2 | awk  'BEGIN { RS = "" }
+              mailq | tail +2 | grep -v '^ *(' | awk  'BEGIN { RS
+              = "" }
                   # $7=sender, $8=recipient1, $9=recipient2
                   { if ($8 == "user@example.com" &amp;&amp; $9 == "")
                         print $1 }
               ' | tr -d '*!' | postsuper -d -
 
               Specify <b>-d ALL</b> to remove all messages; for example,
-              specify <b>-d ALL  deferred</b>  to  delete  mail  in  the
-              <b>deferred</b>  queue.  As a safety measure, the word <b>ALL</b>
+              specify  <b>-d  ALL  deferred</b>  to  delete  mail in the
+              <b>deferred</b> queue.  As a safety measure, the word  <b>ALL</b>
               must be specified in upper case.
 
-              Warning: Postfix queue IDs are reused.  There is  a
-              very  small  possibility that postsuper deletes the
-              wrong message file when it is  executed  while  the
+              Warning:  Postfix queue IDs are reused.  There is a
+              very small possibility that postsuper  deletes  the
+              wrong  message  file  when it is executed while the
               Postfix mail system is delivering mail.
 
               The scenario is as follows:
 
-              1)     The  Postfix  queue manager deletes the mes-
-                     sage that <a href="postsuper.1.html"><b>postsuper</b>(1)</a> is asked  to  delete,
+              1)     The Postfix queue manager deletes  the  mes-
+                     sage  that  <a href="postsuper.1.html"><b>postsuper</b>(1)</a> is asked to delete,
                      because Postfix is finished with the message
-                     (it is delivered, or it is returned  to  the
+                     (it  is  delivered, or it is returned to the
                      sender).
 
-              2)     New  mail  arrives,  and  the new message is
-                     given the same queue ID as the message  that
-                     <a href="postsuper.1.html"><b>postsuper</b>(1)</a>  is  supposed  to  delete.  The
-                     probability for reusing a deleted  queue  ID
+              2)     New mail arrives, and  the  new  message  is
+                     given  the same queue ID as the message that
+                     <a href="postsuper.1.html"><b>postsuper</b>(1)</a> is  supposed  to  delete.   The
+                     probability  for  reusing a deleted queue ID
                      is about 1 in 2**15 (the number of different
                      microsecond values that the system clock can
                      distinguish within a second).
 
-              3)     <a href="postsuper.1.html"><b>postsuper</b>(1)</a>   deletes   the   new  message,
-                     instead of the old message  that  it  should
+              3)     <a href="postsuper.1.html"><b>postsuper</b>(1)</a>  deletes   the   new   message,
+                     instead  of  the  old message that it should
                      have deleted.
 
        <b>-h</b> <i>queue</i><b>_</b><i>id</i>
-              Put  mail  "on  hold" so that no attempt is made to
-              deliver it.  Move one message with the named  queue
+              Put mail "on hold" so that no attempt  is  made  to
+              deliver  it.  Move one message with the named queue
               ID from the named mail queue(s) (default: <b>incoming</b>,
               <b>active</b> and <b>deferred</b>) to the <b>hold</b> queue.
 
-              If a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program  reads
+              If  a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program reads
               queue IDs from standard input.
 
-              Specify  <b>-h  ALL</b> to hold all messages; for example,
+              Specify <b>-h ALL</b> to hold all messages;  for  example,
               specify  <b>-h  ALL  deferred</b>  to  hold  mail  in  the
-              <b>deferred</b>  queue.  As a safety measure, the word <b>ALL</b>
+              <b>deferred</b> queue.  As a safety measure, the word  <b>ALL</b>
               must be specified in upper case.
 
-              Note: while mail is "on hold" it  will  not  expire
-              when  its  time  in  the  queue  exceeds  the <b><a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
+              Note:  while  mail  is "on hold" it will not expire
+              when its  time  in  the  queue  exceeds  the  <b><a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
               <b><a href="postconf.5.html#maximal_queue_lifetime">mal_queue_lifetime</a></b>  or  <b><a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b>  set-
-              ting.  It becomes subject to expiration after it is
+              ting. It becomes subject to expiration after it  is
               released from "hold".
 
        <b>-H</b> <i>queue</i><b>_</b><i>id</i>
               Release mail that was put "on hold".  Move one mes-
-              sage  with  the  named queue ID from the named mail
+              sage with the named queue ID from  the  named  mail
               queue(s) (default: <b>hold</b>) to the <b>deferred</b> queue.
 
-              If a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program  reads
+              If  a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program reads
               queue IDs from standard input.
 
-              Note:  use  "<b>postsuper -r</b>" to release mail that was
-              kept on hold for a significant fraction  of  <b>$<a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
+              Note: use "<b>postsuper -r</b>" to release mail  that  was
+              kept  on  hold for a significant fraction of <b>$<a href="postconf.5.html#maximal_queue_lifetime">maxi</a>-</b>
               <b><a href="postconf.5.html#maximal_queue_lifetime">mal_queue_lifetime</a></b>  or  <b>$<a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b>,  or
               longer.
 
-              Specify <b>-H ALL</b> to release  all  mail  that  is  "on
-              hold".   As  a safety measure, the word <b>ALL</b> must be
+              Specify  <b>-H  ALL</b>  to  release  all mail that is "on
+              hold".  As a safety measure, the word <b>ALL</b>  must  be
               specified in upper case.
 
-       <b>-p</b>     Purge old temporary files that are left over  after
+       <b>-p</b>     Purge  old temporary files that are left over after
               system or software crashes.
 
        <b>-r</b> <i>queue</i><b>_</b><i>id</i>
-              Requeue  the  message  with the named queue ID from
-              the named mail queue(s) (default:  <b>hold</b>,  <b>incoming</b>,
-              <b>active</b>  and  <b>deferred</b>).   To  requeue multiple mes-
+              Requeue the message with the named  queue  ID  from
+              the  named  mail queue(s) (default: <b>hold</b>, <b>incoming</b>,
+              <b>active</b> and <b>deferred</b>).   To  requeue  multiple  mes-
               sages, specify multiple <b>-r</b> command-line options.
 
               Alternatively, if a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the
               program reads queue IDs from standard input.
 
               Specify <b>-r ALL</b> to requeue all messages. As a safety
-              measure, the word <b>ALL</b> must be  specified  in  upper
+              measure,  the  word  <b>ALL</b> must be specified in upper
               case.
 
-              A  requeued message is moved to the <b>maildrop</b> queue,
-              from where it is copied by the pickup daemon  to  a
-              new  file whose name is guaranteed to match the new
+              A requeued message is moved to the <b>maildrop</b>  queue,
+              from  where  it is copied by the pickup daemon to a
+              new file whose name is guaranteed to match the  new
               queue file inode number. The new queue file is sub-
-              jected  again to mail address rewriting and substi-
+              jected again to mail address rewriting and  substi-
               tution. This is useful when rewriting rules or vir-
               tual mappings have changed.
 
-              Warning:  Postfix queue IDs are reused.  There is a
-              very small possibility that  <a href="postsuper.1.html"><b>postsuper</b>(1)</a>  requeues
-              the  wrong  message  file when it is executed while
-              the Postfix mail system is  running,  but  no  harm
+              Warning: Postfix queue IDs are reused.  There is  a
+              very  small  possibility that <a href="postsuper.1.html"><b>postsuper</b>(1)</a> requeues
+              the wrong message file when it  is  executed  while
+              the  Postfix  mail  system  is running, but no harm
               should be done.
 
-       <b>-s</b>     Structure  check and structure repair.  This should
+       <b>-s</b>     Structure check and structure repair.  This  should
               be done once before Postfix startup.
 
-              <b>o</b>      Rename files whose name does not  match  the
+              <b>o</b>      Rename  files  whose name does not match the
                      message file inode number. This operation is
-                     necessary after restoring a mail queue  from
+                     necessary  after restoring a mail queue from
                      a different machine, or from backup media.
 
               <b>o</b>      Move queue files that are in the wrong place
                      in the file system hierarchy and remove sub-
                      directories that are no longer needed.  File
-                     position rearrangements are necessary  after
+                     position  rearrangements are necessary after
                      a  change  in  the  <b><a href="postconf.5.html#hash_queue_names">hash_queue_names</a></b>  and/or
                      <b><a href="postconf.5.html#hash_queue_depth">hash_queue_depth</a></b> configuration parameters.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple  <b>-v</b>  options  make  the software increasingly
+              tiple <b>-v</b> options  make  the  software  increasingly
               verbose.
 
 <b>DIAGNOSTICS</b>
-       Problems are reported to the standard error stream and  to
+       Problems  are reported to the standard error stream and to
        <b>syslogd</b>(8).
 
-       <a href="postsuper.1.html"><b>postsuper</b>(1)</a>  reports  the number of messages deleted with
-       <b>-d</b>, the number of messages requeued with <b>-r</b>, and the  num-
-       ber  of  messages whose queue file name was fixed with <b>-s</b>.
-       The report is written to the standard error stream and  to
+       <a href="postsuper.1.html"><b>postsuper</b>(1)</a> reports the number of messages  deleted  with
+       <b>-d</b>,  the number of messages requeued with <b>-r</b>, and the num-
+       ber of messages whose queue file name was fixed  with  <b>-s</b>.
+       The  report is written to the standard error stream and to
        <b>syslogd</b>(8).
 
 <b>ENVIRONMENT</b>
@@ -182,37 +183,37 @@ POSTSUPER(1)                                                      POSTSUPER(1)
               Directory with the <b>main.cf</b> file.
 
 <b>BUGS</b>
-       Mail  that  is  not sanitized by Postfix (i.e. mail in the
+       Mail that is not sanitized by Postfix (i.e.  mail  in  the
        <b>maildrop</b> queue) cannot be placed "on hold".
 
 <b>CONFIGURATION PARAMETERS</b>
-       The following <b>main.cf</b> parameters are  especially  relevant
+       The  following  <b>main.cf</b> parameters are especially relevant
        to this program.  The text below provides only a parameter
-       summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including  exam-
+       summary.  See <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including exam-
        ples.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
+              The default location of  the  Postfix  main.cf  and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#hash_queue_depth">hash_queue_depth</a> (1)</b>
-              The number of subdirectory levels for queue  direc-
-              tories  listed with the <a href="postconf.5.html#hash_queue_names">hash_queue_names</a> parameter.
+              The  number of subdirectory levels for queue direc-
+              tories listed with the <a href="postconf.5.html#hash_queue_names">hash_queue_names</a>  parameter.
 
        <b><a href="postconf.5.html#hash_queue_names">hash_queue_names</a> (deferred, defer)</b>
-              The names  of  queue  directories  that  are  split
+              The  names  of  queue  directories  that  are split
               across multiple subdirectory levels.
 
        <b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
-              The  location of the Postfix top-level queue direc-
+              The location of the Postfix top-level queue  direc-
               tory.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
+              The  mail  system  name  that  is  prepended to the
+              process name in syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
 <b>SEE ALSO</b>
@@ -220,7 +221,7 @@ POSTSUPER(1)                                                      POSTSUPER(1)
        <a href="postqueue.1.html">postqueue(1)</a>, unprivileged queue operations
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 65b2ff9dbea42b4664266805422fc575b6a6b6b8..78f1ca8b360ca7d263c5cbd679065c6d4a9f7d58 100644 (file)
@@ -7,47 +7,85 @@
 SMTP(8)                                                                SMTP(8)
 
 <b>NAME</b>
-       smtp - Postfix SMTP client
+       smtp - Postfix SMTP+LMTP client
 
 <b>SYNOPSIS</b>
        <b>smtp</b> [generic Postfix daemon options]
 
 <b>DESCRIPTION</b>
-       The   Postfix   SMTP  client  processes  message  delivery
-       requests from the queue manager. Each request specifies  a
-       queue  file, a sender address, a domain or host to deliver
+       The  Postfix SMTP+LMTP client implements the SMTP and LMTP
+       mail delivery protocols.  It  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 <a href="master.8.html"><b>master</b>(8)</a> process manager.
 
-       The  SMTP  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
-       status reports are sent  to  the  <a href="bounce.8.html"><b>bounce</b>(8)</a>,  <a href="defer.8.html"><b>defer</b>(8)</a>  or
-       <a href="trace.8.html"><b>trace</b>(8)</a> daemon as appropriate.
+       The SMTP+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   status  reports  are  sent  to  the  <a href="bounce.8.html"><b>bounce</b>(8)</a>,
+       <a href="defer.8.html"><b>defer</b>(8)</a> or <a href="trace.8.html"><b>trace</b>(8)</a> daemon as appropriate.
 
-       The  SMTP  client  looks  up  a  list  of  mail  exchanger
-       addresses for the destination  host,  sorts  the  list  by
-       preference,  and  connects to each listed address until it
+       The SMTP+LMTP client looks up a  list  of  mail  exchanger
+       addresses  for  the  destination  host,  sorts the list by
+       preference, and connects to each listed address  until  it
        finds a server that responds.
 
-       When a server is not  reachable,  or  when  mail  delivery
-       fails  due  to  a  recoverable  error  condition, the SMTP
-       client will try to deliver the mail to an alternate  host.
+       When  a  server  is  not  reachable, or when mail delivery
+       fails due to a recoverable error condition, the  SMTP+LMTP
+       client  will try to deliver the mail to an alternate host.
 
-       After  a  successful mail transaction, a connection may be
+       After a successful mail transaction, a connection  may  be
        saved to the <a href="scache.8.html"><b>scache</b>(8)</a> connection cache server, so that it
-       may  be  used by any SMTP client for a subsequent transac-
-       tion.
+       may be used by  any  SMTP+LMTP  client  for  a  subsequent
+       transaction.
 
-       By default, connection caching is enabled temporarily  for
+       By  default, connection caching is enabled temporarily for
        destinations that have a high volume of mail in the active
        queue. Session caching can be enabled permanently for spe-
        cific destinations.
 
+<b>SMTP DESTINATION SYNTAX</b>
+       SMTP destinations have the following form:
+
+       <i>domainname</i>, <i>domainname</i>:<i>port</i>
+              Look up  the  mail  exchangers  for  the  specified
+              domain.
+
+       [<i>hostname</i>], [<i>hostname</i>]:<i>port</i>
+              Look up the address of the specified host.
+
+       [<i>address</i>], [<i>address</i>]:<i>port</i>
+              Connect  to  the  host at the specified address. An
+              IPv6 address must be formatted as [<b>ipv6</b>:<i>address</i>].
+
+       In all the above cases, when no port is specified, look up
+       the port defined as <b>smtp</b> in <b>services</b>(4).
+
+<b>LMTP DESTINATION SYNTAX</b>
+       LMTP destinations have the following form:
+
+       <b>unix</b>:<i>pathname</i>
+              Connect  to  the  local  UNIX-domain server that is
+              bound to the specified  <i>pathname</i>.  If  the  process
+              runs  chrooted, an absolute pathname is interpreted
+              relative to the Postfix queue directory.
+
+       <b>inet</b>:<i>hostname</i>, <b>inet:</b><i>hostname</i>:<i>port</i>
+
+       <b>inet</b>:[<i>address</i>], <b>inet</b>:[<i>address</i>]:<i>port</i>
+              Connect to the specified TCP port on the  specified
+              local or remote host. If no port is specified, con-
+              nect to the port defined as  <b>lmtp</b>  in  <b>services</b>(4).
+              If no such service is found, the <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a></b> con-
+              figuration parameter (default value of 24) will  be
+              used.
+
 <b>SECURITY</b>
-       The SMTP client is moderately security-sensitive. It talks
-       to SMTP servers and to DNS servers  on  the  network.  The
-       SMTP client can be run chrooted at fixed low privilege.
+       The  SMTP+LMTP client is moderately security-sensitive. It
+       talks to SMTP or LMTP servers and to DNS  servers  on  the
+       network. The SMTP+LMTP client can be run chrooted at fixed
+       low privilege.
 
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
@@ -55,8 +93,9 @@ SMTP(8)                                                                SMTP(8)
        <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
        <a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
        <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
-       <a href="http://www.faqs.org/rfcs/rfc2045.html">RFC 2045</a> (MIME: Format of Internet Message Bodies)
+       <a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc2034.html">RFC 2034</a> (Enhanced Status Codes)
+       <a href="http://www.faqs.org/rfcs/rfc2045.html">RFC 2045</a> (MIME: Format of Internet Message Bodies)
        <a href="http://www.faqs.org/rfcs/rfc2046.html">RFC 2046</a> (MIME: Media Types)
        <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
        <a href="http://www.faqs.org/rfcs/rfc2821.html">RFC 2821</a> (SMTP protocol)
@@ -65,25 +104,30 @@ SMTP(8)                                                                SMTP(8)
        <a href="http://www.faqs.org/rfcs/rfc3463.html">RFC 3463</a> (Enhanced Status Codes)
 
 <b>DIAGNOSTICS</b>
-       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
-       Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b>  parameter,
-       the  postmaster is notified of bounces, protocol problems,
+       Depending  on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter,
+       the postmaster is notified of bounces, protocol  problems,
        and of other trouble.
 
 <b>BUGS</b>
-       SMTP connection caching does not work with TLS. The neces-
-       sary  support for TLS object passivation and re-activation
-       does not exist without closing the session, which  defeats
-       the purpose.
+       SMTP  and  LMTP connection caching does not work with TLS.
+       The necessary support for TLS object passivation  and  re-
+       activation  does  not  exist  without closing the session,
+       which defeats the purpose.
 
-       SMTP  connection caching assumes that SASL credentials are
-       valid for all destinations  that  map  onto  the  same  IP
-       address and TCP port.
+       SMTP and LMTP connection caching assumes that SASL creden-
+       tials  are  valid  for  all destinations that map onto the
+       same IP address and TCP port.
 
 <b>CONFIGURATION PARAMETERS</b>
+       Most smtp_<i>xxx</i> configuration parameters  have  an  lmtp_<i>xxx</i>
+       "ghost"  parameter  for  the equivalent LMTP feature. This
+       document describes only those LMTP-related parameters that
+       aren't simply "ghost" parameters.
+
        Changes to <b>main.cf</b> are picked up automatically, as <a href="smtp.8.html"><b>smtp</b>(8)</a>
        processes run for only a limited amount of time.  Use  the
        command "<b>postfix reload</b>" to speed up a change.
@@ -158,11 +202,26 @@ SMTP(8)                                                                SMTP(8)
               locally valid address into a globally valid address
               when sending mail across the Internet.
 
+       Available in Postfix version 2.3 and later:
+
+       <b>lmtp_discard_lhlo_keyword_address_maps (empty)</b>
+              Lookup tables, indexed by the  remote  LMTP  server
+              address,  with  case insensitive lists of LHLO key-
+              words (pipelining, starttls, auth, etc.)  that  the
+              LMTP client will ignore in the LHLO response from a
+              remote LMTP server.
+
+       <b>lmtp_discard_lhlo_keywords ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
+              A case insensitive list of LHLO keywords  (pipelin-
+              ing,  starttls,  auth,  etc.)  that the LMTP client
+              will ignore in the LHLO response from a remote LMTP
+              server.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#disable_mime_output_conversion">disable_mime_output_conversion</a> (no)</b>
-              Disable the conversion of 8BITMIME format  to  7BIT
+              Disable  the  conversion of 8BITMIME format to 7BIT
               format.
 
        <b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
@@ -177,121 +236,121 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a> (no)</b>
-              Send  the  non-standard  XFORWARD  command when the
-              Postfix SMTP server EHLO response  announces  XFOR-
+              Send the non-standard  XFORWARD  command  when  the
+              Postfix  SMTP  server EHLO response announces XFOR-
               WARD support.
 
 <b>SASL AUTHENTICATION CONTROLS</b>
        <b><a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> (no)</b>
-              Enable  SASL  authentication  in  the  Postfix SMTP
+              Enable SASL  authentication  in  the  Postfix  SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
-              Optional SMTP client lookup tables with  one  user-
-              name:password  entry per remote hostname or domain,
+              Optional  SMTP  client lookup tables with one user-
+              name:password entry per remote hostname or  domain,
               or sender address when sender-dependent authentica-
               tion is enabled.
 
        <b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
-              What  authentication  mechanisms  the  Postfix SMTP
+              What authentication  mechanisms  the  Postfix  SMTP
               client is allowed to use.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
-              If non-empty, a Postfix SMTP client filter for  the
-              remote  SMTP  server's  list of offered SASL mecha-
+              If  non-empty, a Postfix SMTP client filter for the
+              remote SMTP server's list of  offered  SASL  mecha-
               nisms.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
-              Enable sender-dependent authentication in the  SMTP
-              client;  this is available only with SASL authenti-
-              cation, and disables  SMTP  connection  caching  to
-              ensure  that  mail  from different senders will use
+              Enable  sender-dependent authentication in the SMTP
+              client; this is available only with SASL  authenti-
+              cation,  and  disables  SMTP  connection caching to
+              ensure that mail from different  senders  will  use
               the appropriate credentials.
 
 <b>STARTTLS SUPPORT CONTROLS</b>
-       Detailed information about STARTTLS configuration  may  be
+       Detailed  information  about STARTTLS configuration may be
        found in the <a href="TLS_README.html">TLS_README</a> document.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic  mode:  use  TLS  when  a remote SMTP
-              server announces STARTTLS support,  otherwise  send
+              Opportunistic mode: use  TLS  when  a  remote  SMTP
+              server  announces  STARTTLS support, otherwise send
               the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement  mode: require that remote SMTP servers
-              use TLS encryption, and  never  send  mail  in  the
+              Enforcement mode: require that remote SMTP  servers
+              use  TLS  encryption,  and  never  send mail in the
               clear.
 
        <b><a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_security_options</a>           ($<a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_secu</a>-</b>
        <b><a href="postconf.5.html#smtp_sasl_security_options">rity_options</a>)</b>
-              The  SASL  authentication security options that the
-              Postfix SMTP client uses  for  TLS  encrypted  SMTP
+              The SASL authentication security options  that  the
+              Postfix  SMTP  client  uses  for TLS encrypted SMTP
               sessions.
 
        <b><a href="postconf.5.html#smtp_starttls_timeout">smtp_starttls_timeout</a> (300s)</b>
-              Time  limit  for Postfix SMTP client write and read
-              operations during TLS startup  and  shutdown  hand-
+              Time limit for Postfix SMTP client write  and  read
+              operations  during  TLS  startup and shutdown hand-
               shake procedures.
 
        <b><a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> (empty)</b>
-              The  file with the certificate of the certification
-              authority (CA) that issued the Postfix SMTP  client
+              The file with the certificate of the  certification
+              authority  (CA) that issued the Postfix SMTP client
               certificate.
 
        <b><a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a> (empty)</b>
-              Directory  with  PEM  format  certificate authority
-              certificates that the Postfix SMTP client  uses  to
+              Directory with  PEM  format  certificate  authority
+              certificates  that  the Postfix SMTP client uses to
               verify a remote SMTP server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_cert_file">smtp_tls_cert_file</a> (empty)</b>
-              File  with  the Postfix SMTP client RSA certificate
+              File with the Postfix SMTP client  RSA  certificate
               in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Controls the Postfix SMTP client TLS cipher  selec-
+              Controls  the Postfix SMTP client TLS cipher selec-
               tion scheme.
 
        <b><a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a> (empty)</b>
-              File  with  the Postfix SMTP client DSA certificate
+              File with the Postfix SMTP client  DSA  certificate
               in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_dkey_file">smtp_tls_dkey_file</a> ($<a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a>)</b>
-              File with the Postfix SMTP client DSA  private  key
+              File  with  the Postfix SMTP client DSA private key
               in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              When  TLS  encryption is enforced, require that the
+              When TLS encryption is enforced, require  that  the
               remote SMTP server hostname matches the information
               in the remote SMTP server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_key_file">smtp_tls_key_file</a> ($<a href="postconf.5.html#smtp_tls_cert_file">smtp_tls_cert_file</a>)</b>
-              File  with  the Postfix SMTP client RSA private key
+              File with the Postfix SMTP client RSA  private  key
               in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_loglevel">smtp_tls_loglevel</a> (0)</b>
-              Enable additional Postfix SMTP  client  logging  of
+              Enable  additional  Postfix  SMTP client logging of
               TLS activity.
 
        <b><a href="postconf.5.html#smtp_tls_note_starttls_offer">smtp_tls_note_starttls_offer</a> (no)</b>
-              Log  the  hostname  of  a  remote  SMTP server that
-              offers STARTTLS, when TLS is  not  already  enabled
+              Log the hostname  of  a  remote  SMTP  server  that
+              offers  STARTTLS,  when  TLS is not already enabled
               for that server.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
               Optional lookup tables with the Postfix SMTP client
-              TLS usage policy by next-hop  domain  name  and  by
+              TLS  usage  policy  by  next-hop domain name and by
               remote SMTP server hostname.
 
        <b><a href="postconf.5.html#smtp_tls_scert_verifydepth">smtp_tls_scert_verifydepth</a> (5)</b>
-              The  verification depth for remote SMTP server cer-
+              The verification depth for remote SMTP server  cer-
               tificates.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> (empty)</b>
-              Name of the file containing  the  optional  Postfix
+              Name  of  the  file containing the optional Postfix
               SMTP client TLS session cache.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_timeout">smtp_tls_session_cache_timeout</a> (3600s)</b>
@@ -299,31 +358,36 @@ SMTP(8)                                                                SMTP(8)
               sion cache information.
 
        <b><a href="postconf.5.html#tls_daemon_random_bytes">tls_daemon_random_bytes</a> (32)</b>
-              The number of pseudo-random bytes that  an  <a href="smtp.8.html"><b>smtp</b>(8)</a>
-              or  <a href="smtpd.8.html"><b>smtpd</b>(8)</a>  process  requests  from the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a>
-              server in order to seed its internal pseudo  random
+              The  number  of pseudo-random bytes that an <a href="smtp.8.html"><b>smtp</b>(8)</a>
+              or <a href="smtpd.8.html"><b>smtpd</b>(8)</a> process  requests  from  the  <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a>
+              server  in order to seed its internal pseudo random
               number generator (PRNG).
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a>      ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destina</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">tion_concurrency_limit</a>)</b>
-              The  maximal  number  of parallel deliveries to the
-              same destination  via  the  smtp  message  delivery
+              The maximal number of parallel  deliveries  to  the
+              same  destination  via  the  smtp  message delivery
               transport.
 
        <b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a>        ($<a href="postconf.5.html#default_destination_recipient_limit">default_destina</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">tion_recipient_limit</a>)</b>
-              The  maximal  number of recipients per delivery via
+              The maximal number of recipients per  delivery  via
               the smtp message delivery transport.
 
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The SMTP client time limit  for  completing  a  TCP
+              The  SMTP  client  time  limit for completing a TCP
               connection,  or  zero  (use  the  operating  system
               built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The SMTP client time limit for sending the HELO  or
-              EHLO  command, and for receiving the initial server
+              The  SMTP client time limit for sending the HELO or
+              EHLO command, and for receiving the initial  server
+              response.
+
+       <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
+              The  LMTP  client  time  limit for sending the LHLO
+              command,  and  for  receiving  the  initial  server
               response.
 
        <b><a href="postconf.5.html#smtp_xforward_timeout">smtp_xforward_timeout</a> (300s)</b>
@@ -331,30 +395,30 @@ SMTP(8)                                                                SMTP(8)
               command, and for receiving the server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The  SMTP  client  time  limit for sending the MAIL
-              FROM  command,  and  for   receiving   the   server
+              The SMTP client time limit  for  sending  the  MAIL
+              FROM   command,   and   for  receiving  the  server
               response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The  SMTP  client  time  limit for sending the SMTP
-              RCPT TO  command,  and  for  receiving  the  server
+              The SMTP client time limit  for  sending  the  SMTP
+              RCPT  TO  command,  and  for  receiving  the server
               response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The  SMTP  client  time  limit for sending the SMTP
-              DATA  command,  and  for   receiving   the   server
+              The SMTP client time limit  for  sending  the  SMTP
+              DATA   command,   and   for  receiving  the  server
               response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The  SMTP  client  time  limit for sending the SMTP
+              The SMTP client time limit  for  sending  the  SMTP
               message content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
-              The SMTP client time limit  for  sending  the  SMTP
+              The  SMTP  client  time  limit for sending the SMTP
               ".", and for receiving the server response.
 
        <b><a href="postconf.5.html#smtp_quit_timeout">smtp_quit_timeout</a> (300s)</b>
-              The  SMTP  client  time  limit for sending the QUIT
+              The SMTP client time limit  for  sending  the  QUIT
               command, and for receiving the server response.
 
        Available in Postfix version 2.1 and later:
@@ -365,22 +429,22 @@ SMTP(8)                                                                SMTP(8)
               lookups, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The maximal number of SMTP  sessions  per  delivery
-              request  before  giving up or delivering to a fall-
+              The  maximal  number  of SMTP sessions per delivery
+              request before giving up or delivering to  a  fall-
               back <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
-              The SMTP client time limit  for  sending  the  RSET
+              The  SMTP  client  time  limit for sending the RSET
               command, and for receiving the server response.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently  enable SMTP connection caching for the
+              Permanently enable SMTP connection caching for  the
               specified destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily enable SMTP connection caching while  a
+              Temporarily  enable SMTP connection caching while a
               destination has a high volume of mail in the active
               queue.
 
@@ -390,9 +454,15 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
               When SMTP connection caching is enabled, the amount
-              of time that an unused SMTP client socket  is  kept
+              of  time  that an unused SMTP client socket is kept
               open before it is closed.
 
+       Available in Postfix version 2.3 and later:
+
+       <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
+              Time limit for connection cache  connect,  send  or
+              receive operations.
+
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
               The  increment  in  verbose  logging  level  when a
@@ -437,22 +507,22 @@ SMTP(8)                                                                SMTP(8)
               Disable  DNS  lookups  in the Postfix SMTP and LMTP
               clients.
 
-       <b><a href="postconf.5.html#fallback_relay">fallback_relay</a> (empty)</b>
-              Optional list of relay hosts for SMTP  destinations
-              that can't be found or that are unreachable.
-
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
               The network interface addresses that this mail sys-
               tem receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (ipv4)</b>
-              The Internet protocols Postfix will attempt to  use
+              The  Internet protocols Postfix will attempt to use
               when making or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
               The time limit for sending or receiving information
               over an internal communication channel.
 
+       <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
+              The  default  TCP port that the Postfix LMTP client
+              connects to.
+
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
               The maximum amount of time  that  an  idle  Postfix
               daemon  process  waits for the next service request
@@ -489,6 +559,9 @@ SMTP(8)                                                                SMTP(8)
               The  hostname to send in the SMTP EHLO or HELO com-
               mand.
 
+       <b>lmtp_lhlo_name ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
+              The hostname to send in the LMTP LHLO command.
+
        <b><a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a> (dns)</b>
               What mechanisms when the SMTP client uses  to  look
               up a host's IP address.
@@ -505,6 +578,18 @@ SMTP(8)                                                                SMTP(8)
               process  name  in  syslog  records, so that "smtpd"
               becomes, for example, "postfix/smtpd".
 
+       Available with Postfix 2.2 and earlier:
+
+       <b><a href="postconf.5.html#fallback_relay">fallback_relay</a> (empty)</b>
+              Optional list of relay hosts for SMTP  destinations
+              that can't be found or that are unreachable.
+
+       Available with Postfix 2.3 and later:
+
+       <b>smtp_fallback_relay ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
+              Optional  list of relay hosts for SMTP destinations
+              that can't be found or that are unreachable.
+
 <b>SEE ALSO</b>
        <a href="qmgr.8.html">qmgr(8)</a>, queue manager
        <a href="bounce.8.html">bounce(8)</a>, delivery status reports
index d8a3426fc67a5a72964cd80cf3561a80050f9870..d60263612e3255a987df99c19d0c7aa74973663e 100644 (file)
@@ -401,7 +401,7 @@ CCARGS="$CCARGS -DSNAPSHOT"
 
 # Non-production: needs thorough testing, or major changes are still
 # needed before the code stabilizes.
-#CCARGS="$CCARGS -DNONPROD"
+CCARGS="$CCARGS -DNONPROD"
 
 sed 's/  / /g' <<EOF
 SYSTYPE        = $SYSTYPE
index e81c333bcd53455208b56e18b10fbdef9cabbc7b..99c7daaf5b44f342e7acf86c33f094be1bfb5ce6 100644 (file)
@@ -77,10 +77,8 @@ man8/local.8: ../src/local/local.c
            (cmp -s junk $? || mv junk $?)
        ../mantools/srctoman $? >$@
 
-man8/lmtp.8: ../src/lmtp/lmtp.c
-       ../mantools/fixman ../proto/postconf.proto $? >junk && \
-           (cmp -s junk $? || mv junk $?)
-       ../mantools/srctoman $? >$@
+man8/lmtp.8:
+       echo .so man8/smtp.8 >$@
 
 man8/master.8: ../src/master/master.c
        ../mantools/fixman ../proto/postconf.proto $? >junk && \
index 80c23e5a386d3a4e8afbe00b96311d2480d15541..e19443ea14732bb8d9e5ca8b737dceab35fcc272 100644 (file)
@@ -210,7 +210,6 @@ cleanup(8), canonicalize and enqueue message
 discard(8), Postfix discard delivery agent
 error(8), Postfix error delivery agent
 flush(8), Postfix fast ETRN service
-lmtp(8), Postfix LMTP client
 local(8), Postfix local delivery agent
 master(8), Postfix master daemon
 oqmgr(8), old Postfix queue manager
@@ -221,7 +220,7 @@ qmgr(8), Postfix queue manager
 qmqpd(8), Postfix QMQP server
 scache(8), Postfix connection cache manager
 showq(8), list Postfix mail queue
-smtp(8), Postfix SMTP client
+smtp(8), lmtp(8), Postfix SMTP+LMTP client
 smtpd(8), Postfix SMTP server
 spawn(8), run non-Postfix server
 tlsmgr(8), Postfix TLS cache and randomness manager
@@ -259,3 +258,18 @@ Wietse Venema
 IBM T.J. Watson Research
 P.O. Box 704
 Yorktown Heights, NY 10598, USA
+
+SASL support originally by:
+Till Franke
+SuSE Rhein/Main AG
+65760 Eschborn, Germany
+
+LMTP support originally by:
+Philip A. Prindeville
+Mirapoint, Inc.
+USA.
+
+Amos Gouaux
+University of Texas at Dallas
+P.O. Box 830688, MC34
+Richardson, TX 75083, USA
index 710287b84826e4b665ed82be946ea549356b4d75..23347ef1f5dc00af0631d2f21c060367f2dfde84 100644 (file)
@@ -42,7 +42,7 @@ If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
 queue IDs from standard input. For example, to delete all mail
 with exactly one recipient \fBuser@example.com\fR:
 .sp
-mailq | tail +2 | awk  \'BEGIN { RS = "" }
+mailq | tail +2 | grep -v '^ *(' | awk  \'BEGIN { RS = "" }
 .ti +4
 # $7=sender, $8=recipient1, $9=recipient2
 .ti +4
index 468e5d4a2872805f158d399acbe1de40b31524b7..7c56cf5ce3c15560a1e0bd95b1e951427bb01227 100644 (file)
@@ -496,6 +496,16 @@ a "type:table" lookup table is matched when a name matches a lookup key
 (the lookup result is ignored).  Continue long lines by starting the
 next line with whitespace.
 .PP
+Example:
+.PP
+.nf
+.na
+.ft C
+authorized_submit_users = !www, static:all
+.fi
+.ad
+.ft R
+.PP
 This feature is available in Postfix 2.2 and later.
 .SH authorized_verp_clients (default: $mynetworks)
 What SMTP clients are allowed to specify the XVERP command.
@@ -741,6 +751,11 @@ With Postfix command that run with set-gid privileges, a
 config_directory override requires either root privileges, or it
 requires that the directory is listed with the alternate_config_directories
 parameter in the default main.cf file.
+.SH connection_cache_protocol_timeout (default: 5s)
+Time limit for connection cache connect, send or receive
+operations.  The time limit is enforced in the client.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH connection_cache_service (default: scache)
 The name of the \fBscache\fR(8) connection cache service.  This service
 maintains a limited pool of cached sessions.
@@ -1225,17 +1240,19 @@ from message headers when mail is submitted with "\fBsendmail -t\fR".
 This feature was removed in Postfix version 2.1.
 .SH fallback_relay (default: empty)
 Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable.
+found or that are unreachable. With Postfix 2.3 this parameter
+is renamed to smtp_fallback_relay.
 .PP
 By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred if a destination is unreachable.
+not found, and delivery is deferred when a destination is unreachable.
 .PP
 The fallback relays must be SMTP destinations. Specify a domain,
 host, host:port, [host]:port, [address] or [address]:port; the form
 [host] turns off MX lookups.  If you specify multiple SMTP
 destinations, Postfix will try them in the specified order.
 .PP
-Note: do not use the fallback_relay feature when relaying mail
+Note: before Postfix 2.2, do not use the fallback_relay feature
+when relaying mail
 for a backup or primary MX domain. Mail would loop between the
 Postfix MX host and the fallback_relay host when the final destination
 is unavailable.
@@ -1248,7 +1265,8 @@ the end of the relay entry.
 In transport maps, specify "relay:\fInexthop...\fR"
 as the right-hand side for backup or primary MX domain entries.
 .PP
-These are default settings in Postfix version 2.2 and later.
+Postfix version 2.2 and later will not use the fallback_relay feature
+for destinations that it is MX host for.
 .SH fallback_transport (default: empty)
 Optional message delivery transport that the \fBlocal\fR(8) delivery
 agent should use for names that are not found in the \fBaliases\fR(5)
@@ -1595,6 +1613,16 @@ This feature is available in Postfix 2.1 and later.
 .SH line_length_limit (default: 2048)
 Upon input, long lines are chopped up into pieces of at most
 this length; upon delivery, long lines are reconstructed.
+.SH lmtp_bind_address (default: empty)
+The LMTP-specific version of the smtp_bind_address configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_bind_address6 (default: empty)
+The LMTP-specific version of the smtp_bind_address6 configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_cache_connection (default: yes)
 Keep Postfix LMTP client connections open for up to $max_idle
 seconds. When the LMTP client receives a request for the same
@@ -1640,6 +1668,21 @@ lmtp_connect_timeout = 30s
 .fi
 .ad
 .ft R
+.SH lmtp_connection_cache_destinations (default: empty)
+The LMTP-specific version of the smtp_connection_cache_destinations
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_connection_cache_on_demand (default: yes)
+The LMTP-specific version of the smtp_connection_cache_on_demand
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_connection_reuse_time_limit (default: 300s)
+The LMTP-specific version of the smtp_connection_reuse_time_limit
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_data_done_timeout (default: 600s)
 The LMTP client time limit for sending the LMTP ".", and for
 receiving the server response.  When no response is received within
@@ -1661,6 +1704,11 @@ the LMTP client terminates the transfer.
 .PP
 Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 The default time unit is s (seconds).
+.SH lmtp_defer_if_no_mx_address_found (default: no)
+The LMTP-specific version of the smtp_defer_if_no_mx_address_found
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_destination_concurrency_limit (default: $default_destination_concurrency_limit)
 The maximal number of parallel deliveries to the same destination
 via the lmtp message delivery transport. This limit is enforced by
@@ -1675,27 +1723,116 @@ the entry in the master.cf file.
 Setting this parameter to a value of 1 changes the meaning of
 lmtp_destination_concurrency_limit from concurrency per domain into
 concurrency per recipient.
+.SH lmtp_discard_lhlo_keyword_address_maps (default: empty)
+Lookup tables, indexed by the remote LMTP server address, with
+case insensitive lists of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server. See lmtp_discard_lhlo_keywords for
+details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_discard_lhlo_keywords (default: $myhostname)
+A case insensitive list of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server.
+.PP
+This feature is available in Postfix 2.3 and later.
+.PP
+Notes:
+.IP \(bu
+Specify the \fBsilent-discard\fR pseudo keyword to prevent
+this action from being logged.
+.IP \(bu
+Use the lmtp_discard_lhlo_keyword_address_maps feature to
+discard LHLO keywords selectively.
+.SH lmtp_enforce_tls (default: no)
+The LMTP-specific version of the smtp_enforce_tls configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_generic_maps (default: empty)
+The LMTP-specific version of the smtp_generic_maps configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_host_lookup (default: dns)
+The LMTP-specific version of the smtp_host_lookup configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_lhlo_name (default: $myhostname)
+The hostname to send in the LMTP LHLO command.
+.PP
+The default value is the machine hostname.  Specify a hostname or
+[ip.add.re.ss].
+.PP
+This information can be specified in the main.cf file for all LMTP
+clients, or it can be specified in the master.cf file for a specific
+client, for example:
+.PP
+.nf
+.na
+.ft C
+  /etc/postfix/master.cf:
+        mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_lhlo_timeout (default: 300s)
-The LMTP client time limit for receiving the LMTP greeting
-banner.  When the server drops the connection without sending a
-greeting banner, or when it sends no greeting banner within the
-deadline, the LMTP client tries the next address on the mail
-exchanger list.
+The LMTP client time limit for sending the LHLO command, and
+for receiving the initial server response.
 .PP
-Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
-The default time unit is s (seconds).
+Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks).  The default time unit is s (seconds).
+.SH lmtp_line_length_limit (default: 990)
+The LMTP-specific version of the smtp_line_length_limit
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_mail_timeout (default: 300s)
 The LMTP client time limit for sending the MAIL FROM command, and
 for receiving the server response.
 .PP
 Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 The default time unit is s (seconds).
+.SH lmtp_mx_address_limit (default: 5)
+The LMTP-specific version of the smtp_mx_address_limit configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_mx_session_limit (default: 2)
+The LMTP-specific version of the smtp_mx_session_limit configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_pix_workaround_delay_time (default: 10s)
+The LMTP-specific version of the smtp_pix_workaround_delay_time
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_pix_workaround_threshold_time (default: 500s)
+The LMTP-specific version of the smtp_pix_workaround_threshold_time
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_quit_timeout (default: 300s)
 The LMTP client time limit for sending the QUIT command, and for
 receiving the server response.
 .PP
 Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 The default time unit is s (seconds).
+.SH lmtp_quote_rfc821_envelope (default: yes)
+The LMTP-specific version of the smtp_quote_rfc821_envelope
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_randomize_addresses (default: yes)
+The LMTP-specific version of the smtp_randomize_addresses
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_rcpt_timeout (default: 300s)
 The LMTP client time limit for sending the RCPT TO command, and
 for receiving the server response.
@@ -1712,6 +1849,11 @@ Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 The default time unit is s (seconds).
 .SH lmtp_sasl_auth_enable (default: no)
 Enable SASL authentication in the Postfix LMTP client.
+.SH lmtp_sasl_mechanism_filter (default: empty)
+The LMTP-specific version of the smtp_sasl_mechanism_filter
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_sasl_password_maps (default: empty)
 Optional LMTP client lookup tables with one username:password entry
 per host or domain.  If a remote host or domain has no username:password
@@ -1741,6 +1883,11 @@ lmtp_sasl_security_options = noplaintext
 .fi
 .ad
 .ft R
+.SH lmtp_sasl_tls_security_options (default: $var_lmtp_sasl_opts)
+The LMTP-specific version of the smtp_sasl_tls_security_options
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_send_xforward_command (default: no)
 Send an XFORWARD command to the LMTP server when the LMTP LHLO
 server response announces XFORWARD support.  This allows an \fBlmtp\fR(8)
@@ -1751,10 +1898,50 @@ Before you change the value to yes, it is best to make sure that
 your content filter supports this command.
 .PP
 This feature is available in Postfix 2.1 and later.
+.SH lmtp_sender_dependent_authentication (default: no)
+The LMTP-specific version of the smtp_sender_dependent_authentication
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_skip_5xx_greeting (default: yes)
+The LMTP-specific version of the smtp_skip_5xx_greeting
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_skip_quit_response (default: no)
 Wait for the response to the LMTP QUIT command.
+.SH lmtp_starttls_timeout (default: 300s)
+The LMTP-specific version of the smtp_starttls_timeout configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_tcp_port (default: 24)
 The default TCP port that the Postfix LMTP client connects to.
+.SH lmtp_tls_enforce_peername (default: yes)
+The LMTP-specific version of the smtp_tls_enforce_peername
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_note_starttls_offer (default: no)
+The LMTP-specific version of the smtp_tls_note_starttls_offer
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_per_site (default: empty)
+The LMTP-specific version of the smtp_tls_per_site configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_scert_verifydepth (default: 5)
+The LMTP-specific version of the smtp_tls_scert_verifydepth
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
+.SH lmtp_use_tls (default: no)
+The LMTP-specific version of the smtp_use_tls configuration
+parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_xforward_timeout (default: 300s)
 The LMTP client time limit for sending the XFORWARD command, and
 for receiving the server response.
@@ -3240,7 +3427,7 @@ sender_canonical_maps = hash:/etc/postfix/sender_canonical
 .SH sender_dependent_relayhost_maps (default: empty)
 A sender-dependent override for the global relayhost parameter
 setting. The tables are searched by the sender address and by the
-sender @domain. This information is overruled with relay_transport,
+@domain. This information is overruled with relay_transport,
 default_transport and with the \fBtransport\fR(5) table.
 .PP
 This feature is available in Postfix 2.3 and later.
@@ -3358,6 +3545,9 @@ if mail is sent via a relay host: a relay host name (without
 [] or non-default TCP port), as specified in main.cf or in the
 transport map,
 .IP \(bu
+if mail is sent via a UNIX-domain socket: a pathname (without
+the unix: prefix),
+.IP \(bu
 a /file/name with domain names and/or relay host names as
 defined above,
 .IP \(bu
@@ -3520,6 +3710,22 @@ This option is useful only if you are definitely sure that you
 will only connect to servers that support RFC 2487 _and_ that
 provide valid server certificates.  Typical use is for clients that
 send all their email to a dedicated mailhub.
+.SH smtp_fallback_relay (default: $fallback_relay)
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable. With Postfix 2.2 and earlier this
+parameter is called fallback_relay.
+.PP
+By default, mail is returned to the sender when a destination is
+not found, and delivery is deferred when a destination is unreachable.
+.PP
+The fallback relays must be SMTP destinations. Specify a domain,
+host, host:port, [host]:port, [address] or [address]:port; the form
+[host] turns off MX lookups.  If you specify multiple SMTP
+destinations, Postfix will try them in the specified order.
+.PP
+To prevent mailer loops between MX hosts and fall-back hosts,
+Postfix version 2.3 and later will not use the smtp_fallback_relay
+feature for destinations that it is MX host for.
 .SH smtp_generic_maps (default: empty)
 Optional lookup tables that perform address rewriting in the
 SMTP client, typically to transform a locally valid address into
index 09f8bde961956c3234d9307bdbe76e5e0f9e3062..966d3019943ed17257a88c3ac510fe993707e44a 100644 (file)
@@ -1,279 +1 @@
-.TH LMTP 8 
-.ad
-.fi
-.SH NAME
-lmtp
-\-
-Postfix local delivery via LMTP
-.SH "SYNOPSIS"
-.na
-.nf
-\fBlmtp\fR [generic Postfix daemon options]
-.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 status reports are sent
-to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
-appropriate.
-
-The LMTP client connects to the destination specified in the message
-delivery request. The destination, usually specified in the Postfix
-\fBtransport\fR(5) table, has the form:
-.IP \fBunix\fR:\fIpathname\fR
-Connect to the local UNIX-domain server that is bound to the specified
-\fIpathname\fR. If the process runs chrooted, an absolute pathname
-is interpreted relative to the changed root directory.
-.IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
-.IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
-Connect to the specified IPV4 TCP port on the specified local or
-remote host. If no port is specified, connect to the port defined as
-\fBlmtp\fR in \fBservices\fR(4).
-If no such service is found, the \fBlmtp_tcp_port\fR configuration
-parameter (default value of 24) will be used.
-
-The LMTP client does not perform MX (mail exchanger) lookups since
-those are defined only for mail delivery via SMTP.
-.PP
-If neither \fBunix:\fR nor \fBinet:\fR are specified, \fBinet:\fR
-is assumed.
-.SH "SECURITY"
-.na
-.nf
-.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 1652 (8bit-MIME transport)
-RFC 1870 (Message Size Declaration)
-RFC 2033 (LMTP protocol)
-RFC 2034 (Enhanced Status codes)
-RFC 2554 (AUTH command)
-RFC 2821 (SMTP protocol)
-RFC 2920 (SMTP Pipelining)
-RFC 3463 (Enhanced Status codes)
-.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 "CONFIGURATION PARAMETERS"
-.na
-.nf
-.ad
-.fi
-Changes to \fBmain.cf\fR are picked up automatically, as \fBlmtp\fR(8)
-processes run for only a limited amount of time. Use the command
-"\fBpostfix reload\fR" to speed up a change.
-
-The text below provides only a parameter summary. See
-\fBpostconf\fR(5) for more details including examples.
-.SH "COMPATIBILITY CONTROLS"
-.na
-.nf
-.ad
-.fi
-.IP "\fBlmtp_skip_quit_response (no)\fR"
-Wait for the response to the LMTP QUIT command.
-.SH "TROUBLE SHOOTING CONTROLS"
-.na
-.nf
-.ad
-.fi
-.IP "\fBdebug_peer_level (2)\fR"
-The increment in verbose logging level when a remote client or
-server matches a pattern in the debug_peer_list parameter.
-.IP "\fBdebug_peer_list (empty)\fR"
-Optional list of remote client or server hostname or network
-address patterns that cause the verbose logging level to increase
-by the amount specified in $debug_peer_level.
-.IP "\fBerror_notice_recipient (postmaster)\fR"
-The recipient of postmaster notifications about mail delivery
-problems that are caused by policy, resource, software or protocol
-errors.
-.IP "\fBnotify_classes (resource, software)\fR"
-The list of error classes that are reported to the postmaster.
-.SH "EXTERNAL CONTENT INSPECTION CONTROLS"
-.na
-.nf
-.ad
-.fi
-Available in Postfix version 2.1 and later:
-.IP "\fBlmtp_send_xforward_command (no)\fR"
-Send an XFORWARD command to the LMTP server when the LMTP LHLO
-server response announces XFORWARD support.
-.SH "SASL AUTHENTICATION CONTROLS"
-.na
-.nf
-.ad
-.fi
-.IP "\fBlmtp_sasl_auth_enable (no)\fR"
-Enable SASL authentication in the Postfix LMTP client.
-.IP "\fBlmtp_sasl_password_maps (empty)\fR"
-Optional LMTP client lookup tables with one username:password entry
-per host or domain.
-.IP "\fBlmtp_sasl_security_options (noplaintext, noanonymous)\fR"
-What authentication mechanisms the Postfix LMTP client is allowed
-to use.
-.SH "RESOURCE AND RATE CONTROLS"
-.na
-.nf
-.ad
-.fi
-In the text below, \fItransport\fR is the name
-of the service as specified in the \fBmaster.cf\fR file.
-.IP "\fBlmtp_cache_connection (yes)\fR"
-Keep Postfix LMTP client connections open for up to $max_idle
-seconds.
-.IP "\fItransport_\fBdestination_concurrency_limit ($default_destination_concurrency_limit)\fR"
-Limit the number of parallel deliveries to the same destination
-via this mail delivery transport.
-.IP "\fItransport_\fBdestination_recipient_limit ($default_destination_recipient_limit)\fR"
-Limit the number of recipients per message delivery via this mail
-delivery transport.
-
-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.
-.IP "\fBlmtp_connect_timeout (0s)\fR"
-The LMTP client time limit for completing a TCP connection, or
-zero (use the operating system built-in time limit).
-.IP "\fBlmtp_lhlo_timeout (300s)\fR"
-The LMTP client time limit for receiving the LMTP greeting
-banner.
-.IP "\fBlmtp_xforward_timeout (300s)\fR"
-The LMTP client time limit for sending the XFORWARD command, and
-for receiving the server response.
-.IP "\fBlmtp_mail_timeout (300s)\fR"
-The LMTP client time limit for sending the MAIL FROM command, and
-for receiving the server response.
-.IP "\fBlmtp_rcpt_timeout (300s)\fR"
-The LMTP client time limit for sending the RCPT TO command, and
-for receiving the server response.
-.IP "\fBlmtp_data_init_timeout (120s)\fR"
-The LMTP client time limit for sending the LMTP DATA command, and
-for receiving the server response.
-.IP "\fBlmtp_data_xfer_timeout (180s)\fR"
-The LMTP client time limit for sending the LMTP message content.
-.IP "\fBlmtp_data_done_timeout (600s)\fR"
-The LMTP client time limit for sending the LMTP ".", and for
-receiving the server response.
-.IP "\fBlmtp_rset_timeout (20s)\fR"
-The LMTP client time limit for sending the RSET command, and
-for receiving the server response.
-.IP "\fBlmtp_quit_timeout (300s)\fR"
-The LMTP client time limit for sending the QUIT command, and for
-receiving the server response.
-.SH "MISCELLANEOUS CONTROLS"
-.na
-.nf
-.ad
-.fi
-.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
-The default location of the Postfix main.cf and master.cf
-configuration files.
-.IP "\fBdaemon_timeout (18000s)\fR"
-How much time a Postfix daemon process may take to handle a
-request before it is terminated by a built-in watchdog timer.
-.IP "\fBdelay_logging_resolution_limit (2)\fR"
-The maximal number of digits after the decimal point when logging
-sub-second delay values.
-.IP "\fBdisable_dns_lookups (no)\fR"
-Disable DNS lookups in the Postfix SMTP and LMTP clients.
-.IP "\fBipc_timeout (3600s)\fR"
-The time limit for sending or receiving information over an internal
-communication channel.
-.IP "\fBlmtp_tcp_port (24)\fR"
-The default TCP port that the Postfix LMTP client connects to.
-.IP "\fBmax_idle (100s)\fR"
-The maximum amount of time that an idle Postfix daemon process
-waits for the next service request before exiting.
-.IP "\fBmax_use (100)\fR"
-The maximal number of connection requests before a Postfix daemon
-process terminates.
-.IP "\fBprocess_id (read-only)\fR"
-The process ID of a Postfix command or daemon process.
-.IP "\fBprocess_name (read-only)\fR"
-The process name of a Postfix command or daemon process.
-.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
-The location of the Postfix top-level queue directory.
-.IP "\fBsyslog_facility (mail)\fR"
-The syslog facility of Postfix logging.
-.IP "\fBsyslog_name (postfix)\fR"
-The mail system name that is prepended to the process name in syslog
-records, so that "smtpd" becomes, for example, "postfix/smtpd".
-.SH "SEE ALSO"
-.na
-.nf
-bounce(8), delivery status reports
-qmgr(8), queue manager
-postconf(5), configuration parameters
-master(5), generic daemon options
-services(4), Internet services and aliases
-master(8), process manager
-syslogd(8), system logging
-.SH "README FILES"
-.na
-.nf
-.ad
-.fi
-Use "\fBpostconf readme_directory\fR" or
-"\fBpostconf html_directory\fR" to locate this information.
-.na
-.nf
-LMTP_README, Postfix LMTP client howto
-VIRTUAL_README, virtual delivery agent howto
-.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
-
-Modifications for LMTP by:
-Philip A. Prindeville
-Mirapoint, Inc.
-USA.
-
-SASL support originally by:
-Till Franke
-SuSE Rhein/Main AG
-65760 Eschborn, Germany
-
-Additional work on LMTP by:
-Amos Gouaux
-University of Texas at Dallas
-P.O. Box 830688, MC34
-Richardson, TX 75083, USA
+.so man8/smtp.8
index bce7bafc5e59318ba9a73f1917a41d760022cb1b..a7176c63b8f60ec8839b9a1e8695eb7895e1f924 100644 (file)
@@ -4,7 +4,7 @@
 .SH NAME
 smtp
 \-
-Postfix SMTP client
+Postfix SMTP+LMTP client
 .SH "SYNOPSIS"
 .na
 .nf
@@ -12,42 +12,78 @@ Postfix SMTP client
 .SH DESCRIPTION
 .ad
 .fi
-The Postfix SMTP client processes message delivery requests from
+The Postfix SMTP+LMTP client implements the SMTP and LMTP mail
+delivery protocols. It 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 SMTP client updates the queue file and marks recipients
+The SMTP+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 status reports are sent
 to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
 appropriate.
 
-The SMTP client looks up a list of mail exchanger addresses for
+The SMTP+LMTP client looks up a list of mail exchanger addresses for
 the destination host, sorts the list by preference, and connects
 to each listed address until it finds a server that responds.
 
 When a server is not reachable, or when mail delivery fails due
-to a recoverable error condition, the SMTP client will try to
+to a recoverable error condition, the SMTP+LMTP client will try to
 deliver the mail to an alternate host.
 
 After a successful mail transaction, a connection may be saved
 to the \fBscache\fR(8) connection cache server, so that it
-may be used by any SMTP client for a subsequent transaction.
+may be used by any SMTP+LMTP client for a subsequent transaction.
 
 By default, connection caching is enabled temporarily for
 destinations that have a high volume of mail in the active
 queue. Session caching can be enabled permanently for
 specific destinations.
+.SH "SMTP DESTINATION SYNTAX"
+.na
+.nf
+.ad
+.fi
+SMTP destinations have the following form:
+.IP "\fIdomainname\fR, \fIdomainname\fR:\fIport\fR"
+Look up the mail exchangers for the specified domain.
+.IP "[\fIhostname\fR], [\fIhostname\fR]:\fIport\fR"
+Look up the address of the specified host.
+.IP "[\fIaddress\fR], [\fIaddress\fR]:\fIport\fR"
+Connect to the host at the specified address. An IPv6
+address must be formatted as [\fBipv6\fR:\fIaddress\fR].
+.PP
+In all the above cases, when no port is specified, look up
+the port defined as \fBsmtp\fR in \fBservices\fR(4).
+.SH "LMTP DESTINATION SYNTAX"
+.na
+.nf
+.ad
+.fi
+LMTP destinations have the following form:
+.IP \fBunix\fR:\fIpathname\fR
+Connect to the local UNIX-domain server that is bound to the specified
+\fIpathname\fR. If the process runs chrooted, an absolute pathname
+is interpreted relative to the Postfix queue directory.
+.IP "\fBinet\fR:\fIhostname\fR, \fBinet\fB:\fIhostname\fR:\fIport\fR"
+.IP "\fBinet\fR:[\fIaddress\fR], \fBinet\fR:[\fIaddress\fR]:\fIport\fR"
+Connect to the specified TCP port on the specified local or
+remote host. If no port is specified, connect to the port defined as
+\fBlmtp\fR in \fBservices\fR(4).
+If no such service is found, the \fBlmtp_tcp_port\fR configuration
+parameter (default value of 24) will be used.
+.PP
 .SH "SECURITY"
 .na
 .nf
 .ad
 .fi
-The SMTP client is moderately security-sensitive. It talks to SMTP
-servers and to DNS servers on the network. The SMTP client can be
-run chrooted at fixed low privilege.
+The SMTP+LMTP client is moderately security-sensitive. It
+talks to SMTP or LMTP servers and to DNS servers on the
+network. The SMTP+LMTP client can be run chrooted at fixed
+low privilege.
 .SH "STANDARDS"
 .na
 .nf
@@ -56,8 +92,9 @@ RFC 822 (ARPA Internet Text Messages)
 RFC 1651 (SMTP service extensions)
 RFC 1652 (8bit-MIME transport)
 RFC 1870 (Message Size Declaration)
-RFC 2045 (MIME: Format of Internet Message Bodies)
+RFC 2033 (LMTP protocol)
 RFC 2034 (Enhanced Status Codes)
+RFC 2045 (MIME: Format of Internet Message Bodies)
 RFC 2046 (MIME: Media Types)
 RFC 2554 (AUTH command)
 RFC 2821 (SMTP protocol)
@@ -77,17 +114,23 @@ other trouble.
 .SH BUGS
 .ad
 .fi
-SMTP connection caching does not work with TLS. The necessary
+SMTP and LMTP connection caching does not work with TLS. The necessary
 support for TLS object passivation and re-activation does not
 exist without closing the session, which defeats the purpose.
 
-SMTP connection caching assumes that SASL credentials are valid for
-all destinations that map onto the same IP address and TCP port.
+SMTP and LMTP connection caching assumes that SASL credentials
+are valid for all destinations that map onto the same IP
+address and TCP port.
 .SH "CONFIGURATION PARAMETERS"
 .na
 .nf
 .ad
 .fi
+Most smtp_\fIxxx\fR configuration parameters have an
+lmtp_\fIxxx\fR "ghost" parameter for the equivalent LMTP
+feature. This document describes only those LMTP-related
+parameters that aren't simply "ghost" parameters.
+
 Changes to \fBmain.cf\fR are picked up automatically, as \fBsmtp\fR(8)
 processes run for only a limited amount of time. Use the command
 "\fBpostfix reload\fR" to speed up a change.
@@ -146,6 +189,17 @@ from a remote SMTP server.
 Optional lookup tables that perform address rewriting in the
 SMTP client, typically to transform a locally valid address into
 a globally valid address when sending mail across the Internet.
+.PP
+Available in Postfix version 2.3 and later:
+.IP "\fBlmtp_discard_lhlo_keyword_address_maps (empty)\fR"
+Lookup tables, indexed by the remote LMTP server address, with
+case insensitive lists of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server.
+.IP "\fBlmtp_discard_lhlo_keywords ($myhostname)\fR"
+A case insensitive list of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server.
 .SH "MIME PROCESSING CONTROLS"
 .na
 .nf
@@ -270,6 +324,9 @@ zero (use the operating system built-in time limit).
 .IP "\fBsmtp_helo_timeout (300s)\fR"
 The SMTP client time limit for sending the HELO or EHLO command,
 and for receiving the initial server response.
+.IP "\fBlmtp_lhlo_timeout (300s)\fR"
+The LMTP client time limit for sending the LHLO command, and
+for receiving the initial server response.
 .IP "\fBsmtp_xforward_timeout (300s)\fR"
 The SMTP client time limit for sending the XFORWARD command, and
 for receiving the server response.
@@ -316,6 +373,11 @@ connection repeatedly.
 .IP "\fBsmtp_connection_cache_time_limit (2s)\fR"
 When SMTP connection caching is enabled, the amount of time that
 an unused SMTP client socket is kept open before it is closed.
+.PP
+Available in Postfix version 2.3 and later:
+.IP "\fBconnection_cache_protocol_timeout (5s)\fR"
+Time limit for connection cache connect, send or receive
+operations.
 .SH "TROUBLE SHOOTING CONTROLS"
 .na
 .nf
@@ -353,9 +415,6 @@ The maximal number of digits after the decimal point when logging
 sub-second delay values.
 .IP "\fBdisable_dns_lookups (no)\fR"
 Disable DNS lookups in the Postfix SMTP and LMTP clients.
-.IP "\fBfallback_relay (empty)\fR"
-Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable.
 .IP "\fBinet_interfaces (all)\fR"
 The network interface addresses that this mail system receives
 mail on.
@@ -365,6 +424,8 @@ or accepting connections.
 .IP "\fBipc_timeout (3600s)\fR"
 The time limit for sending or receiving information over an internal
 communication channel.
+.IP "\fBlmtp_tcp_port (24)\fR"
+The default TCP port that the Postfix LMTP client connects to.
 .IP "\fBmax_idle (100s)\fR"
 The maximum amount of time that an idle Postfix daemon process
 waits for the next service request before exiting.
@@ -386,6 +447,8 @@ An optional numerical network address that the SMTP client should
 bind to when making an IPv6 connection.
 .IP "\fBsmtp_helo_name ($myhostname)\fR"
 The hostname to send in the SMTP EHLO or HELO command.
+.IP "\fBlmtp_lhlo_name ($myhostname)\fR"
+The hostname to send in the LMTP LHLO command.
 .IP "\fBsmtp_host_lookup (dns)\fR"
 What mechanisms when the SMTP client uses to look up a host's IP
 address.
@@ -396,6 +459,16 @@ The syslog facility of Postfix logging.
 .IP "\fBsyslog_name (postfix)\fR"
 The mail system name that is prepended to the process name in syslog
 records, so that "smtpd" becomes, for example, "postfix/smtpd".
+.PP
+Available with Postfix 2.2 and earlier:
+.IP "\fBfallback_relay (empty)\fR"
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable.
+.PP
+Available with Postfix 2.3 and later:
+.IP "\fBsmtp_fallback_relay ($fallback_relay)\fR"
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable.
 .SH "SEE ALSO"
 .na
 .nf
index 00fb66a3ac85cf30f3d0063bb717f7c4947c6e8b..eab0521be135631b0965c50ff32f05a49e9975af 100755 (executable)
@@ -313,6 +313,7 @@ while (<>) {
 
     s;\bconnection_cache_service\b;<a href="postconf.5.html#connection_cache_service">$&</a>;g;
     s;\bconnection_cache_status_update_time\b;<a href="postconf.5.html#connection_cache_status_update_time">$&</a>;g;
+    s;\bconnection_cache_protocol_timeout\b;<a href="postconf.5.html#connection_cache_protocol_timeout">$&</a>;g;
     s;\bconnection_cache_ttl_limit\b;<a href="postconf.5.html#connection_cache_ttl_limit">$&</a>;g;
 
     s;\bshow_user_unknown_table_name\b;<a href="postconf.5.html#show_user_unknown_table_name">$&</a>;g;
index 9f61f108cf71c4bb3931292e1179e96cdd4af281..cf73234eb741bc7882831c773a564bfb901696dd 100644 (file)
@@ -1238,15 +1238,37 @@ Example:
 export_environment = TZ PATH=/bin:/usr/bin
 </pre>
 
+%PARAM smtp_fallback_relay $fallback_relay
+
+<p>
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable. With Postfix 2.2 and earlier this
+parameter is called fallback_relay.  </p>
+
+<p>
+By default, mail is returned to the sender when a destination is
+not found, and delivery is deferred when a destination is unreachable.
+</p>
+
+<p> The fallback relays must be SMTP destinations. Specify a domain,
+host, host:port, [host]:port, [address] or [address]:port; the form
+[host] turns off MX lookups.  If you specify multiple SMTP
+destinations, Postfix will try them in the specified order.  </p>
+
+<p> To prevent mailer loops between MX hosts and fall-back hosts,
+Postfix version 2.3 and later will not use the smtp_fallback_relay
+feature for destinations that it is MX host for. </p>
+
 %PARAM fallback_relay 
 
 <p>
 Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable.  </p>
+found or that are unreachable. With Postfix 2.3 this parameter
+is renamed to smtp_fallback_relay. </p>
 
 <p>
 By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred if a destination is unreachable.
+not found, and delivery is deferred when a destination is unreachable.
 </p>
 
 <p> The fallback relays must be SMTP destinations. Specify a domain,
@@ -1254,7 +1276,8 @@ host, host:port, [host]:port, [address] or [address]:port; the form
 [host] turns off MX lookups.  If you specify multiple SMTP
 destinations, Postfix will try them in the specified order.  </p>
 
-<p> Note: do not use the fallback_relay feature when relaying mail
+<p> Note: before Postfix 2.2, do not use the fallback_relay feature
+when relaying mail
 for a backup or primary MX domain. Mail would loop between the
 Postfix MX host and the fallback_relay host when the final destination
 is unavailable. </p>
@@ -1271,7 +1294,8 @@ as the right-hand side for backup or primary MX domain entries.
 
 </ul>
 
-<p> These are default settings in Postfix version 2.2 and later.
+<p> Postfix version 2.2 and later will not use the fallback_relay feature
+for destinations that it is MX host for.
 </p>
 
 %PARAM fast_flush_domains $relay_domains
@@ -3614,6 +3638,9 @@ IP address),
 [] or non-default TCP port), as specified in main.cf or in the
 transport map,
 
+<li> if mail is sent via a UNIX-domain socket: a pathname (without
+the unix: prefix),
+
 <li> a /file/name with domain names and/or relay host names as
 defined above,
 
@@ -6255,6 +6282,14 @@ a "type:table" lookup table is matched when a name matches a lookup key
 (the lookup result is ignored).  Continue long lines by starting the
 next line with whitespace.  </p>
 
+<p>
+Example:
+</p>
+
+<pre>
+authorized_submit_users = !www, static:all
+</pre>
+
 <p>
 This feature is available in Postfix 2.2 and later.
 </p>
@@ -8719,7 +8754,7 @@ is placed into the Postfix configuration directory.  </p>
 
 <p> A sender-dependent override for the global relayhost parameter
 setting. The tables are searched by the sender address and by the
-sender @domain. This information is overruled with relay_transport,
+@domain. This information is overruled with relay_transport,
 default_transport and with the transport(5) table. </p>
 
 <p>
@@ -8749,3 +8784,255 @@ appropriate credentials.  </p>
 This feature is available in Postfix 2.3 and later.
 </p>
 
+%PARAM lmtp_lhlo_name $myhostname
+
+<p>
+The hostname to send in the LMTP LHLO command.
+</p>
+
+<p>
+The default value is the machine hostname.  Specify a hostname or
+[ip.add.re.ss].
+</p>
+
+<p>
+This information can be specified in the main.cf file for all LMTP
+clients, or it can be specified in the master.cf file for a specific
+client, for example:
+</p>
+
+<pre>
+  /etc/postfix/master.cf:
+        mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com
+</pre>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+%PARAM lmtp_discard_lhlo_keyword_address_maps
+
+<p> Lookup tables, indexed by the remote LMTP server address, with
+case insensitive lists of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server. See lmtp_discard_lhlo_keywords for
+details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_discard_lhlo_keywords $myhostname
+
+<p> A case insensitive list of LHLO keywords (pipelining, starttls,
+auth, etc.) that the LMTP client will ignore in the LHLO response
+from a remote LMTP server. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
+this action from being logged. </p>
+
+<li> <p> Use the lmtp_discard_lhlo_keyword_address_maps feature to
+discard LHLO keywords selectively. </p>
+
+</ul>
+
+%PARAM lmtp_lhlo_timeout 300s
+
+<p> The LMTP client time limit for sending the LHLO command, and
+for receiving the initial server response. </p>
+
+<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks).  The default time unit is s (seconds).  </p>
+
+%PARAM lmtp_sasl_tls_security_options $var_lmtp_sasl_opts
+
+<p> The LMTP-specific version of the smtp_sasl_tls_security_options
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sasl_mechanism_filter
+
+<p> The LMTP-specific version of the smtp_sasl_mechanism_filter
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_bind_address
+
+<p> The LMTP-specific version of the smtp_bind_address configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_bind_address6
+
+<p> The LMTP-specific version of the smtp_bind_address6 configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_host_lookup dns
+
+<p> The LMTP-specific version of the smtp_host_lookup configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_cache_destinations
+
+<p> The LMTP-specific version of the smtp_connection_cache_destinations
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_per_site
+
+<p> The LMTP-specific version of the smtp_tls_per_site configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_generic_maps
+
+<p> The LMTP-specific version of the smtp_generic_maps configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_pix_workaround_threshold_time 500s
+
+<p> The LMTP-specific version of the smtp_pix_workaround_threshold_time
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_pix_workaround_delay_time 10s
+
+<p> The LMTP-specific version of the smtp_pix_workaround_delay_time
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_reuse_time_limit 300s
+
+<p> The LMTP-specific version of the smtp_connection_reuse_time_limit
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_starttls_timeout 300s
+
+<p> The LMTP-specific version of the smtp_starttls_timeout configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_line_length_limit 990
+
+<p> The LMTP-specific version of the smtp_line_length_limit
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_mx_address_limit 5
+
+<p> The LMTP-specific version of the smtp_mx_address_limit configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_mx_session_limit 2
+
+<p> The LMTP-specific version of the smtp_mx_session_limit configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_scert_verifydepth 5
+
+<p> The LMTP-specific version of the smtp_tls_scert_verifydepth
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_skip_5xx_greeting yes
+
+<p> The LMTP-specific version of the smtp_skip_5xx_greeting
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_randomize_addresses yes
+
+<p> The LMTP-specific version of the smtp_randomize_addresses
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_quote_rfc821_envelope yes
+
+<p> The LMTP-specific version of the smtp_quote_rfc821_envelope
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_defer_if_no_mx_address_found no
+
+<p> The LMTP-specific version of the smtp_defer_if_no_mx_address_found
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_cache_on_demand yes
+
+<p> The LMTP-specific version of the smtp_connection_cache_on_demand
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_use_tls no
+
+<p> The LMTP-specific version of the smtp_use_tls configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_enforce_tls no
+
+<p> The LMTP-specific version of the smtp_enforce_tls configuration
+parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_enforce_peername yes
+
+<p> The LMTP-specific version of the smtp_tls_enforce_peername
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_note_starttls_offer no
+
+<p> The LMTP-specific version of the smtp_tls_note_starttls_offer
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sender_dependent_authentication no
+
+<p> The LMTP-specific version of the smtp_sender_dependent_authentication
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM connection_cache_protocol_timeout 5s
+
+<p> Time limit for connection cache connect, send or receive
+operations.  The time limit is enforced in the client. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
index 9a9ad6104453afbd23974eec178b4046b67ba86d..590a02221a4843a9c757dbfd672f833be569c5f3 100644 (file)
@@ -1559,14 +1559,15 @@ scache.o: ../../include/vstring_vstream.h
 scache.o: scache.c
 scache.o: scache.h
 scache_clnt.o: ../../include/attr.h
+scache_clnt.o: ../../include/auto_clnt.h
 scache_clnt.o: ../../include/iostuff.h
 scache_clnt.o: ../../include/msg.h
 scache_clnt.o: ../../include/mymalloc.h
+scache_clnt.o: ../../include/stringops.h
 scache_clnt.o: ../../include/sys_defs.h
 scache_clnt.o: ../../include/vbuf.h
 scache_clnt.o: ../../include/vstream.h
 scache_clnt.o: ../../include/vstring.h
-scache_clnt.o: clnt_stream.h
 scache_clnt.o: mail_params.h
 scache_clnt.o: mail_proto.h
 scache_clnt.o: scache.h
index 943a58c257eaf7be39495da255e4361f24377f29..09403e820b532bb367d2d00db64046513bd0d896 100644 (file)
@@ -69,6 +69,9 @@
 #include <deliver_pass.h>
 #include <dsb_scan.h>
 
+#define DELIVER_PASS_DEFER     1
+#define DELIVER_PASS_UNKNOWN   2
+
 /* deliver_pass_initial_reply - retrieve initial delivery process response */
 
 static int deliver_pass_initial_reply(VSTREAM *stream)
@@ -140,9 +143,10 @@ static int deliver_pass_final_reply(VSTREAM *stream, DSN_BUF *dsb)
                  ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &stat,
                  ATTR_TYPE_END) != 2) {
        msg_warn("%s: malformed response", VSTREAM_PATH(stream));
-       stat = -1;
+       return (DELIVER_PASS_UNKNOWN);
+    } else {
+       return (stat ? DELIVER_PASS_DEFER : 0);
     }
-    return (stat);
 }
 
 /* deliver_pass - deliver one per-site queue entry */
@@ -153,6 +157,7 @@ int     deliver_pass(const char *class, const char *service,
 {
     VSTREAM *stream;
     DSN_BUF *dsb;
+    DSN     dsn;
     int     status;
     char   *saved_service;
     char   *transport;
@@ -184,10 +189,23 @@ int     deliver_pass(const char *class, const char *service,
      * XXX Can't pass back hop status info because the problem is with a
      * different transport.
      */
-    if ((status = deliver_pass_initial_reply(stream)) == 0
-       && (status = deliver_pass_send_request(stream, request, nexthop,
-                                              rcpt)) == 0)
-       status = deliver_pass_final_reply(stream, dsb);
+    if (deliver_pass_initial_reply(stream) != 0
+       || deliver_pass_send_request(stream, request, nexthop, rcpt) != 0) {
+       DSN_SMTP(&dsn, "4.3.0",
+                "451 mail transport unavailable",
+                "mail transport unavailable");
+       status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
+                             request->queue_id, &request->msg_stats,
+                             rcpt, "none", &dsn);
+    } else if ((status = deliver_pass_final_reply(stream, dsb))
+              == DELIVER_PASS_UNKNOWN) {
+       DSN_SMTP(&dsn, "4.3.0",
+                "451 unknown mail transport error",
+                "unknown mail transport error");
+       status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
+                             request->queue_id, &request->msg_stats,
+                             rcpt, "none", &dsn);
+    }
 
     /*
      * Clean up.
index fba702725caf81d87353306202112596ac193d8c..1391e5d7c3f1c5299319c2381000e8279a613500 100644 (file)
@@ -17,7 +17,7 @@
 /*             char    *nexthop;
 /*             char    *encoding;
 /*             char    *sender;
-/*             MSG_STATS stats;
+/*             MSG_STATS msg_stats;
 /*             RECIPIENT_LIST rcpt_list;
 /*             DSN     *hop_status;
 /*             char    *client_name;
@@ -240,7 +240,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
                  ATTR_TYPE_STR, MAIL_ATTR_SENDER, address,
                  ATTR_TYPE_STR, MAIL_ATTR_DSN_ENVID, dsn_envid,
                  ATTR_TYPE_NUM, MAIL_ATTR_DSN_RET, &dsn_ret,
-                 ATTR_TYPE_FUNC, msg_stats_scan, (void *) &request->msg_stats,
+              ATTR_TYPE_FUNC, msg_stats_scan, (void *) &request->msg_stats,
                  ATTR_TYPE_STR, MAIL_ATTR_CLIENT_NAME, client_name,
                  ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, client_addr,
                  ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, client_proto,
@@ -304,6 +304,11 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
                           vstring_str(orig_addr),
                           vstring_str(address));
     }
+    if (request->rcpt_list.len <= 0) {
+       msg_warn("%s: no recipients in delivery request for destination %s",
+                request->queue_id, request->nexthop);
+       return (-1);
+    }
 
     /*
      * Open the queue file and set a shared lock, in order to prevent
index fc513fe02513603abfba5c5477dd8b04e4d2be69..eff145f19d15ae2d859281994b304b3dee6b7e05 100644 (file)
@@ -189,7 +189,9 @@ extern char *var_relayhost;
 #define DEF_SND_RELAY_MAPS     ""
 extern char *var_snd_relay_maps;
 
-#define VAR_FALLBACK_RELAY     "fallback_relay"
+#define VAR_SMTP_FALLBACK      "smtp_fallback_relay"
+#define DEF_SMTP_FALLBACK      "$fallback_relay"
+#define VAR_LMTP_FALLBACK      "smtp_fallback_relay"
 #define DEF_FALLBACK_RELAY     ""
 extern char *var_fallback_relay;
 
@@ -202,14 +204,20 @@ extern bool var_disable_dns;
 
 #define VAR_SMTP_HOST_LOOKUP   "smtp_host_lookup"
 #define DEF_SMTP_HOST_LOOKUP   SMTP_HOST_LOOKUP_DNS
+#define VAR_LMTP_HOST_LOOKUP   "lmtp_host_lookup"
+#define DEF_LMTP_HOST_LOOKUP   SMTP_HOST_LOOKUP_DNS
 extern int var_smtp_dns_lookup;
 
 #define VAR_SMTP_MXADDR_LIMIT  "smtp_mx_address_limit"
 #define DEF_SMTP_MXADDR_LIMIT  5
+#define VAR_LMTP_MXADDR_LIMIT  "lmtp_mx_address_limit"
+#define DEF_LMTP_MXADDR_LIMIT  5
 extern int var_smtp_mxaddr_limit;
 
 #define VAR_SMTP_MXSESS_LIMIT  "smtp_mx_session_limit"
 #define DEF_SMTP_MXSESS_LIMIT  2
+#define VAR_LMTP_MXSESS_LIMIT  "lmtp_mx_session_limit"
+#define DEF_LMTP_MXSESS_LIMIT  2
 extern int var_smtp_mxsess_limit;
 
  /*
@@ -848,22 +856,32 @@ extern char *var_inet_protocols;
 #define DEF_BESTMX_TRANSP      ""
 extern char *var_bestmx_transp;
 
-#define VAR_SMTP_CACHE_CONN    "smtp_connection_cache_time_limit"
-#define DEF_SMTP_CACHE_CONN    "2s"
+#define VAR_SMTP_CACHE_CONNT   "smtp_connection_cache_time_limit"
+#define DEF_SMTP_CACHE_CONNT   "2s"
+#define VAR_LMTP_CACHE_CONNT   "smtp_connection_cache_time_limit"
+#define DEF_LMTP_CACHE_CONNT   "2s"
 extern int var_smtp_cache_conn;
 
 #define VAR_SMTP_REUSE_TIME    "smtp_connection_reuse_time_limit"
 #define DEF_SMTP_REUSE_TIME    "300s"
+#define VAR_LMTP_REUSE_TIME    "lmtp_connection_reuse_time_limit"
+#define DEF_LMTP_REUSE_TIME    "300s"
 extern int var_smtp_reuse_time;
 
 #define VAR_SMTP_CACHE_DEST    "smtp_connection_cache_destinations"
 #define DEF_SMTP_CACHE_DEST    ""
+#define VAR_LMTP_CACHE_DEST    "lmtp_connection_cache_destinations"
+#define DEF_LMTP_CACHE_DEST    ""
 extern char *var_smtp_cache_dest;
 
 #define VAR_SMTP_CACHE_DEMAND  "smtp_connection_cache_on_demand"
 #ifndef DEF_SMTP_CACHE_DEMAND
 #define DEF_SMTP_CACHE_DEMAND  1
 #endif
+#define VAR_LMTP_CACHE_DEMAND  "lmtp_connection_cache_on_demand"
+#ifndef DEF_LMTP_CACHE_DEMAND
+#define DEF_LMTP_CACHE_DEMAND  1
+#endif
 extern bool var_smtp_cache_demand;
 
 #define VAR_SMTP_CONN_TMOUT    "smtp_connect_timeout"
@@ -872,6 +890,8 @@ extern int var_smtp_conn_tmout;
 
 #define VAR_SMTP_HELO_TMOUT    "smtp_helo_timeout"
 #define DEF_SMTP_HELO_TMOUT    "300s"
+#define VAR_LMTP_HELO_TMOUT    "lmtp_lhlo_timeout"
+#define DEF_LMTP_HELO_TMOUT    "300s"
 extern int var_smtp_helo_tmout;
 
 #define VAR_SMTP_XFWD_TMOUT    "smtp_xforward_timeout"
@@ -880,6 +900,8 @@ extern int var_smtp_xfwd_tmout;
 
 #define VAR_SMTP_STARTTLS_TMOUT        "smtp_starttls_timeout"
 #define DEF_SMTP_STARTTLS_TMOUT        "300s"
+#define VAR_LMTP_STARTTLS_TMOUT        "lmtp_starttls_timeout"
+#define DEF_LMTP_STARTTLS_TMOUT        "300s"
 extern int var_smtp_starttls_tmout;
 
 #define VAR_SMTP_MAIL_TMOUT    "smtp_mail_timeout"
@@ -912,10 +934,14 @@ extern int var_smtp_quit_tmout;
 
 #define VAR_SMTP_QUOTE_821_ENV "smtp_quote_rfc821_envelope"
 #define DEF_SMTP_QUOTE_821_ENV 1
+#define VAR_LMTP_QUOTE_821_ENV "lmtp_quote_rfc821_envelope"
+#define DEF_LMTP_QUOTE_821_ENV 1
 extern int var_smtp_quote_821_env;
 
 #define VAR_SMTP_SKIP_5XX      "smtp_skip_5xx_greeting"
 #define DEF_SMTP_SKIP_5XX      1
+#define VAR_LMTP_SKIP_5XX      "lmtp_skip_5xx_greeting"
+#define DEF_LMTP_SKIP_5XX      1
 extern bool var_smtp_skip_5xx_greeting;
 
 #define VAR_IGN_MX_LOOKUP_ERR  "ignore_mx_lookup_error"
@@ -940,34 +966,50 @@ extern bool var_smtp_never_ehlo;
 
 #define VAR_SMTP_BIND_ADDR     "smtp_bind_address"
 #define DEF_SMTP_BIND_ADDR     ""
+#define VAR_LMTP_BIND_ADDR     "lmtp_bind_address"
+#define DEF_LMTP_BIND_ADDR     ""
 extern char *var_smtp_bind_addr;
 
 #define VAR_SMTP_BIND_ADDR6    "smtp_bind_address6"
 #define DEF_SMTP_BIND_ADDR6    ""
+#define VAR_LMTP_BIND_ADDR6    "lmtp_bind_address6"
+#define DEF_LMTP_BIND_ADDR6    ""
 extern char *var_smtp_bind_addr6;
 
 #define VAR_SMTP_HELO_NAME     "smtp_helo_name"
 #define DEF_SMTP_HELO_NAME     "$myhostname"
+#define VAR_LMTP_HELO_NAME     "lmtp_lhlo_name"
+#define DEF_LMTP_HELO_NAME     "$myhostname"
 extern char *var_smtp_helo_name;
 
 #define VAR_SMTP_RAND_ADDR     "smtp_randomize_addresses"
 #define DEF_SMTP_RAND_ADDR     1
+#define VAR_LMTP_RAND_ADDR     "lmtp_randomize_addresses"
+#define DEF_LMTP_RAND_ADDR     1
 extern bool var_smtp_rand_addr;
 
 #define VAR_SMTP_LINE_LIMIT    "smtp_line_length_limit"
 #define DEF_SMTP_LINE_LIMIT    990
+#define VAR_LMTP_LINE_LIMIT    "lmtp_line_length_limit"
+#define DEF_LMTP_LINE_LIMIT    990
 extern int var_smtp_line_limit;
 
 #define VAR_SMTP_PIX_THRESH    "smtp_pix_workaround_threshold_time"
 #define DEF_SMTP_PIX_THRESH    "500s"
+#define VAR_LMTP_PIX_THRESH    "lmtp_pix_workaround_threshold_time"
+#define DEF_LMTP_PIX_THRESH    "500s"
 extern int var_smtp_pix_thresh;
 
 #define VAR_SMTP_PIX_DELAY     "smtp_pix_workaround_delay_time"
 #define DEF_SMTP_PIX_DELAY     "10s"
+#define VAR_LMTP_PIX_DELAY     "lmtp_pix_workaround_delay_time"
+#define DEF_LMTP_PIX_DELAY     "10s"
 extern int var_smtp_pix_delay;
 
 #define VAR_SMTP_DEFER_MXADDR  "smtp_defer_if_no_mx_address_found"
 #define DEF_SMTP_DEFER_MXADDR  0
+#define VAR_LMTP_DEFER_MXADDR  "lmtp_defer_if_no_mx_address_found"
+#define DEF_LMTP_DEFER_MXADDR  0
 extern bool var_smtp_defer_mxaddr;
 
 #define VAR_SMTP_SEND_XFORWARD "smtp_send_xforward_command"
@@ -976,6 +1018,8 @@ extern bool var_smtp_send_xforward;
 
 #define VAR_SMTP_GENERIC_MAPS  "smtp_generic_maps"
 #define DEF_SMTP_GENERIC_MAPS  ""
+#define VAR_LMTP_GENERIC_MAPS  "lmtp_generic_maps"
+#define DEF_LMTP_GENERIC_MAPS  ""
 extern char *var_smtp_generic_maps;
 
  /*
@@ -1113,22 +1157,32 @@ extern int var_smtpd_tls_scache_timeout;
 
 #define VAR_SMTP_TLS_PER_SITE  "smtp_tls_per_site"
 #define DEF_SMTP_TLS_PER_SITE  ""
+#define VAR_LMTP_TLS_PER_SITE  "lmtp_tls_per_site"
+#define DEF_LMTP_TLS_PER_SITE  ""
 extern char *var_smtp_tls_per_site;
 
 #define VAR_SMTP_USE_TLS       "smtp_use_tls"
 #define DEF_SMTP_USE_TLS       0
+#define VAR_LMTP_USE_TLS       "lmtp_use_tls"
+#define DEF_LMTP_USE_TLS       0
 extern bool var_smtp_use_tls;
 
 #define VAR_SMTP_ENFORCE_TLS   "smtp_enforce_tls"
 #define DEF_SMTP_ENFORCE_TLS   0
+#define VAR_LMTP_ENFORCE_TLS   "lmtp_enforce_tls"
+#define DEF_LMTP_ENFORCE_TLS   0
 extern bool var_smtp_enforce_tls;
 
 #define VAR_SMTP_TLS_ENFORCE_PN        "smtp_tls_enforce_peername"
 #define DEF_SMTP_TLS_ENFORCE_PN        1
+#define VAR_LMTP_TLS_ENFORCE_PN        "lmtp_tls_enforce_peername"
+#define DEF_LMTP_TLS_ENFORCE_PN        1
 extern bool var_smtp_tls_enforce_peername;
 
 #define VAR_SMTP_TLS_SCERT_VD  "smtp_tls_scert_verifydepth"
 #define DEF_SMTP_TLS_SCERT_VD  5
+#define VAR_LMTP_TLS_SCERT_VD  "lmtp_tls_scert_verifydepth"
+#define DEF_LMTP_TLS_SCERT_VD  5
 extern int var_smtp_tls_scert_vd;
 
 #define VAR_SMTP_TLS_CERT_FILE "smtp_tls_cert_file"
@@ -1165,6 +1219,8 @@ extern int var_smtp_tls_loglevel;
 
 #define VAR_SMTP_TLS_NOTEOFFER "smtp_tls_note_starttls_offer"
 #define DEF_SMTP_TLS_NOTEOFFER 0
+#define VAR_LMTP_TLS_NOTEOFFER "lmtp_tls_note_starttls_offer"
+#define DEF_LMTP_TLS_NOTEOFFER 0
 extern bool var_smtp_tls_note_starttls_offer;
 
 #define VAR_SMTP_TLS_SCACHE_DB "smtp_tls_session_cache_database"
@@ -1233,10 +1289,14 @@ extern char *var_smtp_sasl_opts;
 
 #define VAR_SMTP_SASL_MECHS    "smtp_sasl_mechanism_filter"
 #define DEF_SMTP_SASL_MECHS    ""
+#define VAR_LMTP_SASL_MECHS    "lmtp_sasl_mechanism_filter"
+#define DEF_LMTP_SASL_MECHS    ""
 extern char *var_smtp_sasl_mechs;
 
 #define VAR_SMTP_SASL_TLS_OPTS "smtp_sasl_tls_security_options"
 #define DEF_SMTP_SASL_TLS_OPTS "$var_smtp_sasl_opts"
+#define VAR_LMTP_SASL_TLS_OPTS "lmtp_sasl_tls_security_options"
+#define DEF_LMTP_SASL_TLS_OPTS "$var_lmtp_sasl_opts"
 extern char *var_smtp_sasl_tls_opts;
 
  /*
@@ -1314,8 +1374,8 @@ extern char *var_lmtp_sasl_opts;
   * 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 DEF_LMTP_TCP_PORT      "24"
+extern char *var_lmtp_tcp_port;
 
 #define VAR_LMTP_CACHE_CONN    "lmtp_cache_connection"
 #define DEF_LMTP_CACHE_CONN    1
@@ -2081,10 +2141,14 @@ extern char *var_flush_service;
  /*
   * Session cache service.
   */
-#define VAR_SCACHE_SERVICE             "connection_cache_service"
+#define VAR_SCACHE_SERVICE             "connection_cache_service_name"
 #define DEF_SCACHE_SERVICE             "scache"
 extern char *var_scache_service;
 
+#define VAR_SCACHE_PROTO_TMOUT         "connection_cache_protocol_timeout"
+#define DEF_SCACHE_PROTO_TMOUT         "5s"
+extern int var_scache_proto_tmout;
+
 #define VAR_SCACHE_TTL_LIM             "connection_cache_ttl_limit"
 #define DEF_SCACHE_TTL_LIM             "2s"
 extern int var_scache_ttl_lim;
@@ -2335,7 +2399,7 @@ extern int var_anvil_stat_time;
 #if 0
 #include <anvil_clnt.h>
 
-#define VAR_ANVIL_SERVICE              "client_connection_rate_service"
+#define VAR_ANVIL_SERVICE              "client_connection_rate_service_name"
 #define DEF_ANVIL_SERVICE              "local:" ANVIL_CLASS "/" ANVIL_SERVICE
 extern char *var_anvil_service;
 
@@ -2367,10 +2431,14 @@ extern char *var_smtpd_ehlo_dis_maps;
 
 #define VAR_SMTP_EHLO_DIS_WORDS                "smtp_discard_ehlo_keywords"
 #define DEF_SMTP_EHLO_DIS_WORDS                ""
+#define VAR_LMTP_EHLO_DIS_WORDS                "lmtp_discard_lhlo_keywords"
+#define DEF_LMTP_EHLO_DIS_WORDS                ""
 extern char *var_smtp_ehlo_dis_words;
 
 #define VAR_SMTP_EHLO_DIS_MAPS         "smtp_discard_ehlo_keyword_address_maps"
 #define DEF_SMTP_EHLO_DIS_MAPS         ""
+#define VAR_LMTP_EHLO_DIS_MAPS         "lmtp_discard_lhlo_keyword_address_maps"
+#define DEF_LMTP_EHLO_DIS_MAPS         ""
 extern char *var_smtp_ehlo_dis_maps;
 
  /*
@@ -2417,6 +2485,8 @@ extern char *var_bounce_tmpl;
   */
 #define VAR_SMTP_SENDER_AUTH   "smtp_sender_dependent_authentication"
 #define DEF_SMTP_SENDER_AUTH   0
+#define VAR_LMTP_SENDER_AUTH   "lmtp_sender_dependent_authentication"
+#define DEF_LMTP_SENDER_AUTH   0
 extern bool var_smtp_sender_auth;
 
 /* LICENSE
index 08a7f541dd80efebcb26f963922fd3deb0bbc121..f1d12a758de8a96f05fea0d29c39ed41a4864c4c 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20051202"
+#define MAIL_RELEASE_DATE      "20051208"
 #define MAIL_VERSION_NUMBER    "2.3"
 
 #ifdef SNAPSHOT
index 1670546c5a61a89da19d189bbedb465a80fc361b..836d76599007b5f8413e94db8570e2dfcb431fe0 100644 (file)
@@ -110,7 +110,7 @@ struct SCACHE {
 };
 
 extern SCACHE *scache_single_create(void);
-extern SCACHE *scache_clnt_create(const char *, int, int);
+extern SCACHE *scache_clnt_create(const char *, int, int, int);
 extern SCACHE *scache_multi_create(void);
 
 #define scache_save_endp(scache, ttl, endp_label, endp_prop, fd) \
index f8098eea3c73d0b03f429d88e31544b5592c8dbe..c1d3a058b7461478152ce2315cc5447abb2cea95 100644 (file)
@@ -6,8 +6,9 @@
 /* SYNOPSIS
 /*     #include <scache.h>
 /* DESCRIPTION
-/*     SCACHE *scache_clnt_create(server, idle_limit, ttl_limit)
+/*     SCACHE *scache_clnt_create(server, timeout, idle_limit, ttl_limit)
 /*     const char *server;
+/*     int     timeout;
 /*     int     idle_limit;
 /*     int     ttl_limit;
 /* DESCRIPTION
@@ -19,6 +20,8 @@
 /*     Arguments:
 /* .IP server
 /*     The session cache service name.
+/* .IP timeout
+/*     Time limit for connect, send or receive operations.
 /* .IP idle_limit
 /*     Idle time after which the client disconnects.
 /* .IP ttl_limit
@@ -49,6 +52,8 @@
 
 #include <msg.h>
 #include <mymalloc.h>
+#include <auto_clnt.h>
+#include <stringops.h>
 
 /*#define msg_verbose 1*/
 
@@ -56,7 +61,6 @@
 
 #include <mail_proto.h>
 #include <mail_params.h>
-#include <clnt_stream.h>
 #include <scache.h>
 
 /* Application-specific. */
@@ -66,7 +70,7 @@
   */
 typedef struct {
     SCACHE  scache[1];                 /* super-class */
-    CLNT_STREAM *clnt_stream;          /* client endpoint */
+    AUTO_CLNT *auto_clnt;              /* client endpoint */
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
     VSTRING *dummy;                    /* dummy buffer */
 #endif
@@ -103,44 +107,45 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
      * the session cache service is CPU bound and making the client
      * asynchronous would just complicate the code.
      */
-    for (tries = 0; sp->clnt_stream != 0 ; tries++) {
-       stream = clnt_stream_access(sp->clnt_stream);
-       errno = 0;
-       if (attr_print(stream, ATTR_FLAG_NONE,
-                      ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP,
-                      ATTR_TYPE_NUM, MAIL_ATTR_TTL, endp_ttl,
-                      ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
-                      ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
-                      ATTR_TYPE_END) != 0
-           || vstream_fflush(stream)
+    for (tries = 0; sp->auto_clnt != 0; tries++) {
+       if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
+           errno = 0;
+           if (attr_print(stream, ATTR_FLAG_NONE,
+                        ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP,
+                          ATTR_TYPE_NUM, MAIL_ATTR_TTL, endp_ttl,
+                          ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
+                          ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
+                          ATTR_TYPE_END) != 0
+               || vstream_fflush(stream)
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
-           || attr_scan(stream, ATTR_FLAG_STRICT,
-                        ATTR_TYPE_STR, MAIL_ATTR_DUMMY, sp->dummy,
-                        ATTR_TYPE_END) != 1
+               || attr_scan(stream, ATTR_FLAG_STRICT,
+                            ATTR_TYPE_STR, MAIL_ATTR_DUMMY, sp->dummy,
+                            ATTR_TYPE_END) != 1
 #endif
-           || LOCAL_SEND_FD(vstream_fileno(stream), fd) < 0
-           || attr_scan(stream, ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
-                        ATTR_TYPE_END) != 1) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else {
-           if (msg_verbose && status != 0)
-               msg_warn("%s: descriptor save failed with status %d",
-                        myname, status);
-           break;
+               || LOCAL_SEND_FD(vstream_fileno(stream), fd) < 0
+               || attr_scan(stream, ATTR_FLAG_STRICT,
+                            ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
+                            ATTR_TYPE_END) != 1) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else {
+               if (msg_verbose && status != 0)
+                   msg_warn("%s: descriptor save failed with status %d",
+                            myname, status);
+               break;
+           }
        }
        /* Give up or recover. */
        if (tries >= SCACHE_MAX_TRIES - 1) {
            msg_warn("disabling connection caching");
-           clnt_stream_free(sp->clnt_stream);
-           sp->clnt_stream = 0;
+           auto_clnt_free(sp->auto_clnt);
+           sp->auto_clnt = 0;
            break;
        }
        sleep(1);                               /* XXX make configurable */
-       clnt_stream_recover(sp->clnt_stream);
+       auto_clnt_recover(sp->auto_clnt);
     }
     /* Always close the descriptor before returning. */
     if (close(fd) < 0)
@@ -164,61 +169,62 @@ static int scache_clnt_find_endp(SCACHE *scache, const char *endp_label,
      * the session cache service is CPU bound and making the client
      * asynchronous would just complicate the code.
      */
-    for (tries = 0; sp->clnt_stream != 0 ; tries++) {
-       stream = clnt_stream_access(sp->clnt_stream);
-       errno = 0;
-       if (attr_print(stream, ATTR_FLAG_NONE,
-                      ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_FIND_ENDP,
-                      ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
-                      ATTR_TYPE_END) != 0
-           || vstream_fflush(stream)
-           || attr_scan(stream, ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
-                        ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
-                        ATTR_TYPE_END) != 2) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else if (status != 0) {
-           if (msg_verbose)
-               msg_info("%s: not found: %s", myname, endp_label);
-           return (-1);
-       } else if (
+    for (tries = 0; sp->auto_clnt != 0; tries++) {
+       if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
+           errno = 0;
+           if (attr_print(stream, ATTR_FLAG_NONE,
+                        ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_FIND_ENDP,
+                          ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
+                          ATTR_TYPE_END) != 0
+               || vstream_fflush(stream)
+               || attr_scan(stream, ATTR_FLAG_STRICT,
+                            ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
+                            ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
+                            ATTR_TYPE_END) != 2) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else if (status != 0) {
+               if (msg_verbose)
+                   msg_info("%s: not found: %s", myname, endp_label);
+               return (-1);
+           } else if (
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
-                  attr_print(stream, ATTR_FLAG_NONE,
-                             ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
-                             ATTR_TYPE_END) != 0
-                  || vstream_fflush(stream) != 0
-                  || read_wait(vstream_fileno(stream),
-                               stream->timeout) < 0 || /* XXX */
+                      attr_print(stream, ATTR_FLAG_NONE,
+                                 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
+                                 ATTR_TYPE_END) != 0
+                      || vstream_fflush(stream) != 0
+                      || read_wait(vstream_fileno(stream),
+                                   stream->timeout) < 0 ||     /* XXX */
 #endif
-                  (fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else {
+                      (fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else {
 #ifdef MUST_READ_AFTER_SENDING_FD
-           (void) attr_print(stream, ATTR_FLAG_NONE,
-                             ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
-                             ATTR_TYPE_END);
-           (void) vstream_fflush(stream);
+               (void) attr_print(stream, ATTR_FLAG_NONE,
+                                 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
+                                 ATTR_TYPE_END);
+               (void) vstream_fflush(stream);
 #endif
-           if (msg_verbose)
-               msg_info("%s: endp=%s prop=%s fd=%d",
-                        myname, endp_label, STR(endp_prop), fd);
-           return (fd);
+               if (msg_verbose)
+                   msg_info("%s: endp=%s prop=%s fd=%d",
+                            myname, endp_label, STR(endp_prop), fd);
+               return (fd);
+           }
        }
        /* Give up or recover. */
        if (tries >= SCACHE_MAX_TRIES - 1) {
            msg_warn("disabling connection caching");
-           clnt_stream_free(sp->clnt_stream);
-           sp->clnt_stream = 0;
+           auto_clnt_free(sp->auto_clnt);
+           sp->auto_clnt = 0;
            return (-1);
        }
        sleep(1);                               /* XXX make configurable */
-       clnt_stream_recover(sp->clnt_stream);
+       auto_clnt_recover(sp->auto_clnt);
     }
     return (-1);
 }
@@ -251,39 +257,40 @@ static void scache_clnt_save_dest(SCACHE *scache, int dest_ttl,
      * the session cache service is CPU bound and making the client
      * asynchronous would just complicate the code.
      */
-    for (tries = 0; sp->clnt_stream != 0 ; tries++) {
-       stream = clnt_stream_access(sp->clnt_stream);
-       errno = 0;
-       if (attr_print(stream, ATTR_FLAG_NONE,
-                      ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_DEST,
-                      ATTR_TYPE_NUM, MAIL_ATTR_TTL, dest_ttl,
-                      ATTR_TYPE_STR, MAIL_ATTR_LABEL, dest_label,
-                      ATTR_TYPE_STR, MAIL_ATTR_PROP, dest_prop,
-                      ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
-                      ATTR_TYPE_END) != 0
-           || vstream_fflush(stream)
-           || attr_scan(stream, ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
-                        ATTR_TYPE_END) != 1) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else {
-           if (msg_verbose && status != 0)
-               msg_warn("%s: destination save failed with status %d",
-                        myname, status);
-           break;
-       }
+    for (tries = 0; sp->auto_clnt != 0; tries++) {
+       if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
+           errno = 0;
+           if (attr_print(stream, ATTR_FLAG_NONE,
+                        ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_DEST,
+                          ATTR_TYPE_NUM, MAIL_ATTR_TTL, dest_ttl,
+                          ATTR_TYPE_STR, MAIL_ATTR_LABEL, dest_label,
+                          ATTR_TYPE_STR, MAIL_ATTR_PROP, dest_prop,
+                          ATTR_TYPE_STR, MAIL_ATTR_LABEL, endp_label,
+                          ATTR_TYPE_END) != 0
+               || vstream_fflush(stream)
+               || attr_scan(stream, ATTR_FLAG_STRICT,
+                            ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
+                            ATTR_TYPE_END) != 1) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else {
+               if (msg_verbose && status != 0)
+                   msg_warn("%s: destination save failed with status %d",
+                            myname, status);
+               break;
+           }
+           }
        /* Give up or recover. */
        if (tries >= SCACHE_MAX_TRIES - 1) {
            msg_warn("disabling connection caching");
-           clnt_stream_free(sp->clnt_stream);
-           sp->clnt_stream = 0;
+           auto_clnt_free(sp->auto_clnt);
+           sp->auto_clnt = 0;
            break;
        }
        sleep(1);                               /* XXX make configurable */
-       clnt_stream_recover(sp->clnt_stream);
+       auto_clnt_recover(sp->auto_clnt);
     }
 }
 
@@ -305,62 +312,63 @@ static int scache_clnt_find_dest(SCACHE *scache, const char *dest_label,
      * the session cache service is CPU bound and making the client
      * asynchronous would just complicate the code.
      */
-    for (tries = 0; sp->clnt_stream != 0 ; tries++) {
-       stream = clnt_stream_access(sp->clnt_stream);
-       errno = 0;
-       if (attr_print(stream, ATTR_FLAG_NONE,
-                      ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_FIND_DEST,
-                      ATTR_TYPE_STR, MAIL_ATTR_LABEL, dest_label,
-                      ATTR_TYPE_END) != 0
-           || vstream_fflush(stream)
-           || attr_scan(stream, ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
-                        ATTR_TYPE_STR, MAIL_ATTR_PROP, dest_prop,
-                        ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
-                        ATTR_TYPE_END) != 3) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else if (status != 0) {
-           if (msg_verbose)
-               msg_info("%s: not found: %s", myname, dest_label);
-           return (-1);
-       } else if (
+    for (tries = 0; sp->auto_clnt != 0; tries++) {
+       if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
+           errno = 0;
+           if (attr_print(stream, ATTR_FLAG_NONE,
+                        ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_FIND_DEST,
+                          ATTR_TYPE_STR, MAIL_ATTR_LABEL, dest_label,
+                          ATTR_TYPE_END) != 0
+               || vstream_fflush(stream)
+               || attr_scan(stream, ATTR_FLAG_STRICT,
+                            ATTR_TYPE_NUM, MAIL_ATTR_STATUS, &status,
+                            ATTR_TYPE_STR, MAIL_ATTR_PROP, dest_prop,
+                            ATTR_TYPE_STR, MAIL_ATTR_PROP, endp_prop,
+                            ATTR_TYPE_END) != 3) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else if (status != 0) {
+               if (msg_verbose)
+                   msg_info("%s: not found: %s", myname, dest_label);
+               return (-1);
+           } else if (
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
-                  attr_print(stream, ATTR_FLAG_NONE,
-                             ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
-                             ATTR_TYPE_END) != 0
-                  || vstream_fflush(stream) != 0
-                  || read_wait(vstream_fileno(stream),
-                               stream->timeout) < 0 || /* XXX */
+                      attr_print(stream, ATTR_FLAG_NONE,
+                                 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
+                                 ATTR_TYPE_END) != 0
+                      || vstream_fflush(stream) != 0
+                      || read_wait(vstream_fileno(stream),
+                                   stream->timeout) < 0 ||     /* XXX */
 #endif
-                  (fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
-               msg_warn("problem talking to service %s: %m",
-                        VSTREAM_PATH(stream));
-           /* Give up or recover. */
-       } else {
+                      (fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
+               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+                   msg_warn("problem talking to service %s: %m",
+                            VSTREAM_PATH(stream));
+               /* Give up or recover. */
+           } else {
 #ifdef MUST_READ_AFTER_SENDING_FD
-           (void) attr_print(stream, ATTR_FLAG_NONE,
-                             ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
-                             ATTR_TYPE_END);
-           (void) vstream_fflush(stream);
+               (void) attr_print(stream, ATTR_FLAG_NONE,
+                                 ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
+                                 ATTR_TYPE_END);
+               (void) vstream_fflush(stream);
 #endif
-           if (msg_verbose)
-               msg_info("%s: dest=%s dest_prop=%s endp_prop=%s fd=%d",
+               if (msg_verbose)
+                   msg_info("%s: dest=%s dest_prop=%s endp_prop=%s fd=%d",
                    myname, dest_label, STR(dest_prop), STR(endp_prop), fd);
-           return (fd);
+               return (fd);
+           }
        }
        /* Give up or recover. */
        if (tries >= SCACHE_MAX_TRIES - 1) {
            msg_warn("disabling connection caching");
-           clnt_stream_free(sp->clnt_stream);
-           sp->clnt_stream = 0;
+           auto_clnt_free(sp->auto_clnt);
+           sp->auto_clnt = 0;
            return (-1);
        }
        sleep(1);                               /* XXX make configurable */
-       clnt_stream_recover(sp->clnt_stream);
+       auto_clnt_recover(sp->auto_clnt);
     }
     return (-1);
 }
@@ -381,8 +389,8 @@ static void scache_clnt_free(SCACHE *scache)
 {
     SCACHE_CLNT *sp = (SCACHE_CLNT *) scache;
 
-    if (sp->clnt_stream)
-       clnt_stream_free(sp->clnt_stream);
+    if (sp->auto_clnt)
+       auto_clnt_free(sp->auto_clnt);
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
     vstring_free(sp->dummy);
 #endif
@@ -391,9 +399,11 @@ static void scache_clnt_free(SCACHE *scache)
 
 /* scache_clnt_create - initialize */
 
-SCACHE *scache_clnt_create(const char *server, int idle_limit, int ttl_limit)
+SCACHE *scache_clnt_create(const char *server, int timeout,
+                                  int idle_limit, int ttl_limit)
 {
     SCACHE_CLNT *sp = (SCACHE_CLNT *) mymalloc(sizeof(*sp));
+    char   *service;
 
     sp->scache->save_endp = scache_clnt_save_endp;
     sp->scache->find_endp = scache_clnt_find_endp;
@@ -402,9 +412,10 @@ SCACHE *scache_clnt_create(const char *server, int idle_limit, int ttl_limit)
     sp->scache->size = scache_clnt_size;
     sp->scache->free = scache_clnt_free;
 
-    /* XXX Need flags to stop looping on ECONNREFUSED errors. */
-    sp->clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE, server,
-                                        idle_limit, ttl_limit);
+    service = concatenate("local:private/", var_scache_service, (char *) 0);
+    sp->auto_clnt = auto_clnt_create(service, timeout, idle_limit, ttl_limit);
+    myfree(service);
+
 #ifdef CANT_WRITE_BEFORE_SENDING_FD
     sp->dummy = vstring_alloc(1);
 #endif
diff --git a/postfix/src/lmtp/.indent.pro b/postfix/src/lmtp/.indent.pro
deleted file mode 120000 (symlink)
index 5c837ec..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/lmtp/.printfck b/postfix/src/lmtp/.printfck
deleted file mode 100644 (file)
index 66016ed..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-been_here_xt   2       0
-bounce_append  5       0
-cleanup_out_format     1       0
-defer_append   5       0
-mail_command   1       0
-mail_print     1       0
-msg_error      0       0
-msg_fatal      0       0
-msg_info       0       0
-msg_panic      0       0
-msg_warn       0       0
-opened         4       0
-post_mail_fprintf      1       0
-qmgr_message_bounce    2       0
-rec_fprintf    2       0
-sent   4       0
-smtp_cmd       1       0
-smtp_mesg_fail 2       0
-smtp_printf    1       0
-smtp_rcpt_fail 3       0
-smtp_site_fail 2       0
-udp_syslog     1       0
-vstream_fprintf        1       0
-vstream_printf 0       0
-vstring_sprintf        1       0
diff --git a/postfix/src/lmtp/Makefile.in b/postfix/src/lmtp/Makefile.in
deleted file mode 100644 (file)
index 10210d7..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-SHELL  = /bin/sh
-SRCS   = lmtp.c lmtp_connect.c lmtp_proto.c lmtp_chat.c lmtp_session.c \
-       lmtp_addr.c lmtp_trouble.c lmtp_state.c lmtp_sasl_glue.c \
-       lmtp_sasl_proto.c lmtp_rcpt.c lmtp_dsn.c
-OBJS   = lmtp.o lmtp_connect.o lmtp_proto.o lmtp_chat.o lmtp_session.o \
-       lmtp_addr.o lmtp_trouble.o lmtp_state.o lmtp_sasl_glue.o \
-       lmtp_sasl_proto.o lmtp_rcpt.o lmtp_dsn.o
-HDRS   = lmtp.h
-TESTSRC        = 
-DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
-CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG=
-PROG   = lmtp
-INC_DIR        = ../../include
-LIBS   = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libdns.a ../../lib/libutil.a
-
-.c.o:; $(CC) $(CFLAGS) -c $*.c
-
-$(PROG):       $(OBJS) $(LIBS)
-       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
-
-$(OBJS): ../../conf/makedefs.out
-
-Makefile: Makefile.in
-       (cat ../../conf/makedefs.out $?) >$@
-
-test:  $(TESTPROG)
-
-tests: test
-
-update: ../../libexec/$(PROG)
-
-../../libexec/$(PROG): $(PROG)
-       cp $(PROG) ../../libexec
-
-printfck: $(OBJS) $(PROG)
-       rm -rf printfck
-       mkdir printfck
-       cp *.h printfck
-       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
-       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
-       cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
-
-lint:
-       lint $(DEFS) $(SRCS) $(LINTFIX)
-
-clean:
-       rm -f *.o *core $(PROG) $(TESTPROG) junk 
-       rm -rf printfck
-
-tidy:  clean
-
-depend: $(MAKES)
-       (sed '1,/^# do not edit/!d' Makefile.in; \
-       set -e; for i in [a-z][a-z0-9]*.c; do \
-           $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
-           -e 's/o: \.\//o: /' -e p -e '}' ; \
-       done | sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
-       @$(EXPORT) make -f Makefile.in Makefile 1>&2
-
-# do not edit below this line - it is generated by 'make depend'
-lmtp.o: ../../include/argv.h
-lmtp.o: ../../include/attr.h
-lmtp.o: ../../include/debug_peer.h
-lmtp.o: ../../include/deliver_request.h
-lmtp.o: ../../include/dict.h
-lmtp.o: ../../include/dsn.h
-lmtp.o: ../../include/dsn_buf.h
-lmtp.o: ../../include/dsn_util.h
-lmtp.o: ../../include/flush_clnt.h
-lmtp.o: ../../include/mail_conf.h
-lmtp.o: ../../include/mail_error.h
-lmtp.o: ../../include/mail_params.h
-lmtp.o: ../../include/mail_queue.h
-lmtp.o: ../../include/mail_server.h
-lmtp.o: ../../include/msg.h
-lmtp.o: ../../include/msg_stats.h
-lmtp.o: ../../include/mymalloc.h
-lmtp.o: ../../include/name_mask.h
-lmtp.o: ../../include/recipient_list.h
-lmtp.o: ../../include/split_at.h
-lmtp.o: ../../include/sys_defs.h
-lmtp.o: ../../include/vbuf.h
-lmtp.o: ../../include/vstream.h
-lmtp.o: ../../include/vstring.h
-lmtp.o: lmtp.c
-lmtp.o: lmtp.h
-lmtp.o: lmtp_sasl.h
-lmtp_addr.o: ../../include/argv.h
-lmtp_addr.o: ../../include/attr.h
-lmtp_addr.o: ../../include/deliver_request.h
-lmtp_addr.o: ../../include/dns.h
-lmtp_addr.o: ../../include/dsn.h
-lmtp_addr.o: ../../include/dsn_buf.h
-lmtp_addr.o: ../../include/inet_addr_list.h
-lmtp_addr.o: ../../include/inet_proto.h
-lmtp_addr.o: ../../include/mail_params.h
-lmtp_addr.o: ../../include/msg.h
-lmtp_addr.o: ../../include/msg_stats.h
-lmtp_addr.o: ../../include/myaddrinfo.h
-lmtp_addr.o: ../../include/mymalloc.h
-lmtp_addr.o: ../../include/own_inet_addr.h
-lmtp_addr.o: ../../include/recipient_list.h
-lmtp_addr.o: ../../include/sock_addr.h
-lmtp_addr.o: ../../include/stringops.h
-lmtp_addr.o: ../../include/sys_defs.h
-lmtp_addr.o: ../../include/vbuf.h
-lmtp_addr.o: ../../include/vstream.h
-lmtp_addr.o: ../../include/vstring.h
-lmtp_addr.o: lmtp.h
-lmtp_addr.o: lmtp_addr.c
-lmtp_addr.o: lmtp_addr.h
-lmtp_chat.o: ../../include/argv.h
-lmtp_chat.o: ../../include/attr.h
-lmtp_chat.o: ../../include/cleanup_user.h
-lmtp_chat.o: ../../include/deliver_request.h
-lmtp_chat.o: ../../include/dsn.h
-lmtp_chat.o: ../../include/dsn_buf.h
-lmtp_chat.o: ../../include/dsn_util.h
-lmtp_chat.o: ../../include/line_wrap.h
-lmtp_chat.o: ../../include/mail_addr.h
-lmtp_chat.o: ../../include/mail_error.h
-lmtp_chat.o: ../../include/mail_params.h
-lmtp_chat.o: ../../include/msg.h
-lmtp_chat.o: ../../include/msg_stats.h
-lmtp_chat.o: ../../include/mymalloc.h
-lmtp_chat.o: ../../include/name_mask.h
-lmtp_chat.o: ../../include/post_mail.h
-lmtp_chat.o: ../../include/recipient_list.h
-lmtp_chat.o: ../../include/smtp_stream.h
-lmtp_chat.o: ../../include/stringops.h
-lmtp_chat.o: ../../include/sys_defs.h
-lmtp_chat.o: ../../include/vbuf.h
-lmtp_chat.o: ../../include/vstream.h
-lmtp_chat.o: ../../include/vstring.h
-lmtp_chat.o: lmtp.h
-lmtp_chat.o: lmtp_chat.c
-lmtp_connect.o: ../../include/argv.h
-lmtp_connect.o: ../../include/attr.h
-lmtp_connect.o: ../../include/deliver_request.h
-lmtp_connect.o: ../../include/dns.h
-lmtp_connect.o: ../../include/dsn.h
-lmtp_connect.o: ../../include/dsn_buf.h
-lmtp_connect.o: ../../include/host_port.h
-lmtp_connect.o: ../../include/inet_addr_list.h
-lmtp_connect.o: ../../include/iostuff.h
-lmtp_connect.o: ../../include/mail_params.h
-lmtp_connect.o: ../../include/mail_proto.h
-lmtp_connect.o: ../../include/msg.h
-lmtp_connect.o: ../../include/msg_stats.h
-lmtp_connect.o: ../../include/myaddrinfo.h
-lmtp_connect.o: ../../include/mymalloc.h
-lmtp_connect.o: ../../include/own_inet_addr.h
-lmtp_connect.o: ../../include/recipient_list.h
-lmtp_connect.o: ../../include/sane_connect.h
-lmtp_connect.o: ../../include/sock_addr.h
-lmtp_connect.o: ../../include/split_at.h
-lmtp_connect.o: ../../include/stringops.h
-lmtp_connect.o: ../../include/sys_defs.h
-lmtp_connect.o: ../../include/timed_connect.h
-lmtp_connect.o: ../../include/vbuf.h
-lmtp_connect.o: ../../include/vstream.h
-lmtp_connect.o: ../../include/vstring.h
-lmtp_connect.o: lmtp.h
-lmtp_connect.o: lmtp_addr.h
-lmtp_connect.o: lmtp_connect.c
-lmtp_dsn.o: ../../include/argv.h
-lmtp_dsn.o: ../../include/attr.h
-lmtp_dsn.o: ../../include/deliver_request.h
-lmtp_dsn.o: ../../include/dsn.h
-lmtp_dsn.o: ../../include/dsn_buf.h
-lmtp_dsn.o: ../../include/msg_stats.h
-lmtp_dsn.o: ../../include/recipient_list.h
-lmtp_dsn.o: ../../include/sys_defs.h
-lmtp_dsn.o: ../../include/vbuf.h
-lmtp_dsn.o: ../../include/vstream.h
-lmtp_dsn.o: ../../include/vstring.h
-lmtp_dsn.o: lmtp.h
-lmtp_dsn.o: lmtp_dsn.c
-lmtp_proto.o: ../../include/argv.h
-lmtp_proto.o: ../../include/attr.h
-lmtp_proto.o: ../../include/bounce.h
-lmtp_proto.o: ../../include/defer.h
-lmtp_proto.o: ../../include/deliver_completed.h
-lmtp_proto.o: ../../include/deliver_request.h
-lmtp_proto.o: ../../include/dsn.h
-lmtp_proto.o: ../../include/dsn_buf.h
-lmtp_proto.o: ../../include/dsn_mask.h
-lmtp_proto.o: ../../include/iostuff.h
-lmtp_proto.o: ../../include/mail_params.h
-lmtp_proto.o: ../../include/mail_proto.h
-lmtp_proto.o: ../../include/mail_queue.h
-lmtp_proto.o: ../../include/mark_corrupt.h
-lmtp_proto.o: ../../include/msg.h
-lmtp_proto.o: ../../include/msg_stats.h
-lmtp_proto.o: ../../include/mymalloc.h
-lmtp_proto.o: ../../include/name_code.h
-lmtp_proto.o: ../../include/off_cvt.h
-lmtp_proto.o: ../../include/quote_821_local.h
-lmtp_proto.o: ../../include/quote_822_local.h
-lmtp_proto.o: ../../include/quote_flags.h
-lmtp_proto.o: ../../include/rec_type.h
-lmtp_proto.o: ../../include/recipient_list.h
-lmtp_proto.o: ../../include/record.h
-lmtp_proto.o: ../../include/sent.h
-lmtp_proto.o: ../../include/smtp_stream.h
-lmtp_proto.o: ../../include/stringops.h
-lmtp_proto.o: ../../include/sys_defs.h
-lmtp_proto.o: ../../include/vbuf.h
-lmtp_proto.o: ../../include/vstream.h
-lmtp_proto.o: ../../include/vstring.h
-lmtp_proto.o: ../../include/vstring_vstream.h
-lmtp_proto.o: ../../include/xtext.h
-lmtp_proto.o: lmtp.h
-lmtp_proto.o: lmtp_proto.c
-lmtp_proto.o: lmtp_sasl.h
-lmtp_rcpt.o: ../../include/argv.h
-lmtp_rcpt.o: ../../include/attr.h
-lmtp_rcpt.o: ../../include/bounce.h
-lmtp_rcpt.o: ../../include/deliver_completed.h
-lmtp_rcpt.o: ../../include/deliver_request.h
-lmtp_rcpt.o: ../../include/dsn.h
-lmtp_rcpt.o: ../../include/dsn_buf.h
-lmtp_rcpt.o: ../../include/dsn_mask.h
-lmtp_rcpt.o: ../../include/msg.h
-lmtp_rcpt.o: ../../include/msg_stats.h
-lmtp_rcpt.o: ../../include/recipient_list.h
-lmtp_rcpt.o: ../../include/sent.h
-lmtp_rcpt.o: ../../include/sys_defs.h
-lmtp_rcpt.o: ../../include/vbuf.h
-lmtp_rcpt.o: ../../include/vstream.h
-lmtp_rcpt.o: ../../include/vstring.h
-lmtp_rcpt.o: lmtp.h
-lmtp_rcpt.o: lmtp_rcpt.c
-lmtp_sasl_glue.o: ../../include/argv.h
-lmtp_sasl_glue.o: ../../include/attr.h
-lmtp_sasl_glue.o: ../../include/deliver_request.h
-lmtp_sasl_glue.o: ../../include/dict.h
-lmtp_sasl_glue.o: ../../include/dsn.h
-lmtp_sasl_glue.o: ../../include/dsn_buf.h
-lmtp_sasl_glue.o: ../../include/mail_params.h
-lmtp_sasl_glue.o: ../../include/maps.h
-lmtp_sasl_glue.o: ../../include/match_list.h
-lmtp_sasl_glue.o: ../../include/match_ops.h
-lmtp_sasl_glue.o: ../../include/msg.h
-lmtp_sasl_glue.o: ../../include/msg_stats.h
-lmtp_sasl_glue.o: ../../include/mymalloc.h
-lmtp_sasl_glue.o: ../../include/name_mask.h
-lmtp_sasl_glue.o: ../../include/recipient_list.h
-lmtp_sasl_glue.o: ../../include/split_at.h
-lmtp_sasl_glue.o: ../../include/string_list.h
-lmtp_sasl_glue.o: ../../include/stringops.h
-lmtp_sasl_glue.o: ../../include/sys_defs.h
-lmtp_sasl_glue.o: ../../include/vbuf.h
-lmtp_sasl_glue.o: ../../include/vstream.h
-lmtp_sasl_glue.o: ../../include/vstring.h
-lmtp_sasl_glue.o: lmtp.h
-lmtp_sasl_glue.o: lmtp_sasl.h
-lmtp_sasl_glue.o: lmtp_sasl_glue.c
-lmtp_sasl_proto.o: ../../include/argv.h
-lmtp_sasl_proto.o: ../../include/attr.h
-lmtp_sasl_proto.o: ../../include/deliver_request.h
-lmtp_sasl_proto.o: ../../include/dsn.h
-lmtp_sasl_proto.o: ../../include/dsn_buf.h
-lmtp_sasl_proto.o: ../../include/mail_params.h
-lmtp_sasl_proto.o: ../../include/msg.h
-lmtp_sasl_proto.o: ../../include/msg_stats.h
-lmtp_sasl_proto.o: ../../include/mymalloc.h
-lmtp_sasl_proto.o: ../../include/recipient_list.h
-lmtp_sasl_proto.o: ../../include/sys_defs.h
-lmtp_sasl_proto.o: ../../include/vbuf.h
-lmtp_sasl_proto.o: ../../include/vstream.h
-lmtp_sasl_proto.o: ../../include/vstring.h
-lmtp_sasl_proto.o: lmtp.h
-lmtp_sasl_proto.o: lmtp_sasl.h
-lmtp_sasl_proto.o: lmtp_sasl_proto.c
-lmtp_session.o: ../../include/argv.h
-lmtp_session.o: ../../include/attr.h
-lmtp_session.o: ../../include/debug_peer.h
-lmtp_session.o: ../../include/deliver_request.h
-lmtp_session.o: ../../include/dsn.h
-lmtp_session.o: ../../include/dsn_buf.h
-lmtp_session.o: ../../include/msg_stats.h
-lmtp_session.o: ../../include/mymalloc.h
-lmtp_session.o: ../../include/recipient_list.h
-lmtp_session.o: ../../include/stringops.h
-lmtp_session.o: ../../include/sys_defs.h
-lmtp_session.o: ../../include/vbuf.h
-lmtp_session.o: ../../include/vstream.h
-lmtp_session.o: ../../include/vstring.h
-lmtp_session.o: lmtp.h
-lmtp_session.o: lmtp_session.c
-lmtp_state.o: ../../include/argv.h
-lmtp_state.o: ../../include/attr.h
-lmtp_state.o: ../../include/deliver_request.h
-lmtp_state.o: ../../include/dsn.h
-lmtp_state.o: ../../include/dsn_buf.h
-lmtp_state.o: ../../include/mail_conf.h
-lmtp_state.o: ../../include/msg_stats.h
-lmtp_state.o: ../../include/mymalloc.h
-lmtp_state.o: ../../include/recipient_list.h
-lmtp_state.o: ../../include/sys_defs.h
-lmtp_state.o: ../../include/vbuf.h
-lmtp_state.o: ../../include/vstream.h
-lmtp_state.o: ../../include/vstring.h
-lmtp_state.o: lmtp.h
-lmtp_state.o: lmtp_sasl.h
-lmtp_state.o: lmtp_state.c
-lmtp_trouble.o: ../../include/argv.h
-lmtp_trouble.o: ../../include/attr.h
-lmtp_trouble.o: ../../include/bounce.h
-lmtp_trouble.o: ../../include/defer.h
-lmtp_trouble.o: ../../include/deliver_completed.h
-lmtp_trouble.o: ../../include/deliver_request.h
-lmtp_trouble.o: ../../include/dsn.h
-lmtp_trouble.o: ../../include/dsn_buf.h
-lmtp_trouble.o: ../../include/mail_error.h
-lmtp_trouble.o: ../../include/msg.h
-lmtp_trouble.o: ../../include/msg_stats.h
-lmtp_trouble.o: ../../include/name_mask.h
-lmtp_trouble.o: ../../include/recipient_list.h
-lmtp_trouble.o: ../../include/smtp_stream.h
-lmtp_trouble.o: ../../include/stringops.h
-lmtp_trouble.o: ../../include/sys_defs.h
-lmtp_trouble.o: ../../include/vbuf.h
-lmtp_trouble.o: ../../include/vstream.h
-lmtp_trouble.o: ../../include/vstring.h
-lmtp_trouble.o: lmtp.h
-lmtp_trouble.o: lmtp_trouble.c
diff --git a/postfix/src/lmtp/lmtp.c b/postfix/src/lmtp/lmtp.c
deleted file mode 100644 (file)
index 2af07f7..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-/*++
-/* NAME
-/*     lmtp 8
-/* SUMMARY
-/*     Postfix local delivery via LMTP
-/* SYNOPSIS
-/*     \fBlmtp\fR [generic Postfix daemon options]
-/* 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 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 status reports are sent
-/*     to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
-/*     appropriate.
-/*
-/*     The LMTP client connects to the destination specified in the message
-/*     delivery request. The destination, usually specified in the Postfix
-/*     \fBtransport\fR(5) table, has the form:
-/* .IP \fBunix\fR:\fIpathname\fR
-/*     Connect to the local UNIX-domain server that is bound to the specified
-/*     \fIpathname\fR. If the process runs chrooted, an absolute pathname
-/*     is interpreted relative to the changed root directory.
-/* .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
-/* .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
-/*     Connect to the specified IPV4 TCP port on the specified local or
-/*     remote host. If no port is specified, connect to the port defined as
-/*     \fBlmtp\fR in \fBservices\fR(4).
-/*     If no such service is found, the \fBlmtp_tcp_port\fR configuration
-/*     parameter (default value of 24) will be used.
-/*
-/*     The LMTP client does not perform MX (mail exchanger) lookups since
-/*     those are defined only for mail delivery via SMTP.
-/* .PP
-/*     If neither \fBunix:\fR nor \fBinet:\fR are specified, \fBinet:\fR
-/*     is assumed.
-/* SECURITY
-/* .ad
-/* .fi
-/*     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 1652 (8bit-MIME transport)
-/*     RFC 1870 (Message Size Declaration)
-/*     RFC 2033 (LMTP protocol)
-/*     RFC 2034 (Enhanced Status codes)
-/*     RFC 2554 (AUTH command)
-/*     RFC 2821 (SMTP protocol)
-/*     RFC 2920 (SMTP Pipelining)
-/*     RFC 3463 (Enhanced Status codes)
-/* DIAGNOSTICS
-/*     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.
-/* CONFIGURATION PARAMETERS
-/* .ad
-/* .fi
-/*     Changes to \fBmain.cf\fR are picked up automatically, as \fBlmtp\fR(8)
-/*     processes run for only a limited amount of time. Use the command
-/*     "\fBpostfix reload\fR" to speed up a change.
-/*
-/*     The text below provides only a parameter summary. See
-/*     \fBpostconf\fR(5) for more details including examples.
-/* COMPATIBILITY CONTROLS
-/* .ad
-/* .fi
-/* .IP "\fBlmtp_skip_quit_response (no)\fR"
-/*     Wait for the response to the LMTP QUIT command.
-/* TROUBLE SHOOTING CONTROLS
-/* .ad
-/* .fi
-/* .IP "\fBdebug_peer_level (2)\fR"
-/*     The increment in verbose logging level when a remote client or
-/*     server matches a pattern in the debug_peer_list parameter.
-/* .IP "\fBdebug_peer_list (empty)\fR"
-/*     Optional list of remote client or server hostname or network
-/*     address patterns that cause the verbose logging level to increase
-/*     by the amount specified in $debug_peer_level.
-/* .IP "\fBerror_notice_recipient (postmaster)\fR"
-/*     The recipient of postmaster notifications about mail delivery
-/*     problems that are caused by policy, resource, software or protocol
-/*     errors.
-/* .IP "\fBnotify_classes (resource, software)\fR"
-/*     The list of error classes that are reported to the postmaster.
-/* EXTERNAL CONTENT INSPECTION CONTROLS
-/* .ad
-/* .fi
-/*     Available in Postfix version 2.1 and later:
-/* .IP "\fBlmtp_send_xforward_command (no)\fR"
-/*     Send an XFORWARD command to the LMTP server when the LMTP LHLO
-/*     server response announces XFORWARD support.
-/* SASL AUTHENTICATION CONTROLS
-/* .ad
-/* .fi
-/* .IP "\fBlmtp_sasl_auth_enable (no)\fR"
-/*     Enable SASL authentication in the Postfix LMTP client.
-/* .IP "\fBlmtp_sasl_password_maps (empty)\fR"
-/*     Optional LMTP client lookup tables with one username:password entry
-/*     per host or domain.
-/* .IP "\fBlmtp_sasl_security_options (noplaintext, noanonymous)\fR"
-/*     What authentication mechanisms the Postfix LMTP client is allowed
-/*     to use.
-/* RESOURCE AND RATE CONTROLS
-/* .ad
-/* .fi
-/*     In the text below, \fItransport\fR is the name
-/*     of the service as specified in the \fBmaster.cf\fR file.
-/* .IP "\fBlmtp_cache_connection (yes)\fR"
-/*     Keep Postfix LMTP client connections open for up to $max_idle
-/*     seconds.
-/* .IP "\fItransport_\fBdestination_concurrency_limit ($default_destination_concurrency_limit)\fR"
-/*     Limit the number of parallel deliveries to the same destination
-/*     via this mail delivery transport.
-/* .IP "\fItransport_\fBdestination_recipient_limit ($default_destination_recipient_limit)\fR"
-/*     Limit the number of recipients per message delivery via this mail
-/*     delivery transport.
-/*
-/*     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.
-/* .IP "\fBlmtp_connect_timeout (0s)\fR"
-/*     The LMTP client time limit for completing a TCP connection, or
-/*     zero (use the operating system built-in time limit).
-/* .IP "\fBlmtp_lhlo_timeout (300s)\fR"
-/*     The LMTP client time limit for receiving the LMTP greeting
-/*     banner.
-/* .IP "\fBlmtp_xforward_timeout (300s)\fR"
-/*     The LMTP client time limit for sending the XFORWARD command, and
-/*     for receiving the server response.
-/* .IP "\fBlmtp_mail_timeout (300s)\fR"
-/*     The LMTP client time limit for sending the MAIL FROM command, and
-/*     for receiving the server response.
-/* .IP "\fBlmtp_rcpt_timeout (300s)\fR"
-/*     The LMTP client time limit for sending the RCPT TO command, and
-/*     for receiving the server response.
-/* .IP "\fBlmtp_data_init_timeout (120s)\fR"
-/*     The LMTP client time limit for sending the LMTP DATA command, and
-/*     for receiving the server response.
-/* .IP "\fBlmtp_data_xfer_timeout (180s)\fR"
-/*     The LMTP client time limit for sending the LMTP message content.
-/* .IP "\fBlmtp_data_done_timeout (600s)\fR"
-/*     The LMTP client time limit for sending the LMTP ".", and for
-/*     receiving the server response.
-/* .IP "\fBlmtp_rset_timeout (20s)\fR"
-/*     The LMTP client time limit for sending the RSET command, and
-/*     for receiving the server response.
-/* .IP "\fBlmtp_quit_timeout (300s)\fR"
-/*     The LMTP client time limit for sending the QUIT command, and for
-/*     receiving the server response.
-/* MISCELLANEOUS CONTROLS
-/* .ad
-/* .fi
-/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
-/*     The default location of the Postfix main.cf and master.cf
-/*     configuration files.
-/* .IP "\fBdaemon_timeout (18000s)\fR"
-/*     How much time a Postfix daemon process may take to handle a
-/*     request before it is terminated by a built-in watchdog timer.
-/* .IP "\fBdelay_logging_resolution_limit (2)\fR"
-/*     The maximal number of digits after the decimal point when logging
-/*     sub-second delay values.
-/* .IP "\fBdisable_dns_lookups (no)\fR"
-/*     Disable DNS lookups in the Postfix SMTP and LMTP clients.
-/* .IP "\fBipc_timeout (3600s)\fR"
-/*     The time limit for sending or receiving information over an internal
-/*     communication channel.
-/* .IP "\fBlmtp_tcp_port (24)\fR"
-/*     The default TCP port that the Postfix LMTP client connects to.
-/* .IP "\fBmax_idle (100s)\fR"
-/*     The maximum amount of time that an idle Postfix daemon process
-/*     waits for the next service request before exiting.
-/* .IP "\fBmax_use (100)\fR"
-/*     The maximal number of connection requests before a Postfix daemon
-/*     process terminates.
-/* .IP "\fBprocess_id (read-only)\fR"
-/*     The process ID of a Postfix command or daemon process.
-/* .IP "\fBprocess_name (read-only)\fR"
-/*     The process name of a Postfix command or daemon process.
-/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
-/*     The location of the Postfix top-level queue directory.
-/* .IP "\fBsyslog_facility (mail)\fR"
-/*     The syslog facility of Postfix logging.
-/* .IP "\fBsyslog_name (postfix)\fR"
-/*     The mail system name that is prepended to the process name in syslog
-/*     records, so that "smtpd" becomes, for example, "postfix/smtpd".
-/* SEE ALSO
-/*     bounce(8), delivery status reports
-/*     qmgr(8), queue manager
-/*     postconf(5), configuration parameters
-/*     master(5), generic daemon options
-/*     services(4), Internet services and aliases
-/*     master(8), process manager
-/*     syslogd(8), system logging
-/* README FILES
-/* .ad
-/* .fi
-/*     Use "\fBpostconf readme_directory\fR" or
-/*     "\fBpostconf html_directory\fR" to locate this information.
-/* .na
-/* .nf
-/*     LMTP_README, Postfix LMTP client howto
-/*     VIRTUAL_README, virtual delivery agent howto
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*
-/*     Modifications for LMTP by:
-/*     Philip A. Prindeville
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     SASL support originally by:
-/*     Till Franke
-/*     SuSE Rhein/Main AG
-/*     65760 Eschborn, Germany
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <dict.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <argv.h>
-#include <mymalloc.h>
-#include <name_mask.h>
-#include <split_at.h>
-
-/* Global library. */
-
-#include <deliver_request.h>
-#include <mail_queue.h>
-#include <mail_params.h>
-#include <mail_conf.h>
-#include <debug_peer.h>
-#include <mail_error.h>
-#include <flush_clnt.h>
-#include <dsn_util.h>
-
-/* Single server skeleton. */
-
-#include <mail_server.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_sasl.h"
-
- /*
-  * Tunable parameters. These have compiled-in defaults that can be overruled
-  * by settings in the global Postfix configuration file.
-  */
-int     var_lmtp_tcp_port;
-int     var_lmtp_conn_tmout;
-int     var_lmtp_rset_tmout;
-int     var_lmtp_lhlo_tmout;
-int     var_lmtp_xfwd_tmout;
-int     var_lmtp_mail_tmout;
-int     var_lmtp_rcpt_tmout;
-int     var_lmtp_data0_tmout;
-int     var_lmtp_data1_tmout;
-int     var_lmtp_data2_tmout;
-int     var_lmtp_quit_tmout;
-int     var_lmtp_cache_conn;
-int     var_lmtp_skip_quit_resp;
-char   *var_notify_classes;
-char   *var_error_rcpt;
-char   *var_lmtp_sasl_opts;
-char   *var_lmtp_sasl_passwd;
-bool    var_lmtp_sasl_enable;
-bool    var_lmtp_send_xforward;
-
- /*
-  * Global variables.
-  * 
-  * lmtp_errno is set by the address lookup routines and by the connection
-  * management routines.
-  * 
-  * state is global for the connection caching to work.
-  */
-int     lmtp_errno;
-static LMTP_STATE *state = 0;
-
-/* deliver_message - deliver message with extreme prejudice */
-
-static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
-{
-    char   *myname = "deliver_message";
-    DSN_BUF *why;
-    int     result;
-
-    if (msg_verbose)
-       msg_info("%s: from %s", myname, request->sender);
-
-    /*
-     * Sanity checks.
-     */
-    if (request->rcpt_list.len <= 0)
-       msg_fatal("%s: recipient count: %d", myname, request->rcpt_list.len);
-
-    /*
-     * Initialize. Bundle all information about the delivery request, so that
-     * we can produce understandable diagnostics when something goes wrong
-     * many levels below. The alternative would be to make everything global.
-     * 
-     * 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_POST_INIT function (post_init).
-     * 
-     */
-    why = dsb_create();
-    state->request = request;
-    state->src = request->fp;
-
-    /*
-     * See if we can reuse an existing connection.
-     */
-    if (state->session != 0) {
-
-       /*
-        * Disconnect if we're going to a different destination. Discard
-        * transcript and status information for sending QUIT.
-        * 
-        * XXX Should transform nexthop into canonical form (unix:/path or
-        * inet:host:port) before doing connection cache lookup. See also the
-        * connection cache updating code in lmtp_connect.c.
-        */
-       if (strcasecmp(state->session->dest, request->nexthop) != 0) {
-           lmtp_quit(state);
-           lmtp_chat_reset(state);
-           state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
-           if (var_lmtp_sasl_enable)
-               lmtp_sasl_cleanup(state);
-#endif
-       }
-
-       /*
-        * Disconnect if RSET can't be sent over an existing connection.
-        * Discard transcript and status information for sending RSET.
-        */
-       else if (lmtp_rset(state) != 0
-                || (state->features & LMTP_FEATURE_RSET_REJECTED) != 0) {
-           lmtp_chat_reset(state);
-           state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
-           if (var_lmtp_sasl_enable)
-               lmtp_sasl_cleanup(state);
-#endif
-       }
-
-       /*
-        * 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;
-           if (msg_verbose)
-               msg_info("%s: reusing (count %d) session with: %s",
-                        myname, state->reuse, state->session->host);
-       }
-    }
-
-    /*
-     * See if we need to establish an LMTP connection.
-     */
-    if (state->session == 0) {
-
-       /*
-        * Bounce or defer the recipients if no connection can be made.
-        * 
-        * XXX Unlike enhanced status codes, changing a 4xx into 5xx LMTP code
-        * is not simply a matter of changing the initial digit. What we're
-        * doing here is correct only under specific conditions, such as
-        * changing 450 into 550 or vice versa.
-        */
-       if ((state->session = lmtp_connect(request->nexthop, why)) == 0) {
-           if (lmtp_errno == LMTP_RETRY)
-               STR(why->status)[0] = STR(why->dtext)[0] = '4'; /* XXX */
-           else
-               STR(why->status)[0] = STR(why->dtext)[0] = '5'; /* XXX */
-           lmtp_sess_fail(state, why);
-       }
-
-       /*
-        * Bounce or defer the recipients if the LMTP handshake fails.
-        */
-       else if (lmtp_lhlo(state) != 0) {
-           state->session = lmtp_session_free(state->session);
-#ifdef USE_SASL_AUTH
-           if (var_lmtp_sasl_enable)
-               lmtp_sasl_cleanup(state);
-#endif
-       }
-
-       /*
-        * 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);
-
-    /*
-     * Optionally, notify the postmaster of problems with establishing a
-     * session or with delivering mail.
-     */
-    if (state->history != 0
-     && (state->error_mask & name_mask(VAR_NOTIFY_CLASSES, mail_error_masks,
-                                      var_notify_classes)))
-       lmtp_chat_notify(state);
-
-    /*
-     * Disconnect if we're not caching connections. The pipelined protocol
-     * state machine knows if it should have sent a QUIT command. Do not
-     * cache a broken connection.
-     */
-    if (state->session != 0
-       && (!var_lmtp_cache_conn
-           || vstream_ferror(state->session->stream)
-           || vstream_feof(state->session->stream)))
-       state->session = lmtp_session_free(state->session);
-
-    /*
-     * Clean up.
-     */
-    dsb_free(why);
-    result = state->status;
-    lmtp_chat_reset(state);
-
-    /*
-     * XXX State persists until idle timeout, but these fields will be
-     * dangling pointers. Nuke them.
-     */
-    state->request = 0;
-    state->src = 0;
-
-    return (result);
-}
-
-/* lmtp_service - perform service for client */
-
-static void lmtp_service(VSTREAM *client_stream, char *unused_service, char **argv)
-{
-    DELIVER_REQUEST *request;
-    int     status;
-
-    /*
-     * Sanity check. This service takes no command-line arguments.
-     */
-    if (argv[0])
-       msg_fatal("unexpected command-line argument: %s", argv[0]);
-
-    /*
-     * This routine runs whenever a client connects to the UNIX-domain socket
-     * dedicated to remote LMTP delivery service. What we see below is a
-     * little protocol to (1) tell the queue manager that we are ready, (2)
-     * read a request from the queue manager, and (3) report the completion
-     * status of that request. All connection-management stuff is handled by
-     * the common code in single_server.c.
-     */
-    if ((request = deliver_request_read(client_stream)) != 0) {
-       status = deliver_message(request, argv);
-       deliver_request_done(client_stream, request, status);
-    }
-}
-
-/* post_init - post-jail initialization */
-
-static void post_init(char *unused_name, char **unused_argv)
-{
-    state = lmtp_state_alloc();
-}
-
-/* pre_init - pre-jail initialization */
-
-static void pre_init(char *unused_name, char **unused_argv)
-{
-    debug_peer_init();
-    if (var_lmtp_sasl_enable)
-#ifdef USE_SASL_AUTH
-       lmtp_sasl_initialize();
-#else
-       msg_warn("%s is true, but SASL support is not compiled in",
-                VAR_LMTP_SASL_ENABLE);
-#endif
-
-    /*
-     * flush client.
-     */
-    flush_init();
-}
-
-/* cleanup - close any open connections, etc. */
-
-static void cleanup(void)
-{
-    if (state->session != 0) {
-       lmtp_quit(state);
-       lmtp_chat_reset(state);
-       state->session = lmtp_session_free(state->session);
-       if (msg_verbose)
-           msg_info("cleanup: just closed down session");
-    }
-    lmtp_state_free(state);
-#ifdef USE_SASL_AUTH
-    if (var_lmtp_sasl_enable)
-       sasl_done();
-#endif
-}
-
-/* pre_accept - see if tables have changed */
-
-static void pre_accept(char *unused_name, char **unused_argv)
-{
-    const char *table;
-
-    if ((table = dict_changed_name()) != 0) {
-       msg_info("table %s has changed -- restarting", table);
-       cleanup();
-       exit(0);
-    }
-}
-
-/* main - pass control to the single-threaded skeleton */
-
-int     main(int argc, char **argv)
-{
-    static CONFIG_STR_TABLE str_table[] = {
-       VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
-       VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
-       VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_lmtp_sasl_passwd, 0, 0,
-       VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_lmtp_sasl_opts, 0, 0,
-       0,
-    };
-    static CONFIG_INT_TABLE int_table[] = {
-       VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
-       0,
-    };
-    static CONFIG_TIME_TABLE time_table[] = {
-       VAR_LMTP_CONN_TMOUT, DEF_LMTP_CONN_TMOUT, &var_lmtp_conn_tmout, 0, 0,
-       VAR_LMTP_RSET_TMOUT, DEF_LMTP_RSET_TMOUT, &var_lmtp_rset_tmout, 1, 0,
-       VAR_LMTP_LHLO_TMOUT, DEF_LMTP_LHLO_TMOUT, &var_lmtp_lhlo_tmout, 1, 0,
-       VAR_LMTP_XFWD_TMOUT, DEF_LMTP_XFWD_TMOUT, &var_lmtp_xfwd_tmout, 1, 0,
-       VAR_LMTP_MAIL_TMOUT, DEF_LMTP_MAIL_TMOUT, &var_lmtp_mail_tmout, 1, 0,
-       VAR_LMTP_RCPT_TMOUT, DEF_LMTP_RCPT_TMOUT, &var_lmtp_rcpt_tmout, 1, 0,
-       VAR_LMTP_DATA0_TMOUT, DEF_LMTP_DATA0_TMOUT, &var_lmtp_data0_tmout, 1, 0,
-       VAR_LMTP_DATA1_TMOUT, DEF_LMTP_DATA1_TMOUT, &var_lmtp_data1_tmout, 1, 0,
-       VAR_LMTP_DATA2_TMOUT, DEF_LMTP_DATA2_TMOUT, &var_lmtp_data2_tmout, 1, 0,
-       VAR_LMTP_QUIT_TMOUT, DEF_LMTP_QUIT_TMOUT, &var_lmtp_quit_tmout, 1, 0,
-       0,
-    };
-    static CONFIG_BOOL_TABLE bool_table[] = {
-       VAR_LMTP_CACHE_CONN, DEF_LMTP_CACHE_CONN, &var_lmtp_cache_conn,
-       VAR_LMTP_SKIP_QUIT_RESP, DEF_LMTP_SKIP_QUIT_RESP, &var_lmtp_skip_quit_resp,
-       VAR_LMTP_SASL_ENABLE, DEF_LMTP_SASL_ENABLE, &var_lmtp_sasl_enable,
-       VAR_LMTP_SEND_XFORWARD, DEF_LMTP_SEND_XFORWARD, &var_lmtp_send_xforward,
-       0,
-    };
-
-    single_server_main(argc, argv, lmtp_service,
-                      MAIL_SERVER_INT_TABLE, int_table,
-                      MAIL_SERVER_STR_TABLE, str_table,
-                      MAIL_SERVER_BOOL_TABLE, bool_table,
-                      MAIL_SERVER_TIME_TABLE, time_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/src/lmtp/lmtp.h b/postfix/src/lmtp/lmtp.h
deleted file mode 100644 (file)
index aa44072..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*++
-/* NAME
-/*     lmtp 3h
-/* SUMMARY
-/*     lmtp client program
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/* DESCRIPTION
-/* .nf
-
- /*
-  * SASL library.
-  */
-#ifdef USE_SASL_AUTH
-#include <sasl.h>
-#include <saslutil.h>
-#endif
-
- /*
-  * Utility library.
-  */
-#include <vstream.h>
-#include <vstring.h>
-#include <argv.h>
-
- /*
-  * Global library.
-  */
-#include <deliver_request.h>
-#include <dsn_buf.h>
-
- /*
-  * State information associated with each LMTP delivery. We're bundling the
-  * state so that we can give meaningful diagnostics in case of problems.
-  */
-typedef struct LMTP_STATE {
-    VSTREAM *src;                      /* queue file stream */
-    DELIVER_REQUEST *request;          /* envelope info, offsets */
-    struct LMTP_SESSION *session;      /* network connection */
-    VSTRING *buffer;                   /* I/O buffer */
-    VSTRING *scratch;                  /* scratch buffer */
-    VSTRING *scratch2;                 /* scratch buffer */
-    int     status;                    /* delivery status */
-    int     features;                  /* server features */
-    ARGV   *history;                   /* transaction log */
-    int     error_mask;                        /* error classes */
-#ifdef USE_SASL_AUTH
-    char   *sasl_mechanism_list;       /* server mechanism list */
-    char   *sasl_username;             /* client username */
-    char   *sasl_passwd;               /* client password */
-    sasl_conn_t *sasl_conn;            /* SASL internal state */
-    VSTRING *sasl_encoded;             /* encoding buffer */
-    VSTRING *sasl_decoded;             /* decoding buffer */
-    sasl_callback_t *sasl_callbacks;   /* stateful callbacks */
-#endif
-    int     sndbufsize;                        /* total window size */
-    int     reuse;                     /* connection being reused */
-    VSTRING *dsn_reason;               /* human-readable, sort of */
-} LMTP_STATE;
-
-#define LMTP_FEATURE_ESMTP     (1<<0)
-#define LMTP_FEATURE_8BITMIME  (1<<1)
-#define LMTP_FEATURE_PIPELINING        (1<<2)
-#define LMTP_FEATURE_SIZE      (1<<3)
-#define LMTP_FEATURE_AUTH      (1<<5)
-#define LMTP_FEATURE_XFORWARD_NAME (1<<6)
-#define LMTP_FEATURE_XFORWARD_ADDR (1<<7)
-#define LMTP_FEATURE_XFORWARD_PROTO (1<<8)
-#define LMTP_FEATURE_XFORWARD_HELO (1<<9)
-#define LMTP_FEATURE_XFORWARD_DOMAIN (1<<10)
-#define LMTP_FEATURE_DSN       (1<<11)
-#define LMTP_FEATURE_RSET_REJECTED (1<<12)
-
- /*
-  * lmtp.c
-  */
-extern int lmtp_errno;                 /* XXX can we get rid of this? */
-
- /*
-  * lmtp_session.c
-  */
-typedef struct LMTP_SESSION {
-    VSTREAM *stream;                   /* network 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 *, const char *, const char *, const char *);
-extern LMTP_SESSION *lmtp_session_free(LMTP_SESSION *);
-
- /*
-  * lmtp_connect.c
-  */
-extern LMTP_SESSION *lmtp_connect(const char *, DSN_BUF *);
-
- /*
-  * lmtp_proto.c
-  */
-extern int lmtp_lhlo(LMTP_STATE *);
-extern int lmtp_xfer(LMTP_STATE *);
-extern int lmtp_quit(LMTP_STATE *);
-extern int lmtp_rset(LMTP_STATE *);
-
- /*
-  * lmtp_chat.c
-  */
-typedef struct LMTP_RESP {             /* server response */
-    int     code;                      /* LMTP code */
-    char   *dsn;                       /* enhanced status */
-    char   *str;                       /* full reply */
-    VSTRING *dsn_buf;                  /* status buffer */
-    VSTRING *str_buf;                  /* reply buffer */
-} LMTP_RESP;
-
-extern void PRINTFLIKE(2, 3) lmtp_chat_cmd(LMTP_STATE *, char *,...);
-extern LMTP_RESP *lmtp_chat_resp(LMTP_STATE *);
-extern void lmtp_chat_reset(LMTP_STATE *);
-extern void lmtp_chat_notify(LMTP_STATE *);
-
-#define LMTP_RESP_FAKE(resp, _code, _dsn, _str) \
-    ((resp)->code = (_code), \
-     (resp)->dsn = (_dsn), \
-     (resp)->str = (_str), \
-     (resp))
-
- /*
-  * lmtp_trouble.c
-  */
-extern int lmtp_sess_fail(LMTP_STATE *, DSN_BUF *);
-extern int PRINTFLIKE(4, 5) lmtp_site_fail(LMTP_STATE *, const char *,
-                                            LMTP_RESP *, const char *,...);
-extern int PRINTFLIKE(4, 5) lmtp_mesg_fail(LMTP_STATE *, const char *,
-                                            LMTP_RESP *, const char *,...);
-extern void PRINTFLIKE(5, 6) lmtp_rcpt_fail(LMTP_STATE *, const char *, LMTP_RESP *, RECIPIENT *, const char *,...);
-extern int lmtp_stream_except(LMTP_STATE *, int, const char *);
-
- /*
-  * lmtp_state.c
-  */
-extern LMTP_STATE *lmtp_state_alloc(void);
-extern void lmtp_state_free(LMTP_STATE *);
-
- /*
-  * lmtp_rcpt.c
-  */
-extern void lmtp_rcpt_done(LMTP_STATE *, LMTP_RESP *, RECIPIENT *);
-
- /*
-  * Status codes. Errors must have negative codes so that they do not
-  * interfere with useful counts of work done.
-  */
-#define LMTP_OK                        0       /* so far, so good */
-#define LMTP_RETRY             (-1)    /* transient error */
-#define LMTP_FAIL              (-2)    /* hard error */
-
- /*
-  * lmtp_dsn.c
-  */
-extern void PRINTFLIKE(6, 7) lmtp_dsn_update(DSN_BUF *, const char *,
-                                                    const char *,
-                                                    int, const char *,
-                                                    const char *,...);
-extern void vlmtp_dsn_update(DSN_BUF *, const char *, const char *,
-                                    int, const char *,
-                                    const char *, va_list);
-extern void lmtp_dsn_formal(DSN_BUF *, const char *, const char *,
-                                   int, const char *);
-
-#define LMTP_DSN_ASSIGN(dsn, mta, stat, resp, why) \
-    DSN_ASSIGN((dsn), (stat), DSB_DEF_ACTION, (why), DSB_DTYPE_SMTP, (resp), \
-       (mta) ? DSB_MTYPE_DNS : DSB_MTYPE_NONE, (mta))
-
-#define DSN_BY_LOCAL_MTA       ((char *) 0)    /* DSN issued by local MTA */
-
- /*
-  * Silly little macros.
-  */
-#define STR(s) vstring_str(s)
-
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*      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/src/lmtp/lmtp_addr.c b/postfix/src/lmtp/lmtp_addr.c
deleted file mode 100644 (file)
index e23849b..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_addr 3
-/* SUMMARY
-/*     LMTP server address lookup
-/* SYNOPSIS
-/*     #include "lmtp_addr.h"
-/*
-/*     DNS_RR *lmtp_host_addr(name, why)
-/*     char    *name;
-/*     DSN_BUF *why;
-/* DESCRIPTION
-/*     This module implements Internet address lookups. By default,
-/*     lookups are done via the Internet domain name service (DNS).
-/*     A reasonable number of CNAME indirections is permitted.
-/*
-/*     lmtp_host_addr() looks up all addresses listed for the named
-/*     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.
-/*
-/*     Results from lmtp_host_addr() are destroyed by dns_rr_free(),
-/*     including null lists.
-/* DIAGNOSTICS
-/*     This routine either returns a DNS_RR pointer, or return a null
-/*     pointer and sets the \fIlmtp_errno\fR global variable accordingly:
-/* .IP LMTP_RETRY
-/*     The request failed due to a soft error, and should be retried later.
-/* .IP LMTP_FAIL
-/*     The request attempt failed due to a hard error.
-/* .PP
-/*     In addition, a description of the problem is made available
-/*     via the \fIwhy\fR argument.
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <mymalloc.h>
-#include <inet_addr_list.h>
-#include <stringops.h>
-#include <myaddrinfo.h>
-#include <sock_addr.h>
-#include <inet_proto.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-#include <own_inet_addr.h>
-
-/* DNS library. */
-
-#include <dns.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_addr.h"
-
-/* lmtp_print_addr - print address list */
-
-static void lmtp_print_addr(char *what, DNS_RR *addr_list)
-{
-    DNS_RR *addr;
-    MAI_HOSTADDR_STR hostaddr;
-
-    msg_info("begin %s address list", what);
-    for (addr = addr_list; addr; addr = addr->next) {
-       if (dns_rr_to_pa(addr, &hostaddr) == 0) {
-           msg_warn("skipping record type %s: %m", dns_strtype(addr->type));
-       } else {
-           msg_info("pref %4d host %s/%s",
-                    addr->pref, addr->name,
-                    hostaddr.buf);
-       }
-    }
-    msg_info("end %s address list", what);
-}
-
-/* lmtp_addr_one - address lookup for one host name */
-
-static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref,
-                                    DSN_BUF *why)
-{
-    char   *myname = "lmtp_addr_one";
-    DNS_RR *addr = 0;
-    DNS_RR *rr;
-    int     aierr;
-    struct addrinfo *res0;
-    struct addrinfo *res;
-    INET_PROTO_INFO *proto_info = inet_proto_info();
-    int     found;
-
-    if (msg_verbose)
-       msg_info("%s: host %s", myname, host);
-
-    /*
-     * Interpret a numerical name as an address.
-     */
-    if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
-     && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
-       if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
-           msg_fatal("host %s: conversion error for address family %d: %m",
-                   host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
-       addr_list = dns_rr_append(addr_list, addr);
-       freeaddrinfo(res0);
-       return (addr_list);
-    }
-
-    /*
-     * Use native name service when DNS is disabled.
-     */
-#define RETRY_AI_ERROR(e) \
-       ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
-#ifdef EAI_NODATA
-#define DSN_NOHOST(e) \
-       ((e) == EAI_AGAIN || (e) == EAI_NODATA || (e) == EAI_NONAME)
-#else
-#define DSN_NOHOST(e) \
-       ((e) == EAI_AGAIN || (e) == EAI_NONAME)
-#endif
-
-    if (var_disable_dns) {
-       if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
-           lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                           DSN_NOHOST(aierr) ? "4.4.4" : "4.3.0",
-                           450, "450 Host not found",
-                           "unable to look up host %s: %s",
-                           host, MAI_STRERROR(aierr));
-           lmtp_errno = (RETRY_AI_ERROR(aierr) ? LMTP_RETRY : LMTP_FAIL);
-       } else {
-           for (found = 0, res = res0; res != 0; res = res->ai_next) {
-               if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
-                   msg_info("skipping address family %d for host %s",
-                            res->ai_family, host);
-                   continue;
-               }
-               found++;
-               if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
-                   msg_fatal("host %s: conversion error for address family %d: %m",
-                   host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
-               addr_list = dns_rr_append(addr_list, addr);
-           }
-           freeaddrinfo(res0);
-           if (found == 0) {
-               lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                               "5.4.4", 550, "550 Host not found",
-                               "%s: host not found", host);
-               lmtp_errno = LMTP_FAIL;
-           }
-           return (addr_list);
-       }
-    }
-
-    /*
-     * Append the addresses for this host to the address list.
-     */
-    switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0, why->reason,
-                        DNS_REQ_FLAG_NONE, proto_info->dns_atype_list)) {
-    case DNS_OK:
-       for (rr = addr; rr; rr = rr->next)
-           rr->pref = pref;
-       addr_list = dns_rr_append(addr_list, addr);
-       break;
-    default:
-       lmtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
-                       "4.4.3", 450, "450 Host not found");
-       lmtp_errno = LMTP_RETRY;
-       break;
-    case DNS_FAIL:
-       lmtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
-                       "5.4.3", 550, "550 Name server failure");
-       lmtp_errno = LMTP_FAIL;
-       break;
-    case DNS_INVAL:
-    case DNS_NOTFOUND:
-       lmtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
-                       "5.4.4", 550, "550 Host not found");
-       lmtp_errno = LMTP_FAIL;
-       break;
-    }
-    return (addr_list);
-}
-
-/* lmtp_host_addr - direct host lookup */
-
-DNS_RR *lmtp_host_addr(char *host, DSN_BUF *why)
-{
-    DNS_RR *addr_list;
-
-    /*
-     * If the host is specified by numerical address, just convert the
-     * address to internal form. Otherwise, the host is specified by name.
-     */
-#define PREF0  0
-    addr_list = lmtp_addr_one((DNS_RR *) 0, host, PREF0, why);
-    if (msg_verbose)
-       lmtp_print_addr(host, addr_list);
-    return (addr_list);
-}
diff --git a/postfix/src/lmtp/lmtp_addr.h b/postfix/src/lmtp/lmtp_addr.h
deleted file mode 100644 (file)
index a29dba0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_addr 3h
-/* SUMMARY
-/*     LMTP server address lookup
-/* SYNOPSIS
-/*     #include "lmtp_addr.h"
-/* DESCRIPTION
-/* .nf
-
- /*
-  * Global library.
-  */
-#include <dsn_buf.h>
-
- /*
-  * DNS library.
-  */
-#include <dns.h>
-
- /*
-  * Internal interfaces.
-  */
-extern DNS_RR *lmtp_host_addr(char *, DSN_BUF *);
-
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*      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/src/lmtp/lmtp_chat.c b/postfix/src/lmtp/lmtp_chat.c
deleted file mode 100644 (file)
index 4abb0d6..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_chat 3
-/* SUMMARY
-/*     LMTP client request/response support
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     typedef struct {
-/* .in +4
-/*             int code;
-/*             char *dsn;
-/*             char *str;
-/*             VSTRING *dsn_buf;
-/*             VSTRING *str_buf;
-/* .in -4
-/*     } LMTP_RESP;
-/*
-/*     void    lmtp_chat_cmd(state, format, ...)
-/*     LMTP_STATE *state;
-/*     char    *format;
-/*
-/*     LMTP_RESP *lmtp_chat_resp(state)
-/*     LMTP_STATE *state;
-/*
-/*     void    lmtp_chat_notify(state)
-/*     LMTP_STATE *state;
-/*
-/*     void    lmtp_chat_reset(state)
-/*     LMTP_STATE *state;
-/* DESCRIPTION
-/*     This module implements LMTP client support for request/reply
-/*     conversations, and maintains a limited LMTP transaction log.
-/*
-/*     lmtp_chat_cmd() formats a command and sends it to an LMTP server.
-/*     Optionally, the command is logged.
-/*
-/*     lmtp_chat_resp() reads one LMTP server response. It separates the
-/*     numerical status code from the text, and concatenates multi-line
-/*     responses to one string, using a newline as separator.
-/*     Optionally, the server response is logged.
-/*
-/*     lmtp_chat_notify() sends a copy of the LMTP transaction log
-/*     to the postmaster for review. The postmaster notice is sent only
-/*     when delivery is possible immediately. It is an error to call
-/*     lmtp_chat_notify() when no LMTP transaction log exists.
-/*
-/*     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.
-/*
-/*     lmtp_chat_fake() constructs a synthetic LMTP server response
-/*     from its arguments.
-/* DIAGNOSTICS
-/*     Fatal errors: memory allocation problem, server response exceeds
-/*     configurable limit.
-/*     All other exceptions are handled by long jumps (see smtp_stream(3)).
-/* SEE ALSO
-/*     smtp_stream(3) LMTP session I/O support
-/*     msg(3) generic logging interface
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <stdlib.h>                    /* 44BSD stdarg.h uses abort() */
-#include <stdarg.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <string.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <vstream.h>
-#include <argv.h>
-#include <stringops.h>
-#include <line_wrap.h>
-#include <mymalloc.h>
-
-/* Global library. */
-
-#include <recipient_list.h>
-#include <deliver_request.h>
-#include <smtp_stream.h>
-#include <mail_params.h>
-#include <mail_addr.h>
-#include <post_mail.h>
-#include <mail_error.h>
-#include <dsn_util.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-
-#define LEN    VSTRING_LEN
-
-/* lmtp_chat_reset - reset LMTP transaction log */
-
-void    lmtp_chat_reset(LMTP_STATE *state)
-{
-    if (state->history) {
-       argv_free(state->history);
-       state->history = 0;
-    }
-    /* What's status without history? */
-    state->status = 0;
-    state->error_mask = 0;
-}
-
-/* lmtp_chat_append - append record to LMTP transaction log */
-
-static void lmtp_chat_append(LMTP_STATE *state, char *direction, char *data)
-{
-    char   *line;
-
-    if (state->history == 0)
-       state->history = argv_alloc(10);
-    line = concatenate(direction, data, (char *) 0);
-    argv_add(state->history, line, (char *) 0);
-    myfree(line);
-}
-
-/* lmtp_chat_cmd - send an LMTP command */
-
-void    lmtp_chat_cmd(LMTP_STATE *state, char *fmt,...)
-{
-    LMTP_SESSION *session = state->session;
-    va_list ap;
-
-    /*
-     * Format the command, and update the transaction log.
-     */
-    va_start(ap, fmt);
-    vstring_vsprintf(state->buffer, fmt, ap);
-    va_end(ap);
-    lmtp_chat_append(state, "Out: ", STR(state->buffer));
-
-    /*
-     * Optionally log the command first, so we can see in the log what the
-     * program is trying to do.
-     */
-    if (msg_verbose)
-       msg_info("> %s: %s", session->namaddr, STR(state->buffer));
-
-    /*
-     * Send the command to the LMTP server.
-     */
-    smtp_fputs(STR(state->buffer), LEN(state->buffer), session->stream);
-}
-
-/* lmtp_chat_resp - read and process LMTP server response */
-
-LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
-{
-    static LMTP_RESP rdata;
-    LMTP_SESSION *session = state->session;
-    char   *cp;
-    int     last_char;
-    int     three_digs = 0;
-    size_t  len;
-
-    /*
-     * Initialize the response data buffer.
-     */
-    if (rdata.str_buf == 0) {
-       rdata.dsn_buf = vstring_alloc(10);
-       rdata.str_buf = vstring_alloc(100);
-    }
-
-    /*
-     * Censor out non-printable characters in server responses. Concatenate
-     * multi-line server responses. Separate the status code from the text.
-     * Leave further parsing up to the application.
-     */
-    VSTRING_RESET(rdata.str_buf);
-    for (;;) {
-       last_char = smtp_get(state->buffer, session->stream, var_line_limit);
-       printable(STR(state->buffer), '?');
-       if (last_char != '\n')
-           msg_warn("%s: response longer than %d: %.30s...",
-                    session->namaddr, var_line_limit, STR(state->buffer));
-       if (msg_verbose)
-           msg_info("< %s: %s", session->namaddr, STR(state->buffer));
-
-       /*
-        * Defend against a denial of service attack by limiting the amount
-        * of multi-line text that we are willing to store.
-        */
-       if (LEN(rdata.str_buf) < var_line_limit) {
-           if (VSTRING_LEN(rdata.str_buf))
-               VSTRING_ADDCH(rdata.str_buf, '\n');
-           vstring_strcat(rdata.str_buf, STR(state->buffer));
-           lmtp_chat_append(state, "In:  ", STR(state->buffer));
-       }
-
-       /*
-        * Parse into code and text. Ignore unrecognized garbage. This means
-        * that any character except space (or end of line) will have the
-        * same effect as the '-' line continuation character.
-        */
-       for (cp = STR(state->buffer); *cp && ISDIGIT(*cp); cp++)
-            /* void */ ;
-       if ((three_digs = (cp - STR(state->buffer) == 3)) != 0) {
-           if (*cp == '-')
-               continue;
-           if (*cp == ' ' || *cp == 0)
-               break;
-       }
-
-       /*
-        * XXX Do not ignore garbage when ESMTP command pipelining is turned
-        * on. After sending ".<CR><LF>QUIT<CR><LF>", Postfix might recognize
-        * the server's 2XX QUIT reply as a 2XX END-OF-DATA reply after
-        * garbage, causing mail to be lost. Instead, make a long jump so
-        * that all recipients of multi-recipient mail get consistent
-        * treatment.
-        */
-       state->error_mask |= MAIL_ERROR_PROTOCOL;
-       if (state->features & LMTP_FEATURE_PIPELINING) {
-           msg_warn("non-LMTP response from %s: %.100s",
-                    session->namaddr, STR(state->buffer));
-           vstream_longjmp(session->stream, SMTP_ERR_PROTO);
-       }
-    }
-
-    /*
-     * Extract RFC 821 reply code and RFC 2034 detail code. Use a default
-     * detail code if none was given.
-     * 
-     * Ignore out-of-protocol enhanced status codes: codes that accompany 3XX
-     * replies, or codes whose initial digit is out of sync with the reply
-     * code.
-     * 
-     * XXX Potential stability problem. In order to save memory, the queue
-     * manager stores DSNs in a compact manner:
-     * 
-     * - empty strings are represented by null pointers,
-     * 
-     * - the status and reason are required to be non-empty.
-     * 
-     * Other Postfix daemons inherit this behavior, because they use the same
-     * DSN support code. This means that everything that receives DSNs must
-     * cope with null pointers for the optional DSN attributes, and that
-     * everything that provides DSN information must provide a non-empty
-     * status and reason, otherwise the DSN support code wil panic().
-     * 
-     * Thus, when the remote server sends a malformed reply (or 3XX out of
-     * context) we should not panic() in DSN_COPY() just because we don't
-     * have a status. Robustness suggests that we supply a status here, and
-     * that we leave it up to the down-stream code to override the
-     * server-supplied status in case of an error we can't detect here, such
-     * as an out-of-order server reply.
-     */
-    VSTRING_TERMINATE(rdata.str_buf);
-    vstring_strcpy(rdata.dsn_buf, "5.5.0");    /* SAFETY! protocol error */
-    if (three_digs != 0) {
-       rdata.code = atoi(STR(state->buffer));
-       if (strchr("245", STR(state->buffer)[0]) != 0) {
-           for (cp = STR(state->buffer) + 4; *cp == ' '; cp++)
-                /* void */ ;
-           if ((len = dsn_valid(cp)) > 0 && *cp == *STR(state->buffer)) {
-               vstring_strncpy(rdata.dsn_buf, cp, len);
-           } else {
-               vstring_strcpy(rdata.dsn_buf, "0.0.0");
-               STR(rdata.dsn_buf)[0] = STR(state->buffer)[0];
-           }
-       }
-    } else {
-       rdata.code = 0;
-    }
-    rdata.dsn = STR(rdata.dsn_buf);
-    rdata.str = STR(rdata.str_buf);
-    return (&rdata);
-}
-
-/* print_line - line_wrap callback */
-
-static void print_line(const char *str, int len, int indent, char *context)
-{
-    VSTREAM *notice = (VSTREAM *) context;
-
-    post_mail_fprintf(notice, " %*s%.*s", indent, "", len, str);
-}
-
-/* lmtp_chat_notify - notify postmaster */
-
-void    lmtp_chat_notify(LMTP_STATE *state)
-{
-    char   *myname = "lmtp_chat_notify";
-    LMTP_SESSION *session = state->session;
-    VSTREAM *notice;
-    char  **cpp;
-
-    /*
-     * Sanity checks.
-     */
-    if (state->history == 0)
-       msg_panic("%s: no conversation history", myname);
-    if (msg_verbose)
-       msg_info("%s: notify postmaster", myname);
-
-    /*
-     * Construct a message for the postmaster, explaining what this is all
-     * about. This is junk mail: don't send it when the mail posting service
-     * is unavailable, and use the double bounce sender address, to prevent
-     * mail bounce wars. Always prepend one space to message content that we
-     * generate from untrusted data.
-     */
-#define NULL_TRACE_FLAGS       0
-#define LENGTH 78
-#define INDENT 4
-
-    notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
-                                   var_error_rcpt,
-                                   CLEANUP_FLAG_MASK_INTERNAL,
-                                   NULL_TRACE_FLAGS);
-    if (notice == 0) {
-       msg_warn("postmaster notify: %m");
-       return;
-    }
-    post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
-                     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->namaddr);
-    post_mail_fputs(notice, "");
-    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, "");
-    argv_terminate(state->history);
-    for (cpp = state->history->argv; *cpp; cpp++)
-       line_wrap(printable(*cpp, '?'), LENGTH, INDENT, print_line,
-                 (char *) notice);
-    (void) post_mail_fclose(notice);
-}
diff --git a/postfix/src/lmtp/lmtp_connect.c b/postfix/src/lmtp/lmtp_connect.c
deleted file mode 100644 (file)
index b043257..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_connect 3
-/* SUMMARY
-/*     connect to LMTP server
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     LMTP_SESSION *lmtp_connect(destination, why)
-/*     char    *destination;
-/*     DSN_BUF *why;
-/* DESCRIPTION
-/*     This module implements LMTP connection management.
-/*
-/*     lmtp_connect() attempts to establish an LMTP session.
-/*
-/*     The destination is one of the following:
-/* .IP unix:address
-/*     Connect to a UNIX-domain service. The destination is a pathname.
-/*     Beware: UNIX-domain sockets are flakey on Solaris, at last up to
-/*     and including Solaris 7.0.
-/* .IP inet:address
-/*     Connect to an IPV4 service.
-/*     The destination is either a host name or a numeric address.
-/*     Symbolic or numeric service port information may be appended,
-/*     separated by a colon (":").
-/*
-/*     Numerical address information should always be quoted with `[]'.
-/* .PP
-/*     When no transport is specified, "inet" is assumed.
-/* DIAGNOSTICS
-/*     This routine either returns an LMTP_SESSION pointer, or
-/*     returns a null pointer and set the \fIlmtp_errno\fR
-/*     global variable accordingly:
-/* .IP LMTP_RETRY
-/*     The connection attempt failed, but should be retried later.
-/* .IP LMTP_FAIL
-/*     The connection attempt failed.
-/* .PP
-/*     In addition, a description of the error is made available
-/*     via the \fIwhy\fR argument.
-/* SEE ALSO
-/*     lmtp_proto(3) LMTP client protocol
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstream.h>
-#include <vstring.h>
-#include <split_at.h>
-#include <mymalloc.h>
-#include <iostuff.h>
-#include <timed_connect.h>
-#include <stringops.h>
-#include <host_port.h>
-#include <sane_connect.h>
-#include <inet_addr_list.h>
-#include <myaddrinfo.h>
-#include <sock_addr.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-#include <mail_proto.h>
-#include <own_inet_addr.h>
-#include <dsn_buf.h>
-
-/* DNS library. */
-
-#include <dns.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_addr.h"
-
- /*
-  * Forward declaration.
-  */
-static LMTP_SESSION *lmtp_connect_sock(int, struct sockaddr *, int,
-                                              const char *, const char *,
-                                              const char *, DSN_BUF *);
-
-/* lmtp_connect_unix - connect to UNIX-domain address */
-
-static LMTP_SESSION *lmtp_connect_unix(const char *addr,
-                                     const char *destination, DSN_BUF *why)
-{
-#undef sun
-    char   *myname = "lmtp_connect_unix";
-    struct sockaddr_un sun;
-    int     len = strlen(addr);
-    int     sock;
-
-    /*
-     * Sanity checks.
-     */
-    if (len >= (int) sizeof(sun.sun_path)) {
-       msg_warn("unix-domain name too long: %s", addr);
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA, "4.3.5",
-                       450, "450 Mail server configuration error",
-                       "Server configuration error");
-       lmtp_errno = LMTP_RETRY;
-       return (0);
-    }
-
-    /*
-     * Initialize.
-     */
-    memset((char *) &sun, 0, sizeof(sun));
-    sun.sun_family = AF_UNIX;
-#ifdef HAS_SUN_LEN
-    sun.sun_len = len + 1;
-#endif
-    memcpy(sun.sun_path, addr, len + 1);
-
-    /*
-     * Create a client socket.
-     */
-    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-       msg_fatal("%s: socket: %m", myname);
-
-    /*
-     * Connect to the LMTP server.
-     */
-    if (msg_verbose)
-       msg_info("%s: trying: %s...", myname, addr);
-
-    return (lmtp_connect_sock(sock, (struct sockaddr *) & sun, sizeof(sun),
-                             addr, addr, destination, why));
-}
-
-/* lmtp_connect_addr - connect to explicit address */
-
-static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
-                                     const char *destination, DSN_BUF *why)
-{
-    char   *myname = "lmtp_connect_addr";
-    struct sockaddr_storage ss;
-    struct sockaddr *sa = SOCK_ADDR_PTR(&ss);
-    SOCKADDR_SIZE salen = sizeof(ss);
-    MAI_HOSTADDR_STR hostaddr;
-    int     sock;
-
-    /*
-     * Sanity checks.
-     */
-    if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
-       msg_warn("%s: skip address type %s: %m",
-                myname, dns_strtype(addr->type));
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA, "4.3.0",
-                       450, "450 Network address conversion error",
-                       "network address conversion failed");
-       lmtp_errno = LMTP_RETRY;
-       return (0);
-    }
-
-    /*
-     * Initialize.
-     */
-    if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
-       msg_fatal("%s: socket: %m", myname);
-
-    /*
-     * Connect to the LMTP server.
-     */
-    SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
-    if (msg_verbose)
-       msg_info("%s: trying: %s[%s] port %d...",
-                myname, addr->name, hostaddr.buf, ntohs(port));
-
-    return (lmtp_connect_sock(sock, sa, salen,
-                             addr->name, hostaddr.buf, destination, why));
-}
-
-/* lmtp_connect_sock - connect a socket over some transport */
-
-static LMTP_SESSION *lmtp_connect_sock(int sock, struct sockaddr * sa, int len,
-                                        const char *name, const char *addr,
-                                              const char *destination,
-                                              DSN_BUF *why)
-{
-    int     conn_stat;
-    int     saved_errno;
-    VSTREAM *stream;
-    int     ch;
-
-    if (var_lmtp_conn_tmout > 0) {
-       non_blocking(sock, NON_BLOCKING);
-       conn_stat = timed_connect(sock, sa, len, var_lmtp_conn_tmout);
-       saved_errno = errno;
-       non_blocking(sock, BLOCKING);
-       errno = saved_errno;
-    } else {
-       conn_stat = sane_connect(sock, sa, len);
-    }
-    if (conn_stat < 0) {
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                       "4.4.1", 420, "420 Unable to connect to server",
-                       "connect to %s[%s]: %m", name, addr);
-       lmtp_errno = LMTP_RETRY;
-       close(sock);
-       return (0);
-    }
-
-    /*
-     * Skip this host if it takes no action within some time limit.
-     */
-    if (read_wait(sock, var_lmtp_lhlo_tmout) < 0) {
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                       "4.4.2", 426, "426 No response from server",
-                       "connect to %s[%s]: read timeout", name, addr);
-       lmtp_errno = LMTP_RETRY;
-       close(sock);
-       return (0);
-    }
-
-    /*
-     * Skip this host if it disconnects without talking to us.
-     */
-    stream = vstream_fdopen(sock, O_RDWR);
-    if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                       "4.4.0", 421, "421 Lost connection",
-                       "connect to %s[%s]: server dropped connection without sending the initial greeting",
-                       name, addr);
-       lmtp_errno = LMTP_RETRY;
-       vstream_fclose(stream);
-       return (0);
-    }
-    vstream_ungetc(stream, ch);
-
-    /*
-     * Skip this host if it sends a 4xx or 5xx greeting.
-     */
-    if (ch == '4' || ch == '5') {
-       lmtp_dsn_update(why, DSN_BY_LOCAL_MTA,
-                       "4.3.0", 420, "420 Connection rejected by server",
-                       "connect to %s[%s]: server refused mail service",
-                       name, addr);
-       lmtp_errno = LMTP_RETRY;
-       vstream_fclose(stream);
-       return (0);
-    }
-    return (lmtp_session_alloc(stream, name, addr, destination));
-}
-
-/* lmtp_connect_host - direct connection to host */
-
-static LMTP_SESSION *lmtp_connect_host(char *host, unsigned port,
-                                     const char *destination, DSN_BUF *why)
-{
-    LMTP_SESSION *session = 0;
-    DNS_RR *addr_list;
-    DNS_RR *addr;
-
-    /*
-     * Try each address in the specified order until we find one that works.
-     * The addresses belong to the same A record, so we have no information
-     * on what address is "best".
-     */
-    addr_list = lmtp_host_addr(host, why);
-    for (addr = addr_list; addr; addr = addr->next) {
-       if ((session = lmtp_connect_addr(addr, port, destination, why)) != 0) {
-           break;
-       }
-    }
-    dns_rr_free(addr_list);
-    return (session);
-}
-
-/* lmtp_parse_destination - parse destination */
-
-static char *lmtp_parse_destination(const char *destination, char *def_service,
-                                           char **hostp, unsigned *portp)
-{
-    char   *myname = "lmtp_parse_destination";
-    char   *buf = mystrdup(destination);
-    char   *service;
-    struct servent *sp;
-    char   *protocol = "tcp";          /* XXX configurable? */
-    unsigned port;
-    const char *err;
-
-    if (msg_verbose)
-       msg_info("%s: %s %s", myname, destination, def_service);
-
-    /*
-     * Parse the host/port information. We're working with a copy of the
-     * destination argument so the parsing can be destructive.
-     */
-    if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
-       msg_fatal("%s in LMTP server description: %s", err, destination);
-
-    /*
-     * 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 (alldig(service)) {
-       if ((port = atoi(service)) >= 65536)
-           msg_fatal("bad numeric port in destination: %s", destination);
-       *portp = htons(port);
-    } else if ((sp = getservbyname(service, protocol)) != 0)
-       *portp = sp->s_port;
-    else
-       *portp = htons(var_lmtp_tcp_port);
-    return (buf);
-}
-
-/* lmtp_connect - establish LMTP connection */
-
-LMTP_SESSION *lmtp_connect(const char *destination, DSN_BUF *why)
-{
-    char   *myname = "lmtp_connect";
-    LMTP_SESSION *session;
-    char   *dest_buf;
-    char   *host;
-    unsigned port;
-    char   *def_service = "lmtp";      /* XXX configurable? */
-
-    /*
-     * Connect to the LMTP server.
-     * 
-     * XXX Ad-hoc transport parsing and connection management. Some or all
-     * should be moved away to a reusable library routine so that every
-     * program benefits from it.
-     * 
-     * XXX Should transform destination into canonical form (unix:/path or
-     * inet:host:port before entering it into the connection cache. See also
-     * the connection cache lookup code in lmtp.c.
-     */
-    if (strncmp(destination, "unix:", 5) == 0)
-       return (lmtp_connect_unix(destination + 5, destination, why));
-    if (strncmp(destination, "inet:", 5) == 0)
-       dest_buf = lmtp_parse_destination(destination + 5, def_service,
-                                         &host, &port);
-    else
-       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/src/lmtp/lmtp_dsn.c b/postfix/src/lmtp/lmtp_dsn.c
deleted file mode 100644 (file)
index aba9035..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_dsn 3
-/* SUMMARY
-/*     application-specific wrappers
-/* SYNOPSIS
-/*     #include <smtp.h>
-/*
-/*     void    lmtp_dsn_update(dsb, mta_name, status, code, reply,
-/*                             reason_fmt, ...)
-/*     DSN_BUF *dsb;
-/*     const char *mta_name;
-/*     const char *status;
-/*     const char *reply;
-/*     const char *reason_fmt;
-/*
-/*     void    vlmtp_dsn_update(dsb, mta_name, status, code, reply,
-/*                             reason_fmt, ap)
-/*     DSN_BUF *dsb;
-/*     const char *mta_name;
-/*     const char *status;
-/*     const char *reply;
-/*     const char *reason_fmt;
-/*     va_list ap;
-/*
-/*     void    lmtp_dsn_formal(dsb, mta_name, status, code, reply)
-/*     DSN_BUF *dsb;
-/*     const char *mta_name;
-/*     const char *status;
-/*     const char *reply;
-/*
-/*     DSN     *LMTP_DSN_ASSIGN(dsn, mta_name, status, action, reply, reason)
-/*     DSN     *dsn;
-/*     const char *mta_name;
-/*     const char *status;
-/*     const char *action;
-/*     const char *reply;
-/*     const char *reason;
-/* DESCRIPTION
-/*     This module implements an application-specific wrapper for
-/*     the dsbuf(3) delivery status information module. This
-/*     eliminates clutter from the code.
-/*
-/*     lmtp_dsn_update() updates the formal and informal delivery
-/*     status attributes.
-/*
-/*     vlmtp_dsn_update() implements an alternative interface.
-/*
-/*     lmtp_dsn_formal() updates the formal delivery status
-/*     attributes and leaves the informal reason attribute unmodified.
-/*
-/*     LMTP_DSN_ASSIGN() is a wrapper around the DSN_ASSIGN macro.
-/*
-/*     Arguments:
-/* .IP dsb
-/*     Delivery status information. See dsbuf(3).
-/* .IP mta_name
-/*     The name of the MTA that issued the response given with the
-/*     status and reply arguments. Specify DSN_BY_LOCAL_MTA for
-/*     status and "reply" information that was issued by the local
-/*     MTA.
-/* .IP status
-/*     RFC 3463 status code.
-/* .IP code
-/*     LMTP reply code.
-/* .IP reply
-/*     LMTP reply code followed by text. The bounce(8) server
-/*     replaces non-printable characters by '?', so it is a good
-/*     idea to replace embedded newline characters by spaces.
-/* .IP reason_fmt
-/*     Format string for the informal reason attribute.
-/* .IP DIAGNOSTICS
-/*     Fatal: out of memory. Panic: invalid arguments.
-/* BUGS
-/*     It seems wasteful to copy mostly-constant information into
-/*     VSTRING buffers, but it's unavoidable if one needs to
-/*     delegate work to a subordinate routine, and report the error
-/*     after the subordinate has terminated.
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <stdlib.h>                    /* 44BSD stdarg.h uses abort() */
-#include <stdarg.h>
-
-/* Utility library. */
-
-#include <vstring.h>
-
-/* Global library. */
-
-#include <dsn_buf.h>
-
-/* Application-specific. */
-
-#include <lmtp.h>
-
-/* lmtp_dsn_update - update formal and informal DSN attributes */
-
-void    lmtp_dsn_update(DSN_BUF *why, const char *mta_name,
-                               const char *status, int code,
-                               const char *reply,
-                               const char *format,...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    vlmtp_dsn_update(why, mta_name, status, code, reply, format, ap);
-    va_end(ap);
-}
-
-/* vlmtp_dsn_update - update formal and informal DSN attributes */
-
-void    vlmtp_dsn_update(DSN_BUF *why, const char *mta_name,
-                                const char *status, int code,
-                                const char *reply,
-                                const char *format, va_list ap)
-{
-    dsb_formal(why, status, DSB_DEF_ACTION,
-              mta_name ? DSB_MTYPE_DNS : DSB_MTYPE_NONE,
-              mta_name, DSB_DTYPE_SMTP, code, reply);
-    vstring_vsprintf(why->reason, format, ap);
-}
-
-/* lmtp_dsn_formal - update formal DSN attributes only */
-
-void    lmtp_dsn_formal(DSN_BUF *why, const char *mta_name,
-                               const char *status, int code,
-                               const char *reply)
-{
-    dsb_formal(why, status, DSB_DEF_ACTION,
-              mta_name ? DSB_MTYPE_DNS : DSB_MTYPE_NONE,
-              mta_name, DSB_DTYPE_SMTP, code, reply);
-}
diff --git a/postfix/src/lmtp/lmtp_proto.c b/postfix/src/lmtp/lmtp_proto.c
deleted file mode 100644 (file)
index d051c53..0000000
+++ /dev/null
@@ -1,905 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_proto 3
-/* SUMMARY
-/*     client LMTP protocol
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     int     lmtp_lhlo(state)
-/*     LMTP_STATE *state;
-/*
-/*     int     lmtp_xfer(state)
-/*     LMTP_STATE *state;
-/*
-/*     int     lmtp_rset(state)
-/*     LMTP_STATE *state;
-/*
-/*     int     lmtp_quit(state)
-/*     LMTP_STATE *state;
-/* DESCRIPTION
-/*     This module implements the client side of the LMTP protocol.
-/*
-/*     lmtp_lhlo() performs the initial handshake with the LMTP server.
-/*
-/*     lmtp_xfer() sends message envelope information followed by the
-/*     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 a lone RSET command and waits for the response.
-/*     In case of a negative reply it sets the CANT_RSET_THIS_SESSION flag.
-/*
-/*     lmtp_quit() sends a lone QUIT command and waits for the response
-/*     only if waiting for QUIT replies is enabled.
-/* 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()
-/*     and lmtp_quit(), success means the ability to perform an LMTP
-/*     conversation, not necessarily OK replies from the server.
-/*
-/*     Warnings: corrupt message file. A corrupt message is marked
-/*     as "corrupt" by changing its queue file permissions.
-/* SEE ALSO
-/*     lmtp(3h) internal data structures
-/*     lmtp_chat(3) query/reply LMTP support
-/*     lmtp_trouble(3) error handlers
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*
-/*     Pipelining code in cooperation with:
-/*     Jon Ribbens
-/*     Oaktree Internet Solutions Ltd.,
-/*     Internet House,
-/*     Canal Basin,
-/*     Coventry,
-/*     CV1 4LY, United Kingdom.
-/*
-/*     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
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <sys/stat.h>
-#include <sys/socket.h>                        /* shutdown(2) */
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>                    /* 44BSD stdarg.h uses abort() */
-#include <stdarg.h>
-#include <time.h>
-
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <vstream.h>
-#include <vstring_vstream.h>
-#include <stringops.h>
-#include <mymalloc.h>
-#include <name_code.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-#include <smtp_stream.h>
-#include <mail_queue.h>
-#include <recipient_list.h>
-#include <deliver_request.h>
-#include <deliver_completed.h>
-#include <defer.h>
-#include <bounce.h>
-#include <sent.h>
-#include <record.h>
-#include <rec_type.h>
-#include <off_cvt.h>
-#include <mark_corrupt.h>
-#include <quote_821_local.h>
-#include <quote_822_local.h>
-#include <mail_proto.h>
-#include <dsn_mask.h>
-#include <xtext.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_sasl.h"
-
- /*
-  * 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->QUIT->LAST. The states
-  * MAIL, RCPT, and DATA may also be followed by ABORT->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 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.
-  * 
-  * Client states that are associated with sending mail (up to and including
-  * LMTP_STATE_DOT) must have smaller numerical values than the non-sending
-  * states (LMTP_STATE_ABORT .. LMTP_STATE_LAST).
-  */
-#define LMTP_STATE_XFORWARD_NAME_ADDR 0
-#define LMTP_STATE_XFORWARD_PROTO_HELO 1
-#define LMTP_STATE_MAIL                2
-#define LMTP_STATE_RCPT                3
-#define LMTP_STATE_DATA                4
-#define LMTP_STATE_DOT         5
-#define LMTP_STATE_ABORT       6
-#define LMTP_STATE_RSET                7
-#define LMTP_STATE_QUIT                8
-#define LMTP_STATE_LAST                9
-
-int    *xfer_timeouts[LMTP_STATE_LAST] = {
-    &var_lmtp_xfwd_tmout,              /* name/addr */
-    &var_lmtp_xfwd_tmout,              /* helo/proto */
-    &var_lmtp_mail_tmout,
-    &var_lmtp_rcpt_tmout,
-    &var_lmtp_data0_tmout,
-    &var_lmtp_data2_tmout,
-    &var_lmtp_rset_tmout,              /* abort */
-    &var_lmtp_rset_tmout,              /* rset */
-    &var_lmtp_quit_tmout,
-};
-
-char   *xfer_states[LMTP_STATE_LAST] = {
-    "sending XFORWARD name/address",
-    "sending XFORWARD protocol/helo_name",
-    "sending MAIL FROM",
-    "sending RCPT TO",
-    "sending DATA command",
-    "sending end of data -- message may be sent more than once",
-    "sending RSET",                    /* abort */
-    "sending RSET",                    /* rset */
-    "sending QUIT",
-};
-
-char   *xfer_request[LMTP_STATE_LAST] = {
-    "XFORWARD name/address command",
-    "XFORWARD helo/protocol command",
-    "MAIL FROM command",
-    "RCPT TO command",
-    "DATA command",
-    "end of DATA command",
-    "RSET command",                    /* abort */
-    "RSET command",                    /* rset */
-    "QUIT command",
-};
-
-static int lmtp_send_proto_helo;
-
-/* lmtp_lhlo - perform initial handshake with LMTP server */
-
-int     lmtp_lhlo(LMTP_STATE *state)
-{
-    LMTP_SESSION *session = state->session;
-    LMTP_RESP *resp;
-    int     except;
-    char   *lines;
-    char   *words;
-    char   *word;
-    static NAME_CODE xforward_features[] = {
-       XFORWARD_NAME, LMTP_FEATURE_XFORWARD_NAME,
-       XFORWARD_ADDR, LMTP_FEATURE_XFORWARD_ADDR,
-       XFORWARD_PROTO, LMTP_FEATURE_XFORWARD_PROTO,
-       XFORWARD_HELO, LMTP_FEATURE_XFORWARD_HELO,
-       XFORWARD_DOMAIN, LMTP_FEATURE_XFORWARD_DOMAIN,
-       0, 0,
-    };
-
-    /*
-     * Prepare for disaster.
-     */
-    smtp_timeout_setup(state->session->stream, var_lmtp_lhlo_tmout);
-    if ((except = vstream_setjmp(state->session->stream)) != 0)
-       return (lmtp_stream_except(state, except, "sending LHLO"));
-
-    /*
-     * Read and parse the server's LMTP greeting banner.
-     */
-    if (((resp = lmtp_chat_resp(state))->code / 100) != 2)
-       return (lmtp_site_fail(state, session->host, resp,
-                              "host %s refused to talk to me: %s",
-                        session->namaddr, translit(resp->str, "\n", " ")));
-
-    /*
-     * Return the compliment.
-     */
-    lmtp_chat_cmd(state, "LHLO %s", var_myhostname);
-    if ((resp = lmtp_chat_resp(state))->code / 100 != 2)
-       return (lmtp_site_fail(state, session->host, resp,
-                              "host %s refused to talk to me: %s",
-                              session->namaddr,
-                              translit(resp->str, "\n", " ")));
-
-    /*
-     * Pick up some useful features offered by the LMTP server. XXX Until we
-     * have a portable routine to convert from string to off_t with proper
-     * overflow detection, ignore the message size limit advertised by the
-     * LMTP server. Otherwise, we might do the wrong thing when the server
-     * advertises a really huge message size limit.
-     */
-    state->features = 0;
-    lines = resp->str;
-    (void) mystrtok(&lines, "\n");
-    while ((words = mystrtok(&lines, "\n")) != 0) {
-       if (mystrtok(&words, "- ") && (word = mystrtok(&words, " \t=")) != 0) {
-           if (strcasecmp(word, "8BITMIME") == 0)
-               state->features |= LMTP_FEATURE_8BITMIME;
-           else if (strcasecmp(word, "PIPELINING") == 0)
-               state->features |= LMTP_FEATURE_PIPELINING;
-           else if (strcasecmp(word, "XFORWARD") == 0)
-               while ((word = mystrtok(&words, " \t")) != 0)
-                   state->features |= name_code(xforward_features,
-                                                NAME_CODE_FLAG_NONE, word);
-           else if (strcasecmp(word, "SIZE") == 0)
-               state->features |= LMTP_FEATURE_SIZE;
-#ifdef USE_SASL_AUTH
-           else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0)
-               lmtp_sasl_helo_auth(state, words);
-#endif
-           else if (strcasecmp(word, "DSN") == 0)
-               state->features |= LMTP_FEATURE_DSN;
-       }
-    }
-    if (msg_verbose)
-       msg_info("server features: 0x%x", state->features);
-
-    /*
-     * We use LMTP command pipelining if the server said it supported it.
-     * Since we use blocking I/O, RFC 2197 says that we should inspect the
-     * TCP window size and not send more than this amount of information.
-     * Unfortunately this information is not available using the sockets
-     * interface. However, we *can* get the TCP send buffer size on the local
-     * TCP/IP stack. We should be able to fill this buffer without being
-     * blocked, and then the kernel will effectively do non-blocking I/O for
-     * us by automatically writing out the contents of its send buffer while
-     * we are reading in the responses. In addition to TCP buffering we have
-     * to be aware of application-level buffering by the vstream module,
-     * which is limited to a couple kbytes.
-     * 
-     * 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->sndbufsize = 4 * 1024;
-       if (msg_verbose)
-           msg_info("Using LMTP PIPELINING, send buffer size is %d",
-                    state->sndbufsize);
-    } else
-       state->sndbufsize = 0;
-
-#ifdef USE_SASL_AUTH
-    if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
-       return (lmtp_sasl_helo_login(state));
-#endif
-
-    return (0);
-}
-
-/* lmtp_loop - the LMTP state machine */
-
-static int lmtp_loop(LMTP_STATE *state, NOCLOBBER int send_state,
-                            NOCLOBBER int recv_state)
-{
-    char   *myname = "lmtp_loop";
-    DELIVER_REQUEST *request = state->request;
-    LMTP_SESSION *session = state->session;
-    LMTP_RESP *resp;
-    RECIPIENT *rcpt;
-    VSTRING *next_command = vstring_alloc(100);
-    int    *NOCLOBBER survivors = 0;
-    NOCLOBBER int next_state;
-    NOCLOBBER int next_rcpt;
-    NOCLOBBER int send_rcpt;
-    NOCLOBBER int recv_rcpt;
-    NOCLOBBER int nrcpt;
-    int     except;
-    int     rec_type;
-    NOCLOBBER int prev_type = 0;
-    NOCLOBBER int sndbuffree;
-    NOCLOBBER int mail_from_rejected;
-    NOCLOBBER int recv_dot;
-
-    /*
-     * Macros for readability. XXX Aren't LMTP addresses supposed to be case
-     * insensitive?
-     */
-#define REWRITE_ADDRESS(dst, src) do { \
-         if (*(src)) { \
-             quote_821_local(dst, src); \
-         } else { \
-             vstring_strcpy(dst, src); \
-         } \
-    } while (0)
-
-#define RETURN(x) do { \
-         vstring_free(next_command); \
-         if (survivors) \
-             myfree((char *) survivors); \
-         return (x); \
-    } while (0)
-
-#define SENDER_IS_AHEAD \
-       (recv_state < send_state || recv_rcpt != send_rcpt)
-
-#define SENDER_IN_WAIT_STATE \
-       (send_state == LMTP_STATE_DOT || send_state == LMTP_STATE_LAST)
-
-#define SENDING_MAIL \
-       (recv_state <= LMTP_STATE_DOT)
-
-#define CANT_RSET_THIS_SESSION \
-       (state->features |= LMTP_FEATURE_RSET_REJECTED)
-
-    /*
-     * Pipelining support requires two loops: one loop for sending and one
-     * for receiving. Each loop has its own independent state. Most of the
-     * time the sender can run ahead of the receiver by as much as the TCP
-     * send buffer permits. There are only two places where the sender must
-     * wait for status information from the receiver: once after sending DATA
-     * and once after sending QUIT.
-     * 
-     * The sender state advances until the TCP send buffer would overflow, or
-     * until the sender needs status information from the receiver. At that
-     * point the receiver starts processing responses. Once the receiver has
-     * caught up with the sender, the sender resumes sending commands. If the
-     * receiver detects a serious problem (MAIL FROM rejected, all RCPT TO
-     * commands rejected, DATA rejected) it forces the sender to abort the
-     * LMTP dialog with RSET.
-     */
-    nrcpt = 0;
-    next_rcpt = send_rcpt = recv_rcpt = recv_dot = 0;
-    mail_from_rejected = 0;
-    sndbuffree = state->sndbufsize;
-
-    while (recv_state != LMTP_STATE_LAST) {
-
-       /*
-        * Build the next command.
-        */
-       switch (send_state) {
-
-           /*
-            * Sanity check.
-            */
-       default:
-           msg_panic("%s: bad sender state %d", myname, send_state);
-
-           /*
-            * Build the XFORWARD command. With properly sanitized
-            * information, the command length stays within the 512 byte
-            * command line length limit.
-            */
-       case LMTP_STATE_XFORWARD_NAME_ADDR:
-           vstring_strcpy(next_command, XFORWARD_CMD);
-           if (state->features & LMTP_FEATURE_XFORWARD_NAME)
-               vstring_sprintf_append(next_command, " %s=%s",
-                  XFORWARD_NAME, DEL_REQ_ATTR_AVAIL(request->client_name) ?
-                              request->client_name : XFORWARD_UNAVAILABLE);
-           if (state->features & LMTP_FEATURE_XFORWARD_ADDR)
-               vstring_sprintf_append(next_command, " %s=%s",
-                  XFORWARD_ADDR, DEL_REQ_ATTR_AVAIL(request->client_addr) ?
-                              request->client_addr : XFORWARD_UNAVAILABLE);
-           if (lmtp_send_proto_helo)
-               next_state = LMTP_STATE_XFORWARD_PROTO_HELO;
-           else
-               next_state = LMTP_STATE_MAIL;
-           break;
-
-       case LMTP_STATE_XFORWARD_PROTO_HELO:
-           vstring_strcpy(next_command, XFORWARD_CMD);
-           if (state->features & LMTP_FEATURE_XFORWARD_PROTO)
-               vstring_sprintf_append(next_command, " %s=%s",
-                XFORWARD_PROTO, DEL_REQ_ATTR_AVAIL(request->client_proto) ?
-                             request->client_proto : XFORWARD_UNAVAILABLE);
-           if (state->features & LMTP_FEATURE_XFORWARD_HELO)
-               vstring_sprintf_append(next_command, " %s=%s",
-                  XFORWARD_HELO, DEL_REQ_ATTR_AVAIL(request->client_helo) ?
-                              request->client_helo : XFORWARD_UNAVAILABLE);
-           if (state->features & LMTP_FEATURE_XFORWARD_DOMAIN)
-               vstring_sprintf_append(next_command, " %s=%s", XFORWARD_DOMAIN,
-                        DEL_REQ_ATTR_AVAIL(request->rewrite_context) == 0 ?
-                                      XFORWARD_UNAVAILABLE :
-                    strcmp(request->rewrite_context, MAIL_ATTR_RWR_LOCAL) ?
-                                 XFORWARD_DOM_REMOTE : XFORWARD_DOM_LOCAL);
-           next_state = LMTP_STATE_MAIL;
-           break;
-
-           /*
-            * Build the MAIL FROM command.
-            */
-       case LMTP_STATE_MAIL:
-           GETTIMEOFDAY(&request->msg_stats.conn_setup_done);
-           REWRITE_ADDRESS(state->scratch, request->sender);
-           vstring_sprintf(next_command, "MAIL FROM:<%s>",
-                           vstring_str(state->scratch));
-           if (state->features & LMTP_FEATURE_SIZE)    /* RFC 1652 */
-               vstring_sprintf_append(next_command, " SIZE=%lu",
-                                      request->data_size);
-           if (state->features & LMTP_FEATURE_8BITMIME) {
-               if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
-                   vstring_strcat(next_command, " BODY=8BITMIME");
-               else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
-                   vstring_strcat(next_command, " BODY=7BIT");
-               else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
-                   msg_warn("%s: unknown content encoding: %s",
-                            request->queue_id, request->encoding);
-           }
-           if (state->features & LMTP_FEATURE_DSN) {
-               if (request->dsn_envid[0]) {
-                   vstring_sprintf_append(next_command, " ENVID=");
-                   xtext_quote_append(next_command, request->dsn_envid, "+=");
-               }
-               if (request->dsn_ret)
-                   vstring_sprintf_append(next_command, " RET=%s",
-                                          dsn_ret_str(request->dsn_ret));
-           }
-
-           /*
-            * We authenticate the local MTA only, but not the sender.
-            */
-#ifdef USE_SASL_AUTH
-           if (var_lmtp_sasl_enable
-               && (state->features & LMTP_FEATURE_AUTH)
-               && state->sasl_passwd)
-               vstring_strcat(next_command, " AUTH=<>");
-#endif
-           next_state = LMTP_STATE_RCPT;
-           break;
-
-           /*
-            * Build one RCPT TO command before we have seen the MAIL FROM
-            * response.
-            */
-       case LMTP_STATE_RCPT:
-           rcpt = request->rcpt_list.info + send_rcpt;
-           REWRITE_ADDRESS(state->scratch, rcpt->address);
-           vstring_sprintf(next_command, "RCPT TO:<%s>",
-                           vstring_str(state->scratch));
-           if (state->features & LMTP_FEATURE_DSN) {
-               /* XXX DSN xtext encode address value not type. */
-               if (rcpt->dsn_orcpt[0]) {
-                   xtext_quote(state->scratch, rcpt->dsn_orcpt, "+=");
-                   vstring_sprintf_append(next_command, " ORCPT=%s",
-                                          vstring_str(state->scratch));
-               } else if (rcpt->orig_addr[0]) {
-                   quote_822_local(state->scratch, rcpt->orig_addr);
-                   vstring_sprintf(state->scratch2, "rfc822;%s",
-                                   vstring_str(state->scratch));
-                   xtext_quote(state->scratch, vstring_str(state->scratch2), "+=");
-                   vstring_sprintf_append(next_command, " ORCPT=%s",
-                                          vstring_str(state->scratch));
-               }
-               if (rcpt->dsn_notify)
-                   vstring_sprintf_append(next_command, " NOTIFY=%s",
-                                          dsn_notify_str(rcpt->dsn_notify));
-           }
-           if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
-               next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
-                   LMTP_STATE_RSET : LMTP_STATE_DATA;
-           break;
-
-           /*
-            * Build the DATA command before we have seen all the RCPT TO
-            * responses.
-            */
-       case LMTP_STATE_DATA:
-           vstring_strcpy(next_command, "DATA");
-           next_state = LMTP_STATE_DOT;
-           break;
-
-           /*
-            * Build the "." command before we have seen the DATA response.
-            */
-       case LMTP_STATE_DOT:
-           vstring_strcpy(next_command, ".");
-           next_state = var_lmtp_cache_conn ?
-               LMTP_STATE_LAST : LMTP_STATE_QUIT;
-           break;
-
-           /*
-            * Can't happen. The LMTP_STATE_ABORT sender state is entered by
-            * the receiver and is left before the bottom of the main loop.
-            */
-       case LMTP_STATE_ABORT:
-           msg_panic("%s: sender abort state", myname);
-
-           /*
-            * Build the RSET command.  This is used between pipelined
-            * deliveries, and to abort a trace-only delivery request.
-            */
-       case LMTP_STATE_RSET:
-           vstring_strcpy(next_command, "RSET");
-           next_state = LMTP_STATE_LAST;
-           break;
-
-           /*
-            * Build the QUIT command.
-            */
-       case LMTP_STATE_QUIT:
-           vstring_strcpy(next_command, "QUIT");
-           next_state = LMTP_STATE_LAST;
-           break;
-
-           /*
-            * The final sender state has no action associated with it.
-            */
-       case LMTP_STATE_LAST:
-           VSTRING_RESET(next_command);
-           break;
-       }
-       VSTRING_TERMINATE(next_command);
-
-       /*
-        * Process responses until the receiver has caught up. Vstreams
-        * automatically flush buffered output when reading new data.
-        * 
-        * Flush unsent output if command pipelining is off or if no I/O
-        * happened for a while. This limits the accumulation of client-side
-        * delays in pipelined sessions.
-        */
-       if (SENDER_IN_WAIT_STATE
-           || (SENDER_IS_AHEAD
-               && (VSTRING_LEN(next_command) + 2 > sndbuffree
-           || time((time_t *) 0) - vstream_ftime(session->stream) > 10))) {
-           while (SENDER_IS_AHEAD) {
-
-               /*
-                * Sanity check.
-                */
-               if (recv_state < LMTP_STATE_XFORWARD_NAME_ADDR
-                   || recv_state > LMTP_STATE_QUIT)
-                   msg_panic("%s: bad receiver state %d (sender state %d)",
-                             myname, recv_state, send_state);
-
-               /*
-                * Receive the next server response. Use the proper timeout,
-                * and log the proper client state in case of trouble.
-                */
-               smtp_timeout_setup(state->session->stream,
-                                  *xfer_timeouts[recv_state]);
-               if ((except = vstream_setjmp(state->session->stream)) != 0)
-                   RETURN(SENDING_MAIL ? lmtp_stream_except(state, except,
-                                            xfer_states[recv_state]) : -1);
-               resp = lmtp_chat_resp(state);
-
-               /*
-                * Process the response.
-                */
-               switch (recv_state) {
-
-                   /*
-                    * Process the XFORWARD response.
-                    */
-               case LMTP_STATE_XFORWARD_NAME_ADDR:
-                   if (resp->code / 100 != 2)
-                       msg_warn("host %s said: %s (in reply to %s)",
-                                session->namaddr,
-                                translit(resp->str, "\n", " "),
-                              xfer_request[LMTP_STATE_XFORWARD_NAME_ADDR]);
-                   if (lmtp_send_proto_helo)
-                       recv_state = LMTP_STATE_XFORWARD_PROTO_HELO;
-                   else
-                       recv_state = LMTP_STATE_MAIL;
-                   break;
-
-               case LMTP_STATE_XFORWARD_PROTO_HELO:
-                   if (resp->code / 100 != 2)
-                       msg_warn("host %s said: %s (in reply to %s)",
-                                session->namaddr,
-                                translit(resp->str, "\n", " "),
-                             xfer_request[LMTP_STATE_XFORWARD_PROTO_HELO]);
-                   recv_state = LMTP_STATE_MAIL;
-                   break;
-
-                   /*
-                    * Process the MAIL FROM response. When the server
-                    * rejects the sender, set the mail_from_rejected flag so
-                    * that the receiver may apply a course correction.
-                    */
-               case LMTP_STATE_MAIL:
-                   if (resp->code / 100 != 2) {
-                       lmtp_mesg_fail(state, session->host, resp,
-                                      "host %s said: %s (in reply to %s)",
-                                      session->namaddr,
-                                      translit(resp->str, "\n", " "),
-                                      xfer_request[LMTP_STATE_MAIL]);
-                       mail_from_rejected = 1;
-                   }
-                   recv_state = LMTP_STATE_RCPT;
-                   break;
-
-                   /*
-                    * Process one RCPT TO response. If MAIL FROM was
-                    * rejected, ignore RCPT TO responses: all recipients are
-                    * dead already. When all recipients are rejected the
-                    * receiver may apply a course correction.
-                    * 
-                    * XXX 2821: Section 4.5.3.1 says that a 552 RCPT TO reply
-                    * must be treated as if the server replied with 452.
-                    * However, this causes "too much mail data" to be
-                    * treated as a recoverable error, which is wrong. I'll
-                    * stick with RFC 821.
-                    */
-               case LMTP_STATE_RCPT:
-                   if (!mail_from_rejected) {
-#ifdef notdef
-                       if (resp->code == 552) {
-                           resp->code = 452;
-                           STR(resp->dsn_buf)[0] = '4';
-                       }
-#endif
-                       rcpt = request->rcpt_list.info + recv_rcpt;
-                       if (resp->code / 100 == 2) {
-                           if (survivors == 0)
-                               survivors = (int *)
-                                   mymalloc(request->rcpt_list.len
-                                            * sizeof(int));
-                           survivors[nrcpt++] = recv_rcpt;
-                           /* If trace-only, mark the recipient done. */
-                           if (DEL_REQ_TRACE_ONLY(request->flags)) {
-                               translit(resp->str, "\n", " ");
-                               lmtp_rcpt_done(state, resp, rcpt);
-                           }
-                       } else {
-                           lmtp_rcpt_fail(state, session->host, resp, rcpt,
-                                       "host %s said: %s (in reply to %s)",
-                                          session->namaddr,
-                                          translit(resp->str, "\n", " "),
-                                          xfer_request[LMTP_STATE_RCPT]);
-                       }
-                   }
-                   /* If trace-only, send RSET instead of DATA. */
-                   if (++recv_rcpt == request->rcpt_list.len)
-                       recv_state = DEL_REQ_TRACE_ONLY(request->flags) ?
-                           LMTP_STATE_ABORT : LMTP_STATE_DATA;
-                   break;
-
-                   /*
-                    * Process the DATA response. When the server rejects
-                    * DATA, set nrcpt to a negative value so that the
-                    * receiver can apply a course correction.
-                    */
-               case LMTP_STATE_DATA:
-                   if (resp->code / 100 != 3) {
-                       if (nrcpt > 0)
-                           lmtp_mesg_fail(state, session->host, resp,
-                                       "host %s said: %s (in reply to %s)",
-                                          session->namaddr,
-                                          translit(resp->str, "\n", " "),
-                                          xfer_request[LMTP_STATE_DATA]);
-                       nrcpt = -1;
-                   }
-                   recv_state = LMTP_STATE_DOT;
-                   break;
-
-                   /*
-                    * Process the end of message response. Ignore the
-                    * response when no recipient was accepted: all
-                    * recipients are dead already, and the next receiver
-                    * state is LMTP_STATE_LAST regardless. Otherwise, if the
-                    * message transfer fails, bounce all remaining
-                    * recipients, else cross off the recipients that were
-                    * delivered.
-                    */
-               case LMTP_STATE_DOT:
-                   GETTIMEOFDAY(&request->msg_stats.deliver_done);
-                   if (nrcpt > 0) {
-                       rcpt = request->rcpt_list.info + survivors[recv_dot];
-                       if (resp->code / 100 == 2) {
-                           if (rcpt->offset)
-                               lmtp_rcpt_done(state, resp, rcpt);
-                       } else {
-                           lmtp_rcpt_fail(state, session->host, resp, rcpt,
-                                       "host %s said: %s (in reply to %s)",
-                                          session->namaddr,
-                                          translit(resp->str, "\n", " "),
-                                          xfer_request[LMTP_STATE_DOT]);
-                       }
-                   }
-
-                   /*
-                    * We get one response per valid RCPT TO:
-                    */
-                   if (msg_verbose)
-                       msg_info("%s: recv_dot = %d", myname, recv_dot);
-                   if (++recv_dot >= nrcpt) {
-                       if (msg_verbose)
-                           msg_info("%s: finished . command", myname);
-                       recv_state = var_lmtp_skip_quit_resp || var_lmtp_cache_conn ?
-                           LMTP_STATE_LAST : LMTP_STATE_QUIT;
-                   }
-                   break;
-
-                   /*
-                    * Ignore the RSET response.
-                    */
-               case LMTP_STATE_ABORT:
-                   recv_state = var_lmtp_skip_quit_resp || var_lmtp_cache_conn ?
-                       LMTP_STATE_LAST : LMTP_STATE_QUIT;
-                   break;
-
-                   /*
-                    * Ignore the RSET response.
-                    */
-               case LMTP_STATE_RSET:
-                   if (resp->code / 100 != 2)
-                       CANT_RSET_THIS_SESSION;
-                   recv_state = LMTP_STATE_LAST;
-                   break;
-
-                   /*
-                    * Ignore the QUIT response.
-                    */
-               case LMTP_STATE_QUIT:
-                   recv_state = LMTP_STATE_LAST;
-                   break;
-               }
-           }
-
-           /*
-            * At this point, the sender and receiver are fully synchronized,
-            * so that the entire TCP send buffer becomes available again.
-            */
-           sndbuffree = state->sndbufsize;
-
-           /*
-            * We know the server response to every command that was sent.
-            * Apply a course correction if necessary: the sender wants to
-            * send RCPT TO but MAIL FROM was rejected; the sender wants to
-            * send DATA but all recipients were rejected; the sender wants
-            * to deliver the message but DATA was rejected.
-            */
-           if ((send_state == LMTP_STATE_RCPT && mail_from_rejected)
-               || (send_state == LMTP_STATE_DATA && nrcpt == 0)
-               || (send_state == LMTP_STATE_DOT && nrcpt < 0)) {
-               send_state = recv_state = LMTP_STATE_ABORT;
-               send_rcpt = recv_rcpt = 0;
-               vstring_strcpy(next_command, "RSET");
-               next_state = var_lmtp_cache_conn ?
-                   LMTP_STATE_LAST : LMTP_STATE_QUIT;
-               next_rcpt = 0;
-           }
-       }
-
-       /*
-        * Make the next sender state the current sender state.
-        */
-       if (send_state == LMTP_STATE_LAST)
-           continue;
-
-       /*
-        * Special case if the server accepted the DATA command. If the
-        * server accepted at least one recipient send the entire message.
-        * Otherwise, just send "." as per RFC 2197.
-        */
-       if (send_state == LMTP_STATE_DOT && nrcpt > 0) {
-           smtp_timeout_setup(state->session->stream,
-                              var_lmtp_data1_tmout);
-           if ((except = vstream_setjmp(state->session->stream)) != 0)
-               RETURN(lmtp_stream_except(state, except,
-                                         "sending message body"));
-
-           if (vstream_fseek(state->src, request->data_offset, SEEK_SET) < 0)
-               msg_fatal("seek queue file: %m");
-
-           while ((rec_type = rec_get(state->src, state->scratch, 0)) > 0) {
-               if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
-                   break;
-               if (prev_type != REC_TYPE_CONT)
-                   if (vstring_str(state->scratch)[0] == '.')
-                       smtp_fputc('.', session->stream);
-               if (rec_type == REC_TYPE_CONT)
-                   smtp_fwrite(vstring_str(state->scratch),
-                               VSTRING_LEN(state->scratch),
-                               session->stream);
-               else
-                   smtp_fputs(vstring_str(state->scratch),
-                              VSTRING_LEN(state->scratch),
-                              session->stream);
-               prev_type = rec_type;
-           }
-
-           if (prev_type == REC_TYPE_CONT)     /* missing newline at end */
-               smtp_fputs("", 0, session->stream);
-           if (vstream_ferror(state->src))
-               msg_fatal("queue file read error");
-           if (rec_type != REC_TYPE_XTRA) {
-               msg_warn("%s: bad record type: %d in message content",
-                        request->queue_id, rec_type);
-               RETURN(mark_corrupt(state->src));
-           }
-       }
-
-       /*
-        * Copy the next command to the buffer and update the sender state.
-        */
-       if (sndbuffree > 0)
-           sndbuffree -= VSTRING_LEN(next_command) + 2;
-       lmtp_chat_cmd(state, "%s", vstring_str(next_command));
-       send_state = next_state;
-       send_rcpt = next_rcpt;
-    }
-
-    RETURN(0);
-}
-
-/* lmtp_xfer - send a batch of envelope information and the message data */
-
-int     lmtp_xfer(LMTP_STATE *state)
-{
-    DELIVER_REQUEST *request = state->request;
-    int     start;
-    int     send_name_addr;
-
-    /*
-     * Use the XFORWARD command to forward client attributes only when a
-     * minimal amount of information is available.
-     */
-    send_name_addr =
-       var_lmtp_send_xforward
-       && (((state->features & LMTP_FEATURE_XFORWARD_NAME)
-            && DEL_REQ_ATTR_AVAIL(request->client_name))
-           || ((state->features & LMTP_FEATURE_XFORWARD_ADDR)
-               && DEL_REQ_ATTR_AVAIL(request->client_addr)));
-    lmtp_send_proto_helo =
-       var_lmtp_send_xforward
-       && (((state->features & LMTP_FEATURE_XFORWARD_PROTO)
-            && DEL_REQ_ATTR_AVAIL(request->client_proto))
-           || ((state->features & LMTP_FEATURE_XFORWARD_HELO)
-               && DEL_REQ_ATTR_AVAIL(request->client_helo)));
-    if (send_name_addr)
-       start = LMTP_STATE_XFORWARD_NAME_ADDR;
-    else if (lmtp_send_proto_helo)
-       start = LMTP_STATE_XFORWARD_PROTO_HELO;
-    else
-       start = LMTP_STATE_MAIL;
-    return (lmtp_loop(state, start, start));
-}
-
-/* lmtp_rset - send a lone RSET command and wait for response */
-
-int     lmtp_rset(LMTP_STATE *state)
-{
-    return (lmtp_loop(state, LMTP_STATE_RSET, LMTP_STATE_RSET));
-}
-
-/* lmtp_quit - send a lone QUIT command */
-
-int     lmtp_quit(LMTP_STATE *state)
-{
-    return (lmtp_loop(state, LMTP_STATE_QUIT, var_lmtp_skip_quit_resp ?
-                     LMTP_STATE_LAST : LMTP_STATE_QUIT));
-}
diff --git a/postfix/src/lmtp/lmtp_rcpt.c b/postfix/src/lmtp/lmtp_rcpt.c
deleted file mode 100644 (file)
index 8d2b3e0..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_rcpt 3
-/* SUMMARY
-/*     application-specific recipient list operations
-/* SYNOPSIS
-/*     #include <lmtp.h>
-/*
-/*     void    lmtp_rcpt_done(state, reply, rcpt)
-/*     LMTP_STATE *state;
-/*     LMTP_RESP *reply;
-/*     RECIPIENT *rcpt;
-/* DESCRIPTION
-/*     lmtp_rcpt_done() logs that a recipient is completed and upon
-/*     success it marks the recipient as done in the queue file.
-/* DIAGNOSTICS
-/*     Panic: interface violation.
-/*
-/*     When a recipient can't be logged as completed, the recipient is
-/*     logged as deferred instead.
-/* BUGS
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*--*/
-
-/* System  library. */
-
-#include <sys_defs.h>
-#include <stdlib.h>                    /* lmtp_rcpt_cleanup  */
-#include <string.h>
-
-/* Utility  library. */
-
-#include <msg.h>
-
-/* Global library. */
-
-#include <deliver_request.h>
-#include <deliver_completed.h>
-#include <sent.h>
-#include <dsn_mask.h>
-
-/* Application-specific. */
-
-#include <lmtp.h>
-
-/* lmtp_rcpt_done - mark recipient as done or else */
-
-void    lmtp_rcpt_done(LMTP_STATE *state, LMTP_RESP *resp, RECIPIENT *rcpt)
-{
-    DELIVER_REQUEST *request = state->request;
-    LMTP_SESSION *session = state->session;
-    DSN     dsn;
-    int     status;
-
-    /*
-     * Report success and delete the recipient from the delivery request.
-     * Don't send a DSN "SUCCESS" notification if the receiving site
-     * announced DSN support (however unlikely that may be).
-     */
-    if (state->features & LMTP_FEATURE_DSN)
-       rcpt->dsn_notify &= ~DSN_NOTIFY_SUCCESS;
-
-    (void) LMTP_DSN_ASSIGN(&dsn, session->host, resp->dsn,
-                          resp->str, resp->str);
-
-    status = sent(DEL_REQ_TRACE_FLAGS(request->flags),
-                 request->queue_id, &request->msg_stats, rcpt,
-                 session->namaddr, &dsn);
-    if (status == 0) {
-       if (request->flags & DEL_REQ_FLAG_SUCCESS)
-           deliver_completed(state->src, rcpt->offset);
-       rcpt->offset = 0;                       /* in case deferred */
-    }
-    state->status |= status;
-}
diff --git a/postfix/src/lmtp/lmtp_sasl.h b/postfix/src/lmtp/lmtp_sasl.h
deleted file mode 100644 (file)
index 4d05b1d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_sasl 3h
-/* SUMMARY
-/*     Postfix SASL interface for LMTP client
-/* SYNOPSIS
-/*     #include "lmtp_sasl.h"
-/* DESCRIPTION
-/* .nf
-
- /*
- * SASL protocol functions
- */
-extern void lmtp_sasl_initialize(void);
-extern void lmtp_sasl_connect(LMTP_STATE *);
-extern int lmtp_sasl_passwd_lookup(LMTP_STATE *);
-extern void lmtp_sasl_start(LMTP_STATE *, const char *, const char *);
-extern int lmtp_sasl_authenticate(LMTP_STATE *, DSN_BUF *);
-extern void lmtp_sasl_cleanup(LMTP_STATE *);
-
-extern void lmtp_sasl_helo_auth(LMTP_STATE *, const char *);
-extern int lmtp_sasl_helo_login(LMTP_STATE *);
-
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Initial implementation by:
-/*     Till Franke
-/*     SuSE Rhein/Main AG
-/*     65760 Eschborn, Germany
-/*
-/*     Adopted by:
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
diff --git a/postfix/src/lmtp/lmtp_sasl_glue.c b/postfix/src/lmtp/lmtp_sasl_glue.c
deleted file mode 100644 (file)
index 3c0a6f8..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_sasl 3
-/* SUMMARY
-/*     Postfix SASL interface for LMTP client
-/* SYNOPSIS
-/*     #include lmtp_sasl.h
-/*
-/*     void    lmtp_sasl_initialize()
-/*
-/*     void    lmtp_sasl_connect(state)
-/*     LMTP_STATE *state;
-/*
-/*     void    lmtp_sasl_start(state, sasl_opts_name, sasl_opts_val)
-/*     LMTP_STATE *state;
-/*
-/*     int     lmtp_sasl_passwd_lookup(state)
-/*     LMTP_STATE *state;
-/*
-/*     int     lmtp_sasl_authenticate(state, why)
-/*     LMTP_STATE *state;
-/*     VSTRING *why;
-/*
-/*     void    lmtp_sasl_cleanup(state)
-/*     LMTP_STATE *state;
-/* DESCRIPTION
-/*     lmtp_sasl_initialize() initializes the SASL library. This
-/*     routine must be called once at process startup, before any
-/*     chroot operations.
-/*
-/*     lmtp_sasl_connect() performs per-session initialization. This
-/*     routine must be called once at the start of each connection.
-/*
-/*     lmtp_sasl_start() performs per-session initialization. This
-/*     routine must be called once per session before doing any SASL
-/*     authentication. The sasl_opts_name and sasl_opts_val parameters are
-/*     the postfix configuration parameters setting the security
-/*     policy of the SASL authentication.
-/*
-/*     lmtp_sasl_passwd_lookup() looks up the username/password
-/*     for the current LMTP server. The result is zero in case
-/*     of failure.
-/*
-/*     lmtp_sasl_authenticate() implements the SASL authentication
-/*     dialog. The result is < 0 in case of protocol failure, zero in
-/*     case of unsuccessful authentication, > 0 in case of success.
-/*     The why argument is updated with a reason for failure.
-/*     This routine must be called only when lmtp_sasl_passwd_lookup()
-/*     suceeds.
-/*
-/*     lmtp_sasl_cleanup() cleans up. It must be called at the
-/*     end of every LMTP session that uses SASL authentication.
-/*     This routine is a noop for non-SASL sessions.
-/*
-/*     Arguments:
-/* .IP state
-/*     Session context.
-/* .IP mech_list
-/*     String of SASL mechanisms (separated by blanks)
-/* DIAGNOSTICS
-/*     All errors are fatal.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Original author:
-/*     Till Franke
-/*     SuSE Rhein/Main AG
-/*     65760 Eschborn, Germany
-/*
-/*     Adopted by:
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
- /*
-  * System library.
-  */
-#include <sys_defs.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
- /*
-  * Utility library
-  */
-#include <msg.h>
-#include <mymalloc.h>
-#include <stringops.h>
-#include <split_at.h>
-#include <name_mask.h>
-
- /*
-  * Global library
-  */
-#include <mail_params.h>
-#include <string_list.h>
-#include <maps.h>
-
- /*
-  * Application-specific
-  */
-#include "lmtp.h"
-#include "lmtp_sasl.h"
-
-#ifdef USE_SASL_AUTH
-
- /*
-  * Authentication security options.
-  */
-static NAME_MASK lmtp_sasl_sec_mask[] = {
-    "noplaintext", SASL_SEC_NOPLAINTEXT,
-    "noactive", SASL_SEC_NOACTIVE,
-    "nodictionary", SASL_SEC_NODICTIONARY,
-    "noanonymous", SASL_SEC_NOANONYMOUS,
-#if SASL_VERSION_MAJOR >= 2
-    "mutual_auth", SASL_SEC_MUTUAL_AUTH,
-#endif
-    0,
-};
-
- /*
-  * Macros to handle API differences between SASLv1 and SASLv2. Specifics:
-  * 
-  * The SASL_LOG_* constants were renamed in SASLv2.
-  * 
-  * SASLv2's sasl_client_new takes two new parameters to specify local and
-  * remote IP addresses for auth mechs that use them.
-  * 
-  * SASLv2's sasl_client_start function no longer takes the secret parameter.
-  * 
-  * SASLv2's sasl_decode64 function takes an extra parameter for the length of
-  * the output buffer.
-  * 
-  * The other major change is that SASLv2 now takes more responsibility for
-  * deallocating memory that it allocates internally.  Thus, some of the
-  * function parameters are now 'const', to make sure we don't try to free
-  * them too.  This is dealt with in the code later on.
-  */
-
-#if SASL_VERSION_MAJOR < 2
-/* SASL version 1.x */
-#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
-       sasl_client_new(srv, fqdn, prompt, secflags, pconn)
-#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
-       sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outlen)
-#endif
-
-#if SASL_VERSION_MAJOR >= 2
-/* SASL version > 2.x */
-#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
-       sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
-#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
-       sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outmaxlen, outlen)
-#endif
-
- /*
-  * Per-host login/password information.
-  */
-static MAPS *lmtp_sasl_passwd_map;
-
-/* lmtp_sasl_log - logging call-back routine */
-
-static int lmtp_sasl_log(void *unused_context, int priority,
-                                const char *message)
-{
-    switch (priority) {
-       case SASL_LOG_ERR:              /* unusual errors */
-#ifdef SASL_LOG_WARN                   /* non-fatal warnings (Cyrus-SASL v2) */
-       case SASL_LOG_WARN:
-#endif
-#ifdef SASL_LOG_WARNING                        /* non-fatal warnings (Cyrus-SASL v1) */
-       case SASL_LOG_WARNING:
-#endif
-       msg_warn("SASL authentication problem: %s", message);
-       break;
-#ifdef SASL_LOG_INFO
-    case SASL_LOG_INFO:                        /* other info (Cyrus-SASL v1) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_NOTE
-    case SASL_LOG_NOTE:                        /* other info (Cyrus-SASL v2) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_FAIL
-    case SASL_LOG_FAIL:                        /* authentication failures
-                                                * (Cyrus-SASL v2) */
-       msg_warn("SASL authentication failure: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_DEBUG
-    case SASL_LOG_DEBUG:                       /* more verbose than LOG_NOTE
-                                                * (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication debug: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_TRACE
-    case SASL_LOG_TRACE:                       /* traces of internal
-                                                * protocols (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication trace: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_PASS
-    case SASL_LOG_PASS:                        /* traces of internal
-                                                * protocols, including
-                                                * passwords (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication pass: %s", message);
-       break;
-#endif
-    }
-    return (SASL_OK);
-}
-
-/* lmtp_sasl_get_user - username lookup call-back routine */
-
-static int lmtp_sasl_get_user(void *context, int unused_id, const char **result,
-                                     unsigned *len)
-{
-    char   *myname = "lmtp_sasl_get_user";
-    LMTP_STATE *state = (LMTP_STATE *) context;
-
-    if (msg_verbose)
-       msg_info("%s: %s", myname, state->sasl_username);
-
-    /*
-     * Sanity check.
-     */
-    if (state->sasl_passwd == 0)
-       msg_panic("%s: no username looked up", myname);
-
-    *result = state->sasl_username;
-    if (len)
-       *len = strlen(state->sasl_username);
-    return (SASL_OK);
-}
-
-/* lmtp_sasl_get_passwd - password lookup call-back routine */
-
-static int lmtp_sasl_get_passwd(sasl_conn_t *conn, void *context,
-                                       int id, sasl_secret_t **psecret)
-{
-    char   *myname = "lmtp_sasl_get_passwd";
-    LMTP_STATE *state = (LMTP_STATE *) context;
-    int     len;
-
-    if (msg_verbose)
-       msg_info("%s: %s", myname, state->sasl_passwd);
-
-    /*
-     * Sanity check.
-     */
-    if (!conn || !psecret || id != SASL_CB_PASS)
-       return (SASL_BADPARAM);
-    if (state->sasl_passwd == 0)
-       msg_panic("%s: no password looked up", myname);
-
-    /*
-     * Convert the password into a counted string.
-     */
-    len = strlen(state->sasl_passwd);
-    if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0)
-       return (SASL_NOMEM);
-    (*psecret)->len = len;
-    memcpy((*psecret)->data, state->sasl_passwd, len + 1);
-
-    return (SASL_OK);
-}
-
-/* lmtp_sasl_passwd_lookup - password lookup routine */
-
-int     lmtp_sasl_passwd_lookup(LMTP_STATE *state)
-{
-    char   *myname = "lmtp_sasl_passwd_lookup";
-    const char *value;
-    char   *passwd;
-
-    /*
-     * Sanity check.
-     */
-    if (lmtp_sasl_passwd_map == 0)
-       msg_panic("%s: passwd map not initialized", myname);
-
-    /*
-     * Look up the per-server password information. Try the hostname first,
-     * then try the destination.
-     */
-    if ((value = maps_find(lmtp_sasl_passwd_map, state->session->host, 0)) != 0
-       || (value = maps_find(lmtp_sasl_passwd_map, state->request->nexthop, 0)) != 0) {
-       state->sasl_username = mystrdup(value);
-       passwd = split_at(state->sasl_username, ':');
-       state->sasl_passwd = mystrdup(passwd ? passwd : "");
-       if (msg_verbose)
-           msg_info("%s: host `%s' user `%s' pass `%s'",
-                    myname, state->session->host,
-                    state->sasl_username, state->sasl_passwd);
-       return (1);
-    } else {
-       if (msg_verbose)
-           msg_info("%s: host `%s' no auth info found",
-                    myname, state->session->host);
-       return (0);
-    }
-}
-
-/* lmtp_sasl_initialize - per-process initialization (pre jail) */
-
-void    lmtp_sasl_initialize(void)
-{
-
-    /*
-     * Global callbacks. These have no per-session context.
-     */
-    static sasl_callback_t callbacks[] = {
-       {SASL_CB_LOG, &lmtp_sasl_log, 0},
-       {SASL_CB_LIST_END, 0, 0}
-    };
-
-#if SASL_VERSION_MAJOR >= 2 && (SASL_VERSION_MINOR >= 2 \
-    || (SASL_VERSION_MINOR == 1 && SASL_VERSION_STEP >= 19))
-    int     sasl_major;
-    int     sasl_minor;
-    int     sasl_step;
-
-    /*
-     * DLL hell guard.
-     */
-    sasl_version_info((const char **) 0, (const char **) 0,
-                     &sasl_major, &sasl_minor,
-                     &sasl_step, (int *) 0);
-    if (sasl_major != SASL_VERSION_MAJOR
-#if 0
-       || sasl_minor != SASL_VERSION_MINOR
-       || sasl_step != SASL_VERSION_STEP
-#endif
-       )
-       msg_fatal("incorrect SASL library version. "
-             "Postfix was built with include files from version %d.%d.%d, "
-                 "but the run-time library version is %d.%d.%d",
-                 SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
-                 sasl_major, sasl_minor, sasl_step);
-#endif
-
-    /*
-     * Sanity check.
-     */
-    if (lmtp_sasl_passwd_map)
-       msg_panic("lmtp_sasl_initialize: repeated call");
-    if (*var_lmtp_sasl_passwd == 0)
-       msg_fatal("specify a password table via the `%s' configuration parameter",
-                 VAR_LMTP_SASL_PASSWD);
-
-    /*
-     * Open the per-host password table and initialize the SASL library. Use
-     * shared locks for reading, just in case someone updates the table.
-     */
-    lmtp_sasl_passwd_map = maps_create("lmtp_sasl_passwd",
-                                      var_lmtp_sasl_passwd, DICT_FLAG_LOCK);
-    if (sasl_client_init(callbacks) != SASL_OK)
-       msg_fatal("SASL library initialization");
-
-}
-
-/* lmtp_sasl_connect - per-session client initialization */
-
-void    lmtp_sasl_connect(LMTP_STATE *state)
-{
-    state->sasl_mechanism_list = 0;
-    state->sasl_username = 0;
-    state->sasl_passwd = 0;
-    state->sasl_conn = 0;
-    state->sasl_encoded = 0;
-    state->sasl_decoded = 0;
-    state->sasl_callbacks = 0;
-}
-
-/* lmtp_sasl_start - per-session SASL initialization */
-
-void    lmtp_sasl_start(LMTP_STATE *state, const char *sasl_opts_name,
-                               const char *sasl_opts_val)
-{
-    static sasl_callback_t callbacks[] = {
-       {SASL_CB_USER, &lmtp_sasl_get_user, 0},
-       {SASL_CB_AUTHNAME, &lmtp_sasl_get_user, 0},
-       {SASL_CB_PASS, &lmtp_sasl_get_passwd, 0},
-       {SASL_CB_LIST_END, 0, 0}
-    };
-    sasl_callback_t *cp;
-    sasl_security_properties_t sec_props;
-
-    if (msg_verbose)
-       msg_info("starting new SASL client");
-
-    /*
-     * Per-session initialization. Provide each session with its own callback
-     * context.
-     */
-#define NULL_SECFLAGS          0
-
-    state->sasl_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks));
-    memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
-    for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
-       cp->context = (void *) state;
-
-#define NULL_SERVER_ADDR       ((char *) 0)
-#define NULL_CLIENT_ADDR       ((char *) 0)
-
-    if (SASL_CLIENT_NEW("lmtp", state->session->host,
-                       NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
-                       state->sasl_callbacks, NULL_SECFLAGS,
-                       (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
-       msg_fatal("per-session SASL client initialization");
-
-    /*
-     * Per-session security properties. XXX This routine is not sufficiently
-     * documented. What is the purpose of all this?
-     */
-    memset(&sec_props, 0L, sizeof(sec_props));
-    sec_props.min_ssf = 0;
-    sec_props.max_ssf = 0;                     /* don't allow real SASL
-                                                * security layer */
-    sec_props.security_flags = name_mask(sasl_opts_name, lmtp_sasl_sec_mask,
-                                        sasl_opts_val);
-    sec_props.maxbufsize = 0;
-    sec_props.property_names = 0;
-    sec_props.property_values = 0;
-    if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS,
-                    &sec_props) != SASL_OK)
-       msg_fatal("set per-session SASL security properties");
-
-    /*
-     * We use long-lived conversion buffers rather than local variables in
-     * order to avoid memory leaks in case of read/write timeout or I/O
-     * error.
-     */
-    state->sasl_encoded = vstring_alloc(10);
-    state->sasl_decoded = vstring_alloc(10);
-}
-
-/* lmtp_sasl_authenticate - run authentication protocol */
-
-int     lmtp_sasl_authenticate(LMTP_STATE *state, DSN_BUF *why)
-{
-    char   *myname = "lmtp_sasl_authenticate";
-    LMTP_SESSION *session = state->session;
-    unsigned enc_length;
-    unsigned enc_length_out;
-
-#if SASL_VERSION_MAJOR >= 2
-    const char *clientout;
-
-#else
-    char   *clientout;
-
-#endif
-    unsigned clientoutlen;
-    unsigned serverinlen;
-    LMTP_RESP *resp;
-    const char *mechanism;
-    int     result;
-    char   *line;
-
-#define NO_SASL_SECRET         0
-#define NO_SASL_INTERACTION    0
-#define NO_SASL_LANGLIST       ((const char *) 0)
-#define NO_SASL_OUTLANG                ((const char **) 0)
-
-    if (msg_verbose)
-       msg_info("%s: %s: SASL mechanisms %s",
-                myname, session->namaddr, state->sasl_mechanism_list);
-
-    /*
-     * Start the client side authentication protocol.
-     */
-    result = SASL_CLIENT_START((sasl_conn_t *) state->sasl_conn,
-                              state->sasl_mechanism_list,
-                              NO_SASL_SECRET, NO_SASL_INTERACTION,
-                              &clientout, &clientoutlen, &mechanism);
-    if (result != SASL_OK && result != SASL_CONTINUE) {
-       dsb_update(why, "4.7.0", DSB_DEF_ACTION, DSB_SKIP_RMTA, DSB_DTYPE_SASL,
-                  421, sasl_errstring(result, NO_SASL_LANGLIST,
-                                      NO_SASL_OUTLANG),
-                  "cannot SASL authenticate to server %s: %s",
-                  session->namaddr,
-                  sasl_errstring(result, NO_SASL_LANGLIST,
-                                 NO_SASL_OUTLANG));
-       return (-1);
-    }
-
-    /*
-     * Send the AUTH command and the optional initial client response.
-     * sasl_encode64() produces four bytes for each complete or incomplete
-     * triple of input bytes. Allocate an extra byte for string termination.
-     */
-#define ENCODE64_LENGTH(n)     ((((n) + 2) / 3) * 4)
-
-    if (clientoutlen > 0) {
-       if (msg_verbose)
-           msg_info("%s: %s: uncoded initial reply: %.*s",
-                    myname, session->namaddr,
-                    (int) clientoutlen, clientout);
-       enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
-       VSTRING_SPACE(state->sasl_encoded, enc_length);
-       if (sasl_encode64(clientout, clientoutlen,
-                         STR(state->sasl_encoded), enc_length,
-                         &enc_length_out) != SASL_OK)
-           msg_panic("%s: sasl_encode64 botch", myname);
-#if SASL_VERSION_MAJOR < 2
-       /* SASL version 1 doesn't free memory that it allocates. */
-       free(clientout);
-#endif
-       lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
-    } else {
-       lmtp_chat_cmd(state, "AUTH %s", mechanism);
-    }
-
-    /*
-     * Step through the authentication protocol until the server tells us
-     * that we are done.
-     */
-    while ((resp = lmtp_chat_resp(state))->code / 100 == 3) {
-
-       /*
-        * Process a server challenge.
-        */
-       line = resp->str;
-       (void) mystrtok(&line, "- \t\n");       /* skip over result code */
-       serverinlen = strlen(line);
-       VSTRING_SPACE(state->sasl_decoded, serverinlen);
-       if (SASL_DECODE64(line, serverinlen, STR(state->sasl_decoded),
-                         serverinlen, &enc_length) != SASL_OK) {
-           lmtp_dsn_update(why, "5.7.0", DSN_BY_LOCAL_MTA,
-                           501, "501 malformed SASL challenge",
-                           "malformed SASL challenge from server %s",
-                           session->namaddr);
-           return (-1);
-       }
-       if (msg_verbose)
-           msg_info("%s: %s: decoded challenge: %.*s",
-                    myname, session->namaddr,
-                    (int) enc_length, STR(state->sasl_decoded));
-       result = sasl_client_step((sasl_conn_t *) state->sasl_conn,
-                                 STR(state->sasl_decoded), enc_length,
-                           NO_SASL_INTERACTION, &clientout, &clientoutlen);
-       if (result != SASL_OK && result != SASL_CONTINUE)
-           msg_warn("SASL authentication failed to server %s: %s",
-                    session->namaddr,
-                    sasl_errstring(result, NO_SASL_LANGLIST,
-                                   NO_SASL_OUTLANG));
-
-       /*
-        * Send a client response.
-        */
-       if (clientoutlen > 0) {
-           if (msg_verbose)
-               msg_info("%s: %s: uncoded client response %.*s",
-                        myname, session->namaddr,
-                        (int) clientoutlen, clientout);
-           enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
-           VSTRING_SPACE(state->sasl_encoded, enc_length);
-           if (sasl_encode64(clientout, clientoutlen,
-                             STR(state->sasl_encoded), enc_length,
-                             &enc_length_out) != SASL_OK)
-               msg_panic("%s: sasl_encode64 botch", myname);
-#if SASL_VERSION_MAJOR < 2
-           /* SASL version 1 doesn't free memory that it allocates. */
-           free(clientout);
-#endif
-       } else {
-           vstring_strcat(state->sasl_encoded, "");
-       }
-       lmtp_chat_cmd(state, "%s", STR(state->sasl_encoded));
-    }
-
-    /*
-     * We completed the authentication protocol.
-     */
-    if (resp->code / 100 != 2) {
-       lmtp_dsn_update(why, session->host, resp->dsn, resp->code, resp->str,
-                       "SASL authentication failed; server %s said: %s",
-                       session->namaddr, resp->str);
-       return (0);
-    }
-    return (1);
-}
-
-/* lmtp_sasl_cleanup - per-session cleanup */
-
-void    lmtp_sasl_cleanup(LMTP_STATE *state)
-{
-    if (state->sasl_username) {
-       myfree(state->sasl_username);
-       state->sasl_username = 0;
-    }
-    if (state->sasl_passwd) {
-       myfree(state->sasl_passwd);
-       state->sasl_passwd = 0;
-    }
-    if (state->sasl_mechanism_list) {
-       /* allocated in lmtp_sasl_helo_auth */
-       myfree(state->sasl_mechanism_list);
-       state->sasl_mechanism_list = 0;
-    }
-    if (state->sasl_conn) {
-       if (msg_verbose)
-           msg_info("disposing SASL state information");
-       sasl_dispose(&state->sasl_conn);
-    }
-    if (state->sasl_callbacks) {
-       myfree((char *) state->sasl_callbacks);
-       state->sasl_callbacks = 0;
-    }
-    if (state->sasl_encoded) {
-       vstring_free(state->sasl_encoded);
-       state->sasl_encoded = 0;
-    }
-    if (state->sasl_decoded) {
-       vstring_free(state->sasl_decoded);
-       state->sasl_decoded = 0;
-    }
-}
-
-#endif
diff --git a/postfix/src/lmtp/lmtp_sasl_proto.c b/postfix/src/lmtp/lmtp_sasl_proto.c
deleted file mode 100644 (file)
index 143711f..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_sasl_proto 3
-/* SUMMARY
-/*     Postfix SASL interface for LMTP client
-/* SYNOPSIS
-/*     #include lmtp_sasl.h
-/*
-/*     void    lmtp_sasl_helo_auth(state, words)
-/*     LMTP_STATE *state;
-/*     const char *words;
-/*
-/*     int     lmtp_sasl_helo_login(state)
-/*     LMTP_STATE *state;
-/* DESCRIPTION
-/*     This module contains random chunks of code that implement
-/*     the LMTP protocol interface for SASL negotiation. The goal
-/*     is to reduce clutter in the main LMTP client source code.
-/*
-/*     lmtp_sasl_helo_auth() processes the AUTH option in the
-/*     LMTP server's LHLO response.
-/*
-/*     lmtp_sasl_helo_login() authenticates the LMTP client to the
-/*     LMTP server, using the authentication mechanism information
-/*     given by the server. The result is a Postfix delivery status
-/*     code in case of trouble.
-/*
-/*     Arguments:
-/* .IP state
-/*     Session context.
-/* .IP words
-/*     List of SASL authentication mechanisms (separated by blanks)
-/* DIAGNOSTICS
-/*     All errors are fatal.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Original author:
-/*     Till Franke
-/*     SuSE Rhein/Main AG
-/*     65760 Eschborn, Germany
-/*
-/*     Adopted by:
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <string.h>
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_sasl.h"
-
-#ifdef USE_SASL_AUTH
-
-/* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */
-
-void    lmtp_sasl_helo_auth(LMTP_STATE *state, const char *words)
-{
-
-    /*
-     * XXX If the server offers a null list of authentication mechanisms,
-     * then pretend that the server doesn't support SASL authentication.
-     */
-    if (state->sasl_mechanism_list) {
-       if (strcasecmp(state->sasl_mechanism_list, words) == 0)
-           return;
-       myfree(state->sasl_mechanism_list);
-       msg_warn("%s offered AUTH option multiple times",
-                state->session->namaddr);
-       state->sasl_mechanism_list = 0;
-       state->features &= ~LMTP_FEATURE_AUTH;
-    }
-    if (strlen(words) > 0) {
-       state->sasl_mechanism_list = mystrdup(words);
-       state->features |= LMTP_FEATURE_AUTH;
-    } else {
-       msg_warn("%s offered null AUTH mechanism list",
-                state->session->namaddr);
-    }
-}
-
-/* lmtp_sasl_helo_login - perform SASL login */
-
-int     lmtp_sasl_helo_login(LMTP_STATE *state)
-{
-    DSN_BUF *why = dsb_create();
-    int     ret = 0;
-
-    /*
-     * Skip authentication when no authentication info exists for this
-     * server, so that we talk to each other like strangers. Otherwise, if
-     * authentication information exists, assume that authentication is
-     * required, and assume that an authentication error is recoverable.
-     */
-    if (lmtp_sasl_passwd_lookup(state) != 0) {
-       lmtp_sasl_start(state, VAR_LMTP_SASL_OPTS, var_lmtp_sasl_opts);
-       if (lmtp_sasl_authenticate(state, why) <= 0) {
-           vstring_prepend(why->reason, "Authentication failed: ",
-                           sizeof("Authentication failed: ") - 1);
-           ret = lmtp_sess_fail(state, why);
-       }
-    }
-    dsb_free(why);
-    return (ret);
-}
-
-#endif
diff --git a/postfix/src/lmtp/lmtp_session.c b/postfix/src/lmtp/lmtp_session.c
deleted file mode 100644 (file)
index 411ee81..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_session 3
-/* SUMMARY
-/*     LMTP_SESSION structure management
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     LMTP_SESSION *lmtp_session_alloc(stream, host, addr, dest, type)
-/*     VSTREAM *stream;
-/*     const char *host;
-/*     const char *addr;
-/*     const char *dest;
-/*     int     type;
-/*
-/*     LMTP_SESSION *lmtp_session_free(session)
-/*     LMTP_SESSION *session;
-/* 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 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. 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.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <mymalloc.h>
-#include <vstream.h>
-#include <stringops.h>
-
-/* Global library. */
-
-#include <debug_peer.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-
-/* lmtp_session_alloc - allocate and initialize LMTP_SESSION structure */
-
-LMTP_SESSION *lmtp_session_alloc(VSTREAM *stream, const char *host,
-                                        const char *addr, const char *dest)
-{
-    LMTP_SESSION *session;
-
-    session = (LMTP_SESSION *) mymalloc(sizeof(*session));
-    session->stream = stream;
-    session->host = mystrdup(host);
-    session->addr = mystrdup(addr);
-    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 */
-
-LMTP_SESSION *lmtp_session_free(LMTP_SESSION *session)
-{
-    debug_peer_restore();
-    vstream_fclose(session->stream);
-    myfree(session->host);
-    myfree(session->addr);
-    myfree(session->namaddr);
-    myfree(session->dest);
-    myfree((char *) session);
-    return (0);
-}
diff --git a/postfix/src/lmtp/lmtp_state.c b/postfix/src/lmtp/lmtp_state.c
deleted file mode 100644 (file)
index d514a87..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_state 8
-/* SUMMARY
-/*     initialize/cleanup shared state
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     LMTP_STATE *lmtp_state_alloc()
-/*
-/*     void    lmtp_state_free(state)
-/*     LMTP_STATE *state;
-/* DESCRIPTION
-/*     lmtp_state_init() initializes the shared state, and allocates
-/*     memory for buffers etc.
-/*
-/*     lmtp_cleanup() destroys memory allocated by lmtp_state_init().
-/* STANDARDS
-/* DIAGNOSTICS
-/* BUGS
-/* SEE ALSO
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <mymalloc.h>
-#include <vstring.h>
-#include <vstream.h>
-
-/* Global library. */
-
-#include <mail_conf.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-#include "lmtp_sasl.h"
-
-/* lmtp_state_alloc - initialize */
-
-LMTP_STATE *lmtp_state_alloc(void)
-{
-    LMTP_STATE *state = (LMTP_STATE *) mymalloc(sizeof(*state));
-
-    state->src = 0;
-    state->request = 0;
-    state->session = 0;
-    state->buffer = vstring_alloc(100);
-    state->scratch = vstring_alloc(100);
-    state->scratch2 = vstring_alloc(100);
-    state->status = 0;
-    state->features = 0;
-    state->history = 0;
-    state->error_mask = 0;
-#ifdef USE_SASL_AUTH
-    lmtp_sasl_connect(state);
-#endif
-    state->sndbufsize = 0;
-    state->reuse = 0;
-    state->dsn_reason = 0;
-
-    return (state);
-}
-
-/* lmtp_state_free - destroy state */
-
-void    lmtp_state_free(LMTP_STATE *state)
-{
-    vstring_free(state->buffer);
-    vstring_free(state->scratch);
-    vstring_free(state->scratch2);
-#ifdef USE_SASL_AUTH
-    lmtp_sasl_cleanup(state);
-#endif
-    if (state->dsn_reason)
-       vstring_free(state->dsn_reason);
-
-    myfree((char *) state);
-}
diff --git a/postfix/src/lmtp/lmtp_trouble.c b/postfix/src/lmtp/lmtp_trouble.c
deleted file mode 100644 (file)
index 5ef08f9..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/*++
-/* NAME
-/*     lmtp_trouble 3
-/* SUMMARY
-/*     error handler policies
-/* SYNOPSIS
-/*     #include "lmtp.h"
-/*
-/*     int     lmtp_sess_fail(state, why)
-/*     SMTP_STATE *state;
-/*     DSN_BUF *why;
-/*
-/*     int     lmtp_site_fail(state, mta_name, resp, format, ...)
-/*     LMTP_STATE *state;
-/*     const char *mta_name;
-/*     LMTP_RESP *resp;
-/*     const char *format;
-/*
-/*     int     lmtp_mesg_fail(state, mta_name, resp, format, ...)
-/*     LMTP_STATE *state;
-/*     const char *mta_name;
-/*     LMTP_RESP *resp;
-/*     const char *format;
-/*
-/*     void    lmtp_rcpt_fail(state, mta_name, resp, recipient, format, ...)
-/*     LMTP_STATE *state;
-/*     const char *mta_name;
-/*     LMTP_RESP *resp;
-/*     RECIPIENT *recipient;
-/*     const char *format;
-/*
-/*     int     lmtp_stream_except(state, exception, description)
-/*     LMTP_STATE *state;
-/*     int     exception;
-/*     const char *description;
-/* DESCRIPTION
-/*     This module handles all non-fatal errors that can happen while
-/*     attempting to deliver mail via LMTP, and implements the policy
-/*     of how to deal with the error. Depending on the nature of
-/*     the problem, delivery of a single message is deferred, delivery
-/*     of all messages to the same domain is deferred, or one or more
-/*     recipients are given up as non-deliverable and a bounce log is
-/*     updated.
-/*
-/*     In addition, when an unexpected response code is seen such
-/*     as 3xx where only 4xx or 5xx are expected, or any error code
-/*     that suggests a syntax error or something similar, the
-/*     protocol error flag is set so that the postmaster receives
-/*     a transcript of the session. No notification is generated for
-/*     what appear to be configuration errors - very likely, they
-/*     would suffer the same problem and just cause more trouble.
-/*
-/*     lmtp_sess_fail() takes a pre-formatted error report after
-/*     failure to complete some protocol handshake.  The policy is
-/*     as with lmtp_site_fail().
-/*
-/*     lmtp_site_fail() handles the case where the program fails to
-/*     complete some protocol handshake: the server is not reachable,
-/*     is not running, does not want talk to us, or we talk to ourselves.
-/*     The \fIcode\fR gives an error status code; the \fIformat\fR
-/*     argument gives a textual description.  The policy is: soft
-/*     error: defer delivery of all messages to this domain; hard
-/*     error: bounce all recipients of this message.
-/*     The result is non-zero.
-/*
-/*     lmtp_mesg_fail() handles the case where the lmtp server
-/*     does not accept the sender address or the message data.
-/*     The policy is: soft errors: defer delivery of this message;
-/*     hard error: bounce all recipients of this message.
-/*     The result is non-zero.
-/*
-/*     lmtp_rcpt_fail() handles the case where a recipient is not
-/*     accepted by the server for reasons other than that the server
-/*     recipient limit is reached. The policy is: soft error: defer
-/*     delivery to this recipient; hard error: bounce this recipient.
-/*
-/*     lmtp_stream_except() handles the exceptions generated by
-/*     the smtp_stream(3) module (i.e. timeouts and I/O errors).
-/*     The \fIexception\fR argument specifies the type of problem.
-/*     The \fIdescription\fR argument describes at what stage of
-/*     the LMTP dialog the problem happened. The policy is to defer
-/*     delivery of all messages to the same domain. The result is non-zero.
-/*
-/*     Arguments:
-/* .IP state
-/*     LMTP client state per delivery request.
-/* .IP resp
-/*     Server response including reply code and text.
-/* .IP recipient
-/*     Undeliverable recipient address information.
-/* .IP format
-/*     Human-readable description of why mail is not deliverable.
-/* DIAGNOSTICS
-/*     Panic: unknown exception code.
-/* SEE ALSO
-/*     lmtp_proto(3) lmtp high-level protocol
-/*     smtp_stream(3) lmtp low-level protocol
-/*     defer(3) basic message defer interface
-/*     bounce(3) basic message bounce interface
-/* LICENSE
-/* .ad
-/* .fi
-/*     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
-/*     Mirapoint, Inc.
-/*     USA.
-/*
-/*     Additional work on LMTP by:
-/*     Amos Gouaux
-/*     University of Texas at Dallas
-/*     P.O. Box 830688, MC34
-/*     Richardson, TX 75083, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <stdlib.h>                    /* 44BSD stdarg.h uses abort() */
-#include <stdarg.h>
-#include <string.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <stringops.h>
-
-/* Global library. */
-
-#include <smtp_stream.h>
-#include <deliver_request.h>
-#include <deliver_completed.h>
-#include <bounce.h>
-#include <defer.h>
-#include <mail_error.h>
-#include <dsn_buf.h>
-#include <dsn.h>
-
-/* Application-specific. */
-
-#include "lmtp.h"
-
-#define LMTP_THROTTLE  1
-#define LMTP_NOTHROTTLE        0
-
-/* lmtp_check_code - check response code */
-
-static void lmtp_check_code(LMTP_STATE *state, int code)
-{
-
-    /*
-     * The intention of this code is to alert the postmaster when the local
-     * Postfix LMTP client screws up, protocol wise. RFC 821 says that x0z
-     * replies "refer to syntax errors, syntactically correct commands that
-     * don't fit any functional category, and unimplemented or superfluous
-     * commands". Unfortunately, this also triggers postmaster notices when
-     * remote servers screw up, protocol wise. This is becoming a common
-     * problem now that response codes are configured manually as part of
-     * anti-UCE systems, by people who aren't aware of RFC details.
-     */
-    if (code < 400 || code > 599
-       || code == 555                  /* RFC 1869, section 6.1. */
-       || (code >= 500 && code < 510))
-       state->error_mask |= MAIL_ERROR_PROTOCOL;
-}
-
-/* lmtp_bulk_fail - skip, defer or bounce recipients, maybe throttle queue */
-
-static int lmtp_bulk_fail(LMTP_STATE *state, DSN *dsn, int throttle_queue)
-{
-    DELIVER_REQUEST *request = state->request;
-    LMTP_SESSION *session = state->session;
-    RECIPIENT *rcpt;
-    int     status;
-    int     soft_error = (dsn->dtext[0] == '4');
-    int     nrcpt;
-
-    /*
-     * If we are still in the connection set-up phase, update the set-up
-     * completion time here, otherwise the time spent in set-up latency will
-     * be attributed as message transfer latency.
-     * 
-     * All remaining recipients failed at this point, so we update the delivery
-     * completion time stamp so that multiple recipient status records show
-     * the same delay values.
-     */
-    if (request->msg_stats.conn_setup_done.tv_sec == 0) {
-       GETTIMEOFDAY(&request->msg_stats.conn_setup_done);
-       request->msg_stats.deliver_done =
-           request->msg_stats.conn_setup_done;
-    } else
-       GETTIMEOFDAY(&request->msg_stats.deliver_done);
-
-    /*
-     * If this is a soft error, postpone further deliveries to this domain.
-     * Otherwise, generate a bounce record for each recipient.
-     */
-    for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) {
-       rcpt = request->rcpt_list.info + nrcpt;
-       if (rcpt->offset == 0)
-           continue;
-       status = (soft_error ? defer_append : bounce_append)
-           (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
-            &request->msg_stats, rcpt,
-            session ? session->namaddr : "none", dsn);
-       if (status == 0) {
-           deliver_completed(state->src, rcpt->offset);
-           rcpt->offset = 0;
-       }
-       state->status |= status;
-    }
-    if (throttle_queue && soft_error && request->hop_status == 0)
-       request->hop_status = DSN_COPY(dsn);
-
-    return (-1);
-}
-
-/* lmtp_sess_fail - skip site, defer or bounce all recipients */
-
-int     lmtp_sess_fail(LMTP_STATE *state, DSN_BUF *why)
-{
-    DSN     dsn;
-
-    /*
-     * We need to incur the expense of copying lots of strings into VSTRING
-     * buffers when the error information is collected by a routine that
-     * terminates BEFORE the error is reported. If no copies were made, the
-     * information would not be frozen in time.
-     */
-    return (lmtp_bulk_fail(state, DSN_FROM_DSN_BUF(&dsn, why), LMTP_THROTTLE));
-}
-
-/* vlmtp_fill_dsn - fill in temporary DSN structure */
-
-static void vlmtp_fill_dsn(LMTP_STATE *state, DSN *dsn, const char *mta_name,
-                                  const char *status, const char *reply,
-                                  const char *format, va_list ap)
-{
-
-    /*
-     * We can avoid the cost of copying lots of strings into VSTRING buffers
-     * when the error information is collected by the routine that terminates
-     * AFTER the error is reported. In this case, the information is already
-     * frozen in time, so we don't need to make copies.
-     */
-    if (state->dsn_reason == 0)
-       state->dsn_reason = vstring_alloc(100);
-    else
-       VSTRING_RESET(state->dsn_reason);
-    if (mta_name && reply[0] != '4' && reply[0] != '5') {
-       vstring_strcpy(state->dsn_reason, "Protocol error: ");
-       mta_name = DSN_BY_LOCAL_MTA;
-       status = "5.5.0";
-       reply = "501 Protocol error in server reply";
-    }
-    vstring_vsprintf_append(state->dsn_reason, format, ap);
-    LMTP_DSN_ASSIGN(dsn, mta_name, status, reply, STR(state->dsn_reason));
-}
-
-/* lmtp_fill_dsn - fill in temporary DSN structure */
-
-static void lmtp_fill_dsn(LMTP_STATE *state, DSN *dsn, const char *mta_name,
-                                 const char *status, const char *reply,
-                                 const char *format,...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    vlmtp_fill_dsn(state, dsn, mta_name, status, reply, format, ap);
-    va_end(ap);
-}
-
-/* lmtp_site_fail - defer site or bounce recipients */
-
-int     lmtp_site_fail(LMTP_STATE *state, const char *mta_name, LMTP_RESP *resp,
-                              const char *format,...)
-{
-    DSN     dsn;
-    va_list ap;
-
-    /*
-     * Initialize.
-     */
-    va_start(ap, format);
-    vlmtp_fill_dsn(state, &dsn, mta_name, resp->dsn, resp->str, format, ap);
-    va_end(ap);
-
-    if (state->session && mta_name)
-       lmtp_check_code(state, resp->code);
-
-    /*
-     * Skip, defer or bounce recipients, and throttle this queue.
-     */
-    return (lmtp_bulk_fail(state, &dsn, LMTP_THROTTLE));
-}
-
-/* lmtp_mesg_fail - defer message or bounce all recipients */
-
-int     lmtp_mesg_fail(LMTP_STATE *state, const char *mta_name, LMTP_RESP *resp,
-                              const char *format,...)
-{
-    va_list ap;
-    DSN     dsn;
-
-    /*
-     * Initialize.
-     */
-    va_start(ap, format);
-    vlmtp_fill_dsn(state, &dsn, mta_name, resp->dsn, resp->str, format, ap);
-    va_end(ap);
-
-    if (state->session && mta_name)
-       lmtp_check_code(state, resp->code);
-
-    /*
-     * Skip, defer or bounce recipients, but don't throttle this queue.
-     */
-    return (lmtp_bulk_fail(state, &dsn, LMTP_NOTHROTTLE));
-}
-
-/* lmtp_rcpt_fail - defer or bounce recipient */
-
-void    lmtp_rcpt_fail(LMTP_STATE *state, const char *mta_name, LMTP_RESP *resp,
-                              RECIPIENT *rcpt, const char *format,...)
-{
-    DELIVER_REQUEST *request = state->request;
-    LMTP_SESSION *session = state->session;
-    int     soft_error;
-    int     status;
-    DSN     dsn;
-    va_list ap;
-
-    /*
-     * Initialize.
-     */
-    va_start(ap, format);
-    vlmtp_fill_dsn(state, &dsn, mta_name, resp->dsn, resp->str, format, ap);
-    va_end(ap);
-    soft_error = dsn.dtext[0] == '4';
-
-    if (state->session && mta_name)
-       lmtp_check_code(state, resp->code);
-
-    /*
-     * If this is a soft error, postpone delivery to this recipient.
-     * Otherwise, generate a bounce record for this recipient.
-     */
-    status = (soft_error ? defer_append : bounce_append)
-       (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
-        &request->msg_stats, rcpt,
-        session ? session->namaddr : "none", &dsn);
-    if (status == 0) {
-       deliver_completed(state->src, rcpt->offset);
-       rcpt->offset = 0;
-    }
-    state->status |= status;
-}
-
-/* lmtp_stream_except - defer domain after I/O problem */
-
-int     lmtp_stream_except(LMTP_STATE *state, int code, const char *description)
-{
-    LMTP_SESSION *session = state->session;
-    DSN     dsn;
-
-    /*
-     * Sanity check.
-     */
-    if (session == 0)
-       msg_panic("lmtp_stream_except: no session");
-
-    /*
-     * Initialize.
-     */
-    switch (code) {
-    default:
-       msg_panic("lmtp_stream_except: unknown exception %d", code);
-    case SMTP_ERR_EOF:
-       lmtp_fill_dsn(state, &dsn, DSN_BY_LOCAL_MTA,
-                     "4.4.2", "421 lost connection",
-                     "lost connection with %s while %s",
-                     session->namaddr, description);
-       break;
-    case SMTP_ERR_TIME:
-       lmtp_fill_dsn(state, &dsn, DSN_BY_LOCAL_MTA,
-                     "4.4.2", "426 conversation timed out",
-                     "conversation with %s timed out while %s",
-                     session->namaddr, description);
-       break;
-    case SMTP_ERR_PROTO:
-       lmtp_fill_dsn(state, &dsn, DSN_BY_LOCAL_MTA,
-                     "4.5.0", "403 remote protocol error",
-                     "remote protocol error in reply from %s while %s",
-                     session->namaddr, description);
-       break;
-    }
-    return (lmtp_bulk_fail(state, &dsn, LMTP_THROTTLE));
-}
index fded3afe834fb0ce81cb16574140e6a8731633c2..bad094a78d062fe4c9a9fcb148e77f805414ac39 100644 (file)
 /*     discard(8), Postfix discard delivery agent
 /*     error(8), Postfix error delivery agent
 /*     flush(8), Postfix fast ETRN service
-/*     lmtp(8), Postfix LMTP client
 /*     local(8), Postfix local delivery agent
 /*     master(8), Postfix master daemon
 /*     oqmgr(8), old Postfix queue manager
 /*     qmqpd(8), Postfix QMQP server
 /*     scache(8), Postfix connection cache manager
 /*     showq(8), list Postfix mail queue
-/*     smtp(8), Postfix SMTP client
+/*     smtp(8), lmtp(8), Postfix SMTP+LMTP client
 /*     smtpd(8), Postfix SMTP server
 /*     spawn(8), run non-Postfix server
 /*     tlsmgr(8), Postfix TLS cache and randomness manager
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     SASL support originally by:
+/*     Till Franke
+/*     SuSE Rhein/Main AG
+/*     65760 Eschborn, Germany
+/*
+/*     LMTP support originally by:
+/*     Philip A. Prindeville
+/*     Mirapoint, Inc.
+/*     USA.
+/*
+/*     Amos Gouaux
+/*     University of Texas at Dallas
+/*     P.O. Box 830688, MC34
+/*     Richardson, TX 75083, USA
 /*--*/
 
 /* System library. */
index 32b818d3bf70470730448c1e73ad97d1be26cab7..94c55aa11b55377b38d64174f126e92efa3ee704 100644 (file)
@@ -36,7 +36,7 @@
 /*     queue IDs from standard input. For example, to delete all mail
 /*     with exactly one recipient \fBuser@example.com\fR:
 /* .sp
-/*     mailq | tail +2 | awk  \'BEGIN { RS = "" }
+/*     mailq | tail +2 | grep -v '^ *(' | awk  \'BEGIN { RS = "" }
 /* .ti +4
 /*     # $7=sender, $8=recipient1, $9=recipient2
 /* .ti +4
index deb6f0dad5da671e30a0b7d8aae846784344b3e5..86e17f45913b0de5f3e69b09efb4dad93d454cb8 100644 (file)
@@ -421,27 +421,36 @@ static void scache_service(VSTREAM *client_stream, char *unused_service,
      * This routine runs whenever a client connects to the UNIX-domain socket
      * dedicated to the scache service. All connection-management stuff is
      * handled by the common code in multi_server.c.
+     * 
+     * XXX Workaround: with some requests, the client sends a dummy message
+     * after the server replies (yes that's a botch). When the scache server
+     * is slow, this dummy message may become concatenated with the next
+     * request from the same client. The do-while loop below will repeat
+     * instead of discarding the client request. We must process it now
+     * because there will be no select() notification.
      */
-    if (attr_scan(client_stream,
-                 ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
-                 ATTR_TYPE_STR, MAIL_ATTR_REQ, scache_request,
-                 ATTR_TYPE_END) == 1) {
-       if (VSTREQ(scache_request, SCACHE_REQ_SAVE_DEST)) {
-           scache_save_dest_service(client_stream);
-       } else if (VSTREQ(scache_request, SCACHE_REQ_FIND_DEST)) {
-           scache_find_dest_service(client_stream);
-       } else if (VSTREQ(scache_request, SCACHE_REQ_SAVE_ENDP)) {
-           scache_save_endp_service(client_stream);
-       } else if (VSTREQ(scache_request, SCACHE_REQ_FIND_ENDP)) {
-           scache_find_endp_service(client_stream);
-       } else {
-           msg_warn("unrecognized request: \"%s\", ignored",
-                    STR(scache_request));
-           attr_print(client_stream, ATTR_FLAG_NONE,
-                      ATTR_TYPE_NUM, MAIL_ATTR_STATUS, SCACHE_STAT_BAD,
-                      ATTR_TYPE_END);
+    do {
+       if (attr_scan(client_stream,
+                     ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
+                     ATTR_TYPE_STR, MAIL_ATTR_REQ, scache_request,
+                     ATTR_TYPE_END) == 1) {
+           if (VSTREQ(scache_request, SCACHE_REQ_SAVE_DEST)) {
+               scache_save_dest_service(client_stream);
+           } else if (VSTREQ(scache_request, SCACHE_REQ_FIND_DEST)) {
+               scache_find_dest_service(client_stream);
+           } else if (VSTREQ(scache_request, SCACHE_REQ_SAVE_ENDP)) {
+               scache_save_endp_service(client_stream);
+           } else if (VSTREQ(scache_request, SCACHE_REQ_FIND_ENDP)) {
+               scache_find_endp_service(client_stream);
+           } else {
+               msg_warn("unrecognized request: \"%s\", ignored",
+                        STR(scache_request));
+               attr_print(client_stream, ATTR_FLAG_NONE,
+                          ATTR_TYPE_NUM, MAIL_ATTR_STATUS, SCACHE_STAT_BAD,
+                          ATTR_TYPE_END);
+           }
        }
-    }
+    } while (vstream_peek(client_stream) > 0);
     vstream_fflush(client_stream);
 }
 
index a67da3b554eb0818e472debbaac122c50f6ec2fe..b384472076befd418b8c920d18bb064654d6a549 100644 (file)
@@ -36,6 +36,12 @@ update: ../../libexec/$(PROG)
 ../../libexec/$(PROG): $(PROG)
        cp $(PROG) ../../libexec
 
+smtp.o:        smtp.c smtp_params.c lmtp_params.c
+
+lmtp_params.c: smtp_params.c $(INC_DIR)/mail_params.h
+       egrep -v -f smtp-only smtp_params.c | \
+           sed 's/SMTP/LMTP/g; s/smtp_\([a-z]*_table\)/lmtp_\1/' >$@
+
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
        mkdir printfck
@@ -79,6 +85,7 @@ depend: $(MAKES)
        @$(EXPORT) make -f Makefile.in Makefile 1>&2
 
 # do not edit below this line - it is generated by 'make depend'
+lmtp_params.o: lmtp_params.c
 smtp.o: ../../include/argv.h
 smtp.o: ../../include/attr.h
 smtp.o: ../../include/debug_peer.h
@@ -103,14 +110,17 @@ smtp.o: ../../include/recipient_list.h
 smtp.o: ../../include/resolve_clnt.h
 smtp.o: ../../include/scache.h
 smtp.o: ../../include/string_list.h
+smtp.o: ../../include/stringops.h
 smtp.o: ../../include/sys_defs.h
 smtp.o: ../../include/tls.h
 smtp.o: ../../include/tok822.h
 smtp.o: ../../include/vbuf.h
 smtp.o: ../../include/vstream.h
 smtp.o: ../../include/vstring.h
+smtp.o: lmtp_params.c
 smtp.o: smtp.c
 smtp.o: smtp.h
+smtp.o: smtp_params.c
 smtp.o: smtp_sasl.h
 smtp_addr.o: ../../include/argv.h
 smtp_addr.o: ../../include/attr.h
@@ -231,6 +241,7 @@ smtp_dsn.o: ../../include/dict.h
 smtp_dsn.o: ../../include/dsn.h
 smtp_dsn.o: ../../include/dsn_buf.h
 smtp_dsn.o: ../../include/htable.h
+smtp_dsn.o: ../../include/mail_params.h
 smtp_dsn.o: ../../include/maps.h
 smtp_dsn.o: ../../include/match_list.h
 smtp_dsn.o: ../../include/match_ops.h
@@ -275,6 +286,7 @@ smtp_map11.o: ../../include/vstream.h
 smtp_map11.o: ../../include/vstring.h
 smtp_map11.o: smtp.h
 smtp_map11.o: smtp_map11.c
+smtp_params.o: smtp_params.c
 smtp_proto.o: ../../include/argv.h
 smtp_proto.o: ../../include/attr.h
 smtp_proto.o: ../../include/bounce.h
@@ -361,7 +373,6 @@ smtp_reuse.o: ../../include/argv.h
 smtp_reuse.o: ../../include/attr.h
 smtp_reuse.o: ../../include/deliver_request.h
 smtp_reuse.o: ../../include/dict.h
-smtp_reuse.o: ../../include/dns.h
 smtp_reuse.o: ../../include/dsn.h
 smtp_reuse.o: ../../include/dsn_buf.h
 smtp_reuse.o: ../../include/htable.h
@@ -371,12 +382,10 @@ smtp_reuse.o: ../../include/match_list.h
 smtp_reuse.o: ../../include/match_ops.h
 smtp_reuse.o: ../../include/msg.h
 smtp_reuse.o: ../../include/msg_stats.h
-smtp_reuse.o: ../../include/myaddrinfo.h
 smtp_reuse.o: ../../include/mymalloc.h
 smtp_reuse.o: ../../include/recipient_list.h
 smtp_reuse.o: ../../include/resolve_clnt.h
 smtp_reuse.o: ../../include/scache.h
-smtp_reuse.o: ../../include/sock_addr.h
 smtp_reuse.o: ../../include/string_list.h
 smtp_reuse.o: ../../include/stringops.h
 smtp_reuse.o: ../../include/sys_defs.h
@@ -395,6 +404,7 @@ smtp_sasl_glue.o: ../../include/dict.h
 smtp_sasl_glue.o: ../../include/dsn.h
 smtp_sasl_glue.o: ../../include/dsn_buf.h
 smtp_sasl_glue.o: ../../include/htable.h
+smtp_sasl_glue.o: ../../include/mail_addr_find.h
 smtp_sasl_glue.o: ../../include/mail_params.h
 smtp_sasl_glue.o: ../../include/maps.h
 smtp_sasl_glue.o: ../../include/match_list.h
@@ -488,6 +498,7 @@ smtp_state.o: ../../include/mail_params.h
 smtp_state.o: ../../include/maps.h
 smtp_state.o: ../../include/match_list.h
 smtp_state.o: ../../include/match_ops.h
+smtp_state.o: ../../include/msg.h
 smtp_state.o: ../../include/msg_stats.h
 smtp_state.o: ../../include/mymalloc.h
 smtp_state.o: ../../include/recipient_list.h
diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c
new file mode 100644 (file)
index 0000000..39f2018
--- /dev/null
@@ -0,0 +1,72 @@
+    static CONFIG_STR_TABLE lmtp_str_table[] = {
+       VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
+       VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
+       VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
+       VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
+       VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
+#ifdef USE_TLS
+       VAR_LMTP_SASL_TLS_OPTS, DEF_LMTP_SASL_TLS_OPTS, &var_smtp_sasl_tls_opts, 0, 0,
+#endif
+       VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
+       VAR_LMTP_BIND_ADDR, DEF_LMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
+       VAR_LMTP_BIND_ADDR6, DEF_LMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
+       VAR_LMTP_HELO_NAME, DEF_LMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
+       VAR_LMTP_HOST_LOOKUP, DEF_LMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
+       VAR_LMTP_CACHE_DEST, DEF_LMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
+       VAR_SCACHE_SERVICE, DEF_SCACHE_SERVICE, &var_scache_service, 1, 0,
+       VAR_LMTP_EHLO_DIS_WORDS, DEF_LMTP_EHLO_DIS_WORDS, &var_smtp_ehlo_dis_words, 0, 0,
+       VAR_LMTP_EHLO_DIS_MAPS, DEF_LMTP_EHLO_DIS_MAPS, &var_smtp_ehlo_dis_maps, 0, 0,
+       VAR_LMTP_TLS_PER_SITE, DEF_LMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
+       VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
+       VAR_LMTP_GENERIC_MAPS, DEF_LMTP_GENERIC_MAPS, &var_smtp_generic_maps, 0, 0,
+       VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
+       0,
+    };
+    static CONFIG_TIME_TABLE lmtp_time_table[] = {
+       VAR_LMTP_CONN_TMOUT, DEF_LMTP_CONN_TMOUT, &var_smtp_conn_tmout, 0, 0,
+       VAR_LMTP_HELO_TMOUT, DEF_LMTP_HELO_TMOUT, &var_smtp_helo_tmout, 1, 0,
+       VAR_LMTP_XFWD_TMOUT, DEF_LMTP_XFWD_TMOUT, &var_smtp_xfwd_tmout, 1, 0,
+       VAR_LMTP_MAIL_TMOUT, DEF_LMTP_MAIL_TMOUT, &var_smtp_mail_tmout, 1, 0,
+       VAR_LMTP_RCPT_TMOUT, DEF_LMTP_RCPT_TMOUT, &var_smtp_rcpt_tmout, 1, 0,
+       VAR_LMTP_DATA0_TMOUT, DEF_LMTP_DATA0_TMOUT, &var_smtp_data0_tmout, 1, 0,
+       VAR_LMTP_DATA1_TMOUT, DEF_LMTP_DATA1_TMOUT, &var_smtp_data1_tmout, 1, 0,
+       VAR_LMTP_DATA2_TMOUT, DEF_LMTP_DATA2_TMOUT, &var_smtp_data2_tmout, 1, 0,
+       VAR_LMTP_RSET_TMOUT, DEF_LMTP_RSET_TMOUT, &var_smtp_rset_tmout, 1, 0,
+       VAR_LMTP_QUIT_TMOUT, DEF_LMTP_QUIT_TMOUT, &var_smtp_quit_tmout, 1, 0,
+       VAR_LMTP_PIX_THRESH, DEF_LMTP_PIX_THRESH, &var_smtp_pix_thresh, 0, 0,
+       VAR_LMTP_PIX_DELAY, DEF_LMTP_PIX_DELAY, &var_smtp_pix_delay, 1, 0,
+       VAR_LMTP_CACHE_CONNT, DEF_LMTP_CACHE_CONNT, &var_smtp_cache_conn, 1, 0,
+       VAR_LMTP_REUSE_TIME, DEF_LMTP_REUSE_TIME, &var_smtp_reuse_time, 1, 0,
+#ifdef USE_TLS
+       VAR_LMTP_STARTTLS_TMOUT, DEF_LMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
+#endif
+       VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0,
+       0,
+    };
+    static CONFIG_INT_TABLE lmtp_int_table[] = {
+       VAR_LMTP_LINE_LIMIT, DEF_LMTP_LINE_LIMIT, &var_smtp_line_limit, 0, 0,
+       VAR_LMTP_MXADDR_LIMIT, DEF_LMTP_MXADDR_LIMIT, &var_smtp_mxaddr_limit, 0, 0,
+       VAR_LMTP_MXSESS_LIMIT, DEF_LMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 0, 0,
+#ifdef USE_TLS
+       VAR_LMTP_TLS_SCERT_VD, DEF_LMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
+#endif
+       0,
+    };
+    static CONFIG_BOOL_TABLE lmtp_bool_table[] = {
+       VAR_LMTP_SKIP_5XX, DEF_LMTP_SKIP_5XX, &var_smtp_skip_5xx_greeting,
+       VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
+       VAR_LMTP_SASL_ENABLE, DEF_LMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+       VAR_LMTP_RAND_ADDR, DEF_LMTP_RAND_ADDR, &var_smtp_rand_addr,
+       VAR_LMTP_QUOTE_821_ENV, DEF_LMTP_QUOTE_821_ENV, &var_smtp_quote_821_env,
+       VAR_LMTP_DEFER_MXADDR, DEF_LMTP_DEFER_MXADDR, &var_smtp_defer_mxaddr,
+       VAR_LMTP_SEND_XFORWARD, DEF_LMTP_SEND_XFORWARD, &var_smtp_send_xforward,
+       VAR_LMTP_CACHE_DEMAND, DEF_LMTP_CACHE_DEMAND, &var_smtp_cache_demand,
+       VAR_LMTP_USE_TLS, DEF_LMTP_USE_TLS, &var_smtp_use_tls,
+       VAR_LMTP_ENFORCE_TLS, DEF_LMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
+#ifdef USE_TLS
+       VAR_LMTP_TLS_ENFORCE_PN, DEF_LMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
+       VAR_LMTP_TLS_NOTEOFFER, DEF_LMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
+#endif
+       VAR_LMTP_SENDER_AUTH, DEF_LMTP_SENDER_AUTH, &var_smtp_sender_auth,
+       0,
+    };
diff --git a/postfix/src/smtp/smtp-only b/postfix/src/smtp/smtp-only
new file mode 100644 (file)
index 0000000..134dcd4
--- /dev/null
@@ -0,0 +1,4 @@
+_ALWAYS_EHLO
+_NEVER_EHLO
+_SMTP_FALLBACK
+_IGN_MX_LOOKUP_ERR
index 0208d2749cd2ecf659572280b5e507010b4a3d25..ee1312b18421dd4fd672c3d76163529b364e405f 100644 (file)
@@ -2,52 +2,85 @@
 /* NAME
 /*     smtp 8
 /* SUMMARY
-/*     Postfix SMTP client
+/*     Postfix SMTP+LMTP client
 /* SYNOPSIS
 /*     \fBsmtp\fR [generic Postfix daemon options]
 /* DESCRIPTION
-/*     The Postfix SMTP client processes message delivery requests from
+/*     The Postfix SMTP+LMTP client implements the SMTP and LMTP mail
+/*     delivery protocols. It 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 SMTP client updates the queue file and marks recipients
+/*     The SMTP+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 status reports are sent
 /*     to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
 /*     appropriate.
 /*
-/*     The SMTP client looks up a list of mail exchanger addresses for
+/*     The SMTP+LMTP client looks up a list of mail exchanger addresses for
 /*     the destination host, sorts the list by preference, and connects
 /*     to each listed address until it finds a server that responds.
 /*
 /*     When a server is not reachable, or when mail delivery fails due
-/*     to a recoverable error condition, the SMTP client will try to
+/*     to a recoverable error condition, the SMTP+LMTP client will try to
 /*     deliver the mail to an alternate host.
 /*
 /*     After a successful mail transaction, a connection may be saved
 /*     to the \fBscache\fR(8) connection cache server, so that it
-/*     may be used by any SMTP client for a subsequent transaction.
+/*     may be used by any SMTP+LMTP client for a subsequent transaction.
 /*
 /*     By default, connection caching is enabled temporarily for
 /*     destinations that have a high volume of mail in the active
 /*     queue. Session caching can be enabled permanently for
 /*     specific destinations.
+/* SMTP DESTINATION SYNTAX
+/* .ad
+/* .fi
+/*     SMTP destinations have the following form:
+/* .IP "\fIdomainname\fR, \fIdomainname\fR:\fIport\fR"
+/*     Look up the mail exchangers for the specified domain.
+/* .IP "[\fIhostname\fR], [\fIhostname\fR]:\fIport\fR"
+/*     Look up the address of the specified host.
+/* .IP "[\fIaddress\fR], [\fIaddress\fR]:\fIport\fR"
+/*     Connect to the host at the specified address. An IPv6
+/*     address must be formatted as [\fBipv6\fR:\fIaddress\fR].
+/* .PP
+/*     In all the above cases, when no port is specified, look up
+/*     the port defined as \fBsmtp\fR in \fBservices\fR(4).
+/* LMTP DESTINATION SYNTAX
+/* .ad
+/* .fi
+/*      LMTP destinations have the following form:
+/* .IP \fBunix\fR:\fIpathname\fR
+/*      Connect to the local UNIX-domain server that is bound to the specified
+/*      \fIpathname\fR. If the process runs chrooted, an absolute pathname
+/*      is interpreted relative to the Postfix queue directory.
+/* .IP "\fBinet\fR:\fIhostname\fR, \fBinet\fB:\fIhostname\fR:\fIport\fR"
+/* .IP "\fBinet\fR:[\fIaddress\fR], \fBinet\fR:[\fIaddress\fR]:\fIport\fR"
+/*      Connect to the specified TCP port on the specified local or
+/*      remote host. If no port is specified, connect to the port defined as
+/*      \fBlmtp\fR in \fBservices\fR(4).
+/*      If no such service is found, the \fBlmtp_tcp_port\fR configuration
+/*      parameter (default value of 24) will be used.
+/* .PP
 /* SECURITY
 /* .ad
 /* .fi
-/*     The SMTP client is moderately security-sensitive. It talks to SMTP
-/*     servers and to DNS servers on the network. The SMTP client can be
-/*     run chrooted at fixed low privilege.
+/*     The SMTP+LMTP client is moderately security-sensitive. It
+/*     talks to SMTP or LMTP servers and to DNS servers on the
+/*     network. The SMTP+LMTP client can be run chrooted at fixed
+/*     low privilege.
 /* STANDARDS
 /*     RFC 821 (SMTP protocol)
 /*     RFC 822 (ARPA Internet Text Messages)
 /*     RFC 1651 (SMTP service extensions)
 /*     RFC 1652 (8bit-MIME transport)
 /*     RFC 1870 (Message Size Declaration)
-/*     RFC 2045 (MIME: Format of Internet Message Bodies)
+/*     RFC 2033 (LMTP protocol)
 /*     RFC 2034 (Enhanced Status Codes)
+/*     RFC 2045 (MIME: Format of Internet Message Bodies)
 /*     RFC 2046 (MIME: Media Types)
 /*     RFC 2554 (AUTH command)
 /*     RFC 2821 (SMTP protocol)
 /*     the postmaster is notified of bounces, protocol problems, and of
 /*     other trouble.
 /* BUGS
-/*     SMTP connection caching does not work with TLS. The necessary
+/*     SMTP and LMTP connection caching does not work with TLS. The necessary
 /*     support for TLS object passivation and re-activation does not
 /*     exist without closing the session, which defeats the purpose.
 /*
-/*     SMTP connection caching assumes that SASL credentials are valid for
-/*     all destinations that map onto the same IP address and TCP port.
+/*     SMTP and LMTP connection caching assumes that SASL credentials
+/*     are valid for all destinations that map onto the same IP
+/*     address and TCP port.
 /* CONFIGURATION PARAMETERS
 /* .ad
 /* .fi
+/*     Most smtp_\fIxxx\fR configuration parameters have an
+/*     lmtp_\fIxxx\fR "ghost" parameter for the equivalent LMTP
+/*     feature. This document describes only those LMTP-related
+/*     parameters that aren't simply "ghost" parameters.
+/*
 /*     Changes to \fBmain.cf\fR are picked up automatically, as \fBsmtp\fR(8)
 /*     processes run for only a limited amount of time. Use the command
 /*     "\fBpostfix reload\fR" to speed up a change.
 /*     Optional lookup tables that perform address rewriting in the
 /*     SMTP client, typically to transform a locally valid address into
 /*     a globally valid address when sending mail across the Internet.
+/* .PP
+/*     Available in Postfix version 2.3 and later:
+/* .IP "\fBlmtp_discard_lhlo_keyword_address_maps (empty)\fR"
+/*     Lookup tables, indexed by the remote LMTP server address, with
+/*     case insensitive lists of LHLO keywords (pipelining, starttls,
+/*     auth, etc.) that the LMTP client will ignore in the LHLO response
+/*     from a remote LMTP server.
+/* .IP "\fBlmtp_discard_lhlo_keywords ($myhostname)\fR"
+/*     A case insensitive list of LHLO keywords (pipelining, starttls,
+/*     auth, etc.) that the LMTP client will ignore in the LHLO response
+/*     from a remote LMTP server.
 /* MIME PROCESSING CONTROLS
 /* .ad
 /* .fi
 /* .IP "\fBsmtp_helo_timeout (300s)\fR"
 /*     The SMTP client time limit for sending the HELO or EHLO command,
 /*     and for receiving the initial server response.
+/* .IP "\fBlmtp_lhlo_timeout (300s)\fR"
+/*     The LMTP client time limit for sending the LHLO command, and
+/*     for receiving the initial server response.
 /* .IP "\fBsmtp_xforward_timeout (300s)\fR"
 /*     The SMTP client time limit for sending the XFORWARD command, and
 /*     for receiving the server response.
 /* .IP "\fBsmtp_connection_cache_time_limit (2s)\fR"
 /*     When SMTP connection caching is enabled, the amount of time that
 /*     an unused SMTP client socket is kept open before it is closed.
+/* .PP
+/*     Available in Postfix version 2.3 and later:
+/* .IP "\fBconnection_cache_protocol_timeout (5s)\fR"
+/*     Time limit for connection cache connect, send or receive
+/*     operations.
 /* TROUBLE SHOOTING CONTROLS
 /* .ad
 /* .fi
 /*     sub-second delay values.
 /* .IP "\fBdisable_dns_lookups (no)\fR"
 /*     Disable DNS lookups in the Postfix SMTP and LMTP clients.
-/* .IP "\fBfallback_relay (empty)\fR"
-/*     Optional list of relay hosts for SMTP destinations that can't be
-/*     found or that are unreachable.
 /* .IP "\fBinet_interfaces (all)\fR"
 /*     The network interface addresses that this mail system receives
 /*     mail on.
 /* .IP "\fBipc_timeout (3600s)\fR"
 /*     The time limit for sending or receiving information over an internal
 /*     communication channel.
+/* .IP "\fBlmtp_tcp_port (24)\fR"
+/*     The default TCP port that the Postfix LMTP client connects to.
 /* .IP "\fBmax_idle (100s)\fR"
 /*     The maximum amount of time that an idle Postfix daemon process
 /*     waits for the next service request before exiting.
 /*     bind to when making an IPv6 connection.
 /* .IP "\fBsmtp_helo_name ($myhostname)\fR"
 /*     The hostname to send in the SMTP EHLO or HELO command.
+/* .IP "\fBlmtp_lhlo_name ($myhostname)\fR"
+/*     The hostname to send in the LMTP LHLO command.
 /* .IP "\fBsmtp_host_lookup (dns)\fR"
 /*     What mechanisms when the SMTP client uses to look up a host's IP
 /*     address.
 /* .IP "\fBsyslog_name (postfix)\fR"
 /*     The mail system name that is prepended to the process name in syslog
 /*     records, so that "smtpd" becomes, for example, "postfix/smtpd".
+/* .PP
+/*     Available with Postfix 2.2 and earlier:
+/* .IP "\fBfallback_relay (empty)\fR"
+/*     Optional list of relay hosts for SMTP destinations that can't be
+/*     found or that are unreachable.
+/* .PP
+/*     Available with Postfix 2.3 and later:
+/* .IP "\fBsmtp_fallback_relay ($fallback_relay)\fR"
+/*     Optional list of relay hosts for SMTP destinations that can't be
+/*     found or that are unreachable.
 /* SEE ALSO
 /*     qmgr(8), queue manager
 /*     bounce(8), delivery status reports
 #include <string.h>
 #include <fcntl.h>
 #include <dict.h>
+#include <stringops.h>
 
 /* Utility library. */
 
@@ -518,6 +588,8 @@ bool    var_smtp_tls_note_starttls_offer;
 char   *var_smtp_generic_maps;
 char   *var_prop_extension;
 bool    var_smtp_sender_auth;
+char   *var_lmtp_tcp_port;
+int     var_scache_proto_tmout;
 
  /*
   * Global variables. smtp_errno is set by the address lookup routines and by
@@ -645,6 +717,7 @@ static void post_init(char *unused_name, char **unused_argv)
        smtp_scache = scache_multi_create();
 #else
        smtp_scache = scache_clnt_create(var_scache_service,
+                                        var_scache_proto_tmout,
                                         var_ipc_idle_limit,
                                         var_ipc_ttl_limit);
 #endif
@@ -740,87 +813,27 @@ static void pre_exit(void)
 
 int     main(int argc, char **argv)
 {
-    static CONFIG_STR_TABLE str_table[] = {
-       VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
-       VAR_FALLBACK_RELAY, DEF_FALLBACK_RELAY, &var_fallback_relay, 0, 0,
-       VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
-       VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
-       VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
-       VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
-#ifdef USE_TLS
-       VAR_SMTP_SASL_TLS_OPTS, DEF_SMTP_SASL_TLS_OPTS, &var_smtp_sasl_tls_opts, 0, 0,
-#endif
-       VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
-       VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
-       VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
-       VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
-       VAR_SMTP_HOST_LOOKUP, DEF_SMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
-       VAR_SMTP_CACHE_DEST, DEF_SMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
-       VAR_SCACHE_SERVICE, DEF_SCACHE_SERVICE, &var_scache_service, 1, 0,
-       VAR_SMTP_EHLO_DIS_WORDS, DEF_SMTP_EHLO_DIS_WORDS, &var_smtp_ehlo_dis_words, 0, 0,
-       VAR_SMTP_EHLO_DIS_MAPS, DEF_SMTP_EHLO_DIS_MAPS, &var_smtp_ehlo_dis_maps, 0, 0,
-       VAR_SMTP_TLS_PER_SITE, DEF_SMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
-       VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
-       VAR_SMTP_GENERIC_MAPS, DEF_SMTP_GENERIC_MAPS, &var_smtp_generic_maps, 0, 0,
-       0,
-    };
-    static CONFIG_TIME_TABLE time_table[] = {
-       VAR_SMTP_CONN_TMOUT, DEF_SMTP_CONN_TMOUT, &var_smtp_conn_tmout, 0, 0,
-       VAR_SMTP_HELO_TMOUT, DEF_SMTP_HELO_TMOUT, &var_smtp_helo_tmout, 1, 0,
-       VAR_SMTP_XFWD_TMOUT, DEF_SMTP_XFWD_TMOUT, &var_smtp_xfwd_tmout, 1, 0,
-       VAR_SMTP_MAIL_TMOUT, DEF_SMTP_MAIL_TMOUT, &var_smtp_mail_tmout, 1, 0,
-       VAR_SMTP_RCPT_TMOUT, DEF_SMTP_RCPT_TMOUT, &var_smtp_rcpt_tmout, 1, 0,
-       VAR_SMTP_DATA0_TMOUT, DEF_SMTP_DATA0_TMOUT, &var_smtp_data0_tmout, 1, 0,
-       VAR_SMTP_DATA1_TMOUT, DEF_SMTP_DATA1_TMOUT, &var_smtp_data1_tmout, 1, 0,
-       VAR_SMTP_DATA2_TMOUT, DEF_SMTP_DATA2_TMOUT, &var_smtp_data2_tmout, 1, 0,
-       VAR_SMTP_RSET_TMOUT, DEF_SMTP_RSET_TMOUT, &var_smtp_rset_tmout, 1, 0,
-       VAR_SMTP_QUIT_TMOUT, DEF_SMTP_QUIT_TMOUT, &var_smtp_quit_tmout, 1, 0,
-       VAR_SMTP_PIX_THRESH, DEF_SMTP_PIX_THRESH, &var_smtp_pix_thresh, 0, 0,
-       VAR_SMTP_PIX_DELAY, DEF_SMTP_PIX_DELAY, &var_smtp_pix_delay, 1, 0,
-       VAR_SMTP_CACHE_CONN, DEF_SMTP_CACHE_CONN, &var_smtp_cache_conn, 1, 0,
-       VAR_SMTP_REUSE_TIME, DEF_SMTP_REUSE_TIME, &var_smtp_reuse_time, 1, 0,
-#ifdef USE_TLS
-       VAR_SMTP_STARTTLS_TMOUT, DEF_SMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
-#endif
-       0,
-    };
-    static CONFIG_INT_TABLE int_table[] = {
-       VAR_SMTP_LINE_LIMIT, DEF_SMTP_LINE_LIMIT, &var_smtp_line_limit, 0, 0,
-       VAR_SMTP_MXADDR_LIMIT, DEF_SMTP_MXADDR_LIMIT, &var_smtp_mxaddr_limit, 0, 0,
-       VAR_SMTP_MXSESS_LIMIT, DEF_SMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 0, 0,
-#ifdef USE_TLS
-       VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
-#endif
-       0,
-    };
-    static CONFIG_BOOL_TABLE bool_table[] = {
-       VAR_SMTP_SKIP_5XX, DEF_SMTP_SKIP_5XX, &var_smtp_skip_5xx_greeting,
-       VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err,
-       VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
-       VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
-       VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
-       VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
-       VAR_SMTP_RAND_ADDR, DEF_SMTP_RAND_ADDR, &var_smtp_rand_addr,
-       VAR_SMTP_QUOTE_821_ENV, DEF_SMTP_QUOTE_821_ENV, &var_smtp_quote_821_env,
-       VAR_SMTP_DEFER_MXADDR, DEF_SMTP_DEFER_MXADDR, &var_smtp_defer_mxaddr,
-       VAR_SMTP_SEND_XFORWARD, DEF_SMTP_SEND_XFORWARD, &var_smtp_send_xforward,
-       VAR_SMTP_CACHE_DEMAND, DEF_SMTP_CACHE_DEMAND, &var_smtp_cache_demand,
-       VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
-       VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
-#ifdef USE_TLS
-       VAR_SMTP_TLS_ENFORCE_PN, DEF_SMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
-       VAR_SMTP_TLS_NOTEOFFER, DEF_SMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
-#endif
-       VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
+#include "smtp_params.c"
+#include "lmtp_params.c"
+    int     smtp_mode;
 
-       0,
-    };
+    /*
+     * XXX At this point, var_procname etc. are not initialized.
+     */
+    smtp_mode = (strcmp(sane_basename((VSTRING *) 0, argv[0]), "smtp") == 0);
 
+    /*
+     * Initialize with the LMTP or SMTP parameter name space.
+     */
     single_server_main(argc, argv, smtp_service,
-                      MAIL_SERVER_TIME_TABLE, time_table,
-                      MAIL_SERVER_INT_TABLE, int_table,
-                      MAIL_SERVER_STR_TABLE, str_table,
-                      MAIL_SERVER_BOOL_TABLE, bool_table,
+                      MAIL_SERVER_TIME_TABLE, smtp_mode ?
+                      smtp_time_table : lmtp_time_table,
+                      MAIL_SERVER_INT_TABLE, smtp_mode ?
+                      smtp_int_table : lmtp_int_table,
+                      MAIL_SERVER_STR_TABLE, smtp_mode ?
+                      smtp_str_table : lmtp_str_table,
+                      MAIL_SERVER_BOOL_TABLE, smtp_mode ?
+                      smtp_bool_table : lmtp_bool_table,
                       MAIL_SERVER_PRE_INIT, pre_init,
                       MAIL_SERVER_POST_INIT, post_init,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
index 681a7e05f6d2d7a5672ce41fba5a5b9fa5a032da..0448b8a63dbe4d0f70347ecf72651e1a879640b5 100644 (file)
@@ -46,6 +46,7 @@
   * Session-specific state is stored separately.
   */
 typedef struct SMTP_STATE {
+    int     misc_flags;                        /* processing flags, see below */
     VSTREAM *src;                      /* queue file stream */
     const char *service;               /* transport name */
     DELIVER_REQUEST *request;          /* envelope info, offsets */
@@ -139,8 +140,7 @@ typedef struct SMTP_STATE {
   */
 #define SMTP_MISC_FLAG_LOOP_DETECT     (1<<0)
 #define        SMTP_MISC_FLAG_IN_STARTTLS      (1<<1)
-
-#define SMTP_MISC_FLAG_DEFAULT         SMTP_MISC_FLAG_LOOP_DETECT
+#define SMTP_MISC_FLAG_USE_LMTP                (1<<2)
 
  /*
   * smtp.c
@@ -246,7 +246,7 @@ extern int smtp_connect(SMTP_STATE *);
  /*
   * smtp_proto.c
   */
-extern int smtp_helo(SMTP_STATE *, int);
+extern int smtp_helo(SMTP_STATE *);
 extern int smtp_xfer(SMTP_STATE *);
 extern int smtp_rset(SMTP_STATE *);
 extern int smtp_quit(SMTP_STATE *);
index 62fa9c53b88242f2f3d767f207306671f488aa78..b9a4a7164fe90eee0b92dd3642c6349f831bfcf7 100644 (file)
@@ -2,29 +2,31 @@
 /* NAME
 /*     smtp_connect 3
 /* SUMMARY
-/*     connect to SMTP server and deliver
+/*     connect to SMTP/LMTP server and deliver
 /* SYNOPSIS
 /*     #include "smtp.h"
 /*
 /*     int     smtp_connect(state)
 /*     SMTP_STATE *state;
 /* DESCRIPTION
-/*     This module implements SMTP connection management and controls
+/*     This module implements SMTP/LMTP connection management and controls
 /*     mail delivery.
 /*
-/*     smtp_connect() attempts to establish an SMTP session with a host
+/*     smtp_connect() attempts to establish an SMTP/LMTP session with a host
 /*     that represents the destination domain, or with an optional fallback
 /*     relay when the destination cannot be found, or when all the
 /*     destination servers are unavailable. It skips over IP addresses
-/*     that fail to complete the SMTP handshake and tries to find
-/*     an alternate server when an SMTP session fails to deliver.
+/*     that fail to complete the SMTP/LMTP handshake and tries to find
+/*     an alternate server when an SMTP/LMTP session fails to deliver.
 /*
-/*     This layer also controls what sessions are retrieved from
-/*     the session cache, and what sessions are saved to the cache.
+/*     This layer also controls what connections are retrieved from
+/*     the connection cache, and what connections are saved to the cache.
 /*
 /*     The destination is either a host (or domain) name or a numeric
 /*     address. Symbolic or numeric service port information may be
-/*     appended, separated by a colon (":").
+/*     appended, separated by a colon (":"). In the case of LMTP,
+/*     destinations may be specified as "unix:pathname", "inet:host"
+/*     or "inet:host:port".
 /*
 /*     By default, the Internet domain name service is queried for mail
 /*     exchanger hosts. Quote the domain name with `[' and `]' to
@@ -55,6 +57,7 @@
 #include <sys_defs.h>
 #include <stdlib.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
 #include <smtp_addr.h>
 #include <smtp_reuse.h>
 
+ /*
+  * Forward declaration.
+  */
+static SMTP_SESSION *smtp_connect_sock(int, struct sockaddr *, int,
+                                              const char *, const char *,
+                                              unsigned,
+                                              const char *, DSN_BUF *,
+                                              int);
+
+/* smtp_connect_unix - connect to UNIX-domain address */
+
+static SMTP_SESSION *smtp_connect_unix(const char *addr,
+                                              DSN_BUF *why,
+                                              int sess_flags)
+{
+    char   *myname = "smtp_connect_unix";
+    struct sockaddr_un sock_un;
+    int     len = strlen(addr);
+    int     sock;
+
+    smtp_errno = SMTP_ERR_NONE;                        /* Paranoia */
+
+    /*
+     * Sanity checks.
+     */
+    if (len >= (int) sizeof(sock_un.sun_path)) {
+       msg_warn("unix-domain name too long: %s", addr);
+       smtp_dsn_update(why, DSN_BY_LOCAL_MTA, "4.3.5",
+                       450, "450 Mail server configuration error",
+                       "Server configuration error");
+       smtp_errno = SMTP_ERR_RETRY;
+       return (0);
+    }
+
+    /*
+     * Initialize.
+     */
+    memset((char *) &sock_un, 0, sizeof(sock_un));
+    sock_un.sun_family = AF_UNIX;
+#ifdef HAS_SUN_LEN
+    sock_un.sun_len = len + 1;
+#endif
+    memcpy(sock_un.sun_path, addr, len + 1);
+
+    /*
+     * Create a client socket.
+     */
+    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+       msg_fatal("%s: socket: %m", myname);
+
+    /*
+     * Connect to the server.
+     */
+    if (msg_verbose)
+       msg_info("%s: trying: %s...", myname, addr);
+
+    return (smtp_connect_sock(sock, (struct sockaddr *) & sock_un,
+                             sizeof(sock_un), var_myhostname, addr,
+                             0, addr, why, sess_flags));
+}
+
 /* smtp_connect_addr - connect to explicit address */
 
-static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
+static SMTP_SESSION *smtp_connect_addr(const char *destination, DNS_RR *addr,
                                               unsigned port, DSN_BUF *why,
                                               int sess_flags)
 {
@@ -115,13 +179,8 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
     SOCKADDR_SIZE salen = sizeof(ss);
     MAI_HOSTADDR_STR hostaddr;
     int     sock;
-    int     conn_stat;
-    int     saved_errno;
-    VSTREAM *stream;
-    int     ch;
     char   *bind_addr;
     char   *bind_var;
-    time_t  start_time;
 
     smtp_errno = SMTP_ERR_NONE;                        /* Paranoia */
 
@@ -207,12 +266,33 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
     }
 
     /*
-     * Connect to the SMTP server.
+     * Connect to the server.
      */
     SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
     if (msg_verbose)
        msg_info("%s: trying: %s[%s] port %d...",
                 myname, addr->name, hostaddr.buf, ntohs(port));
+
+    return (smtp_connect_sock(sock, sa, salen, addr->name, hostaddr.buf,
+                             port, destination, why, sess_flags));
+}
+
+/* smtp_connect_sock - connect a socket over some transport */
+
+static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
+                                              int salen, const char *name,
+                                              const char *addr,
+                                              unsigned port,
+                                              const char *destination,
+                                              DSN_BUF *why,
+                                              int sess_flags)
+{
+    int     conn_stat;
+    int     saved_errno;
+    VSTREAM *stream;
+    int     ch;
+    time_t  start_time;
+
     start_time = time((time_t *) 0);
     if (var_smtp_conn_tmout > 0) {
        non_blocking(sock, NON_BLOCKING);
@@ -227,7 +307,7 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
     if (conn_stat < 0) {
        smtp_dsn_update(why, DSN_BY_LOCAL_MTA,
                        "4.4.1", 420, "420 Unable to connect to server",
-                       "connect to %s[%s]: %m", addr->name, hostaddr.buf);
+                       "connect to %s[%s]: %m", name, addr);
        smtp_errno = SMTP_ERR_RETRY;
        close(sock);
        return (0);
@@ -274,11 +354,11 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
     /*
      * Bundle up what we have into a nice SMTP_SESSION object.
      */
-    return (smtp_session_alloc(stream, dest, addr->name, hostaddr.buf,
+    return (smtp_session_alloc(stream, destination, name, addr,
                               port, start_time, sess_flags));
 }
 
-/* smtp_parse_destination - parse destination */
+/* smtp_parse_destination - parse host/port destination */
 
 static char *smtp_parse_destination(char *destination, char *def_service,
                                            char **hostp, unsigned *portp)
@@ -304,7 +384,7 @@ static char *smtp_parse_destination(char *destination, char *def_service,
      * Convert service to port number, network byte order.
      */
     if (alldig(service)) {
-       if ((port = atoi(service)) >= 65536)
+       if ((port = atoi(service)) >= 65536 || port == 0)
            msg_fatal("bad network port in destination: %s", destination);
        *portp = htons(port);
     } else {
@@ -390,6 +470,62 @@ static void smtp_cleanup_session(SMTP_STATE *state)
     request->msg_stats.reuse_count = 0;
 }
 
+/* smtp_connect_local - connect to local server */
+
+static void smtp_connect_local(SMTP_STATE *state, const char *path,
+                                      DSN_BUF *why)
+{
+    DELIVER_REQUEST *request = state->request;
+    int     sess_flags = SMTP_SESS_FLAG_NONE;
+    SMTP_SESSION *session;
+
+    /*
+     * It's too painful to weave this code into the SMTP connection
+     * management routine.
+     * 
+     * Connection cache management is based on the UNIX-domain pathname, without
+     * the "unix:" prefix.
+     * 
+     * XXX Disable connection caching when sender-dependent authentication is
+     * enabled. We must not send someone elses mail over an authenticated
+     * connection, and we must not send mail that requires authentication
+     * over a connection that wasn't authenticated.
+     */
+#define CAN_ENABLE_CONN_CACHE(request, dest) \
+    (!var_smtp_sender_auth \
+     && ((var_smtp_cache_demand && (request->flags & DEL_REQ_FLAG_SCACHE)) \
+        || (smtp_cache_dest && string_list_match(smtp_cache_dest, dest))))
+
+    if (CAN_ENABLE_CONN_CACHE(request, path))
+       sess_flags |= SMTP_SESS_FLAG_CACHE;
+
+    /*
+     * XXX We assume that the session->addr member refers to a copy of the
+     * UNIX-domain pathname, so that smtp_save_session() will cache the
+     * connection using the pathname as the physical endpoint name.
+     */
+#define NO_MX  0
+#define NO_PORT        0
+
+    if ((sess_flags & SMTP_SESS_FLAG_CACHE) == 0
+       || (session = smtp_reuse_addr(state, path, NO_PORT)) == 0)
+       session = smtp_connect_unix(path, why, sess_flags);
+    if ((state->session = session) != 0) {
+       session->state = state;
+       /* All delivery errors bounce or defer. */
+       state->final_server = 1;
+       if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
+           && smtp_helo(state) != 0) {
+           if (vstream_ferror(session->stream) == 0
+               && vstream_feof(session->stream) == 0)
+               smtp_quit(state);
+       } else {
+           smtp_xfer(state);
+       }
+       smtp_cleanup_session(state);
+    }
+}
+
 /* smtp_scrub_address_list - delete all cached addresses from list */
 
 static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
@@ -474,6 +610,7 @@ static int smtp_reuse_session(SMTP_STATE *state, int lookup_mx,
     DNS_RR *addr;
     DNS_RR *next;
     int     saved_final_server = state->final_server;
+    MAI_HOSTADDR_STR hostaddr;
     SMTP_SESSION *session;
 
     /*
@@ -503,7 +640,8 @@ static int smtp_reuse_session(SMTP_STATE *state, int lookup_mx,
        if (addr->pref != domain_best_pref)
            break;
        next = addr->next;
-       if ((session = smtp_reuse_addr(state, addr, port)) != 0) {
+       if (dns_rr_to_pa(addr, &hostaddr) != 0
+           && (session = smtp_reuse_addr(state, hostaddr.buf, port)) != 0) {
            session->features |= SMTP_FEATURE_BEST_MX;
            session_count += 1;
            smtp_update_addr_list(addr_list, session->addr, session_count);
@@ -517,31 +655,19 @@ static int smtp_reuse_session(SMTP_STATE *state, int lookup_mx,
     return (session_count);
 }
 
-/* smtp_connect - establish SMTP connection */
+/* smtp_connect_remote - establish remote connection */
 
-int     smtp_connect(SMTP_STATE *state)
+static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop,
+                                       DSN_BUF *why)
 {
     DELIVER_REQUEST *request = state->request;
-    DSN_BUF *why = dsb_create();
-    char   *dest_buf;
-    char   *domain;
-    unsigned port;
-    char   *def_service = "smtp";      /* XXX ##IPPORT_SMTP? */
+    char   *def_service;
     ARGV   *sites;
     char   *dest;
     char  **cpp;
-    DNS_RR *addr_list;
-    DNS_RR *addr;
-    DNS_RR *next;
-    int     addr_count;
-    int     sess_count;
-    int     misc_flags = SMTP_MISC_FLAG_DEFAULT;
-    SMTP_SESSION *session;
-    int     lookup_mx;
-    unsigned domain_best_pref;
     int     sess_flags = SMTP_SESS_FLAG_NONE;
-    int     i_am_mx = 0;
     int     non_fallback_sites;
+    int     saved_misc_flags = state->misc_flags;
 
     /*
      * First try to deliver to the indicated destination, then try to deliver
@@ -555,7 +681,12 @@ int     smtp_connect(SMTP_STATE *state)
     if (sites->argc == 0)
        msg_panic("null destination: \"%s\"", request->nexthop);
     non_fallback_sites = sites->argc;
-    argv_split_append(sites, var_fallback_relay, ", \t\r\n");
+    if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+       argv_split_append(sites, var_fallback_relay, ", \t\r\n");
+       def_service = "smtp";                   /* XXX ##IPPORT_SMTP? */
+    } else {
+       def_service = var_lmtp_tcp_port;
+    }
 
     /*
      * Don't give up after a hard host lookup error until we have tried the
@@ -577,6 +708,20 @@ int     smtp_connect(SMTP_STATE *state)
            (*(cpp) && (cpp) >= (sites)->argv + (non_fallback_sites))
 
     for (cpp = sites->argv; SMTP_RCPT_LEFT(state) > 0 && (dest = *cpp) != 0; cpp++) {
+       char   *dest_buf;
+       char   *domain;
+       unsigned port;
+       DNS_RR *addr_list;
+       DNS_RR *addr;
+       DNS_RR *next;
+       int     addr_count;
+       int     sess_count;
+       SMTP_SESSION *session;
+       int     lookup_mx;
+       unsigned domain_best_pref;
+       MAI_HOSTADDR_STR hostaddr;
+
+       state->misc_flags = saved_misc_flags;
 
        /*
         * Parse the destination. Default is to use the SMTP port. Look up
@@ -591,21 +736,39 @@ int     smtp_connect(SMTP_STATE *state)
         */
        if (msg_verbose)
            msg_info("connecting to %s port %d", domain, ntohs(port));
-       if (ntohs(port) != IPPORT_SMTP)
-           misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
-       else
-           misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
-       lookup_mx = (var_disable_dns == 0 && *dest != '[');
+       if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+           if (ntohs(port) == IPPORT_SMTP)
+               state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
+           lookup_mx = (var_disable_dns == 0 && *dest != '[');
+       } else
+           lookup_mx = 0;
        if (!lookup_mx) {
-           addr_list = smtp_host_addr(domain, misc_flags, why);
+           addr_list = smtp_host_addr(domain, state->misc_flags, why);
            /* XXX We could be an MX host for this destination... */
        } else {
-           addr_list = smtp_domain_addr(domain, misc_flags, why, &i_am_mx);
+           int     i_am_mx = 0;
+
+           addr_list = smtp_domain_addr(domain, state->misc_flags,
+                                        why, &i_am_mx);
            /* If we're MX host, don't connect to non-MX backups. */
            if (i_am_mx)
                argv_truncate(sites, cpp - sites->argv + 1);
        }
-       state->final_server = (cpp[1] == 0);
+
+       /*
+        * Don't try any backup host if mail loops to myself. That would just
+        * make the problem worse.
+        */
+       if (addr_list == 0 && smtp_errno == SMTP_ERR_LOOP) {
+           myfree(dest_buf);
+           break;
+       }
+
+       /*
+        * No early loop exit or we have a memory leak with dest_buf.
+        */
+       if (addr_list)
+           domain_best_pref = addr_list->pref;
 
        /*
         * When session caching is enabled, store the first good session for
@@ -631,34 +794,16 @@ int     smtp_connect(SMTP_STATE *state)
         * authenticated connection, and we must not send mail that requires
         * authentication over a connection that wasn't authenticated.
         */
-       if (cpp == sites->argv
-           && !var_smtp_sender_auth
-           && ((var_smtp_cache_demand && (request->flags & DEL_REQ_FLAG_SCACHE) != 0)
-               || (smtp_cache_dest && string_list_match(smtp_cache_dest, domain)))) {
+       if (cpp == sites->argv && CAN_ENABLE_CONN_CACHE(request, domain)) {
            sess_flags |= SMTP_SESS_FLAG_CACHE;
            SET_NEXTHOP_STATE(state, lookup_mx, domain, port);
        }
 
-       /*
-        * Don't try any backup host if mail loops to myself. That would just
-        * make the problem worse.
-        */
-       if (addr_list == 0 && smtp_errno == SMTP_ERR_LOOP) {
-           myfree(dest_buf);
-           break;
-       }
-
-       /*
-        * No early loop exit or we have a memory leak with dest_buf.
-        */
-       if (addr_list)
-           domain_best_pref = addr_list->pref;
-
        /*
         * Delete visited cached hosts from the address list.
         * 
         * Optionally search the connection cache by domain name or by primary
-        * MX address.
+        * MX address before we try to create new connections.
         * 
         * Enforce the MX session and MX address counts per next-hop or
         * fall-back destination. smtp_reuse_session() will truncate the
@@ -667,6 +812,8 @@ int     smtp_connect(SMTP_STATE *state)
        if (addr_list && (sess_flags & SMTP_SESS_FLAG_CACHE) != 0) {
            if (state->cache_used->used > 0)
                smtp_scrub_addr_list(state->cache_used, &addr_list);
+           /* Count delivery errors towards the session limit. */
+           state->final_server = (cpp[1] == 0);
            sess_count = addr_count =
                smtp_reuse_session(state, lookup_mx, domain, port,
                                   &addr_list, domain_best_pref);
@@ -674,7 +821,8 @@ int     smtp_connect(SMTP_STATE *state)
            sess_count = addr_count = 0;
 
        /*
-        * Connect to an SMTP server.
+        * Connect to an SMTP server: create primary MX connections, and
+        * reuse or create backup MX connections.
         * 
         * At the start of an SMTP session, all recipients are unmarked. In the
         * course of an SMTP session, recipients are marked as KEEP (deliver
@@ -696,7 +844,8 @@ int     smtp_connect(SMTP_STATE *state)
                next = 0;
            if ((sess_flags & SMTP_SESS_FLAG_CACHE) == 0
                || addr->pref == domain_best_pref
-               || (session = smtp_reuse_addr(state, addr, port)) == 0)
+               || dns_rr_to_pa(addr, &hostaddr) == 0
+               || !(session = smtp_reuse_addr(state, hostaddr.buf, port)))
                session = smtp_connect_addr(dest, addr, port, why, sess_flags);
            if ((state->session = session) != 0) {
                session->state = state;
@@ -705,7 +854,7 @@ int     smtp_connect(SMTP_STATE *state)
                /* Don't count handshake errors towards the session limit. */
                state->final_server = (cpp[1] == 0 && next == 0);
                if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
-                   && smtp_helo(state, misc_flags) != 0) {
+                   && smtp_helo(state) != 0) {
                    if (vstream_ferror(session->stream) == 0
                        && vstream_feof(session->stream) == 0)
                        smtp_quit(state);
@@ -728,35 +877,35 @@ int     smtp_connect(SMTP_STATE *state)
     /*
      * We still need to deliver, bounce or defer some left-over recipients:
      * either mail loops or some backup mail server was unavailable.
-     * 
-     * Pay attention to what could be configuration problems, and pretend that
-     * these are recoverable rather than bouncing the mail.
-     * 
-     * In case of a "no error" indication we make up an excuse; this can happen
-     * when the fall-back relay was already tried via a cached connection, so
-     * that the address list scrubber left behind an empty list.
      */
     if (SMTP_RCPT_LEFT(state) > 0) {
+
+       /*
+        * In case of a "no error" indication we make up an excuse; this can
+        * happen when the fall-back relay was already tried via a cached
+        * connection, so that the address list scrubber left behind an empty
+        * list.
+        */
        if (smtp_errno == SMTP_ERR_NONE) {
            smtp_dsn_update(why, DSN_BY_LOCAL_MTA,
                            "4.3.0", 450, "450 Server unavailable",
                            "server unavailable or unable to receive mail");
            smtp_errno = SMTP_ERR_RETRY;
        }
-       switch (smtp_errno) {
 
-       default:
-           msg_panic("smtp_connect: bad error indication %d", smtp_errno);
-
-       case SMTP_ERR_LOOP:
-       case SMTP_ERR_FAIL:
+       /*
+        * Pay attention to what could be configuration problems, and pretend
+        * that these are recoverable rather than bouncing the mail.
+        */
+       else if (smtp_errno != SMTP_ERR_RETRY
+                && (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
 
            /*
             * The fall-back destination did not resolve as expected, or it
             * is refusing to talk to us, or mail for it loops back to us.
             */
            if (IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites)) {
-               msg_warn("%s configuration problem", VAR_FALLBACK_RELAY);
+               msg_warn("%s configuration problem", VAR_SMTP_FALLBACK);
                vstring_strcpy(why->status, "4.3.5");
                /* XXX Keep the diagnostic code and MTA. */
                smtp_errno = SMTP_ERR_RETRY;
@@ -781,36 +930,9 @@ int     smtp_connect(SMTP_STATE *state)
                state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
                                                 var_bestmx_transp,
                                                 request);
+               smtp_errno = 0;                 /* XXX */
                SMTP_RCPT_LEFT(state) = 0;      /* XXX */
-               break;
            }
-           /* FALLTHROUGH */
-
-       case SMTP_ERR_RETRY:
-
-           /*
-            * We still need to bounce or defer some left-over recipients:
-            * either mail loops or some mail server was unavailable.
-            * 
-            * XXX Unlike enhanced status codes, changing a 4xx into 5xx SMTP
-            * code is not simply a matter of changing the initial digit.
-            * What we're doing here is correct only under specific
-            * conditions, such as changing 450 into 550 or vice versa.
-            */
-           state->final_server = 1;            /* XXX */
-           if (smtp_errno == SMTP_ERR_RETRY)
-               STR(why->status)[0] = STR(why->dtext)[0] = '4'; /* XXX */
-           else
-               STR(why->status)[0] = STR(why->dtext)[0] = '5'; /* XXX */
-           why->dcode = atoi(STR(why->dtext)); /* XXX */
-           smtp_sess_fail(state, why);
-
-           /*
-            * Sanity check. Don't silently lose recipients.
-            */
-           smtp_rcpt_cleanup(state);
-           if (SMTP_RCPT_LEFT(state) > 0)
-               msg_panic("smtp_connect: left-over recipients");
        }
     }
 
@@ -820,6 +942,78 @@ int     smtp_connect(SMTP_STATE *state)
     if (HAVE_NEXTHOP_STATE(state))
        FREE_NEXTHOP_STATE(state);
     argv_free(sites);
+}
+
+/* smtp_connect - establish SMTP connection */
+
+int     smtp_connect(SMTP_STATE *state)
+{
+    DELIVER_REQUEST *request = state->request;
+    DSN_BUF *why = dsb_create();
+    char   *destination = request->nexthop;
+
+    /*
+     * All deliveries proceed along the same lines, whether they are over TCP
+     * or UNIX-domain sockets, and whether they use SMTP or LMTP: get a
+     * connection from the cache or create a new connection; deliver mail;
+     * update the connection cache or disconnect.
+     * 
+     * The major differences appear at a higher level: the expansion from
+     * destination to address list, and whether to stop before we reach the
+     * end of that list.
+     */
+
+    /*
+     * With LMTP we have direct-to-host delivery only. The destination may
+     * have multiple IP addresses.
+     */
+    if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
+       if (strncmp(destination, "unix:", 5) == 0) {
+           smtp_connect_local(state, destination + 5, why);
+       } else {
+           if (strncmp(destination, "inet:", 5) == 0)
+               destination += 5;
+           smtp_connect_remote(state, destination, why);
+       }
+    }
+
+    /*
+     * With SMTP we can have indirection via MX host lookup, as well as an
+     * optional fall-back relayhost that we must avoid when we are MX host.
+     * 
+     * XXX We don't add support for "unix:" or "inet:" prefixes in SMTP
+     * destinations, because that would break compatibility with existing
+     * Postfix configurations that have a host with such a name.
+     */
+    else {
+       smtp_connect_remote(state, destination, why);
+    }
+
+    /*
+     * We still need to bounce or defer some left-over recipients: either
+     * (SMTP) mail loops or some server was unavailable.
+     * 
+     * XXX Unlike enhanced status codes, changing a 4xx into 5xx SMTP code is
+     * not simply a matter of changing the initial digit. What we're doing
+     * here is correct only under specific conditions, such as changing 450
+     * into 550 or vice versa.
+     */
+    if (SMTP_RCPT_LEFT(state) > 0) {
+       state->final_server = 1;                /* XXX */
+       if (smtp_errno == SMTP_ERR_RETRY)
+           STR(why->status)[0] = STR(why->dtext)[0] = '4';     /* XXX */
+       else
+           STR(why->status)[0] = STR(why->dtext)[0] = '5';     /* XXX */
+       why->dcode = atoi(STR(why->dtext));     /* XXX */
+       smtp_sess_fail(state, why);
+
+       /*
+        * Sanity check. Don't silently lose recipients.
+        */
+       smtp_rcpt_cleanup(state);
+       if (SMTP_RCPT_LEFT(state) > 0)
+           msg_panic("smtp_connect: left-over recipients");
+    }
     dsb_free(why);
     return (state->status);
 }
index 9a880ab6a7b927207536a755827511c2518ecfbc..a48701ec0b8b38f3cd322f34a466d0a65e6201c7 100644 (file)
 /* Global library. */
 
 #include <dsn_buf.h>
+#include <mail_params.h>
 
 /* Application-specific. */
 
@@ -132,7 +133,7 @@ void    vsmtp_dsn_update(DSN_BUF *why, const char *mta_name,
 {
     dsb_formal(why, status, DSB_DEF_ACTION,
               mta_name ? DSB_MTYPE_DNS : DSB_MTYPE_NONE,
-              mta_name, DSB_DTYPE_SMTP, code, reply);
+              mta_name, var_procname, code, reply);
     vstring_vsprintf(why->reason, format, ap);
 }
 
@@ -144,5 +145,5 @@ void    smtp_dsn_formal(DSN_BUF *why, const char *mta_name,
 {
     dsb_formal(why, status, DSB_DEF_ACTION,
               mta_name ? DSB_MTYPE_DNS : DSB_MTYPE_NONE,
-              mta_name, DSB_DTYPE_SMTP, code, reply);
+              mta_name, var_procname, code, reply);
 }
diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c
new file mode 100644 (file)
index 0000000..021229c
--- /dev/null
@@ -0,0 +1,76 @@
+    static CONFIG_STR_TABLE smtp_str_table[] = {
+       VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
+       VAR_SMTP_FALLBACK, DEF_SMTP_FALLBACK, &var_fallback_relay, 0, 0,
+       VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
+       VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
+       VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
+       VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
+#ifdef USE_TLS
+       VAR_SMTP_SASL_TLS_OPTS, DEF_SMTP_SASL_TLS_OPTS, &var_smtp_sasl_tls_opts, 0, 0,
+#endif
+       VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
+       VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
+       VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
+       VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
+       VAR_SMTP_HOST_LOOKUP, DEF_SMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
+       VAR_SMTP_CACHE_DEST, DEF_SMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
+       VAR_SCACHE_SERVICE, DEF_SCACHE_SERVICE, &var_scache_service, 1, 0,
+       VAR_SMTP_EHLO_DIS_WORDS, DEF_SMTP_EHLO_DIS_WORDS, &var_smtp_ehlo_dis_words, 0, 0,
+       VAR_SMTP_EHLO_DIS_MAPS, DEF_SMTP_EHLO_DIS_MAPS, &var_smtp_ehlo_dis_maps, 0, 0,
+       VAR_SMTP_TLS_PER_SITE, DEF_SMTP_TLS_PER_SITE, &var_smtp_tls_per_site, 0, 0,
+       VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
+       VAR_SMTP_GENERIC_MAPS, DEF_SMTP_GENERIC_MAPS, &var_smtp_generic_maps, 0, 0,
+       VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
+       0,
+    };
+    static CONFIG_TIME_TABLE smtp_time_table[] = {
+       VAR_SMTP_CONN_TMOUT, DEF_SMTP_CONN_TMOUT, &var_smtp_conn_tmout, 0, 0,
+       VAR_SMTP_HELO_TMOUT, DEF_SMTP_HELO_TMOUT, &var_smtp_helo_tmout, 1, 0,
+       VAR_SMTP_XFWD_TMOUT, DEF_SMTP_XFWD_TMOUT, &var_smtp_xfwd_tmout, 1, 0,
+       VAR_SMTP_MAIL_TMOUT, DEF_SMTP_MAIL_TMOUT, &var_smtp_mail_tmout, 1, 0,
+       VAR_SMTP_RCPT_TMOUT, DEF_SMTP_RCPT_TMOUT, &var_smtp_rcpt_tmout, 1, 0,
+       VAR_SMTP_DATA0_TMOUT, DEF_SMTP_DATA0_TMOUT, &var_smtp_data0_tmout, 1, 0,
+       VAR_SMTP_DATA1_TMOUT, DEF_SMTP_DATA1_TMOUT, &var_smtp_data1_tmout, 1, 0,
+       VAR_SMTP_DATA2_TMOUT, DEF_SMTP_DATA2_TMOUT, &var_smtp_data2_tmout, 1, 0,
+       VAR_SMTP_RSET_TMOUT, DEF_SMTP_RSET_TMOUT, &var_smtp_rset_tmout, 1, 0,
+       VAR_SMTP_QUIT_TMOUT, DEF_SMTP_QUIT_TMOUT, &var_smtp_quit_tmout, 1, 0,
+       VAR_SMTP_PIX_THRESH, DEF_SMTP_PIX_THRESH, &var_smtp_pix_thresh, 0, 0,
+       VAR_SMTP_PIX_DELAY, DEF_SMTP_PIX_DELAY, &var_smtp_pix_delay, 1, 0,
+       VAR_SMTP_CACHE_CONNT, DEF_SMTP_CACHE_CONNT, &var_smtp_cache_conn, 1, 0,
+       VAR_SMTP_REUSE_TIME, DEF_SMTP_REUSE_TIME, &var_smtp_reuse_time, 1, 0,
+#ifdef USE_TLS
+       VAR_SMTP_STARTTLS_TMOUT, DEF_SMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
+#endif
+       VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0,
+       0,
+    };
+    static CONFIG_INT_TABLE smtp_int_table[] = {
+       VAR_SMTP_LINE_LIMIT, DEF_SMTP_LINE_LIMIT, &var_smtp_line_limit, 0, 0,
+       VAR_SMTP_MXADDR_LIMIT, DEF_SMTP_MXADDR_LIMIT, &var_smtp_mxaddr_limit, 0, 0,
+       VAR_SMTP_MXSESS_LIMIT, DEF_SMTP_MXSESS_LIMIT, &var_smtp_mxsess_limit, 0, 0,
+#ifdef USE_TLS
+       VAR_SMTP_TLS_SCERT_VD, DEF_SMTP_TLS_SCERT_VD, &var_smtp_tls_scert_vd, 0, 0,
+#endif
+       0,
+    };
+    static CONFIG_BOOL_TABLE smtp_bool_table[] = {
+       VAR_SMTP_SKIP_5XX, DEF_SMTP_SKIP_5XX, &var_smtp_skip_5xx_greeting,
+       VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err,
+       VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
+       VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
+       VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
+       VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+       VAR_SMTP_RAND_ADDR, DEF_SMTP_RAND_ADDR, &var_smtp_rand_addr,
+       VAR_SMTP_QUOTE_821_ENV, DEF_SMTP_QUOTE_821_ENV, &var_smtp_quote_821_env,
+       VAR_SMTP_DEFER_MXADDR, DEF_SMTP_DEFER_MXADDR, &var_smtp_defer_mxaddr,
+       VAR_SMTP_SEND_XFORWARD, DEF_SMTP_SEND_XFORWARD, &var_smtp_send_xforward,
+       VAR_SMTP_CACHE_DEMAND, DEF_SMTP_CACHE_DEMAND, &var_smtp_cache_demand,
+       VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
+       VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
+#ifdef USE_TLS
+       VAR_SMTP_TLS_ENFORCE_PN, DEF_SMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
+       VAR_SMTP_TLS_NOTEOFFER, DEF_SMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
+#endif
+       VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
+       0,
+    };
index 56429fcc8f2a16a145ad5346ed6d4aef4fe55cc6..c8adb4c4c4d35b8c1f2618fbfd95a519afe57c53 100644 (file)
@@ -2,13 +2,12 @@
 /* NAME
 /*     smtp_proto 3
 /* SUMMARY
-/*     client SMTP protocol
+/*     client SMTP/LMTP protocol
 /* SYNOPSIS
 /*     #include "smtp.h"
 /*
-/*     int     smtp_helo(state, misc_flags)
+/*     int     smtp_helo(state)
 /*     SMTP_STATE *state;
-/*     int     misc_flags;
 /*
 /*     int     smtp_xfer(state)
 /*     SMTP_STATE *state;
@@ -19,6 +18,7 @@
 /*     int     smtp_quit(state)
 /*     SMTP_STATE *state;
 /* DESCRIPTION
+/*     In the subsequent text, SMTP implies LMTP.
 /*     This module implements the client side of the SMTP protocol.
 /*
 /*     smtp_helo() performs the initial handshake with the SMTP server.
@@ -230,11 +230,11 @@ char   *xfer_request[SMTP_STATE_LAST] = {
     "QUIT command",
 };
 
-static int smtp_start_tls(SMTP_STATE *, int);
+static int smtp_start_tls(SMTP_STATE *);
 
 /* smtp_helo - perform initial handshake with SMTP server */
 
-int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
+int     smtp_helo(SMTP_STATE *state)
 {
     char   *myname = "smtp_helo";
     SMTP_SESSION *session = state->session;
@@ -267,7 +267,7 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
      * If not recursing after STARTTLS, examine the server greeting banner
      * and decide if we are going to send EHLO as the next command.
      */
-    if ((misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
+    if ((state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
 
        /*
         * Prepare for disaster.
@@ -275,7 +275,7 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
        smtp_timeout_setup(state->session->stream, var_smtp_helo_tmout);
        if ((except = vstream_setjmp(state->session->stream)) != 0)
            return (smtp_stream_except(state, except,
-                                   "receiving the initial SMTP greeting"));
+                                 "receiving the initial server greeting"));
 
        /*
         * Read and parse the server's SMTP greeting banner.
@@ -312,18 +312,22 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
        (void) mystrtok(&words, "- \t\n");
        for (n = 0; (word = mystrtok(&words, " \t\n")) != 0; n++) {
            if (n == 0 && strcasecmp(word, var_myhostname) == 0) {
-               if (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
+               if (state->misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
                    msg_warn("host %s greeted me with my own hostname %s",
                             session->namaddr, var_myhostname);
            } else if (strcasecmp(word, "ESMTP") == 0)
                session->features |= SMTP_FEATURE_ESMTP;
        }
-       if (var_smtp_always_ehlo
-           && (session->features & SMTP_FEATURE_MAYBEPIX) == 0)
+       if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+           if (var_smtp_always_ehlo
+               && (session->features & SMTP_FEATURE_MAYBEPIX) == 0)
+               session->features |= SMTP_FEATURE_ESMTP;
+           if (var_smtp_never_ehlo
+               || (session->features & SMTP_FEATURE_MAYBEPIX) != 0)
+               session->features &= ~SMTP_FEATURE_ESMTP;
+       } else {
            session->features |= SMTP_FEATURE_ESMTP;
-       if (var_smtp_never_ehlo
-           || (session->features & SMTP_FEATURE_MAYBEPIX) != 0)
-           session->features &= ~SMTP_FEATURE_ESMTP;
+       }
     }
 
     /*
@@ -338,19 +342,28 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
      * Return the compliment. Fall back to SMTP if our ESMTP recognition
      * heuristic failed.
      */
-    if (session->features & SMTP_FEATURE_ESMTP) {
-       smtp_chat_cmd(session, "EHLO %s", var_smtp_helo_name);
-       if ((resp = smtp_chat_resp(session))->code / 100 != 2)
-           session->features &= ~SMTP_FEATURE_ESMTP;
-    }
-    if ((session->features & SMTP_FEATURE_ESMTP) == 0) {
-       smtp_chat_cmd(session, "HELO %s", var_smtp_helo_name);
+    if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+       if (session->features & SMTP_FEATURE_ESMTP) {
+           smtp_chat_cmd(session, "EHLO %s", var_smtp_helo_name);
+           if ((resp = smtp_chat_resp(session))->code / 100 != 2)
+               session->features &= ~SMTP_FEATURE_ESMTP;
+       }
+       if ((session->features & SMTP_FEATURE_ESMTP) == 0) {
+           smtp_chat_cmd(session, "HELO %s", var_smtp_helo_name);
+           if ((resp = smtp_chat_resp(session))->code / 100 != 2)
+               return (smtp_site_fail(state, session->host, resp,
+                                      "host %s refused to talk to me: %s",
+                                      session->namaddr,
+                                      translit(resp->str, "\n", " ")));
+           return (0);
+       }
+    } else {
+       smtp_chat_cmd(session, "LHLO %s", var_smtp_helo_name);
        if ((resp = smtp_chat_resp(session))->code / 100 != 2)
            return (smtp_site_fail(state, session->host, resp,
                                   "host %s refused to talk to me: %s",
                                   session->namaddr,
                                   translit(resp->str, "\n", " ")));
-       return (0);
     }
 
     /*
@@ -382,7 +395,7 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
                    myfree(session->helo);
                session->helo = lowercase(mystrdup(word));
                if (strcasecmp(word, var_myhostname) == 0
-                   && (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) != 0) {
+                && (state->misc_flags & SMTP_MISC_FLAG_LOOP_DETECT) != 0) {
                    msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
                             session->namaddrport, var_myhostname);
                    if (session->features & SMTP_FEATURE_BEST_MX)
@@ -483,7 +496,7 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
     /*
      * Skip this part if we already sent STARTTLS.
      */
-    if ((misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
+    if ((state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
 
        /*
         * Optionally log unused STARTTLS opportunities.
@@ -528,8 +541,8 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
                }
 #endif
                session->features = saved_features;
-               misc_flags |= SMTP_MISC_FLAG_IN_STARTTLS;
-               return (smtp_start_tls(state, misc_flags));
+               state->misc_flags |= SMTP_MISC_FLAG_IN_STARTTLS;
+               return (smtp_start_tls(state));
            }
 
            /*
@@ -587,7 +600,7 @@ int     smtp_helo(SMTP_STATE *state, NOCLOBBER int misc_flags)
 
 /* smtp_start_tls - turn on TLS and recurse into the HELO dialog */
 
-static int smtp_start_tls(SMTP_STATE *state, int misc_flags)
+static int smtp_start_tls(SMTP_STATE *state)
 {
     SMTP_SESSION *session = state->session;
     VSTRING *serverid;
@@ -644,7 +657,7 @@ static int smtp_start_tls(SMTP_STATE *state, int misc_flags)
      * At this point we have to re-negotiate the "EHLO" to reget the
      * feature-list.
      */
-    return (smtp_helo(state, misc_flags));
+    return (smtp_helo(state));
 }
 
 #endif
@@ -848,11 +861,13 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
     SMTP_RESP *resp;
     RECIPIENT *rcpt;
     VSTRING *next_command = vstring_alloc(100);
+    int    *NOCLOBBER survivors = 0;
     NOCLOBBER int next_state;
     NOCLOBBER int next_rcpt;
     NOCLOBBER int send_rcpt;
     NOCLOBBER int recv_rcpt;
     NOCLOBBER int nrcpt;
+    NOCLOBBER int recv_done;
     int     except;
     int     rec_type;
     NOCLOBBER int prev_type = 0;
@@ -881,6 +896,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
 
 #define RETURN(x) do { \
        vstring_free(next_command); \
+       if (survivors) \
+           myfree((char *) survivors); \
        if (session->mime_state) \
            session->mime_state = mime_state_free(session->mime_state); \
        return (x); \
@@ -929,7 +946,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
      * SMTP dialog with RSET and QUIT.
      */
     nrcpt = 0;
-    next_rcpt = send_rcpt = recv_rcpt = 0;
+    next_rcpt = send_rcpt = recv_rcpt = recv_done = 0;
     mail_from_rejected = 0;
 
     /*
@@ -1277,6 +1294,13 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
 #endif
                        rcpt = request->rcpt_list.info + recv_rcpt;
                        if (resp->code / 100 == 2) {
+                           if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
+                               if (survivors == 0)
+                                   survivors = (int *)
+                                       mymalloc(request->rcpt_list.len
+                                                * sizeof(int));
+                               survivors[nrcpt] = recv_rcpt;
+                           }
                            ++nrcpt;
                            /* If trace-only, mark the recipient done. */
                            if (DEL_REQ_TRACE_ONLY(request->flags)) {
@@ -1327,24 +1351,53 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
                     */
                case SMTP_STATE_DOT:
                    GETTIMEOFDAY(&request->msg_stats.deliver_done);
-                   if (nrcpt > 0) {
-                       if (resp->code / 100 != 2) {
-                           smtp_mesg_fail(state, session->host, resp,
+                   if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+                       if (nrcpt > 0) {
+                           if (resp->code / 100 != 2) {
+                               smtp_mesg_fail(state, session->host, resp,
                                        "host %s said: %s (in reply to %s)",
-                                          session->namaddr,
-                                          translit(resp->str, "\n", " "),
-                                          xfer_request[SMTP_STATE_DOT]);
-                       } else {
-                           for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
-                               rcpt = request->rcpt_list.info + nrcpt;
-                               if (!SMTP_RCPT_ISMARKED(rcpt)) {
-                                   translit(resp->str, "\n", " ");
-                                   smtp_rcpt_done(state, resp, rcpt);
+                                              session->namaddr,
+                                            translit(resp->str, "\n", " "),
+                                              xfer_request[SMTP_STATE_DOT]);
+                           } else {
+                               for (nrcpt = 0; nrcpt < recv_rcpt; nrcpt++) {
+                                   rcpt = request->rcpt_list.info + nrcpt;
+                                   if (!SMTP_RCPT_ISMARKED(rcpt)) {
+                                       translit(resp->str, "\n", " ");
+                                       smtp_rcpt_done(state, resp, rcpt);
+                                   }
                                }
                            }
                        }
                    }
 
+                   /*
+                    * With LMTP we have one response per accepted RCPT TO
+                    * command. Stay in the SMTP_STATE_DOT state until we
+                    * have collected all responses.
+                    */
+                   else {
+                       if (nrcpt > 0) {
+                           rcpt = request->rcpt_list.info
+                               + survivors[recv_done++];
+                           if (resp->code / 100 != 2) {
+                               smtp_rcpt_fail(state, rcpt, session->host, resp,
+                                       "host %s said: %s (in reply to %s)",
+                                              session->namaddr,
+                                            translit(resp->str, "\n", " "),
+                                              xfer_request[SMTP_STATE_DOT]);
+                           } else {
+                               translit(resp->str, "\n", " ");
+                               smtp_rcpt_done(state, resp, rcpt);
+                           }
+                       }
+                       if (msg_verbose)
+                           msg_info("%s: got %d of %d end-of-data replies",
+                                    myname, recv_done, nrcpt);
+                       if (recv_done < nrcpt)
+                           break;
+                   }
+
                    /*
                     * XXX Do not change the connection caching state here,
                     * even if the connection caching timer expired between
index 6d122421d7a9ce4f9f5e3429d159bd4f857b6abc..3cb09749562adbe2da65c907ad2b06372b474675 100644 (file)
@@ -18,7 +18,7 @@
 /*
 /*     SMTP_SESSION *smtp_reuse_addr(state, addr, port)
 /*     SMTP_STATE *state;
-/*     DNS_RR  *addr;
+/*     const char *addr;
 /*     unsigned port;
 /* DESCRIPTION
 /*     This module implements the SMTP client specific interface to
@@ -46,7 +46,7 @@
 /* .IP domain
 /*     Domain name or bare numerical address.
 /* .IP addr
-/*     The remote server name and address.
+/*     The remote server address as printable text.
 /* .IP port
 /*     The remote server port, network byte order.
 /* LICENSE
@@ -221,9 +221,9 @@ SMTP_SESSION *smtp_reuse_domain(SMTP_STATE *state, int lookup_mx,
 
 /* smtp_reuse_addr - reuse session cached under numerical address */
 
-SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, DNS_RR *addr, unsigned port)
+SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, const char *addr,
+                                     unsigned port)
 {
-    MAI_HOSTADDR_STR hostaddr;
     SMTP_SESSION *session;
     int     fd;
 
@@ -234,10 +234,8 @@ SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, DNS_RR *addr, unsigned port)
      * Note: if the label needs to be made more specific (with e.g., SASL login
      * information), just append the text with vstring_sprintf_append().
      */
-    if (dns_rr_to_pa(addr, &hostaddr) == 0)
-       return (0);
     vstring_sprintf(state->endp_label, SMTP_SCACHE_LABEL(NO_MX_LOOKUP),
-                   state->service, hostaddr.buf, ntohs(port));
+                   state->service, addr, ntohs(port));
     if ((fd = scache_find_endp(smtp_scache, STR(state->endp_label),
                               state->endp_prop)) < 0)
        return (0);
index 9018c9fc751b2b04fb17a3c60742aeec43795ca7..bf005c043c41a33c4172313ebd8b1f18976e6879 100644 (file)
@@ -8,17 +8,12 @@
 /* DESCRIPTION
 /* .nf
 
- /*
-  * DNS library.
-  */
-#include <dns.h>
-
  /*
   * Internal interfaces.
   */
 extern void smtp_save_session(SMTP_STATE *);
 extern SMTP_SESSION *smtp_reuse_domain(SMTP_STATE *, int, const char *, unsigned);
-extern SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *, DNS_RR *, unsigned);
+extern SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *, const char *, unsigned);
 
 /* LICENSE
 /* .ad
index 81a931d0340acedfb69ceb200fa27bc764ad379a..8e78942d241956bc4bed634bc86a10580a9b638a 100644 (file)
@@ -331,7 +331,8 @@ int     smtp_sasl_passwd_lookup(SMTP_SESSION *session)
      * but didn't canonicalize the TCP port, and did not append the port to
      * the MX hostname.
      */
-    if ((var_smtp_sender_auth && state->request->sender[0]
+    if (((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0
+        && var_smtp_sender_auth && state->request->sender[0]
         && (value = mail_addr_find(smtp_sasl_passwd_map,
                                 state->request->sender, (char **) 0)) != 0)
        || (value = maps_find(smtp_sasl_passwd_map, session->host, 0)) != 0
@@ -460,7 +461,7 @@ void    smtp_sasl_start(SMTP_SESSION *session, const char *sasl_opts_name,
 #define NULL_SERVER_ADDR       ((char *) 0)
 #define NULL_CLIENT_ADDR       ((char *) 0)
 
-    if (SASL_CLIENT_NEW("smtp", session->host,
+    if (SASL_CLIENT_NEW(var_procname, session->host,
                        NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
                        session->sasl_callbacks, NULL_SECFLAGS,
                        (sasl_conn_t **) &session->sasl_conn) != SASL_OK)
index bfcea38184441e2faa3640e8fda4cd3114c6a3c7..9f364b6710582c958e126c3b8fa55a30543153c2 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <mymalloc.h>
 #include <vstring.h>
+#include <msg.h>
 
 /* Global library. */
 
@@ -54,6 +55,7 @@ SMTP_STATE *smtp_state_alloc(void)
 {
     SMTP_STATE *state = (SMTP_STATE *) mymalloc(sizeof(*state));
 
+    state->misc_flags = 0;
     state->src = 0;
     state->service = 0;
     state->request = 0;
@@ -76,6 +78,23 @@ SMTP_STATE *smtp_state_alloc(void)
     }
     state->dsn_reason = 0;
 
+    /*
+     * The process name, "smtp" or "lmtp", is also used as the DSN server
+     * reply type and for SASL service information lookup. Since all three
+     * external representations are identical there is no reason to transform
+     * from some external form X to some Postfix-specific canonical internal
+     * form, and then to transform from the internal form to external forms Y
+     * and Z.
+     */
+    if (strcmp(var_procname, "lmtp") == 0) {
+       state->misc_flags |= SMTP_MISC_FLAG_USE_LMTP;
+    } else if (strcmp(var_procname, "smtp") == 0) {
+       /* void */
+    } else {
+       msg_fatal("unexpected process name \"%s\" - "
+                 "specify \"smtp\" or \"lmtp\"",
+                 var_procname);
+    }
     return (state);
 }
 
index 6517698b8acde977e1aca694b61bddb5a2b3cabe..55ee99b25db5201fcafedef3bd1663d3fb815792 100644 (file)
@@ -246,6 +246,11 @@ int     main(int argc, char **argv)
     const char *protocols = INET_PROTO_NAME_ALL;
     INET_PROTO_INFO *proto_info;
 
+    /*
+     * Fix 20051207.
+     */
+    signal(SIGPIPE, SIG_IGN);
+
     /*
      * Initialize diagnostics.
      */
index 15140378cf1ea9ab992fd5f2264e91ccd3932a1d..b5f218874cb56712360884db9db5f6b9d1b53341 100644 (file)
@@ -790,6 +790,11 @@ int     main(int argc, char **argv)
     const char *protocols = INET_PROTO_NAME_ALL;
     INET_PROTO_INFO *proto_info;
 
+    /*
+     * Fix 20051207.
+     */
+    signal(SIGPIPE, SIG_IGN);
+
     /*
      * Initialize diagnostics.
      */
index 153836e0da624ab4175919fce2063b38f864169e..8e3cb4e08bd795af6499d14b0c0acd12a219b657 100644 (file)
@@ -570,12 +570,10 @@ attr_clnt.o: attr.h
 attr_clnt.o: attr_clnt.c
 attr_clnt.o: attr_clnt.h
 attr_clnt.o: auto_clnt.h
-attr_clnt.o: connect.h
 attr_clnt.o: htable.h
 attr_clnt.o: iostuff.h
 attr_clnt.o: msg.h
 attr_clnt.o: mymalloc.h
-attr_clnt.o: split_at.h
 attr_clnt.o: sys_defs.h
 attr_clnt.o: vbuf.h
 attr_clnt.o: vstream.h
@@ -642,10 +640,12 @@ attr_scan_plain.o: vstream.h
 attr_scan_plain.o: vstring.h
 auto_clnt.o: auto_clnt.c
 auto_clnt.o: auto_clnt.h
+auto_clnt.o: connect.h
 auto_clnt.o: events.h
 auto_clnt.o: iostuff.h
 auto_clnt.o: msg.h
 auto_clnt.o: mymalloc.h
+auto_clnt.o: split_at.h
 auto_clnt.o: sys_defs.h
 auto_clnt.o: vbuf.h
 auto_clnt.o: vstream.h
index 130615b9b350a119a0e0ceabca29b333d521256c..87aac757478ccda3eed5d521f05ec14999bd5d37 100644 (file)
 /*     This module implements a client for a simple attribute-based
 /*     protocol. The default protocol is described in attr_scan_plain(3).
 /*
-/*     attr_clnt_create() creates a client handle. The server
-/*     argument specifies "transport:servername" where transport is
-/*     currently limited to "inet" or "unix", and servername has the
-/*     form "host:port", "private/servicename" or "public/servicename".
-/*     The timeout parameter limits the time for sending or receiving
-/*     a reply, max_idle specifies how long an idle connection is
-/*     kept open, and the max_ttl parameter bounds the time that a
-/*     connection is kept open.
-/*     Specify zero to disable a max_idle or max_ttl limit.
+/*     attr_clnt_create() creates a client handle. See auto_clnt(3) for
+/*     a description of the arguments.
 /*
 /*     attr_clnt_request() sends the specified request attributes and
 /*     receives a reply. The reply argument specifies a name-value table.
 #include <sys_defs.h>
 #include <unistd.h>
 #include <errno.h>
-#include <string.h>
 
 /* Utility library. */
 
 #include <msg.h>
 #include <mymalloc.h>
-#include <split_at.h>
 #include <vstream.h>
-#include <connect.h>
 #include <htable.h>
 #include <attr.h>
+#include <iostuff.h>
 #include <auto_clnt.h>
 #include <attr_clnt.h>
 
 
 struct ATTR_CLNT {
     AUTO_CLNT *auto_clnt;
-    int     (*connect) (const char *, int, int);
-    char   *endpoint;
-    int     timeout;
     ATTR_CLNT_PRINT_FN print;
     ATTR_CLNT_SCAN_FN scan;
 };
 
-/* attr_clnt_connect - connect to server */
-
-static VSTREAM *attr_clnt_connect(void *context)
-{
-    const char *myname = "attr_clnt_connect";
-    ATTR_CLNT *client = (ATTR_CLNT *) context;
-    VSTREAM *fp;
-    int     fd;
-
-    fd = client->connect(client->endpoint, BLOCKING, client->timeout);
-    if (fd < 0) {
-       msg_warn("connect to %s: %m", client->endpoint);
-       return (0);
-    } else {
-       if (msg_verbose)
-           msg_info("%s: connected to %s", myname, client->endpoint);
-       fp = vstream_fdopen(fd, O_RDWR);
-       vstream_control(fp, VSTREAM_CTL_PATH, client->endpoint,
-                       VSTREAM_CTL_TIMEOUT, client->timeout,
-                       VSTREAM_CTL_END);
-       return (fp);
-    }
-}
-
 /* attr_clnt_free - destroy attribute client */
 
 void    attr_clnt_free(ATTR_CLNT *client)
 {
-    myfree(client->endpoint);
     auto_clnt_free(client->auto_clnt);
     myfree((char *) client);
 }
@@ -146,34 +109,12 @@ void    attr_clnt_free(ATTR_CLNT *client)
 ATTR_CLNT *attr_clnt_create(const char *service, int timeout,
                                    int max_idle, int max_ttl)
 {
-    const char *myname = "attr_clnt_create";
-    char   *transport = mystrdup(service);
-    char   *endpoint;
     ATTR_CLNT *client;
 
-    if ((endpoint = split_at(transport, ':')) == 0
-       || *endpoint == 0 || *transport == 0)
-       msg_fatal("need service transport:endpoint instead of \"%s\"", service);
-    if (msg_verbose)
-       msg_info("%s: transport=%s endpoint=%s", myname, transport, endpoint);
-
     client = (ATTR_CLNT *) mymalloc(sizeof(*client));
+    client->auto_clnt = auto_clnt_create(service, timeout, max_idle, max_ttl);
     client->scan = attr_vscan_plain;
     client->print = attr_vprint_plain;
-    client->endpoint = mystrdup(endpoint);
-    client->timeout = timeout;
-    if (strcmp(transport, "inet") == 0) {
-       client->connect = inet_connect;
-    } else if (strcmp(transport, "local") == 0) {
-       client->connect = LOCAL_CONNECT;
-    } else if (strcmp(transport, "unix") == 0) {
-       client->connect = unix_connect;
-    } else {
-       msg_fatal("invalid attribute transport name: %s", service);
-    }
-    client->auto_clnt = auto_clnt_create(max_idle, max_ttl,
-                                        attr_clnt_connect, (void *) client);
-    myfree(transport);
     return (client);
 }
 
@@ -249,7 +190,7 @@ int     attr_clnt_request(ATTR_CLNT *client, int send_flags,...)
        if (++count >= 2
            || msg_verbose
            || (errno && errno != EPIPE && errno != ENOENT && errno != ECONNRESET))
-           msg_warn("problem talking to server %s: %m", client->endpoint);
+           msg_warn("problem talking to server %s: %m", VSTREAM_PATH(stream));
        if (count >= 2)
            return (-1);
        sleep(1);                               /* XXX make configurable */
index 6bd6e2eb8e63fda6d7e2c1339a1c7446069d6f66..c608c6c283ec6783deff8360fc08ff149c87c212 100644 (file)
@@ -6,11 +6,11 @@
 /* SYNOPSIS
 /*     #include <auto_clnt.h>
 /*
-/*     AUTO_CLNT *auto_clnt_create(max_idle, max_ttl, open_action, context)
+/*     AUTO_CLNT *auto_clnt_create(service, timeout, max_idle, max_ttl)
+/*     const char *service;
+/*     int     timeout;
 /*     int     max_idle;
 /*     int     max_ttl;
-/*     VSTREAM *(open_action)(void *context)
-/*     void    *context;
 /*
 /*     VSTREAM *auto_clnt_access(auto_clnt)
 /*     AUTO_CLNT *auto_clnt;
 /*     that disconnect after a configurable time to live,
 /*     and that transparently handle most server-initiated disconnects.
 /*
+/*     This module tries each operation only a limited number of
+/*     times and then reports an error.  This is unlike the
+/*     clnt_stream(3) module which will retry forever, so that
+/*     the application never experiences an error.
+/*
 /*     auto_clnt_create() instantiates a client endpoint.
 /*
 /*     auto_clnt_access() returns an open stream to the service specified
 /*     auto_clnt_free() destroys of the specified client endpoint.
 /*
 /*     Arguments:
+/* .IP service
+/*     The service argument specifies "transport:servername" where
+/*     transport is currently limited to one of the following:
+/* .RS
+/* .IP inet
+/*     servername has the form "host:port".
+/* .IP unix
+/*     servername has the form "private/servicename" or
+/*     "public/servicename".
+/* .RE
+/* .IP timeout
+/*     The time limit for sending, receiving, or for connecting
+/*     to a server. Specify a value <=0 to disable the time limit.
 /* .IP max_idle
-/*     Idle time after which the client disconnects. Specify 0 to disable
-/*     the limit.
+/*     Idle time after which the client disconnects. Specify 0 to
+/*     disable the limit.
 /* .IP max_ttl
 /*     Upper bound on the time that a connection is allowed to persist.
 /*     Specify 0 to disable the limit.
@@ -66,6 +84,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <string.h>
 
 /* Utility library. */
 
@@ -74,6 +93,8 @@
 #include <vstream.h>
 #include <events.h>
 #include <iostuff.h>
+#include <connect.h>
+#include <split_at.h>
 #include <auto_clnt.h>
 
 /* Application-specific. */
   */
 struct AUTO_CLNT {
     VSTREAM *vstream;                  /* buffered I/O */
+    char   *endpoint;                  /* host:port or pathname */
+    int     timeout;                   /* I/O time limit */
     int     max_idle;                  /* time before client disconnect */
     int     max_ttl;                   /* time before client disconnect */
-    VSTREAM *(*open_action) (void *);  /* callback */
-    void   *context;                   /* callback context */
+    int     (*connect) (const char *, int, int);       /* unix, local, inet */
 };
 
 static void auto_clnt_close(AUTO_CLNT *);
@@ -132,6 +154,8 @@ static void auto_clnt_ttl_event(int event, char *context)
 
 static void auto_clnt_open(AUTO_CLNT *auto_clnt)
 {
+    const char *myname = "auto_clnt_open";
+    int     fd;
 
     /*
      * Sanity check.
@@ -148,8 +172,18 @@ static void auto_clnt_open(AUTO_CLNT *auto_clnt)
      * connection is not idle. This is to prevent one client from clinging on
      * to a server forever.
      */
-    auto_clnt->vstream =
-       auto_clnt->open_action(auto_clnt->context);
+    fd = auto_clnt->connect(auto_clnt->endpoint, BLOCKING, auto_clnt->timeout);
+    if (fd < 0) {
+       msg_warn("connect to %s: %m", auto_clnt->endpoint);
+    } else {
+       if (msg_verbose)
+           msg_info("%s: connected to %s", myname, auto_clnt->endpoint);
+       auto_clnt->vstream = vstream_fdopen(fd, O_RDWR);
+       vstream_control(auto_clnt->vstream,
+                       VSTREAM_CTL_PATH, auto_clnt->endpoint,
+                       VSTREAM_CTL_TIMEOUT, auto_clnt->timeout,
+                       VSTREAM_CTL_END);
+    }
 
     if (auto_clnt->vstream != 0) {
        close_on_exec(vstream_fileno(auto_clnt->vstream), CLOSE_ON_EXEC);
@@ -168,18 +202,20 @@ static void auto_clnt_open(AUTO_CLNT *auto_clnt)
 
 static void auto_clnt_close(AUTO_CLNT *auto_clnt)
 {
+    const char *myname = "auto_clnt_close";
 
     /*
      * Sanity check.
      */
     if (auto_clnt->vstream == 0)
-       msg_panic("auto_clnt_close: stream is closed");
+       msg_panic("%s: stream is closed", myname);
 
     /*
      * Be sure to disable read and timer events.
      */
     if (msg_verbose)
-       msg_info("%s stream disconnect", VSTREAM_PATH(auto_clnt->vstream));
+       msg_info("%s: disconnect %s stream",
+                myname, VSTREAM_PATH(auto_clnt->vstream));
     event_disable_readwrite(vstream_fileno(auto_clnt->vstream));
     event_cancel_timer(auto_clnt_event, (char *) auto_clnt);
     event_cancel_timer(auto_clnt_ttl_event, (char *) auto_clnt);
@@ -219,22 +255,41 @@ VSTREAM *auto_clnt_access(AUTO_CLNT *auto_clnt)
     return (auto_clnt->vstream);
 }
 
-/* auto_clnt_create - create client stream connection */
+/* auto_clnt_create - create client stream object */
 
-AUTO_CLNT *auto_clnt_create(int max_idle, int max_ttl,
-                      VSTREAM *(*open_action) (void *), void *context)
+AUTO_CLNT *auto_clnt_create(const char *service, int timeout,
+                                   int max_idle, int max_ttl)
 {
+    const char *myname = "auto_clnt_create";
+    char   *transport = mystrdup(service);
+    char   *endpoint;
     AUTO_CLNT *auto_clnt;
 
     /*
      * Don't open the stream until the caller needs it.
      */
+    if ((endpoint = split_at(transport, ':')) == 0
+       || *endpoint == 0 || *transport == 0)
+       msg_fatal("need service transport:endpoint instead of \"%s\"", service);
+    if (msg_verbose)
+       msg_info("%s: transport=%s endpoint=%s", myname, transport, endpoint);
     auto_clnt = (AUTO_CLNT *) mymalloc(sizeof(*auto_clnt));
     auto_clnt->vstream = 0;
+    auto_clnt->endpoint = mystrdup(endpoint);
+    auto_clnt->timeout = timeout;
     auto_clnt->max_idle = max_idle;
     auto_clnt->max_ttl = max_ttl;
-    auto_clnt->open_action = open_action;
-    auto_clnt->context = context;
+    if (strcmp(transport, "inet") == 0) {
+       auto_clnt->connect = inet_connect;
+    } else if (strcmp(transport, "local") == 0) {
+       auto_clnt->connect = LOCAL_CONNECT;
+    } else if (strcmp(transport, "unix") == 0) {
+       auto_clnt->connect = unix_connect;
+    } else {
+       msg_fatal("invalid transport name: %s in service: %s",
+                 transport, service);
+    }
+    myfree(transport);
     return (auto_clnt);
 }
 
@@ -244,5 +299,6 @@ void    auto_clnt_free(AUTO_CLNT *auto_clnt)
 {
     if (auto_clnt->vstream)
        auto_clnt_close(auto_clnt);
+    myfree(auto_clnt->endpoint);
     myfree((char *) auto_clnt);
 }
index a4aaec21d664af3a6cf7f28bf215d7aae4d2b777..458c5f9371d8d226c5e237075787ad817183483f 100644 (file)
@@ -21,7 +21,7 @@
   */
 typedef struct AUTO_CLNT AUTO_CLNT;
 
-extern AUTO_CLNT *auto_clnt_create(int, int, VSTREAM *(*) (void *), void *);
+extern AUTO_CLNT *auto_clnt_create(const char *, int, int, int);
 extern VSTREAM *auto_clnt_access(AUTO_CLNT *);
 extern void auto_clnt_recover(AUTO_CLNT *);
 extern void auto_clnt_free(AUTO_CLNT *);
index 5ae4525431d76354ae2bfad8ad362e17f469ed00..402befb9085086beea2899f297681af51c6d20ef 100644 (file)
@@ -4,7 +4,7 @@
 /* SUMMARY
 /*     connect to UNIX-domain listener
 /* SYNOPSIS
-/*     #include <unix_connect.h>
+/*     #include <connect.h>
 /*
 /*     int     unix_connect(addr, block_mode, timeout)
 /*     const char *addr;