]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.0.16-20030914
authorWietse Venema <wietse@porcupine.org>
Tue, 12 Aug 2003 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:29:06 +0000 (06:29 +0000)
75 files changed:
postfix/HISTORY
postfix/README_FILES/LDAP_README
postfix/README_FILES/SMTPD_PROXY_README
postfix/RELEASE_NOTES
postfix/conf/canonical
postfix/conf/main.cf
postfix/conf/master.cf
postfix/conf/sample-auth.cf
postfix/conf/sample-filter.cf
postfix/conf/sample-ldap.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-smtpd.cf
postfix/conf/virtual
postfix/examples/smtpd-policy/smtpd-policy.pl
postfix/html/canonical.5.html
postfix/html/cleanup.8.html
postfix/html/faq.html
postfix/html/lmtp.8.html
postfix/html/local.8.html
postfix/html/postalias.1.html
postfix/html/sendmail.1.html
postfix/html/smtpd.8.html
postfix/html/uce.html
postfix/html/virtual.5.html
postfix/man/man1/postalias.1
postfix/man/man1/smtp-sink.1
postfix/man/man5/canonical.5
postfix/man/man5/virtual.5
postfix/man/man8/cleanup.8
postfix/man/man8/local.8
postfix/man/man8/smtpd.8
postfix/mantools/man2html
postfix/proto/access
postfix/proto/canonical
postfix/proto/virtual
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup_message.c
postfix/src/global/mail_params.h
postfix/src/global/mime_state.c
postfix/src/global/pipe_command.c
postfix/src/global/post_mail.c
postfix/src/lmtp/Makefile.in
postfix/src/lmtp/lmtp.c
postfix/src/lmtp/lmtp.h
postfix/src/lmtp/lmtp_connect.c
postfix/src/lmtp/lmtp_proto.c
postfix/src/lmtp/lmtp_sasl_glue.c
postfix/src/lmtp/lmtp_state.c
postfix/src/local/local.c
postfix/src/postalias/postalias.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpstone/Makefile.in
postfix/src/smtpstone/qmqp-source.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/smtpstone/smtp-source.c
postfix/src/trivial-rewrite/resolve.c
postfix/src/util/Makefile.in
postfix/src/util/clean_env.c
postfix/src/util/dict_ldap.c
postfix/src/util/file_limit.c
postfix/src/util/inet_connect.c
postfix/src/util/inet_listen.c
postfix/src/util/msg_syslog.c
postfix/src/util/sane_accept.c
postfix/src/util/sane_connect.c [new file with mode: 0644]
postfix/src/util/sane_connect.h [new file with mode: 0644]
postfix/src/util/sys_defs.h
postfix/src/util/timed_connect.c
postfix/src/util/timed_read.c
postfix/src/util/timed_write.c
postfix/src/util/unix_connect.c

index ae2d125b8f65f682d735bfe70ac974e250d05203..e75da34935f1a0afd3841fcc2e17fd6905ae6f88 100644 (file)
@@ -8437,14 +8437,121 @@ Apologies for any names omitted.
        when it is given a non-existent command-line macro name.
        File:  pipe/pipe.c.
 
+20030810
+
+       Bugfix: dict_ldap had a few harmless memory leaks.  By
+       Liviu Daia.  File: util/dict_ldap.c.
+
+       Feature: support for LDAP URLs in the LDAP parameter
+       "server_host", if Postfix is linked against OpenLDAP.  This
+       allows Postfix to connect to LDAP SSL sources.  By Liviu
+       Daia.  File: util/dict_ldap.c.
+
+
 20030811
 
        Cleanup: produce a warning when host:port specifies a badly
        formatted numerical port.  Files:  util/find_inet.c,
        smtp/smtp_connect.c, lmtp/lmtp_connect.c.
 
+20030822
+
+       Feature: the export_environment and import_environment
+       parameters now accept name=value information that will be
+       entered into the new environment. File: util/clean_env.c.
+
+20030823
+
+       Feature: smtpd_sasl_exceptions_networks parameter to prevent
+       Postfix from offering AUTH  to clients that match the listed
+       networks. Based on code by Ben Rosengart, Panix. Files:
+       conf/sample-auth.cf, smtpd/smtpd.c.
+
+20030905
+
+       Workaround: Solaris 8 select() claims that a non-blocking
+       socket is readable and then read() fails with EAGAIN. Files:
+       util/timed_read.c and as precautionary measure,
+       util/timed_write.c.
+
+       Bugfix: dict_register() should not be called from dict_open()
+       in dict_mysql and dict_pgsql.  Liviu Daia.  Files:
+       util/dict_mysql.c, util/dict_pgsql.c.
+
+       Feature: LDAP parameters can now be specified in external
+       files.  This makes it possible to securely store bind
+       passwords for plain auth outside of main.cf (which is world
+       readable).  By Liviu Daia, based on a suggestion by Victor
+       Duchovni and Lamont Jones.  File: util/dict_ldap.c.
+
+       Feature: STARTTLS option for LDAP, if Postfix is linked
+       against OpenLDAP.  By Liviu Daia, amended by Victor Duchovni.
+       File:  util/dict_ldap.c.
+
+       Cleanup: connections to LDAP sources are now postponed
+       until they are actually needed.  By Liviu Daia.  File:
+       util/dict_ldap.c.
+
+20030908
+
+       The 20030905 workaround triggers too many warnings. TCP
+       sockets are back to blocking, and keepalives are turned on
+       to kill off dead sockets, as suggested by Leandro Santi.
+       Files: master/{single,multi}_server.c, smtpd/smtpd.c,
+       util/sys_defs.h.
+
+20030909
+
+       Bugfix: the LMTP session caching code had problems with
+       SASL authentication after the first connection, and pipelining
+       was working poorly.  Fix by Victor Duchovni, Morgan Stanley.
+       Files: lmtp/lmtp.c, lmtp/lmtp_proto.c.
+
+20030913
+
+       Safety: set-gid commands don't trust TZ.  File: msg_syslog.c.
+
+20030914
+
+       Address extension propagation wasn't documented enough when
+       it was added to Postfix. Based on patches by Roman Neuhauser.
+
+       Added clarifying notes to main.cf, master.cf and access by
+       Dean Gibson.
+
+       In header/body_checks, DUNNO is now the preferred action
+       instead of the now deprecated OK.
+
+       In header/body_checks, allow text after IGNORE and DUNNO,
+       suggested by Victor Duchovni, Morgan Stanley.  File:
+       src/cleanup/cleanup_message.c.
+
+       Feature: reject_rhsbl_helo. File: smtpd/smtpd_check.c.
+
+       Cleanup: the LMTP and SMTP clients now send "MAIL FROM:<sender>
+       AUTH=<>" when SASL authenticated. Suggested by by Victor
+       Duchovni, Morgan Stanley. Files: smtp/smtp_proto.c,
+       lmtp/lmtp_proto.c.
+
 Open problems:
 
+       Med: do not list myorigin in virtual_alias_maps.
+
+       High: when virtual aliasing is turned off after content
+       filtering, local submissions may escape virtual aliasing.
+
+       Med: qmgr should not exit while an asynchronous bounce
+       request is in progress; this can result in multiple
+       non-delivery notifications.
+
+       Low: postcat should be null byte transparent.
+
+       Low: qmgr_move should not reset time stamps on queue files
+       without shared lock (i.e. not open by a delivery agent).
+
+       Low: postsuper re-run after renaming files, but only a
+       limited number of times.
+
        Doc: mention the proxy_interfaces parameter everywhere the
        inet_interfaces and mydestination parameters are mentioned.
 
index abf8fd5d969a4117adca62298d34bcbe0efa225c..e41eb66721e54cb60469bac05379f393c9454ea2 100644 (file)
@@ -69,39 +69,41 @@ CONFIGURING LDAP LOOKUPS
 In order to use LDAP lookups, define at least one LDAP source as a table
 lookup in main.cf, for example:
 
-    alias_maps = hash:/etc/aliases, ldap:ldapsource
+    alias_maps = hash:/etc/aliases, ldap:/etc/ldap-aliases.cf
 
-Each LDAP source can have the following parameters, which should be
-prefixed in main.cf with the name you've given the source in its
-definition and an underscore. To continue the example, the first
-parameter below, "server_host", would be defined in main.cf as
-"ldapsource_server_host". Defaults are given in parentheses:
+The file /etc/postfix/ldap-aliases.cf can specify the following
+parameters. Defaults are given in parentheses:
 
     server_host (localhost)
        The name of the host running the LDAP server, e.g.
-               ldapsource_server_host = ldap.your.com
+               server_host = ldap.your.com
        It should be possible with all the libraries mentioned above to 
        specify multiple servers separated by spaces, with the libraries
        trying them in order should the first one fail. It should also
        be possible to give each server in the list a different port, by
        naming them like "ldap.your.com:1444".
 
+        With OpenLDAP, LDAP URLs can be used to request connection
+        over UNIX domain sockets (ldapi://%2Fsome%2Fpath) or LDAP SSL
+        (ldaps://ldap.your.com:636, provided OpenLDAP was compiled with
+        support for SSL).
+
     server_port (389) 
        The port the LDAP server listens on, e.g.
-               ldapsource_server_port = 778
+               server_port = 778
 
     search_base (No default; you must configure this.)
        The base at which to conduct the search, e.g. 
-               ldapsource_search_base = dc=your, dc=com
+               search_base = dc=your, dc=com
 
     timeout (10 seconds)
        The number of seconds a search can take before timing out, e.g.
-               ldapsource_timeout = 5
+               timeout = 5
        
     query_filter (mailacceptinggeneralid=%s)
        The RFC2254 filter used to search the directory, where %s is a 
        substitute for the address Postfix is trying to resolve, e.g.
-               ldapsource_query_filter = (&(mail=%s)(paid_up=true))
+               query_filter = (&(mail=%s)(paid_up=true))
 
     result_filter (%s)
        Filter applied to result attributes.  Supports the same expansions
@@ -114,17 +116,17 @@ parameter below, "server_host", would be defined in main.cf as
        performed.  This means that the LDAP map won't get searched for
        'user', nor will it get searched for any domain not listed.  This
        can significantly reduce the query load on the LDAP server.
-               ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains
+               domain = postfix.org, hash:/etc/postfix/searchdomains
 
     result_attribute (maildrop)
        The attribute(s) Postfix will read from any directory entries
        returned by the lookup, to be resolved to an email address.
-               ldapsource_result_attribute = mailbox,maildrop
+               result_attribute = mailbox,maildrop
 
     special_result_attribute (No default)
        The attribute(s) of directory entries that can contain DNs or URLs.
        If found, a recursive subsequent search is done using their values.
-               ldapsource_special_result_attribute = member
+               special_result_attribute = member
 
     scope (sub)
         The LDAP search scope: sub, base, or one. These translate into
@@ -134,7 +136,7 @@ parameter below, "server_host", would be defined in main.cf as
        Whether or not to bind to the LDAP server. Newer LDAP
        implementations don't require clients to bind, which saves
        time. Example:
-               ldapsource_bind = no
+               bind = no
 
        If you do need to bind, you might consider configuring Postfix
        to connect to the local machine on a port that's an SSL tunnel
@@ -146,13 +148,17 @@ parameter below, "server_host", would be defined in main.cf as
     bind_dn ("")
        If you do have to bind, do it with this distinguished name.
        Example:
-               ldapsource_bind_dn = uid=postfix, dc=your, dc=com
+               bind_dn = uid=postfix, dc=your, dc=com
 
     bind_pw ("")
-       The password for the distinguished name above. If you have to
-       use this, you probably want to make main.cf readable only by
-       the Postfix user. Example:
-               ldapsource_bind_pw = postfixpw
+       The password for the distinguished name above. If you have to
+       use this, you probably want to make the map configuration file
+       readable only by the Postfix user. When using the obselete
+       ldap:ldapsource syntax, with map parameters in main.cf, it is
+       not possible to securely store the bind password. This is
+       because main.cf needs to be world readable to allow local
+       accounts to submit mail via the sendmail command. Example:
+               bind_pw = postfixpw
 
     cache        (IGNORED with a warning)
     cache_expiry (IGNORED with a warning)
@@ -213,6 +219,76 @@ parameter below, "server_host", would be defined in main.cf as
 Don't use quotes in these variables; at least, not until the Postfix
 configuration routines understand how to deal with quoted strings.
 
+For backward compatibility, these parameters can also be defined
+in main.cf, prefixed with the name you've given the source in its
+definition, and an underscore. For example, if the map is specified as
+"ldap:ldapsource", the first parameter above, "server_host", would be
+defined in main.cf as "ldapsource_server_host".
+
+LDAP SSL and STARTTLS
+---------------------
+
+If you're using the OpenLDAP libraries compiled with SSL support,
+Postfix can connect to LDAP SSL servers and can issue the STARTTLS
+command.  The first form can be requested by using a LDAP URL in
+server_host:
+
+        server_host = ldaps://ldap.your.com:636
+
+STARTTLS can be turned on with the start_tls command:
+
+       start_tls = yes
+
+Both forms require LDAP protocol version 3, which has to be set
+explicitly:
+
+       version = 3
+
+If any of the Postfix programs querying the map is configured in
+master.cf to run chrooted, all the certificates and keys involved have
+to be copied to the chroot jail.  Of course, the private keys should
+only be readable by the user "postfix".
+
+The following commands are relevant to LDAP SSL and STARTTLS:
+
+       start_tls (no)
+             Whether or not to issue STARTTLS upon connection to
+             the server.  Don't set this with LDAP SSL.
+
+       tls_ca_cert_dir (No default; set either this or tls_ca_cert_file)
+             Directory containing, in separate individual files,
+             the  X509  Certificate Authority certificates which
+             are to be recognized by the client in SSL/TLS  con-
+             nections.
+
+       tls_ca_cert_file (No default; set either this or tls_ca_cert_dir)
+             File containing the X509 Certificate Authority cer-
+             tificates which are to be recognized by the  client
+             in  SSL/TLS connections.  This setting takes prece-
+             dence over tls_ca_cert_dir.
+
+       tls_cert (No default; you must set this)
+             File containing client's  X509  certificate  to  be
+             used by the client in SSL/TLS connections.
+
+       tls_key (No default; you must set this)
+             File  containing  the  private key corresponding to
+             the above tls_cert.
+
+       tls_require_cert (no)
+             Whether or not to request server's X509 certificate
+             and  check  its  validity when establishing SSL/TLS
+             connections.
+
+       tls_random_file (No default)
+             Path of a file to  obtain  random  bits  from  when
+             /dev/[u]random  is not available, to be used by the
+             client in SSL/TLS connections.
+
+       tls_cipher_suite  (No default)
+             Cipher suite to use in SSL/TLS negotiations.
+
+
 EXAMPLES
 ========
 
@@ -220,11 +296,14 @@ ALIASES
 -------
 
 Here's a basic example for using LDAP to look up aliases. Assume that in
-main.cf, you have these configuration parameters defined:
+main.cf, you have:
+
+alias_maps = hash:/etc/aliases, ldap:/etc/ldap-aliases.cf
+
+and in ldap:/etc/ldap-aliases.cf you have:
 
-alias_maps = hash:/etc/aliases, ldap:ldapsource
-ldapsource_server_host = ldap.my.com
-ldapsource_search_base = dc=my, dc=com
+server_host = ldap.my.com
+search_base = dc=my, dc=com
 
 Upon receiving mail for a local address "ldapuser" that isn't found in
 the /etc/aliases database, Postfix will search the LDAP server listening
@@ -321,7 +400,7 @@ NOTES AND THINGS TO THINK ABOUT
   Postfix can't know how to set the ownership for program or file
   delivery. Your query_filter should probably look something like this:
 
-  virtual_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
+  query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
 
 - And for that matter, even for aliases, you may not want users able to
   specify their maildrops as programs, includes, etc. This might be
@@ -330,7 +409,7 @@ NOTES AND THINGS TO THINK ABOUT
   the fun stuff only for directory entries owned by an administrative
   account:
 
-  local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
+  query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
 
   So that if the object had a program as its maildrop and weren't owned
   by "cn=root" it wouldn't be returned as a valid local user. This will
@@ -356,7 +435,7 @@ contents, please include the applicable bits of some directory entries.
 CREDITS
 =======
 
-Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
+Manuel Guesdon: Spotted a bug with the timeout attribute.
 John Hensley: Multiple LDAP sources with more configurable attributes.
 Carsten Hoeger: Search scope handling. 
 LaMont Jones: Domain restriction, URL and DN searches, multiple result
@@ -369,5 +448,11 @@ Samuel Tardieu: Noticed that searches could include wildcards, prompting
                 the work on RFC 2254 escaping in queries. Spotted a bug
                 in binding.
 Sami Haahtinen: Referral chasing and v3 support.
+Victor Duchovni: ldap_bind() timeout. With fixes from LaMont Jones:
+                OpenLDAP cache deprecation. Limits on recursion, expansion
+                and query results size.
+Liviu Daia: Support for SSL/STARTTLS. Support for storing map definitions in
+           external files (ldap:/path/ldap.cf) need to securely store
+           passwords for plain auth.
 
 And of course Wietse.
index 613ad27e92bf07b5d41a427a3e33511fc8c00edd..3379a588b1c4a6b019f18ce879522baa65aa9a36 100644 (file)
@@ -1,9 +1,9 @@
-Purpose of the SMTPD pass-through proxy feature
-===============================================
+Purpose of the SMTP-based before-queue proxy filter feature
+===========================================================
 
 Normally, Postfix receives mail, stores it in the mail queue and
 then delivers it.  The Postfix SMTP server can be configured to
-forward all incoming mail to an SMTP proxy server (for example, a
+forward all incoming mail through a proxy filter (for example, a
 real-time SPAM filter) that inspects all mail BEFORE it is stored
 in the Postfix mail queue.
 
@@ -11,10 +11,11 @@ in the Postfix mail queue.
 FILTER_README document, where all mail is inspected AFTER it is
 stored in the Postfix mail queue]
 
-This feature is meant to be used as follows:
-                                                             / smtp
-    Internet -> smtpd -> proxy -> smtpd -> cleanup -> queue -> local
-               Postfix           Postfix                     \ virtual etc.
+The SMTP-based before-queue proxy filter is meant to be used as follows:
+
+                        before                               / smtp
+    Internet -> smtpd -> queue -> smtpd -> cleanup -> queue -> local
+               Postfix  filter   Postfix                     \ virtual etc.
 
 For reference, this is the normal path through Postfix:
 
@@ -23,20 +24,21 @@ For reference, this is the normal path through Postfix:
                 Postfix                    \ virtual etc.
 
 For comparison, this is the FILTER_README approach with an SMTP-based
-content filter:
+after-queue content filter:
                                            / smtp
     Internet -> smtpd -> cleanup -> queue -> local
                Postfix      ^         v    \ virtual etc.
                           smtpd      smtp
                          Postfix   Postfix
-                            \         /
-                             filter <-
+                            \ after   /
+                              queue <-
+                             filter
 
-The SMTP proxy server receives unfiltered mail from Postfix and
-does one of the following:
+The SMTP-based before-queue proxy filter receives unfiltered mail
+from Postfix and does one of the following:
 
-1 - Re-inject the mail back into Postfix, perhaps after changing
-    content.
+1 - Re-inject the mail back into Postfix via SMTP, perhaps after
+    changing content.
 
 2 - Reject the mail (by sending a suitable status code back to
     Postfix). Postfix passes the status back to the remote SMTP
@@ -47,8 +49,8 @@ does one of the following:
 Limitations
 ===========
 
-When used with a real-time SPAM filter, this approach allows Postfix
-to reject mail before the SMTP mail transfer completes, so that
+The SMTP-based before-queue proxy filter allows Postfix to reject
+mail before the incoming SMTP mail transfer completes, so that
 Postfix does not have to send rejected mail back to the sender.
 Mail that is not accepted remains the responsibility of the client.
 
@@ -57,7 +59,7 @@ to the existing content filter (see FILTER_README) which processes
 mail AFTER it is queued, because that gives you full control over
 how many filtering processes can be run in parallel.
 
-The problem with real-time content filtering is that the remote
+The problem with before-queue content filtering is that the remote
 SMTP client expects an SMTP reply within a deadline. As the system
 load increases, fewer and fewer CPU cycles remain available to
 answer within the deadline, and eventually you either have to stop
@@ -69,15 +71,23 @@ triggers a Postfix header_checks FILTER action, or send the mail
 into Postfix via an alternative Postfix SMTP server that always
 turns on content filtering.
 
-How the Postfix talks to the SMTP proxy
-=======================================
+How Postfix talks to the before-queue proxy filter
+==================================================
+
+When passing mail to the SMTP-based before-queue filter, Postfix
+generates its own EHLO, DATA and QUIT commands, and forwards
+unmodified copies of the MAIL FROM and RCPT TO commands that the
+Postfix SMTP server has approved.  All commands are sent without
+using ESMTP command pipelining. The SMTP proxy server should accept
+the same MAIL FROM and RCPT TO command syntax as the Postfix SMTP
+server.
 
-When Postfix talks to the SMTP proxy server it generates its own
-EHLO, DATA and QUIT commands, and forwards unmodified copies of
-the MAIL FROM and RCPT TO commands that the Postfix SMTP server
-has approved.  All commands are sent without using ESMTP command
-pipelining. The SMTP proxy server must accept the same MAIL FROM
-and RCPT TO command syntax as the Postfix SMTP server.
+The before-queue proxy filter is expected literally pass on the
+SMTP commands that it receives from Postfix to an after-filter
+Postfix SMTP server that listens on a non-standard port.  When the
+filter rejects content, it should send a negative response back to
+Postfix, and it should abort any connection with the after-filter
+Postfix SMTP server without completing the SMTP dialog.
 
 Configuration parameters 
 ========================
@@ -86,26 +96,28 @@ Parameters that control proxying:
 
 smtpd_proxy_filter (syntax: host:port)
 
-    The host and TCP port of the SMTP proxy server.  When no host
-    or host:  is specified, localhost is assumed.
+    The host and TCP port of the before-queue proxy filter.  When
+    no host or host:  is specified, localhost is assumed.
 
 smtpd_proxy_timeout (default: 100s)
 
-    Timeout for connecting to the SMTP proxy server and for sending
-    and receiving data.  All proxy errors are logged to the maillog
-    file, but the client sees "451 Error: queue file write error".
+    Timeout for connecting to the before-queue proxy filter and
+    for sending and receiving commands and data.  All proxy errors
+    are logged to the maillog file. For privacy reasons, all the
+    remote SMTP client sees is "451 Error:  queue file write error".
 
 smtpd_proxy_ehlo (default: $myhostname)
 
-    The hostname to use when sending an EHLO command to the SMTP
-    proxy server.
+    The hostname to use when sending an EHLO command to the
+    before-queue proxy filter.
 
 Testing the SMTP pass-through proxy feature
 ===========================================
 
 The following example sets up a null proxy, that is, the Postfix
 SMTP server gives the mail directly to another Postfix SMTP server
-process.
+process without intervening content filter. This useful only for
+testing, of course.
 
 /etc/postfix/master.cf
     smtp      inet  n       -       n       -       -       smtpd 
index 217c2de861cbde1ec2e451aa10ae246ce3bf378b..5824fc4ff551aa9ce4b76952df04330701d88224 100644 (file)
@@ -22,6 +22,53 @@ snapshot release).  Patches change the patchlevel and the release
 date. Snapshots change only the release date, unless they include
 the same bugfixes as a patch release.
 
+Incompatible changes with Postfix snapshot 2.0.13-20030914
+==========================================================
+
+In header/body_checks actions, the OK action is being phased out,
+and the DUNNO action is being phased in. Both actions still work
+and do the same thing, but hopefully DUNNO causes less confusion.
+
+Major changes with Postfix snapshot 2.0.13-20030914
+===================================================
+
+LDAP parameters can now be defined in external files.  Specify the
+LDAP maps in main.cf as
+
+    ldap:/path/to/ldap.cf
+
+and write the LDAP parameters in /path/to/ldap.cf, without the
+"ldapsource_" prefix.  This makes it possible to securely store
+bind passwords for plain auth outside of main.cf (which must be
+world readable).  The old syntax still works, for backwards
+compatibility.  By Liviu Daia, based on a suggestion by Victor
+Duchovni and Lamont Jones.
+
+Support for LDAP URLs in the LDAP parameter "server_host", if
+Postfix is linked against OpenLDAP.  LDAP hosts, ports, and connection
+protocols to be used as LDAP sources can be specified as a
+blank-separated list of LDAP URLs in "server_host".  As with
+OpenLDAP, specifying a port in a LDAP URL overrides "server_port".
+Examples:
+
+    server_host = ldap://ldap.itd.umich.edu
+    server_host = ldaps://ldap.itd.umich.edu:636
+    server_host = ldapi://%2Fsome%2Fpath
+
+The LDAP SSL scheme ldaps:// is available if OpenLDAP was compiled
+with SSL support.  New parameters "tls_ca_cert_dir", "tls_ca_cert_file",
+"tls_cert", "tls_key", "tls_require_cert", "tls_random_file",
+"tls_cipher_suite" control the certificates, source of random
+numbers, and cipher suites used for SSL connections.  See LDAP_README
+for further information.  By Liviu Daia.
+
+Support for STARTTLS command in LDAP, if Postfix is linked against
+OpenLDAP and OpenLDAP was compiled with SSL support.  STARTTLS is
+controlled by the "start_tls" parameter.  The above parameters for
+certificates, source of random numbers, and cipher suites also
+apply.  See LDAP_README for further information.  By Liviu Daia,
+amended by Victor Duchovni.
+
 Major changes with Postfix snapshot 2.0.13-20030715
 ===================================================
 
index d24d5732db1a93c4a921810e9be9cab7f5929c2c..4cea8b406765bcefd79de474068bf1440bb7d5cb 100644 (file)
 #        When a mail address localpart contains the optional recip-
 #        ient delimiter (e.g., user+foo@domain), the  lookup  order
 #        becomes: user+foo@domain, user@domain, user+foo, user, and
-#        @domain.  An unmatched address extension (+foo) is  propa-
+#        @domain.
+# 
+#        The  propagate_unmatched_extensions   parameter   controls
+#        whether  an  unmatched  address extension (+foo) is propa-
 #        gated to the result of table lookup.
 # 
 # REGULAR EXPRESSION TABLES
-#        This  section  describes how the table lookups change when
+#        This section describes how the table lookups  change  when
 #        the table is given in the form of regular expressions. For
-#        a  description  of regular expression lookup table syntax,
+#        a description of regular expression lookup  table  syntax,
 #        see regexp_table(5) or pcre_table(5).
 # 
-#        Each pattern is a regular expression that  is  applied  to
+#        Each  pattern  is  a regular expression that is applied to
 #        the entire address being looked up. Thus, user@domain mail
-#        addresses are not broken up into their  user  and  @domain
+#        addresses  are  not  broken up into their user and @domain
 #        constituent parts, nor is user+foo broken up into user and
 #        foo.
 # 
-#        Patterns are applied in the  order  as  specified  in  the
-#        table,  until  a  pattern is found that matches the search
+#        Patterns  are  applied  in  the  order as specified in the
+#        table, until a pattern is found that  matches  the  search
 #        string.
 # 
-#        Results are the same as with indexed  file  lookups,  with
-#        the  additional feature that parenthesized substrings from
+#        Results  are  the  same as with indexed file lookups, with
+#        the additional feature that parenthesized substrings  from
 #        the pattern can be interpolated as $1, $2 and so on.
 # 
 # TCP-BASED TABLES
-#        This section describes how the table lookups  change  when
+#        This  section  describes how the table lookups change when
 #        lookups are directed to a TCP-based server. For a descrip-
-#        tion  of  the  TCP  client/server  lookup  protocol,   see
+#        tion   of  the  TCP  client/server  lookup  protocol,  see
 #        tcp_table(5).
 # 
 #        Each lookup operation uses the entire address once.  Thus,
-#        user@domain mail addresses are not broken  up  into  their
+#        user@domain  mail  addresses  are not broken up into their
 #        user and @domain constituent parts, nor is user+foo broken
 #        up into user and foo.
 # 
 #        Results are the same as with indexed file lookups.
 # 
 # BUGS
-#        The table format does not understand quoting  conventions.
+#        The  table format does not understand quoting conventions.
 # 
 # CONFIGURATION PARAMETERS
-#        The  following  main.cf parameters are especially relevant
-#        to this topic. See the Postfix  main.cf  file  for  syntax
-#        details  and  for  default  values. Use the postfix reload
+#        The following main.cf parameters are  especially  relevant
+#        to  this  topic.  See  the Postfix main.cf file for syntax
+#        details and for default values.  Use  the  postfix  reload
 #        command after a configuration change.
 # 
 #        canonical_maps
 #               Address  mapping  lookup  table  for  envelope  and
 #               header sender addresses.
 # 
+#        propagate_unmatched_extensions
+#               A  list  of  address rewriting or forwarding mecha-
+#               nisms that propagate an address extension from  the
+#               original  address  to  the result.  Specify zero or
+#               more of  canonical,  virtual,  alias,  forward,  or
+#               include.
+# 
 #        Other parameters of interest:
 # 
 #        inet_interfaces
-#               The network interface addresses  that  this  system
+#               The  network  interface  addresses that this system
 #               receives mail on.  You need to stop and start Post-
 #               fix when this parameter changes.
 # 
 #        masquerade_classes
-#               List of address classes  subject  to  masquerading:
-#               zero  or  more of envelope_sender, envelope_recipi-
+#               List  of  address  classes subject to masquerading:
+#               zero or more of  envelope_sender,  envelope_recipi-
 #               ent, header_sender, header_recipient.
 # 
 #        masquerade_domains
-#               List of domains that hide  their  subdomain  struc-
+#               List  of  domains  that hide their subdomain struc-
 #               ture.
 # 
 #        masquerade_exceptions
-#               List  of user names that are not subject to address
+#               List of user names that are not subject to  address
 #               masquerading.
 # 
 #        mydestination
-#               List of domains that  this  mail  system  considers
+#               List  of  domains  that  this mail system considers
 #               local.
 # 
 #        myorigin
 #        tcp_table(5) TCP client/server table lookup protocol
 # 
 # LICENSE
-#        The  Secure  Mailer  license must be distributed with this
+#        The Secure Mailer license must be  distributed  with  this
 #        software.
 # 
 # AUTHOR(S)
index fd7a99836fc4557bcd9d5307680dab071432614d..957b181387bc36ac89c7756e42a7776aabd4d38c 100644 (file)
@@ -1,7 +1,7 @@
 # Global Postfix configuration file. This file lists only a subset
 # of all 300+ parameters. See the sample-xxx.cf files for a full list.
 # 
-# The general format is lines with parameter = value pairs. Lines
+# The general format of each line is: parameter = value. Lines
 # that begin with whitespace continue the previous line. A value can
 # contain references to other $names or ${name}s.
 #
@@ -147,6 +147,12 @@ mail_owner = postfix
 # a name matches a lookup key (the right-hand side is ignored).
 # Continue long lines by starting the next line with whitespace.
 #
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+#
 # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
 #
 #mydestination = $myhostname, localhost.$mydomain
index 1418667605b9a3260cf20d1c6c9901de397b33d3..c3b46d85ab6e2b5827acd02787a91cfaae3284c6 100644 (file)
 # in the main.cf configuration file). See individual command man pages
 # for specific command-line options, if any.
 #
+# General main.cf options can be overridden for specific services.
+# To override one or more main.cf options, specify them as arguments
+# below, preceding each option by "-o".  There must be no whitespace
+# in the option itself (separate multiple values for an option by
+# commas).
+#
 # In order to use the "uucp" message tranport below, set up entries
 # in the transport table.
 #
index 5ab638e11aefa28c80ee734226542167ffe82786..7d3943241c6539b4c42791dd0cfc98461baf8d51 100644 (file)
@@ -78,6 +78,25 @@ smtpd_sasl_security_options = noanonymous
 #smtpd_sasl_local_domain = $mydomain
 smtpd_sasl_local_domain = $myhostname
 
+# The smtpd_sasl_exceptions_networks parameter controls what SMTP
+# clients Postfix will not offer AUTH support.
+# 
+# Some clients (Netscape 4 at least) have a bug that causes them to
+# require a login and password whenever AUTH is offered, whether it's
+# necessary or not. To work around this, specify, for example,
+# $mynetworks to prevent Postfix from offering AUTH to local clients.
+# 
+# Specify an explicit list of network/netmask patterns, where the
+# mask specifies the number of bits in the network part of a host
+# address.
+#
+# You can also specify the absolute pathname of a pattern file instead
+# of listing the patterns here. Specify type:table for table-based lookups
+# (the value on the table right-hand side is not used).
+#
+#smtpd_sasl_exceptions_networks = $mynetworks
+smtpd_sasl_exceptions_networks =
+
 # SMTP CLIENT CONTROLS
 
 # The smtp_sasl_auth_enable parameter controls whether authentication
index 6424d8732875fa603c8133d3af73e880f15ef49b..0f667ca7eeba84a0fc792a81a973bb79036e07d0 100644 (file)
 # REJECT [optional text...]
 #      Reject the entire message. The optional text is sent to the
 #      originator and is logged to the maillog file.
-# OK   Skip all further header patterns for this header line.
-# IGNORE Silently discard the header line.
+# DUNNO [optional text...]
+#      Skip all further header patterns for this header line.
+# IGNORE [optional text...]
+#      Silently discard the header line.
 # WARN [optional text...]
 #      Log the message header and the optional text. This is useful
 #      for testing. When the pattern is good, change the WARN into a
 #      REJECT or into a DISCARD.
 # HOLD [optional text...]
 #      Place the message on the hold queue. Mail on hold can be
-#       inspected with the postcat command, and can be destroyed or
-#       taken off hold (i.e. delivered) with the postsuper command.
-#       The matched header is logged with the optional text.
+#      inspected with the postcat command, and can be destroyed or
+#      taken off hold (i.e. delivered) with the postsuper command.
+#      The matched header is logged with the optional text.
 # DISCARD [optional text...]
 #      Claim successful delivery and silently discard the message.
-#       The matched header is logged with the optional text.
+#      The matched header is logged with the optional text.
 # FILTER transport:nexthop
-#       after the message is queued, the message is sent through
-#       a content filter. This requires different cleanup servers
-#       before and after the filter, with header/body checks turned
-#       off in the second cleanup server. More info about content
+#      After the message is queued, send the message through
+#      a content filter. This requires different cleanup servers
+#      before and after the filter, with header/body checks turned
+#      off in the second cleanup server. More info about content
 #      filtering is in the Postfix FILTER_README file. This feature
 #      overrides the main.cf content_filter setting.
 # REDIRECT user@domain
@@ -60,38 +62,7 @@ header_checks = regexp:/etc/postfix/header_checks
 # For examples of pattern syntax see the sample-regexp-header.cf and
 # sample-pcre-header files.
 #
-# When a pattern matches, what happens next depends on the associated
-# action that is specified in the right-hand side of the table:
-#
-# REJECT [optional text...]
-#       Reject the entire message. The optional text is sent to the
-#       originator and is logged to the maillog file.
-# OK   Skip all further header patterns for this header line.
-# IGNORE Silently discard the body line
-# WARN [optional text...]
-#       Log the body line and the optional text. This is useful
-#       for testing. When the pattern is good, change the WARN into a
-#       REJECT or into a DISCARD.
-# HOLD [optional text...]
-#       Place the message on the hold queue. Mail on hold can be
-#       inspected with the postcat command, and can be destroyed or
-#       taken off hold (i.e. delivered) with the postsuper command.
-#       The matched body line is logged with the optional text.
-# DISCARD [optional text...]
-#       Claim successful delivery and silently discard the message.
-#       The matched body line is logged with the optional text.
-# FILTER transport:nexthop
-#       after the message is queued, the message is sent through
-#       a content filter. This requires different cleanup servers
-#       before and after the filter, with header/body checks turned
-#       off in the second cleanup server. More info about content
-#      filtering is in the Postfix FILTER_README file. This feature
-#      overrides the main.cf content_filter setting.
-# REDIRECT user@domain
-#      Send the message to the specified address instead of the
-#      intended recipient(s). This feature overrides the FILTER action.
-#
-# By default, the same patterns are applied as for header_checks.
+# Actions on the table right-hand side are the same as with header_checks.
 #
 mime_header_checks = $header_checks
 
@@ -107,33 +78,7 @@ mime_header_checks = $header_checks
 # When a pattern matches, what happens next depends on the associated
 # action that is specified in the right-hand side of the table:
 #
-# REJECT [optional text...]
-#       Reject the entire message. The optional text is sent to the
-#       originator and is logged to the maillog file.
-# OK   Skip all further header patterns for this header line.
-# IGNORE Silently discard the body line
-# WARN [optional text...]
-#       Log the body line and the optional text. This is useful
-#       for testing. When the pattern is good, change the WARN into a
-#       REJECT or into a DISCARD.
-# HOLD [optional text...]
-#       Place the message on the hold queue. Mail on hold can be
-#       inspected with the postcat command, and can be destroyed or
-#       taken off hold (i.e. delivered) with the postsuper command.
-#       The matched body line is logged with the optional text.
-# DISCARD [optional text...]
-#       Claim successful delivery and silently discard the message.
-#       The matched body line is logged with the optional text.
-# FILTER transport:nexthop
-#       after the message is queued, the message is sent through
-#       a content filter. This requires different cleanup servers
-#       before and after the filter, with header/body checks turned
-#       off in the second cleanup server. More info about content
-#      filtering is in the Postfix FILTER_README file. This feature
-#      overrides the main.cf content_filter setting.
-# REDIRECT user@domain
-#      Send the message to the specified address instead of the
-#      intended recipient(s). This feature overrides the FILTER action.
+# Actions on the table right-hand side are the same as with header_checks.
 #
 # By default, the same patterns are applied as for header_checks.
 #
@@ -150,21 +95,7 @@ nested_header_checks = $header_checks
 # For examples of pattern syntax see the sample-regexp-body.cf and
 # sample-pcre-body.cf files.
 #
-# When a pattern matches, what happens next depends on the associated
-# action that is specified in the right-hand side of the table:
-#
-# REJECT the entire message is rejected.
-# REJECT text.... The text is sent to the originator.
-# IGNORE the body line is silently discarded.
-# WARN   the body line is logged (not rejected) with a warning message.
-# WARN text... as above, and the text is logged, too.
-# FILTER transport:nexthop
-#       after the message is queued, the message is sent through
-#       a content filter. This requires different cleanup servers
-#       before and after the filter, with header/body checks turned
-#       off in the second cleanup server. More info about content
-#      filtering is in the Postfix FILTER_README file. This feature
-#      overrides the main.cf content_filter setting.
+# Actions on the table right-hand side are the same as with header_checks.
 #
 body_checks = regexp:/etc/postfix/body_checks
 
index 2f8e564589cab7411a22475dbe548c992f4d32ca..e1eb3d00811e74bd6d45fcc3af0e8cb31ed9dbf3 100644 (file)
@@ -5,24 +5,28 @@
 # parameters that control LDAP lookups. Source code for LDAP
 # lookup is available separately from http://www.postfix.org/
 
-# The ldap_timeout parameter specifies the timeout for LDAP database
+# The timeout parameter specifies the timeout for LDAP database
 # lookups.
 #
-#ldap_timeout = 10
+#timeout = 10
 
-# The ldap_search_base parameter specifies the LDAP database to search.
+# The search_base parameter specifies the LDAP database to search.
 #
-#ldap_search_base = 
+#search_base = 
 
-# The ldap_server_host parameter specifies the LDAP server hostname.
+# The server_host parameter specifies the LDAP server hostname.
 #
-#ldap_server_host = localhost
+#server_host = localhost
 
-# The ldap_server_port parameter specifies the LDAP server port number.
+# The server_port parameter specifies the LDAP server port number.
 #
-#ldap_server_port = 389
+#server_port = 389
 
-# The ldap_query_filter parameter specifies the filter used for queries.
+# The version parameter specifies the LDAP protocol version to use.
+#
+#version = 2
+
+# The query_filter parameter specifies the filter used for queries.
 # The replacement for "%s" is the address input into the map; e.g.
 # for alias maps, the "user" part (the RFC 2822 local-part) of
 # "user@domain.com" for To: addresses destined for local delivery 
 # "%u" provides just the user portion of the input, and "%d" provides
 # just the hostname.
 #
-#ldap_query_filter = (mailacceptinggeneralid=%s)
+#query_filter = (mailacceptinggeneralid=%s)
 
-# The ldap_result_filter parameter specifies the filter to be applied
-# to the result attribute(s).  See ldap_query_filter for valid expansions.
+# The result_filter parameter specifies the filter to be applied
+# to the result attribute(s).  See query_filter for valid expansions.
 #
-#ldap_result_filter = %s
+#result_filter = %s
 
-# The ldap_result_attribute parameter specifies the attribute returned by
+# The result_attribute parameter specifies the attribute returned by
 # the search.
 #
-#ldap_result_attribute = maildrop
+#result_attribute = maildrop
 
-# The ldap_special_result_attribute lists the attribute(s) of an
+# The special_result_attribute lists the attribute(s) of an
 # entry which contain links, either ldap url's or distinguished names.
 # The entries referenced by these links are (recursively) treated as if
 # they were contained in the referencing entity.
 #
-#ldap_special_result_attribute =
+#special_result_attribute =
 
-# The ldap_scope parameter specifies the LDAP search scope: sub, base, or one.
+# The scope parameter specifies the LDAP search scope: sub, base, or one.
 #
-#ldap_scope = sub
+#scope = sub
 
-# The ldap_bind parameter specifies whether or not to bind to the server.
+# The bind parameter specifies whether or not to bind to the server.
 # LDAP v3 implementations don't require it, which saves some overhead.
 #
-#ldap_bind = yes
+#bind = yes
 
-# The ldap_bind_dn parameter specifies what distinguished name to use
+# The bind_dn parameter specifies what distinguished name to use
 # when binding.
 #
-#ldap_bind_dn =
+#bind_dn =
 
-# The ldap_bind_pw parameter specifies the password to use.
+# The bind_pw parameter specifies the password to use.
 #
-#ldap_bind_pw =
+#bind_pw =
 
-#ldap_cache        (IGNORED with a warning)
-#ldap_cache_expiry (IGNORED with a warning)
-#ldap_cache_size   (IGNORED with a warning)
+#cache        (IGNORED with a warning)
+#cache_expiry (IGNORED with a warning)
+#cache_size   (IGNORED with a warning)
 #
 # The above parameters are NO LONGER SUPPORTED by Postfix.
 # Cache support has been dropped from OpenLDAP as of release 2.1.13.
 
-# The ldap_recursion_limit parameter specifies a limit on the nesting
+# The recursion_limit parameter specifies a limit on the nesting
 # depth of DN and URL special result attribute evaluation. The limit
 # must be a non-zero positive number. The default value is 1000.
 # 
-#ldap_recursion_limit = 1000
+#recursion_limit = 1000
 
-# The ldap_expansion_limit parameter specifies a limit on the total
+# The expansion_limit parameter specifies a limit on the total
 # number of result elements returned (as a comma separated list) by a lookup
 # against the map. A setting of 0 disables the limit. Lookups fail with a
 # temporary error if the limit is exceeded. Setting the limit to 1 ensures
 # that lookups do not return multiple values. The default value is 0.
 #
-#ldap_expansion_limit = 0
+#expansion_limit = 0
 
-# The ldap_size_limit parameter specifies a limit on the number of LDAP
+# The size_limit parameter specifies a limit on the number of LDAP
 # entries returned by any single LDAP query performed as part of the
 # lookup. A setting of 0 disables the limit. Expansion of DN and URL
 # references involves nested LDAP queries, each of which is separately
-# subjected to this limit. The default value is $ldap_expansion_limit.
+# subjected to this limit. The default value is $expansion_limit.
 # 
 # Note: even a single LDAP entry can generate multiple lookup results, via
 # multiple result attributes and/or multi-valued result attributes.
 # not the final multiplicity of the lookup result. It is analogous to the
 # "-z" option of "ldapsearch".
 #
-#ldap_size_limit = $ldap_expansion_limit
+#size_limit = 0
 
-# The ldap_deference parameter specifies how to handle LDAP aliases.  See the
+# The deference parameter specifies how to handle LDAP aliases.  See the
 # ldap_open(3) man page.
 #
-#ldap_dereference = 0
+#dereference = 0
 
-# The ldap_domain parameter limits the LDAP searches to just things in
+# The domain parameter limits the LDAP searches to just things in
 # (exactly) the specified list of domains.
 #
-#ldap_domain =
+#domain =
+
+# The start_tls parameter specifies whether or not to issue
+# STARTTLS upon connection to the server.  STARTTLS requires LDAP
+# protocol version 3.
+#
+#start_tls = no
+
+# The tls_ca_cert_dir parameter specifies a directory containing,
+# in separate individual files, the X509 Certificate Authority
+# certificates which are to be recognized by the client in SSL/TLS
+# connections.
+#
+#tls_ca_cert_dir =
+
+# The tls_ca_cert_file parameter specifies a file containing the
+# X509 Certificate Authority certificates which are to be recognized by
+# the client in SSL/TLS connections.  This setting takes precedence over
+# tls_ca_cert_dir.
+#
+#tls_ca_cert_file =
+
+# The tls_cert parameter specifies the client's X509 certificate to
+# be used in SSL/TLS connections.
+#
+#tls_cert =
+
+# The tls_key parameter specifies the private key corresponding to
+# the above tls_cert.
+#
+#tls_key =
+
+# The tls_require_cert parameter specifies whether or not to
+# request server's X509 certificate and check its validity when
+# establishing SSL/TLS connections.
+#
+#tls_require_cert = no
+
+# The tls_random_file parameter specifies a file to obtain random
+# bits from when /dev/[u]random is not available, to be used in SSL/TLS
+# connections.
+#
+#tls_random_file =
+
+# The tls_cipher_suite parameter specifies the cipher suite to be
+# use in SSL/TLS negotiations.
+#
+#tls_cipher_suite =
 
-# The ldap_debuglevel parameter sets the debug level in the OpenLDAP
+# The debuglevel parameter sets the debug level in the OpenLDAP
 # libraries.
-#ldap_debuglevel = 0
+#debuglevel = 0
index ce7698da6d9d8047eddbdd47d710c5486d671493..4d010158efe5c9970eed743834cab0238c9cef58 100644 (file)
@@ -88,8 +88,10 @@ enable_original_recipient = yes
 # 
 # - TZ is needed for sane time keeping on most SYSV-ish systems
 # 
-# Specify a list of names separated by whitespace or comma.
+# Specify a list of names and/or name=value pairs, separated by 
+# whitespace or comma.
 #
+#export_environment = TZ PATH=/bin:/usr/bin
 export_environment = TZ
 
 # The hash_queue_depth parameter specifies the number of subdirectory
@@ -133,7 +135,8 @@ hopcount_limit = 50
 #   with an X-windows debugger.
 # - MAIL_CONFIG is needed to make "postfix -c" work.
 # 
-# Specify a list of names separated by whitespace or comma.
+# Specify a list of names and/or name=value pairs, separated by 
+# whitespace or comma.
 #
 #import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS
 import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY
index bb45d958735b66f6a94163b67e2f32b539d79d2b..a3fdb46b01166ffbda5b585906f06504b0bfb611 100644 (file)
@@ -360,6 +360,10 @@ smtpd_helo_required = no
 #      see access(5) for possible lookup results.
 #   check_policy_service transport:endpoint: delegate the decision to
 #      an external policy server. See SMTPD_POLICY_README for details.
+#   reject_rhsbl_helo domain.tld: reject if the helo argument is listed
+#      in an A record under domain.tld.
+#      Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+#      address record when an RBL server provides multi-valued results.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
 #   warn_if_reject: next restriction logs a warning instead of rejecting.
index 17493baa3d294bfcbaf82897fa654bb88cee8148..9baed6d5d17c4bf4514cca2cfb2a94c23438f755 100644 (file)
 #        When a mail address localpart contains the optional recip-
 #        ient delimiter (e.g., user+foo@domain), the  lookup  order
 #        becomes: user+foo@domain, user@domain, user+foo, user, and
-#        @domain.  An unmatched address extension (+foo) is  propa-
+#        @domain.
+# 
+#        The  propagate_unmatched_extensions   parameter   controls
+#        whether  an  unmatched  address extension (+foo) is propa-
 #        gated to the result of table lookup.
 # 
 # VIRTUAL ALIAS DOMAINS
-#        Besides  virtual aliases, the virtual alias table can also
+#        Besides virtual aliases, the virtual alias table can  also
 #        be used to implement virtual alias domains. With a virtual
-#        alias  domain,  all  recipient  addresses  are  aliased to
+#        alias domain,  all  recipient  addresses  are  aliased  to
 #        addresses in other domains.
 # 
 #        Virtual alias domains are not to be confused with the vir-
 #        tual mailbox domains that are implemented with the Postfix
 #        virtual(8)  mail  delivery  agent.  With  virtual  mailbox
-#        domains,  each recipient address can have its own mailbox.
+#        domains, each recipient address can have its own  mailbox.
 # 
-#        With a virtual alias domain, the virtual  domain  has  its
-#        own  user  name  space. Local (i.e. non-virtual) usernames
-#        are not visible in a virtual alias domain. In  particular,
-#        local  aliases(5)  and local mailing lists are not visible
+#        With  a  virtual  alias domain, the virtual domain has its
+#        own user name space. Local  (i.e.  non-virtual)  usernames
+#        are  not visible in a virtual alias domain. In particular,
+#        local aliases(5) and local mailing lists are  not  visible
 #        as localname@virtual-alias.domain.
 # 
 #        Support for a virtual alias domain looks like:
 #        /etc/postfix/main.cf:
 #            virtual_alias_maps = hash:/etc/postfix/virtual
 # 
-#            Note: some systems use dbm databases instead of  hash.
+#            Note:  some systems use dbm databases instead of hash.
 #            See the output from postconf -m for available database
 #            types.
 # 
 #            user1@virtual-alias.domain   address1
 #            user2@virtual-alias.domain   address2, address3
 # 
-#        The virtual-alias.domain anything entry is required for  a
+#        The  virtual-alias.domain anything entry is required for a
 #        virtual alias domain. Without this entry, mail is rejected
-#        with "relay access denied", or bounces  with  "mail  loops
+#        with  "relay  access  denied", or bounces with "mail loops
 #        back to myself".
 # 
-#        Do  not  specify virtual alias domain names in the main.cf
+#        Do not specify virtual alias domain names in  the  main.cf
 #        mydestination or relay_domains configuration parameters.
 # 
-#        With a virtual  alias  domain,  the  Postfix  SMTP  server
-#        accepts   mail  for  known-user@virtual-alias.domain,  and
-#        rejects  mail  for  unknown-user@virtual-alias.domain   as
+#        With  a  virtual  alias  domain,  the  Postfix SMTP server
+#        accepts  mail  for  known-user@virtual-alias.domain,   and
+#        rejects   mail  for  unknown-user@virtual-alias.domain  as
 #        undeliverable.
 # 
-#        Instead  of  specifying  the virtual alias domain name via
-#        the virtual_alias_maps table, you may also specify it  via
+#        Instead of specifying the virtual alias  domain  name  via
+#        the  virtual_alias_maps table, you may also specify it via
 #        the main.cf virtual_alias_domains configuration parameter.
-#        This latter parameter uses the same syntax as the  main.cf
+#        This  latter parameter uses the same syntax as the main.cf
 #        mydestination configuration parameter.
 # 
 # REGULAR EXPRESSION TABLES
-#        This  section  describes how the table lookups change when
+#        This section describes how the table lookups  change  when
 #        the table is given in the form of regular expressions. For
-#        a  description  of regular expression lookup table syntax,
+#        a description of regular expression lookup  table  syntax,
 #        see regexp_table(5) or pcre_table(5).
 # 
-#        Each pattern is a regular expression that  is  applied  to
+#        Each  pattern  is  a regular expression that is applied to
 #        the entire address being looked up. Thus, user@domain mail
-#        addresses are not broken up into their  user  and  @domain
+#        addresses  are  not  broken up into their user and @domain
 #        constituent parts, nor is user+foo broken up into user and
 #        foo.
 # 
-#        Patterns are applied in the  order  as  specified  in  the
-#        table,  until  a  pattern is found that matches the search
+#        Patterns  are  applied  in  the  order as specified in the
+#        table, until a pattern is found that  matches  the  search
 #        string.
 # 
-#        Results are the same as with indexed  file  lookups,  with
-#        the  additional feature that parenthesized substrings from
+#        Results  are  the  same as with indexed file lookups, with
+#        the additional feature that parenthesized substrings  from
 #        the pattern can be interpolated as $1, $2 and so on.
 # 
 # TCP-BASED TABLES
-#        This section describes how the table lookups  change  when
+#        This  section  describes how the table lookups change when
 #        lookups are directed to a TCP-based server. For a descrip-
-#        tion  of  the  TCP  client/server  lookup  protocol,   see
+#        tion   of  the  TCP  client/server  lookup  protocol,  see
 #        tcp_table(5).
 # 
 #        Each lookup operation uses the entire address once.  Thus,
-#        user@domain mail addresses are not broken  up  into  their
+#        user@domain  mail  addresses  are not broken up into their
 #        user and @domain constituent parts, nor is user+foo broken
 #        up into user and foo.
 # 
 #        Results are the same as with indexed file lookups.
 # 
 # BUGS
-#        The table format does not understand quoting  conventions.
+#        The  table format does not understand quoting conventions.
 # 
 # CONFIGURATION PARAMETERS
-#        The  following  main.cf parameters are especially relevant
-#        to this topic. See the Postfix  main.cf  file  for  syntax
-#        details  and  for  default  values. Use the postfix reload
+#        The following main.cf parameters are  especially  relevant
+#        to  this  topic.  See  the Postfix main.cf file for syntax
+#        details and for default values.  Use  the  postfix  reload
 #        command after a configuration change.
 # 
 #        virtual_alias_maps
 #               List of virtual aliasing tables.
 # 
 #        virtual_alias_domains
-#               List of virtual alias domains. This uses  the  same
+#               List  of  virtual alias domains. This uses the same
 #               syntax as the mydestination parameter.
 # 
+#        propagate_unmatched_extensions
+#               A list of address rewriting  or  forwarding  mecha-
+#               nisms  that propagate an address extension from the
+#               original address to the result.   Specify  zero  or
+#               more  of  canonical,  virtual,  alias,  forward, or
+#               include.
+# 
 #        Other parameters of interest:
 # 
 #        inet_interfaces
-#               The  network  interface  addresses that this system
+#               The network interface addresses  that  this  system
 #               receives mail on.  You need to stop and start Post-
 #               fix when this parameter changes.
 # 
 #        mydestination
-#               List  of  domains  that  this mail system considers
+#               List of domains that  this  mail  system  considers
 #               local.
 # 
 #        myorigin
-#               The domain that is appended  to  any  address  that
+#               The  domain  that  is  appended to any address that
 #               does not have a domain.
 # 
 #        owner_request_special
 #        tcp_table(5) TCP client/server table lookup protocol
 # 
 # LICENSE
-#        The Secure Mailer license must be  distributed  with  this
+#        The  Secure  Mailer  license must be distributed with this
 #        software.
 # 
 # AUTHOR(S)
index 1b9f9f22f31863eb488abb8fb482e86e7953924b..b42cfc3b01f0ec86abe7b53e61153087d5287e42 100755 (executable)
@@ -65,6 +65,9 @@ use Sys::Syslog qw(:DEFAULT setlogsock);
 # or /var/tmp. DO NOT create the greylist database in a file system
 # that can run out of space.
 #
+# In case of database corruption, this script saves the database as
+# $database_name.time(), so that the mail system does not get stuck.
+#
 $database_name="/var/mta/smtpd-policy.db";
 $greylist_delay=3600;
 
@@ -147,7 +150,8 @@ sub open_database {
 
 #
 # Read database. Use a shared lock to avoid reading the database
-# while it is being changed.
+# while it is being changed. XXX There should be a way to synchronize
+# our cache from the on-file database before looking up the key.
 #
 sub read_database {
     my($key) = @_;
@@ -155,6 +159,7 @@ sub read_database {
 
     flock DATABASE_HANDLE, LOCK_SH ||
        fatal_exit "Can't get shared lock on %s: $!", $database_name;
+    # XXX Synchronize our cache from the on-disk copy before lookup.
     $value = $db_hash{$key};
     syslog $syslog_priority, "lookup %s: %s", $key, $value if $verbose;
     flock DATABASE_HANDLE, LOCK_UN ||
@@ -164,7 +169,9 @@ sub read_database {
 
 #
 # Update database. Use an exclusive lock to avoid collisions with
-# other updaters, and to avoid surprises in database readers.
+# other updaters, and to avoid surprises in database readers. XXX
+# There should be a way to synchronize our cache from the on-file
+# database before updating the database.
 #
 sub update_database {
     my($key, $value) = @_;
@@ -172,6 +179,7 @@ sub update_database {
     syslog $syslog_priority, "store %s: %s", $key, $value if $verbose;
     flock DATABASE_HANDLE, LOCK_EX ||
        fatal_exit "Can't exclusively lock %s: $!", $database_name;
+    # XXX Synchronize our cache from the on-disk copy before update.
     $db_hash{$key} = $value;
     $database_obj->sync() &&
        fatal_exit "Can't update %s: $!", $database_name;
@@ -179,6 +187,21 @@ sub update_database {
        fatal_exit "Can't unlock %s: $!", $database_name;
 }
 
+#
+# Signal 11 means that we have some kind of database corruption (yes
+# Berkeley DB should handle this better).  Move the corrupted database
+# out of the way, and start with a new database.
+#
+sub sigsegv_handler {
+    my $backup = $database_name . time();
+
+    rename $database_name, $backup || 
+       fatal_exit "Can't save %s as %s: $!", $database_name, $backup;
+    fatal_exit "Caught signal 11; the corrupted database is saved as $backup";
+}
+
+$SIG{'SEGV'} = 'sigsegv_handler';
+
 #
 # This process runs as a daemon, so it can't log to a terminal. Use
 # syslog so that people can actually see our messages.
index a09bf0683b1e7a47fb1a97161183fa5437c9c00f..b767e0fcff909bfd5c11d890eb665fd159fd1ec8 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 CANONICAL(5)                                         CANONICAL(5)
 
 <b>NAME</b>
@@ -99,49 +99,52 @@ CANONICAL(5)                                         CANONICAL(5)
        When a mail address localpart contains the optional recip-
        ient delimiter (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order
        becomes: <i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and
-       @<i>domain</i>.  An unmatched address extension (<i>+foo</i>) is  propa-
+       @<i>domain</i>.
+
+       The  <b>propagate_unmatched_extensions</b>   parameter   controls
+       whether  an  unmatched  address extension (<i>+foo</i>) is propa-
        gated to the result of table lookup.
 
 <b>REGULAR EXPRESSION TABLES</b>
-       This  section  describes how the table lookups change when
+       This section describes how the table lookups  change  when
        the table is given in the form of regular expressions. For
-       a  description  of regular expression lookup table syntax,
+       a description of regular expression lookup  table  syntax,
        see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to
+       Each  pattern  is  a regular expression that is applied to
        the entire address being looked up. Thus, <i>user@domain</i> mail
-       addresses are not broken up into their  <i>user</i>  and  <i>@domain</i>
+       addresses  are  not  broken up into their <i>user</i> and <i>@domain</i>
        constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
        <i>foo</i>.
 
-       Patterns are applied in the  order  as  specified  in  the
-       table,  until  a  pattern is found that matches the search
+       Patterns  are  applied  in  the  order as specified in the
+       table, until a pattern is found that  matches  the  search
        string.
 
-       Results are the same as with indexed  file  lookups,  with
-       the  additional feature that parenthesized substrings from
+       Results  are  the  same as with indexed file lookups, with
+       the additional feature that parenthesized substrings  from
        the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
 
 <b>TCP-BASED TABLES</b>
-       This section describes how the table lookups  change  when
+       This  section  describes how the table lookups change when
        lookups are directed to a TCP-based server. For a descrip-
-       tion  of  the  TCP  client/server  lookup  protocol,   see
+       tion   of  the  TCP  client/server  lookup  protocol,  see
        <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
 
        Each lookup operation uses the entire address once.  Thus,
-       <i>user@domain</i> mail addresses are not broken  up  into  their
+       <i>user@domain</i>  mail  addresses  are not broken up into their
        <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i> broken
        up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
 
 <b>BUGS</b>
-       The table format does not understand quoting  conventions.
+       The  table format does not understand quoting conventions.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this topic. See the Postfix  <b>main.cf</b>  file  for  syntax
-       details  and  for  default  values. Use the <b>postfix reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  topic.  See  the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix  reload</b>
        command after a configuration change.
 
        <b>canonical_maps</b>
@@ -155,28 +158,35 @@ CANONICAL(5)                                         CANONICAL(5)
               Address  mapping  lookup  table  for  envelope  and
               header sender addresses.
 
+       <b>propagate_unmatched_extensions</b>
+              A  list  of  address rewriting or forwarding mecha-
+              nisms that propagate an address extension from  the
+              original  address  to  the result.  Specify zero or
+              more of  <b>canonical</b>,  <b>virtual</b>,  <b>alias</b>,  <b>forward</b>,  or
+              <b>include</b>.
+
        Other parameters of interest:
 
        <b>inet_interfaces</b>
-              The network interface addresses  that  this  system
+              The  network  interface  addresses that this system
               receives mail on.  You need to stop and start Post-
               fix when this parameter changes.
 
        <b>masquerade_classes</b>
-              List of address classes  subject  to  masquerading:
-              zero  or  more of <b>envelope_sender</b>, <b>envelope_recipi-</b>
+              List  of  address  classes subject to masquerading:
+              zero or more of  <b>envelope_sender</b>,  <b>envelope_recipi-</b>
               <b>ent</b>, <b>header_sender</b>, <b>header_recipient</b>.
 
        <b>masquerade_domains</b>
-              List of domains that hide  their  subdomain  struc-
+              List  of  domains  that hide their subdomain struc-
               ture.
 
        <b>masquerade_exceptions</b>
-              List  of user names that are not subject to address
+              List of user names that are not subject to  address
               masquerading.
 
        <b>mydestination</b>
-              List of domains that  this  mail  system  considers
+              List  of  domains  that  this mail system considers
               local.
 
        <b>myorigin</b>
@@ -195,7 +205,7 @@ CANONICAL(5)                                         CANONICAL(5)
        <a href="tcp_table.5.html">tcp_table(5)</a> TCP client/server table lookup protocol
 
 <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 10ec2edd7e11ce389deba913d328bb2a89eb7051..c283ca9016e8d069980190f468db0dfdb0af03e8 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 CLEANUP(8)                                             CLEANUP(8)
 
 <b>NAME</b>
@@ -200,6 +200,13 @@ CLEANUP(8)                                             CLEANUP(8)
               List of user names that are not subject to  address
               masquerading.
 
+       <b>propagate_unmatched_extensions</b>
+              A  list  of  address rewriting or forwarding mecha-
+              nisms that propagate an address extension from  the
+              original  address  to  the result.  Specify zero or
+              more of  <b>canonical</b>,  <b>virtual</b>,  <b>alias</b>,  <b>forward</b>,  or
+              <b>include</b>.
+
        <b>virtual_alias_maps</b>
               Address mapping lookup table for envelope recipient
               addresses.
index 17e7a3133446c4e03fc4c7c838d579475c5d031a..1f593d55fa6e0086c1062878d45c8cbef4e45faf 100644 (file)
@@ -1441,7 +1441,20 @@ the address does resolve to a name.
 <p>
 
 You run the Postfix SMTP server inside a <b>chroot</b> jail for
-extra security, but some configuration files are missing. In order
+extra security, but some configuration files are missing or have
+incorrect information. The command "postfix check" will report
+what files may have incorrect information. For example:
+
+<blockquote>
+<pre>
+warning: /var/spool/postfix/etc/resolv.conf and /etc/resolv.conf differ
+warning: /var/spool/postfix/etc/localtime and /etc/localtime differ
+</pre>
+</blockquote>
+
+<p>
+
+In order
 to run inside a chroot jail, the Postfix SMTP client and server
 need copies of system configuration files inside the Postfix queue
 directory.  The exact list of files is very system dependent, but
@@ -1776,7 +1789,8 @@ for the <b>/etc/resolv.conf</b> file.
 Check out your Postfix <b>master.cf</b> file. If the SMTP client
 runs chrooted, then it needs a bunch of files inside the Postfix
 queue directory.  Examples are in the source distribution in the
-<b>examples</b> subdirectory.
+<b>examples</b> subdirectory. See also the other FAQ entry on 
+<a href="#numerical_log">name service trouble</a>.
 
 </ul>
 
index 1f9342a088be080daef972168269f825e700f3f2..1d368f7618562947bf1ea9735e4af110b7cb16b2 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 LMTP(8)                                                   LMTP(8)
 
 <b>NAME</b>
@@ -37,7 +37,7 @@ LMTP(8)                                                   LMTP(8)
               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>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>   configuration   parameter  (default
+              <b>lmtp_tcp_port</b>   configuration   parameter  (default
               value of 24) will be used.
 
               The  LMTP  client  does  not   perform   MX   (mail
@@ -67,58 +67,58 @@ LMTP(8)                                                   LMTP(8)
        rupted message files are marked so that the queue  manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
-       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
+       Depending on the setting of the <b>notify_classes</b>  parameter,
        the  postmaster is notified of bounces, protocol problems,
        and of other trouble.
 
 <b>BUGS</b>
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
        The following <b>main.cf</b> parameters are  especially  relevant
        to  this  program. See the Postfix <b>main.cf</b> file for syntax
-       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
+       details and for default values.  Use  the  <b>postfix  reload</b>
        command after a configuration change.
 
 <b>Miscellaneous</b>
-       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+       <b>debug_peer_level</b>
               Verbose  logging  level  increment  for  hosts that
-              match a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> parameter.
+              match a pattern in the <b>debug_peer_list</b> parameter.
 
-       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+       <b>debug_peer_list</b>
               List of domain or network patterns. When  a  remote
               host  matches  a pattern, increase the verbose log-
               ging  level  by  the  amount   specified   in   the
-              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
+              <b>debug_peer_level</b> parameter.
 
-       <b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
+       <b>error_notice_recipient</b>
               Recipient    of   protocol/policy/resource/software
               error notices.
 
-       <b>notify</b><i>_</i><b>classes</b>
+       <b>notify_classes</b>
               When this parameter includes  the  <b>protocol</b>  class,
               send  mail  to  the  postmaster with transcripts of
               LMTP sessions with protocol errors.
 
-       <b>lmtp</b><i>_</i><b>skip</b><i>_</i><b>quit</b><i>_</i><b>response</b>
+       <b>lmtp_skip_quit_response</b>
               Do not wait for the server response  after  sending
               QUIT.
 
-       <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>
+       <b>lmtp_tcp_port</b>
               The  TCP  port to be used when connecting to a LMTP
               server.  Used as backup if the <b>lmtp</b> service is  not
               found in <b>services</b>(4).
 
-<b>Authentication</b> <b>controls</b>
-       <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>auth</b><i>_</i><b>enable</b>
+<b>Authentication controls</b>
+       <b>lmtp_sasl_auth_enable</b>
               Enable  per-session  authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
               (SASL).  By default, Postfix is built without  SASL
               support.
 
-       <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b>
+       <b>lmtp_sasl_password_maps</b>
               Lookup tables with per-host or domain <i>name</i>:<i>password</i>
               entries.  No entry for a host means no  attempt  to
               authenticate.
 
-       <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
+       <b>lmtp_sasl_security_options</b>
               Zero or more of the following.
 
               <b>noplaintext</b>
@@ -136,8 +136,8 @@ LMTP(8)                                                   LMTP(8)
               <b>noanonymous</b>
                      Disallow anonymous logins.
 
-<b>Resource</b> <b>controls</b>
-       <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
+<b>Resource controls</b>
+       <b>lmtp_cache_connection</b>
               Should  we cache the connection to the LMTP server?
               The effectiveness of  cached  connections  will  be
               determined  by  the  number of LMTP servers in use,
@@ -147,14 +147,14 @@ LMTP(8)                                                   LMTP(8)
 
               <b>o</b>      The LMTP client idle time limit is  reached.
                      This  limit  is  specified  with the Postfix
-                     <b>max</b><i>_</i><b>idle</b> configuration parameter.
+                     <b>max_idle</b> configuration parameter.
 
               <b>o</b>      A delivery  request  specifies  a  different
                      destination than the one currently cached.
 
               <b>o</b>      The  per-process  limit  on  the  number  of
                      delivery requests is reached.  This limit is
-                     specified  with the Postfix <b>max</b><i>_</i><b>use</b> configu-
+                     specified  with the Postfix <b>max_use</b> configu-
                      ration parameter.
 
               <b>o</b>      Upon the onset of another delivery  request,
@@ -162,20 +162,20 @@ LMTP(8)                                                   LMTP(8)
                      session does not respond to  the  <b>RSET</b>  com-
                      mand.
 
-       <i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+       <i>transport</i><b>_destination_concurrency_limit</b>
               Limit the number of parallel deliveries to the same
               destination  via  this  mail  delivery   transport.
               <i>transport</i>  is  the name of the service as specified
               in the <b>master.cf</b> file.  The default limit is  taken
-              from    the   <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+              from    the   <b>default_destination_concurrency_limit</b>
               parameter.
 
-       <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+       <i>transport</i><b>_destination_recipient_limit</b>
               Limit the number of recipients per message delivery
               via  this mail delivery transport. <i>transport</i> is the
               name of the service as specified in  the  <b>master.cf</b>
               file.    The   default  limit  is  taken  from  the
-              <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+              <b>default_destination_recipient_limit</b> parameter.
 
               This parameter  becomes  significant  if  the  LMTP
               client  is  used  for  local  delivery.   Some LMTP
@@ -191,51 +191,51 @@ LMTP(8)                                                   LMTP(8)
               of  recipients.   Exercise  care  when setting this
               parameter.
 
-<b>Timeout</b> <b>controls</b>
+<b>Timeout controls</b>
        The default time unit is seconds; an  explicit  time  unit
        can  be  specified by appending a one-letter suffix to the
        value: s (seconds), m (minutes), h (hours), d (days) or  w
        (weeks).
 
-       <b>lmtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
+       <b>lmtp_connect_timeout</b>
               Timeout  for  opening  a  connection  to  the  LMTP
               server.  If no connection can be  made  within  the
               deadline, the message is deferred.
 
-       <b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b>
+       <b>lmtp_lhlo_timeout</b>
               Timeout  for  sending  the  <b>LHLO</b>  command,  and for
               receiving the server response.
 
-       <b>lmtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b>
-              Timeout for sending the <b>MAIL</b> <b>FROM</b> command, and  for
+       <b>lmtp_mail_timeout</b>
+              Timeout for sending the <b>MAIL FROM</b> command, and  for
               receiving the server response.
 
-       <b>lmtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b>
-              Timeout  for  sending  the <b>RCPT</b> <b>TO</b> command, and for
+       <b>lmtp_rcpt_timeout</b>
+              Timeout  for  sending  the <b>RCPT TO</b> command, and for
               receiving the server response.
 
-       <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>init</b><i>_</i><b>timeout</b>
+       <b>lmtp_data_init_timeout</b>
               Timeout for  sending  the  <b>DATA</b>  command,  and  for
               receiving the server response.
 
-       <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
+       <b>lmtp_data_xfer_timeout</b>
               Timeout for sending the message content.
 
-       <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>done</b><i>_</i><b>timeout</b>
+       <b>lmtp_data_done_timeout</b>
               Timeout  for  sending  the  "<b>.</b>"  command,  and  for
               receiving the server response. When no response  is
               received,  a warning is logged that the mail may be
               delivered multiple times.
 
-       <b>lmtp</b><i>_</i><b>rset</b><i>_</i><b>timeout</b>
+       <b>lmtp_rset_timeout</b>
               Timeout for  sending  the  <b>RSET</b>  command,  and  for
               receiving the server response.
 
-       <b>lmtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b>
+       <b>lmtp_quit_timeout</b>
               Timeout  for  sending  the  <b>QUIT</b>  command,  and for
               receiving the server response.
 
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
        <a href="bounce.8.html">bounce(8)</a> non-delivery status reports
        <a href="local.8.html">local(8)</a> local mail delivery
        <a href="master.8.html">master(8)</a> process manager
index ab2f45f0e2b686967297cbfc0419d5895c10ca89..67fab1c9040e4acc3eafdd880bacca8c4f01fc00 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 LOCAL(8)                                                 LOCAL(8)
 
 <b>NAME</b>
@@ -31,20 +31,20 @@ LOCAL(8)                                                 LOCAL(8)
 
        The  system  administrator can specify a comma/space sepa-
        rated list of  ~/.<b>forward</b>  like  files  through  the  <b>for-</b>
-       <b>ward</b><i>_</i><b>path</b>  configuration  parameter.  Upon  delivery,  the
+       <b>ward_path</b>  configuration  parameter.  Upon  delivery,  the
        local delivery agent tries each pathname in the list until
-       a file is found.  The <b>forward</b><i>_</i><b>path</b> parameter is subject to
+       a file is found.  The <b>forward_path</b> parameter is subject to
        interpolation of <b>$user</b> (recipient username), <b>$home</b> (recip-
        ient home directory), <b>$shell</b> (recipient shell), <b>$recipient</b>
        (complete  recipient   address),   <b>$extension</b>   (recipient
        address  extension),  <b>$domain</b>  (recipient  domain),  <b>local</b>
-       (entire recipient address localpart) and <b>$recipient</b><i>_</i><b>delim-</b>
+       (entire recipient address localpart) and <b>$recipient_delim-</b>
        <b>iter.</b>  The  forms  <i>${name?value}</i>  and <i>${name:value}</i> expand
        conditionally to <i>value</i> when <i>$name</i>  is  (is  not)  defined.
        Characters  that  may have special meaning to the shell or
        file system are replaced  by  underscores.   The  list  of
-       acceptable characters is specified with the <b>forward</b><i>_</i><b>expan-</b>
-       <b>sion</b><i>_</i><b>filter</b> configuration parameter.
+       acceptable characters is specified with the <b>forward_expan-</b>
+       <b>sion_filter</b> configuration parameter.
 
        An alias or ~/.<b>forward</b> file may list  any  combination  of
        external   commands,  destination  file  names,  <b>:include:</b>
@@ -61,11 +61,11 @@ LOCAL(8)                                                 LOCAL(8)
        In order to prevent the mail system from using  up  unrea-
        sonable   amounts  of  memory,  input  records  read  from
        <b>:include:</b> or from ~/.<b>forward</b>  files  are  broken  up  into
-       chunks of length <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>.
+       chunks of length <b>line_length_limit</b>.
 
        While  expanding aliases, ~/.<b>forward</b> files, and so on, the
        program attempts to avoid duplicate deliveries. The <b>dupli-</b>
-       <b>cate</b><i>_</i><b>filter</b><i>_</i><b>limit</b>  configuration parameter limits the num-
+       <b>cate_filter_limit</b>  configuration parameter limits the num-
        ber of remembered recipients.
 
 <b>MAIL FORWARDING</b>
@@ -74,51 +74,51 @@ LOCAL(8)                                                 LOCAL(8)
        rate on-file delivery status record.
 
        In order to stop mail forwarding loops early, the software
-       adds  an  optional  <b>Delivered-To:</b> header with the envelope
-       recipient address. If mail arrives for a recipient that is
-       already  listed  in a <b>Delivered-To:</b> header, the message is
-       bounced.
+       adds an optional <b>Delivered-To:</b> header with the final enve-
+       lope recipient address. If mail arrives  for  a  recipient
+       that is already listed in a <b>Delivered-To:</b> header, the mes-
+       sage is bounced.
 
 <b>MAILBOX DELIVERY</b>
        The default per-user mailbox is a file in  the  UNIX  mail
        spool  directory (<b>/var/mail/</b><i>user</i> or <b>/var/spool/mail/</b><i>user</i>);
-       the location can be specified with  the  <b>mail</b><i>_</i><b>spool</b><i>_</i><b>direc-</b>
+       the location can be specified with  the  <b>mail_spool_direc-</b>
        <b>tory</b>  configuration  parameter. Specify a name ending in <b>/</b>
        for <b>qmail</b>-compatible <b>maildir</b> delivery.
 
        Alternatively, the per-user mailbox can be a file  in  the
        user's  home  directory  with  a  name  specified  via the
-       <b>home</b><i>_</i><b>mailbox</b> configuration parameter. Specify  a  relative
+       <b>home_mailbox</b> configuration parameter. Specify  a  relative
        path name. Specify a name ending in <b>/</b> for <b>qmail</b>-compatible
        <b>maildir</b> delivery.
 
        Mailbox delivery can be delegated to an  external  command
-       specified  with  the <b>mailbox</b><i>_</i><b>command</b> configuration parame-
+       specified  with  the <b>mailbox_command</b> configuration parame-
        ter. The command  executes  with  the  privileges  of  the
        recipient  user  (exception:  in case of delivery as root,
        the   command   executes   with    the    privileges    of
-       <b>default</b><i>_</i><b>privs</b>).
+       <b>default_privs</b>).
 
        Mailbox  delivery  can be delegated to alternative message
        transports specified in the  <b>master.cf</b>  file.   The  <b>mail-</b>
-       <b>box</b><i>_</i><b>transport</b>  configuration parameter specifies a message
+       <b>box_transport</b>  configuration parameter specifies a message
        transport that is to be used  for  all  local  recipients,
        regardless  of  whether  they are found in the UNIX passwd
-       database.  The <b>fallback</b><i>_</i><b>transport</b>  parameter  specifies  a
+       database.  The <b>fallback_transport</b>  parameter  specifies  a
        message transport for recipients that are not found in the
        UNIX passwd database.
 
        In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
-       mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
+       mon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" envelope header to
        each message, prepends an <b>X-Original-To:</b> header  with  the
        recipient   address  as  given  to  Postfix,  prepends  an
-       optional <b>Delivered-To:</b> header with the envelope  recipient
-       address,  prepends a <b>Return-Path:</b> header with the envelope
-       sender address, prepends a &gt; character to lines  beginning
-       with  "<b>From</b>  ", and appends an empty line.  The mailbox is
-       locked for exclusive access while delivery is in progress.
-       In  case  of  problems, an attempt is made to truncate the
-       mailbox to its original length.
+       optional <b>Delivered-To:</b>  header  with  the  final  envelope
+       recipient address, prepends a <b>Return-Path:</b> header with the
+       envelope sender address, prepends a &gt; character  to  lines
+       beginning  with  "<b>From</b>  ", and appends an empty line.  The
+       mailbox is locked for exclusive access while  delivery  is
+       in  progress.  In  case of problems, an attempt is made to
+       truncate the mailbox to its original length.
 
        In the case of <b>maildir</b> delivery, the local daemon prepends
        an  optional  <b>Delivered-To:</b> header with the final envelope
@@ -127,7 +127,7 @@ LOCAL(8)                                                 LOCAL(8)
        <b>Return-Path:</b> header with the envelope sender address.
 
 <b>EXTERNAL COMMAND DELIVERY</b>
-       The   <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>    configuration    parameter
+       The   <b>allow_mail_to_commands</b>    configuration    parameter
        restricts  delivery to external commands. The default set-
        ting (<b>alias,  forward</b>)  forbids  command  destinations  in
        <b>:include:</b> files.
@@ -140,15 +140,15 @@ LOCAL(8)                                                 LOCAL(8)
        A limited amount of command output  (standard  output  and
        standard  error) is captured for inclusion with non-deliv-
        ery status reports.  A command is forcibly  terminated  if
-       it  does  not  complete within <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> seconds.
+       it  does  not  complete within <b>command_time_limit</b> seconds.
        Command exit status codes are expected to follow the  con-
        ventions defined in &lt;<b>sysexits.h</b>&gt;.
 
        A  limited amount of message context is exported via envi-
        ronment variables. Characters that may have special  mean-
        ing to the shell are replaced by underscores.  The list of
-       acceptable characters is specified with the <b>command</b><i>_</i><b>expan-</b>
-       <b>sion</b><i>_</i><b>filter</b> configuration parameter.
+       acceptable characters is specified with the <b>command_expan-</b>
+       <b>sion_filter</b> configuration parameter.
 
        <b>SHELL</b>  The recipient user's login shell.
 
@@ -174,60 +174,62 @@ LOCAL(8)                                                 LOCAL(8)
 
        The <b>PATH</b> environment variable is always reset to a system-
        dependent  default  path,  and environment variables whose
-       names are blessed by the <b>export</b><i>_</i><b>environment</b>  configuration
+       names are blessed by the <b>export_environment</b>  configuration
        parameter are exported unchanged.
 
        The current working directory is the mail queue directory.
 
-       The <b>local</b> daemon prepends a "<b>From</b> <i>sender time_stamp</i>" enve-
+       The <b>local</b> daemon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" enve-
        lope  header  to  each message, prepends an <b>X-Original-To:</b>
        header with the recipient address  as  given  to  Postfix,
-       prepends an optional <b>Delivered-To:</b> header with the recipi-
-       ent envelope address, prepends a <b>Return-Path:</b> header  with
-       the sender envelope address, and appends no empty line.
+       prepends  an  optional <b>Delivered-To:</b> header with the final
+       recipient envelope address, prepends a <b>Return-Path:</b> header
+       with  the  sender  envelope  address, and appends no empty
+       line.
 
 <b>EXTERNAL FILE DELIVERY</b>
-       The  delivery  format  depends on the destination filename
-       syntax.  The default is to use UNIX-style mailbox  format.
-       Specify  a  name  ending in <b>/</b> for <b>qmail</b>-compatible <b>maildir</b>
+       The delivery format depends on  the  destination  filename
+       syntax.   The default is to use UNIX-style mailbox format.
+       Specify a name ending in <b>/</b>  for  <b>qmail</b>-compatible  <b>maildir</b>
        delivery.
 
-       The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b> configuration parameter  restricts
-       delivery  to  external  files. The default setting (<b>alias,</b>
+       The  <b>allow_mail_to_files</b> configuration parameter restricts
+       delivery to external files. The  default  setting  (<b>alias,</b>
        <b>forward</b>) forbids file destinations in <b>:include:</b> files.
 
        In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
-       mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
-       each message, prepends an <b>X-Original-To:</b> header  with  the
-       recipient   address  as  given  to  Postfix,  prepends  an
-       optional <b>Delivered-To:</b> header with the recipient  envelope
-       address,  prepends  a  &gt; character to lines beginning with
-       "<b>From</b> ", and appends an empty line.  The  envelope  sender
-       address is available in the <b>Return-Path:</b> header.  When the
-       destination is a regular file, it is locked for  exclusive
-       access while delivery is in progress. In case of problems,
-       an attempt is made to truncate a regular file to its orig-
-       inal length.
+       mon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" envelope header to
+       each  message,  prepends an <b>X-Original-To:</b> header with the
+       recipient  address  as  given  to  Postfix,  prepends   an
+       optional  <b>Delivered-To:</b>  header  with  the final recipient
+       envelope address, prepends a &gt; character to  lines  begin-
+       ning  with  "<b>From</b> ", and appends an empty line.  The enve-
+       lope sender  address  is  available  in  the  <b>Return-Path:</b>
+       header.   When  the  destination  is a regular file, it is
+       locked for exclusive access while delivery is in progress.
+       In case of problems, an attempt is made to truncate a reg-
+       ular file to its original length.
 
        In the case of <b>maildir</b> delivery, the local daemon prepends
-       an optional <b>Delivered-To:</b> header with the envelope recipi-
-       ent  address,  and  prepends an <b>X-Original-To:</b> header with
-       the recipient address as given to Postfix.   The  envelope
-       sender address is available in the <b>Return-Path:</b> header.
+       an  optional  <b>Delivered-To:</b> header with the final envelope
+       recipient address, and prepends an  <b>X-Original-To:</b>  header
+       with the recipient address as given to Postfix.  The enve-
+       lope sender  address  is  available  in  the  <b>Return-Path:</b>
+       header.
 
 <b>ADDRESS EXTENSION</b>
-       The  optional  <b>recipient</b><i>_</i><b>delimiter</b> configuration parameter
+       The  optional  <b>recipient_delimiter</b> configuration parameter
        specifies how to separate address  extensions  from  local
        recipient names.
 
-       For  example,  with  "<b>recipient</b><i>_</i><b>delimiter  =  +</b>", mail for
+       For  example,  with  "<b>recipient_delimiter  =  +</b>", mail for
        <i>name</i>+<i>foo</i> is delivered to the  alias  <i>name</i>+<i>foo</i>  or  to  the
        alias  <i>name</i>,  to  the  destinations  listed in ~<i>name</i>/.<b>for-</b>
        <b>ward</b>+<i>foo</i> or in ~<i>name</i>/.<b>forward</b>, to the mailbox owned by the
        user <i>name</i>, or it is sent back as undeliverable.
 
        In all cases the <b>local</b> daemon prepends an optional `<b>Deliv-</b>
-       <b>ered-To:</b> <i>name</i>+<i>foo</i>' header line.
+       <b>ered-To:</b> header line with the final recipient address.
 
 <b>DELIVERY RIGHTS</b>
        Deliveries to external files  and  external  commands  are
@@ -236,7 +238,7 @@ LOCAL(8)                                                 LOCAL(8)
        the  <b>local</b>  daemon  uses the owner rights of the <b>:include:</b>
        file or alias database.  When those files are owned by the
        superuser, delivery is made with the rights specified with
-       the <b>default</b><i>_</i><b>privs</b> configuration parameter.
+       the <b>default_privs</b> configuration parameter.
 
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
@@ -246,7 +248,7 @@ LOCAL(8)                                                 LOCAL(8)
        rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue afterwards.
 
-       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
+       Depending on the setting of the <b>notify_classes</b>  parameter,
        the  postmaster  is notified of bounces and of other trou-
        ble.
 
@@ -268,176 +270,183 @@ LOCAL(8)                                                 LOCAL(8)
        command after a configuration change.
 
 <b>Miscellaneous</b>
-       <b>alias</b><i>_</i><b>maps</b>
+       <b>alias_maps</b>
               List of alias databases.
 
        <b>biff</b>   Enable  or disable notification of new mail via the
               <b>comsat</b> network service.
 
-       <b>expand</b><i>_</i><b>owner</b><i>_</i><b>alias</b>
+       <b>expand_owner_alias</b>
               When delivering to an alias that has an owner- com-
               panion  alias,  set  the envelope sender address to
               the right-hand side of  the  owner  alias,  instead
               using of the left-hand side address.
 
-       <b>export</b><i>_</i><b>environment</b>
+       <b>export_environment</b>
               List of names of environment parameters that can be
               exported to non-Postfix processes.
 
-       <b>forward</b><i>_</i><b>path</b>
+       <b>forward_path</b>
               Search list for .forward files.  The names are sub-
               ject to <i>$name</i> expansion.
 
-       <b>local</b><i>_</i><b>command</b><i>_</i><b>shell</b>
+       <b>local_command_shell</b>
               Shell  to  use  for external command execution (for
               example, /some/where/smrsh -c).  When  a  shell  is
               specified, it is invoked even when the command con-
               tains no shell built-in commands  or  meta  charac-
               ters.
 
-       <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+       <b>owner_request_special</b>
               Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
               addresses.
 
-       <b>prepend</b><i>_</i><b>delivered</b><i>_</i><b>header</b>
+       <b>prepend_delivered_header</b>
               Prepend  an  optional  <b>Delivered-To:</b>  header   upon
               external  forwarding,  delivery to command or file.
               Specify zero or more of:  <b>command,  file,  forward</b>.
               Turning  off  <b>Delivered-To:</b> when forwarding mail is
               not recommended.
 
-       <b>recipient</b><i>_</i><b>delimiter</b>
+       <b>propagate_unmatched_extensions</b>
+              A list of address rewriting  or  forwarding  mecha-
+              nisms  that propagate an address extension from the
+              original address to the result.   Specify  zero  or
+              more  of  <b>canonical</b>,  <b>virtual</b>,  <b>alias</b>,  <b>forward</b>, or
+              <b>include</b>.
+
+       <b>recipient_delimiter</b>
               Separator between username and address extension.
 
-       <b>require</b><i>_</i><b>home</b><i>_</i><b>directory</b>
+       <b>require_home_directory</b>
               Require that a recipient's home directory is acces-
               sible  by the recipient before attempting delivery.
               Defer delivery otherwise.
 
 <b>Mailbox delivery</b>
-       <b>fallback</b><i>_</i><b>transport</b>
+       <b>fallback_transport</b>
               Message transport for recipients that are not found
               in  the UNIX passwd database.  This parameter over-
-              rides <b>luser</b><i>_</i><b>relay</b>.
+              rides <b>luser_relay</b>.
 
-              Note: you must update the <b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> set-
+              Note: you must update the <b>local_recipient_maps</b> set-
               ting  in  the  <b>main.cf</b>  file, otherwise the Postfix
               SMTP server will reject mail for non-UNIX  accounts
               with "<b>User unknown in local recipient table</b>".
 
-       <b>home</b><i>_</i><b>mailbox</b>
+       <b>home_mailbox</b>
               Pathname  of  a  mailbox  relative to a user's home
               directory.  Specify a path ending in <b>/</b> for maildir-
               style delivery.
 
-       <b>luser</b><i>_</i><b>relay</b>
+       <b>luser_relay</b>
               Destination  (<i>@domain</i>  or <i>address</i>) for non-existent
               users.  The <i>address</i> is subjected  to  <i>$name</i>  expan-
               sion.
 
-              Note:  you  must  specify  "<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps =</b>"
+              Note:  you  must  specify  "<b>local_recipient_maps =</b>"
               (i.e. empty) in the  <b>main.cf</b>  file,  otherwise  the
               Postfix  SMTP  server will reject mail for non-UNIX
               accounts with  "<b>User  unknown  in  local  recipient</b>
               <b>table</b>".
 
-       <b>mail</b><i>_</i><b>spool</b><i>_</i><b>directory</b>
+       <b>mail_spool_directory</b>
               Directory  with  UNIX-style  mailboxes. The default
               pathname is system dependent.  Specify a path  end-
               ing in <b>/</b> for maildir-style delivery.
 
-       <b>mailbox</b><i>_</i><b>command</b>
+       <b>mailbox_command</b>
               External  command  to use for mailbox delivery. The
               command  executes  with  the  recipient  privileges
               (exception:  root).  The string is subject to $name
               expansions.
 
-       <b>mailbox</b><i>_</i><b>command</b><i>_</i><b>maps</b>
+       <b>mailbox_command_maps</b>
               Lookup tables with per-recipient external  commands
               to  use  for  mailbox delivery. Behavior is as with
-              <b>mailbox</b><i>_</i><b>command</b>.
+              <b>mailbox_command</b>.
 
-       <b>mailbox</b><i>_</i><b>transport</b>
+       <b>mailbox_transport</b>
               Message transport to use for  mailbox  delivery  to
               all local recipients, whether or not they are found
               in the UNIX passwd database.  This parameter  over-
               rides  all other configuration parameters that con-
-              trol mailbox delivery, including <b>luser</b><i>_</i><b>relay</b>.
+              trol mailbox delivery, including <b>luser_relay</b>.
 
               Note: if you use this feature to receive  mail  for
               non-UNIX   accounts   then   you  must  update  the
-              <b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> setting in the  <b>main.cf</b>  file,
+              <b>local_recipient_maps</b> setting in the  <b>main.cf</b>  file,
               otherwise  the Postfix SMTP server will reject mail
               for non-UNIX accounts with "<b>User unknown  in  local</b>
               <b>recipient table</b>".
 
 <b>Locking controls</b>
-       <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
+       <b>deliver_lock_attempts</b>
               Limit  the  number of attempts to acquire an exclu-
               sive lock on a mailbox or external file.
 
-       <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
+       <b>deliver_lock_delay</b>
               Time in  seconds  between  successive  attempts  to
               acquire an exclusive lock.
 
-       <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
+       <b>stale_lock_time</b>
               Limit the time after which a stale lock is removed.
 
-       <b>mailbox</b><i>_</i><b>delivery</b><i>_</i><b>lock</b>
+       <b>mailbox_delivery_lock</b>
               What file locking method(s) to use when  delivering
               to  a  UNIX-style  mailbox.  The default setting is
               system dependent.  For a  list  of  available  file
               locking methods, use the <b>postconf -l</b> command.
 
 <b>Resource controls</b>
-       <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>
+       <b>command_time_limit</b>
               Limit  the  amount of time for delivery to external
               command.
 
-       <b>duplicate</b><i>_</i><b>filter</b><i>_</i><b>limit</b>
+       <b>duplicate_filter_limit</b>
               Limit the size of the duplicate filter for  results
               from alias etc. expansion.
 
-       <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
+       <b>line_length_limit</b>
               Limit  the  amount  of memory used for processing a
               partial input line.
 
-       <b>local</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+       <b>local_destination_concurrency_limit</b>
               Limit the number of parallel deliveries to the same
               user.    The   default  limit  is  taken  from  the
-              <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
+              <b>default_destination_concurrency_limit</b> parameter.
 
-       <b>local</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+       <b>local_destination_recipient_limit</b>
               Limit the number of recipients per  message  deliv-
               ery.    The   default   limit  is  taken  from  the
-              <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+              <b>default_destination_recipient_limit</b> parameter.
 
-       <b>mailbox</b><i>_</i><b>size</b><i>_</i><b>limit</b>
+       <b>mailbox_size_limit</b>
               Limit the size of a mailbox  etc.  file  (any  file
               that  is written to upon delivery).  Set to zero to
               disable the limit.
 
 <b>Security controls</b>
-       <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
+       <b>allow_mail_to_commands</b>
               Restrict the usage of  mail  delivery  to  external
               command.   Specify zero or more of: <b>alias</b>, <b>forward</b>,
               <b>include</b>.
 
-       <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b>
+       <b>allow_mail_to_files</b>
               Restrict the usage of  mail  delivery  to  external
               file.   Specify  zero  or  more of: <b>alias</b>, <b>forward</b>,
               <b>include</b>.
 
-       <b>command</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
+       <b>command_expansion_filter</b>
               What characters are  allowed  to  appear  in  $name
               expansions  of  mailbox_command. Illegal characters
               are replaced by underscores.
 
-       <b>default</b><i>_</i><b>privs</b>
+       <b>default_privs</b>
               Default rights for delivery  to  external  file  or
               command.
 
-       <b>forward</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
+       <b>forward_expansion_filter</b>
               What  characters  are  allowed  to  appear in $name
               expansions of forward_path. Illegal characters  are
               replaced by underscores.
index 09a3169c1fea6295ba07396aa4e877401ad76f1a..56f2fd370cb3b5fcca55305c6b93f9f86f0f7359 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 POSTALIAS(1)                                         POSTALIAS(1)
 
 <b>NAME</b>
@@ -71,14 +71,14 @@ POSTALIAS(1)                                         POSTALIAS(1)
               ate a new  file  with  default  access  permissions
               (mode 0644).
 
-       <b>-q</b> <i>key</i> Search  the  specified  maps  for <i>key</i> and print the
-              first value found on the  standard  output  stream.
+       <b>-q</b> <i>key</i> Search  the  specified  maps  for <i>key</i> and write the
+              first value found to the  standard  output  stream.
               The exit status is zero when the requested informa-
               tion was found.
 
               If a key value of <b>-</b> is specified, the program reads
               key  values  from  the  standard  input  stream and
-              prints one line of <i>key: value</i> output for  each  key
+              writes one line of <i>key: value</i> output for  each  key
               that  was  found.  The  exit status is zero when at
               least one of the requested keys was found.
 
index cbdf2d5c6ab4f6659831f7b64ffe098e9a8d313a..173d9bf31c66918f5c30c575498889bab1a3577b 100644 (file)
@@ -1,17 +1,17 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 SENDMAIL(1)                                           SENDMAIL(1)
 
 <b>NAME</b>
        sendmail - Postfix to Sendmail compatibility interface
 
 <b>SYNOPSIS</b>
-       <b>sendmail</b> [<i>option</i> <i>...</i>] [<i>recipient</i> <i>...</i>]
+       <b>sendmail</b> [<i>option ...</i>] [<i>recipient ...</i>]
 
        <b>mailq</b>
-       <b>sendmail</b> <b>-bp</b>
+       <b>sendmail -bp</b>
 
        <b>newaliases</b>
-       <b>sendmail</b> <b>-I</b>
+       <b>sendmail -I</b>
 
 <b>DESCRIPTION</b>
        The  <b>sendmail</b>  program  implements the Postfix to Sendmail
@@ -40,9 +40,9 @@ SENDMAIL(1)                                           SENDMAIL(1)
               Initialize the alias database.  If no input file is
               specified (with the <b>-oA</b>  option,  see  below),  the
               program  processes  the  file(s) specified with the
-              <b>alias</b><i>_</i><b>database</b>  configuration  parameter.   If   no
+              <b>alias_database</b>  configuration  parameter.   If   no
               alias  database type is specified, the program uses
-              the type specified with  the  <b>default</b><i>_</i><b>database</b><i>_</i><b>type</b>
+              the type specified with  the  <b>default_database_type</b>
               configuration parameter.  This mode of operation is
               implemented by running the <a href="postalias.1.html"><b>postalias</b>(1)</a> command.
 
@@ -64,14 +64,14 @@ SENDMAIL(1)                                           SENDMAIL(1)
               regardless of whether or not a message is  an  ini-
               tial submission.
 
-       <b>-B</b> <i>body_type</i>
+       <b>-B</b> <i>body</i><b>_</b><i>type</i>
               The message body MIME type: <b>7BIT</b> or <b>8BITMIME</b>.
 
-       <b>-C</b> <i>config_file</i> (ignored :-)
+       <b>-C</b> <i>config</i><b>_</b><i>file</i> (ignored :-)
               The path name of the <b>sendmail.cf</b> file. Postfix con-
               figuration files are kept in <b>/etc/postfix</b>.
 
-       <b>-F</b> <i>full_name</i>
+       <b>-F</b> <i>full</i><b>_</b><i>name</i>
               Set the sender full name. This is  used  only  with
               messages that have no <b>From:</b> message header.
 
@@ -83,20 +83,20 @@ SENDMAIL(1)                                           SENDMAIL(1)
               mand above.
 
        <b>-L</b> <i>label</i> (ignored)
-              The  logging  label. Use the <b>syslog</b><i>_</i><b>name</b> configura-
+              The  logging  label. Use the <b>syslog_name</b> configura-
               tion parameter instead.
 
        <b>-N</b> <i>dsn</i> (ignored)
               Delivery status  notification  control.  Currently,
               Postfix does not implement <b>DSN</b>.
 
-       <b>-R</b> <i>return_limit</i> (ignored)
+       <b>-R</b> <i>return</i><b>_</b><i>limit</i> (ignored)
               Limit   the   size   of   bounced   mail.  Use  the
-              <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b> configuration parameter  instead.
+              <b>bounce_size_limit</b> configuration parameter  instead.
 
-       <b>-X</b> <i>log_file</i> (ignored)
-              Log  mailer  traffic.  Use  the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
-              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters  instead.
+       <b>-X</b> <i>log</i><b>_</b><i>file</i> (ignored)
+              Log  mailer  traffic.  Use  the <b>debug_peer_list</b> and
+              <b>debug_peer_level</b> configuration parameters  instead.
 
        <b>-U</b> (ignored)
               Initial user submission.
@@ -109,16 +109,16 @@ SENDMAIL(1)                                           SENDMAIL(1)
               By  default,  the  personalized   envelope   sender
               address  is  <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>. The
               default <b>+</b> and <b>=</b> characters  are  configurable  with
-              the  <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration parame-
+              the  <b>default_verp_delimiters</b>  configuration parame-
               ter.
 
        <b>-V</b><i>xy</i>   As <b>-V</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter char-
               acters,  instead  of  the characters specified with
-              the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>  configuration  parame-
+              the <b>default_verp_delimiters</b>  configuration  parame-
               ter.
 
        <b>-bd</b>    Go  into  daemon  mode.  This  mode of operation is
-              implemented by executing the <b>postfix</b> <b>start</b> command.
+              implemented by executing the <b>postfix start</b> command.
 
        <b>-bi</b>    Initialize  alias database. See the <b>newaliases</b> com-
               mand above.
@@ -133,7 +133,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
               dard  output.  In stand-alone SMTP server mode, UCE
               restrictions and access controls  are  disabled  by
               default.  To  enable  them,  run the process as the
-              <b>mail</b><i>_</i><b>owner</b> user.
+              <b>mail_owner</b> user.
 
               This mode of operation is  implemented  by  running
               the <a href="smtpd.8.html"><b>smtpd</b>(8)</a> daemon.
@@ -148,8 +148,8 @@ SENDMAIL(1)                                           SENDMAIL(1)
               address where delivery problems are sent to, unless
               the message contains an <b>Errors-To:</b> message  header.
 
-       <b>-h</b> <i>hop_count</i> (ignored)
-              Hop  count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
+       <b>-h</b> <i>hop</i><b>_</b><i>count</i> (ignored)
+              Hop  count limit. Use the <b>hopcount_limit</b> configura-
               tion parameter instead.
 
        <b>-i</b>     When reading a message from standard  input,  don't
@@ -162,7 +162,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
        <b>-n</b> (ignored)
               Backwards compatibility.
 
-       <b>-oA</b><i>alias_database</i>
+       <b>-oA</b><i>alias</i><b>_</b><i>database</i>
               Non-default alias  database.  Specify  <i>pathname</i>  or
               <i>type</i>:<i>pathname</i>. See <a href="postalias.1.html"><b>postalias</b>(1)</a> for details.
 
@@ -181,7 +181,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
               The  sender  is  never  eliminated  from alias etc.
               expansions.
 
-       <b>-o</b> <i>x</i> <i>value</i> (ignored)
+       <b>-o</b> <i>x value</i> (ignored)
               Set option <i>x</i> to <i>value</i>. Use the equivalent  configu-
               ration parameter in <b>main.cf</b> instead.
 
@@ -195,7 +195,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        <b>-q</b><i>interval</i> (ignored)
               The   interval   between   queue   runs.   Use  the
-              <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b> configuration parameter instead.
+              <b>queue_run_delay</b> configuration parameter instead.
 
        <b>-qR</b><i>site</i>
               Schedule immediate delivery of  all  mail  that  is
@@ -207,7 +207,7 @@ SENDMAIL(1)                                           SENDMAIL(1)
 
        <b>-qS</b><i>site</i>
               This  command  is  not  implemented. Use the slower
-              <b>sendmail</b> <b>-q</b> command instead.
+              <b>sendmail -q</b> command instead.
 
        <b>-t</b>     Extract recipients from message headers. These  are
               added  to  any  recipients specified on the command
@@ -229,101 +229,101 @@ SENDMAIL(1)                                           SENDMAIL(1)
        error stream.
 
 <b>ENVIRONMENT</b>
-       <b>MAIL</b><i>_</i><b>CONFIG</b>
+       <b>MAIL_CONFIG</b>
               Directory with Postfix configuration files.
 
-       <b>MAIL</b><i>_</i><b>VERBOSE</b>
+       <b>MAIL_VERBOSE</b>
               Enable verbose logging for debugging purposes.
 
-       <b>MAIL</b><i>_</i><b>DEBUG</b>
+       <b>MAIL_DEBUG</b>
               Enable debugging with an external command, as spec-
-              ified  with  the   <b>debugger</b><i>_</i><b>command</b>   configuration
+              ified  with  the   <b>debugger_command</b>   configuration
               parameter.
 
 <b>FILES</b>
        /var/spool/postfix, mail queue
        /etc/postfix, configuration files
 
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
        See  the  Postfix  <b>main.cf</b> file for syntax details and for
-       default values. Use the <b>postfix</b>  <b>reload</b>  command  after  a
+       default values. Use the <b>postfix  reload</b>  command  after  a
        configuration change.
 
-       <b>alias</b><i>_</i><b>database</b>
+       <b>alias_database</b>
               Default   alias  database(s)  for  <b>newaliases</b>.  The
               default value for  this  parameter  is  system-spe-
               cific.
 
-       <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
+       <b>bounce_size_limit</b>
               The amount of original message context that is sent
               along with a non-delivery notification.
 
-       <b>default</b><i>_</i><b>database</b><i>_</i><b>type</b>
+       <b>default_database_type</b>
               Default alias etc. database type. On many UNIX sys-
               tems the default type is either <b>dbm</b> or <b>hash</b>.
 
-       <b>debugger</b><i>_</i><b>command</b>
+       <b>debugger_command</b>
               Command that is executed after a Postfix daemon has
               initialized.
 
-       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+       <b>debug_peer_level</b>
               Increment in verbose logging level  when  a  remote
-              host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+              host  matches  a  pattern  in  the  <b>debug_peer_list</b>
               parameter.
 
-       <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+       <b>debug_peer_list</b>
               List of domain or network patterns. When  a  remote
               host  matches  a pattern, increase the verbose log-
               ging  level  by  the  amount   specified   in   the
-              <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
+              <b>debug_peer_level</b> parameter.
 
-       <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
+       <b>default_verp_delimiters</b>
               The  VERP  delimiter  characters that are used when
               the <b>-V</b> command line  option  is  specified  without
               delimiter characters.
 
-       <b>fast</b><i>_</i><b>flush</b><i>_</i><b>domains</b>
+       <b>fast_flush_domains</b>
               List of domains that will receive "fast flush" ser-
               vice (default: all  domains  that  this  system  is
               willing  to relay mail to). This list specifies the
               domains that  Postfix  accepts  in  the  SMTP  <b>ETRN</b>
-              request and in the <b>sendmail</b> <b>-qR</b> command.
+              request and in the <b>sendmail -qR</b> command.
 
-       <b>fork</b><i>_</i><b>attempts</b>
+       <b>fork_attempts</b>
               Number  of attempts to <b>fork</b>() a process before giv-
               ing up.
 
-       <b>fork</b><i>_</i><b>delay</b>
+       <b>fork_delay</b>
               Delay  in   seconds   between   successive   <b>fork</b>()
               attempts.
 
-       <b>hopcount</b><i>_</i><b>limit</b>
+       <b>hopcount_limit</b>
               Limit the number of <b>Received:</b> message headers.
 
-       <b>mail</b><i>_</i><b>owner</b>
+       <b>mail_owner</b>
               The  owner  of  the  mail queue and of most Postfix
               processes.
 
-       <b>command</b><i>_</i><b>directory</b>
+       <b>command_directory</b>
               Directory with Postfix support commands.
 
-       <b>daemon</b><i>_</i><b>directory</b>
+       <b>daemon_directory</b>
               Directory with Postfix daemon programs.
 
-       <b>queue</b><i>_</i><b>directory</b>
+       <b>queue_directory</b>
               Top-level directory of the Postfix queue.  This  is
               also the root directory of Postfix daemons that run
               chrooted.
 
-       <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
+       <b>queue_run_delay</b>
               The time between successive scans of  the  deferred
               queue.
 
-       <b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
+       <b>verp_delimiter_filter</b>
               The  characters that Postfix accepts as VERP delim-
               iter characters.
 
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
        <a href="pickup.8.html">pickup(8)</a> mail pickup daemon
        <a href="postsuper.1.html">postsuper(1)</a> queue maintenance
        <a href="postalias.1.html">postalias(1)</a> maintain alias database
index 864b182a4e1e27f38263b08e5a4932c1cf1772cd..b9e87a03eafb166b06f7579d67deabc3574790ad 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 SMTPD(8)                                                 SMTPD(8)
 
 <b>NAME</b>
@@ -62,53 +62,61 @@ SMTPD(8)                                                 SMTPD(8)
               with comments that Sendmail allows.
 
        <b>broken_sasl_auth_clients</b>
-              Support older Microsoft clients that  mis-implement
-              the AUTH protocol, and that expect an EHLO response
-              of "250 AUTH=list" instead of "250 AUTH list".
+              Support Microsoft clients that implement  an  older
+              version  of  the  AUTH protocol, and that expect an
+              EHLO response of "250 AUTH=list"  instead  of  "250
+              AUTH list".
+
+       <b>smtpd_sasl_exceptions_networks</b>
+              Don't offer AUTH in the response to EHLO when talk-
+              ing to clients in the specified networks.  This  is
+              a  workaround  for clients that that demand a login
+              and password from the user whenever AUTH is offered
+              by an SMTP server.
 
        <b>smtpd_noop_commands</b>
               List of commands that are treated as NOOP (no oper-
-              ation)   commands,  without  any  parameter  syntax
-              checking and without any state change.   This  list
+              ation)  commands,  without  any  parameter   syntax
+              checking  and  without any state change.  This list
               overrides built-in command definitions.
 
 <b>Content inspection controls</b>
-       Optionally,  Postfix can be configured to send new mail to
+       Optionally, Postfix can be configured to send new mail  to
        external content filter software AFTER the mail is queued.
 
        <b>content_filter</b>
-              The  name of a mail delivery transport that filters
+              The name of a mail delivery transport that  filters
               mail and that either bounces mail or re-injects the
-              result  back into Postfix.  This parameter uses the
-              same syntax as the right-hand  side  of  a  Postfix
+              result back into Postfix.  This parameter uses  the
+              same  syntax  as  the  right-hand side of a Postfix
               transport table.
 
        <b>receive_override_options</b>
-              The  following  options  override <b>main.cf</b> settings.
-              The options are  either  implemented  by  the  SMTP
-              server  or  are passed on to the downstream cleanup
+              The following options  override  <b>main.cf</b>  settings.
+              The  options  are  either  implemented  by the SMTP
+              server or are passed on to the  downstream  cleanup
               server.
 
               <b>no_unknown_recipient_checks</b>
-                     Do not try  to  reject  unknown  recipients.
-                     This  is  typically  specified with the SMTP
+                     Do  not  try  to  reject unknown recipients.
+                     This is typically specified  with  the  SMTP
                      server <b>after</b> an external content filter.
 
               <b>no_address_mappings</b>
-                     Disable canonical address  mapping,  virtual
-                     alias  map  expansion, address masquerading,
-                     and automatic BCC recipients. This is  typi-
-                     cally  specified with the SMTP server <b>before</b>
+                     Disable  canonical  address mapping, virtual
+                     alias map expansion,  address  masquerading,
+                     and  automatic BCC recipients. This is typi-
+                     cally specified with the SMTP server  <b>before</b>
                      an external content filter.
 
               <b>no_header_body_checks</b>
-                     Disable header/body_checks.  This  is  typi-
-                     cally  specified  with the SMTP server <b>after</b>
+                     Disable  header/body_checks.  This  is typi-
+                     cally specified with the SMTP  server  <b>after</b>
                      an external content filter.
 
 <b>Pass-through proxy</b>
-       Optionally, the Postfix SMTP server can be  configured  to
-       forward  all  mail  to a proxy server, for example a real-
+       Optionally,  the  Postfix SMTP server can be configured to
+       forward all mail to a proxy server, for  example  a  real-
        time content filter, BEFORE mail is queued.
 
        <b>smtpd_proxy_filter</b>
@@ -125,8 +133,8 @@ SMTPD(8)                                                 SMTPD(8)
 
 <b>Authentication controls</b>
        <b>smtpd_sasl_auth_enable</b>
-              Enable  per-session  authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
-              (SASL).  This functionality is available only  when
+              Enable per-session authentication as per  <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC  2554</a>
+              (SASL).   This functionality is available only when
               explicitly  selected  at  program  build  time  and
               explicitly enabled at runtime.
 
@@ -152,8 +160,8 @@ SMTPD(8)                                                 SMTPD(8)
                      Disallow anonymous logins.
 
        <b>smtpd_sender_login_maps</b>
-              Maps that specify the SASL login name that  owns  a
-              MAIL    FROM    sender   address.   Used   by   the
+              Maps  that  specify the SASL login name that owns a
+              MAIL   FROM   sender   address.   Used    by    the
               <b>reject_sender_login_mismatch</b>  sender  anti-spoofing
               restriction.
 
@@ -163,23 +171,23 @@ SMTPD(8)                                                 SMTPD(8)
               that are authorized to use the XVERP extension.
 
        <b>debug_peer_level</b>
-              Increment in verbose logging level  when  a  remote
+              Increment  in  verbose  logging level when a remote
               host  matches  a  pattern  in  the  <b>debug_peer_list</b>
               parameter.
 
        <b>debug_peer_list</b>
-              List of domain or network patterns. When  a  remote
-              host  matches  a pattern, increase the verbose log-
-              ging  level  by  the  amount   specified   in   the
+              List  of  domain or network patterns. When a remote
+              host matches a pattern, increase the  verbose  log-
+              ging   level   by   the  amount  specified  in  the
               <b>debug_peer_level</b> parameter.
 
        <b>default_verp_delimiters</b>
               The default VERP delimiter characters that are used
-              when  the  XVERP  command  is   specified   without
+              when   the   XVERP  command  is  specified  without
               explicit delimiters.
 
        <b>error_notice_recipient</b>
-              Recipient    of   protocol/policy/resource/software
+              Recipient   of    protocol/policy/resource/software
               error notices.
 
        <b>hopcount_limit</b>
@@ -188,18 +196,18 @@ SMTPD(8)                                                 SMTPD(8)
        <b>notify_classes</b>
               List of error classes. Of special interest are:
 
-              <b>policy</b> When a client violates any  policy,  mail  a
+              <b>policy</b> When  a  client  violates any policy, mail a
                      transcript of the entire SMTP session to the
                      postmaster.
 
               <b>protocol</b>
-                     When a client violates the SMTP protocol  or
+                     When  a client violates the SMTP protocol or
                      issues  an  unimplemented  command,  mail  a
                      transcript of the entire SMTP session to the
                      postmaster.
 
        <b>smtpd_banner</b>
-              Text  that  follows the <b>220</b> status code in the SMTP
+              Text that follows the <b>220</b> status code in  the  SMTP
               greeting banner.
 
        <b>smtpd_expansion_filter</b>
@@ -207,57 +215,57 @@ SMTPD(8)                                                 SMTPD(8)
               expansion of rbl template responses and other text.
 
        <b>smtpd_recipient_limit</b>
-              Restrict the number of  recipients  that  the  SMTP
+              Restrict  the  number  of  recipients that the SMTP
               server accepts per message delivery.
 
        <b>smtpd_timeout</b>
-              Limit  the  time  to  send a server response and to
+              Limit the time to send a  server  response  and  to
               receive a client request.
 
        <b>soft_bounce</b>
-              Change hard (5xx) reject responses into soft  (4xx)
-              reject  responses.   This can be useful for testing
+              Change  hard (5xx) reject responses into soft (4xx)
+              reject responses.  This can be useful  for  testing
               purposes.
 
        <b>verp_delimiter_filter</b>
-              The characters that Postfix accepts as VERP  delim-
+              The  characters that Postfix accepts as VERP delim-
               iter characters.
 
 <b>Known versus unknown recipients</b>
        <b>show_user_unknown_table_name</b>
-              Whether  or  not  to  reveal  the table name in the
-              "User unknown" responses. The  extra  detail  makes
-              trouble  shooting  easier but also reveals informa-
+              Whether or not to reveal  the  table  name  in  the
+              "User  unknown"  responses.  The extra detail makes
+              trouble shooting easier but also  reveals  informa-
               tion that is nobody elses business.
 
        <b>unknown_local_recipient_reject_code</b>
               The response code when a client specifies a recipi-
-              ent   whose   domain   matches   <b>$mydestination</b>  or
+              ent  whose   domain   matches   <b>$mydestination</b>   or
               <b>$inet_interfaces</b>,  while  <b>$local_recipient_maps</b>  is
-              non-empty  and  does not list the recipient address
+              non-empty and does not list the  recipient  address
               or address local-part.
 
        <b>unknown_relay_recipient_reject_code</b>
               The response code when a client specifies a recipi-
               ent  whose  domain  matches  <b>$relay_domains</b>,  while
-              <b>$relay_recipient_maps</b> is  non-empty  and  does  not
+              <b>$relay_recipient_maps</b>  is  non-empty  and  does not
               list the recipient address.
 
        <b>unknown_virtual_alias_reject_code</b>
               The response code when a client specifies a recipi-
-              ent whose  domain  matches  <b>$virtual_alias_domains</b>,
-              while   the   recipient  is  not  listed  in  <b>$vir-</b>
+              ent  whose  domain  matches <b>$virtual_alias_domains</b>,
+              while  the  recipient  is  not  listed   in   <b>$vir-</b>
               <b>tual_alias_maps</b>.
 
        <b>unknown_virtual_mailbox_reject_code</b>
               The response code when a client specifies a recipi-
-              ent  whose domain matches <b>$virtual_mailbox_domains</b>,
+              ent whose domain matches  <b>$virtual_mailbox_domains</b>,
               while the recipient is not listed in <b>$virtual_mail-</b>
               <b>box_maps</b>.
 
 <b>Resource controls</b>
        <b>line_length_limit</b>
-              Limit  the  amount  of memory in bytes used for the
+              Limit the amount of memory in bytes  used  for  the
               handling of partial input lines.
 
        <b>message_size_limit</b>
@@ -265,8 +273,8 @@ SMTPD(8)                                                 SMTPD(8)
               ing on-disk storage for envelope information.
 
        <b>queue_minfree</b>
-              Minimal  amount of free space in bytes in the queue
-              file system for the SMTP server to accept any  mail
+              Minimal amount of free space in bytes in the  queue
+              file  system for the SMTP server to accept any mail
               at all.
 
        <b>smtpd_history_flush_threshold</b>
@@ -281,17 +289,17 @@ SMTPD(8)                                                 SMTPD(8)
 
        <b>smtpd_soft_error_limit</b>
               When an SMTP client has made this number of errors,
-              wait  <i>error</i><b>_</b><i>count</i>  seconds before responding to any
+              wait <i>error</i><b>_</b><i>count</i> seconds before responding  to  any
               client request.
 
        <b>smtpd_hard_error_limit</b>
-              Disconnect after a client has made this  number  of
+              Disconnect  after  a client has made this number of
               errors.
 
        <b>smtpd_junk_command_limit</b>
               Limit the number of times a client can issue a junk
-              command such as NOOP, VRFY, ETRN  or  RSET  in  one
-              SMTP  session  before  it  is penalized with tarpit
+              command  such  as  NOOP,  VRFY, ETRN or RSET in one
+              SMTP session before it  is  penalized  with  tarpit
               delays.
 
 <b>Delegated policy</b>
@@ -300,17 +308,17 @@ SMTPD(8)                                                 SMTPD(8)
               receiving from a delegated SMTPD policy server.
 
        <b>smtpd_policy_service_max_idle</b>
-              Time  after  which  an  unused SMTPD policy service
+              Time after which an  unused  SMTPD  policy  service
               connection is closed.
 
        <b>smtpd_policy_service_timeout</b>
-              Time after which an  active  SMTPD  policy  service
+              Time  after  which  an  active SMTPD policy service
               connection is closed.
 
 <b>UCE control restrictions</b>
        <b>parent_domain_matches_subdomains</b>
-              List  of  Postfix features that use <i>domain.tld</i> pat-
-              terns  to  match  <i>sub.domain.tld</i>  (as  opposed   to
+              List of Postfix features that use  <i>domain.tld</i>  pat-
+              terns   to  match  <i>sub.domain.tld</i>  (as  opposed  to
               requiring <i>.domain.tld</i> patterns).
 
        <b>smtpd_client_restrictions</b>
@@ -318,19 +326,19 @@ SMTPD(8)                                                 SMTPD(8)
               tem.
 
        <b>smtpd_helo_required</b>
-              Require that clients introduce  themselves  at  the
+              Require  that  clients  introduce themselves at the
               beginning of an SMTP session.
 
        <b>smtpd_helo_restrictions</b>
-              Restrict  what client hostnames are allowed in <b>HELO</b>
+              Restrict what client hostnames are allowed in  <b>HELO</b>
               and <b>EHLO</b> commands.
 
        <b>smtpd_sender_restrictions</b>
-              Restrict what sender addresses are allowed in  <b>MAIL</b>
+              Restrict  what sender addresses are allowed in <b>MAIL</b>
               <b>FROM</b> commands.
 
        <b>smtpd_recipient_restrictions</b>
-              Restrict  what  recipient  addresses are allowed in
+              Restrict what recipient addresses  are  allowed  in
               <b>RCPT TO</b> commands.
 
        <b>smtpd_etrn_restrictions</b>
@@ -338,96 +346,96 @@ SMTPD(8)                                                 SMTPD(8)
               mands, and what clients may issue <b>ETRN</b> commands.
 
        <b>smtpd_data_restrictions</b>
-              Restrictions  on  the  <b>DATA</b> command. Currently, the
-              only  restriction  that   makes   sense   here   is
+              Restrictions on the <b>DATA</b>  command.  Currently,  the
+              only   restriction   that   makes   sense  here  is
               <b>reject_unauth_pipelining</b>.
 
        <b>allow_untrusted_routing</b>
-              Allow  untrusted  clients to specify addresses with
-              sender-specified routing.  Enabling this  opens  up
-              nasty  relay  loopholes involving trusted backup MX
+              Allow untrusted clients to specify  addresses  with
+              sender-specified  routing.   Enabling this opens up
+              nasty relay loopholes involving trusted  backup  MX
               hosts.
 
        <b>smtpd_restriction_classes</b>
-              Declares the name of zero or more  parameters  that
-              contain  a  list  of UCE restrictions. The names of
-              these parameters can then be used  instead  of  the
+              Declares  the  name of zero or more parameters that
+              contain a list of UCE restrictions.  The  names  of
+              these  parameters  can  then be used instead of the
               restriction lists that they represent.
 
        <b>smtpd_null_access_lookup_key</b>
-              The  lookup  key  to be used in SMTPD access tables
-              instead of the null sender address. A  null  sender
+              The lookup key to be used in  SMTPD  access  tables
+              instead  of  the null sender address. A null sender
               address cannot be looked up.
 
        <b>maps_rbl_domains</b> (deprecated)
-              List  of  DNS domains that publish the addresses of
+              List of DNS domains that publish the  addresses  of
               blacklisted hosts. This is used with the deprecated
               <b>reject_maps_rbl</b> restriction.
 
        <b>permit_mx_backup_networks</b>
-              Only  domains  whose  primary  MX  hosts  match the
-              listed  networks  are   eligible   for   the   <b>per-</b>
+              Only domains  whose  primary  MX  hosts  match  the
+              listed   networks   are   eligible   for  the  <b>per-</b>
               <b>mit_mx_backup</b> feature.
 
        <b>relay_domains</b>
-              Restrict  what  domains this mail system will relay
-              mail to. The domains are  routed  to  the  delivery
+              Restrict what domains this mail system  will  relay
+              mail  to.  The  domains  are routed to the delivery
               agent specified with the <b>relay_transport</b> setting.
 
 <b>Sender/recipient address verification</b>
        Address verification is implemented by sending probe email
-       messages that are not actually delivered, and  is  enabled
-       via    the   reject_unverified_{sender,recipient}   access
-       restriction.  The status of verification probes  is  main-
+       messages  that  are not actually delivered, and is enabled
+       via   the   reject_unverified_{sender,recipient}    access
+       restriction.   The  status of verification probes is main-
        tained by the address verification service.
 
        <b>address_verify_poll_count</b>
-              How  many  times  to query the address verification
-              service for completion of an  address  verification
-              request.   Specify  1 to implement a simple form of
-              greylisting, that is, always defer the request  for
+              How many times to query  the  address  verification
+              service  for  completion of an address verification
+              request.  Specify 1 to implement a simple  form  of
+              greylisting,  that is, always defer the request for
               a new sender or recipient address.
 
        <b>address_verify_poll_delay</b>
-              Time  to  wait after querying the address verifica-
+              Time to wait after querying the  address  verifica-
               tion service for completion of an address verifica-
               tion request.
 
 <b>UCE control responses</b>
        <b>access_map_reject_code</b>
-              Response  code  when  a  client  violates an access
+              Response code when  a  client  violates  an  access
               database restriction.
 
        <b>default_rbl_reply</b>
               Default template reply when a request is RBL black-
-              listed.   This template is used by the <b>reject_rbl_*</b>
-              and   <b>reject_rhsbl_*</b>   restrictions.   See    also:
+              listed.  This template is used by the  <b>reject_rbl_*</b>
+              and    <b>reject_rhsbl_*</b>   restrictions.   See   also:
               <b>rbl_reply_maps</b> and <b>smtpd_expansion_filter</b>.
 
        <b>defer_code</b>
-              Response  code when a client request is rejected by
+              Response code when a client request is rejected  by
               the <b>defer</b> restriction.
 
        <b>invalid_hostname_reject_code</b>
-              Response  code   when   a   client   violates   the
+              Response   code   when   a   client   violates  the
               <b>reject_invalid_hostname</b> restriction.
 
        <b>maps_rbl_reject_code</b>
               Response code when a request is RBL blacklisted.
 
        <b>multi_recipient_bounce_reject_code</b>
-              Response  code  when  a  multi-recipient  bounce is
+              Response code  when  a  multi-recipient  bounce  is
               blocked.
 
        <b>rbl_reply_maps</b>
-              Table with template responses for  RBL  blacklisted
-              requests,  indexed  by  RBL domain name. These tem-
+              Table  with  template responses for RBL blacklisted
+              requests, indexed by RBL domain  name.  These  tem-
               plates   are   used   by   the   <b>reject_rbl_*</b>   and
-              <b>reject_rhsbl_*</b>      restrictions.     See     also:
+              <b>reject_rhsbl_*</b>     restrictions.     See      also:
               <b>default_rbl_reply</b> and <b>smtpd_expansion_filter</b>.
 
        <b>reject_code</b>
-              Response code when  the  client  matches  a  <b>reject</b>
+              Response  code  when  the  client  matches a <b>reject</b>
               restriction.
 
        <b>relay_domains_reject_code</b>
@@ -435,7 +443,7 @@ SMTPD(8)                                                 SMTPD(8)
               mail relay policy.
 
        <b>unknown_address_reject_code</b>
-              Response  code   when   a   client   violates   the
+              Response   code   when   a   client   violates  the
               <b>reject_unknown_address</b> restriction.
 
        <b>unknown_client_reject_code</b>
@@ -444,15 +452,15 @@ SMTPD(8)                                                 SMTPD(8)
               tion.
 
        <b>unknown_hostname_reject_code</b>
-              Response   code   when   a   client   violates  the
+              Response  code   when   a   client   violates   the
               <b>reject_unknown_hostname</b> restriction.
 
        <b>unverified_sender_reject_code</b>
-              Response code when a sender address is known to  be
+              Response  code when a sender address is known to be
               undeliverable.
 
        <b>unverified_recipient_reject_code</b>
-              Response  code when a recipient address is known to
+              Response code when a recipient address is known  to
               be undeliverable.
 
 <b>SEE ALSO</b>
@@ -463,7 +471,7 @@ SMTPD(8)                                                 SMTPD(8)
        <a href="verify.8.html">verify(8)</a> address verification service
 
 <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 dfc4f9d8974b00a900c388f96a88fc6f4a63dda4..f75848d09da8c61c69e150b63dfe2d65ab978051 100644 (file)
@@ -134,9 +134,14 @@ matches a table, the action depends on the lookup result:
 Reject the message, log the header and the optional text,
 and send the optional text to the originator.
 
-<dt>OK <dd>Skip all further header patterns for this header line.
+<dt>DUNNO <dd>
 
-<dt>IGNORE <dd> Delete the header line from the message.
+<dt>DUNNO text... <dd>Skip all further header patterns for this header line.
+This has the same effect as OK, which is deprecated.
+
+<dt>IGNORE <dd>
+
+<dt>IGNORE text... <dd> Delete the header line from the message.
 
 <dt>WARN <dd>
 
@@ -247,9 +252,14 @@ and send the optional text to the originator.
 Log (but do not reject) the body line with a warning, and log the
 optional text.
 
-<dt>OK <dd>Skip all further body patterns for this body line.
+<dt>DUNNO <dd>
+
+<dt>DUNNO text... <dd>Skip all further body patterns for this body line.
+This has the same effect as OK, which is deprecated.
 
-<dt>IGNORE <dd> Delete the body line from the message.
+<dt>IGNORE <dd>
+
+<dt>IGNORE text... <dd> Delete the body line from the message.
 
 <dt>HOLD <dd> 
 
@@ -358,8 +368,8 @@ reject_rbl_client relays.mail-abuse.org</b> (paid service)
 <dd> <b>smtpd_client_restrictions = hash:/etc/postfix/access,
 reject_rbl_client relays.ordb.org</b> (free service)
 
-<dd> <b>smtpd_client_restrictions = hash:/etc/postfix/access,
-reject_rhsbl_client dsn.rfc-ignorant.org</b> (free service)
+<dd> <b>smtpd_sender_restrictions = hash:/etc/postfix/access,
+reject_rhsbl_sender dsn.rfc-ignorant.org</b> (free service)
 
 <dd> <b>smtpd_client_restrictions = permit_mynetworks,
 reject_unknown_client</b>
@@ -589,6 +599,27 @@ or parent domains.
 
 <p>
 
+<a name="reject_rhsbl_helo">
+
+<dt> <b>reject_rhsbl_helo</b> <i>domain.tld=127.0.0.2</i>
+
+<dt> <b>reject_rhsbl_helo</b> <i>domain.tld</i> <dd> Reject the
+request when the HELO (or EHLO) hostname is listed with an A record
+under <i>domain.tld</i>.  See above for additional RBL related
+configuration parameters.
+
+Append the address to the RBL server's domain name to select a
+specific address from a multi-valued result.
+
+The <b> maps_rbl_reject_code</b> parameter specifies the response
+code for rejected requests (default:  <b>554</b>), the <b><a
+href="#default_rbl_reply"> default_rbl_reply </a></b> parameter
+specifies the default server reply, and the <b><a href="#rbl_reply_maps">
+rbl_reply_maps </a></b> parameter specifies tables with server replies
+indexed by RBL domain.
+
+<p>
+
 <dt> <b><a href="#permit">permit</a></b>
 
 <dt> <b><a href="#defer">defer</a></b>
@@ -974,19 +1005,19 @@ lookup tables:
 
 <table border="1">
 
-<tr><th>Recipient domain matches <th>Recipient lookup table 
+<tr><th>Recipient domain matches</th> <th>Recipient lookup table</th> 
 
-<tr><td><a href="basic.html#mydestination"> $mydestination</a> or
-<a href="basic.html#inet_interfaces">$inet_interfaces</a> 
-<td>$local_recipient_maps
+</tr><tr><td><a href="basic.html#mydestination"> $mydestination</a> or
+<a href="basic.html#inet_interfaces">$inet_interfaces</a></td> 
+<td>$local_recipient_maps</td>
 
-<tr><td>$virtual_alias_domains <td>$virtual_alias_maps 
+</tr><tr><td>$virtual_alias_domains</td> <td>$virtual_alias_maps</td> 
 
-<tr><td>$virtual_mailbox_domains <td>$virtual_mailbox_maps 
+</tr><tr><td>$virtual_mailbox_domains</td> <td>$virtual_mailbox_maps</td> 
 
-<tr><td>$relay_domains <td>$relay_recipient_maps 
+</tr><tr><td>$relay_domains</td> <td>$relay_recipient_maps</td> 
 
-</table>
+</tr></table>
 
 </blockquote>
 
index 6181cae1df91259d0fcf063b120c92fde627ca7e..fdeb53c3e8e3a4e00175b8e8be8a8b8d56f15a9d 100644 (file)
@@ -1,4 +1,4 @@
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
 VIRTUAL(5)                                             VIRTUAL(5)
 
 <b>NAME</b>
@@ -103,24 +103,27 @@ VIRTUAL(5)                                             VIRTUAL(5)
        When a mail address localpart contains the optional recip-
        ient delimiter (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order
        becomes: <i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and
-       @<i>domain</i>.  An unmatched address extension (<i>+foo</i>) is  propa-
+       @<i>domain</i>.
+
+       The  <b>propagate_unmatched_extensions</b>   parameter   controls
+       whether  an  unmatched  address extension (<i>+foo</i>) is propa-
        gated to the result of table lookup.
 
 <b>VIRTUAL ALIAS DOMAINS</b>
-       Besides  virtual aliases, the virtual alias table can also
+       Besides virtual aliases, the virtual alias table can  also
        be used to implement virtual alias domains. With a virtual
-       alias  domain,  all  recipient  addresses  are  aliased to
+       alias domain,  all  recipient  addresses  are  aliased  to
        addresses in other domains.
 
        Virtual alias domains are not to be confused with the vir-
        tual mailbox domains that are implemented with the Postfix
        <a href="virtual.8.html"><b>virtual</b>(8)</a>  mail  delivery  agent.  With  virtual  mailbox
-       domains,  each recipient address can have its own mailbox.
+       domains, each recipient address can have its own  mailbox.
 
-       With a virtual alias domain, the virtual  domain  has  its
-       own  user  name  space. Local (i.e. non-virtual) usernames
-       are not visible in a virtual alias domain. In  particular,
-       local  <a href="aliases.5.html"><b>aliases</b>(5)</a>  and local mailing lists are not visible
+       With  a  virtual  alias domain, the virtual domain has its
+       own user name space. Local  (i.e.  non-virtual)  usernames
+       are  not visible in a virtual alias domain. In particular,
+       local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists are  not  visible
        as <i>localname@virtual-alias.domain</i>.
 
        Support for a virtual alias domain looks like:
@@ -128,7 +131,7 @@ VIRTUAL(5)                                             VIRTUAL(5)
        /etc/postfix/main.cf:
            virtual_alias_maps = hash:/etc/postfix/virtual
 
-           Note: some systems use <b>dbm</b> databases instead of  <b>hash</b>.
+           Note:  some systems use <b>dbm</b> databases instead of <b>hash</b>.
            See the output from <b>postconf -m</b> for available database
            types.
 
@@ -138,87 +141,94 @@ VIRTUAL(5)                                             VIRTUAL(5)
            <i>user1@virtual-alias.domain   address1</i>
            <i>user2@virtual-alias.domain   address2, address3</i>
 
-       The <i>virtual-alias.domain anything</i> entry is required for  a
+       The  <i>virtual-alias.domain anything</i> entry is required for a
        virtual alias domain. <b>Without this entry, mail is rejected</b>
-       <b>with "relay access denied", or bounces  with  "mail  loops</b>
+       <b>with  "relay  access  denied", or bounces with "mail loops</b>
        <b>back to myself".</b>
 
-       Do  not  specify virtual alias domain names in the <b>main.cf</b>
+       Do not specify virtual alias domain names in  the  <b>main.cf</b>
        <b>mydestination</b> or <b>relay_domains</b> configuration parameters.
 
-       With a virtual  alias  domain,  the  Postfix  SMTP  server
-       accepts   mail  for  <i>known-user@virtual-alias.domain</i>,  and
-       rejects  mail  for  <i>unknown-user</i>@<i>virtual-alias.domain</i>   as
+       With  a  virtual  alias  domain,  the  Postfix SMTP server
+       accepts  mail  for  <i>known-user@virtual-alias.domain</i>,   and
+       rejects   mail  for  <i>unknown-user</i>@<i>virtual-alias.domain</i>  as
        undeliverable.
 
-       Instead  of  specifying  the virtual alias domain name via
-       the <b>virtual_alias_maps</b> table, you may also specify it  via
+       Instead of specifying the virtual alias  domain  name  via
+       the  <b>virtual_alias_maps</b> table, you may also specify it via
        the <b>main.cf virtual_alias_domains</b> configuration parameter.
-       This latter parameter uses the same syntax as the  <b>main.cf</b>
+       This  latter parameter uses the same syntax as the <b>main.cf</b>
        <b>mydestination</b> configuration parameter.
 
 <b>REGULAR EXPRESSION TABLES</b>
-       This  section  describes how the table lookups change when
+       This section describes how the table lookups  change  when
        the table is given in the form of regular expressions. For
-       a  description  of regular expression lookup table syntax,
+       a description of regular expression lookup  table  syntax,
        see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to
+       Each  pattern  is  a regular expression that is applied to
        the entire address being looked up. Thus, <i>user@domain</i> mail
-       addresses are not broken up into their  <i>user</i>  and  <i>@domain</i>
+       addresses  are  not  broken up into their <i>user</i> and <i>@domain</i>
        constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
        <i>foo</i>.
 
-       Patterns are applied in the  order  as  specified  in  the
-       table,  until  a  pattern is found that matches the search
+       Patterns  are  applied  in  the  order as specified in the
+       table, until a pattern is found that  matches  the  search
        string.
 
-       Results are the same as with indexed  file  lookups,  with
-       the  additional feature that parenthesized substrings from
+       Results  are  the  same as with indexed file lookups, with
+       the additional feature that parenthesized substrings  from
        the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
 
 <b>TCP-BASED TABLES</b>
-       This section describes how the table lookups  change  when
+       This  section  describes how the table lookups change when
        lookups are directed to a TCP-based server. For a descrip-
-       tion  of  the  TCP  client/server  lookup  protocol,   see
+       tion   of  the  TCP  client/server  lookup  protocol,  see
        <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
 
        Each lookup operation uses the entire address once.  Thus,
-       <i>user@domain</i> mail addresses are not broken  up  into  their
+       <i>user@domain</i>  mail  addresses  are not broken up into their
        <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i> broken
        up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
 
 <b>BUGS</b>
-       The table format does not understand quoting  conventions.
+       The  table format does not understand quoting conventions.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this topic. See the Postfix  <b>main.cf</b>  file  for  syntax
-       details  and  for  default  values. Use the <b>postfix reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  topic.  See  the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix  reload</b>
        command after a configuration change.
 
        <b>virtual_alias_maps</b>
               List of virtual aliasing tables.
 
        <b>virtual_alias_domains</b>
-              List of virtual alias domains. This uses  the  same
+              List  of  virtual alias domains. This uses the same
               syntax as the <b>mydestination</b> parameter.
 
+       <b>propagate_unmatched_extensions</b>
+              A list of address rewriting  or  forwarding  mecha-
+              nisms  that propagate an address extension from the
+              original address to the result.   Specify  zero  or
+              more  of  <b>canonical</b>,  <b>virtual</b>,  <b>alias</b>,  <b>forward</b>, or
+              <b>include</b>.
+
        Other parameters of interest:
 
        <b>inet_interfaces</b>
-              The  network  interface  addresses that this system
+              The network interface addresses  that  this  system
               receives mail on.  You need to stop and start Post-
               fix when this parameter changes.
 
        <b>mydestination</b>
-              List  of  domains  that  this mail system considers
+              List of domains that  this  mail  system  considers
               local.
 
        <b>myorigin</b>
-              The domain that is appended  to  any  address  that
+              The  domain  that  is  appended to any address that
               does not have a domain.
 
        <b>owner_request_special</b>
@@ -233,7 +243,7 @@ VIRTUAL(5)                                             VIRTUAL(5)
        <a href="tcp_table.5.html">tcp_table(5)</a> TCP client/server table lookup protocol
 
 <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 e03d6986215efebce35e7b2cd8c201324e302529..7317bd31674a384ba39f76f5a04eebdc953d16e1 100644 (file)
@@ -66,12 +66,12 @@ Do not inherit the file access permissions from the input file
 when creating a new file.  Instead, create a new file with default
 access permissions (mode 0644).
 .IP "\fB-q \fIkey\fR"
-Search the specified maps for \fIkey\fR and print the first value
-found on the standard output stream. The exit status is zero
+Search the specified maps for \fIkey\fR and write the first value
+found to the standard output stream. The exit status is zero
 when the requested information was found.
 
 If a key value of \fB-\fR is specified, the program reads key
-values from the standard input stream and prints one line of
+values from the standard input stream and writes one line of
 \fIkey: value\fR output for each key that was found. The exit
 status is zero when at least one of the requested keys was found.
 .IP \fB-r\fR
index 05e522ef05b87ac0f4c26d132b6a38a03044420a..637ddc97e125b28a601103de238c8e9f2525b7ac 100644 (file)
@@ -25,11 +25,15 @@ IPV4 is the default.
 This program is the complement of the \fIsmtp-source\fR program.
 
 Arguments:
+.IP \fB-a\fR
+Do not announce SASL authentication support.
 .IP \fB-c\fR
 Display a running counter that is updated whenever an SMTP
 QUIT command is executed.
 .IP \fB-e\fR
 Disable ESMTP support.
+.IP "\fB-f  \fIcommand,command,...\fR"
+Reject the specified commands with a hard (5xx) error code.
 .IP \fB-h\fI hostname\fR
 Use \fIhostname\fR in the SMTP greeting, in the HELO response,
 and in the EHLO response. The default hostname is "smtp-sink".
@@ -42,6 +46,8 @@ Disable ESMTP command pipelining.
 .IP \fB-P\fR
 Change the server greeting so that it appears to come through
 a CISCO PIX system. Implies \fB-e\fR.
+.IP "\fB-r  \fIcommand,command,...\fR"
+Reject the specified commands with a soft (4xx) error code.
 .IP "\fB-s \fIcommand,command,...\fR"
 Log the named commands to syslogd.
 Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
index 09778b32fdc22c1504831fc4c3540d87da23a671..99a1da1ae6ebed349b6f78def4c3af593a618778 100644 (file)
@@ -97,8 +97,11 @@ In all the above forms, when \fIaddress\fR has the form
 When a mail address localpart contains the optional recipient delimiter
 (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
 \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-\fIuser\fR, and @\fIdomain\fR.  An unmatched address extension
-(\fI+foo\fR) is propagated to the result of table lookup.
+\fIuser\fR, and @\fIdomain\fR.
+
+The \fBpropagate_unmatched_extensions\fR parameter controls whether
+an unmatched address extension (\fI+foo\fR) is propagated to the
+result of table lookup.
 .SH REGULAR EXPRESSION TABLES
 .na
 .nf
@@ -156,6 +159,11 @@ addresses.
 .IP \fBsender_canonical_maps\fR
 Address mapping lookup table for envelope and header sender
 addresses.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
 .PP
 Other parameters of interest:
 .IP \fBinet_interfaces\fR
index 59fccdd090b9bf9340ff2662f563b6b3a9ba23f4..c95c5dc0b95b3eec039df9e21c8b03b1274318d4 100644 (file)
@@ -97,8 +97,11 @@ This works for the first address in the expansion only.
 When a mail address localpart contains the optional recipient delimiter
 (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
 \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-\fIuser\fR, and @\fIdomain\fR.  An unmatched address extension
-(\fI+foo\fR) is propagated to the result of table lookup.
+\fIuser\fR, and @\fIdomain\fR.
+
+The \fBpropagate_unmatched_extensions\fR parameter controls whether
+an unmatched address extension (\fI+foo\fR) is propagated to the
+result of table lookup.
 .SH VIRTUAL ALIAS DOMAINS
 .na
 .nf
@@ -212,6 +215,11 @@ List of virtual aliasing tables.
 .IP \fBvirtual_alias_domains\fR
 List of virtual alias domains. This uses the same syntax
 as the \fBmydestination\fR parameter.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
 .PP
 Other parameters of interest:
 .IP \fBinet_interfaces\fR
index 8542c99dd3349d6fad435956ea00431df4faeac3..63c7c2d171aadf4391e8a779c0500a8e2b5f0469 100644 (file)
@@ -169,6 +169,11 @@ more of \fBenvelope_sender\fR, \fBenvelope_recipient\fR,
 List of domains that hide their subdomain structure.
 .IP \fBmasquerade_exceptions\fR
 List of user names that are not subject to address masquerading.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
 .IP \fBvirtual_alias_maps\fR
 Address mapping lookup table for envelope recipient addresses.
 .SH "Resource controls"
index c92ad6a94753c4251274bcce9dc0eab40a7c21f5..ca23b1671aac99222cd24efa82ca2c9af38c3af1 100644 (file)
@@ -85,7 +85,7 @@ delivery status record.
 
 In order to stop mail forwarding loops early, the software adds an
 optional
-\fBDelivered-To:\fR header with the envelope recipient address. If
+\fBDelivered-To:\fR header with the final envelope recipient address. If
 mail arrives for a recipient that is already listed in a
 \fBDelivered-To:\fR header, the message is bounced.
 .SH MAILBOX DELIVERY
@@ -124,7 +124,7 @@ envelope header to each message, prepends an
 \fBX-Original-To:\fR header with the recipient address as given to
 Postfix, prepends an
 optional \fBDelivered-To:\fR header
-with the envelope recipient address, prepends a \fBReturn-Path:\fR
+with the final envelope recipient address, prepends a \fBReturn-Path:\fR
 header with the envelope sender address, prepends a \fB>\fR character
 to lines beginning with "\fBFrom \fR", and appends an empty line.
 The mailbox is locked for exclusive access while delivery is in
@@ -196,7 +196,7 @@ envelope header to each message, prepends an
 \fBX-Original-To:\fR header with the recipient address as given to
 Postfix, prepends an
 optional \fBDelivered-To:\fR
-header with the recipient envelope address, prepends a
+header with the final recipient envelope address, prepends a
 \fBReturn-Path:\fR header with the sender envelope address,
 and appends no empty line.
 .SH EXTERNAL FILE DELIVERY
@@ -218,7 +218,7 @@ envelope header to each message, prepends an
 \fBX-Original-To:\fR header with the recipient address as given to
 Postfix, prepends an
 optional \fBDelivered-To:\fR
-header with the recipient envelope address, prepends a \fB>\fR
+header with the final recipient envelope address, prepends a \fB>\fR
 character to lines beginning with "\fBFrom \fR", and appends an
 empty line.
 The envelope sender address is available in the \fBReturn-Path:\fR
@@ -229,8 +229,8 @@ is made to truncate a regular file to its original length.
 
 In the case of \fBmaildir\fR delivery, the local daemon prepends
 an optional
-\fBDelivered-To:\fR header with the envelope recipient address, and
-prepends an
+\fBDelivered-To:\fR header with the final envelope recipient address,
+and prepends an
 \fBX-Original-To:\fR header with the recipient address as given to
 Postfix.
 The envelope sender address is available in the \fBReturn-Path:\fR
@@ -252,7 +252,8 @@ to the mailbox owned by the user \fIname\fR, or it is sent back as
 undeliverable.
 
 In all cases the \fBlocal\fR daemon prepends an optional
-`\fBDelivered-To:\fR \fIname\fR+\fIfoo\fR' header line.
+`\fBDelivered-To:\fR header line with the final recipient
+address.
 .SH DELIVERY RIGHTS
 .na
 .nf
@@ -329,6 +330,11 @@ Prepend an optional \fBDelivered-To:\fR header upon external
 forwarding, delivery to command or file. Specify zero or more of:
 \fBcommand, file, forward\fR. Turning off \fBDelivered-To:\fR when
 forwarding mail is not recommended.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
 .IP \fBrecipient_delimiter\fR
 Separator between username and address extension.
 .IP \fBrequire_home_directory\fR
index 1e004fad2298b490e65ce073e61f7358faa21ec7..71ba43107eb1077ade64c4ba7027adc3e999c2ac 100644 (file)
@@ -73,9 +73,14 @@ a configuration change.
 Disallow non-RFC 821 style addresses in SMTP commands. For example,
 the RFC822-style address forms with comments that Sendmail allows.
 .IP \fBbroken_sasl_auth_clients\fR
-Support older Microsoft clients that mis-implement the AUTH
+Support Microsoft clients that implement an older version of the AUTH
 protocol, and that expect an EHLO response of "250 AUTH=list"
 instead of "250 AUTH list".
+.IP \fBsmtpd_sasl_exceptions_networks\fR
+Don't offer AUTH in the response to EHLO when talking to clients
+in the specified networks.  This is a workaround for clients that
+that demand a login and password from the user whenever AUTH is
+offered by an SMTP server.
 .IP \fBsmtpd_noop_commands\fR
 List of commands that are treated as NOOP (no operation) commands,
 without any parameter syntax checking and without any state change.
index be7c1c8229b992e21474917c4e8a4950866cbbcc..23f673cbc290cc52a95d3ce8e2d38189ae6955f1 100755 (executable)
@@ -2,7 +2,7 @@
 
 # Crude script to convert formatted manual pages to HTML
 
-echo '<html> <head> </head> <body> <pre>'
+echo '<html> <body> <pre>'
 
 sed '
        s/\([<>&]\)\b\1/\1/g
index 68c3c0b7682ccbc842ef8ce45439269fd0dddb28..700d4f3397794afa27ab0113c551980b30a637a3 100644 (file)
@@ -56,7 +56,8 @@
 # .sp
 #      The pattern \fIdomain.tld\fR also matches subdomains, but only
 #      when the string \fBsmtpd_access_maps\fR is listed in the Postfix
-#      \fBparent_domain_matches_subdomains\fR configuration setting.
+#      \fBparent_domain_matches_subdomains\fR configuration setting
+#      (note that this is the default for some versions of Postfix).
 #      Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
 #      order to match subdomains.
 # .IP \fIuser\fR@
index 7245d920d3efdddf7fe1d37c33065d9a7f9d230b..3cc6ae707941c1285c324d6e7e3c483fa45e121b 100644 (file)
 #      When a mail address localpart contains the optional recipient delimiter
 #      (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
 #      \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-#      \fIuser\fR, and @\fIdomain\fR.  An unmatched address extension
-#      (\fI+foo\fR) is propagated to the result of table lookup.
+#      \fIuser\fR, and @\fIdomain\fR.
+#
+#      The \fBpropagate_unmatched_extensions\fR parameter controls whether
+#      an unmatched address extension (\fI+foo\fR) is propagated to the 
+#      result of table lookup.
 # REGULAR EXPRESSION TABLES
 # .ad
 # .fi
 # .IP \fBsender_canonical_maps\fR
 #      Address mapping lookup table for envelope and header sender
 #      addresses.
+# .IP \fBpropagate_unmatched_extensions\fR 
+#      A list of address rewriting or forwarding mechanisms that propagate
+#      an address extension from the original address to the result.
+#      Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,  
+#      \fBforward\fR, or \fBinclude\fR.
 # .PP
 #      Other parameters of interest:
 # .IP \fBinet_interfaces\fR
index 2df396de3de35afa3bb7e022b2b039418729b493..284b1879690e2141690e57bfd1218062040753d9 100644 (file)
 #      When a mail address localpart contains the optional recipient delimiter
 #      (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
 #      \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-#      \fIuser\fR, and @\fIdomain\fR.  An unmatched address extension
-#      (\fI+foo\fR) is propagated to the result of table lookup.
+#      \fIuser\fR, and @\fIdomain\fR.
+#
+#      The \fBpropagate_unmatched_extensions\fR parameter controls whether
+#      an unmatched address extension (\fI+foo\fR) is propagated to the
+#      result of table lookup.
 # VIRTUAL ALIAS DOMAINS
 # .ad
 # .fi
 # .IP \fBvirtual_alias_domains\fR
 #      List of virtual alias domains. This uses the same syntax
 #      as the \fBmydestination\fR parameter.
+# .IP \fBpropagate_unmatched_extensions\fR
+#      A list of address rewriting or forwarding mechanisms that propagate   
+#      an address extension from the original address to the result.     
+#      Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+#      \fBforward\fR, or \fBinclude\fR.
 # .PP
 #      Other parameters of interest:
 # .IP \fBinet_interfaces\fR
index 50db85b85878f0da747b9c6cb9b903f48ab593e4..5eb690e763f15daaed6eb3c822e33a7ac46167e8 100644 (file)
 /*     Address mapping lookup table for envelope and header sender
 /*     addresses.
 /* .IP \fBmasquerade_classes\fR
-/*      List of address classes subject to masquerading: zero or
-/*      more of \fBenvelope_sender\fR, \fBenvelope_recipient\fR,
+/*     List of address classes subject to masquerading: zero or
+/*     more of \fBenvelope_sender\fR, \fBenvelope_recipient\fR,
 /*     \fBheader_sender\fR, \fBheader_recipient\fR.
 /* .IP \fBmasquerade_domains\fR
 /*     List of domains that hide their subdomain structure.
 /* .IP \fBmasquerade_exceptions\fR
 /*     List of user names that are not subject to address masquerading.
+/* .IP \fBpropagate_unmatched_extensions\fR
+/*     A list of address rewriting or forwarding mechanisms that propagate   
+/*     an address extension from the original address to the result.
+/*     Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,  
+/*     \fBforward\fR, or \fBinclude\fR.
 /* .IP \fBvirtual_alias_maps\fR
 /*     Address mapping lookup table for envelope recipient addresses.
 /* .SH "Resource controls"
index 328d62890f05851e4ed9313a8f40af5d094ff83d..48f1178c488f05710f73cdab650cd47b75d0020e 100644 (file)
@@ -342,14 +342,15 @@ static int cleanup_act(CLEANUP_STATE *state, char *context, const char *buf,
        }
        return (CLEANUP_ACT_KEEP);
     }
-    if (*optional_text)
-       msg_warn("unexpected text after command in %s map: %s",
-                map_class, value);
+    /* Allow and ignore optional text after the action. */
 
     if (STREQUAL(value, "IGNORE", command_len))
        return (CLEANUP_ACT_DROP);
 
-    if (STREQUAL(value, "OK", command_len))
+    if (STREQUAL(value, "DUNNO", command_len)) /* preferred */
+       return (CLEANUP_ACT_KEEP);
+
+    if (STREQUAL(value, "OK", command_len))    /* compat */
        return (CLEANUP_ACT_KEEP);
 
     msg_warn("unknown command in %s map: %s", map_class, value);
index 7d8961c6fce83e6ee7474c7590518399f82ae79b..0d16455bff2c427c7e8d8a432f4e350d96a68eb9 100644 (file)
@@ -939,6 +939,10 @@ extern int var_lmtpd_err_sleep;
 #define DEF_LMTPD_JUNK_CMD     1000
 extern int var_lmtpd_junk_cmd_limit;
 
+#define VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS     "smtpd_sasl_exceptions_networks"
+#define DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS     ""
+extern char *var_smtpd_sasl_exceptions_networks;
+
  /*
   * SASL authentication support, LMTP server side.
   */
@@ -1315,6 +1319,7 @@ extern int var_access_map_code;
 #define REJECT_RBL             "reject_rbl"    /* LaMont compatibility */
 #define REJECT_RBL_CLIENT      "reject_rbl_client"
 #define REJECT_RHSBL_CLIENT    "reject_rhsbl_client"
+#define REJECT_RHSBL_HELO      "reject_rhsbl_helo"
 #define REJECT_RHSBL_SENDER    "reject_rhsbl_sender"
 #define REJECT_RHSBL_RECIPIENT "reject_rhsbl_recipient"
 
index 5a3345fe3b2e63445b7334fcd125b65622fec4ed..eb7bfc4ba9422272f3a31a5681b77c2ad50acffe 100644 (file)
@@ -56,7 +56,7 @@
 /*     A message header contains 8-bit data. This is always illegal.
 /* .IP MIME_ERR_8BIT_IN_7BIT_BODY
 /*     A MIME header specifies (or defaults to) 7-bit content, but the
-/*     correspnding message body or body parts contain 8-bit content.
+/*     corresponding message body or body parts contain 8-bit content.
 /* .IP MIME_ERR_ENCODING_DOMAIN
 /*     An entity of type "message" or "multipart" specifies the wrong
 /*     content transfer encoding domain, or specifies a transformation
index 322747b8a65e0d4dcdbce790dd80b3f33b0bcfbc..7cbd9795c041b4112aa6e850cf28ca1f11877e78 100644 (file)
@@ -413,7 +413,8 @@ int     pipe_command(VSTREAM *src, VSTRING *why,...)
         */
     case 0:
        set_ugid(args.uid, args.gid);
-       setsid();
+       if (setsid() < 0)
+           msg_warn("setsid failed: %m");
 
        /*
         * Pipe plumbing.
index 3550d299bb6fedb8bbd587801310ec7c36cdf116..bff950cf35d9e074ab83d6f6567cad0ba1c42aa3 100644 (file)
@@ -294,6 +294,7 @@ static void post_mail_open_event(int event, char *context)
            event_disable_readwrite(vstream_fileno(state->stream));
            vstream_fclose(state->stream);
        } else {
+    case EVENT_XCPT:
            msg_warn("connect to service: %s: %m", var_cleanup_service);
        }
        myfree(state->sender);
index 41303b3bc98bcaa1a33bdafacbc01207c508342e..4b86772e8ade2a21bf62f28eb8aa60b81cf1011c 100644 (file)
@@ -130,6 +130,7 @@ lmtp_connect.o: ../../include/iostuff.h
 lmtp_connect.o: ../../include/timed_connect.h
 lmtp_connect.o: ../../include/stringops.h
 lmtp_connect.o: ../../include/host_port.h
+lmtp_connect.o: ../../include/sane_connect.h
 lmtp_connect.o: ../../include/mail_params.h
 lmtp_connect.o: ../../include/mail_proto.h
 lmtp_connect.o: ../../include/attr.h
index e1f36e45a6a951abef91f9ba93082c848009e8a3..8eb40b7e0238852307f6ab4de30121910a2f610d 100644 (file)
@@ -337,6 +337,10 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
            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
        }
 
        /*
@@ -346,6 +350,10 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
        else if (lmtp_rset(state) != 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
        }
 
        /*
@@ -380,6 +388,10 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
         */
        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
        }
 
        /*
index 419cb38d5b0059b67e8ab7332c8e91e2b0a9121b..2f9643970121d160f14bb9aabedef5fb65307cec 100644 (file)
@@ -53,7 +53,6 @@ typedef struct LMTP_STATE {
     sasl_callback_t *sasl_callbacks;   /* stateful callbacks */
 #endif
     int     sndbufsize;                        /* total window size */
-    int     sndbuffree;                        /* remaining window */
     int     reuse;                     /* connection being reused */
 } LMTP_STATE;
 
index 63321e4960da13422bd4f7e706e72a91677364bb..36c19246cf1c7465c4ad62cef45c0ddab88e4ff7 100644 (file)
@@ -93,6 +93,7 @@
 #include <timed_connect.h>
 #include <stringops.h>
 #include <host_port.h>
+#include <sane_connect.h>
 
 /* Global library. */
 
@@ -221,7 +222,7 @@ static LMTP_SESSION *lmtp_connect_sock(int sock, struct sockaddr * sa, int len,
        non_blocking(sock, BLOCKING);
        errno = saved_errno;
     } else {
-       conn_stat = connect(sock, sa, len);
+       conn_stat = sane_connect(sock, sa, len);
     }
     if (conn_stat < 0) {
        vstring_sprintf(why, "connect to %s[%s]: %m",
index 808811baec25dc088dbc91a22f329f7b183432ad..ccf905e60ff6797a88b4c6bc1f596416de065a8b 100644 (file)
@@ -246,11 +246,6 @@ int     lmtp_lhlo(LMTP_STATE *state)
     if (msg_verbose)
        msg_info("server features: 0x%x", state->features);
 
-#ifdef USE_SASL_AUTH
-    if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
-       return (lmtp_sasl_helo_login(state));
-#endif
-
     /*
      * 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
@@ -276,6 +271,11 @@ int     lmtp_lhlo(LMTP_STATE *state)
     } 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);
 }
 
@@ -383,6 +383,16 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
                    msg_warn("%s: unknown content encoding: %s",
                             request->queue_id, request->encoding);
            }
+
+           /*
+            * We authenticate the client, 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;
 
@@ -536,8 +546,8 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
                                && sent(DEL_REQ_TRACE_FLAGS(request->flags),
                                        request->queue_id, rcpt->orig_addr,
                                        rcpt->address, session->namaddr,
-                                       request->arrival_time, "%s", 
-                                       translit(resp->str, "\n", " ")) == 0) {
+                                       request->arrival_time, "%s",
+                                    translit(resp->str, "\n", " ")) == 0) {
                                if (request->flags & DEL_REQ_FLAG_SUCCESS)
                                    deliver_completed(state->src, rcpt->offset);
                                rcpt->offset = 0;       /* in case deferred */
@@ -720,8 +730,8 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
        /*
         * Copy the next command to the buffer and update the sender state.
         */
-       if (state->sndbuffree > 0)
-           state->sndbuffree -= VSTRING_LEN(next_command) + 2;
+       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;
index 9b0e673c07d537f13355050a71e06c426d8ab2ae..05bcc7d926c9050df8cc921671772f6a49860a91 100644 (file)
@@ -38,7 +38,7 @@
 /*     policy of the SASL authentication.
 /*
 /*     lmtp_sasl_passwd_lookup() looks up the username/password
-/*     for the current SMTP server. The result is zero in case
+/*     for the current LMTP server. The result is zero in case
 /*     of failure.
 /*
 /*     lmtp_sasl_authenticate() implements the SASL authentication
@@ -49,7 +49,7 @@
 /*     suceeds.
 /*
 /*     lmtp_sasl_cleanup() cleans up. It must be called at the
-/*     end of every SMTP session that uses SASL authentication.
+/*     end of every LMTP session that uses SASL authentication.
 /*     This routine is a noop for non-SASL sessions.
 /*
 /*     Arguments:
index 9f25f814959325bac282429cb7a2434729d3d774..f3cadc0b388e6ea971ca5ae14f9f5a2a6a9540d4 100644 (file)
@@ -80,7 +80,6 @@ LMTP_STATE *lmtp_state_alloc(void)
     lmtp_sasl_connect(state);
 #endif
     state->sndbufsize = 0;
-    state->sndbuffree = 0;
     state->reuse = 0;
     return (state);
 }
index 0a387d506a5628269c6c7afcce52ca2be465a683..d0f7cec2313dcbe51adcf2dda0b1426c53def361 100644 (file)
@@ -75,7 +75,7 @@
 /*
 /*     In order to stop mail forwarding loops early, the software adds an
 /*     optional
-/*     \fBDelivered-To:\fR header with the envelope recipient address. If
+/*     \fBDelivered-To:\fR header with the final envelope recipient address. If
 /*     mail arrives for a recipient that is already listed in a
 /*     \fBDelivered-To:\fR header, the message is bounced.
 /* MAILBOX DELIVERY
 /*     \fBX-Original-To:\fR header with the recipient address as given to
 /*     Postfix, prepends an
 /*     optional \fBDelivered-To:\fR header
-/*     with the envelope recipient address, prepends a \fBReturn-Path:\fR
+/*     with the final envelope recipient address, prepends a \fBReturn-Path:\fR
 /*     header with the envelope sender address, prepends a \fB>\fR character
 /*     to lines beginning with "\fBFrom \fR", and appends an empty line.
 /*     The mailbox is locked for exclusive access while delivery is in
 /*     \fBX-Original-To:\fR header with the recipient address as given to
 /*     Postfix, prepends an
 /*     optional \fBDelivered-To:\fR
-/*     header with the recipient envelope address, prepends a
+/*     header with the final recipient envelope address, prepends a
 /*     \fBReturn-Path:\fR header with the sender envelope address,
 /*     and appends no empty line.
 /* EXTERNAL FILE DELIVERY
 /*     \fBX-Original-To:\fR header with the recipient address as given to
 /*     Postfix, prepends an
 /*     optional \fBDelivered-To:\fR
-/*     header with the recipient envelope address, prepends a \fB>\fR
+/*     header with the final recipient envelope address, prepends a \fB>\fR
 /*     character to lines beginning with "\fBFrom \fR", and appends an
 /*     empty line.
 /*     The envelope sender address is available in the \fBReturn-Path:\fR
 /*
 /*     In the case of \fBmaildir\fR delivery, the local daemon prepends
 /*     an optional
-/*     \fBDelivered-To:\fR header with the envelope recipient address, and
-/*     prepends an
+/*     \fBDelivered-To:\fR header with the final envelope recipient address,
+/*     and prepends an
 /*     \fBX-Original-To:\fR header with the recipient address as given to
 /*     Postfix.
 /*     The envelope sender address is available in the \fBReturn-Path:\fR
 /*     undeliverable.
 /*
 /*     In all cases the \fBlocal\fR daemon prepends an optional
-/*     `\fBDelivered-To:\fR \fIname\fR+\fIfoo\fR' header line.
+/*     `\fBDelivered-To:\fR header line with the final recipient
+/*     address.
 /* DELIVERY RIGHTS
 /* .ad
 /* .fi
 /*     forwarding, delivery to command or file. Specify zero or more of:
 /*     \fBcommand, file, forward\fR. Turning off \fBDelivered-To:\fR when
 /*     forwarding mail is not recommended.
+/* .IP \fBpropagate_unmatched_extensions\fR
+/*     A list of address rewriting or forwarding mechanisms that propagate
+/*     an address extension from the original address to the result.
+/*     Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+/*     \fBforward\fR, or \fBinclude\fR.
 /* .IP \fBrecipient_delimiter\fR
 /*     Separator between username and address extension.
 /* .IP \fBrequire_home_directory\fR
index f7f95666aa26784ae9b25a4f0574947aa2ec8434..2df71cc5cc19c9cb22555f118caa84eceb956e24 100644 (file)
 /*     when creating a new file.  Instead, create a new file with default
 /*     access permissions (mode 0644).
 /* .IP "\fB-q \fIkey\fR"
-/*     Search the specified maps for \fIkey\fR and print the first value
-/*     found on the standard output stream. The exit status is zero
+/*     Search the specified maps for \fIkey\fR and write the first value
+/*     found to the standard output stream. The exit status is zero
 /*     when the requested information was found.
 /*
 /*     If a key value of \fB-\fR is specified, the program reads key
-/*     values from the standard input stream and prints one line of
+/*     values from the standard input stream and writes one line of
 /*     \fIkey: value\fR output for each key that was found. The exit
 /*     status is zero when at least one of the requested keys was found.
 /* .IP \fB-r\fR
index 205767d766a41510b29117027d0bf233df691894..d510098143accc873b0184cebb78d24d18753afd 100644 (file)
@@ -137,6 +137,7 @@ smtp_connect.o: ../../include/iostuff.h
 smtp_connect.o: ../../include/timed_connect.h
 smtp_connect.o: ../../include/stringops.h
 smtp_connect.o: ../../include/host_port.h
+smtp_connect.o: ../../include/sane_connect.h
 smtp_connect.o: ../../include/mail_params.h
 smtp_connect.o: ../../include/own_inet_addr.h
 smtp_connect.o: ../../include/dns.h
index bdfb00ca32d76c9e517afb0b516d86a212f76f88..95bb9179cee1a0a925abf0861e68819cb8f7a7b4 100644 (file)
 #include <timed_connect.h>
 #include <stringops.h>
 #include <host_port.h>
+#include <sane_connect.h>
 
 /* Global library. */
 
@@ -208,7 +209,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
        non_blocking(sock, BLOCKING);
        errno = saved_errno;
     } else {
-       conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
+       conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
     }
     if (conn_stat < 0) {
        vstring_sprintf(why, "connect to %s[%s]: %m",
index 6cbdb5d3ff9b6ef50c5f6ac1475c2ed6eb859cb0..943720b7c3d2ec7db268b4585e652ca2171e9b56 100644 (file)
@@ -504,6 +504,16 @@ int     smtp_xfer(SMTP_STATE *state)
                    msg_warn("%s: unknown content encoding: %s",
                             request->queue_id, request->encoding);
            }
+
+           /*
+            * We authenticate the client, not the sender.
+            */
+#ifdef USE_SASL_AUTH
+           if (var_smtp_sasl_enable
+               && (state->features & SMTP_FEATURE_AUTH)
+               && state->sasl_passwd)
+               vstring_strcat(next_command, " AUTH=<>");
+#endif
            next_state = SMTP_STATE_RCPT;
            break;
 
index d77b8fd4e57c3a60366cc22feac8fe24d3e7970c..ad0640f3b1e39ca6702801e96ee0c36a12136271 100644 (file)
 /*     Disallow non-RFC 821 style addresses in SMTP commands. For example,
 /*     the RFC822-style address forms with comments that Sendmail allows.
 /* .IP \fBbroken_sasl_auth_clients\fR
-/*     Support older Microsoft clients that mis-implement the AUTH
+/*     Support Microsoft clients that implement an older version of the AUTH
 /*     protocol, and that expect an EHLO response of "250 AUTH=list"
 /*     instead of "250 AUTH list".
+/* .IP \fBsmtpd_sasl_exceptions_networks\fR
+/*     Don't offer AUTH in the response to EHLO when talking to clients
+/*     in the specified networks.  This is a workaround for clients that
+/*     that demand a login and password from the user whenever AUTH is
+/*     offered by an SMTP server.
 /* .IP \fBsmtpd_noop_commands\fR
 /*     List of commands that are treated as NOOP (no operation) commands,
 /*     without any parameter syntax checking and without any state change.
@@ -492,6 +497,7 @@ int     var_smtpd_junk_cmd_limit;
 bool    var_smtpd_sasl_enable;
 char   *var_smtpd_sasl_opts;
 char   *var_smtpd_sasl_realm;
+char   *var_smtpd_sasl_exceptions_networks;
 char   *var_filter_xport;
 bool    var_broken_auth_clients;
 char   *var_perm_mx_networks;
@@ -549,6 +555,35 @@ static void mail_reset(SMTPD_STATE *);
 static void rcpt_reset(SMTPD_STATE *);
 static void chat_reset(SMTPD_STATE *, int);
 
+ /*
+  * SASL exceptions.
+  */
+static NAMADR_LIST *sasl_exceptions_networks;
+
+/* sasl_client_exception - can we offer AUTH for this client */
+
+static int sasl_client_exception(SMTPD_STATE *state)
+{
+    int     match;
+
+    /*
+     * This is to work around a Netscape mail client bug where it tries to
+     * use AUTH if available, even if user has not configured it. Returns
+     * TRUE if AUTH should be offered in the EHLO.
+     */
+    if (sasl_exceptions_networks == 0)
+       return (0);
+
+    match = namadr_list_match(sasl_exceptions_networks,
+                             state->name, state->addr);
+
+    if (msg_verbose)
+       msg_info("sasl_exceptions: %s[%s], match=%d",
+                state->name, state->addr, match);
+
+    return (match);
+}
+
 /* collapse_args - put arguments together again */
 
 static void collapse_args(int argc, SMTPD_TOKEN *argv)
@@ -635,7 +670,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "250-VRFY");
     smtpd_chat_reply(state, "250-ETRN");
 #ifdef USE_SASL_AUTH
-    if (var_smtpd_sasl_enable) {
+    if (var_smtpd_sasl_enable && !sasl_client_exception(state)) {
        smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
        if (var_broken_auth_clients)
            smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list);
@@ -1764,13 +1799,6 @@ static void smtpd_service(VSTREAM *stream, char *unused_service, char **argv)
     smtpd_state_init(&state, stream);
     msg_info("connect from %s[%s]", state.name, state.addr);
 
-    /*
-     * XXX non_blocking() aborts upon error.
-     */
-#ifdef BROKEN_READ_SELECT_ON_BLOCKING_SOCKET
-    non_blocking(vstream_fileno(stream), NON_BLOCKING);
-#endif
-
     /*
      * See if we need to turn on verbose logging for this client.
      */
@@ -1820,6 +1848,11 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     if (var_smtpd_sasl_enable)
 #ifdef USE_SASL_AUTH
        smtpd_sasl_initialize();
+
+    if (*var_smtpd_sasl_exceptions_networks)
+       sasl_exceptions_networks =
+           namadr_list_init(MATCH_FLAG_NONE,
+                            var_smtpd_sasl_exceptions_networks);
 #else
        msg_warn("%s is true, but SASL support is not compiled in",
                 VAR_SMTPD_SASL_ENABLE);
@@ -1912,6 +1945,7 @@ int     main(int argc, char **argv)
        VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
        VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
        VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0,
+       VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS, DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS, &var_smtpd_sasl_exceptions_networks, 0, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
        VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
        VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0,
index bd9f8b2a639802197bd5e29c70947ff1d0190d7e..387ffa65defc7bc568a004fdb2bf5c19fbded2b8 100644 (file)
 /*     configuration parameter specifies the reject status code used in
 /*     the default template (default: 554).
 /* .IP reject_rhsbl_client rbl.domain.tld
+/* .IP reject_rhsbl_helo rbl.domain.tld
 /* .IP reject_rhsbl_sender rbl.domain.tld
 /* .IP reject_rhsbl_recipient rbl.domain.tld
-/*     Look up the client/sender/recipient domain name in the specified
+/*     Look up the client/helo/sender/recipient domain name in the specified
 /*     real-time blackhole DNS zone.  The \fIrbl_reply_maps\fR configuration
 /*     parameter is used to generate the template for the reject message.
 /*     If it is not specified, or the rbl domain cannot be found, then a
@@ -2987,6 +2988,16 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
                    status = reject_invalid_hostaddr(state, state->helo_name,
                                         state->helo_name, SMTPD_NAME_HELO);
            }
+       } else if (strcasecmp(name, REJECT_RHSBL_HELO) == 0) {
+           if (cpp[1] == 0)
+               msg_warn("restriction %s requires domain name argument",
+                        name);
+           else {
+               cpp += 1;
+               if (state->helo_name)
+                   status = reject_rbl_domain(state, *cpp, state->helo_name,
+                                              SMTPD_NAME_HELO);
+           }
        }
 
        /*
index 186538bb6d824e587898048bcc87448484d0595f..c541cdbaa57743365378e39a1d32e1365d9f51d4 100644 (file)
@@ -103,6 +103,7 @@ qmqp-source.o: ../../include/mymalloc.h
 qmqp-source.o: ../../include/events.h
 qmqp-source.o: ../../include/find_inet.h
 qmqp-source.o: ../../include/netstring.h
+qmqp-source.o: ../../include/sane_connect.h
 qmqp-source.o: ../../include/mail_date.h
 qmqp-source.o: ../../include/qmqp_proto.h
 smtp-sink.o: smtp-sink.c
@@ -119,6 +120,7 @@ smtp-sink.o: ../../include/events.h
 smtp-sink.o: ../../include/mymalloc.h
 smtp-sink.o: ../../include/msg_vstream.h
 smtp-sink.o: ../../include/stringops.h
+smtp-sink.o: ../../include/sane_accept.h
 smtp-sink.o: ../../include/smtp_stream.h
 smtp-source.o: smtp-source.c
 smtp-source.o: ../../include/sys_defs.h
@@ -135,5 +137,6 @@ smtp-source.o: ../../include/iostuff.h
 smtp-source.o: ../../include/mymalloc.h
 smtp-source.o: ../../include/events.h
 smtp-source.o: ../../include/find_inet.h
+smtp-source.o: ../../include/sane_connect.h
 smtp-source.o: ../../include/smtp_stream.h
 smtp-source.o: ../../include/mail_date.h
index b2beb0202792aba5a1fdd7124ae3ed3fe81eb82b..16ef364a40990152ca213f23f81d1cd93678cb90 100644 (file)
@@ -83,6 +83,7 @@
 #include <find_inet.h>
 #include <iostuff.h>
 #include <netstring.h>
+#include <sane_connect.h>
 
 /* Global library. */
 
@@ -312,7 +313,7 @@ static void start_connect(SESSION *session)
     session->stream = vstream_fdopen(fd, O_RDWR);
     event_enable_write(fd, connect_done, (char *) session);
     netstring_setup(session->stream, var_timeout);
-    if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
+    if (sane_connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
        fail_connect(session);
 }
 
index 2f3f7af046dc12e2f9e9287df91a20202d252d36..6d305e23bf3103403c6eb06a9226f082b0ea9a3d 100644 (file)
 /*     This program is the complement of the \fIsmtp-source\fR program.
 /*
 /*     Arguments:
+/* .IP \fB-a\fR
+/*     Do not announce SASL authentication support.
 /* .IP \fB-c\fR
 /*     Display a running counter that is updated whenever an SMTP
 /*     QUIT command is executed.
 /* .IP \fB-e\fR
 /*     Disable ESMTP support.
+/* .IP "\fB-f  \fIcommand,command,...\fR"
+/*     Reject the specified commands with a hard (5xx) error code.
 /* .IP \fB-h\fI hostname\fR
 /*     Use \fIhostname\fR in the SMTP greeting, in the HELO response,
 /*     and in the EHLO response. The default hostname is "smtp-sink".
@@ -36,6 +40,8 @@
 /* .IP \fB-P\fR
 /*     Change the server greeting so that it appears to come through
 /*     a CISCO PIX system. Implies \fB-e\fR.
+/* .IP "\fB-r  \fIcommand,command,...\fR"
+/*     Reject the specified commands with a soft (4xx) error code.
 /* .IP "\fB-s \fIcommand,command,...\fR"
 /*     Log the named commands to syslogd.
 /*     Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
 #include <iostuff.h>
 #include <msg_vstream.h>
 #include <stringops.h>
+#include <sane_accept.h>
 
 /* Global library. */
 
@@ -135,6 +142,7 @@ static int fixed_delay;
 static int disable_esmtp;
 static int enable_lmtp;
 static int pretend_pix;
+static int disable_saslauth;
 
 /* ehlo_response - respond to EHLO command */
 
@@ -145,6 +153,8 @@ static void ehlo_response(SINK_STATE *state)
        smtp_printf(state->stream, "250-PIPELINING");
     if (!disable_8bitmime)
        smtp_printf(state->stream, "250-8BITMIME");
+    if (!disable_saslauth)
+       smtp_printf(state->stream, "250-AUTH PLAIN LOGIN");
     smtp_printf(state->stream, "250 ");
     smtp_flush(state->stream);
 }
@@ -205,8 +215,8 @@ static void data_event(int unused_event, char *context)
 static void dot_response(SINK_STATE *state)
 {
     if (enable_lmtp) {
-       while (state->rcpts-- > 0)              /* XXX this could block */
-           ok_response(state);                 /* XXX this flushes too often */
+       while (state->rcpts-- > 0)      /* XXX this could block */
+           ok_response(state);         /* XXX this flushes too often */
     } else {
        ok_response(state);
     }
@@ -297,11 +307,14 @@ typedef struct SINK_COMMAND {
 
 #define FLAG_ENABLE    (1<<0)          /* command is enabled */
 #define FLAG_SYSLOG    (1<<1)          /* log the command */
+#define FLAG_HARD_ERR  (1<<2)          /* report hard error */
+#define FLAG_SOFT_ERR  (1<<3)          /* report soft error */
 
 static SINK_COMMAND command_table[] = {
     "helo", helo_response, 0,
     "ehlo", ehlo_response, 0,
     "lhlo", ehlo_response, 0,
+    "auth", ok_response, FLAG_ENABLE,
     "mail", mail_response, FLAG_ENABLE,
     "rcpt", rcpt_response, FLAG_ENABLE,
     "data", data_response, FLAG_ENABLE,
@@ -436,6 +449,16 @@ static int command_read(SINK_STATE *state)
        smtp_flush(state->stream);
        return (0);
     }
+    if (cmdp->flags & FLAG_HARD_ERR) {
+       smtp_printf(state->stream, "500 Error: command failed");
+       smtp_flush(state->stream);
+       return (0);
+    }
+    if (cmdp->flags & FLAG_SOFT_ERR) {
+       smtp_printf(state->stream, "450 Error: command failed");
+       smtp_flush(state->stream);
+       return (0);
+    }
     /* We use raw syslog. Sanitize data content and length. */
     if (cmdp->flags & FLAG_SYSLOG)
        syslog(LOG_INFO, "%s %.100s", command, printable(ptr, '?'));
@@ -503,7 +526,7 @@ static void connect_event(int unused_event, char *context)
     SINK_STATE *state;
     int     fd;
 
-    if ((fd = accept(sock, &sa, &len)) >= 0) {
+    if ((fd = sane_accept(sock, &sa, &len)) >= 0) {
        if (msg_verbose)
            msg_info("connect (%s)",
 #ifdef AF_LOCAL
@@ -555,14 +578,20 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "ceh:Ln:pPs:vw:8")) > 0) {
+    while ((ch = GETOPT(argc, argv, "acef:h:Ln:pPr:s:vw:8")) > 0) {
        switch (ch) {
+       case 'a':
+           disable_saslauth = 1;
+           break;
        case 'c':
            count++;
            break;
        case 'e':
            disable_esmtp = 1;
            break;
+       case 'f':
+           set_cmds_flags(optarg, FLAG_HARD_ERR);
+           break;
        case 'h':
            var_myhostname = optarg;
            break;
@@ -579,6 +608,9 @@ int     main(int argc, char **argv)
            pretend_pix = 1;
            disable_esmtp = 1;
            break;
+       case 'r':
+           set_cmds_flags(optarg, FLAG_SOFT_ERR);
+           break;
        case 's':
            openlog(basename(argv[0]), LOG_PID, LOG_MAIL);
            set_cmds_flags(optarg, FLAG_SYSLOG);
index c575c5a34ee74d24acb4d1372d3ec8bf25f63ab2..fdb2f8690d26bfdd978ba3728d2ca3f76b4dc635 100644 (file)
 #include <events.h>
 #include <find_inet.h>
 #include <iostuff.h>
+#include <sane_connect.h>
 
 /* Global library. */
 
@@ -418,7 +419,7 @@ static void start_connect(SESSION *session)
     session->stream = vstream_fdopen(fd, O_RDWR);
     event_enable_write(fd, connect_done, (char *) session);
     smtp_timeout_setup(session->stream, var_timeout);
-    if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
+    if (sane_connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
        fail_connect(session);
 }
 
index 8e6f88b0a5dd99b4aa39d4ea1177015e341dd181..a8fa58d71056a5bed3834a558c8686769abbb188 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <msg.h>
@@ -405,6 +409,9 @@ static void resolve_addr(RES_CONTEXT *rp, char *addr,
                    msg_warn("do not list domain %s in BOTH %s and %s",
                             rcpt_domain, VAR_VIRT_ALIAS_DOMS,
                             VAR_RELAY_DOMAINS);
+               if (strcasecmp(rcpt_domain, var_myorigin) == 0)
+                   msg_warn("do not list $%s in %s",
+                            VAR_MYORIGIN, VAR_VIRT_ALIAS_DOMS);
            }
            vstring_strcpy(channel, MAIL_SERVICE_ERROR);
            vstring_sprintf(nexthop, "User unknown%s",
index 3bffdf56f752aa9f0e91286c6f0e94a2724d86b5..5dc045801a2c7f257edf7a7137e91869e10110c0 100644 (file)
@@ -27,7 +27,7 @@ SRCS  = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \
        username.c valid_hostname.c vbuf.c vbuf_print.c vstream.c \
        vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
        write_buf.c write_wait.c auto_clnt.c attr_clnt.c attr_scan_plain.c \
-       attr_print_plain.c
+       attr_print_plain.c sane_connect.c
 OBJS   = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
        attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
        chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
@@ -56,7 +56,7 @@ OBJS  = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
        username.o valid_hostname.o vbuf.o vbuf_print.o vstream.o \
        vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
        write_buf.o write_wait.o auto_clnt.o attr_clnt.o attr_scan_plain.o \
-       attr_print_plain.o $(STRCASE)
+       attr_print_plain.o sane_connect.o $(STRCASE)
 HDRS   = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
        connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
        dict_cidr.h dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
@@ -75,7 +75,7 @@ HDRS  = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
        split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
        timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
        vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
-       auto_clnt.h attr_clnt.h
+       auto_clnt.h attr_clnt.h sane_connect.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -891,6 +891,7 @@ inet_connect.o: msg.h
 inet_connect.o: find_inet.h
 inet_connect.o: inet_util.h
 inet_connect.o: iostuff.h
+inet_connect.o: sane_connect.h
 inet_connect.o: connect.h
 inet_connect.o: timed_connect.h
 inet_listen.o: inet_listen.c
@@ -1002,6 +1003,7 @@ msg_syslog.o: stringops.h
 msg_syslog.o: msg.h
 msg_syslog.o: msg_output.h
 msg_syslog.o: msg_syslog.h
+msg_syslog.o: safe.h
 msg_vstream.o: msg_vstream.c
 msg_vstream.o: sys_defs.h
 msg_vstream.o: vstream.h
@@ -1122,6 +1124,10 @@ sane_accept.o: sane_accept.c
 sane_accept.o: sys_defs.h
 sane_accept.o: msg.h
 sane_accept.o: sane_accept.h
+sane_connect.o: sane_connect.c
+sane_connect.o: sys_defs.h
+sane_connect.o: msg.h
+sane_connect.o: sane_connect.h
 sane_link.o: sane_link.c
 sane_link.o: sys_defs.h
 sane_link.o: msg.h
@@ -1229,9 +1235,11 @@ timed_connect.o: timed_connect.c
 timed_connect.o: sys_defs.h
 timed_connect.o: msg.h
 timed_connect.o: iostuff.h
+timed_connect.o: sane_connect.h
 timed_connect.o: timed_connect.h
 timed_read.o: timed_read.c
 timed_read.o: sys_defs.h
+timed_read.o: msg.h
 timed_read.o: iostuff.h
 timed_wait.o: timed_wait.c
 timed_wait.o: sys_defs.h
@@ -1240,6 +1248,7 @@ timed_wait.o: posix_signals.h
 timed_wait.o: timed_wait.h
 timed_write.o: timed_write.c
 timed_write.o: sys_defs.h
+timed_write.o: msg.h
 timed_write.o: iostuff.h
 translit.o: translit.c
 translit.o: sys_defs.h
@@ -1260,6 +1269,7 @@ unix_connect.o: unix_connect.c
 unix_connect.o: sys_defs.h
 unix_connect.o: msg.h
 unix_connect.o: iostuff.h
+unix_connect.o: sane_connect.h
 unix_connect.o: connect.h
 unix_connect.o: timed_connect.h
 unix_listen.o: unix_listen.c
index edd8675c92b446a4eba349026e7e190fb2e0e627..14023dfe2eb5802d163443a56a700461bfa408b0 100644 (file)
@@ -12,7 +12,8 @@
 /*     clean_env() reduces the process environment to the bare minimum.
 /*     The function takes a null-terminated list of arguments.
 /*     Each argument specifies the name of an environment variable
-/*     that should be preserved.
+/*     that should be preserved, or specifies a name=value that should
+/*     be entered into the new environment.
 /* DIAGNOSTICS
 /*     Fatal error: out of memory.
 /* SEE ALSO
@@ -33,6 +34,7 @@
 #include <sys_defs.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 
 /* Utility library. */
 
@@ -49,15 +51,20 @@ void    clean_env(char **preserve_list)
     ARGV   *save_list;
     char   *value;
     char  **cpp;
+    char   *eq;
 
     /*
-     * Preserve selected environment variables.
+     * Preserve or specify selected environment variables.
      */
+#define STRING_AND_LENGTH(x, y) (x), (y)
+
     save_list = argv_alloc(10);
     for (cpp = preserve_list; *cpp; cpp++)
-       if ((value = safe_getenv(*cpp)) != 0)
+       if ((eq = strchr(*cpp, '=')) != 0)
+           argv_addn(save_list, STRING_AND_LENGTH(*cpp, eq - *cpp),
+                     STRING_AND_LENGTH(eq + 1, strlen(eq + 1)), (char *) 0);
+       else if ((value = safe_getenv(*cpp)) != 0)
            argv_add(save_list, *cpp, value, (char *) 0);
-    argv_terminate(save_list);
 
     /*
      * Truncate the process environment, if available. On some systems
@@ -71,7 +78,7 @@ void    clean_env(char **preserve_list)
      */
     for (cpp = save_list->argv; *cpp; cpp += 2)
        if (setenv(cpp[0], cpp[1], 1))
-           msg_fatal("setenv: %m");
+           msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
 
     /*
      * Cleanup.
index c4867ba65f1be17e21a2d1b9416052e81e80e96d..1523c3397789a80f21ef2e2c1b6e9b0559cb51bb 100644 (file)
 /*
 /*     Arguments:
 /* .IP ldapsource
-/*     The prefix which will be used to obtain configuration parameters
-/*     for this search. If it's 'ldapone', the configuration variables below
-/*     would look like 'ldapone_server_host', 'ldapone_search_base', and so
-/*     on in main.cf.
+/*      Either the path to the LDAP configuration file (if it starts
+/*      with '/' or '.'), or the prefix which will be used to obtain
+/*      configuration parameters for this search.
+/*
+/*      In the first case, the configuration variables below are
+/*      specified in the file as \fBname\fR=\fBvalue\fR pairs.
+/*
+/*      In the second case, the configuration variables are prefixed
+/*      with the value of \fIldapsource\fR and an underscore,
+/*      and they are specified in main.cf.  For example, if this
+/*      value is \fBldapone\fR, the variables would look like
+/*      \fBldapone_server_host\fR, \fBldapone_search_base\fR, and so on.
 /* .IP dummy
 /*     Not used; this argument exists only for compatibility with
 /*     the dict_open(3) interface.
 /* .PP
 /*     Configuration parameters:
-/* .IP \fIldapsource_\fRserver_host
-/*     The host at which all LDAP queries are directed.
-/* .IP \fIldapsource_\fRserver_port
+/* .IP server_host
+/*     Blank-separated list of hosts at which all LDAP queries are directed.
+/*     The host names can also be LDAP URLs if the LDAP client library used
+/*     is OpenLDAP.
+/* .IP server_port
 /*     The port the LDAP server listens on.
-/* .IP \fIldapsource_\fRsearch_base
+/* .IP search_base
 /*     The LDAP search base, for example: \fIO=organization name, C=country\fR.
-/* .IP \fIldapsource_\fRdomain
+/* .IP domain
 /*     If specified, only lookups ending in this value will be queried.
 /*      This can significantly reduce the query load on the LDAP server.
-/* .IP \fIldapsource_\fRtimeout
+/* .IP timeout
 /*     Deadline for LDAP open() and LDAP search() .
-/* .IP \fIldapsource_\fRquery_filter
+/* .IP query_filter
 /*     The filter used to search for directory entries, for example
 /*     \fI(mailacceptinggeneralid=%s)\fR.
-/* .IP \fIldapsource_\fRresult_filter
+/* .IP result_filter
 /*     The filter used to expand results from queries.  Default is
 /*     \fI%s\fR.
-/* .IP \fIldapsource_\fRresult_attribute
+/* .IP result_attribute
 /*     The attribute(s) returned by the search, in which to find
 /*     RFC822 addresses, for example \fImaildrop\fR.
-/* .IP \fIldapsource_\fRspecial_result_attribute
+/* .IP special_result_attribute
 /*     The attribute(s) of directory entries that can contain DNs or URLs.
 /*      If found, a recursive subsequent search is done using their values.
-/* .IP \fIldapsource_\fRscope
+/* .IP scope
 /*     LDAP search scope: sub, base, or one.
-/* .IP \fIldapsource_\fRbind
+/* .IP bind
 /*     Whether or not to bind to the server -- LDAP v3 implementations don't
 /*     require it, which saves some overhead.
-/* .IP \fIldapsource_\fRbind_dn
+/* .IP bind_dn
 /*     If you must bind to the server, do it with this distinguished name ...
-/* .IP \fIldapsource_\fRbind_pw
+/* .IP bind_pw
 /*     \&... and this password.
-/* .IP \fIldapsource_\fRcache (no longer supported)
+/* .IP cache (no longer supported)
 /*     Whether or not to turn on client-side caching.
-/* .IP \fIldapsource_\fRcache_expiry (no longer supported)
+/* .IP cache_expiry (no longer supported)
 /*     If you do cache results, expire them after this many seconds.
-/* .IP \fIldapsource_\fRcache_size (no longer supported)
+/* .IP cache_size (no longer supported)
 /*     The cache size in bytes. Does nothing if the cache is off, of course.
-/* .IP \fIldapsource_\fRrecursion_limit
+/* .IP recursion_limit
 /*     Maximum recursion depth when expanding DN or URL references.
 /*     Queries which exceed the recursion limit fail with
 /*     dict_errno = DICT_ERR_RETRY.
-/* .IP \fIldapsource_\fRexpansion_limit
+/* .IP expansion_limit
 /*     Limit (if any) on the total number of lookup result values. Lookups which
 /*     exceed the limit fail with dict_errno=DICT_ERR_RETRY. Note that
 /*     each value of a multivalued result attribute counts as one result.
-/* .IP \fIldapsource_\fRsize_limit
+/* .IP size_limit
 /*     Limit on the number of entries returned by individual LDAP queries.
 /*     Queries which exceed the limit fail with dict_errno=DICT_ERR_RETRY.
 /*     This is an *entry* count, for any single query performed during the
 /*     possibly recursive lookup.
-/* .IP \fIldapsource_\fRchase_referrals
+/* .IP chase_referrals
 /*     Controls whether LDAP referrals are obeyed.
-/* .IP \fIldapsource_\fRdereference
+/* .IP dereference
 /*     How to handle LDAP aliases. See ldap.h or ldap_open(3) man page.
-/* .IP \fIldapsource_\fRdebuglevel
+/* .IP version
+/*     Specifies the LDAP protocol version to use.  Default is version
+/*     \fI2\fR.
+/* .IP start_tls
+/*     Whether or not to issue STARTTLS upon connection to the server.
+/*     At this time, STARTTLS and LDAP SSL are only available if the
+/*     LDAP client library used is OpenLDAP.  Default is \fIno\fR.
+/* .IP tls_ca_cert_file
+/*     File containing certificates for all of the X509 Certificate
+/*     Authorities the client will recognize.  Takes precedence over
+/*     tls_ca_cert_dir.
+/* .IP tls_ca_cert_dir
+/*     Directory containing X509 Certificate Authority certificates
+/*     in separate individual files.
+/* .IP tls_cert
+/*     File containing client's X509 certificate.
+/* .IP tls_key
+/*     File containing the private key corresponding to
+/*     tls_cert.
+/* .IP tls_require_cert
+/*     Whether or not to request server's X509 certificate and check its
+/*     validity.
+/* .IP tls_random_file
+/*     Path of a file to obtain random bits from when /dev/[u]random is
+/*     not available. Generally set to the name of the EGD/PRNGD socket.
+/* .IP tls_cipher_suite
+/*     Cipher suite to use in SSL/TLS negotiations.
+/* .IP debuglevel
 /*     Debug level.  See 'loglevel' option in slapd.conf(5) man page.
 /*      Currently only in openldap libraries (and derivatives).
 /* SEE ALSO
 #include "vstring.h"
 #include "dict.h"
 #include "dict_ldap.h"
+#include "stringops.h"
 
 /* AAARGH!! */
 
@@ -174,10 +212,27 @@ typedef struct {
     int     chase_referrals;
     int     debuglevel;
     int     version;
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+    int     ldap_ssl;
+    int     start_tls;
+    int     tls_require_cert;
+    char   *tls_ca_cert_file;
+    char   *tls_ca_cert_dir;
+    char   *tls_cert;
+    char   *tls_key;
+    char   *tls_random_file;
+    char   *tls_cipher_suite;
+#endif
     LDAP   *ld;
 } DICT_LDAP;
 
-#ifndef LDAP_OPT_NETWORK_TIMEOUT
+typedef struct {
+    char   *(*get_str) (const char *, const char *, const char *, int, int);
+    int     (*get_int) (const char *, const char *, int, int, int);
+    int     (*get_bool) (const char *, const char *, int);
+}       CFG_PARSER;
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
 /*
  * LDAP connection timeout support.
  */
@@ -198,6 +253,104 @@ static void dict_ldap_logprint(LDAP_CONST char *data)
 }
 
 
+static char *dict_ldap_get_dict_str(const char *opt_dict_name,
+                                      const char *name, const char *defval,
+                                           int min, int max)
+{
+    const char *strval;
+    int     len;
+
+    if ((strval = (char *) dict_lookup(opt_dict_name, name)) == 0)
+       strval = defval;
+
+    len = strlen(strval);
+    if (min && len < min)
+       msg_fatal("%s: bad string length %d < %d: %s = %s",
+                 opt_dict_name, len, min, name, strval);
+    if (max && len > max)
+       msg_fatal("%s: bad string length %d > %d: %s = %s",
+                 opt_dict_name, len, max, name, strval);
+    return (mystrdup(strval));
+}
+
+static char *dict_ldap_get_mail_str(const char *opt_dict_name,
+                                      const char *name, const char *defval,
+                                           int min, int max)
+{
+    static VSTRING *buf = 0;
+
+    if (buf == 0)
+       buf = vstring_alloc(15);
+    vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+    return ((char *) get_mail_conf_str(vstring_str(buf),
+                                      defval, min, max));
+}
+
+static int dict_ldap_get_dict_int(const char *opt_dict_name,
+                            const char *name, int defval, int min, int max)
+{
+    const char *strval;
+    int     intval;
+    char    junk;
+
+    if ((strval = (char *) dict_lookup(opt_dict_name, name)) != 0) {
+       if (sscanf(strval, "%d%c", &intval, &junk) != 1)
+           msg_fatal("%s: bad numerical configuration: %s = %s",
+                     opt_dict_name, name, strval);
+    } else
+       intval = defval;
+    if (min && intval < min)
+       msg_fatal("%s: invalid %s parameter value %d < %d",
+                 opt_dict_name, name, intval, min);
+    if (max && intval > max)
+       msg_fatal("%s: invalid %s parameter value %d > %d",
+                 opt_dict_name, name, intval, max);
+    return (intval);
+}
+
+static int dict_ldap_get_mail_int(const char *opt_dict_name,
+                            const char *name, int defval, int min, int max)
+{
+    static VSTRING *buf = 0;
+
+    if (buf == 0)
+       buf = vstring_alloc(15);
+    vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+    return (get_mail_conf_int(vstring_str(buf), defval, min, max));
+}
+
+static int dict_ldap_get_dict_bool(const char *opt_dict_name,
+                                          const char *name, int defval)
+{
+    const char *strval;
+    int     intval;
+
+    if ((strval = (char *) dict_lookup(opt_dict_name, name)) != 0) {
+       if (strcasecmp(strval, CONFIG_BOOL_YES) == 0) {
+           intval = 1;
+       } else if (strcasecmp(strval, CONFIG_BOOL_NO) == 0) {
+           intval = 0;
+       } else {
+           msg_fatal("%s: bad boolean configuration: %s = %s",
+                     opt_dict_name, name, strval);
+       }
+    } else
+       intval = defval;
+    return (intval);
+}
+
+static int dict_ldap_get_mail_bool(const char *opt_dict_name,
+                                          const char *name, int defval)
+{
+    static VSTRING *buf = 0;
+
+    if (buf == 0)
+       buf = vstring_alloc(15);
+    vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+    return (get_mail_conf_bool(vstring_str(buf), defval));
+}
+
+
 static int dict_ldap_get_errno(LDAP * ld)
 {
     int     rc;
@@ -240,6 +393,67 @@ static int dict_ldap_bind_st(DICT_LDAP *dict_ldap)
     return (ldap_result2error(dict_ldap->ld, res, 1));
 }
 
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+static void dict_ldap_set_tls_options(DICT_LDAP *dict_ldap)
+{
+    char   *myname = "dict_ldap_set_tls_options";
+    int     rc;
+
+    if (dict_ldap->start_tls || dict_ldap->ldap_ssl) {
+       if (*dict_ldap->tls_random_file) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
+                              dict_ldap->tls_random_file)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_random_file to %s: %d: %s",
+                        myname, dict_ldap->tls_random_file,
+                        rc, ldap_err2string(rc));
+       }
+       if (*dict_ldap->tls_ca_cert_file) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+                             dict_ldap->tls_ca_cert_file)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_ca_cert_file to %s: %d: %s",
+                        myname, dict_ldap->tls_ca_cert_file,
+                        rc, ldap_err2string(rc));
+       }
+       if (*dict_ldap->tls_ca_cert_dir) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR,
+                              dict_ldap->tls_ca_cert_dir)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_ca_cert_dir to %s: %d: %s",
+                        myname, dict_ldap->tls_ca_cert_dir,
+                        rc, ldap_err2string(rc));
+       }
+       if (*dict_ldap->tls_cert) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE,
+                                     dict_ldap->tls_cert)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_cert to %s: %d: %s",
+                        myname, dict_ldap->tls_cert,
+                        rc, ldap_err2string(rc));
+       }
+       if (*dict_ldap->tls_key) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE,
+                                     dict_ldap->tls_key)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_key to %s: %d: %s",
+                        myname, dict_ldap->tls_key,
+                        rc, ldap_err2string(rc));
+       }
+       if (*dict_ldap->tls_cipher_suite) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
+                             dict_ldap->tls_cipher_suite)) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_cipher_suite to %s: %d: %s",
+                        myname, dict_ldap->tls_cipher_suite,
+                        rc, ldap_err2string(rc));
+       }
+       if (dict_ldap->tls_require_cert) {
+           if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+                          &(dict_ldap->tls_require_cert))) != LDAP_SUCCESS)
+               msg_warn("%s: Unable to set tls_require_cert to %d: %d: %s",
+                        myname, dict_ldap->tls_require_cert,
+                        rc, ldap_err2string(rc));
+       }
+    }
+}
+
+#endif
+
 /* Establish a connection to the LDAP server. */
 static int dict_ldap_connect(DICT_LDAP *dict_ldap)
 {
@@ -249,7 +463,9 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
     struct timeval mytimeval;
 
-#else
+#endif
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
     void    (*saved_alarm) (int);
 
 #endif
@@ -261,8 +477,13 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
                 dict_ldap->server_host);
 
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+    dict_ldap_set_tls_options(dict_ldap);
+    ldap_initialize(&(dict_ldap->ld), dict_ldap->server_host);
+#else
     dict_ldap->ld = ldap_init(dict_ldap->server_host,
                              (int) dict_ldap->server_port);
+#endif
     if (dict_ldap->ld == NULL) {
        msg_warn("%s: Unable to init LDAP server %s",
                 myname, dict_ldap->server_host);
@@ -318,7 +539,7 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
                            &dict_ldap->version) != LDAP_OPT_SUCCESS)
            msg_warn("%s: Unable to get LDAP protocol version", myname);
        else
-           msg_warn("%s: Actual Protocol version used is %d.",
+           msg_info("%s: Actual Protocol version used is %d.",
                     myname, dict_ldap->version);
     }
 #endif
@@ -368,6 +589,36 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
     }
 #endif
 
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+    if (dict_ldap->start_tls) {
+       if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) {
+           msg_warn("%s: Error setting signal handler for STARTTLS timeout: %m",
+                    myname);
+           dict_errno = DICT_ERR_RETRY;
+           return (-1);
+       }
+       alarm(dict_ldap->timeout);
+       if (setjmp(env) == 0)
+           rc = ldap_start_tls_s(dict_ldap->ld, NULL, NULL);
+       else
+           rc = LDAP_TIMEOUT;
+       alarm(0);
+
+       if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
+           msg_warn("%s: Error resetting signal handler after STARTTLS: %m",
+                    myname);
+           dict_errno = DICT_ERR_RETRY;
+           return (-1);
+       }
+       if (rc != LDAP_SUCCESS) {
+           msg_error("%s: Unable to set STARTTLS: %d: %s", myname,
+                     rc, ldap_err2string(rc));
+           dict_errno = DICT_ERR_RETRY;
+           return (-1);
+       }
+    }
+#endif
+
     /*
      * If this server requires a bind, do so. Thanks to Sam Tardieu for
      * noticing that the original bind call was broken.
@@ -893,6 +1144,14 @@ static void dict_ldap_close(DICT *dict)
     argv_free(dict_ldap->result_attributes);
     myfree(dict_ldap->bind_dn);
     myfree(dict_ldap->bind_pw);
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+    myfree(dict_ldap->tls_ca_cert_file);
+    myfree(dict_ldap->tls_ca_cert_dir);
+    myfree(dict_ldap->tls_cert);
+    myfree(dict_ldap->tls_key);
+    myfree(dict_ldap->tls_random_file);
+    myfree(dict_ldap->tls_cipher_suite);
+#endif
     dict_free(dict);
 }
 
@@ -902,7 +1161,15 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
 {
     char   *myname = "dict_ldap_open";
     DICT_LDAP *dict_ldap;
-    VSTRING *config_param;
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+    VSTRING *url_list;
+    char   *s,
+           *h;
+
+#endif
+    char   *server_host;
+    CFG_PARSER parser;
     char   *domainlist;
     char   *scope;
     char   *attr;
@@ -917,71 +1184,134 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     dict_ldap->dict.close = dict_ldap_close;
     dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
 
+    dict_ldap->ld = NULL;
     dict_ldap->ldapsource = mystrdup(ldapsource);
 
-    config_param = vstring_alloc(15);
-    vstring_sprintf(config_param, "%s_server_host", ldapsource);
+    if (ldapsource[0] == '/' || ldapsource[0] == '.') {
+       dict_load_file(ldapsource, ldapsource);
+       parser.get_str = dict_ldap_get_dict_str;
+       parser.get_int = dict_ldap_get_dict_int;
+       parser.get_bool = dict_ldap_get_dict_bool;
+    } else {
+
+       /*
+        * msg_warn("Defining LDAP attributes in main.cf is deprecated. Use
+        * ldap:/path/to/file instead");
+        */
+       parser.get_str = dict_ldap_get_mail_str;
+       parser.get_int = dict_ldap_get_mail_int;
+       parser.get_bool = dict_ldap_get_mail_bool;
+    }
 
-    dict_ldap->server_host =
-       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                           "localhost", 0, 0));
+    server_host = parser.get_str(ldapsource, "server_host",
+                                "localhost", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
-                dict_ldap->server_host);
+       msg_info("%s: %s server_host is %s", myname, ldapsource,
+                server_host);
 
     /*
-     * get configured value of "ldapsource_server_port"; default to LDAP_PORT
-     * (389)
+     * get configured value of "server_port"; default to LDAP_PORT (389)
      */
-    vstring_sprintf(config_param, "%s_server_port", ldapsource);
     dict_ldap->server_port =
-       get_mail_conf_int(vstring_str(config_param), LDAP_PORT, 0, 0);
+       parser.get_int(ldapsource, "server_port", LDAP_PORT, 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s server_port is %d", myname, ldapsource,
                 dict_ldap->server_port);
 
+    /*
+     * Define LDAP Version.
+     */
+    dict_ldap->version = parser.get_int(ldapsource, "version", 2, 0, 0);
+    switch (dict_ldap->version) {
+    case 2:
+       dict_ldap->version = LDAP_VERSION2;
+       break;
+    case 3:
+       dict_ldap->version = LDAP_VERSION3;
+       break;
+    default:
+       msg_warn("%s: %s Unknown version %d.", myname, ldapsource,
+                dict_ldap->version);
+       dict_ldap->version = LDAP_VERSION2;
+    }
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+
+    /*
+     * Convert (host, port) pairs to LDAP URLs
+     */
+    url_list = vstring_alloc(32);
+    s = server_host;
+    dict_ldap->ldap_ssl = 0;
+    while ((h = mystrtok(&s, " \t")) != NULL) {
+       if (ldap_is_ldap_url(h)) {
+           LDAPURLDesc *url_desc;
+           int     rc;
+
+           if ((rc = ldap_url_parse(h, &url_desc)) != 0) {
+               msg_error("%s: error parsing URL %s: %d: %s; skipping", myname,
+                         h, rc, ldap_err2string(rc));
+               continue;
+           }
+           if (strcasecmp(url_desc->lud_scheme, "ldap") != 0 &&
+               dict_ldap->version != LDAP_VERSION3) {
+               msg_warn("%s: URL scheme %s requires protocol version 3", myname,
+                        url_desc->lud_scheme);
+               dict_ldap->version = LDAP_VERSION3;
+           }
+           if (strcasecmp(url_desc->lud_scheme, "ldaps") == 0)
+               dict_ldap->ldap_ssl = 1;
+           ldap_free_urldesc(url_desc);
+           vstring_sprintf_append(url_list, " %s", h);
+       } else {
+           if (strrchr(h, ':'))
+               vstring_sprintf_append(url_list, " ldap://%s", h);
+           else
+               vstring_sprintf_append(url_list, " ldap://%s:%d", h,
+                                      dict_ldap->server_port);
+       }
+    }
+    dict_ldap->server_host = mystrdup(vstring_str(url_list) + 1);
+    if (msg_verbose)
+       msg_info("%s: %s server_host URL is %s", myname, ldapsource,
+                dict_ldap->server_host);
+    myfree(server_host);
+    vstring_free(url_list);
+#else
+    dict_ldap->server_host = server_host;
+#endif
+
     /*
      * Scope handling thanks to Carsten Hoeger of SuSE.
      */
-    vstring_sprintf(config_param, "%s_scope", ldapsource);
-    scope =
-       (char *) get_mail_conf_str(vstring_str(config_param), "sub", 0, 0);
+    scope = parser.get_str(ldapsource, "scope", "sub", 0, 0);
 
     if (strcasecmp(scope, "one") == 0) {
        dict_ldap->scope = LDAP_SCOPE_ONELEVEL;
        if (msg_verbose)
-           msg_info("%s: %s is LDAP_SCOPE_ONELEVEL", myname,
-                    vstring_str(config_param));
+           msg_info("%s: %s scope is LDAP_SCOPE_ONELEVEL", myname, ldapsource);
 
     } else if (strcasecmp(scope, "base") == 0) {
        dict_ldap->scope = LDAP_SCOPE_BASE;
        if (msg_verbose)
-           msg_info("%s: %s is LDAP_SCOPE_BASE", myname,
-                    vstring_str(config_param));
+           msg_info("%s: %s scope is LDAP_SCOPE_BASE", myname, ldapsource);
 
     } else {
        dict_ldap->scope = LDAP_SCOPE_SUBTREE;
        if (msg_verbose)
-           msg_info("%s: %s is LDAP_SCOPE_SUBTREE", myname,
-                    vstring_str(config_param));
+           msg_info("%s: %s scope is LDAP_SCOPE_SUBTREE", myname, ldapsource);
 
     }
 
     myfree(scope);
 
-    vstring_sprintf(config_param, "%s_search_base", ldapsource);
-    dict_ldap->search_base = mystrdup((char *)
-                                     get_mail_conf_str(vstring_str
-                                                       (config_param), "",
-                                                       0, 0));
+    dict_ldap->search_base = parser.get_str(ldapsource, "search_base",
+                                           "", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+       msg_info("%s: %s search_base is %s", myname, ldapsource,
                 dict_ldap->search_base);
 
-    vstring_sprintf(config_param, "%s_domain", ldapsource);
-    domainlist =
-       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                           "", 0, 0));
+    domainlist = parser.get_str(ldapsource, "domain", "", 0, 0);
     if (*domainlist) {
 #ifdef MATCH_FLAG_NONE
        dict_ldap->domain = match_list_init(MATCH_FLAG_NONE,
@@ -1000,219 +1330,212 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     myfree(domainlist);
 
     /*
-     * get configured value of "ldapsource_timeout"; default to 10 seconds
+     * get configured value of "timeout"; default to 10 seconds
      * 
      * Thanks to Manuel Guesdon for spotting that this wasn't really getting
      * set.
      */
-    vstring_sprintf(config_param, "%s_timeout", ldapsource);
     dict_ldap->timeout =
-       get_mail_conf_int(vstring_str(config_param), 10, 0, 0);
+       parser.get_int(ldapsource, "timeout", 10, 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s timeout is %d", myname, ldapsource,
                 dict_ldap->timeout);
 
-    vstring_sprintf(config_param, "%s_query_filter", ldapsource);
     dict_ldap->query_filter =
-       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                           "(mailacceptinggeneralid=%s)",
-                                           0, 0));
+       parser.get_str(ldapsource, "query_filter",
+                      "(mailacceptinggeneralid=%s)", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+       msg_info("%s: %s query_filter is %s", myname, ldapsource,
                 dict_ldap->query_filter);
 
-    vstring_sprintf(config_param, "%s_result_filter", ldapsource);
     dict_ldap->result_filter =
-       mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                           "%s",
-                                           0, 0));
+       parser.get_str(ldapsource, "result_filter", "%s", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+       msg_info("%s: %s result_filter is %s", myname, ldapsource,
                 dict_ldap->result_filter);
 
     if (strcmp(dict_ldap->result_filter, "%s") == 0) {
        myfree(dict_ldap->result_filter);
        dict_ldap->result_filter = NULL;
     }
-    vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
-    attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                              "maildrop", 0, 0));
+    attr = parser.get_str(ldapsource, "result_attribute", "maildrop", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
+       msg_info("%s: %s result_attribute is %s", myname, ldapsource, attr);;
     dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
     dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
+    myfree(attr);
 
-    vstring_sprintf(config_param, "%s_special_result_attribute", ldapsource);
-    attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
-                                              "", 0, 0));
+    attr = parser.get_str(ldapsource, "special_result_attribute", "", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);
-
+       msg_info("%s: %s special_result_attribute is %s", myname, ldapsource,
+                attr);
     if (*attr) {
        argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
     }
+    myfree(attr);
 
     /*
-     * get configured value of "ldapsource_bind"; default to true
+     * get configured value of "bind"; default to true
      */
-    vstring_sprintf(config_param, "%s_bind", ldapsource);
-    dict_ldap->bind = get_mail_conf_bool(vstring_str(config_param), 1);
+    dict_ldap->bind = parser.get_bool(ldapsource, "bind", 1);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
-                dict_ldap->bind);
+       msg_info("%s: %s bind is %d", myname, ldapsource, dict_ldap->bind);
 
     /*
-     * get configured value of "ldapsource_bind_dn"; default to ""
+     * get configured value of "bind_dn"; default to ""
      */
-    vstring_sprintf(config_param, "%s_bind_dn", ldapsource);
-    dict_ldap->bind_dn = mystrdup((char *)
-                                 get_mail_conf_str(vstring_str
-                                                   (config_param), "", 0,
-                                                   0));
+    dict_ldap->bind_dn = parser.get_str(ldapsource, "bind_dn", "", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+       msg_info("%s: %s bind_dn is %s", myname, ldapsource,
                 dict_ldap->bind_dn);
 
     /*
-     * get configured value of "ldapsource_bind_pw"; default to ""
+     * get configured value of "bind_pw"; default to ""
      */
-    vstring_sprintf(config_param, "%s_bind_pw", ldapsource);
-    dict_ldap->bind_pw = mystrdup((char *)
-                                 get_mail_conf_str(vstring_str
-                                                   (config_param), "", 0,
-                                                   0));
+    dict_ldap->bind_pw = parser.get_str(ldapsource, "bind_pw", "", 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %s", myname, vstring_str(config_param),
+       msg_info("%s: %s bind_pw is %s", myname, ldapsource,
                 dict_ldap->bind_pw);
 
     /*
-     * get configured value of "ldapsource_cache"; default to false
+     * get configured value of "cache"; default to false
      */
-    vstring_sprintf(config_param, "%s_cache", ldapsource);
-    tmp = get_mail_conf_bool(vstring_str(config_param), 0);
+    tmp = parser.get_bool(ldapsource, "cache", 0);
     if (tmp)
-       msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+       msg_warn("%s: %s ignoring cache", myname, ldapsource);
 
     /*
-     * get configured value of "ldapsource_cache_expiry"; default to 30
-     * seconds
+     * get configured value of "cache_expiry"; default to 30 seconds
      */
-    vstring_sprintf(config_param, "%s_cache_expiry", ldapsource);
-    tmp = get_mail_conf_int(vstring_str(config_param), -1, 0, 0);
+    tmp = parser.get_int(ldapsource, "cache_expiry", -1, 0, 0);
     if (tmp >= 0)
-       msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+       msg_warn("%s: %s ignoring cache_expiry", myname, ldapsource);
 
     /*
-     * get configured value of "ldapsource_cache_size"; default to 32k
+     * get configured value of "cache_size"; default to 32k
      */
-    vstring_sprintf(config_param, "%s_cache_size", ldapsource);
-    tmp = get_mail_conf_int(vstring_str(config_param), -1, 0, 0);
+    tmp = parser.get_int(ldapsource, "cache_size", -1, 0, 0);
     if (tmp >= 0)
-       msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+       msg_warn("%s: %s ignoring cache_size", myname, ldapsource);
 
     /*
-     * get configured value of "ldapsource_recursion_limit"; default to 1000
+     * get configured value of "recursion_limit"; default to 1000
      */
-    vstring_sprintf(config_param, "%s_recursion_limit", ldapsource);
-    dict_ldap->recursion_limit = get_mail_conf_int(vstring_str(config_param),
-                                                  1000, 1, 0);
+    dict_ldap->recursion_limit = parser.get_int(ldapsource, "recursion_limit",
+                                               1000, 1, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+       msg_info("%s: %s recursion_limit is %ld", myname, ldapsource,
                 dict_ldap->recursion_limit);
 
     /*
-     * get configured value of "ldapsource_expansion_limit"; default to 1000
+     * get configured value of "expansion_limit"; default to 0
      */
-    vstring_sprintf(config_param, "%s_expansion_limit", ldapsource);
-    dict_ldap->expansion_limit = get_mail_conf_int(vstring_str(config_param),
-                                                  0, 0, 0);
+    dict_ldap->expansion_limit = parser.get_int(ldapsource, "expansion_limit",
+                                               0, 0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+       msg_info("%s: %s expansion_limit is %ld", myname, ldapsource,
                 dict_ldap->expansion_limit);
 
     /*
-     * get configured value of "ldapsource_size_limit"; default to
-     * expansion_limit
+     * get configured value of "size_limit"; default to expansion_limit
      */
-    vstring_sprintf(config_param, "%s_size_limit", ldapsource);
-    dict_ldap->size_limit = get_mail_conf_int(vstring_str(config_param),
-                                             dict_ldap->expansion_limit,
-                                             0, 0);
+    dict_ldap->size_limit = parser.get_int(ldapsource, "size_limit",
+                                          dict_ldap->expansion_limit,
+                                          0, 0);
     if (msg_verbose)
-       msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+       msg_info("%s: %s size_limit is %ld", myname, ldapsource,
                 dict_ldap->size_limit);
 
     /*
      * Alias dereferencing suggested by Mike Mattice.
      */
-    vstring_sprintf(config_param, "%s_dereference", ldapsource);
-    dict_ldap->dereference = get_mail_conf_int(vstring_str(config_param), 0, 0,
-                                              0);
-
-    /*
-     * Define LDAP Version.
-     */
-    vstring_sprintf(config_param, "%s_version", ldapsource);
-    dict_ldap->version = get_mail_conf_int(vstring_str(config_param), 2, 0,
-                                          0);
-    switch (dict_ldap->version) {
-    case 2:
-       dict_ldap->version = LDAP_VERSION2;
-       break;
-    case 3:
-       dict_ldap->version = LDAP_VERSION3;
-       break;
-    default:
-       msg_warn("%s: Unknown version %d.", myname, dict_ldap->version);
-       dict_ldap->version = LDAP_VERSION2;
-    }
-
-    /*
-     * Make sure only valid options for alias dereferencing are used.
-     */
+    dict_ldap->dereference = parser.get_int(ldapsource, "dereference", 0, 0,
+                                           0);
     if (dict_ldap->dereference < 0 || dict_ldap->dereference > 3) {
-       msg_warn("%s: Unrecognized value %d specified for %s; using 0",
-                myname, dict_ldap->dereference, vstring_str(config_param));
+       msg_warn("%s: %s Unrecognized value %d specified for dereference; using 0",
+                myname, ldapsource, dict_ldap->dereference);
        dict_ldap->dereference = 0;
     }
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s dereference is %d", myname, ldapsource,
                 dict_ldap->dereference);
 
     /* Referral chasing */
-    vstring_sprintf(config_param, "%s_chase_referrals", ldapsource);
-    dict_ldap->chase_referrals = get_mail_conf_bool(vstring_str(config_param), 0);
+    dict_ldap->chase_referrals = parser.get_bool(ldapsource, "chase_referrals",
+                                                0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
+       msg_info("%s: %s chase_referrals is %d", myname, ldapsource,
                 dict_ldap->chase_referrals);
 
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+
     /*
-     * Debug level.
+     * TLS options
      */
-#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
-    vstring_sprintf(config_param, "%s_debuglevel", ldapsource);
-    dict_ldap->debuglevel = get_mail_conf_int(vstring_str(config_param), 0, 0,
-                                             0);
+    /* get configured value of "start_tls"; default to no */
+    dict_ldap->start_tls = parser.get_bool(ldapsource, "start_tls", 0);
     if (msg_verbose)
-       msg_info("%s: %s is %d", myname, vstring_str(config_param),
-                dict_ldap->debuglevel);
+       msg_info("%s: %s start_tls is %d", myname, ldapsource,
+                dict_ldap->start_tls);
+    if (dict_ldap->start_tls && dict_ldap->version < LDAP_VERSION3) {
+       msg_warn("%s: %s start_tls requires protocol version 3", myname, ldapsource);
+       dict_ldap->version = LDAP_VERSION3;
+    }
+    /* get configured value of "tls_require_cert"; default to no */
+    dict_ldap->tls_require_cert = parser.get_bool(ldapsource, "tls_require_cert", 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_require_cert is %d", myname, ldapsource,
+                dict_ldap->tls_require_cert);
+    /* get configured value of "tls_ca_cert_file"; default "" */
+    dict_ldap->tls_ca_cert_file = parser.get_str(ldapsource, "tls_ca_cert_file",
+                                                "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_ca_cert_file is %s", myname, ldapsource,
+                dict_ldap->tls_ca_cert_file);
+    /* get configured value of "tls_ca_cert_dir"; default "" */
+    dict_ldap->tls_ca_cert_dir = parser.get_str(ldapsource, "tls_ca_cert_dir",
+                                               "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_ca_cert_dir is %s", myname, ldapsource,
+                dict_ldap->tls_ca_cert_dir);
+    /* get configured value of "tls_cert"; default "" */
+    dict_ldap->tls_cert = parser.get_str(ldapsource, "tls_cert",
+                                        "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_cert is %s", myname, ldapsource,
+                dict_ldap->tls_cert);
+    /* get configured value of "tls_key"; default "" */
+    dict_ldap->tls_key = parser.get_str(ldapsource, "tls_key",
+                                       "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_key is %s", myname, ldapsource,
+                dict_ldap->tls_key);
+    /* get configured value of "tls_random_file"; default "" */
+    dict_ldap->tls_random_file = parser.get_str(ldapsource,
+                                               "tls_random_file", "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_random_file is %s", myname, ldapsource,
+                dict_ldap->tls_random_file);
+    /* get configured value of "tls_cipher_suite"; default "" */
+    dict_ldap->tls_cipher_suite = parser.get_str(ldapsource,
+                                             "tls_cipher_suite", "", 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s tls_cipher_suite is %s", myname, ldapsource,
+                dict_ldap->tls_cipher_suite);
 #endif
 
-    dict_ldap_connect(dict_ldap);
-
     /*
-     * if dict_ldap_connect() set dict_errno, free dict_ldap and abort.
+     * Debug level.
      */
-    if (dict_errno) {
-       if (dict_ldap->ld)
-           ldap_unbind(dict_ldap->ld);
-
-       myfree((char *) dict_ldap);
-       return (0);
-    }
+#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
+    dict_ldap->debuglevel = parser.get_int(ldapsource, "debuglevel", 0, 0, 0);
+    if (msg_verbose)
+       msg_info("%s: %s debuglevel is %d", myname, ldapsource,
+                dict_ldap->debuglevel);
+#endif
 
     /*
-     * Otherwise, we're all set. Return the new dict_ldap structure.
+     * Return the new dict_ldap structure.
      */
     return (DICT_DEBUG (&dict_ldap->dict));
 }
index 91066dacdb101e2656f481b014d28b9a7e4e01f1..5cfae4e5055402c0eb0ef7bd766ea1914e022b99 100644 (file)
@@ -62,8 +62,8 @@ off_t   get_file_limit(void)
 #ifdef USE_ULIMIT
     if ((limit = ulimit(UL_GETFSIZE, 0)) < 0)
        msg_fatal("ulimit: %m");
-    if (limit > INT_MAX / ULIMIT_BLOCK_SIZE)
-       limit = INT_MAX / ULIMIT_BLOCK_SIZE;
+    if (limit > OFF_T_MAX / ULIMIT_BLOCK_SIZE)
+       limit = OFF_T_MAX / ULIMIT_BLOCK_SIZE;
     return (limit * ULIMIT_BLOCK_SIZE);
 #else
     struct rlimit rlim;
@@ -71,7 +71,7 @@ off_t   get_file_limit(void)
     if (getrlimit(RLIMIT_FSIZE, &rlim) < 0)
        msg_fatal("getrlimit: %m");
     limit = rlim.rlim_cur;
-    return (limit < 0 ? INT_MAX : rlim.rlim_cur);
+    return (limit < 0 ? OFF_T_MAX : rlim.rlim_cur);
 #endif                                         /* USE_ULIMIT */
 }
 
index 152e498461e117dba8d908e8e4c17763d4f7f53d..3c76734cdda4f9663c47f24ac0966725f11eaaf2 100644 (file)
@@ -63,6 +63,7 @@
 #include "find_inet.h"
 #include "inet_util.h"
 #include "iostuff.h"
+#include "sane_connect.h"
 #include "connect.h"
 #include "timed_connect.h"
 
@@ -114,7 +115,7 @@ int     inet_connect(const char *addr, int block_mode, int timeout)
      */
     else {
        non_blocking(sock, block_mode);
-       if (connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
+       if (sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
            && errno != EINPROGRESS) {
            close(sock);
            return (-1);
index 91347c95ab44bbf06a98a4401edbba48858cc711..2a846b39b8ddaad234038f6a8b9d596789dbd573 100644 (file)
@@ -116,5 +116,8 @@ int     inet_listen(const char *addr, int backlog, int block_mode)
 
 int     inet_accept(int fd)
 {
-    return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
+    struct sockaddr_in sin;
+    SOCKADDR_SIZE len = sizeof(sin);
+
+    return (sane_accept(fd, (struct sockaddr *) & sin, &len));
 }
index fb93014572ade21ed3c31050eda2748f33037b2e..5af7cb950da55b685274f01c930960e3d856945a 100644 (file)
@@ -49,6 +49,7 @@
 #include <errno.h>
 #include <syslog.h>
 #include <string.h>
+#include <time.h>
 
 /* Application-specific. */
 
@@ -57,6 +58,7 @@
 #include "msg.h"
 #include "msg_output.h"
 #include "msg_syslog.h"
+#include "safe.h"
 
  /*
   * Stay a little below the 2048-byte limit of older syslog()
@@ -167,6 +169,13 @@ void    msg_syslog_init(const char *name, int logopt, int facility)
 {
     static int first_call = 1;
 
+    /*
+     * XXX If this program is set-gid, then TZ must not be trusted.
+     * This scrubbing code is in the wrong place.
+     */
+    if (unsafe())
+       putenv("TZ=");
+    tzset();
     openlog(name, LOG_NDELAY | logopt, facility);
     if (first_call) {
        first_call = 0;
index a28e5bf93313950f51d80d18c284375928e71aad..30a3d8533e1413e68567cd523591305619446d53 100644 (file)
@@ -13,6 +13,9 @@
 /* DESCRIPTION
 /*     sane_accept() implements the accept(2) socket call, and maps
 /*     known harmless error results to EAGAIN.
+/*
+/*     If the buf and len arguments are not null, then additional
+/*     workarounds may be enabled that depend on the socket type.
 /* BUGS
 /*     Bizarre systems may have other harmless error results. Such
 /*     systems encourage programers to ignore error results, and
@@ -89,5 +92,21 @@ int     sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len)
            }
        }
     }
+
+    /*
+     * XXX Solaris select() produces false read events, so that read() blocks
+     * forever on a blocking socket, and fails with EAGAIN on a non-blocking
+     * socket. Turning on keepalives will fix a blocking socket provided that
+     * the kernel's keepalive timer expires before the Postfix watchdog
+     * timer.
+     */
+#if defined(BROKEN_READ_SELECT_ON_TCP_SOCKET) && defined(SO_KEEPALIVE)
+    else if (sa != 0 && sa->sa_family == AF_INET) {
+       int     on = 1;
+
+       (void) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
+                         (char *) &on, sizeof(on));
+    }
+#endif
     return (fd);
 }
diff --git a/postfix/src/util/sane_connect.c b/postfix/src/util/sane_connect.c
new file mode 100644 (file)
index 0000000..cdb2874
--- /dev/null
@@ -0,0 +1,63 @@
+/*++
+/* NAME
+/*     sane_connect 3
+/* SUMMARY
+/*     sanitize connect() results
+/* SYNOPSIS
+/*     #include <sane_connect.h>
+/*
+/*     int     sane_connect(sock, buf, len)
+/*     int     sock;
+/*     struct sockaddr *buf;
+/*     SOCKADDR_SIZE *len;
+/* DESCRIPTION
+/*     sane_connect() implements the accept(2) socket call, and maps
+/*     known harmless error results to EAGAIN.
+/* BUGS
+/*     Bizarre systems may have other harmless error results. Such
+/*     systems encourage programers to ignore error results, and
+/*     penalizes programmers who code defensively.
+/* 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 <sys/socket.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include "msg.h"
+#include "sane_connect.h"
+
+/* sane_connect - sanitize connect() results */
+
+int     sane_connect(int sock, struct sockaddr * sa, SOCKADDR_SIZE len)
+{
+
+    /*
+     * XXX Solaris select() produces false read events, so that read() blocks
+     * forever on a blocking socket, and fails with EAGAIN on a non-blocking
+     * socket. Turning on keepalives will fix a blocking socket provided that
+     * the kernel's keepalive timer expires before the Postfix watchdog
+     * timer.
+     */
+#if defined(BROKEN_READ_SELECT_ON_TCP_SOCKET) && defined(SO_KEEPALIVE)
+    if (sa->sa_family == AF_INET) {
+       int     on = 1;
+
+       (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+                         (char *) &on, sizeof(on));
+    }
+#endif
+    return (connect(sock, sa, len));
+}
diff --git a/postfix/src/util/sane_connect.h b/postfix/src/util/sane_connect.h
new file mode 100644 (file)
index 0000000..1f023b0
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _SANE_CONNECT_H_
+#define _SANE_CONNECT_H_
+
+/*++
+/* NAME
+/*     sane_connect 3h
+/* SUMMARY
+/*     sanitize connect() results
+/* SYNOPSIS
+/*     #include <sane_connect.h>
+/* DESCRIPTION
+/* .nf
+
+ /* External interface. */
+
+extern int sane_connect(int, struct sockaddr *, SOCKADDR_SIZE);
+
+/* 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
+/*--*/
+
+#endif
index 9223422e1c6e3213faa5d640b8c5e06db1ab3d8b..db080b1eb3f6a7c8b393c41e629ca7459fc0208e 100644 (file)
@@ -261,7 +261,7 @@ extern int opterr;
 #define LOCAL_CONNECT  stream_connect
 #define LOCAL_TRIGGER  stream_trigger
 #define HAS_VOLATILE_LOCKS
-#define BROKEN_READ_SELECT_ON_BLOCKING_SOCKET
+#define BROKEN_READ_SELECT_ON_TCP_SOCKET
 
 /*
  * Allow build environment to override paths.
@@ -1087,6 +1087,17 @@ typedef int pid_t;
 #else
 #define SCANFLIKE(x,y)
 #endif
+#endif
+
+ /*
+  * Bit banging!! There is no official constant that defines the INT_MAX
+  * equivalent of the off_t type. Wietse came up with the following macro
+  * that works as long as off_t is some two's complement number.
+  */
+#include <limits.h>
+#define __MAXINT__(T) ((T) (((T)1 << ((sizeof(T) * CHAR_BIT) - 1) ^ ((T) -1))))
+#ifndef OFF_T_MAX
+#define OFF_T_MAX __MAXINT__(off_t)
 #endif
 
  /*
index c40fe3e6311c00f9717988c6e4162a0520485af1..ee4e150b1269720e01d498608ea7ecf089fe35fd 100644 (file)
@@ -59,6 +59,7 @@
 
 #include "msg.h"
 #include "iostuff.h"
+#include "sane_connect.h"
 #include "timed_connect.h"
 
 /* timed_connect - connect with deadline */
@@ -78,7 +79,7 @@ int     timed_connect(int sock, struct sockaddr * sa, int len, int timeout)
     /*
      * Start the connection, and handle all possible results.
      */
-    if (connect(sock, sa, len) == 0)
+    if (sane_connect(sock, sa, len) == 0)
        return (0);
     if (errno != EINPROGRESS)
        return (-1);
index 1a29a69f9f52dbe4491c7a0d752a9c8226174ab6..509004ba3a561ad56ce61c66bfb447be6d0ab565 100644 (file)
 
 #include <sys_defs.h>
 #include <unistd.h>
+#include <errno.h>
 
 /* Utility library. */
 
-#include "iostuff.h"
+#include <msg.h>
+#include <iostuff.h>
 
 /* timed_read - read with deadline */
 
 int     timed_read(int fd, void *buf, unsigned len,
                           int timeout, void *unused_context)
 {
+    int     ret;
 
     /*
      * Wait for a limited amount of time for something to happen. If nothing
      * happens, report an ETIMEDOUT error.
+     * 
+     * XXX Solaris 8 read() fails with EAGAIN after read-select() returns
+     * success.
      */
-    if (timeout > 0 && read_wait(fd, timeout) < 0)
-       return (-1);
-    else
-       return (read(fd, buf, len));
+    for (;;) {
+       if (timeout > 0 && read_wait(fd, timeout) < 0)
+           return (-1);
+       if ((ret = read(fd, buf, len)) < 0 && timeout > 0 && errno == EAGAIN) {
+           msg_warn("read() returns EAGAIN on a readable file descriptor!");
+           msg_warn("pausing to avoid going into a tight select/read loop!");
+           sleep(1);
+       } else {
+           return (ret);
+       }
+    }
 }
index 723bf036d35b9d79d996b862638187dd25a09b44..3089a83903205b8aa828e6a69775fb10b3045951 100644 (file)
 
 #include <sys_defs.h>
 #include <unistd.h>
+#include <errno.h>
 
 /* Utility library. */
 
-#include "iostuff.h"
+#include <msg.h>
+#include <iostuff.h>
 
 /* timed_write - write with deadline */
 
 int     timed_write(int fd, void *buf, unsigned len,
                            int timeout, void *unused_context)
 {
+    int     ret;
 
     /*
      * Wait for a limited amount of time for something to happen. If nothing
      * happens, report an ETIMEDOUT error.
+     * 
+     * XXX Solaris 8 read() fails with EAGAIN after read-select() returns
+     * success. The code below exists just in case their write implementation
+     * is equally broken.
+     * 
+     * This condition may also be found on systems where select() returns
+     * success on pipes with less than PIPE_BUF bytes of space, and with
+     * badly designed software where multiple writers are fighting for access
+     * to the same resource.
      */
-    if (timeout > 0 && write_wait(fd, timeout) < 0)
-       return (-1);
-    else
-       return (write(fd, buf, len));
+    for (;;) {
+       if (timeout > 0 && write_wait(fd, timeout) < 0)
+           return (-1);
+       if ((ret = write(fd, buf, len)) < 0 && timeout > 0 && errno == EAGAIN) {
+           msg_warn("write() returns EAGAIN on a writable file descriptor!");
+           msg_warn("pausing to avoid going into a tight select/write loop!");
+           sleep(1);
+       } else {
+           return (ret);
+       }
+    }
 }
index 0890f7e1cb0eff25def975c9ded993f3b7b70513..5ae4525431d76354ae2bfad8ad362e17f469ed00 100644 (file)
@@ -50,6 +50,7 @@
 
 #include "msg.h"
 #include "iostuff.h"
+#include "sane_connect.h"
 #include "connect.h"
 #include "timed_connect.h"
 
@@ -99,7 +100,7 @@ int     unix_connect(const char *addr, int block_mode, int timeout)
      */
     else {
        non_blocking(sock, block_mode);
-       if (connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
+       if (sane_connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
            && errno != EINPROGRESS) {
            close(sock);
            return (-1);