]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.9-20111209
authorWietse Venema <wietse@porcupine.org>
Fri, 9 Dec 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:37:45 +0000 (06:37 +0000)
72 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/AAAREADME
postfix/README_FILES/DATABASE_README
postfix/README_FILES/MEMCACHE_README [new file with mode: 0644]
postfix/README_FILES/MULTI_INSTANCE_README
postfix/README_FILES/TLS_README
postfix/README_FILES/TUNING_README
postfix/WISHLIST
postfix/conf/postfix-files
postfix/html/DATABASE_README.html
postfix/html/MEMCACHE_README.html [new file with mode: 0644]
postfix/html/MULTI_INSTANCE_README.html
postfix/html/Makefile.in
postfix/html/TLS_README.html
postfix/html/TUNING_README.html
postfix/html/index.html
postfix/html/memcache_table.5.html [new file with mode: 0644]
postfix/html/postconf.1.html
postfix/html/postfix-manuals.html
postfix/html/postfix.1.html
postfix/html/postqueue.1.html
postfix/man/Makefile.in
postfix/man/man1/postconf.1
postfix/man/man1/postfix.1
postfix/man/man5/memcache_table.5 [new file with mode: 0644]
postfix/mantools/double
postfix/mantools/postlink
postfix/proto/DATABASE_README.html
postfix/proto/MEMCACHE_README.html [new file with mode: 0644]
postfix/proto/MULTI_INSTANCE_README.html
postfix/proto/Makefile.in
postfix/proto/TLS_README.html
postfix/proto/TUNING_README.html
postfix/proto/memcache_table [new file with mode: 0644]
postfix/src/global/Makefile.in
postfix/src/global/db_common.c
postfix/src/global/db_common.h
postfix/src/global/dict_memcache.c [new file with mode: 0644]
postfix/src/global/dict_memcache.h [new file with mode: 0644]
postfix/src/global/mail_dict.c
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.c
postfix/src/global/mail_version.h
postfix/src/global/mail_version.in [new file with mode: 0644]
postfix/src/global/mail_version.ref [new file with mode: 0644]
postfix/src/master/Makefile.in
postfix/src/master/event_server.c
postfix/src/master/master.c
postfix/src/master/multi_server.c
postfix/src/master/single_server.c
postfix/src/master/trigger_server.c
postfix/src/postalias/postalias.c
postfix/src/postconf/postconf.c
postfix/src/postdrop/postdrop.c
postfix/src/postfix/postfix.c
postfix/src/postlog/postlog.c
postfix/src/postmap/postmap.c
postfix/src/postmulti/postmulti.c
postfix/src/postqueue/postqueue.c
postfix/src/postscreen/postscreen.c
postfix/src/postscreen/postscreen_starttls.c
postfix/src/postsuper/postsuper.c
postfix/src/sendmail/sendmail.c
postfix/src/tlsproxy/tlsproxy.c
postfix/src/tlsproxy/tlsproxy.h
postfix/src/tlsproxy/tlsproxy_state.c
postfix/src/util/Makefile.in
postfix/src/util/dict.c
postfix/src/util/dict.h
postfix/src/util/dict_open.c
postfix/src/util/dict_test.c [new file with mode: 0644]

index 4756b026693759ddac974ef1ae37dd99670f7cce..d2e1c26f5ef75f30009a54cc232aa5c6d0895d82 100644 (file)
@@ -71,6 +71,7 @@
 -TDICT_ENV
 -TDICT_HT
 -TDICT_LDAP
+-TDICT_MC
 -TDICT_MYSQL
 -TDICT_NI
 -TDICT_NIS
 -TMAIL_PRINT
 -TMAIL_SCAN
 -TMAIL_STREAM
+-TMAIL_VERSION
 -TMAI_HOSTADDR_STR
 -TMAI_HOSTNAME_STR
 -TMAI_SERVNAME_STR
index 969e18671b64019adbb8e590084f0cae488af871..c8473aa89607cebfb2ee77660baab77392d9884c 100644 (file)
@@ -17231,3 +17231,55 @@ Apologies for any names omitted.
        Bugfix: tlsproxy(8) stored TLS sessions with a serverID of
        "tlsproxy" instead of "smtpd", wasting an opportunity for
        session reuse.  File: tlsproxy/tlsproxy.c.
+
+20111206
+
+       Documentation: removed descriptions of Postfix < 2.3 user
+       interface from TLS_README. Users of earlier releases are
+       referred to TLS_LEGACY_README. File: proto/TLS_README.html.
+
+20111207
+
+       Cleanup: tlsproxy(8) now receives the session cache serverID
+       from its client (postscreen(8)). Files: global/mail_proto.h,
+       postscreen/postscreen_starttls.c, tlsproxy/tlsproxy.[hc],
+       tlsproxy_state.c.
+
+       Cleanup: the postscreen(8) daemon did not support a zero
+       cache cleanup interval. This is needed for memcache support.
+       File: postscreen/postscreen.c.
+
+       Bugfix (introduced: 20110227): null pointer bug while
+       updating dictionary owner attributes, after reading an empty
+       (database) configuration file. File: util/dict.c.
+
+20111208
+
+       Cleanup: db_common_parse_domain() could not be called without
+       preceding db_common_parse() call. Files: global/db_common.[hc].
+
+20111209
+
+       Feature: memcache client support. This implementation is
+       based on the under-documented libmemcache library, and
+       therefore supports only libmemcache version 1.4.0.  Files:
+       conf/postfix-files, global/dict_memcache.[hc], global/mail_dict.c,
+       html/index.html, mantools/postlink, postconf/postconf.c,
+       postfix/postfix.c, proto/DATABASE_README.html,
+       proto/MEMCACHE_README.html, proto/memcache_table.
+
+20111209
+
+       Cleanup: support for scripted and manual database tests with
+       LDAP, *SQL, and memcache. Files: util/dict_test.c, util/dict.c,
+       global/mail_dict.c.
+
+       Workaround: apparently, some distributions don't use proper
+       so-number versioning, causing programs to fail erratically
+       after an update replaces the Postfix library but not the
+       program.  Files: global/mail_version.[hc], master/*server.c,
+       master/master.c, src/postalias/postalias.c,
+       src/postdrop/postdrop.c, src/postfix/postfix.c,
+       src/postlog/postlog.c, src/postmap/postmap.c,
+       src/postmulti/postmulti.c, src/postqueue/postqueue.c,
+       src/postsuper/postsuper.c, src/sendmail/sendmail.c.
index 605390d513f97d63e046250f0ffc4cf1a22479c8..7a93a6ba4ea232462ea3381a9a9a1d9a1b185105 100644 (file)
@@ -48,6 +48,7 @@ L\bLo\boo\bok\bku\bup\bp t\bta\bab\bbl\ble\bes\bs (\b(d\bda\bat\bta\bab\bba\bas\bse\bes\bs)\b)
   * DB_README: Berkeley DB Howto
   * CDB_README: CDB Howto
   * LDAP_README: LDAP Howto
+  * MEMCACHE_README: Memcache Howto
   * MYSQL_README: MySQL Howto
   * PCRE_README: PCRE Howto
   * PGSQL_README: PostgreSQL Howto
index 22d5801e6c7c0ea30c16ae507bbc96d8c3b7408f..dcd3952944603a5b6897714aea913bf2d773e987 100644 (file)
@@ -210,6 +210,9 @@ To find out what database types your Postfix system supports, use the "p\bpo\bos\bs
     l\bld\bda\bap\bp (read-only)
         Perform lookups using the LDAP protocol. Configuration details are
         given in the ldap_table(5).
+    m\bme\bem\bmc\bca\bac\bch\bhe\be (read-write)
+        Perform memcache database lookups or updates. Configuration details are
+        given in memcache_table(5).
     m\bmy\bys\bsq\bql\bl (read-only)
         Perform MySQL database lookups. Configuration details are given in
         mysql_table(5).
diff --git a/postfix/README_FILES/MEMCACHE_README b/postfix/README_FILES/MEMCACHE_README
new file mode 100644 (file)
index 0000000..9c17f55
--- /dev/null
@@ -0,0 +1,75 @@
+P\bPo\bos\bst\btf\bfi\bix\bx m\bme\bem\bmc\bca\bac\bch\bhe\be c\bcl\bli\bie\ben\bnt\bt H\bHo\bow\bwt\bto\bo
+
+-------------------------------------------------------------------------------
+
+I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
+
+The Postfix memcache client type allows you to hook up Postfix to a memcache
+server. This implementation supports multiple memcache servers for redundancy,
+and multiple memcache clients that you can use for different table lookups. The
+Postfix memcache client supports both lookup and update operations.
+
+Typically, a memcache map is used to reduce query load on a database server, or
+to share a low-latency database among different Postfix instances.
+
+L\bLi\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs
+
+  * The Postfix memcache client is based on libmemcache, which will terminate
+    its process after a memcache server goes down. To avoid this, set up
+    redundant memcache servers that have no common source of failure.
+
+  * The Postfix memcache client cannot be used for security-sensitive tables
+    such as alias_maps (these may contain "|command" and "/file/name"
+    destinations), or virtual_uid_maps and virtual_gid_maps (these specify UNIX
+    process privileges). Typically, a memcache database is shared via a TCP
+    socket, and is writable not only by Postfix, but by any process that can
+    talk to the memcache server.
+
+  * The Postfix memcache client requires additional configuration when used
+    with the postscreen(8) and verify(8) daemons. For details see the ttl
+    parameter discussion in the memcache_table(5) manual page.
+
+  * The Postfix memcache client is supported only with libmemcache version
+    1.4.0. Some libmemcache features are documented by reading libmemcache
+    source code, instead of a proper API.
+
+B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh m\bme\bem\bmc\bca\bac\bch\bhe\be s\bsu\bup\bpp\bpo\bor\brt\bt
+
+To build Postfix with memcache client support, specify -DHAS_MEMCACHE, the
+location of the libmemcache include files, and the location of the libmemcache
+object library.
+
+For example:
+
+    % make -f Makefile.init makefiles \
+            'CCARGS=-DHAS_MEMCACHE -I/usr/local/include' \
+       'AUXLIBS=-L/usr/local/lib -lmemcache'
+
+Then run 'make'.
+
+If the build fails with "undefined reference to `mcm_buf_len'" (and with a
+similar error message for mcm_buf_remain_off), then you need to edit
+libmemcache source code.
+
+The following instructions apply to libmemcache 1.4.0.rc2.
+
+  * Open the libmemcache source file include/memcache/buffer.h.
+
+  * Delete the "inline" words before the functions that were reported in the
+    "undefined reference" error messages.
+
+  * Recompile and reinstall libmemcache.
+
+Then, continue building Postfix by running 'make'.
+
+C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg m\bme\bem\bmc\bca\bac\bch\bhe\be l\blo\boo\bok\bku\bup\bp t\bta\bab\bbl\ble\bes\bs
+
+Configuration is described in the memcache_table(5) manpage.
+
+C\bCr\bre\bed\bdi\bit\bts\bs
+
+The first memcache client for Postfix was written by Omar Kilani.
+
+Wietse wrote a new memcache client from the ground up. Besides also using
+libmemcache, the current implementation bears no resemblance to Omar's work.
+
index 3ac94733f8fc5edfdeb32ecf288a681b308be8b4..b6e15d2e33a9fbe9df812eb24180cc8b4b0a9c4c 100644 (file)
@@ -492,8 +492,8 @@ Shared among all instances:
     $readme_directory.
 
   * Entries in /etc/passwd and /etc/group for the $mail_owner user and
-    $setgid_group group. The the $mail_owner user provides the mail system with
-    protected (non-root) execution context. The $setgid_group group is used
+    $setgid_group group. The $mail_owner user provides the mail system with a
+    protected (non-root) execution context. The $setgid_group group is used
     exclusively to support the setgid postdrop(1) and postqueue(1) utilities
     (it m\bmu\bus\bst\bt n\bno\bot\bt be the primary group or secondary group of any users,
     including the $mail_owner user).
index f37d187c7d85340447d6f8d6c87cfa61b8f077ef..2ac714f1f7501c0386c0542d5e7c9144c1a7d7ed 100644 (file)
@@ -10,21 +10,17 @@ thousands and thousands of lines of OpenSSL library code. Assuming that OpenSSL
 is written as carefully as Wietse's own code, every 1000 lines introduce one
 additional bug into Postfix.
 
-At this time, you should no longer be using OpenSSL releases prior to the most
-recent 0.9.8 release unless all relevant security fixes have been backported to
-the earlier release by you or your O/S vendor. OpenSSL 0.9.7 and earlier are no
-longer maintained by the OpenSSL team.
-
 W\bWh\bha\bat\bt P\bPo\bos\bst\btf\bfi\bix\bx T\bTL\bLS\bS s\bsu\bup\bpp\bpo\bor\brt\bt d\bdo\boe\bes\bs f\bfo\bor\br y\byo\bou\bu
 
 Transport Layer Security (TLS, formerly called SSL) provides certificate-based
 authentication and encrypted sessions. An encrypted session protects the
 information that is transmitted with SMTP mail or with SASL authentication.
 
-This document describes a TLS user interface that was introduced with Postfix
-version 2.3. Support for an older user interface is documented in
-TLS_LEGACY_README, which also describes the differences between Postfix and the
-third-party patch on which Postfix version 2.2 TLS support was based.
+      NOTE: This document describes a TLS user interface that was introduced
+    with Postfix version 2.3. Support for an older user interface is documented
+    in TLS_LEGACY_README, which also describes the differences between Postfix
+    and the third-party patch on which Postfix version 2.2 TLS support was
+    based.
 
 Topics covered in this document:
 
@@ -48,12 +44,15 @@ programs. Other colored boxes represent storage elements.
 
   * The smtpd(8) server implements the SMTP over TLS server side.
 
-  * The smtp(8) client implements the SMTP over TLS client side.
+  * The smtp(8) client implements the SMTP (and LMTP) over TLS client side.
 
   * The tlsmgr(8) server maintains the pseudo-random number generator (PRNG)
     that seeds the TLS engines in the smtpd(8) server and smtp(8) client
     processes, and maintains the TLS session key cache files.
 
+Not shown in the figure are the tlsproxy(8) server and the postscreen(8)
+server. These use TLS in the same manner as smtpd(8).
+
                     <---seed----             ----seed--->
 Network-> smtpd(8)                tlsmgr(8)                 smtp(8)  ->Network
                     <-key/cert->             <-key/cert->       
@@ -94,7 +93,7 @@ Public Internet MX hosts without certificates signed by a "reputable" CA must
 generate, and be prepared to present to most clients, a self-signed or private-
 CA signed certificate. The remote SMTP client will generally not be able to
 authenticate the self-signed certificate, but unless the client is running
-Postfix 2.3 or similar software, it will still insist on a server certificate.
+Postfix or similar software, it will still insist on a server certificate.
 
 For servers that are n\bno\bot\bt public Internet MX hosts, Postfix supports
 configurations with no certificates. This entails the use of just the anonymous
@@ -254,16 +253,12 @@ E\bEn\bna\bab\bbl\bli\bin\bng\bg T\bTL\bLS\bS i\bin\bn t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bM
 
 By default, TLS is disabled in the Postfix SMTP server, so no difference to
 plain Postfix is visible. Explicitly switch it on with
-"smtpd_tls_security_level = may" (Postfix 2.3 and later) or "smtpd_use_tls =
-yes" (obsolete but still supported).
+"smtpd_tls_security_level = may".
 
 Example:
 
     /etc/postfix/main.cf:
-        # Postfix 2.3 and later
         smtpd_tls_security_level = may
-        # Obsolete, but still supported
-        smtpd_use_tls = yes
 
 With this, the Postfix SMTP server announces STARTTLS support to remote SMTP
 clients, but does not require that clients use TLS encryption.
@@ -274,18 +269,14 @@ private key. This is intended behavior.
 
 You can ENFORCE the use of TLS, so that the Postfix SMTP server announces
 STARTTLS and accepts no mail without TLS encryption, by setting
-"smtpd_tls_security_level = encrypt" (Postfix 2.3 and later) or
-"smtpd_enforce_tls = yes" (obsolete but still supported). According to RFC 2487
-this MUST NOT be applied in case of a publicly-referenced Postfix SMTP server.
-This option is off by default and should only seldom be used.
+"smtpd_tls_security_level = encrypt". According to RFC 2487 this MUST NOT be
+applied in case of a publicly-referenced Postfix SMTP server. This option is
+off by default and should only seldom be used.
 
 Example:
 
     /etc/postfix/main.cf:
-        # Postfix 2.3 and later
         smtpd_tls_security_level = encrypt
-        # Obsolete, but still supported
-        smtpd_enforce_tls = yes
 
 TLS is sometimes used in the non-standard "wrapper" mode where a server always
 uses TLS, instead of announcing STARTTLS support and waiting for remote SMTP
@@ -316,7 +307,7 @@ TLS negotiation when client certificates are requested, and abort the SMTP
 session. So this option is "off" by default. You will however need the
 certificate if you want to use certificate based relaying with, for example,
 the permit_tls_clientcerts feature. A server that wants client certificates
-must first present its own certificate. While Postfix 2.3 by default offers
+must first present its own certificate. While Postfix by default offers
 anonymous ciphers to remote SMTP clients, these are automatically suppressed
 when the Postfix SMTP server is configured to ask for client certificates.
 
@@ -324,10 +315,7 @@ Example:
 
     /etc/postfix/main.cf:
         smtpd_tls_ask_ccert = yes
-        # Postfix 2.3 and later
         smtpd_tls_security_level = may
-        # Obsolete, but still supported
-        smtpd_use_tls = yes
 
 When TLS is enforced you may also decide to REQUIRE a remote SMTP client
 certificate for all TLS connections, by setting "smtpd_tls_req_ccert = yes".
@@ -338,10 +326,7 @@ Example:
 
     /etc/postfix/main.cf:
         smtpd_tls_req_ccert = yes
-        # Postfix 2.3 and later
         smtpd_tls_security_level = encrypt
-        # Obsolete, but still supported
-        smtpd_enforce_tls = yes
 
 The client certificate verification depth is specified with the main.cf
 smtpd_tls_ccert_verifydepth parameter. The default verification depth is 9 (the
@@ -363,14 +348,13 @@ Example:
 S\bSu\bup\bpp\bpo\bor\brt\bti\bin\bng\bg A\bAU\bUT\bTH\bH o\bov\bve\ber\br T\bTL\bLS\bS o\bon\bnl\bly\by
 
 Sending AUTH data over an unencrypted channel poses a security risk. When TLS
-layer encryption is required ("smtpd_tls_security_level = encrypt" or the
-obsolete "smtpd_enforce_tls = yes"), the Postfix SMTP server will announce and
-accept AUTH only after the TLS layer has been activated with STARTTLS. When TLS
-layer encryption is optional ("smtpd_tls_security_level = may" or the obsolete
-"smtpd_enforce_tls = no"), it may however still be useful to only offer AUTH
-when TLS is active. To maintain compatibility with non-TLS clients, the default
-is to accept AUTH without encryption. In order to change this behavior, set
-"smtpd_tls_auth_only = yes".
+layer encryption is required ("smtpd_tls_security_level = encrypt"), the
+Postfix SMTP server will announce and accept AUTH only after the TLS layer has
+been activated with STARTTLS. When TLS layer encryption is optional
+("smtpd_tls_security_level = may"), it may however still be useful to only
+offer AUTH when TLS is active. To maintain compatibility with non-TLS clients,
+the default is to accept AUTH without encryption. In order to change this
+behavior, set "smtpd_tls_auth_only = yes".
 
 Example:
 
@@ -480,11 +464,6 @@ host:
 
 S\bSe\ber\brv\bve\ber\br-\b-s\bsi\bid\bde\be c\bci\bip\bph\bhe\ber\br c\bco\bon\bnt\btr\bro\bol\bls\bs
 
-The description below is for Postfix 2.3; for Postfix < 2.3 the
-smtpd_tls_cipherlist parameter specifies the acceptable ciphers as an explicit
-OpenSSL cipherlist. The obsolete setting applies even when TLS encryption is
-not enforced. Use of this control on public MX hosts is strongly discouraged.
-
 The Postfix SMTP server supports 5 distinct cipher security levels as specified
 by the smtpd_tls_mandatory_ciphers configuration parameter, which determines
 the cipher grade with mandatory TLS encryption. The default value is "medium"
@@ -511,7 +490,7 @@ mandatory TLS protocol list is specified via the smtpd_tls_mandatory_protocols
 configuration parameter. The corresponding smtpd_tls_protocols parameter
 (Postfix >= 2.6) controls the SSL/TLS protocols used with opportunistic TLS.
 
-For a server that is not a public Internet MX host, Postfix (>= 2.3) supports
+For a server that is not a public Internet MX host, Postfix supports
 configurations with no server certificates that use o\bon\bnl\bly\by the anonymous ciphers.
 This is enabled by explicitly setting "smtpd_tls_cert_file = none" and not
 specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file.
@@ -610,8 +589,6 @@ Topics covered in this section:
   * Client-side TLS session cache
   * Client TLS limitations
   * Per-destination TLS policy
-  * Obsolete per-site TLS policy support
-  * Closing a DNS loophole with obsolete per-site TLS policies
   * Discovering servers that support TLS
   * Server certificate verification depth
   * Client-side cipher controls
@@ -659,28 +636,23 @@ authentication without encryption.
 N\bNo\bo T\bTL\bLS\bS e\ben\bnc\bcr\bry\byp\bpt\bti\bio\bon\bn
 
 At the "none" TLS security level, TLS encryption is disabled. This is the
-default security level. With Postfix 2.3 and later, it can be configured
-explicitly by setting "smtp_tls_security_level = none".
-
-With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to its
-default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_use_tls = no" and "smtp_enforce_tls = no". With either
-approach, TLS is not used even if supported by the server. For LMTP, use the
-corresponding "lmtp_" parameters.
+default security level, and can be configured explicitly by setting
+"smtp_tls_security_level = none". For LMTP, use the corresponding "lmtp_"
+parameter.
 
-Per destination settings may override this default setting, in which case TLS
+Per-destination settings may override this default setting, in which case TLS
 is used selectively, only with destinations explicitly configured for TLS.
 
 You can disable TLS for a subset of destinations, while leaving it enabled for
-the rest. With the Postfix 2.3 and later TLS policy table, specify the "none"
-security level. With the obsolete per-site table, specify the "NONE" keyword.
+the rest. With the Postfix TLS policy table, specify the "none" security level.
 
 O\bOp\bpp\bpo\bor\brt\btu\bun\bni\bis\bst\bti\bic\bc T\bTL\bLS\bS
 
 At the "may" TLS security level, TLS encryption is opportunistic. The SMTP
 transaction is encrypted if the STARTTLS ESMTP feature is supported by the
-server. Otherwise, messages are sent in the clear. With Postfix 2.3 and later,
-opportunistic TLS can be configured by setting "smtp_tls_security_level = may".
+server. Otherwise, messages are sent in the clear. Opportunistic TLS can be
+configured by setting "smtp_tls_security_level = may". For LMTP, use the
+corresponding "lmtp_" parameter.
 
 Since sending in the clear is acceptable, demanding stronger than default TLS
 security mostly reduces inter-operability. If you must restrict TLS protocol or
@@ -690,15 +662,10 @@ over the protocols and cipher grade used with opportunistic TLS. With earlier
 releases the opportunistic TLS cipher grade is always "export" and no protocols
 are disabled.
 
-With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to its
-default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_use_tls = yes" and "smtp_enforce_tls = no". For LMTP use the
-corresponding "lmtp_" parameters.
-
 With opportunistic TLS, mail delivery continues even if the server certificate
-is untrusted or bears the wrong name. Starting with Postfix 2.3, when the TLS
-handshake fails for an opportunistic TLS session, rather than give up on mail
-delivery, the transaction is retried with TLS disabled. Trying an unencrypted
+is untrusted or bears the wrong name. When the TLS handshake fails for an
+opportunistic TLS session, rather than give up on mail delivery, the Postfix
+SMTP client retries the transaction with TLS disabled. Trying an unencrypted
 connection makes it possible to deliver mail to sites with non-interoperable
 server TLS implementations.
 
@@ -711,8 +678,7 @@ configure opportunistic encryption of LMTP sessions will be ignored with a
 warning written to the mail logs.
 
 You can enable opportunistic TLS just for selected destinations. With the
-Postfix 2.3 and later TLS policy table, specify the "may" security level. With
-the obsolete per-site table, specify the "MAY" keyword.
+Postfix TLS policy table, specify the "may" security level.
 
 This is the most common security level for TLS protected SMTP sessions,
 stronger security is not generally available and, if needed, is typically only
@@ -724,21 +690,15 @@ Example:
     /etc/postfix/main.cf:
         smtp_tls_security_level = may
 
-Postfix 2.2 syntax:
-
-    /etc/postfix/main.cf:
-        smtp_use_tls = yes
-        smtp_enforce_tls = no
-
 M\bMa\ban\bnd\bda\bat\bto\bor\bry\by T\bTL\bLS\bS e\ben\bnc\bcr\bry\byp\bpt\bti\bio\bon\bn
 
 At the "encrypt" TLS security level, messages are sent only over TLS encrypted
 sessions. The SMTP transaction is aborted unless the STARTTLS ESMTP feature is
 supported by the remote SMTP server. If no suitable servers are found, the
-message will be deferred. With Postfix 2.3 and later, mandatory TLS encryption
-can be configured by setting "smtp_tls_security_level = encrypt". Even though
-TLS encryption is always used, mail delivery continues even if the server
-certificate is untrusted or bears the wrong name.
+message will be deferred. Mandatory TLS encryption can be configured by setting
+"smtp_tls_security_level = encrypt". Even though TLS encryption is always used,
+mail delivery continues even if the server certificate is untrusted or bears
+the wrong name. For LMTP, use the corresponding "lmtp_" parameter.
 
 At this security level and higher, the smtp_tls_mandatory_protocols and
 smtp_tls_mandatory_ciphers configuration parameters determine the list of
@@ -747,11 +707,6 @@ the protocol or cipher requirements are not met, the mail transaction is
 aborted. The documentation for these parameters includes useful
 interoperability and security guidelines.
 
-With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to its
-default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = no". For
-LMTP use the corresponding "lmtp_" parameters.
-
 Despite the potential for eliminating passive eavesdropping attacks, mandatory
 TLS encryption is not viable as a default security level for mail delivery to
 the public Internet. Most MX hosts do not support TLS at all, and some of those
@@ -760,11 +715,7 @@ Internet, you should not configure mandatory TLS encryption as the default
 security level.
 
 You can enable mandatory TLS encryption just for specific destinations. With
-the Postfix 2.3 and later TLS policy table, specify the "encrypt" security
-level. With the obsolete per-site table, specify the "MUST_NOPEERMATCH"
-keyword. While the obsolete approach still works with Postfix 2.3, it is
-strongly discouraged: users of Postfix 2.3 and later should use the new TLS
-policy settings.
+the Postfix TLS policy table, specify the "encrypt" security level.
 
 Examples:
 
@@ -781,15 +732,6 @@ default for all "encrypt" security level sessions.
         example.com       encrypt
         .example.com      encrypt
 
-Postfix 2.2 syntax (no support for sub-domains without resorting to regexp
-tables). With Postfix 2.3 and later, do not use the obsolete per-site table.
-
-    /etc/postfix/main.cf:
-        smtp_tls_per_site = hash:/etc/postfix/tls_per_site
-
-    /etc/postfix/tls_per_site:
-        example.com       MUST_NOPEERMATCH
-
 In the next example, secure message submission is configured via the MSA "
 [example.net]:587". TLS sessions are encrypted without authentication, because
 this MSA does not possess an acceptable certificate. This MSA is known to be
@@ -817,21 +759,6 @@ not specified consistently.
         [example.net]:msa encrypt protocols=TLSv1 ciphers=high
         [example.net]:submission encrypt protocols=TLSv1 ciphers=high
 
-Postfix 2.2 syntax:
-
-N\bNo\bot\bte\be:\b: Avoid policy lookups with the bare hostname (for example, "example.net").
-Instead, use the destination (for example, "[example.net]:587"), as the per-
-site table lookup key (a recipient domain or MX-enabled transport nexthop with
-no port suffix may look like a bare hostname, but is still a suitable
-destination). With Postfix 2.3 and later, do not use the obsolete per-site
-table; use the new policy table instead.
-
-    /etc/postfix/main.cf:
-        smtp_tls_per_site = hash:/etc/postfix/tls_per_site
-
-    /etc/postfix/tls_per_site:
-        [example.net]:587   MUST_NOPEERMATCH
-
 C\bCe\ber\brt\bti\bif\bfi\bic\bca\bat\bte\be f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 
 Certificate fingerprint verification is available with Postfix 2.5 and later.
@@ -898,12 +825,8 @@ certificate name matches a known pattern. Mandatory server certificate
 verification can be configured by setting "smtp_tls_security_level = verify".
 The smtp_tls_verify_cert_match parameter can override the default "hostname"
 certificate name matching strategy. Fine-tuning the matching strategy is
-generally only appropriate for secure-channel destinations.
-
-With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to its
-default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = yes".
-For LMTP use the corresponding "lmtp_" parameters.
+generally only appropriate for secure-channel destinations. For LMTP use the
+corresponding "lmtp_" parameters.
 
 If the server certificate chain is trusted (see smtp_tls_CAfile and
 smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate
@@ -927,11 +850,8 @@ STARTTLS support. In such cases, you can often use a secure-channel
 configuration instead.
 
 You can enable mandatory server certificate verification just for specific
-destinations. With the Postfix 2.3 and later TLS policy table, specify the
-"verify" security level. With the obsolete per-site table, specify the "MUST"
-keyword. While the obsolete approach still works with Postfix 2.3, it is
-strongly discouraged: users of Postfix 2.3 and later should use the new TLS
-policy settings.
+destinations. With the Postfix TLS policy table, specify the "verify" security
+level.
 
 Example:
 
@@ -948,30 +868,15 @@ uses "high" grade ciphers.
     /etc/postfix/tls_policy:
         example.com       verify ciphers=high
 
-Postfix 2.2 syntax:
-
-    /etc/postfix/main.cf:
-        indexed = ${default_database_type}:${config_directory}/
-        smtp_tls_CAfile = ${config_directory}/CAfile.pem
-        smtp_tls_per_site = ${indexed}tls_per_site
-
-    /etc/postfix/tls_per_site:
-        example.com         MUST
-
 S\bSe\bec\bcu\bur\bre\be s\bse\ber\brv\bve\ber\br c\bce\ber\brt\bti\bif\bfi\bic\bca\bat\bte\be v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 
 At the secure TLS security level, messages are sent only over secure-channel
 TLS sessions where DNS forgery resistant server certificate verification
-succeeds. If no suitable servers are found, the message will be deferred. With
-Postfix 2.3 and later, secure-channels can be configured by setting
-"smtp_tls_security_level = secure". The smtp_tls_secure_cert_match parameter
-can override the default "nexthop, dot-nexthop" certificate match strategy.
-
-With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to its
-default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = yes"
-with additional settings to harden peer certificate verification against forged
-DNS data. For LMTP, use the corresponding "lmtp_" parameters.
+succeeds. If no suitable servers are found, the message will be deferred.
+Postfix secure-channels can be configured by setting "smtp_tls_security_level =
+secure". The smtp_tls_secure_cert_match parameter can override the default
+"nexthop, dot-nexthop" certificate match strategy. For LMTP, use the
+corresponding "lmtp_" parameters.
 
 If the server certificate chain is trusted (see smtp_tls_CAfile and
 smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate
@@ -994,97 +899,70 @@ would be a client that sends all email to a central mailhub that offers the
 necessary STARTTLS support.
 
 You can enable secure TLS verification just for specific destinations. With the
-Postfix 2.3 and later TLS policy table, specify the "secure" security level.
-With the obsolete per-site table, specify the "MUST" keyword and harden the
-certificate verification against DNS forgery. While the obsolete approach still
-works with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3 and
-later should use the new TLS policy settings.
+Postfix TLS policy table, specify the "secure" security level.
 
 Examples:
 
-Secure-channel TLS without transport(5) table overrides:
-
-The Postfix SMTP client will encrypt all traffic and verify the destination
-name immune from forged DNS responses. MX lookups are still used to find the
-hostnames of the SMTP servers for example.com, but these hostnames are not used
-when checking the names in the server certificate(s). Rather, the requirement
-is that the MX hosts for example.com have trusted certificates with a subject
-name of example.com or a sub-domain, see the documentation for the
-smtp_tls_secure_cert_match parameter.
-
-The related domains example.co.uk and example.co.jp are hosted on the same MX
-hosts as the primary example.com domain, and traffic to these is secured by
-verifying the primary example.com domain in the server certificates. This frees
-the server administrator from needing the CA to sign certificates that list all
-the secondary domains. The downside is that clients that want secure channels
-to the secondary domains need explicit TLS policy table entries.
-
-Note, there are two ways to handle related domains. The first is to use the
-default routing for each domain, but add policy table entries to override the
-expected certificate subject name. The second is to override the next-hop in
-the transport table, and use a single policy table entry for the common
-nexthop. We choose the first approach, because it works better when domain
-ownership changes. With the second approach we securely deliver mail to the
-wrong destination, with the first approach, authentication fails and mail stays
-in the local queue, the first approach is more appropriate in most cases.
-
-    /etc/postfix/main.cf:
-        smtp_tls_CAfile = /etc/postfix/CAfile.pem
-        smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
-
-    /etc/postfix/transport:
-
-    /etc/postfix/tls_policy:
-        example.com     secure
-        example.co.uk   secure match=example.com:.example.com
-        example.co.jp   secure match=example.com:.example.com
-
-Secure-channel TLS with transport(5) table overrides:
-
-In this case traffic to example.com and its related domains is sent to a single
-logical gateway (to avoid a single point of failure, its name may resolve to
-one or more load-balancer addresses, or to the combined addresses of multiple
-physical hosts). All the physical hosts reachable via the gateway's IP
-addresses have the logical gateway name listed in their certificates. This
-secure-channel configuration can also be implemented via a hardened variant of
-the MUST policy in the obsolete per-site table. As stated above, this approach
-has the potential to mis-deliver email if the related domains change hands.
+  * Secure-channel TLS without transport(5) table overrides:
+
+    The Postfix SMTP client will encrypt all traffic and verify the destination
+    name immune from forged DNS responses. MX lookups are still used to find
+    the hostnames of the SMTP servers for example.com, but these hostnames are
+    not used when checking the names in the server certificate(s). Rather, the
+    requirement is that the MX hosts for example.com have trusted certificates
+    with a subject name of example.com or a sub-domain, see the documentation
+    for the smtp_tls_secure_cert_match parameter.
+
+    The related domains example.co.uk and example.co.jp are hosted on the same
+    MX hosts as the primary example.com domain, and traffic to these is secured
+    by verifying the primary example.com domain in the server certificates.
+    This frees the server administrator from needing the CA to sign
+    certificates that list all the secondary domains. The downside is that
+    clients that want secure channels to the secondary domains need explicit
+    TLS policy table entries.
+
+    Note, there are two ways to handle related domains. The first is to use the
+    default routing for each domain, but add policy table entries to override
+    the expected certificate subject name. The second is to override the next-
+    hop in the transport table, and use a single policy table entry for the
+    common nexthop. We choose the first approach, because it works better when
+    domain ownership changes. With the second approach we securely deliver mail
+    to the wrong destination, with the first approach, authentication fails and
+    mail stays in the local queue, the first approach is more appropriate in
+    most cases.
 
-    /etc/postfix/main.cf:
-        smtp_tls_CAfile = /etc/postfix/CAfile.pem
-        transport_maps = hash:/etc/postfix/transport
-        smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+        /etc/postfix/main.cf:
+            smtp_tls_CAfile = /etc/postfix/CAfile.pem
+            smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
 
-    /etc/postfix/transport:
-        example.com     smtp:[tls.example.com]
-        example.co.uk   smtp:[tls.example.com]
-        example.co.jp   smtp:[tls.example.com]
+        /etc/postfix/transport:
 
-    /etc/postfix/tls_policy:
-        [tls.example.com] secure match=tls.example.com
+        /etc/postfix/tls_policy:
+            example.com     secure
+            example.co.uk   secure match=example.com:.example.com
+            example.co.jp   secure match=example.com:.example.com
 
-Postfix 2.2.9 and later syntax:
+  * Secure-channel TLS with transport(5) table overrides:
 
-N\bNo\bot\bte\be:\b: Avoid policy lookups with the bare hostname (for example,
-"tls.example.com"). Instead, use the destination (for example, "
-[tls.example.com]") as the per-site table lookup key (a recipient domain or MX-
-enabled transport nexthop with no port suffix may look like a bare hostname,
-but is still a suitable destination). With Postfix 2.3 and later, do not use
-the obsolete per-site table; use the new policy table instead.
+    In this case traffic to example.com and its related domains is sent to a
+    single logical gateway (to avoid a single point of failure, its name may
+    resolve to one or more load-balancer addresses, or to the combined
+    addresses of multiple physical hosts). All the physical hosts reachable via
+    the gateway's IP addresses have the logical gateway name listed in their
+    certificates.
 
-    /etc/postfix/main.cf:
-        smtp_cname_overrides_servername = no
-        smtp_tls_CAfile = /etc/postfix/CAfile.pem
-        transport_maps = hash:/etc/postfix/transport
-        smtp_tls_per_site = hash:/etc/postfix/tls_per_site
+        /etc/postfix/main.cf:
+            smtp_tls_CAfile = /etc/postfix/CAfile.pem
+            transport_maps = hash:/etc/postfix/transport
+            smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
 
-    /etc/postfix/transport:
-        example.com     smtp:[tls.example.com]
-        example.co.uk   smtp:[tls.example.com]
-        example.co.jp   smtp:[tls.example.com]
+        /etc/postfix/transport:
+            example.com     smtp:[tls.example.com]
+            example.co.uk   smtp:[tls.example.com]
+            example.co.jp   smtp:[tls.example.com]
 
-    /etc/postfix/tls_per_site:
-        [tls.example.com]       MUST
+        /etc/postfix/tls_policy:
+            [tls.example.com] secure match=tls.example.com
 
 C\bCl\bli\bie\ben\bnt\bt-\b-s\bsi\bid\bde\be T\bTL\bLS\bS a\bac\bct\bti\biv\bvi\bit\bty\by l\blo\bog\bgg\bgi\bin\bng\bg
 
@@ -1322,10 +1200,9 @@ immune to man-in-the-middle attacks) impose constraints on the sending and
 receiving sites that preclude ubiquitous deployment. One needs to manually
 configure this type of security for each destination domain, and in many cases
 implement non-default TLS policy table entries for additional domains hosted at
-a common secured destination. With Postfix 2.3, we make secure-channel
-configurations substantially easier to configure, but they will never be the
-norm. For the generic domain with which you have made no specific security
-arrangements, this security level is not a good fit.
+a common secured destination. For these reasons secure-channel configurations
+will never be the norm. For the generic domain with which you have made no
+specific security arrangements, this security level is not a good fit.
 
 Given that strong authentication is not generally possible, and that verifiable
 certificates cost time and money, many servers that implement TLS use self-
@@ -1333,30 +1210,24 @@ signed certificates or private CAs. This further limits the applicability of
 verified TLS on the public Internet.
 
 Historical note: while the documentation of these issues and many of the
-related features are new with Postfix 2.3, the issue was well understood before
-Postfix 1.0, when Lutz Jänicke was designing the first unofficial Postfix TLS
-patch. See his original post http://www.imc.org/ietf-apps-tls/mail-archive/
-msg00304.html and the first response http://www.imc.org/ietf-apps-tls/mail-
-archive/msg00305.html. The problem is not even unique to SMTP or even TLS,
+related features were new with Postfix 2.3, the issue was well understood
+before Postfix 1.0, when Lutz Jänicke was designing the first unofficial
+Postfix TLS patch. See his original post http://www.imc.org/ietf-apps-tls/mail-
+archive/msg00304.html and the first response http://www.imc.org/ietf-apps-tls/
+mail-archive/msg00305.html. The problem is not even unique to SMTP or even TLS,
 similar issues exist for secure connections via aliases for HTTPS and Kerberos.
 SMTP merely uses indirect naming (via MX records) more frequently.
 
 T\bTL\bLS\bS p\bpo\bol\bli\bic\bcy\by t\bta\bab\bbl\ble\be
 
-The current TLS policy table was introduced with Postfix 2.3. For earlier
-releases, read the description of the obsolete Postfix 2.2 per-site table.
-
 A small fraction of servers offer STARTTLS but the negotiation consistently
-fails. With Postfix 2.3, so long as encryption is not enforced, the delivery is
-immediately retried with TLS disabled. You no longer need to explicitly disable
-TLS for the problem destinations. As soon as their TLS software or
-configuration is repaired, encryption will be used.
+fails. As long as encryption is not mandatory, the Postfix SMTP client retries
+the delivery immediately with TLS disabled, without any need to explicitly
+disable TLS for the problem destinations.
 
-The new policy table is specified via the smtp_tls_policy_maps parameter. This
+The policy table is specified via the smtp_tls_policy_maps parameter. This
 lists optional lookup tables with the Postfix SMTP client TLS security policy
-by next-hop destination. When $smtp_tls_policy_maps is not empty, the obsolete
-smtp_tls_per_site parameter is ignored (a warning is written to the logs if
-both parameter values are non-empty).
+by next-hop destination.
 
 The TLS policy table is indexed by the full next-hop destination, which is
 either the recipient domain, or the verbatim next-hop specified in the
@@ -1479,164 +1350,6 @@ render the "secure" level vulnerable to DNS forgery. Do not use the "hostname"
 strategy for secure-channel configurations in environments where DNS security
 is not assured.
 
-O\bOb\bbs\bso\bol\ble\bet\bte\be p\bpe\ber\br-\b-s\bsi\bit\bte\be T\bTL\bLS\bS p\bpo\bol\bli\bic\bcy\by s\bsu\bup\bpp\bpo\bor\brt\bt
-
-This section describes an obsolete per-site TLS policy mechanism. Unlike the
-Postfix 2.3 policy table mechanism, this uses as a policy lookup key a
-potentially untrusted server hostname, and lacks control over what names can
-appear in server certificates. Because of this, the obsolete mechanism is
-typically vulnerable to false DNS hostname information in MX or CNAME records.
-These attacks can be eliminated only with great difficulty. The new policy
-table makes secure-channel configurations easier and provides more control over
-the cipher and protocol selection for sessions with mandatory encryption.
-
-Avoid policy lookups with the bare hostname. Instead, use the full destination
-nexthop (enclosed in [] with a possible ":port" suffix) as the per-site table
-lookup key (a recipient domain or MX-enabled transport nexthop with no port
-suffix may look like a bare hostname, but is still a suitable destination).
-With Postfix 2.3 and later, use of the obsolete approach documented here is
-strongly discouraged: use the new policy table instead.
-
-Starting with Postfix 2.3, the underlying TLS enforcement levels are common to
-the obsolete per-site table and the new policy table. The main.cf
-smtp_tls_mandatory_ciphers and smtp_tls_mandatory_protocols parameters control
-the TLS ciphers and protocols for mandatory encryption regardless of which
-table is used. The smtp_tls_verify_cert_match parameter determines the match
-strategy for the obsolete "MUST" keyword in the same way as for the "verify"
-level in the new policy.
-
-With Postfix < 2.3, the obsolete smtp_tls_cipherlist parameter is also applied
-for opportunistic TLS sessions, and should be used with care, or not at all.
-Setting cipherlist restrictions that are incompatible with a remote SMTP server
-render that server unreachable, TLS handshakes are always attempted and always
-fail.
-
-When smtp_tls_policy_maps is empty (default) and smtp_tls_per_site is not
-empty, the per-site table is searched for a policy that matches the following
-information:
-
-    remote SMTP server hostname
-        This is simply the DNS name of the server that the Postfix SMTP client
-        connects to; this name may be obtained from other DNS lookups, such as
-        MX lookups or CNAME lookups. Use of the hostname lookup key is
-        discouraged; always use the next-hop destination instead.
-    next-hop destination
-        This is normally the domain portion of the recipient address, but it
-        may be overridden by information from the transport(5) table, from the
-        relayhost parameter setting, or from the relay_transport setting. When
-        it is not the recipient domain, the next-hop destination can have the
-        Postfix-specific form "[name]", "[name]:port", "name" or "name:port".
-        This is the recommended lookup key for per-site policy lookups (and
-        incidentally for SASL password lookups).
-
-When both the hostname lookup and the next-hop lookup succeed, the host policy
-does not automatically override the next-hop policy. Instead, precedence is
-given to either the more specific or the more secure per-site policy as
-described below.
-
-The smtp_tls_per_site table uses a simple "name whitespace value" format.
-Specify host names or next-hop destinations on the left-hand side; no wildcards
-are allowed. On the right hand side specify one of the following keywords:
-
-    NONE
-        No TLS. This overrides a less specific "MAY" lookup result from the
-        alternate host or next-hop lookup key, and overrides the global
-        smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername settings.
-    MAY
-        Opportunistic TLS. This has less precedence than a more specific result
-        (including "NONE") from the alternate host or next-hop lookup key, and
-        has less precedence than the more specific global "smtp_enforce_tls =
-        yes" or "smtp_tls_enforce_peername = yes".
-    MUST_NOPEERMATCH
-        Mandatory TLS encryption. This overrides a less secure "NONE" or a less
-        specific "MAY" lookup result from the alternate host or next-hop lookup
-        key, and overrides the global smtp_use_tls, smtp_enforce_tls and
-        smtp_tls_enforce_peername settings.
-    MUST
-        Mandatory server certificate verification. This overrides a less secure
-        "NONE" and "MUST_NOPEERMATCH" or a less specific "MAY" lookup result
-        from the alternate host or next-hop lookup key, and overrides the
-        global smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername
-        settings.
-
-The precedences between global (main.cf) and per-site TLS policies can be
-summarized as follows:
-
-  * When neither the remote SMTP server hostname nor the next-hop destination
-    are found in the smtp_tls_per_site table, the policy is based on
-    smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername. Note:
-    "smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = yes" imply
-    "smtp_use_tls = yes".
-
-  * When both hostname and next-hop destination lookups produce a result, the
-    more specific per-site policy (NONE, MUST, etc) overrides the less specific
-    one (MAY), and the more secure per-site policy (MUST, etc) overrides the
-    less secure one (NONE).
-
-  * After the per-site policy lookups are combined, the result generally
-    overrides the global policy. The exception is the less specific "MAY" per-
-    site policy, which is overruled by the more specific global
-    "smtp_enforce_tls = yes" with server certificate verification as specified
-    with the smtp_tls_enforce_peername parameter.
-
-C\bCl\blo\bos\bsi\bin\bng\bg a\ba D\bDN\bNS\bS l\blo\boo\bop\bph\bho\bol\ble\be w\bwi\bit\bth\bh o\bob\bbs\bso\bol\ble\bet\bte\be p\bpe\ber\br-\b-s\bsi\bit\bte\be T\bTL\bLS\bS p\bpo\bol\bli\bic\bci\bie\bes\bs
-
-For a general discussion of TLS security for SMTP see TLS limitations above.
-What follows applies only to Postfix 2.2.9 and subsequent Postfix 2.2 patch
-levels. Do not use this approach with Postfix 2.3 and later; instead see the
-instructions under secure server certificate verification.
-
-As long as no secure DNS lookup mechanism is available, false hostnames in MX
-or CNAME responses can change Postfix's notion of the server hostname that is
-used for TLS policy lookup and server certificate verification. Even with a
-perfect match between the server hostname and the server certificate, there is
-no guarantee that Postfix is connected to the right server. To avoid this
-loophole, take all of the following steps:
-
- 1. Use a dedicated message delivery transport (for example, "securetls") as
-    illustrated below.
-
- 2. Eliminate MX lookups. Specify local transport(5) table entries for
-    sensitive domains with explicit securetls:[mailhost] or securetls:
-    [mailhost]:port destinations (you can assure security of this table unlike
-    DNS). This prevents false hostname information in DNS MX records from
-    changing Postfix's notion of the server hostname that is used for TLS
-    policy lookup and server certificate verification. The "securetls"
-    transport is configured to enforce TLS with peername verification, and to
-    disable the SMTP connection cache which could interfere with enforcement of
-    smtp_tls_per_site policies.
-
- 3. Disallow CNAME hostname overrides. In main.cf, specify
-    "smtp_cname_overrides_servername = no". This prevents false hostname
-    information in DNS CNAME records from changing the server hostname that
-    Postfix uses for TLS policy lookup and server certificate verification.
-    This feature requires Postfix 2.2.9 or later. The default value is "no"
-    starting with Postfix 2.3.
-
-Example:
-
-We give the non-default "securetls" transport an explicit master.cf process
-limit, so that we don't raise its process limit when raising
-$default_process_limit. The total process limit for *all* transports should
-stay somewhat under 1024 (the typical select() file descriptor limit);
-otherwise transports may be throttled under steady high load, compounding
-congestion. It is not uncommon at high volume sites to set the default process
-limit to 500 or more.
-
-We also default the "securetls" transport TLS security level to MUST, obviating
-the need for per-site table entries for secure-channel destinations.
-
-    /etc/postfix/main.cf:
-        transport_maps = hash:/etc/postfix/transport
-
-    /etc/postfix/transport:
-        example.com         securetls:[tls.example.com]
-
-    /etc/postfix/master.cf:
-        securetls unix  -       -       n       -       100     smtp
-            -o smtp_enforce_tls=yes
-            -o smtp_tls_enforce_peername=yes
-
 D\bDi\bis\bsc\bco\bov\bve\ber\bri\bin\bng\bg s\bse\ber\brv\bve\ber\brs\bs t\bth\bha\bat\bt s\bsu\bup\bpp\bpo\bor\brt\bt T\bTL\bLS\bS
 
 As we decide on a "per site" basis whether or not to use TLS, it would be good
@@ -1971,10 +1684,7 @@ indicates a super-user shell.
             smtpd_tls_session_cache_database =
                btree:/var/lib/postfix/smtpd_tls_session_cache
             tls_random_source = dev:/dev/urandom
-            # Postfix 2.3 and later
             smtpd_tls_security_level = may
-            # Obsolete, but still supported
-            smtpd_use_tls = yes
 
 B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh T\bTL\bLS\bS s\bsu\bup\bpp\bpo\bor\brt\bt
 
index b704fb2d29ef4121fc415f33b9c9a600c37caa34..56f87da73e353295f8ad1be6cee973c363c23248 100644 (file)
@@ -390,12 +390,12 @@ T\bTu\bun\bni\bin\bng\bg t\bth\bhe\be n\bnu\bum\bmb\bbe\ber\br o\bof\bf P\bPo\bos\bst\btf\bfi\bix\bx p\bp
 
 The default_process_limit configuration parameter gives direct control over how
 many daemon processes Postfix will run. As of Postfix 2.0 the default limit is
-100 smtp client processes, 100 smtp server processes, and so on. This may
+100 SMTP client processes, 100 SMTP server processes, and so on. This may
 overwhelm systems with little memory, as well as networks with low bandwidth.
 
 You can change the global process limit by specifying a non-default
-default_process_limit in the main.cf file. For example, to run up to 10 smtp
-client processes, 10 smtp server processes, and so on:
+default_process_limit in the main.cf file. For example, to run up to 10 SMTP
+client processes, 10 SMTP server processes, and so on:
 
     /etc/postfix/main.cf:
         default_process_limit = 10
index d305283a013df1c6f3d7805122dd8f8a6c254f01..d2a4e8cb92b390a6492ef29294b4cb4853e95489 100644 (file)
@@ -2,14 +2,18 @@ Wish list:
 
        Things to do before the stable release:
 
+       Either make all void dict_* operations return an error code,
+       or require that they reset dict_errno on entry, either exit
+       with a fatal error or set dict_errno on error.
+
+       Is it possible to replace msg_fatal calls in match_ops.c
+       by msg_warn and longjmp? The callers will have to specify
+       if they want the code to return instead of terminate.
+
        Remove this file from the stable release.
 
        Things to do after the stable release:
 
-       Investigate viability of memcached for applications
-       that require performance for low-security operations
-       such as sharing the postscreen cache.
-
        What is the feasibility of adding an mta_name (personality)
        attribute that is propagated via queue files and delivery
        agent requests? It would default to myhostname.
index d3911d633f3b7289ccd18810e9a69e5b37ee3070..90ef9575ab8812957c8d0747bce3b67134ac1cc4 100644 (file)
@@ -166,6 +166,7 @@ $manpage_directory/man5/generic.5:f:root:-:644
 $manpage_directory/man5/header_checks.5:f:root:-:644
 $manpage_directory/man5/ldap_table.5:f:root:-:644
 $manpage_directory/man5/master.5:f:root:-:644
+$manpage_directory/man5/memcache_table.5:f:root:-:644
 $manpage_directory/man5/mysql_table.5:f:root:-:644
 $manpage_directory/man5/sqlite_table.5:f:root:-:644
 $manpage_directory/man5/nisplus_table.5:f:root:-:644
@@ -264,6 +265,7 @@ $readme_directory/LINUX_README:f:root:-:644
 $readme_directory/LOCAL_RECIPIENT_README:f:root:-:644
 $readme_directory/MACOSX_README:f:root:-:644:o
 $readme_directory/MAILDROP_README:f:root:-:644
+$readme_directory/MEMCACHE_README:f:root:-:644
 $readme_directory/MILTER_README:f:root:-:644
 $readme_directory/MULTI_INSTANCE_README:f:root:-:644
 $readme_directory/MYSQL_README:f:root:-:644
@@ -369,6 +371,7 @@ $html_directory/local.8.html:f:root:-:644
 $html_directory/mailq.1.html:f:root:-:644
 $html_directory/master.5.html:f:root:-:644
 $html_directory/master.8.html:f:root:-:644
+$html_directory/memcache_table.5.html:f:root:-:644
 $html_directory/mysql_table.5.html:f:root:-:644
 $html_directory/sqlite_table.5.html:f:root:-:644
 $html_directory/nisplus_table.5.html:f:root:-:644
index b2166e9cb96c396a7448727fef566c118716559e..f394976c51a14dcb3d26f3cd9c7a59aaa3172ac3 100644 (file)
@@ -310,6 +310,11 @@ a process terminates. </dd>
 <dd> Perform lookups using the LDAP protocol. Configuration details
 are given in the <a href="ldap_table.5.html">ldap_table(5)</a>. </dd>
 
+<dt> <b>memcache</b> (read-write) </dt>
+
+<dd> Perform memcache database lookups or updates. Configuration
+details are given in <a href="memcache_table.5.html">memcache_table(5)</a>. </dd>
+
 <dt> <b>mysql</b> (read-only) </dt>
 
 <dd> Perform MySQL database lookups. Configuration details are given
@@ -367,7 +372,7 @@ in <a href="sqlite_table.5.html">sqlite_table(5)</a>. </dd>
 <dt> <b>static</b> (read-only) </dt>
 
 <dd> Always returns its lookup table name as lookup result.  For
-example, the lookup table "static:foobar" always returns the string
+example, the lookup table "<a href="DATABASE_README.html#types">static</a>:foobar" always returns the string
 "foobar" as lookup result. </dd>
 
 <dt> <b>tcp</b> </dt>
@@ -383,8 +388,8 @@ number.
 
 <dd> This produces similar results as hash: files, except that you
 don't have to run the <a href="postmap.1.html">postmap(1)</a> command before you can use the
-file, and that texthash: does not detect changes after the file is
-read.  The lookup table name is "texthash:filename", where the file
+file, and that <a href="DATABASE_README.html#types">texthash</a>: does not detect changes after the file is
+read.  The lookup table name is "<a href="DATABASE_README.html#types">texthash</a>:filename", where the file
 name is taken literally; no suffix is appended. </dd>
 
 <dt> <b>unix</b> (read-only) </dt>
diff --git a/postfix/html/MEMCACHE_README.html b/postfix/html/MEMCACHE_README.html
new file mode 100644 (file)
index 0000000..ff96b8b
--- /dev/null
@@ -0,0 +1,113 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix memcache client Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix memcache client Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p>The Postfix memcache client type allows you to hook up Postfix to
+a memcache server. This implementation supports multiple memcache
+servers for redundancy, and multiple memcache clients that you can
+use for different table lookups. The Postfix memcache client
+supports both lookup and update operations. </p>
+
+<p> Typically, a memcache map is used to reduce query load on a
+database server, or to share a low-latency database among different
+Postfix instances. </p>
+
+<h2>Limitations</h2>
+
+<ul>
+
+<li> <p> The Postfix memcache client is based on libmemcache, which
+will terminate its process after a memcache server goes down. To
+avoid this, set up redundant memcache servers that have no common
+source of failure. </p>
+
+<li> <p> The Postfix memcache client cannot be used for security-sensitive
+tables such as <tt><a href="postconf.5.html#alias_maps">alias_maps</a></tt> (these may contain "<tt>|command</tt>"
+and "<tt>/file/name</tt>" destinations), or <tt><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></tt>
+and <tt><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></tt> (these specify UNIX process privileges).
+Typically, a memcache database is shared via a TCP socket, and is
+writable not only by Postfix, but by any process that can talk to
+the memcache server. </p>
+
+<li> <p> The Postfix memcache client requires additional configuration
+when used with the <a href="postscreen.8.html">postscreen(8)</a> and <a href="verify.8.html">verify(8)</a> daemons. For details
+see the <tt>ttl</tt> parameter discussion in the <a href="memcache_table.5.html">memcache_table(5)</a>
+manual page. </p>
+
+<li> <p> The Postfix memcache client is supported only with libmemcache
+version 1.4.0.  Some libmemcache features are documented by reading
+libmemcache source code, instead of a proper API.  </p>
+
+</ul>
+
+<h2>Building Postfix with memcache support</h2>
+
+<p>To build Postfix with memcache client support, specify
+<tt>-DHAS_MEMCACHE</tt>, the location of the libmemcache include
+files, and the location of the libmemcache object library. </p>
+
+<p> For example: </p>
+
+<blockquote>
+<pre>
+% make -f Makefile.init makefiles \
+        'CCARGS=-DHAS_MEMCACHE -I/usr/local/include' \
+       'AUXLIBS=-L/usr/local/lib -lmemcache'
+</pre>
+</blockquote>
+
+<p> Then run 'make'.  </p>
+
+<p> If the build fails with "<tt>undefined reference to `mcm_buf_len'</tt>"
+(and with a similar error message for <tt>mcm_buf_remain_off</tt>),
+then you need to edit libmemcache source code. </p>
+
+<p> The following instructions apply to libmemcache 1.4.0.rc2. </p>
+
+<ul>
+
+<li> <p> Open the libmemcache source file
+<tt>include/memcache/buffer.h</tt>. </p>
+
+<li> <p> Delete the "<tt>inline</tt>" words before the functions
+that were reported in the "<tt>undefined reference</tt>" error
+messages.  </p>
+
+<li> <p> Recompile and reinstall libmemcache. </p>
+
+</ul>
+
+<p> Then, continue building Postfix by running 'make'. </p>
+
+<h2>Configuring memcache lookup tables</h2>
+
+<p> Configuration is described in the <a href="memcache_table.5.html">memcache_table(5)</a> manpage. </p>
+
+<h2>Credits</h2>
+
+<p> The first memcache client for Postfix was written by Omar Kilani. </p>
+
+<p> Wietse wrote a new memcache client from the ground up.  Besides
+also using libmemcache, the current implementation bears no resemblance
+to Omar's work.  </p>
+
+</body>
+
+</html>
index d4874bae9392b375c60241c05401eb528fd8c888..f224338747b45c6054fe75efae6d00c78f02963d 100644 (file)
@@ -620,7 +620,7 @@ $<a href="postconf.5.html#daemon_directory">daemon_directory</a>. </p>
 $<a href="postconf.5.html#manpage_directory">manpage_directory</a> and $<a href="postconf.5.html#readme_directory">readme_directory</a>. </p>
 
 <li><p> Entries in /etc/passwd and /etc/group for the $<a href="postconf.5.html#mail_owner">mail_owner</a> user and
-$<a href="postconf.5.html#setgid_group">setgid_group</a> group. The the $<a href="postconf.5.html#mail_owner">mail_owner</a> user provides the mail system
+$<a href="postconf.5.html#setgid_group">setgid_group</a> group. The $<a href="postconf.5.html#mail_owner">mail_owner</a> user provides the mail system
 with a protected (non-root) execution context. The $<a href="postconf.5.html#setgid_group">setgid_group</a> group
 is used exclusively to support the setgid <a href="postdrop.1.html">postdrop(1)</a> and <a href="postqueue.1.html">postqueue(1)</a>
 utilities (it <b>must not</b> be the primary group or secondary group
index 36327f2befefd96a6b8f092bb4086a445dff098b..2778e7bac97ccfb337833029f14b23469a4f26db 100644 (file)
@@ -20,6 +20,7 @@ CONFIG        = access.5.html aliases.5.html canonical.5.html relocated.5.html \
        transport.5.html virtual.5.html pcre_table.5.html regexp_table.5.html \
        cidr_table.5.html tcp_table.5.html header_checks.5.html \
        ldap_table.5.html mysql_table.5.html pgsql_table.5.html \
+       memcache_table.5.html \
        master.5.html nisplus_table.5.html generic.5.html bounce.5.html \
        postfix-wrapper.5.html sqlite_table.5.html
 OTHER  = postfix-manuals.html
@@ -272,6 +273,10 @@ master.5.html: ../proto/master
        PATH=../mantools:$$PATH; \
        srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
 
+memcache_table.5.html: ../proto/memcache_table
+       PATH=../mantools:$$PATH; \
+       srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
+
 mysql_table.5.html: ../proto/mysql_table
        PATH=../mantools:$$PATH; \
        srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
index 2ce5805b28277374ad89907c4488041ec7284189..d7ce9a8a1af8bae3409ec7f933f9d97e36f433e3 100644 (file)
@@ -27,11 +27,6 @@ code.  Assuming that OpenSSL is written as carefully as Wietse's
 own code, every 1000 lines introduce one additional bug into
 Postfix.  </p>
 
-<p> At this time, you should no longer be using OpenSSL releases prior
-to the most recent 0.9.8 release unless all relevant security fixes have
-been backported to the earlier release by you or your O/S vendor. OpenSSL
-0.9.7 and earlier are no longer maintained by the OpenSSL team. </p>
-
 <h2> What Postfix TLS support does for you </h2>
 
 <p> Transport Layer Security (TLS, formerly called SSL) provides
@@ -39,11 +34,13 @@ certificate-based authentication and encrypted sessions.  An
 encrypted session protects the information that is transmitted with
 SMTP mail or with SASL authentication.
 
-<p> This document describes a TLS user interface that was introduced
-with Postfix version 2.3. Support for an older user interface is
-documented in <a href="TLS_LEGACY_README.html">TLS_LEGACY_README</a>, which also describes the differences
-between Postfix and the third-party patch on which Postfix version
-2.2 TLS support was based.  </p>
+<blockquote> <p> <a name="client_tls_obs"></a> <a
+name="client_tls_harden"></a> NOTE: This document describes a TLS
+user interface that was introduced with Postfix version 2.3. Support
+for an older user interface is documented in <a href="TLS_LEGACY_README.html">TLS_LEGACY_README</a>,
+which also describes the differences between Postfix and the
+third-party patch on which Postfix version 2.2 TLS support was
+based.  </p> </blockquote>
 
 <p> Topics covered in this document: </p>
 
@@ -85,8 +82,8 @@ represent storage elements. </p>
 <li> <p> The <a href="smtpd.8.html">smtpd(8)</a> server implements the SMTP over TLS server
 side. </p>
 
-<li> <p> The <a href="smtp.8.html">smtp(8)</a> client implements the SMTP over TLS client
-side. </p>
+<li> <p> The <a href="smtp.8.html">smtp(8)</a> client implements the SMTP (and LMTP) over TLS
+client side. </p>
 
 <li> <p> The <a href="tlsmgr.8.html">tlsmgr(8)</a> server maintains the pseudo-random number
 generator (PRNG) that seeds the TLS engines in the <a href="smtpd.8.html">smtpd(8)</a> server
@@ -95,6 +92,10 @@ cache files. </p>
 
 </ul>
 
+<p> Not shown in the figure are the <a href="tlsproxy.8.html">tlsproxy(8)</a> server and the
+<a href="postscreen.8.html">postscreen(8)</a> server. These use TLS in the same manner as <a href="smtpd.8.html">smtpd(8)</a>.
+</p>
+
 <table>
 
 <tr> <td>Network<tt>-&gt; </tt> </td> <td align="center"
@@ -170,7 +171,7 @@ CA must generate, and be prepared to present to most clients, a
 self-signed or private-CA signed certificate. The remote SMTP client
 will generally not be
 able to authenticate the self-signed certificate, but unless the
-client is running Postfix 2.3 or
+client is running Postfix or
 similar software, it will still insist on a server certificate. </p>
 
 <p> For servers that are <b>not</b> public Internet MX hosts, Postfix
@@ -389,19 +390,14 @@ since the headers may be changed by intermediate servers. </p>
 
 <p> By default, TLS is disabled in the Postfix SMTP server, so no
 difference to plain Postfix is visible.  Explicitly switch it on
-with "<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may" (Postfix 2.3 and
-later) or "<a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> = yes" (obsolete but still
-supported). </p>
+with "<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may". </p>
 
 <p> Example: </p>
  
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    # Postfix 2.3 and later
     <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may
-    # Obsolete, but still supported
-    <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> = yes
 </pre>
 </blockquote>
 
@@ -417,9 +413,8 @@ private key. This is intended behavior. </p>
 <p> <a name="server_enforce">You can ENFORCE the use of TLS</a>,
 so that the Postfix SMTP server announces STARTTLS and accepts no
 mail without TLS encryption, by setting
-"<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt" (Postfix 2.3 and
-later) or "<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a> = yes" (obsolete but still
-supported). According to <a href="http://tools.ietf.org/html/rfc2487">RFC 2487</a> this MUST NOT be applied in case
+"<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt". According to <a href="http://tools.ietf.org/html/rfc2487">RFC 2487</a> this
+MUST NOT be applied in case
 of a publicly-referenced Postfix SMTP server.  This option is off
 by default and should only seldom be used. </p>
 
@@ -428,10 +423,7 @@ by default and should only seldom be used. </p>
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    # Postfix 2.3 and later
     <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt
-    # Obsolete, but still supported
-    <a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a> = yes
 </pre>
 </blockquote>
 
@@ -473,7 +465,7 @@ when client certificates are requested, and abort the SMTP session. So
 this option is "off" by default. You will however need the certificate
 if you want to use certificate based relaying with, for example, the
 <a href="postconf.5.html#permit_tls_clientcerts">permit_tls_clientcerts</a> feature. A server that wants client certificates
-must first present its own certificate. While Postfix 2.3 by default
+must first present its own certificate. While Postfix by default
 offers anonymous ciphers to remote SMTP clients, these are automatically
 suppressed
 when the Postfix SMTP server is configured to ask for client
@@ -485,10 +477,7 @@ certificates. </p>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> = yes
-    # Postfix 2.3 and later
     <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may
-    # Obsolete, but still supported
-    <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> = yes
 </pre>
 </blockquote>
 
@@ -505,10 +494,7 @@ logged. </p>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtpd_tls_req_ccert">smtpd_tls_req_ccert</a> = yes
-    # Postfix 2.3 and later
     <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt
-    # Obsolete, but still supported
-    <a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a> = yes
 </pre>
 </blockquote>
 
@@ -539,12 +525,10 @@ configured to supply its intermediate CA certificate). </p>
 
 <p> Sending AUTH data over an unencrypted channel poses a security
 risk.  When TLS layer encryption is required
-("<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt" or the obsolete
-"<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a> = yes"), the Postfix SMTP server will
+("<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt"), the Postfix SMTP server will
 announce and accept AUTH only after the TLS layer has been activated
 with STARTTLS. When TLS layer encryption is optional
-("<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may" or the obsolete
-"<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a> = no"), it may however still be useful
+("<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may"), it may however still be useful
 to only offer AUTH when TLS is active. To maintain compatibility
 with non-TLS clients, the default is to accept AUTH without encryption.
 In order to change this behavior, set
@@ -695,12 +679,6 @@ the name of the user or host:</p>
 
 <h3><a name="server_cipher">Server-side cipher controls</a> </h3>
 
-<p> The description below is for Postfix 2.3; for Postfix &lt; 2.3 the
-<a href="postconf.5.html#smtpd_tls_cipherlist">smtpd_tls_cipherlist</a> parameter specifies the acceptable ciphers as an
-explicit OpenSSL cipherlist. The obsolete setting applies even when TLS
-encryption is not enforced. Use of this control on public MX hosts is
-strongly discouraged. </p>
-
 <p> The Postfix SMTP server supports 5 distinct cipher security levels
 as specified by the <a href="postconf.5.html#smtpd_tls_mandatory_ciphers">smtpd_tls_mandatory_ciphers</a> configuration parameter,
 which determines the cipher grade with mandatory TLS encryption. The
@@ -732,7 +710,7 @@ is optional. The mandatory TLS protocol list is specified via the
 corresponding <a href="postconf.5.html#smtpd_tls_protocols">smtpd_tls_protocols</a> parameter (Postfix &ge; 2.6)
 controls the SSL/TLS protocols used with opportunistic TLS. </p>
 
-<p> For a server that is not a public Internet MX host, Postfix (&ge; 2.3)
+<p> For a server that is not a public Internet MX host, Postfix
 supports configurations with no <a href="#server_cert_key">server
 certificates</a> that use <b>only</b> the anonymous ciphers. This is
 enabled by explicitly setting "<a href="postconf.5.html#smtpd_tls_cert_file">smtpd_tls_cert_file</a> = none"
@@ -870,10 +848,6 @@ key configuration </a>
 
 <li><a href="#client_tls_policy"> Per-destination TLS policy </a>
 
-<li><a href="#client_tls_obs"> Obsolete per-site TLS policy support </a>
-
-<li><a href="#client_tls_harden"> Closing a DNS loophole with obsolete per-site TLS policies </a>
-
 <li><a href="#client_tls_discover"> Discovering servers that support TLS </a>
 
 <li><a href="#client_vrfy_server">Server certificate verification depth</a>
@@ -934,32 +908,26 @@ The "null" ciphers provide authentication without encryption. </p>
 <h4><a name="client_tls_none"> No TLS encryption </a> </h4>
 
 <p> At the "none" TLS security level, TLS encryption is
-disabled. This is the default security level. With Postfix 2.3 and later,
-it can be configured explicitly by setting "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = none". </p>
+disabled. This is the default security level, and
+can be configured explicitly by setting "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = none".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
-<p> With Postfix 2.2 and earlier, or when <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> is set to
-its default (backwards compatible) empty value, the appropriate configuration
-settings are "<a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> = no" and "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = no".
-With either approach, TLS is not used even if supported by the server.
-For LMTP, use the corresponding "lmtp_" parameters. </p>
-
-<p> Per destination settings may override this default setting, in which case
+<p> Per-destination settings may override this default setting, in which case
 TLS is used selectively, only with destinations explicitly configured
 for TLS. </p>
 
 <p> You can disable TLS for a subset of destinations, while leaving
-it enabled for the rest. With the Postfix 2.3 and later TLS <a
+it enabled for the rest. With the Postfix TLS <a
 href="#client_tls_policy">policy table</a>, specify the "none"
-security level. With the obsolete <a href="#client_tls_obs">per-site</a>
-table, specify the "NONE" keyword. </p>
+security level.
 
 <h4><a name="client_tls_may"> Opportunistic TLS </a> </h4>
 
 <p> At the "may" TLS security level, TLS encryption is <i>opportunistic</i>.
 The SMTP transaction is encrypted if the STARTTLS ESMTP feature
 is supported by the server. Otherwise, messages are sent in the clear.
-With Postfix 2.3 and later, opportunistic TLS can be configured by
-setting "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = may".
+Opportunistic TLS can be configured by setting "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = may".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
 <p> Since sending in the clear is acceptable, demanding stronger
 than default TLS security mostly reduces inter-operability. If you
@@ -970,17 +938,12 @@ and cipher grade
 used with opportunistic TLS. With earlier releases the opportunistic TLS
 cipher grade is always "export" and no protocols are disabled. </p>
 
-<p> With Postfix 2.2 and earlier, or when <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> is
-set to its default (backwards compatible) empty value, the appropriate
-configuration settings are "<a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> = yes" and
-"<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = no".
-For LMTP use the corresponding "lmtp_" parameters. </p>
-
 <p> With opportunistic TLS, mail delivery continues even if the
-server certificate is untrusted or bears the wrong name.  Starting
-with Postfix 2.3, when the TLS handshake fails for an opportunistic
-TLS session, rather than give up on mail delivery, the transaction
-is retried with TLS disabled. Trying an unencrypted connection makes
+server certificate is untrusted or bears the wrong name.  
+When the TLS handshake fails for an opportunistic
+TLS session, rather than give up on mail delivery, the Postfix SMTP
+client retries the transaction
+with TLS disabled. Trying an unencrypted connection makes
 it possible to deliver mail to sites with non-interoperable server
 TLS implementations. </p>
 
@@ -994,9 +957,8 @@ Attempts to configure opportunistic encryption of LMTP sessions will
 be ignored with a warning written to the mail logs. </p>
 
 <p> You can enable opportunistic TLS just for selected destinations. With
-the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy table</a>,
-specify the "may" security level. With the obsolete <a
-href="#client_tls_obs">per-site</a> table, specify the "MAY" keyword.</p>
+the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "may" security level. </p>
 
 <p> This is the most common security level for TLS protected SMTP
 sessions, stronger security is not generally available and, if needed,
@@ -1012,27 +974,18 @@ on TLS <a href="#client_tls_limits">limitations</a> above. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> = yes
-    <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = no
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_encrypt"> Mandatory TLS encryption </a> </h4>
 
 <p> At the "encrypt" TLS security level, messages are sent only
 over TLS encrypted sessions. The SMTP transaction is aborted unless
 the STARTTLS ESMTP feature is supported by the remote SMTP server.
 If no suitable
-servers are found, the message will be deferred. With Postfix 2.3
-and later, mandatory TLS encryption can be configured by setting
+servers are found, the message will be deferred.
+Mandatory TLS encryption can be configured by setting
 "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = encrypt". Even though TLS
 encryption is always used, mail delivery continues even if the server
-certificate is untrusted or bears the wrong name. </p>
+certificate is untrusted or bears the wrong name.
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
 <p> At this security level and higher, the <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>
 and <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> configuration parameters determine
@@ -1042,12 +995,6 @@ met, the mail transaction is aborted.  The documentation for these
 parameters includes useful interoperability and security guidelines.
 </p>
 
-<p> With Postfix 2.2 and earlier, or when <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a>
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes"
-and "<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> = no". For LMTP use the corresponding
-"lmtp_" parameters. </p>
-
 <p> Despite the potential for eliminating passive eavesdropping attacks,
 mandatory TLS encryption is not viable as a default security level for
 mail delivery to the public Internet. Most MX hosts do not support TLS at
@@ -1056,12 +1003,9 @@ that delivers mail to the Internet, you should not configure mandatory
 TLS encryption as the default security level. </p>
 
 <p> You can enable mandatory TLS encryption just for specific destinations.
-With the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy
-table</a>, specify the "encrypt" security level. With the
-obsolete <a href="#client_tls_obs">per-site</a> table, specify the
-"MUST_NOPEERMATCH" keyword. While the obsolete approach still works
-with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3 and later
-should use the new TLS policy settings. </p>
+With the Postfix TLS <a href="#client_tls_policy">policy
+table</a>, specify the "encrypt" security level.
+</p>
 
 <p> Examples: </p>
 
@@ -1083,20 +1027,6 @@ level sessions. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax (no support for sub-domains without resorting to
-regexp tables). With Postfix 2.3 and later, do not use the obsolete <a
-href="#client_tls_obs">per-site</a> table. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/tls_per_site:
-    example.com       MUST_NOPEERMATCH
-</pre>
-</blockquote>
-
 <p> In the next example, secure message submission is configured
 via the MSA "<tt>[example.net]:587</tt>". TLS sessions are encrypted
 without authentication, because this MSA does not possess an acceptable
@@ -1128,28 +1058,6 @@ just in case the transport table entries are not specified consistently. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-
-<p> <b>Note:</b> Avoid policy lookups with the bare hostname (for
-example, "example.net").  Instead,
-use the destination (for example, "[example.net]:587"), as the <a
-href="#client_tls_obs">per-site</a> table lookup key (a recipient domain
-or MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>). With Postfix 2.3
-and later,
-do not use the obsolete <a href="#client_tls_obs">per-site</a> table;
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/tls_per_site:
-    [example.net]:587   MUST_NOPEERMATCH
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_fprint"> Certificate fingerprint verification </a> </h4>
 
 <p> Certificate fingerprint verification is available with Postfix
@@ -1234,13 +1142,8 @@ server certificate verification can be configured by setting
 <a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> parameter can override the default
 "hostname" certificate name matching strategy. Fine-tuning the
 matching strategy is generally only appropriate for <a
-href="#client_tls_secure">secure-channel</a> destinations. </p>
-
-<p> With Postfix 2.2 and earlier, or when <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a>
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes" and
-"<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> = yes". For LMTP use the corresponding
-"lmtp_" parameters. </p>
+href="#client_tls_secure">secure-channel</a> destinations.
+For LMTP use the corresponding "lmtp_" parameters. </p>
 
 <p> If the server certificate chain is trusted (see <a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a>
 and <a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a>), any DNS names in the SubjectAlternativeName
@@ -1269,12 +1172,9 @@ href="#client_tls_secure">secure-channel</a> configuration instead.
 </p>
 
 <p> You can enable mandatory server certificate verification just
-for specific destinations.  With the Postfix 2.3 and later TLS <a
+for specific destinations.  With the Postfix TLS <a
 href="#client_tls_policy">policy table</a>, specify the "verify"
-security level. With the obsolete <a href="#client_tls_obs">per-site</a>
-table, specify the "MUST" keyword.  While the obsolete approach
-still works with Postfix 2.3, it is strongly discouraged: users of
-Postfix 2.3 and later should use the new TLS policy settings. </p>
+security level. </p>
 
 <p> Example: </p>
 
@@ -1295,36 +1195,16 @@ to <i>example.com</i> recipients uses "high" grade ciphers. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    indexed = ${<a href="postconf.5.html#default_database_type">default_database_type</a>}:${<a href="postconf.5.html#config_directory">config_directory</a>}/
-    <a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> = ${<a href="postconf.5.html#config_directory">config_directory</a>}/CAfile.pem
-    <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> = ${indexed}tls_per_site
-
-/etc/postfix/tls_per_site:
-    example.com         MUST
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_secure"> Secure server certificate verification </a> </h4>
 
 <p> At the <i>secure</i> TLS security level, messages are sent only over
 <i>secure-channel</i> TLS sessions where DNS forgery resistant server
 certificate verification succeeds. If no suitable servers are found, the
-message will be deferred. With Postfix 2.3 and later, secure-channels
+message will be deferred. Postfix secure-channels
 can be configured by setting "<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = secure".
 The <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> parameter can override the default
-"nexthop, dot-nexthop" certificate match strategy. </p>
-
-<p> With Postfix 2.2 and earlier, or when <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a>
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes"
-and "<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> = yes" with additional settings to
-<a href="#client_tls_harden">harden</a> peer certificate verification
-against forged DNS data. For LMTP, use the corresponding "lmtp_"
-parameters. </p>
+"nexthop, dot-nexthop" certificate match strategy.
+For LMTP, use the corresponding "lmtp_" parameters. </p>
 
 <p> If the server certificate chain is trusted (see <a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> and
 <a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a>), any DNS names in the SubjectAlternativeName certificate
@@ -1351,18 +1231,14 @@ sends all email to a central mailhub that offers the necessary
 STARTTLS support. </p>
 
 <p> You can enable secure TLS verification just for specific destinations.
-With the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy table</a>,
-specify the "secure" security level. With the obsolete
-<a href="#client_tls_obs">per-site</a> table, specify the "MUST"
-keyword and <a href="#client_tls_harden">harden</a> the certificate
-verification against DNS forgery. While the obsolete approach still
-works with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3
-and later
-should use the new TLS policy settings. </p>
+With the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "secure" security level. </p>
 
 <p> Examples: </p>
 
-<p> Secure-channel TLS without <a href="transport.5.html">transport(5)</a> table overrides: </p>
+<ul>
+
+<li> <p> Secure-channel TLS without <a href="transport.5.html">transport(5)</a> table overrides: </p>
 
 <p> The Postfix SMTP client will encrypt all traffic and verify the
 destination name
@@ -1408,18 +1284,14 @@ the first approach is more appropriate in most cases. <p>
 </pre>
 </blockquote>
 
-<p> Secure-channel TLS with <a href="transport.5.html">transport(5)</a> table overrides: <p>
+<li> <p> Secure-channel TLS with <a href="transport.5.html">transport(5)</a> table overrides: <p>
 
 <p> In this case traffic to <i>example.com</i> and its related domains
 is sent to a single logical gateway (to avoid a single point of failure,
 its name may resolve to one or more load-balancer addresses, or to the
 combined addresses of multiple physical hosts). All the physical hosts
 reachable via the gateway's IP addresses have the logical gateway name
-listed in their certificates. This secure-channel configuration can also
-be implemented via a <a href="#client_tls_harden">hardened</a> variant of
-the MUST policy in the obsolete <a href="#client_tls_obs">per-site</a>
-table. As stated above, this approach has the potential to mis-deliver
-email if the related domains change hands. </p>
+listed in their certificates. </p>
 
 <blockquote>
 <pre>
@@ -1438,35 +1310,7 @@ email if the related domains change hands. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2.9 and later syntax: </p>
-
-<p> <b>Note:</b> Avoid policy lookups with the bare hostname (for
-example, "tls.example.com").  Instead, use the destination (for
-example, "[tls.example.com]") as the <a
-href="#client_tls_obs">per-site</a> table lookup key (a recipient domain
-or MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>). With Postfix 2.3
-and later,
-do not use the obsolete <a href="#client_tls_obs">per-site</a> table;
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_cname_overrides_servername">smtp_cname_overrides_servername</a> = no
-    <a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> = /etc/postfix/CAfile.pem
-    <a href="postconf.5.html#transport_maps">transport_maps</a> = hash:/etc/postfix/transport
-    <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/transport:
-    example.com     <a href="smtp.8.html">smtp</a>:[tls.example.com]
-    example.co.uk   <a href="smtp.8.html">smtp</a>:[tls.example.com]
-    example.co.jp   <a href="smtp.8.html">smtp</a>:[tls.example.com]
-
-/etc/postfix/tls_per_site:
-    [tls.example.com]       MUST
-</pre>
-</blockquote>
+</ul>
 
 <h3><a name="client_logging"> Client-side TLS activity logging </a> </h3>
 
@@ -1778,9 +1622,9 @@ constraints on the sending and receiving sites that preclude ubiquitous
 deployment. One needs to manually configure this type of security for
 each destination domain, and in many cases implement non-default TLS
 <a href="#client_tls_policy">policy table</a> entries for additional
-domains hosted at a common secured destination. With Postfix 2.3, we
-make secure-channel configurations substantially easier to configure,
-but they will never be the norm. For the generic domain with which you
+domains hosted at a common secured destination. For these reasons
+secure-channel configurations
+will never be the norm. For the generic domain with which you
 have made no specific security arrangements, this security level is not
 a good fit. </p>
 
@@ -1790,7 +1634,7 @@ TLS use self-signed certificates or private CAs. This further limits
 the applicability of verified TLS on the public Internet. </p>
 
 <p> Historical note: while the documentation of these issues and many of the
-related features are new with Postfix 2.3, the issue was well
+related features were new with Postfix 2.3, the issue was well
 understood before Postfix 1.0, when Lutz J&auml;nicke was designing
 the first unofficial Postfix TLS patch. See his original post <a
 href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html</a>
@@ -1803,23 +1647,15 @@ uses indirect naming (via MX records) more frequently. </p>
 <h3> <a name="client_tls_policy"> TLS policy table </a>
 </h3>
 
-<p> The current TLS policy table was introduced with Postfix 2.3. For
-earlier releases, read the description of the obsolete Postfix 2.2 <a
-href="#client_tls_obs">per-site</a> table. </p>
-
 <p> A small fraction of servers offer STARTTLS but the negotiation
-consistently fails. With Postfix 2.3, so long as encryption is not
-enforced, the delivery is immediately retried with TLS disabled.  You no
-longer need to explicitly disable TLS for the problem destinations.
-As soon as their TLS software or configuration is repaired, encryption
-will be used. </p>
+consistently fails. As long as encryption is not mandatory, the
+Postfix SMTP client retries the delivery immediately with TLS
+disabled, without any need to explicitly disable TLS for the problem
+destinations. </p>
 
-<p> The new policy table is specified via the <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>
+<p> The policy table is specified via the <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>
 parameter. This lists optional lookup tables with the Postfix SMTP client
-TLS security policy by next-hop destination. When $<a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>
-is not empty, the obsolete <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> parameter is ignored
-(a warning is written to the logs if both parameter values are
-non-empty).  </p>
+TLS security policy by next-hop destination. </p>
 
 <p> The TLS policy table is indexed by the full next-hop destination,
 which is either the recipient domain, or the verbatim next-hop
@@ -1968,211 +1804,6 @@ table can render the "secure" level vulnerable to DNS forgery. Do not use
 the "hostname" strategy for <a href="#client_tls_secure">secure-channel</a>
 configurations in environments where DNS security is not assured. </p>
 
-<h3> <a name="client_tls_obs"> Obsolete per-site TLS policy support 
-</a> </h3>
-
-<p> This section describes an obsolete per-site TLS policy mechanism.
-Unlike the Postfix 2.3 <a href="#client_tls_policy">policy table</a>
-mechanism, this uses as a policy lookup key a potentially untrusted
-server hostname, and lacks control over what names can appear in
-server certificates.  Because of this, the obsolete mechanism is
-typically vulnerable to false DNS hostname information in MX or
-CNAME records.  These attacks can be eliminated only with great
-difficulty. The new <a href="#client_tls_policy">policy table</a>
-makes <a href="#client_tls_secure">secure-channel</a> configurations
-easier and provides more control over the cipher and protocol selection
-for sessions with mandatory encryption. </p>
-
-<p> Avoid policy lookups with the bare hostname.  Instead, use the
-full destination nexthop (enclosed in [] with a possible ":port"
-suffix) as the per-site table lookup key (a recipient domain or
-MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>).  With Postfix 2.3
-and later,
-use of the obsolete approach documented here is strongly discouraged:
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<p> Starting with Postfix 2.3, the underlying TLS enforcement levels are
-common to the obsolete per-site table and the new policy table. The
-<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> and <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>
-parameters control the TLS ciphers and protocols for mandatory
-encryption regardless of which table is used. The
-<a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> parameter determines the match strategy
-for the obsolete "MUST" keyword in the same way as for the "verify"
-level in the new policy. </p>
-
-<p> With Postfix &lt; 2.3, the obsolete <a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> parameter
-is also applied for opportunistic TLS sessions, and should be used with
-care, or not at all. Setting cipherlist restrictions that are incompatible
-with a remote SMTP server render that server unreachable, TLS handshakes
-are always attempted and always fail. </p>
-
-<p> When <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> is empty (default) and <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a>
-is not empty, the per-site table is searched for a policy that matches
-the following information:  </p>
-
-<blockquote>
-
-<dl>
-
-<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS
-name of the server that the Postfix SMTP client connects to; this
-name may be obtained from other DNS lookups, such as MX lookups or
-CNAME lookups. Use of the hostname lookup key is discouraged; always
-use the next-hop destination instead. </dd>
-
-<dt> next-hop destination </dt> <dd> This is normally the domain portion
-of the recipient address, but it may be overridden by information from
-the <a href="transport.5.html">transport(5)</a> table, from the <a href="postconf.5.html#relayhost">relayhost</a> parameter setting, or from
-the <a href="postconf.5.html#relay_transport">relay_transport</a> setting. When it is not the recipient domain, the
-next-hop destination can have the Postfix-specific form "<tt>[name]</tt>",
-"<tt>[name]:port</tt>", "<tt>name</tt>" or "<tt>name:port</tt>".  This is
-the recommended lookup key for per-site policy lookups (and incidentally
-for <a href="SASL_README.html#client_sasl">SASL password</a> lookups). </dd>
-
-</dl>
-
-</blockquote>
-
-<p> When both the hostname lookup and the next-hop lookup succeed,
-the host policy does not automatically override the next-hop policy.
-Instead, precedence is given to either the more specific or the
-more secure per-site policy as described below.  </p>
-
-<p> The <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> table uses a simple "<i>name whitespace
-value</i>" format. Specify host names or next-hop destinations on
-the left-hand side; no wildcards are allowed.  On the right hand
-side specify one of the following keywords:  </p>
-
-<blockquote>
-
-<dl>
-
-<dt> NONE </dt> <dd> No TLS. This overrides a less specific "MAY" lookup
-result from the alternate host or next-hop lookup key, and overrides
-the global <a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a>, <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a>, and <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>
-settings. </dd>
-
-<dt> MAY </dt> <dd> Opportunistic TLS. This has less precedence than
-a more specific result (including "NONE") from the alternate host or
-next-hop lookup key, and has less precedence than the more specific global
-"<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes" or "<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> = yes".  </dd>
-
-<dt> MUST_NOPEERMATCH </dt> <dd> Mandatory TLS encryption. This
-overrides a less secure "NONE" or a less specific "MAY" lookup result
-from the alternate host or next-hop lookup key, and overrides the global
-<a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a>, <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> and <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> settings.
-</dd>
-
-<dt> MUST </dt> <dd> Mandatory server certificate verification.
-This overrides a less secure "NONE" and "MUST_NOPEERMATCH" or a
-less specific "MAY" lookup result from the alternate host or next-hop
-lookup key, and overrides the global <a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a>, <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a>
-and <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> settings.  </dd>
-
-</dl>
-
-</blockquote>
-
-<p> The precedences between global (<a href="postconf.5.html">main.cf</a>) and per-site TLS
-policies can be summarized as follows: </p>
-
-<ul>
-
-<li> <p> When neither the remote SMTP server hostname nor the
-next-hop destination are found in the <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> table, the
-policy is based on <a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a>, <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> and
-<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>. Note: "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes" and
-"<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> = yes" imply "<a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> = yes". </p>
-
-<li> <p> When both hostname and next-hop destination lookups produce
-a result, the more specific per-site policy (NONE, MUST, etc)
-overrides the less specific one (MAY), and the more secure per-site
-policy (MUST, etc) overrides the less secure one (NONE).  </p>
-
-<li> <p> After the per-site policy lookups are combined, the result
-generally overrides the global policy. The exception is the less
-specific "MAY" per-site policy, which is overruled by the more
-specific global "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes" with server certificate
-verification as specified with the <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>
-parameter.  </p>
-
-</ul>
-
-<h3> <a name="client_tls_harden"> Closing a DNS loophole with 
-obsolete per-site TLS policies </a> </h3>
-
-<p> For a general discussion of TLS security for SMTP see <a
-href="#client_tls_limits">TLS limitations</a> above. What follows applies
-only to Postfix 2.2.9 and subsequent Postfix 2.2 patch levels. Do
-not use this approach with Postfix 2.3
-and later; instead see the instructions under <a
-href="#client_tls_secure">secure</a> server certificate verification. </p>
-
-<p> As long as no secure DNS lookup mechanism is available, false
-hostnames in MX or CNAME responses can change Postfix's notion of the
-server hostname that is used for TLS policy lookup and server certificate
-verification. Even with a perfect match between the server hostname and
-the server certificate, there is no guarantee that Postfix is connected
-to the right server.  To avoid this loophole, take all of the following
-steps: </p>
-
-<ol>
-
-<li> <p> Use a dedicated message delivery transport (for example,
-"securetls") as illustrated below. </p>
-
-<li> <p> Eliminate MX lookups. Specify local <a href="transport.5.html">transport(5)</a> table
-entries for sensitive domains with explicit securetls:[<i>mailhost</i>]
-or securetls:[<i>mailhost</i>]:<i>port</i> destinations (you can
-assure security of this table unlike DNS). This prevents false
-hostname information in DNS MX records from changing Postfix's
-notion of the server hostname that is used for TLS policy lookup
-and server certificate verification. The "securetls" transport is
-configured to enforce TLS with peername verification, and to disable
-the SMTP connection cache which could interfere with enforcement
-of <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> policies. </p>
-
-<li> <p> Disallow CNAME hostname overrides. In <a href="postconf.5.html">main.cf</a>, specify
-"<a href="postconf.5.html#smtp_cname_overrides_servername">smtp_cname_overrides_servername</a> = no". This prevents false hostname
-information in DNS CNAME records from changing the server hostname
-that Postfix uses for TLS policy lookup and server certificate
-verification. This feature requires Postfix 2.2.9 or later.  The
-default value is "no" starting with Postfix 2.3. </p>
-
-</ol>
-
-<p> Example: </p>
-
-<p> We give the <a href="postconf.5.html#default_transport">non-default</a>
-"securetls" transport an explicit <a href="master.5.html">master.cf</a> process limit, so that we
-don't raise its process limit when raising $<a href="postconf.5.html#default_process_limit">default_process_limit</a>. The
-total process limit for *all* transports should stay somewhat under 1024
-(the typical select() file descriptor limit); otherwise transports may
-be throttled under steady high load, compounding congestion.  It is not
-uncommon at high volume sites to set the default process limit to 500
-or more. </p>
-
-<p> We also default the "securetls" transport TLS security level to
-<a href="#client_tls_verify">MUST</a>, obviating the need for <a
-href="#client_tls_obs">per-site</a> table entries for secure-channel
-destinations. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#transport_maps">transport_maps</a> = hash:/etc/postfix/transport
-
-/etc/postfix/transport:
-    example.com         securetls:[tls.example.com]
-
-/etc/postfix/<a href="master.5.html">master.cf</a>:
-    securetls unix  -       -       n       -       100     smtp
-        -o <a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a>=yes
-        -o <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>=yes
-</pre>
-</blockquote>
-
 <h3> <a name="client_tls_discover"> Discovering servers that support
 TLS </a> </h3>
 
@@ -2601,10 +2232,7 @@ but don't require them from all clients. </p>
     <a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> =
        btree:/var/lib/postfix/smtpd_tls_session_cache
     <a href="postconf.5.html#tls_random_source">tls_random_source</a> = dev:/dev/urandom
-    # Postfix 2.3 and later
     <a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = may
-    # Obsolete, but still supported
-    <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> = yes
 </pre>
 </blockquote>
 
index 343e424e1560f09184c0c674b6a75773140e2c17..48f59f2ffa72849eaaa0b69c499f40da1fbbd199 100644 (file)
@@ -551,13 +551,13 @@ mail deliveries.  </p>
 
 <p> The <a href="postconf.5.html#default_process_limit">default_process_limit</a> configuration parameter gives direct
 control over how many daemon processes Postfix will run.  As of
-Postfix 2.0 the default limit is 100 smtp client processes, 100
-smtp server processes, and so on.  This may overwhelm systems with
+Postfix 2.0 the default limit is 100 SMTP client processes, 100
+SMTP server processes, and so on.  This may overwhelm systems with
 little memory, as well as networks with low bandwidth.  </p>
 
 <p> You can change the global process limit by specifying a
 non-default <a href="postconf.5.html#default_process_limit">default_process_limit</a> in the <a href="postconf.5.html">main.cf</a> file. For example,
-to run up to 10 smtp client processes, 10 smtp server processes,
+to run up to 10 SMTP client processes, 10 SMTP server processes,
 and so on: </p>
 
 <blockquote>
index 6199868361b379215eb85cd93fe1d5ee8fb596cd..77544f5adffee6b774f4b3959b3069a45ec7cda0 100644 (file)
@@ -132,6 +132,8 @@ Per-client/user/etc. access </a>
 
 <li> <a href="LDAP_README.html"> LDAP Howto  </a>
 
+<li> <a href="MEMCACHE_README.html"> Memcache Howto  </a>
+
 <li> <a href="MYSQL_README.html"> MySQL Howto  </a>
 
 <li> <a href="PCRE_README.html"> PCRE Howto </a>
diff --git a/postfix/html/memcache_table.5.html b/postfix/html/memcache_table.5.html
new file mode 100644 (file)
index 0000000..ddf5db8
--- /dev/null
@@ -0,0 +1,178 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+<title> Postfix manual - memcache_table(5) </title>
+</head> <body> <pre>
+MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
+
+<b>NAME</b>
+       memcache_table - Postfix memcache client configuration
+
+<b>SYNOPSIS</b>
+       <b>postmap -q "</b><i>string</i><b>" <a href="memcache_table.5.html">memcache</a>:/etc/postfix/filename</b>
+
+       <b>postmap -q - <a href="memcache_table.5.html">memcache</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
+
+<b>DESCRIPTION</b>
+       The  Postfix  mail system uses optional tables for address
+       rewriting or mail routing. These tables are usually in <b>dbm</b>
+       or <b>db</b> format.
+
+       Alternatively,  lookup tables can be specified as memcache
+       instances.  In order to use  memcache  lookups,  define  a
+       memcache source as a lookup table in <a href="postconf.5.html">main.cf</a>, for example:
+
+           <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="memcache_table.5.html">memcache</a>:/etc/postfix/memcache-aliases.cf
+
+       The file  /etc/postfix/memcache-aliases.cf  has  the  same
+       format  as  the  Postfix  <a href="postconf.5.html">main.cf</a>  file, and specifies the
+       parameters described below.
+
+       The Postfix memcache client supports the lookup and update
+       operations.
+
+<b>MEMCACHE PARAMETERS</b>
+       <b>hosts (default: localhost:11211)</b>
+              The  memcache servers that Postfix will try to con-
+              nect to.  Specify a hostname or address, optionally
+              followed  by  ":"  and  a  port name or number. The
+              default port is 11211.  Examples:
+
+                  hosts = memcache01.example.com
+                      memcache02.example.com
+
+       <b>key_format (default: %s)</b>
+              Format of the lookup and update  keys  in  memcache
+              queries.   By  default,  these  are the same as the
+              lookup and update keys that are given to the  Post-
+              fix memcache client.
+
+              When  the  same  memcache database is used to cache
+              information from multiple tables, you can  use  the
+              <b>key_format</b>  feature  to  avoid  name  collisions by
+              prepending a fixed string.  Examples:
+
+                  key_format = aliases:%s
+                  key_format = access:%s
+
+              The <b>key_format</b> parameter supports the following '%'
+              expansions:
+
+              <b>%%</b>     This is replaced by a literal '%' character.
+
+              <b>%s</b>     This is  replaced  by  the  memcache  client
+                     input key.
+
+              <b>%u</b>     When the input key is an address of the form
+                     user@domain,  <b>%u</b>  is  replaced  by  the  SQL
+                     quoted  local  part  of the address.  Other-
+                     wise, <b>%u</b> is replaced by  the  entire  search
+                     string.  If the localpart is empty, a lookup
+                     is  silently  suppressed  and   returns   no
+                     results  (an  update is skipped with a warn-
+                     ing).
+
+              <b>%d</b>     When the input key is an address of the form
+                     user@domain,  <b>%d</b>  is  replaced by the domain
+                     part of the address.  Otherwise, a lookup is
+                     silently  suppressed  and returns no results
+                     (an update is skipped with a warning).
+
+              <b>%[SUD]</b> The  upper-case  equivalents  of  the  above
+                     expansions  behave in the <b>key_format</b> parame-
+                     ter identically to their lower-case counter-
+                     parts.
+
+              <b>%[1-9]</b> The  patterns %1, %2, ... %9 are replaced by
+                     the corresponding most significant component
+                     of  the input key's domain. If the input key
+                     is <i>user@mail.example.com</i>, then %1 is <b>com</b>, %2
+                     is  <b>example</b> and %3 is <b>mail</b>. If the input key
+                     is  unqualified  or  does  not  have  enough
+                     domain  components to satisfy all the speci-
+                     fied patterns, a  lookup  is  silently  sup-
+                     pressed and returns no results (an update is
+                     skipped with a warning).
+
+       <b>domain (default: no domain list)</b>
+              This  feature  can  significantly  reduce  database
+              server load.  Specify a list of domain names, paths
+              to files, or dictionaries.   When  specified,  only
+              fully  qualified  search  keys  with  a *non-empty*
+              localpart and a matching domain  are  eligible  for
+              lookup  or update: bare 'user' lookups, bare domain
+              lookups and "@domain" lookups are silently  skipped
+              (updates are skipped with a warning).  Example:
+
+                  domain = example.com, hash:/etc/postfix/searchdomains
+
+       <b>flags (default: 0)</b>
+              Optional  flags  that should be stored along with a
+              memcache update.
+
+       <b>ttl (default: 604800)</b>
+              The expiration time in seconds of memcache updates.
+              The default is one week.
+
+              When  using  memcache  tables with <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or
+              <a href="verify.8.html"><b>verify</b>(8)</a>, specify a zero  *_cache_cleanup_interval
+              value,  and specify the largest <a href="postscreen.8.html"><b>postscreen</b>(8)</a> *_ttl
+              value or <a href="verify.8.html"><b>verify</b>(8)</a> *_expire_time value as the  mem-
+              cache map's <b>ttl</b> value.
+
+              Note: according to memcache protocol documentation,
+              a value greater  than  30  days  (2592000  seconds)
+              specifies  absolute  UNIX  time. Smaller values are
+              relative to the time of the update.
+
+<b>BUGS</b>
+       The Postfix memcache client is based on libmemcache, which
+       will  terminate  its  process after a memcache server goes
+       down. To avoid this, set  up  redundant  memcache  servers
+       that have no common source of failure.
+
+       The  Postfix  memcache client cannot be used for security-
+       sensitive tables such as  <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>  (these  may  contain
+       "<i>|command</i>   and   "<i>/file/name</i>"   destinations),   or  <b><a href="postconf.5.html#virtual_uid_maps">vir</a>-</b>
+       <b><a href="postconf.5.html#virtual_uid_maps">tual_uid_maps</a></b> and  <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b>  (these  specify  UNIX
+       process  privileges).   In a typical deployment a memcache
+       database is shared via a  TCP  socket,  and  is  therefore
+       writable  not only by Postfix, but by any process that can
+       talk to the memcache server.
+
+       The Postfix memcache client requires additional configura-
+       tion  when  used with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> and <a href="verify.8.html"><b>verify</b>(8)</a> dae-
+       mons.  For details see the <b>ttl</b> parameter discussion at the
+       end of the MEMCACHE PARAMETERS section in this document.
+
+       The Postfix memcache client is supported only with libmem-
+       cache version 1.4.0.  Some libmemcache features are  docu-
+       mented  by  reading  libmemcache  source  code,  instead a
+       proper API.
+
+<b>SEE ALSO</b>
+       <a href="postmap.1.html">postmap(1)</a>, Postfix lookup table manager
+       <a href="postconf.5.html">postconf(5)</a>, configuration parameters
+
+<b>README FILES</b>
+       <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
+       <a href="MEMCACHE_README.html">MEMCACHE_README</a>, Postfix memcache client guide
+
+<b>LICENSE</b>
+       The  Secure  Mailer  license must be distributed with this
+       software.
+
+<b>HISTORY</b>
+       The first memcache client for Postfix was written by  Omar
+       Kilani.   Besides  being  implemented on libmemcache, this
+       implementation bears no resemblance to his work.
+
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       IBM T.J. Watson Research
+       P.O. Box 704
+       Yorktown Heights, NY 10598, USA
+
+                                                             MEMCACHE_TABLE(5)
+</pre> </body> </html>
index 1d1948e759f774ac68adc04ffe03619f3135e90a..cf4086fc7802d0cea9a378e3f2e662f39ff364e5 100644 (file)
@@ -193,127 +193,131 @@ POSTCONF(1)                                                        POSTCONF(1)
                      Perform  lookups  using  the  LDAP protocol.
                      This is described in <a href="ldap_table.5.html"><b>ldap_table</b>(5)</a>.
 
+              <b>memcache</b> (read-write)
+                     Perform lookups using the memcache protocol.
+                     This is described in <a href="memcache_table.5.html"><b>memcache_table</b>(5)</a>.
+
               <b>mysql</b> (read-only)
-                     Perform lookups using  the  MYSQL  protocol.
+                     Perform  lookups  using  the MYSQL protocol.
                      This is described in <a href="mysql_table.5.html"><b>mysql_table</b>(5)</a>.
 
               <b>pcre</b> (read-only)
                      A lookup table based on Perl Compatible Reg-
-                     ular  Expressions.  The   file   format   is
+                     ular   Expressions.   The   file  format  is
                      described in <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
               <b>pgsql</b> (read-only)
-                     Perform  lookups using the PostgreSQL proto-
+                     Perform lookups using the PostgreSQL  proto-
                      col. This is described in <a href="pgsql_table.5.html"><b>pgsql_table</b>(5)</a>.
 
               <b>proxy</b> (read-only)
-                     A lookup table that is implemented  via  the
-                     Postfix  <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table name
+                     A  lookup  table that is implemented via the
+                     Postfix <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table  name
                      syntax is <i>type</i><b>:</b><i>name</i>.
 
               <b>regexp</b> (read-only)
                      A lookup table based on regular expressions.
-                     The  file  format is described in <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
+                     The file format is described  in  <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
                      <a href="regexp_table.5.html"><b>ble</b>(5)</a>.
 
               <b>sdbm</b>   An indexed file type based on hashing.  This
-                     is  available  on  systems  with support for
+                     is available on  systems  with  support  for
                      SDBM databases.
 
               <b>sqlite</b> (read-only)
-                     Perform lookups from SQLite database  files.
+                     Perform  lookups from SQLite database files.
                      This is described in <a href="sqlite_table.5.html"><b>sqlite_table</b>(5)</a>.
 
               <b>static</b> (read-only)
-                     A  table  that  always  returns  its name as
-                     lookup result.  For  example,  <b><a href="DATABASE_README.html#types">static</a>:foobar</b>
-                     always  returns  the string <b>foobar</b> as lookup
+                     A table that  always  returns  its  name  as
+                     lookup  result.  For  example, <b><a href="DATABASE_README.html#types">static</a>:foobar</b>
+                     always returns the string <b>foobar</b>  as  lookup
                      result.
 
               <b>tcp</b> (read-only)
                      Perform lookups using a simple request-reply
-                     protocol  that is described in <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
+                     protocol that is described in  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
 
               <b>texthash</b> (read-only)
-                     Produces similar  results  as  hash:  files,
+                     Produces  similar  results  as  hash: files,
                      except  that  you  don't  need  to  run  the
-                     <a href="postmap.1.html"><b>postmap</b>(1)</a> command before you  can  use  the
-                     file,  and  that  it does not detect changes
+                     <a href="postmap.1.html"><b>postmap</b>(1)</a>  command  before  you can use the
+                     file, and that it does  not  detect  changes
                      after the file is read.
 
               <b>unix</b> (read-only)
-                     A limited way to query the UNIX  authentica-
+                     A  limited way to query the UNIX authentica-
                      tion  database.  The  following  tables  are
                      implemented:
 
                      <b>unix:passwd.byname</b>
-                            The table is the UNIX password  data-
-                            base.  The  key is a login name.  The
-                            result is a password  file  entry  in
+                            The  table is the UNIX password data-
+                            base. The key is a login  name.   The
+                            result  is  a  password file entry in
                             <b>passwd</b>(5) format.
 
                      <b>unix:group.byname</b>
                             The table is the UNIX group database.
-                            The key is a group name.  The  result
-                            is  a  group  file  entry in <b>group</b>(5)
+                            The  key is a group name.  The result
+                            is a group  file  entry  in  <b>group</b>(5)
                             format.
 
-              Other table types may exist depending on how  Post-
+              Other  table types may exist depending on how Post-
               fix was built.
 
-       <b>-M</b>     Show  <a href="master.5.html"><b>master.cf</b></a>  file  contents  instead of <a href="postconf.5.html"><b>main.cf</b></a>
-              file contents.  Specify <b>-Mf</b> to fold long lines  for
+       <b>-M</b>     Show <a href="master.5.html"><b>master.cf</b></a> file  contents  instead  of  <a href="postconf.5.html"><b>main.cf</b></a>
+              file  contents.  Specify <b>-Mf</b> to fold long lines for
               human readability.
 
               If <i>service ...</i> is specified, only the matching ser-
-              vices will be output. For  example,  "<b>postconf  -Mf</b>
-              <b>inet</b>"  will  output all services that listen on the
+              vices  will  be  output. For example, "<b>postconf -Mf</b>
+              <b>inet</b>" will output all services that listen  on  the
               network.
 
-              Specify zero or more arguments, each  with  a  <i>ser-</i>
-              <i>vice-type</i>  name (<b>inet</b>, <b>unix</b>, <b>fifo</b>, or <b>pass</b>) or with
-              a <i>service-name.service-type</i>  pair,  where  <i>service-</i>
+              Specify  zero  or  more arguments, each with a <i>ser-</i>
+              <i>vice-type</i> name (<b>inet</b>, <b>unix</b>, <b>fifo</b>, or <b>pass</b>) or  with
+              a  <i>service-name.service-type</i>  pair,  where <i>service-</i>
               <i>name</i> is the first field of a <a href="master.5.html">master.cf</a> entry.
 
-              This  feature  is  available  with  Postfix 2.9 and
+              This feature is  available  with  Postfix  2.9  and
               later.
 
-       <b>-n</b>     Print <a href="postconf.5.html"><b>main.cf</b></a> parameter settings that  are  explic-
-              itly  specified  in  <a href="postconf.5.html"><b>main.cf</b></a>.   Specify <b>-nf</b> to fold
-              long lines for human readability (Postfix  2.9  and
+       <b>-n</b>     Print  <a href="postconf.5.html"><b>main.cf</b></a>  parameter settings that are explic-
+              itly specified in <a href="postconf.5.html"><b>main.cf</b></a>.   Specify  <b>-nf</b>  to  fold
+              long  lines  for human readability (Postfix 2.9 and
               later).
 
        <b>-t</b> [<i>template</i><b>_</b><i>file</i>]
-              Display  the templates for text that appears at the
-              beginning of  delivery  status  notification  (DSN)
+              Display the templates for text that appears at  the
+              beginning  of  delivery  status  notification (DSN)
               messages, without expanding $<b>name</b> expressions.
 
-              To  override the built-in templates, specify a tem-
-              plate file name at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a>  com-
-              mand  line,  or specify a file name in <a href="postconf.5.html"><b>main.cf</b></a> with
+              To override the built-in templates, specify a  tem-
+              plate  file name at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
+              mand line, or specify a file name in  <a href="postconf.5.html"><b>main.cf</b></a>  with
               the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.
 
               To force selection of the built-in templates, spec-
-              ify  an empty template file name on the <a href="postconf.1.html"><b>postconf</b>(1)</a>
+              ify an empty template file name on the  <a href="postconf.1.html"><b>postconf</b>(1)</a>
               command line (in shell language: "").
 
-              This feature is  available  with  Postfix  2.3  and
+              This  feature  is  available  with  Postfix 2.3 and
               later.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple <b>-v</b> options  make  the  software  increasingly
+              tiple  <b>-v</b>  options  make  the software increasingly
               verbose.
 
-       <b>-#</b>     Edit  the  <a href="postconf.5.html"><b>main.cf</b></a>  configuration file, and comment
+       <b>-#</b>     Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration  file,  and  comment
               out the parameters given on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
-              line,  so  that  those  parameters  revert to their
-              default values.  The file is copied to a  temporary
-              file  then  renamed  into place.  Specify a list of
+              line, so that  those  parameters  revert  to  their
+              default  values.  The file is copied to a temporary
+              file then renamed into place.  Specify  a  list  of
               parameter names, not <i>name</i>=<i>value</i> pairs.  There is no
-              <a href="postconf.1.html"><b>postconf</b>(1)</a>  command  to perform the reverse opera-
+              <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the  reverse  opera-
               tion.
 
-              This feature is  available  with  Postfix  2.6  and
+              This  feature  is  available  with  Postfix 2.6 and
               later.
 
 <b>DIAGNOSTICS</b>
@@ -324,18 +328,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               Directory with Postfix configuration files.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant
        to this program.
 
-       The text below provides  only  a  parameter  summary.  See
+       The  text  below  provides  only  a parameter summary. See
        <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix <a href="postconf.5.html">main.cf</a> and
+              The default location of  the  Postfix  <a href="postconf.5.html">main.cf</a>  and
               <a href="master.5.html">master.cf</a> configuration files.
 
        <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a> (empty)</b>
-              Pathname of a configuration file with  bounce  mes-
+              Pathname  of  a configuration file with bounce mes-
               sage templates.
 
 <b>FILES</b>
@@ -351,7 +355,7 @@ POSTCONF(1)                                                        POSTCONF(1)
        <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
 
 <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 36cdfa5b27b3205a5851c7d584b8600bf7edb684..4397bd7c3f14b6abc852222a4d1b9abb3f6e1bb5 100644 (file)
@@ -155,6 +155,8 @@ the following convention:  </p>
 
 <li> <a href="ldap_table.5.html">ldap_table(5)</a>, Postfix LDAP client 
 
+<li> <a href="memcache_table.5.html">memcache_table(5)</a>, Postfix memcache client 
+
 <li> <a href="mysql_table.5.html">mysql_table(5)</a>, Postfix MYSQL client 
 
 <li> <a href="nisplus_table.5.html">nisplus_table(5)</a>, Postfix NIS+ client 
index c4bb73a256ae936e90c23b15f47423abd3251264..b62e5a8b17fc049fbaedd5d56d15095bdccf29fa 100644 (file)
@@ -296,6 +296,7 @@ POSTFIX(1)                                                          POSTFIX(1)
        Table lookup mechanisms:
        <a href="cidr_table.5.html">cidr_table(5)</a>, Associate CIDR pattern with value
        <a href="ldap_table.5.html">ldap_table(5)</a>, Postfix LDAP client
+       <a href="memcache_table.5.html">memcache_table(5)</a>, Postfix memcache client
        <a href="mysql_table.5.html">mysql_table(5)</a>, Postfix MYSQL client
        <a href="nisplus_table.5.html">nisplus_table(5)</a>, Postfix NIS+ client
        <a href="pcre_table.5.html">pcre_table(5)</a>, Associate PCRE pattern with value
index a49832868a32d3b4c2d011b44cd533f0a325eb50..4a5dfc560a1d6b23a6662ba1e0b58cdd85f7815f 100644 (file)
@@ -157,11 +157,11 @@ POSTQUEUE(1)                                                      POSTQUEUE(1)
 
        Available in Postfix version 2.2 and later:
 
-       <b><a href="postconf.5.html#authorized_flush_users">authorized_flush_users</a> (static:anyone)</b>
+       <b><a href="postconf.5.html#authorized_flush_users">authorized_flush_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
               List of users  who  are  authorized  to  flush  the
               queue.
 
-       <b><a href="postconf.5.html#authorized_mailq_users">authorized_mailq_users</a> (static:anyone)</b>
+       <b><a href="postconf.5.html#authorized_mailq_users">authorized_mailq_users</a> (<a href="DATABASE_README.html#types">static</a>:anyone)</b>
               List of users who are authorized to view the queue.
 
 <b>FILES</b>
index 912ace4099674fbe9ce521f9cb799da8b6808084..c8a80e53bcdb12aae7746c918c6a888a8fed4f57 100644 (file)
@@ -16,7 +16,8 @@ COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
 CONFIG = man5/access.5 man5/aliases.5 man5/canonical.5 man5/relocated.5 \
        man5/transport.5 man5/virtual.5 man5/pcre_table.5 man5/regexp_table.5 \
        man5/cidr_table.5 man5/tcp_table.5 man5/header_checks.5 \
-       man5/body_checks.5 man5/ldap_table.5 man5/mysql_table.5 \
+       man5/body_checks.5 man5/ldap_table.5 man5/memcache_table.5 \
+       man5/mysql_table.5 \
        man5/pgsql_table.5 man5/master.5 man5/nisplus_table.5 \
        man5/generic.5 man5/bounce.5 man5/postfix-wrapper.5 \
        man5/sqlite_table.5
@@ -276,6 +277,9 @@ man5/ldap_table.5: ../proto/ldap_table
 man5/master.5: ../proto/master
        ../mantools/srctoman - $? >$@
 
+man5/memcache_table.5: ../proto/memcache_table
+       ../mantools/srctoman - $? >$@
+
 man5/mysql_table.5: ../proto/mysql_table
        ../mantools/srctoman - $? >$@
 
index 3ad16176120889e33bad9e5ee0f4a8ab74ae926b..c2a83503fd69f9679471f319d5ac0ae3467f430c 100644 (file)
@@ -181,6 +181,9 @@ when a process terminates.
 .IP "\fBldap\fR (read-only)"
 Perform lookups using the LDAP protocol. This is described
 in \fBldap_table\fR(5).
+.IP "\fBmemcache\fR (read-write)"
+Perform lookups using the memcache protocol. This is described
+in \fBmemcache_table\fR(5).
 .IP "\fBmysql\fR (read-only)"
 Perform lookups using the MYSQL protocol. This is described
 in \fBmysql_table\fR(5).
index 95a31350682555d84c56fd0cd6461c1ad6b54935..3cf7b9cae98e4edd7f08d15e4d9433b9d3482da1 100644 (file)
@@ -254,6 +254,7 @@ virtual(5), Postfix virtual aliasing
 Table lookup mechanisms:
 cidr_table(5), Associate CIDR pattern with value
 ldap_table(5), Postfix LDAP client
+memcache_table(5), Postfix memcache client
 mysql_table(5), Postfix MYSQL client
 nisplus_table(5), Postfix NIS+ client
 pcre_table(5), Associate PCRE pattern with value
diff --git a/postfix/man/man5/memcache_table.5 b/postfix/man/man5/memcache_table.5
new file mode 100644 (file)
index 0000000..3e617b8
--- /dev/null
@@ -0,0 +1,188 @@
+.TH MEMCACHE_TABLE 5 
+.ad
+.fi
+.SH NAME
+memcache_table
+\-
+Postfix memcache client configuration
+.SH "SYNOPSIS"
+.na
+.nf
+\fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/filename\fR
+
+\fBpostmap -q - memcache:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+.SH DESCRIPTION
+.ad
+.fi
+The Postfix mail system uses optional tables for address
+rewriting or mail routing. These tables are usually in
+\fBdbm\fR or \fBdb\fR format.
+
+Alternatively, lookup tables can be specified as memcache
+instances.  In order to use memcache lookups, define a
+memcache source as a lookup table in main.cf, for example:
+
+.nf
+    virtual_alias_maps = memcache:/etc/postfix/memcache-aliases.cf
+.fi
+
+The file /etc/postfix/memcache-aliases.cf has the same
+format as the Postfix main.cf file, and specifies the
+parameters described below.
+
+The Postfix memcache client supports the lookup and update
+operations.
+.SH "MEMCACHE PARAMETERS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBhosts (default: localhost:11211)\fR"
+The memcache servers that Postfix will try to connect to.
+Specify a hostname or address, optionally followed by ":"
+and a port name or number. The default port is 11211.
+Examples:
+
+.nf
+    hosts = memcache01.example.com
+        memcache02.example.com
+.fi
+.IP "\fBkey_format (default: %s)\fB"
+Format of the lookup and update keys in memcache queries.
+By default, these are the same as the lookup and update
+keys that are given to the Postfix memcache client.
+
+When the same memcache database is used to cache information
+from multiple tables, you can use the \fBkey_format\fR
+feature to avoid name collisions by prepending a fixed
+string.  Examples:
+
+.nf
+    key_format = aliases:%s
+    key_format = access:%s
+.fi
+
+The \fBkey_format\fR parameter supports the following '%'
+expansions:
+.RS
+.IP "\fB\fB%%\fR\fR"
+This is replaced by a literal '%' character.
+.IP "\fB\fB%s\fR\fR"
+This is replaced by the memcache client input key.
+.IP "\fB\fB%u\fR\fR"
+When the input key is an address of the form user@domain,
+\fB%u\fR is replaced by the SQL quoted local part of the
+address.  Otherwise, \fB%u\fR is replaced by the entire
+search string.  If the localpart is empty, a lookup is
+silently suppressed and returns no results (an update is
+skipped with a warning).
+.IP "\fB\fB%d\fR\fR"
+When the input key is an address of the form user@domain,
+\fB%d\fR is replaced by the domain part of the address.
+Otherwise, a lookup is silently suppressed and returns no
+results (an update is skipped with a warning).
+.IP "\fB\fB%[SUD]\fR\fR"
+The upper-case equivalents of the above expansions behave
+in the \fBkey_format\fR parameter identically to their
+lower-case counter-parts.
+.IP "\fB\fB%[1-9]\fR\fR"
+The patterns %1, %2, ... %9 are replaced by the corresponding
+most significant component of the input key's domain. If
+the input key is \fIuser@mail.example.com\fR, then %1 is
+\fBcom\fR, %2 is \fBexample\fR and %3 is \fBmail\fR. If the
+input key is unqualified or does not have enough domain
+components to satisfy all the specified patterns, a lookup
+is silently suppressed and returns no results (an update
+is skipped with a warning).
+.RE
+.IP "\fBdomain (default: no domain list)\fR"
+This feature can significantly reduce database server load.
+Specify a list of domain names, paths to files, or dictionaries.
+When specified, only fully qualified search keys with a
+*non-empty* localpart and a matching domain are eligible
+for lookup or update: bare 'user' lookups, bare domain
+lookups and "@domain" lookups are silently skipped (updates
+are skipped with a warning).  Example:
+
+.nf
+    domain = example.com, hash:/etc/postfix/searchdomains
+.fi
+.IP "\fBflags (default: 0)\fR"
+Optional flags that should be stored along with a memcache
+update.
+.IP "\fBttl (default: 604800)\fR"
+The expiration time in seconds of memcache updates.
+The default is one week.
+
+When using memcache tables with \fBpostscreen\fR(8) or
+\fBverify\fR(8), specify a zero *_cache_cleanup_interval
+value, and specify the largest \fBpostscreen\fR(8) *_ttl
+value or \fBverify\fR(8) *_expire_time value as the memcache
+map's \fBttl\fR value.
+
+Note: according to memcache protocol documentation, a value
+greater than 30 days (2592000 seconds) specifies absolute UNIX
+time. Smaller values are relative to the time of the update.
+.SH BUGS
+.ad
+.fi
+The Postfix memcache client is based on libmemcache, which
+will terminate its process after a memcache server goes
+down. To avoid this, set up redundant memcache servers that
+have no common source of failure.
+
+The Postfix memcache client cannot be used for security-sensitive
+tables such as \fBalias_maps\fR (these may contain
+"\fI|command\fR and "\fI/file/name\fR" destinations), or
+\fBvirtual_uid_maps\fR and \fBvirtual_gid_maps\fR (these
+specify UNIX process privileges).  In a typical deployment
+a memcache database is shared via a TCP socket, and is
+therefore writable not only by Postfix, but by any process
+that can talk to the memcache server.
+
+The Postfix memcache client requires additional configuration
+when used with the \fBpostscreen\fR(8) and \fBverify\fR(8)
+daemons.  For details see the \fBttl\fR parameter discussion
+at the end of the MEMCACHE PARAMETERS section in this
+document.
+
+The Postfix memcache client is supported only with libmemcache
+version 1.4.0.  Some libmemcache features are documented
+by reading libmemcache source code, instead a proper API.
+.SH "SEE ALSO"
+.na
+.nf
+postmap(1), Postfix lookup table manager
+postconf(5), configuration parameters
+.SH "README FILES"
+.na
+.nf
+.ad
+.fi
+Use "\fBpostconf readme_directory\fR" or
+"\fBpostconf html_directory\fR" to locate this information.
+.na
+.nf
+DATABASE_README, Postfix lookup table overview
+MEMCACHE_README, Postfix memcache client guide
+.SH "LICENSE"
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH "HISTORY"
+.na
+.nf
+.ad
+.fi
+The first memcache client for Postfix was written by Omar
+Kilani.  Besides being implemented on libmemcache, this
+implementation bears no resemblance to his work.
+.SH "AUTHOR(S)"
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
index dfefd72b0421a16e25cf4bbe40b97c274a4eb715..a573a9244214c948cab252130adc036b25e73eee 100755 (executable)
@@ -3,5 +3,5 @@
 for i in $*
 do
        echo === $i ===
-       dehtml $i | double
+       dehtml $i | tr A-Z a-z | double
 done
index 5831ffe25548149846007f495c858e2c735b0ab4..8f3b7f274b153f31adf63529351290bda1c98577 100755 (executable)
@@ -776,6 +776,7 @@ while (<>) {
     s/[<bB>]*gener[-<\/bB>]*\n* *[<bB>]*ic[<\/bB>]*\(5\)/<a href="generic.5.html">$&<\/a>/g;
     s/[<bB>]*ldap[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="ldap_table.5.html">$&<\/a>/g;
     s/[<bB>]*mas[-<\/bB>]*\n* *[<bB>]*ter[<\/bB>]*\(5\)/<a href="master.5.html">$&<\/a>/g;
+    s/[<bB>]*memcache[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="memcache_table.5.html">$&<\/a>/g;
     s/[<bB>]*mysql[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="mysql_table.5.html">$&<\/a>/g;
     s/[<bB>]*nisplus[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="nisplus_table.5.html">$&<\/a>/g;
     s/[<bB>]*pcre[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="pcre_table.5.html">$&<\/a>/g;
@@ -788,7 +789,7 @@ while (<>) {
     s/[<bB>]*scache[<\/bB>]*\(8\)/<a href="scache.8.html">$&<\/a>/g;
     s/[<bB>]*sqlite[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="sqlite_table.5.html">$&<\/a>/g;
     s/[<bB>]*trans[-<\/bB>]*\n*[ <bB>]*port[<\/bB>]*\(5\)/<a href="transport.5.html">$&<\/a>/g;
-    s/[<bB>]*verify[<\/bB>]*\(8\)/<a href="verify.8.html">$&<\/a>/g;
+    s/[<bB>]*ver[-<\/bB>]*\n*[ <bB>]*ify[<\/bB>]*\(8\)/<a href="verify.8.html">$&<\/a>/g;
     s/[<bB>]*vir[-<\/bB>]*\n*[ <bB>]*tual[<\/bB>]*\(5\)/<a href="virtual.5.html">$&<\/a>/g;
     s/[<bB>]*vir[-<\/bB>]*\n*[ <bB>]*tual[<\/bB>]*\(8\)/<a href="virtual.8.html">$&<\/a>/g;
     s/[<bB>]*cidr_ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="cidr_table.5.html">$&<\/a>/g;
@@ -1064,6 +1065,7 @@ while (<>) {
     s/\b(static):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
     s/\b(tcp):/<a href="tcp_table.5.html">$1<\/a>:/g;
     s/\b(texthash):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
+    s/\b(memcache):/<a href="memcache_table.5.html">$1<\/a>:/g;
 
     # Do nice links for smtp:host:port etc.
 
index e1541a985a1c79cdb2d7fdc9a8c970a6e718187f..1b0237b3771deeb714c7844a0e9d0d4b6b1a7747 100644 (file)
@@ -310,6 +310,11 @@ a process terminates. </dd>
 <dd> Perform lookups using the LDAP protocol. Configuration details
 are given in the ldap_table(5). </dd>
 
+<dt> <b>memcache</b> (read-write) </dt>
+
+<dd> Perform memcache database lookups or updates. Configuration
+details are given in memcache_table(5). </dd>
+
 <dt> <b>mysql</b> (read-only) </dt>
 
 <dd> Perform MySQL database lookups. Configuration details are given
diff --git a/postfix/proto/MEMCACHE_README.html b/postfix/proto/MEMCACHE_README.html
new file mode 100644 (file)
index 0000000..fbf9006
--- /dev/null
@@ -0,0 +1,113 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix memcache client Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix memcache client Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p>The Postfix memcache client type allows you to hook up Postfix to
+a memcache server. This implementation supports multiple memcache
+servers for redundancy, and multiple memcache clients that you can
+use for different table lookups. The Postfix memcache client
+supports both lookup and update operations. </p>
+
+<p> Typically, a memcache map is used to reduce query load on a
+database server, or to share a low-latency database among different
+Postfix instances. </p>
+
+<h2>Limitations</h2>
+
+<ul>
+
+<li> <p> The Postfix memcache client is based on libmemcache, which
+will terminate its process after a memcache server goes down. To
+avoid this, set up redundant memcache servers that have no common
+source of failure. </p>
+
+<li> <p> The Postfix memcache client cannot be used for security-sensitive
+tables such as <tt>alias_maps</tt> (these may contain "<tt>|command</tt>"
+and "<tt>/file/name</tt>" destinations), or <tt>virtual_uid_maps</tt>
+and <tt>virtual_gid_maps</tt> (these specify UNIX process privileges).
+Typically, a memcache database is shared via a TCP socket, and is
+writable not only by Postfix, but by any process that can talk to
+the memcache server. </p>
+
+<li> <p> The Postfix memcache client requires additional configuration
+when used with the postscreen(8) and verify(8) daemons. For details
+see the <tt>ttl</tt> parameter discussion in the memcache_table(5)
+manual page. </p>
+
+<li> <p> The Postfix memcache client is supported only with libmemcache
+version 1.4.0.  Some libmemcache features are documented by reading
+libmemcache source code, instead of a proper API.  </p>
+
+</ul>
+
+<h2>Building Postfix with memcache support</h2>
+
+<p>To build Postfix with memcache client support, specify
+<tt>-DHAS_MEMCACHE</tt>, the location of the libmemcache include
+files, and the location of the libmemcache object library. </p>
+
+<p> For example: </p>
+
+<blockquote>
+<pre>
+% make -f Makefile.init makefiles \
+        'CCARGS=-DHAS_MEMCACHE -I/usr/local/include' \
+       'AUXLIBS=-L/usr/local/lib -lmemcache'
+</pre>
+</blockquote>
+
+<p> Then run 'make'.  </p>
+
+<p> If the build fails with "<tt>undefined reference to `mcm_buf_len'</tt>"
+(and with a similar error message for <tt>mcm_buf_remain_off</tt>),
+then you need to edit libmemcache source code. </p>
+
+<p> The following instructions apply to libmemcache 1.4.0.rc2. </p>
+
+<ul>
+
+<li> <p> Open the libmemcache source file
+<tt>include/memcache/buffer.h</tt>. </p>
+
+<li> <p> Delete the "<tt>inline</tt>" words before the functions
+that were reported in the "<tt>undefined reference</tt>" error
+messages.  </p>
+
+<li> <p> Recompile and reinstall libmemcache. </p>
+
+</ul>
+
+<p> Then, continue building Postfix by running 'make'. </p>
+
+<h2>Configuring memcache lookup tables</h2>
+
+<p> Configuration is described in the memcache_table(5) manpage. </p>
+
+<h2>Credits</h2>
+
+<p> The first memcache client for Postfix was written by Omar Kilani. </p>
+
+<p> Wietse wrote a new memcache client from the ground up.  Besides
+also using libmemcache, the current implementation bears no resemblance
+to Omar's work.  </p>
+
+</body>
+
+</html>
index 375c58cab74f643f9427e32c6c2bb07841e6a068..fe6fc7c6df44813f14f19e790ed18a5717bdf8af 100644 (file)
@@ -620,7 +620,7 @@ $daemon_directory. </p>
 $manpage_directory and $readme_directory. </p>
 
 <li><p> Entries in /etc/passwd and /etc/group for the $mail_owner user and
-$setgid_group group. The the $mail_owner user provides the mail system
+$setgid_group group. The $mail_owner user provides the mail system
 with a protected (non-root) execution context. The $setgid_group group
 is used exclusively to support the setgid postdrop(1) and postqueue(1)
 utilities (it <b>must not</b> be the primary group or secondary group
index 39033c17d3f79d075879d95b68fb1395f0fa0a99..d71454fc0959b7ad6ff81da1dba00a2f072b2108 100644 (file)
@@ -23,6 +23,7 @@ HTML  = ../html/ADDRESS_CLASS_README.html \
        ../html/LDAP_README.html \
        ../html/LINUX_README.html \
        ../html/LOCAL_RECIPIENT_README.html ../html/MAILDROP_README.html \
+       ../html/MEMCACHE_README.html \
        ../html/MILTER_README.html \
        ../html/MULTI_INSTANCE_README.html \
        ../html/MYSQL_README.html ../html/NFS_README.html \
@@ -63,6 +64,7 @@ README        = ../README_FILES/ADDRESS_CLASS_README \
        ../README_FILES/LDAP_README \
        ../README_FILES/LINUX_README \
        ../README_FILES/LOCAL_RECIPIENT_README ../README_FILES/MAILDROP_README \
+       ../README_FILES/MEMCACHE_README \
        ../README_FILES/MILTER_README \
        ../README_FILES/MULTI_INSTANCE_README \
        ../README_FILES/MYSQL_README ../README_FILES/NFS_README \
@@ -199,6 +201,9 @@ clobber:
 ../html/MAILDROP_README.html: MAILDROP_README.html
        $(POSTLINK) $? >$@
 
+../html/MEMCACHE_README.html: MEMCACHE_README.html
+       $(POSTLINK) $? >$@
+
 ../html/MILTER_README.html: MILTER_README.html
        $(POSTLINK) $? >$@
 
@@ -355,6 +360,9 @@ clobber:
 ../README_FILES/MAILDROP_README: MAILDROP_README.html
        $(HT2READ) $? >$@
 
+../README_FILES/MEMCACHE_README: MEMCACHE_README.html
+       $(HT2READ) $? >$@
+
 ../README_FILES/MILTER_README: MILTER_README.html
        $(HT2READ) $? >$@
 
index caa7112f2721cab35987a041630a6dc473d14611..b2500d351017d952622461d2d1fd80ca4554ffcb 100644 (file)
@@ -27,11 +27,6 @@ code.  Assuming that OpenSSL is written as carefully as Wietse's
 own code, every 1000 lines introduce one additional bug into
 Postfix.  </p>
 
-<p> At this time, you should no longer be using OpenSSL releases prior
-to the most recent 0.9.8 release unless all relevant security fixes have
-been backported to the earlier release by you or your O/S vendor. OpenSSL
-0.9.7 and earlier are no longer maintained by the OpenSSL team. </p>
-
 <h2> What Postfix TLS support does for you </h2>
 
 <p> Transport Layer Security (TLS, formerly called SSL) provides
@@ -39,11 +34,13 @@ certificate-based authentication and encrypted sessions.  An
 encrypted session protects the information that is transmitted with
 SMTP mail or with SASL authentication.
 
-<p> This document describes a TLS user interface that was introduced
-with Postfix version 2.3. Support for an older user interface is
-documented in TLS_LEGACY_README, which also describes the differences
-between Postfix and the third-party patch on which Postfix version
-2.2 TLS support was based.  </p>
+<blockquote> <p> <a name="client_tls_obs"></a> <a
+name="client_tls_harden"></a> NOTE: This document describes a TLS
+user interface that was introduced with Postfix version 2.3. Support
+for an older user interface is documented in TLS_LEGACY_README,
+which also describes the differences between Postfix and the
+third-party patch on which Postfix version 2.2 TLS support was
+based.  </p> </blockquote>
 
 <p> Topics covered in this document: </p>
 
@@ -85,8 +82,8 @@ represent storage elements. </p>
 <li> <p> The smtpd(8) server implements the SMTP over TLS server
 side. </p>
 
-<li> <p> The smtp(8) client implements the SMTP over TLS client
-side. </p>
+<li> <p> The smtp(8) client implements the SMTP (and LMTP) over TLS
+client side. </p>
 
 <li> <p> The tlsmgr(8) server maintains the pseudo-random number
 generator (PRNG) that seeds the TLS engines in the smtpd(8) server
@@ -95,6 +92,10 @@ cache files. </p>
 
 </ul>
 
+<p> Not shown in the figure are the tlsproxy(8) server and the
+postscreen(8) server. These use TLS in the same manner as smtpd(8).
+</p>
+
 <table>
 
 <tr> <td>Network<tt>-&gt; </tt> </td> <td align="center"
@@ -170,7 +171,7 @@ CA must generate, and be prepared to present to most clients, a
 self-signed or private-CA signed certificate. The remote SMTP client
 will generally not be
 able to authenticate the self-signed certificate, but unless the
-client is running Postfix 2.3 or
+client is running Postfix or
 similar software, it will still insist on a server certificate. </p>
 
 <p> For servers that are <b>not</b> public Internet MX hosts, Postfix
@@ -389,19 +390,14 @@ since the headers may be changed by intermediate servers. </p>
 
 <p> By default, TLS is disabled in the Postfix SMTP server, so no
 difference to plain Postfix is visible.  Explicitly switch it on
-with "smtpd_tls_security_level = may" (Postfix 2.3 and
-later) or "smtpd_use_tls = yes" (obsolete but still
-supported). </p>
+with "smtpd_tls_security_level = may". </p>
 
 <p> Example: </p>
  
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    # Postfix 2.3 and later
     smtpd_tls_security_level = may
-    # Obsolete, but still supported
-    smtpd_use_tls = yes
 </pre>
 </blockquote>
 
@@ -417,9 +413,8 @@ private key. This is intended behavior. </p>
 <p> <a name="server_enforce">You can ENFORCE the use of TLS</a>,
 so that the Postfix SMTP server announces STARTTLS and accepts no
 mail without TLS encryption, by setting
-"smtpd_tls_security_level = encrypt" (Postfix 2.3 and
-later) or "smtpd_enforce_tls = yes" (obsolete but still
-supported). According to RFC 2487 this MUST NOT be applied in case
+"smtpd_tls_security_level = encrypt". According to RFC 2487 this
+MUST NOT be applied in case
 of a publicly-referenced Postfix SMTP server.  This option is off
 by default and should only seldom be used. </p>
 
@@ -428,10 +423,7 @@ by default and should only seldom be used. </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    # Postfix 2.3 and later
     smtpd_tls_security_level = encrypt
-    # Obsolete, but still supported
-    smtpd_enforce_tls = yes
 </pre>
 </blockquote>
 
@@ -473,7 +465,7 @@ when client certificates are requested, and abort the SMTP session. So
 this option is "off" by default. You will however need the certificate
 if you want to use certificate based relaying with, for example, the
 permit_tls_clientcerts feature. A server that wants client certificates
-must first present its own certificate. While Postfix 2.3 by default
+must first present its own certificate. While Postfix by default
 offers anonymous ciphers to remote SMTP clients, these are automatically
 suppressed
 when the Postfix SMTP server is configured to ask for client
@@ -485,10 +477,7 @@ certificates. </p>
 <pre>
 /etc/postfix/main.cf:
     smtpd_tls_ask_ccert = yes
-    # Postfix 2.3 and later
     smtpd_tls_security_level = may
-    # Obsolete, but still supported
-    smtpd_use_tls = yes
 </pre>
 </blockquote>
 
@@ -505,10 +494,7 @@ logged. </p>
 <pre>
 /etc/postfix/main.cf:
     smtpd_tls_req_ccert = yes
-    # Postfix 2.3 and later
     smtpd_tls_security_level = encrypt
-    # Obsolete, but still supported
-    smtpd_enforce_tls = yes
 </pre>
 </blockquote>
 
@@ -539,12 +525,10 @@ configured to supply its intermediate CA certificate). </p>
 
 <p> Sending AUTH data over an unencrypted channel poses a security
 risk.  When TLS layer encryption is required
-("smtpd_tls_security_level = encrypt" or the obsolete
-"smtpd_enforce_tls = yes"), the Postfix SMTP server will
+("smtpd_tls_security_level = encrypt"), the Postfix SMTP server will
 announce and accept AUTH only after the TLS layer has been activated
 with STARTTLS. When TLS layer encryption is optional
-("smtpd_tls_security_level = may" or the obsolete
-"smtpd_enforce_tls = no"), it may however still be useful
+("smtpd_tls_security_level = may"), it may however still be useful
 to only offer AUTH when TLS is active. To maintain compatibility
 with non-TLS clients, the default is to accept AUTH without encryption.
 In order to change this behavior, set
@@ -695,12 +679,6 @@ the name of the user or host:</p>
 
 <h3><a name="server_cipher">Server-side cipher controls</a> </h3>
 
-<p> The description below is for Postfix 2.3; for Postfix &lt; 2.3 the
-smtpd_tls_cipherlist parameter specifies the acceptable ciphers as an
-explicit OpenSSL cipherlist. The obsolete setting applies even when TLS
-encryption is not enforced. Use of this control on public MX hosts is
-strongly discouraged. </p>
-
 <p> The Postfix SMTP server supports 5 distinct cipher security levels
 as specified by the smtpd_tls_mandatory_ciphers configuration parameter,
 which determines the cipher grade with mandatory TLS encryption. The
@@ -732,7 +710,7 @@ smtpd_tls_mandatory_protocols configuration parameter.  The
 corresponding smtpd_tls_protocols parameter (Postfix &ge; 2.6)
 controls the SSL/TLS protocols used with opportunistic TLS. </p>
 
-<p> For a server that is not a public Internet MX host, Postfix (&ge; 2.3)
+<p> For a server that is not a public Internet MX host, Postfix
 supports configurations with no <a href="#server_cert_key">server
 certificates</a> that use <b>only</b> the anonymous ciphers. This is
 enabled by explicitly setting "smtpd_tls_cert_file = none"
@@ -870,10 +848,6 @@ key configuration </a>
 
 <li><a href="#client_tls_policy"> Per-destination TLS policy </a>
 
-<li><a href="#client_tls_obs"> Obsolete per-site TLS policy support </a>
-
-<li><a href="#client_tls_harden"> Closing a DNS loophole with obsolete per-site TLS policies </a>
-
 <li><a href="#client_tls_discover"> Discovering servers that support TLS </a>
 
 <li><a href="#client_vrfy_server">Server certificate verification depth</a>
@@ -934,32 +908,26 @@ The "null" ciphers provide authentication without encryption. </p>
 <h4><a name="client_tls_none"> No TLS encryption </a> </h4>
 
 <p> At the "none" TLS security level, TLS encryption is
-disabled. This is the default security level. With Postfix 2.3 and later,
-it can be configured explicitly by setting "smtp_tls_security_level = none". </p>
+disabled. This is the default security level, and
+can be configured explicitly by setting "smtp_tls_security_level = none".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
-<p> With Postfix 2.2 and earlier, or when smtp_tls_security_level is set to
-its default (backwards compatible) empty value, the appropriate configuration
-settings are "smtp_use_tls = no" and "smtp_enforce_tls = no".
-With either approach, TLS is not used even if supported by the server.
-For LMTP, use the corresponding "lmtp_" parameters. </p>
-
-<p> Per destination settings may override this default setting, in which case
+<p> Per-destination settings may override this default setting, in which case
 TLS is used selectively, only with destinations explicitly configured
 for TLS. </p>
 
 <p> You can disable TLS for a subset of destinations, while leaving
-it enabled for the rest. With the Postfix 2.3 and later TLS <a
+it enabled for the rest. With the Postfix TLS <a
 href="#client_tls_policy">policy table</a>, specify the "none"
-security level. With the obsolete <a href="#client_tls_obs">per-site</a>
-table, specify the "NONE" keyword. </p>
+security level.
 
 <h4><a name="client_tls_may"> Opportunistic TLS </a> </h4>
 
 <p> At the "may" TLS security level, TLS encryption is <i>opportunistic</i>.
 The SMTP transaction is encrypted if the STARTTLS ESMTP feature
 is supported by the server. Otherwise, messages are sent in the clear.
-With Postfix 2.3 and later, opportunistic TLS can be configured by
-setting "smtp_tls_security_level = may".
+Opportunistic TLS can be configured by setting "smtp_tls_security_level = may".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
 <p> Since sending in the clear is acceptable, demanding stronger
 than default TLS security mostly reduces inter-operability. If you
@@ -970,17 +938,12 @@ and cipher grade
 used with opportunistic TLS. With earlier releases the opportunistic TLS
 cipher grade is always "export" and no protocols are disabled. </p>
 
-<p> With Postfix 2.2 and earlier, or when smtp_tls_security_level is
-set to its default (backwards compatible) empty value, the appropriate
-configuration settings are "smtp_use_tls = yes" and
-"smtp_enforce_tls = no".
-For LMTP use the corresponding "lmtp_" parameters. </p>
-
 <p> With opportunistic TLS, mail delivery continues even if the
-server certificate is untrusted or bears the wrong name.  Starting
-with Postfix 2.3, when the TLS handshake fails for an opportunistic
-TLS session, rather than give up on mail delivery, the transaction
-is retried with TLS disabled. Trying an unencrypted connection makes
+server certificate is untrusted or bears the wrong name.  
+When the TLS handshake fails for an opportunistic
+TLS session, rather than give up on mail delivery, the Postfix SMTP
+client retries the transaction
+with TLS disabled. Trying an unencrypted connection makes
 it possible to deliver mail to sites with non-interoperable server
 TLS implementations. </p>
 
@@ -994,9 +957,8 @@ Attempts to configure opportunistic encryption of LMTP sessions will
 be ignored with a warning written to the mail logs. </p>
 
 <p> You can enable opportunistic TLS just for selected destinations. With
-the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy table</a>,
-specify the "may" security level. With the obsolete <a
-href="#client_tls_obs">per-site</a> table, specify the "MAY" keyword.</p>
+the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "may" security level. </p>
 
 <p> This is the most common security level for TLS protected SMTP
 sessions, stronger security is not generally available and, if needed,
@@ -1012,27 +974,18 @@ on TLS <a href="#client_tls_limits">limitations</a> above. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    smtp_use_tls = yes
-    smtp_enforce_tls = no
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_encrypt"> Mandatory TLS encryption </a> </h4>
 
 <p> At the "encrypt" TLS security level, messages are sent only
 over TLS encrypted sessions. The SMTP transaction is aborted unless
 the STARTTLS ESMTP feature is supported by the remote SMTP server.
 If no suitable
-servers are found, the message will be deferred. With Postfix 2.3
-and later, mandatory TLS encryption can be configured by setting
+servers are found, the message will be deferred.
+Mandatory TLS encryption can be configured by setting
 "smtp_tls_security_level = encrypt". Even though TLS
 encryption is always used, mail delivery continues even if the server
-certificate is untrusted or bears the wrong name. </p>
+certificate is untrusted or bears the wrong name.
+For LMTP, use the corresponding "lmtp_" parameter. </p>
 
 <p> At this security level and higher, the smtp_tls_mandatory_protocols
 and smtp_tls_mandatory_ciphers configuration parameters determine
@@ -1042,12 +995,6 @@ met, the mail transaction is aborted.  The documentation for these
 parameters includes useful interoperability and security guidelines.
 </p>
 
-<p> With Postfix 2.2 and earlier, or when smtp_tls_security_level
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "smtp_enforce_tls = yes"
-and "smtp_tls_enforce_peername = no". For LMTP use the corresponding
-"lmtp_" parameters. </p>
-
 <p> Despite the potential for eliminating passive eavesdropping attacks,
 mandatory TLS encryption is not viable as a default security level for
 mail delivery to the public Internet. Most MX hosts do not support TLS at
@@ -1056,12 +1003,9 @@ that delivers mail to the Internet, you should not configure mandatory
 TLS encryption as the default security level. </p>
 
 <p> You can enable mandatory TLS encryption just for specific destinations.
-With the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy
-table</a>, specify the "encrypt" security level. With the
-obsolete <a href="#client_tls_obs">per-site</a> table, specify the
-"MUST_NOPEERMATCH" keyword. While the obsolete approach still works
-with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3 and later
-should use the new TLS policy settings. </p>
+With the Postfix TLS <a href="#client_tls_policy">policy
+table</a>, specify the "encrypt" security level.
+</p>
 
 <p> Examples: </p>
 
@@ -1083,20 +1027,6 @@ level sessions. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax (no support for sub-domains without resorting to
-regexp tables). With Postfix 2.3 and later, do not use the obsolete <a
-href="#client_tls_obs">per-site</a> table. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    smtp_tls_per_site = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/tls_per_site:
-    example.com       MUST_NOPEERMATCH
-</pre>
-</blockquote>
-
 <p> In the next example, secure message submission is configured
 via the MSA "<tt>[example.net]:587</tt>". TLS sessions are encrypted
 without authentication, because this MSA does not possess an acceptable
@@ -1128,28 +1058,6 @@ just in case the transport table entries are not specified consistently. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-
-<p> <b>Note:</b> Avoid policy lookups with the bare hostname (for
-example, "example.net").  Instead,
-use the destination (for example, "[example.net]:587"), as the <a
-href="#client_tls_obs">per-site</a> table lookup key (a recipient domain
-or MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>). With Postfix 2.3
-and later,
-do not use the obsolete <a href="#client_tls_obs">per-site</a> table;
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    smtp_tls_per_site = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/tls_per_site:
-    [example.net]:587   MUST_NOPEERMATCH
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_fprint"> Certificate fingerprint verification </a> </h4>
 
 <p> Certificate fingerprint verification is available with Postfix
@@ -1234,13 +1142,8 @@ server certificate verification can be configured by setting
 smtp_tls_verify_cert_match parameter can override the default
 "hostname" certificate name matching strategy. Fine-tuning the
 matching strategy is generally only appropriate for <a
-href="#client_tls_secure">secure-channel</a> destinations. </p>
-
-<p> With Postfix 2.2 and earlier, or when smtp_tls_security_level
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "smtp_enforce_tls = yes" and
-"smtp_tls_enforce_peername = yes". For LMTP use the corresponding
-"lmtp_" parameters. </p>
+href="#client_tls_secure">secure-channel</a> destinations.
+For LMTP use the corresponding "lmtp_" parameters. </p>
 
 <p> If the server certificate chain is trusted (see smtp_tls_CAfile
 and smtp_tls_CApath), any DNS names in the SubjectAlternativeName
@@ -1269,12 +1172,9 @@ href="#client_tls_secure">secure-channel</a> configuration instead.
 </p>
 
 <p> You can enable mandatory server certificate verification just
-for specific destinations.  With the Postfix 2.3 and later TLS <a
+for specific destinations.  With the Postfix TLS <a
 href="#client_tls_policy">policy table</a>, specify the "verify"
-security level. With the obsolete <a href="#client_tls_obs">per-site</a>
-table, specify the "MUST" keyword.  While the obsolete approach
-still works with Postfix 2.3, it is strongly discouraged: users of
-Postfix 2.3 and later should use the new TLS policy settings. </p>
+security level. </p>
 
 <p> Example: </p>
 
@@ -1295,36 +1195,16 @@ to <i>example.com</i> recipients uses "high" grade ciphers. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2 syntax: </p>
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    indexed = ${default_database_type}:${config_directory}/
-    smtp_tls_CAfile = ${config_directory}/CAfile.pem
-    smtp_tls_per_site = ${indexed}tls_per_site
-
-/etc/postfix/tls_per_site:
-    example.com         MUST
-</pre>
-</blockquote>
-
 <h4><a name="client_tls_secure"> Secure server certificate verification </a> </h4>
 
 <p> At the <i>secure</i> TLS security level, messages are sent only over
 <i>secure-channel</i> TLS sessions where DNS forgery resistant server
 certificate verification succeeds. If no suitable servers are found, the
-message will be deferred. With Postfix 2.3 and later, secure-channels
+message will be deferred. Postfix secure-channels
 can be configured by setting "smtp_tls_security_level = secure".
 The smtp_tls_secure_cert_match parameter can override the default
-"nexthop, dot-nexthop" certificate match strategy. </p>
-
-<p> With Postfix 2.2 and earlier, or when smtp_tls_security_level
-is set to its default (backwards compatible) empty value, the
-appropriate configuration settings are "smtp_enforce_tls = yes"
-and "smtp_tls_enforce_peername = yes" with additional settings to
-<a href="#client_tls_harden">harden</a> peer certificate verification
-against forged DNS data. For LMTP, use the corresponding "lmtp_"
-parameters. </p>
+"nexthop, dot-nexthop" certificate match strategy.
+For LMTP, use the corresponding "lmtp_" parameters. </p>
 
 <p> If the server certificate chain is trusted (see smtp_tls_CAfile and
 smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate
@@ -1351,18 +1231,14 @@ sends all email to a central mailhub that offers the necessary
 STARTTLS support. </p>
 
 <p> You can enable secure TLS verification just for specific destinations.
-With the Postfix 2.3 and later TLS <a href="#client_tls_policy">policy table</a>,
-specify the "secure" security level. With the obsolete
-<a href="#client_tls_obs">per-site</a> table, specify the "MUST"
-keyword and <a href="#client_tls_harden">harden</a> the certificate
-verification against DNS forgery. While the obsolete approach still
-works with Postfix 2.3, it is strongly discouraged: users of Postfix 2.3
-and later
-should use the new TLS policy settings. </p>
+With the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "secure" security level. </p>
 
 <p> Examples: </p>
 
-<p> Secure-channel TLS without transport(5) table overrides: </p>
+<ul>
+
+<li> <p> Secure-channel TLS without transport(5) table overrides: </p>
 
 <p> The Postfix SMTP client will encrypt all traffic and verify the
 destination name
@@ -1408,18 +1284,14 @@ the first approach is more appropriate in most cases. <p>
 </pre>
 </blockquote>
 
-<p> Secure-channel TLS with transport(5) table overrides: <p>
+<li> <p> Secure-channel TLS with transport(5) table overrides: <p>
 
 <p> In this case traffic to <i>example.com</i> and its related domains
 is sent to a single logical gateway (to avoid a single point of failure,
 its name may resolve to one or more load-balancer addresses, or to the
 combined addresses of multiple physical hosts). All the physical hosts
 reachable via the gateway's IP addresses have the logical gateway name
-listed in their certificates. This secure-channel configuration can also
-be implemented via a <a href="#client_tls_harden">hardened</a> variant of
-the MUST policy in the obsolete <a href="#client_tls_obs">per-site</a>
-table. As stated above, this approach has the potential to mis-deliver
-email if the related domains change hands. </p>
+listed in their certificates. </p>
 
 <blockquote>
 <pre>
@@ -1438,35 +1310,7 @@ email if the related domains change hands. </p>
 </pre>
 </blockquote>
 
-<p> Postfix 2.2.9 and later syntax: </p>
-
-<p> <b>Note:</b> Avoid policy lookups with the bare hostname (for
-example, "tls.example.com").  Instead, use the destination (for
-example, "[tls.example.com]") as the <a
-href="#client_tls_obs">per-site</a> table lookup key (a recipient domain
-or MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>). With Postfix 2.3
-and later,
-do not use the obsolete <a href="#client_tls_obs">per-site</a> table;
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    smtp_cname_overrides_servername = no
-    smtp_tls_CAfile = /etc/postfix/CAfile.pem
-    transport_maps = hash:/etc/postfix/transport
-    smtp_tls_per_site = hash:/etc/postfix/tls_per_site
-
-/etc/postfix/transport:
-    example.com     smtp:[tls.example.com]
-    example.co.uk   smtp:[tls.example.com]
-    example.co.jp   smtp:[tls.example.com]
-
-/etc/postfix/tls_per_site:
-    [tls.example.com]       MUST
-</pre>
-</blockquote>
+</ul>
 
 <h3><a name="client_logging"> Client-side TLS activity logging </a> </h3>
 
@@ -1778,9 +1622,9 @@ constraints on the sending and receiving sites that preclude ubiquitous
 deployment. One needs to manually configure this type of security for
 each destination domain, and in many cases implement non-default TLS
 <a href="#client_tls_policy">policy table</a> entries for additional
-domains hosted at a common secured destination. With Postfix 2.3, we
-make secure-channel configurations substantially easier to configure,
-but they will never be the norm. For the generic domain with which you
+domains hosted at a common secured destination. For these reasons
+secure-channel configurations
+will never be the norm. For the generic domain with which you
 have made no specific security arrangements, this security level is not
 a good fit. </p>
 
@@ -1790,7 +1634,7 @@ TLS use self-signed certificates or private CAs. This further limits
 the applicability of verified TLS on the public Internet. </p>
 
 <p> Historical note: while the documentation of these issues and many of the
-related features are new with Postfix 2.3, the issue was well
+related features were new with Postfix 2.3, the issue was well
 understood before Postfix 1.0, when Lutz J&auml;nicke was designing
 the first unofficial Postfix TLS patch. See his original post <a
 href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html</a>
@@ -1803,23 +1647,15 @@ uses indirect naming (via MX records) more frequently. </p>
 <h3> <a name="client_tls_policy"> TLS policy table </a>
 </h3>
 
-<p> The current TLS policy table was introduced with Postfix 2.3. For
-earlier releases, read the description of the obsolete Postfix 2.2 <a
-href="#client_tls_obs">per-site</a> table. </p>
-
 <p> A small fraction of servers offer STARTTLS but the negotiation
-consistently fails. With Postfix 2.3, so long as encryption is not
-enforced, the delivery is immediately retried with TLS disabled.  You no
-longer need to explicitly disable TLS for the problem destinations.
-As soon as their TLS software or configuration is repaired, encryption
-will be used. </p>
+consistently fails. As long as encryption is not mandatory, the
+Postfix SMTP client retries the delivery immediately with TLS
+disabled, without any need to explicitly disable TLS for the problem
+destinations. </p>
 
-<p> The new policy table is specified via the smtp_tls_policy_maps
+<p> The policy table is specified via the smtp_tls_policy_maps
 parameter. This lists optional lookup tables with the Postfix SMTP client
-TLS security policy by next-hop destination. When $smtp_tls_policy_maps
-is not empty, the obsolete smtp_tls_per_site parameter is ignored
-(a warning is written to the logs if both parameter values are
-non-empty).  </p>
+TLS security policy by next-hop destination. </p>
 
 <p> The TLS policy table is indexed by the full next-hop destination,
 which is either the recipient domain, or the verbatim next-hop
@@ -1968,211 +1804,6 @@ table can render the "secure" level vulnerable to DNS forgery. Do not use
 the "hostname" strategy for <a href="#client_tls_secure">secure-channel</a>
 configurations in environments where DNS security is not assured. </p>
 
-<h3> <a name="client_tls_obs"> Obsolete per-site TLS policy support 
-</a> </h3>
-
-<p> This section describes an obsolete per-site TLS policy mechanism.
-Unlike the Postfix 2.3 <a href="#client_tls_policy">policy table</a>
-mechanism, this uses as a policy lookup key a potentially untrusted
-server hostname, and lacks control over what names can appear in
-server certificates.  Because of this, the obsolete mechanism is
-typically vulnerable to false DNS hostname information in MX or
-CNAME records.  These attacks can be eliminated only with great
-difficulty. The new <a href="#client_tls_policy">policy table</a>
-makes <a href="#client_tls_secure">secure-channel</a> configurations
-easier and provides more control over the cipher and protocol selection
-for sessions with mandatory encryption. </p>
-
-<p> Avoid policy lookups with the bare hostname.  Instead, use the
-full destination nexthop (enclosed in [] with a possible ":port"
-suffix) as the per-site table lookup key (a recipient domain or
-MX-enabled transport nexthop with no port suffix may look like a bare
-hostname, but is still a suitable <i>destination</i>).  With Postfix 2.3
-and later,
-use of the obsolete approach documented here is strongly discouraged:
-use the new <a href="#client_tls_policy">policy table</a> instead. </p>
-
-<p> Starting with Postfix 2.3, the underlying TLS enforcement levels are
-common to the obsolete per-site table and the new policy table. The
-main.cf smtp_tls_mandatory_ciphers and smtp_tls_mandatory_protocols
-parameters control the TLS ciphers and protocols for mandatory
-encryption regardless of which table is used. The
-smtp_tls_verify_cert_match parameter determines the match strategy
-for the obsolete "MUST" keyword in the same way as for the "verify"
-level in the new policy. </p>
-
-<p> With Postfix &lt; 2.3, the obsolete smtp_tls_cipherlist parameter
-is also applied for opportunistic TLS sessions, and should be used with
-care, or not at all. Setting cipherlist restrictions that are incompatible
-with a remote SMTP server render that server unreachable, TLS handshakes
-are always attempted and always fail. </p>
-
-<p> When smtp_tls_policy_maps is empty (default) and smtp_tls_per_site
-is not empty, the per-site table is searched for a policy that matches
-the following information:  </p>
-
-<blockquote>
-
-<dl>
-
-<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS
-name of the server that the Postfix SMTP client connects to; this
-name may be obtained from other DNS lookups, such as MX lookups or
-CNAME lookups. Use of the hostname lookup key is discouraged; always
-use the next-hop destination instead. </dd>
-
-<dt> next-hop destination </dt> <dd> This is normally the domain portion
-of the recipient address, but it may be overridden by information from
-the transport(5) table, from the relayhost parameter setting, or from
-the relay_transport setting. When it is not the recipient domain, the
-next-hop destination can have the Postfix-specific form "<tt>[name]</tt>",
-"<tt>[name]:port</tt>", "<tt>name</tt>" or "<tt>name:port</tt>".  This is
-the recommended lookup key for per-site policy lookups (and incidentally
-for <a href="SASL_README.html#client_sasl">SASL password</a> lookups). </dd>
-
-</dl>
-
-</blockquote>
-
-<p> When both the hostname lookup and the next-hop lookup succeed,
-the host policy does not automatically override the next-hop policy.
-Instead, precedence is given to either the more specific or the
-more secure per-site policy as described below.  </p>
-
-<p> The smtp_tls_per_site table uses a simple "<i>name whitespace
-value</i>" format. Specify host names or next-hop destinations on
-the left-hand side; no wildcards are allowed.  On the right hand
-side specify one of the following keywords:  </p>
-
-<blockquote>
-
-<dl>
-
-<dt> NONE </dt> <dd> No TLS. This overrides a less specific "MAY" lookup
-result from the alternate host or next-hop lookup key, and overrides
-the global smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername
-settings. </dd>
-
-<dt> MAY </dt> <dd> Opportunistic TLS. This has less precedence than
-a more specific result (including "NONE") from the alternate host or
-next-hop lookup key, and has less precedence than the more specific global
-"smtp_enforce_tls = yes" or "smtp_tls_enforce_peername = yes".  </dd>
-
-<dt> MUST_NOPEERMATCH </dt> <dd> Mandatory TLS encryption. This
-overrides a less secure "NONE" or a less specific "MAY" lookup result
-from the alternate host or next-hop lookup key, and overrides the global
-smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername settings.
-</dd>
-
-<dt> MUST </dt> <dd> Mandatory server certificate verification.
-This overrides a less secure "NONE" and "MUST_NOPEERMATCH" or a
-less specific "MAY" lookup result from the alternate host or next-hop
-lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls
-and smtp_tls_enforce_peername settings.  </dd>
-
-</dl>
-
-</blockquote>
-
-<p> The precedences between global (main.cf) and per-site TLS
-policies can be summarized as follows: </p>
-
-<ul>
-
-<li> <p> When neither the remote SMTP server hostname nor the
-next-hop destination are found in the smtp_tls_per_site table, the
-policy is based on smtp_use_tls, smtp_enforce_tls and
-smtp_tls_enforce_peername. Note: "smtp_enforce_tls = yes" and
-"smtp_tls_enforce_peername = yes" imply "smtp_use_tls = yes". </p>
-
-<li> <p> When both hostname and next-hop destination lookups produce
-a result, the more specific per-site policy (NONE, MUST, etc)
-overrides the less specific one (MAY), and the more secure per-site
-policy (MUST, etc) overrides the less secure one (NONE).  </p>
-
-<li> <p> After the per-site policy lookups are combined, the result
-generally overrides the global policy. The exception is the less
-specific "MAY" per-site policy, which is overruled by the more
-specific global "smtp_enforce_tls = yes" with server certificate
-verification as specified with the smtp_tls_enforce_peername
-parameter.  </p>
-
-</ul>
-
-<h3> <a name="client_tls_harden"> Closing a DNS loophole with 
-obsolete per-site TLS policies </a> </h3>
-
-<p> For a general discussion of TLS security for SMTP see <a
-href="#client_tls_limits">TLS limitations</a> above. What follows applies
-only to Postfix 2.2.9 and subsequent Postfix 2.2 patch levels. Do
-not use this approach with Postfix 2.3
-and later; instead see the instructions under <a
-href="#client_tls_secure">secure</a> server certificate verification. </p>
-
-<p> As long as no secure DNS lookup mechanism is available, false
-hostnames in MX or CNAME responses can change Postfix's notion of the
-server hostname that is used for TLS policy lookup and server certificate
-verification. Even with a perfect match between the server hostname and
-the server certificate, there is no guarantee that Postfix is connected
-to the right server.  To avoid this loophole, take all of the following
-steps: </p>
-
-<ol>
-
-<li> <p> Use a dedicated message delivery transport (for example,
-"securetls") as illustrated below. </p>
-
-<li> <p> Eliminate MX lookups. Specify local transport(5) table
-entries for sensitive domains with explicit securetls:[<i>mailhost</i>]
-or securetls:[<i>mailhost</i>]:<i>port</i> destinations (you can
-assure security of this table unlike DNS). This prevents false
-hostname information in DNS MX records from changing Postfix's
-notion of the server hostname that is used for TLS policy lookup
-and server certificate verification. The "securetls" transport is
-configured to enforce TLS with peername verification, and to disable
-the SMTP connection cache which could interfere with enforcement
-of smtp_tls_per_site policies. </p>
-
-<li> <p> Disallow CNAME hostname overrides. In main.cf, specify
-"smtp_cname_overrides_servername = no". This prevents false hostname
-information in DNS CNAME records from changing the server hostname
-that Postfix uses for TLS policy lookup and server certificate
-verification. This feature requires Postfix 2.2.9 or later.  The
-default value is "no" starting with Postfix 2.3. </p>
-
-</ol>
-
-<p> Example: </p>
-
-<p> We give the <a href="postconf.5.html#default_transport">non-default</a>
-"securetls" transport an explicit master.cf process limit, so that we
-don't raise its process limit when raising $default_process_limit. The
-total process limit for *all* transports should stay somewhat under 1024
-(the typical select() file descriptor limit); otherwise transports may
-be throttled under steady high load, compounding congestion.  It is not
-uncommon at high volume sites to set the default process limit to 500
-or more. </p>
-
-<p> We also default the "securetls" transport TLS security level to
-<a href="#client_tls_verify">MUST</a>, obviating the need for <a
-href="#client_tls_obs">per-site</a> table entries for secure-channel
-destinations. </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    transport_maps = hash:/etc/postfix/transport
-
-/etc/postfix/transport:
-    example.com         securetls:[tls.example.com]
-
-/etc/postfix/master.cf:
-    securetls unix  -       -       n       -       100     smtp
-        -o smtp_enforce_tls=yes
-        -o smtp_tls_enforce_peername=yes
-</pre>
-</blockquote>
-
 <h3> <a name="client_tls_discover"> Discovering servers that support
 TLS </a> </h3>
 
@@ -2601,10 +2232,7 @@ but don't require them from all clients. </p>
     smtpd_tls_session_cache_database =
        btree:/var/lib/postfix/smtpd_tls_session_cache
     tls_random_source = dev:/dev/urandom
-    # Postfix 2.3 and later
     smtpd_tls_security_level = may
-    # Obsolete, but still supported
-    smtpd_use_tls = yes
 </pre>
 </blockquote>
 
index 5c7b5b39bfb264526a95f5dd6b6bad8e7b3ffb27..09a362a967dcca18b5903274d8815250f436c58a 100644 (file)
@@ -551,13 +551,13 @@ mail deliveries.  </p>
 
 <p> The default_process_limit configuration parameter gives direct
 control over how many daemon processes Postfix will run.  As of
-Postfix 2.0 the default limit is 100 smtp client processes, 100
-smtp server processes, and so on.  This may overwhelm systems with
+Postfix 2.0 the default limit is 100 SMTP client processes, 100
+SMTP server processes, and so on.  This may overwhelm systems with
 little memory, as well as networks with low bandwidth.  </p>
 
 <p> You can change the global process limit by specifying a
 non-default default_process_limit in the main.cf file. For example,
-to run up to 10 smtp client processes, 10 smtp server processes,
+to run up to 10 SMTP client processes, 10 SMTP server processes,
 and so on: </p>
 
 <blockquote>
diff --git a/postfix/proto/memcache_table b/postfix/proto/memcache_table
new file mode 100644 (file)
index 0000000..83d687a
--- /dev/null
@@ -0,0 +1,169 @@
+#++
+# NAME
+#      memcache_table 5
+# SUMMARY
+#      Postfix memcache client configuration
+# SYNOPSIS
+#      \fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/filename\fR
+#
+#      \fBpostmap -q - memcache:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+# DESCRIPTION
+#      The Postfix mail system uses optional tables for address
+#      rewriting or mail routing. These tables are usually in
+#      \fBdbm\fR or \fBdb\fR format.
+#
+#      Alternatively, lookup tables can be specified as memcache
+#      instances.  In order to use memcache lookups, define a
+#      memcache source as a lookup table in main.cf, for example:
+#
+# .nf
+#          virtual_alias_maps = memcache:/etc/postfix/memcache-aliases.cf
+# .fi
+#
+#      The file /etc/postfix/memcache-aliases.cf has the same
+#      format as the Postfix main.cf file, and specifies the
+#      parameters described below.
+#
+#      The Postfix memcache client supports the lookup and update
+#      operations.
+# MEMCACHE PARAMETERS
+# .ad
+# .fi
+# .IP "\fBhosts (default: localhost:11211)\fR"
+#      The memcache servers that Postfix will try to connect to.
+#      Specify a hostname or address, optionally followed by ":"
+#      and a port name or number. The default port is 11211.
+#      Examples:
+#
+# .nf
+#          hosts = memcache01.example.com
+#              memcache02.example.com
+# .fi
+# .IP "\fBkey_format (default: %s)\fB"
+#      Format of the lookup and update keys in memcache queries.
+#      By default, these are the same as the lookup and update
+#      keys that are given to the Postfix memcache client.
+#
+#      When the same memcache database is used to cache information
+#      from multiple tables, you can use the \fBkey_format\fR
+#      feature to avoid name collisions by prepending a fixed
+#      string.  Examples:
+#
+# .nf
+#          key_format = aliases:%s
+#          key_format = access:%s
+# .fi
+#
+#      The \fBkey_format\fR parameter supports the following '%'
+#      expansions:
+# .RS 
+# .IP "\fB\fB%%\fR\fR"
+#      This is replaced by a literal '%' character.
+# .IP "\fB\fB%s\fR\fR"
+#      This is replaced by the memcache client input key.
+# .IP "\fB\fB%u\fR\fR"
+#      When the input key is an address of the form user@domain,
+#      \fB%u\fR is replaced by the SQL quoted local part of the
+#      address.  Otherwise, \fB%u\fR is replaced by the entire
+#      search string.  If the localpart is empty, a lookup is
+#      silently suppressed and returns no results (an update is
+#      skipped with a warning).
+# .IP "\fB\fB%d\fR\fR"
+#      When the input key is an address of the form user@domain,
+#      \fB%d\fR is replaced by the domain part of the address.
+#      Otherwise, a lookup is silently suppressed and returns no
+#      results (an update is skipped with a warning).
+# .IP "\fB\fB%[SUD]\fR\fR"
+#      The upper-case equivalents of the above expansions behave
+#      in the \fBkey_format\fR parameter identically to their
+#      lower-case counter-parts.
+# .IP "\fB\fB%[1-9]\fR\fR"
+#      The patterns %1, %2, ... %9 are replaced by the corresponding
+#      most significant component of the input key's domain. If
+#      the input key is \fIuser@mail.example.com\fR, then %1 is
+#      \fBcom\fR, %2 is \fBexample\fR and %3 is \fBmail\fR. If the
+#      input key is unqualified or does not have enough domain
+#      components to satisfy all the specified patterns, a lookup
+#      is silently suppressed and returns no results (an update
+#      is skipped with a warning).
+# .RE
+# .IP "\fBdomain (default: no domain list)\fR"
+#      This feature can significantly reduce database server load.
+#      Specify a list of domain names, paths to files, or dictionaries.
+#      When specified, only fully qualified search keys with a
+#      *non-empty* localpart and a matching domain are eligible
+#      for lookup or update: bare 'user' lookups, bare domain
+#      lookups and "@domain" lookups are silently skipped (updates
+#      are skipped with a warning).  Example:
+#
+# .nf
+#          domain = example.com, hash:/etc/postfix/searchdomains
+# .fi
+# .IP "\fBflags (default: 0)\fR"
+#      Optional flags that should be stored along with a memcache
+#      update.
+# .IP "\fBttl (default: 604800)\fR"
+#      The expiration time in seconds of memcache updates.
+#      The default is one week.
+#
+#      When using memcache tables with \fBpostscreen\fR(8) or
+#      \fBverify\fR(8), specify a zero *_cache_cleanup_interval
+#      value, and specify the largest \fBpostscreen\fR(8) *_ttl
+#      value or \fBverify\fR(8) *_expire_time value as the memcache
+#      map's \fBttl\fR value.
+#
+#      Note: according to memcache protocol documentation, a value
+#      greater than 30 days (2592000 seconds) specifies absolute UNIX
+#      time. Smaller values are relative to the time of the update.
+# BUGS
+#      The Postfix memcache client is based on libmemcache, which
+#      will terminate its process after a memcache server goes
+#      down. To avoid this, set up redundant memcache servers that
+#      have no common source of failure.
+#
+#      The Postfix memcache client cannot be used for security-sensitive
+#      tables such as \fBalias_maps\fR (these may contain
+#      "\fI|command\fR and "\fI/file/name\fR" destinations), or
+#      \fBvirtual_uid_maps\fR and \fBvirtual_gid_maps\fR (these
+#      specify UNIX process privileges).  In a typical deployment
+#      a memcache database is shared via a TCP socket, and is
+#      therefore writable not only by Postfix, but by any process
+#      that can talk to the memcache server.
+#
+#      The Postfix memcache client requires additional configuration
+#      when used with the \fBpostscreen\fR(8) and \fBverify\fR(8)
+#      daemons.  For details see the \fBttl\fR parameter discussion
+#      at the end of the MEMCACHE PARAMETERS section in this
+#      document.
+#
+#      The Postfix memcache client is supported only with libmemcache
+#      version 1.4.0.  Some libmemcache features are documented
+#      by reading libmemcache source code, instead a proper API.
+# SEE ALSO
+#      postmap(1), Postfix lookup table manager
+#      postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+#      Use "\fBpostconf readme_directory\fR" or
+#      "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+#      DATABASE_README, Postfix lookup table overview
+#      MEMCACHE_README, Postfix memcache client guide
+# LICENSE
+# .ad
+# .fi
+#      The Secure Mailer license must be distributed with this software.
+# HISTORY
+# .ad
+# .fi
+#      The first memcache client for Postfix was written by Omar
+#      Kilani.  Besides being implemented on libmemcache, this
+#      implementation bears no resemblance to his work.
+# AUTHOR(S)
+#      Wietse Venema
+#      IBM T.J. Watson Research
+#      P.O. Box 704
+#      Yorktown Heights, NY 10598, USA
+#--
index 365b5b1aded7d8ee242fc252ce3bdad6ee9923b7..489027763cefc7c8d7a9f34e2e9367a6dd716a74 100644 (file)
@@ -30,7 +30,8 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
        fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
        match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
-       smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c
+       smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \
+       dict_memcache.c mail_version.c
 OBJS   = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
        clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
@@ -62,7 +63,8 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
        fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
        match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
-       smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o
+       smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \
+       dict_memcache.o mail_version.o
 HDRS   = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
        conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@@ -88,7 +90,7 @@ HDRS  = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \
        fold_addr.h header_body_checks.h data_redirect.h match_service.h \
        addr_match_list.h smtp_reply_footer.h safe_ultostr.h \
-       verify_sender_addr.h
+       verify_sender_addr.h dict_memcache.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -101,7 +103,8 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
        quote_821_local mail_conf_time mime_state strip_addr \
        verify_clnt xtext anvil_clnt scache ehlo_mask \
        valid_mailhost_addr own_inet_addr header_body_checks \
-       data_redirect addr_match_list safe_ultostr verify_sender_addr
+       data_redirect addr_match_list safe_ultostr verify_sender_addr \
+       mail_version mail_dict
 
 LIBS   = ../../lib/libutil.a
 LIB_DIR        = ../../lib
@@ -293,9 +296,16 @@ safe_ultostr: safe_ultostr.c $(LIB) $(LIBS)
 verify_sender_addr: verify_sender_addr.c $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
+mail_version: mail_version.c $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
+mail_dict: mail_dict.c $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
 tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
        xtext_test scache_multi_test ehlo_mask_test \
-       namadr_list_test mail_conf_time_test header_body_checks_tests
+       namadr_list_test mail_conf_time_test header_body_checks_tests \
+       mail_version_test
 
 mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \
        mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 mime_garb4
@@ -387,6 +397,11 @@ xtext_test: xtext
        cmp xtext.ref xtext.tmp
        rm -f xtext.ref xtext.tmp
 
+mail_version_test: mail_version mail_version.in mail_version.ref
+       ./mail_version <mail_version.in >mail_version.tmp
+       diff  mail_version.ref mail_version.tmp
+       rm -f mail_version.tmp
+
 # Requires: Postfix running, root privileges
 
 rewrite_clnt_test: rewrite_clnt rewrite_clnt.in rewrite_clnt.ref
@@ -850,6 +865,23 @@ dict_ldap.o: dict_ldap.c
 dict_ldap.o: dict_ldap.h
 dict_ldap.o: mail_conf.h
 dict_ldap.o: string_list.h
+dict_memcache.o: ../../include/argv.h
+dict_memcache.o: ../../include/binhash.h
+dict_memcache.o: ../../include/dict.h
+dict_memcache.o: ../../include/match_list.h
+dict_memcache.o: ../../include/match_ops.h
+dict_memcache.o: ../../include/msg.h
+dict_memcache.o: ../../include/mymalloc.h
+dict_memcache.o: ../../include/stringops.h
+dict_memcache.o: ../../include/sys_defs.h
+dict_memcache.o: ../../include/vbuf.h
+dict_memcache.o: ../../include/vstream.h
+dict_memcache.o: ../../include/vstring.h
+dict_memcache.o: cfg_parser.h
+dict_memcache.o: db_common.h
+dict_memcache.o: dict_memcache.c
+dict_memcache.o: dict_memcache.h
+dict_memcache.o: string_list.h
 dict_mysql.o: ../../include/argv.h
 dict_mysql.o: ../../include/dict.h
 dict_mysql.o: ../../include/events.h
@@ -1302,6 +1334,7 @@ mail_dict.o: ../../include/vbuf.h
 mail_dict.o: ../../include/vstream.h
 mail_dict.o: ../../include/vstring.h
 mail_dict.o: dict_ldap.h
+mail_dict.o: dict_memcache.h
 mail_dict.o: dict_mysql.h
 mail_dict.o: dict_pgsql.h
 mail_dict.o: dict_proxy.h
@@ -1437,7 +1470,14 @@ mail_trigger.o: ../../include/vstream.h
 mail_trigger.o: mail_params.h
 mail_trigger.o: mail_proto.h
 mail_trigger.o: mail_trigger.c
+mail_version.o: ../../include/mymalloc.h
+mail_version.o: ../../include/split_at.h
+mail_version.o: ../../include/stringops.h
+mail_version.o: ../../include/sys_defs.h
+mail_version.o: ../../include/vbuf.h
+mail_version.o: ../../include/vstring.h
 mail_version.o: mail_version.c
+mail_version.o: mail_version.h
 maps.o: ../../include/argv.h
 maps.o: ../../include/dict.h
 maps.o: ../../include/msg.h
@@ -1520,7 +1560,15 @@ mime_state.o: mail_params.h
 mime_state.o: mime_state.c
 mime_state.o: mime_state.h
 mime_state.o: rec_type.h
+mkmap_cdb.o: ../../include/argv.h
+mkmap_cdb.o: ../../include/dict.h
+mkmap_cdb.o: ../../include/dict_cdb.h
+mkmap_cdb.o: ../../include/mymalloc.h
 mkmap_cdb.o: ../../include/sys_defs.h
+mkmap_cdb.o: ../../include/vbuf.h
+mkmap_cdb.o: ../../include/vstream.h
+mkmap_cdb.o: ../../include/vstring.h
+mkmap_cdb.o: mkmap.h
 mkmap_cdb.o: mkmap_cdb.c
 mkmap_db.o: ../../include/argv.h
 mkmap_db.o: ../../include/dict.h
index 6a2fa4bec29c1ea02f09d67dea379208cc5892b8..4dbeedb937871a60c3dc632f69dac16b7183d948 100644 (file)
@@ -49,6 +49,9 @@
 /*     value indicates that data-depedent '%' expansions were found in the input
 /*     template.
 /*
+/*     db_common_alloc() provides a way to use db_common_parse_domain()
+/*     etc. without prior db_common_parse() call.
+/*
 /*     \fIdb_common_expand\fR expands the specifiers in \fIformat\fR.
 /*     When the input data lacks all fields needed for the expansion, zero
 /*     is returned and the query or result should be skipped. Otherwise
@@ -163,6 +166,20 @@ typedef struct {
     int     nparts;
 } DB_COMMON_CTX;
 
+/* db_common_alloc - allocate db_common context */
+
+void   *db_common_alloc(DICT *dict)
+{
+    DB_COMMON_CTX *ctx;
+
+    ctx = (DB_COMMON_CTX *) mymalloc(sizeof *ctx);
+    ctx->dict = dict;
+    ctx->domain = 0;
+    ctx->flags = 0;
+    ctx->nparts = 0;
+    return ((void *) ctx);
+}
+
 /* db_common_parse - validate query or result template */
 
 int     db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query)
@@ -171,13 +188,9 @@ int     db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query
     const char *cp;
     int     dynamic = 0;
 
-    if (ctx == 0) {
-       ctx = (DB_COMMON_CTX *) (*ctxPtr = mymalloc(sizeof *ctx));
-       ctx->dict = dict;
-       ctx->domain = 0;
-       ctx->flags = 0;
-       ctx->nparts = 0;
-    }
+    if (ctx == 0)
+       ctx = (DB_COMMON_CTX *) (*ctxPtr = db_common_alloc(dict));
+
     for (cp = format; *cp; ++cp)
        if (*cp == '%')
            switch (*++cp) {
index ce7adc1e134a9d3086c7ffcd7e860bc0d1566ece..26ebf9731e9eca2f187af380fafc7df7096c3a1d 100644 (file)
@@ -21,6 +21,7 @@
 typedef void (*db_quote_callback_t)(DICT *, const char *, VSTRING *);
 
 extern int db_common_parse(DICT *, void **, const char *, int);
+extern void *db_common_alloc(DICT *);
 extern void db_common_parse_domain(CFG_PARSER *, void *);
 extern int db_common_dict_partial(void *);
 extern int db_common_expand(void *, const char *, const char *,
diff --git a/postfix/src/global/dict_memcache.c b/postfix/src/global/dict_memcache.c
new file mode 100644 (file)
index 0000000..ee3c33c
--- /dev/null
@@ -0,0 +1,493 @@
+/*++
+/* NAME
+/*     dict_memcache 3
+/* SUMMARY
+/*     dictionary interface to memcache databases
+/* SYNOPSIS
+/*     #include <dict_memcache.h>
+/*
+/*     DICT    *dict_memcache_open(name, open_flags, dict_flags)
+/*     const char *name;
+/*     int     open_flags;
+/*     int     dict_flags;
+/* DESCRIPTION
+/*     dict_memcache_open() opens a memcache database, providing
+/*     a dictionary interface for Postfix key->value mappings.
+/*     The result is a pointer to the installed dictionary.
+/*
+/*     Configuration parameters are described in memcache_table(5).
+/*
+/*     Arguments:
+/* .IP name
+/*     Either the path to the Postfix memcache configuration file
+/*     (if it starts with '/' or '.'), or the parameter name prefix
+/*     which will be used to obtain main.cf configuration parameters.
+/* .IP open_flags
+/*     O_RDONLY or O_RDWR. This function ignores flags that don't
+/*     specify a read, write or append mode.
+/* .IP dict_flags
+/*     See dict_open(3).
+/* SEE ALSO
+/*     dict(3) generic dictionary manager
+/* BUGS
+/*     This code requires libmemcache 1.4.0, because some parts
+/*     of their API are documented by looking at the implementation.
+/* HISTORY
+/*     The first memcache client for Postfix was written by:
+/*     Omar Kilani
+/*     omar@tinysofa.com
+/*     This implementation bears no resemblance to his work.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include "sys_defs.h"
+
+#ifdef HAS_MEMCACHE
+#include <string.h>
+#include <memcache.h>
+
+#if !defined(MEMCACHE_VERNUM) || MEMCACHE_VERNUM != 10400
+#error "Postfix memcache supports only libmemcache version 1.4.0"
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <dict.h>
+#include <vstring.h>
+#include <stringops.h>
+#include <binhash.h>
+
+/* Global library. */
+
+#include <cfg_parser.h>
+#include <db_common.h>
+
+/* Application-specific. */
+
+#include <dict_memcache.h>
+
+ /*
+  * Robustness tests (with a single memcache server) proved disappointing.
+  * 
+  * After failure to connect to the memcache server, libmemcache reports the
+  * error once. From then on it silently discards all updates and always
+  * reports "not found" for all lookups, without ever reporting an error. To
+  * avoid this, we destroy the memcache client and create a new one after
+  * libmemcache reports an error.
+  * 
+  * Even more problematic is that libmemcache will terminate the process when
+  * the memcache server connection is lost (the libmemcache error message is:
+  * "read(2) failed: Socket is already connected"). Unfortunately, telling
+  * libmemcache not to terminate the process will result in an assertion
+  * failure followed by core dump.
+  * 
+  * Conclusion: if we want robust code, then we should use our own memcache
+  * protocol implementation instead of libmemcache.
+  */
+
+ /*
+  * Structure of one memcache dictionary handle.
+  */
+typedef struct {
+    DICT    dict;                      /* parent class */
+    struct memcache_ctxt *mc_ctxt;     /* libmemcache context */
+    struct memcache *mc;               /* libmemcache object */
+    CFG_PARSER *parser;                        /* common parameter parser */
+    void   *dbc_ctxt;                  /* db_common context */
+    char   *key_format;                        /* query key translation */
+    int     mc_ttl;                    /* memcache expiration */
+    int     mc_flags;                  /* memcache flags */
+    VSTRING *key_buf;                  /* lookup key */
+    VSTRING *res_buf;                  /* lookup result */
+} DICT_MC;
+
+ /*
+  * Default memcache options.
+  */
+#define DICT_MC_DEF_HOST       "localhost"
+#define DICT_MC_DEF_PORT       "11211"
+#define DICT_MC_DEF_HOST_PORT  DICT_MC_DEF_HOST ":" DICT_MC_DEF_PORT
+#define DICT_MC_DEF_KEY_FMT    "%s"
+#define DICT_MC_DEF_TTL                (7 * 86400)
+#define DICT_MC_DEF_FLAGS      0
+
+ /*
+  * libmemcache can report errors through an application call-back function,
+  * but there is no support for passing application context to the call-back.
+  * The call-back API has two documented arguments: pointer to memcache_ctxt,
+  * and pointer to memcache_ectxt. The memcache_ctxt data structure has no
+  * space for application context, and the mcm_err() function zero-fills the
+  * memcache_ectxt data structure, making it useless for application context.
+  * 
+  * We use our own hash table to find our dictionary handle, so that we can
+  * report errors in the proper context.
+  */
+static BINHASH *dict_mc_hash;
+
+ /*
+  * SLMs.
+  */
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/*#define msg_verbose 1*/
+
+/* dict_memcache_error_cb - error call-back */
+
+static int dict_memcache_error_cb(MCM_ERR_FUNC_ARGS)
+{
+    const char *myname = "dict_memcache_error_cb";
+    const struct memcache_ctxt *ctxt;
+    struct memcache_err_ctxt *ectxt;
+    DICT_MC *dict_mc;
+    void    (*log_fn) (const char *,...);
+
+    /*
+     * Play by the rules of the libmemcache API.
+     */
+    MCM_ERR_INIT_CTXT(ctxt, ectxt);
+
+    /*
+     * Locate our own dictionary handle for error reporting context.
+     * Unfortunately, the ctxt structure does not store application context,
+     * and mcm_err() zero-fills the ectxt structure, making it useless for
+     * storing application context. We use our own hash table instead.
+     */
+    if ((dict_mc = (DICT_MC *) binhash_find(dict_mc_hash, (char *) &ctxt,
+                                           sizeof(ctxt))) == 0)
+       msg_panic("%s: can't locate DICT_MC database handle", myname);
+
+    /*
+     * Report the error in our context, and set dict_errno for possible
+     * errors. We override dict_errno when an error was recoverable.
+     */
+    switch (ectxt->severity) {
+    default:
+#ifdef DICT_MC_RECOVER_FROM_DISCONNECT
+       /* Code below causes an assert failure and core dump. */
+       if (ectxt->errcode == MCM_ERR_SYS_READ)
+           /* Also: MCM_ERR_SYS_WRITEV, MCM_ERR_SYS_SETSOCKOPT */
+           ectxt->cont = 'y';
+#endif
+       /* FALLTHROUGH */
+    case MCM_ERR_LVL_NOTICE:
+       log_fn = msg_warn;
+       dict_errno = 1;
+       break;
+    case MCM_ERR_LVL_INFO:
+       log_fn = msg_info;
+       break;
+    }
+    log_fn((ectxt)->errnum ? "database %s:%s: libmemcache error: %s: %m" :
+          "database %s:%s: libmemcache error: %s",
+          DICT_TYPE_MEMCACHE, dict_mc->dict.name, (ectxt)->errstr);
+    return (0);
+}
+
+static void dict_memcache_mc_free(DICT_MC *);
+static void dict_memcache_mc_init(DICT_MC *);
+
+/* dict_memcache_recover - recover after libmemcache error */
+
+static void dict_memcache_recover(DICT_MC *dict_mc)
+{
+    int     saved_dict_errno;
+
+    /*
+     * XXX If we don't try to recover from the first error, libmemcache will
+     * silently skip all subsequent database operations.
+     */
+    saved_dict_errno = dict_errno;
+    dict_memcache_mc_free(dict_mc);
+    dict_memcache_mc_init(dict_mc);
+    dict_errno = saved_dict_errno;
+}
+
+/* dict_memcache_prepare_key - prepare lookup key */
+
+static int dict_memcache_prepare_key(DICT_MC *dict_mc, const char *name)
+{
+
+    /*
+     * Optionally case-fold the search string.
+     */
+    if (dict_mc->dict.flags & DICT_FLAG_FOLD_FIX) {
+       if (dict_mc->dict.fold_buf == 0)
+           dict_mc->dict.fold_buf = vstring_alloc(10);
+       vstring_strcpy(dict_mc->dict.fold_buf, name);
+       name = lowercase(STR(dict_mc->dict.fold_buf));
+    }
+
+    /*
+     * Optionally expand the query key format.
+     */
+#define DICT_MC_NO_KEY         (0)
+#define DICT_MC_NO_QUOTING     ((void (*)(DICT *, const char *, VSTRING *)) 0)
+
+    if (dict_mc->key_format != 0
+       && strcmp(dict_mc->key_format, DICT_MC_DEF_KEY_FMT) != 0) {
+       VSTRING_RESET(dict_mc->key_buf);
+       if (db_common_expand(dict_mc->dbc_ctxt, dict_mc->key_format,
+                            name, DICT_MC_NO_KEY, dict_mc->key_buf,
+                            DICT_MC_NO_QUOTING) == 0)
+           return (0);
+    } else {
+       vstring_strcpy(dict_mc->key_buf, name);
+    }
+
+    /*
+     * The length indicates whether the expansion is empty or not.
+     */
+    return (LEN(dict_mc->key_buf));
+}
+
+/* dict_memcache_update - update memcache database */
+
+static void dict_memcache_update(DICT *dict, const char *name,
+                                        const char *value)
+{
+    const char *myname = "dict_memcache_update";
+    DICT_MC *dict_mc = (DICT_MC *) dict;
+
+    /*
+     * Skip updates with a null key, noisily. This would result in loss of
+     * information.
+     */
+    if (dict_memcache_prepare_key(dict_mc, name) == 0) {
+       dict_errno = 1;
+       msg_warn("database %s:%s: name \"%s\" expands to empty lookup key "
+                "-- skipping update", DICT_TYPE_MEMCACHE,
+                dict_mc->dict.name, name);
+       return;
+    }
+
+    /*
+     * Our error call-back routine will report errors and set dict_errno.
+     */
+    dict_errno = (mcm_set(dict_mc->mc_ctxt, dict_mc->mc, STR(dict_mc->key_buf),
+                         LEN(dict_mc->key_buf), value, strlen(value),
+                         dict_mc->mc_ttl, dict_mc->mc_flags) != 0);
+    if (msg_verbose)
+       msg_info("%s: %s: update key \"%s\" => \"%s\" %s",
+                myname, dict_mc->dict.name, STR(dict_mc->key_buf), value,
+                dict_errno ? "(error)" : "(no error)");
+
+    /*
+     * Recover after server failure.
+     */
+    if (dict_errno)
+       dict_memcache_recover(dict_mc);
+}
+
+/* dict_memcache_lookup - lookup memcache database */
+
+static const char *dict_memcache_lookup(DICT *dict, const char *name)
+{
+    const char *myname = "dict_memcache_lookup";
+    DICT_MC *dict_mc = (DICT_MC *) dict;
+    struct memcache_req *req;
+    struct memcache_res *res;
+    const char *retval;
+
+    /*
+     * Skip lookups with a null key, silently. This is just asking for
+     * information that cannot exist.
+     */
+#define DICT_MC_SKIP(why, map_name, key) do { \
+       if (msg_verbose) \
+           msg_info("%s: %s: skipping lookup of key \"%s\": %s", \
+                    myname, (map_name), (key), (why)); \
+       return (0); \
+    } while (0)
+
+    if (*name == 0)
+       DICT_MC_SKIP("empty lookup key", dict_mc->dict.name, name);
+    if (db_common_check_domain(dict_mc->dbc_ctxt, name) == 0)
+       DICT_MC_SKIP("domain mismatch", dict_mc->dict.name, name);
+    if (dict_memcache_prepare_key(dict_mc, name) == 0)
+       DICT_MC_SKIP("empty lookup key expansion", dict_mc->dict.name, name);
+
+    /*
+     * Our error call-back routine will report errors and set dict_errno. We
+     * reset dict_errno after an error turns out to be recoverable.
+     */
+    if ((req = mcm_req_new(dict_mc->mc_ctxt)) == 0)
+       msg_fatal("%s: can't create new request: %m", myname);  /* XXX */
+    /* Not: mcm_req_add(), because that makes unnecessary copy of the key. */
+    if ((res = mcm_req_add_ref(dict_mc->mc_ctxt, req, STR(dict_mc->key_buf),
+                              LEN(dict_mc->key_buf))) == 0)
+       msg_fatal("%s: can't create new result: %m", myname);   /* XXX */
+
+    dict_errno = 0;
+    mcm_get(dict_mc->mc_ctxt, dict_mc->mc, req);
+    if (mcm_res_found(dict_mc->mc_ctxt, res) && res->bytes) {
+       vstring_strncpy(dict_mc->res_buf, res->val, res->bytes);
+       retval = STR(dict_mc->res_buf);
+       dict_errno = 0;
+    } else {
+       retval = 0;
+    }
+    mcm_res_free(dict_mc->mc_ctxt, req, res);
+    mcm_req_free(dict_mc->mc_ctxt, req);
+
+    if (msg_verbose)
+       msg_info("%s: %s: key %s => %s",
+                myname, dict_mc->dict.name, STR(dict_mc->key_buf),
+                retval ? STR(dict_mc->res_buf) :
+                dict_errno ? "(error)" : "(not found)");
+
+    /*
+     * Recover after server failure.
+     */
+    if (dict_errno)
+       dict_memcache_recover(dict_mc);
+
+    return (retval);
+}
+
+/* dict_memcache_mc_free - destroy libmemcache objects */
+
+static void dict_memcache_mc_free(DICT_MC *dict_mc)
+{
+    binhash_delete(dict_mc_hash, (char *) &dict_mc->mc_ctxt,
+                  sizeof(dict_mc->mc_ctxt), (void (*) (char *)) 0);
+    mcm_free(dict_mc->mc_ctxt, dict_mc->mc);
+    mcMemFreeCtxt(dict_mc->mc_ctxt);
+}
+
+/* dict_memcache_mc_init - create libmemcache objects */
+
+static void dict_memcache_mc_init(DICT_MC *dict_mc)
+{
+    const char *myname = "dict_memcache_mc_init";
+    char   *servers;
+    char   *server;
+    char   *cp;
+
+    /*
+     * Create the libmemcache objects.
+     */
+    dict_mc->mc_ctxt =
+       mcMemNewCtxt((mcFreeFunc) myfree, (mcMallocFunc) mymalloc,
+                    (mcMallocFunc) mymalloc, (mcReallocFunc) myrealloc);
+    if (dict_mc->mc_ctxt == 0)
+       msg_fatal("error creating memcache context: %m");       /* XXX */
+    dict_mc->mc = mcm_new(dict_mc->mc_ctxt);
+    if (dict_mc->mc == 0)
+       msg_fatal("error creating memcache object: %m");        /* XXX */
+
+    /*
+     * Set up call-back info for error reporting.
+     */
+    if (dict_mc_hash == 0)
+       dict_mc_hash = binhash_create(1);
+    binhash_enter(dict_mc_hash, (char *) &dict_mc->mc_ctxt,
+                 sizeof(dict_mc->mc_ctxt), (char *) dict_mc);
+    mcErrSetupCtxt(dict_mc->mc_ctxt, dict_memcache_error_cb);
+
+    /*
+     * Add the server list.
+     */
+    cp = servers = cfg_get_str(dict_mc->parser, "hosts",
+                              DICT_MC_DEF_HOST_PORT, 0, 0);
+    while ((server = mystrtok(&cp, " ,\t\r\n")) != 0) {
+       if (msg_verbose)
+           msg_info("%s: database %s:%s: adding server %s",
+                    myname, DICT_TYPE_MEMCACHE, dict_mc->dict.name, server);
+       if (mcm_server_add4(dict_mc->mc_ctxt, dict_mc->mc, server) < 0)
+           msg_warn("database %s:%s: error adding server %s",
+                    DICT_TYPE_MEMCACHE, dict_mc->dict.name, server);
+    }
+    myfree(servers);
+}
+
+/* dict_memcache_close - close memcache database */
+
+static void dict_memcache_close(DICT *dict)
+{
+    DICT_MC *dict_mc = (DICT_MC *) dict;
+
+    dict_memcache_mc_free(dict_mc);
+    cfg_parser_free(dict_mc->parser);
+    db_common_free_ctx(dict_mc->dbc_ctxt);
+    vstring_free(dict_mc->key_buf);
+    vstring_free(dict_mc->res_buf);
+    if (dict_mc->key_format)
+       myfree(dict_mc->key_format);
+    if (dict->fold_buf)
+       vstring_free(dict->fold_buf);
+    dict_free(dict);
+}
+
+/* dict_memcache_open - open memcache database */
+
+DICT   *dict_memcache_open(const char *name, int open_flags, int dict_flags)
+{
+    DICT_MC *dict_mc;
+
+    /*
+     * Sanity checks.
+     */
+    if (dict_flags & DICT_FLAG_NO_UNAUTH)
+       msg_fatal("%s:%s map is not allowed for security-sensitive data",
+                 DICT_TYPE_MEMCACHE, name);
+    open_flags &= (O_RDONLY | O_RDWR | O_WRONLY | O_APPEND);
+    if (open_flags != O_RDONLY && open_flags != O_RDWR)
+       msg_fatal("%s:%s map requires O_RDONLY or O_RDWR access mode",
+                 DICT_TYPE_MEMCACHE, name);
+
+    /*
+     * Create the dictionary object.
+     */
+    dict_mc = (DICT_MC *) dict_alloc(DICT_TYPE_MEMCACHE, name,
+                                    sizeof(*dict_mc));
+    dict_mc->dict.lookup = dict_memcache_lookup;
+    if (open_flags == O_RDWR)
+       dict_mc->dict.update = dict_memcache_update;
+    dict_mc->dict.close = dict_memcache_close;
+    dict_mc->dict.flags = dict_flags;
+    dict_mc->key_buf = vstring_alloc(10);
+    dict_mc->res_buf = vstring_alloc(10);
+
+    /*
+     * Parse the configuration file.
+     */
+    dict_mc->parser = cfg_parser_alloc(name);
+    dict_mc->key_format = cfg_get_str(dict_mc->parser, "key_format",
+                                     DICT_MC_DEF_KEY_FMT, 0, 0);
+    dict_mc->mc_ttl = cfg_get_int(dict_mc->parser, "ttl",
+                                 DICT_MC_DEF_TTL, 0, 0);
+    dict_mc->mc_flags = cfg_get_int(dict_mc->parser, "flags",
+                                   DICT_MC_DEF_FLAGS, 0, 0);
+
+    /*
+     * Initialize the memcache objects.
+     */
+    dict_memcache_mc_init(dict_mc);
+
+    /*
+     * Parse templates and common database parameters. Maps that use
+     * substring keys should only be used with the full input key.
+     */
+    dict_mc->dbc_ctxt = 0;
+    db_common_parse(&dict_mc->dict, &dict_mc->dbc_ctxt,
+                   dict_mc->key_format, 1);
+    db_common_parse_domain(dict_mc->parser, dict_mc->dbc_ctxt);
+    if (db_common_dict_partial(dict_mc->dbc_ctxt))
+       /* Breaks recipient delimiters */
+       dict_mc->dict.flags |= DICT_FLAG_PATTERN;
+    else
+       dict_mc->dict.flags |= DICT_FLAG_FIXED;
+
+    return (&dict_mc->dict);
+}
+
+#endif
diff --git a/postfix/src/global/dict_memcache.h b/postfix/src/global/dict_memcache.h
new file mode 100644 (file)
index 0000000..3b6e7a4
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _DICT_MEMCACHE_INCLUDED_
+#define _DICT_MEMCACHE_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_memcache 3h
+/* SUMMARY
+/*     dictionary interface to memcache databases
+/* SYNOPSIS
+/*     #include <dict_memcache.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_MEMCACHE "memcache"
+
+extern DICT *dict_memcache_open(const char *name, int unused_flags,
+                                       int dict_flags);
+
+/* 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 337861d112fced922e72e581f8a1051d65c90e78..3d456ea7d02d9c6353c932726e1782c4cc0a1f40 100644 (file)
@@ -37,6 +37,7 @@
 #include <dict_mysql.h>
 #include <dict_pgsql.h>
 #include <dict_sqlite.h>
+#include <dict_memcache.h>
 #include <mail_dict.h>
 
 typedef struct {
@@ -57,6 +58,9 @@ static const DICT_OPEN_INFO dict_open_info[] = {
 #endif
 #ifdef HAS_SQLITE
     DICT_TYPE_SQLITE, dict_sqlite_open,
+#endif
+#ifdef HAS_MEMCACHE
+    DICT_TYPE_MEMCACHE, dict_memcache_open,
 #endif
     0,
 };
@@ -70,3 +74,17 @@ void    mail_dict_init(void)
     for (dp = dict_open_info; dp->type; dp++)
        dict_open_register(dp->type, dp->open);
 }
+
+#ifdef TEST
+
+ /*
+  * Proof-of-concept test program.
+  */
+int     main(int argc, char **argv)
+{
+    mail_dict_init();
+    dict_test(argc, argv);
+    return (0);
+}
+
+#endif
index ad0505b980e175c6a815487d0dd3f25aeab4f874..da5dc31afc88c131ecfcb8eb557f03de5051c19c 100644 (file)
@@ -257,6 +257,7 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_CIPHER_NAME  "cipher_name"
 #define MAIL_ATTR_CIPHER_USEBITS "cipher_usebits"
 #define MAIL_ATTR_CIPHER_ALGBITS "cipher_algbits"
+#define MAIL_ATTR_SERVER_ID    "server_id"
 
  /*
   * SMTP reply footer support.
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6b2402132640dfab72a617ab47d6a4468f9688f5 100644 (file)
@@ -0,0 +1,258 @@
+/*++
+/* NAME
+/*     mail_version 3
+/* SUMMARY
+/*     time-dependent probe sender addresses
+/* SYNOPSIS
+/*     #include <mail_version.h>
+/*
+/*     typedef struct {
+/*         char   *program;            /* postfix */
+/*         int     major;              /* 2 */
+/*         int     minor;              /* 9 */
+/*         int     patch;              /* patchlevel or -1 */
+/*         char   *snapshot;           /* null or snapshot info */
+/*     } MAIL_VERSION;
+/*
+/*     MAIL_VERSION *mail_version_parse(version_string, why)
+/*     const char *version_string;
+/*     const char **why;
+/*
+/*     void    mail_version_free(mp)
+/*     MAIL_VERSION *mp;
+/*
+/*     const char *get_mail_version()
+/*
+/*     int     check_mail_version(version_string)
+/*     const char *version_string;
+/* DESCRIPTION
+/*     This module understands the format of Postfix version strings
+/*     (for example the default value of "mail_version"), and
+/*     provides support to compare the compile-time version of a
+/*     Postfix program with the run-time version of a Postfix
+/*     library. Apparently, some distributions don't use proper
+/*     so-number versioning, causing programs to fail erratically
+/*     after an update replaces the library but not the program.
+/*
+/*     A Postfix version string consists of two or three parts
+/*     separated by a single "-" character:
+/* .IP \(bu
+/*     The first part is a string with the program name.
+/* .IP \(bu
+/*     The second part is the program version: either two or three
+/*     non-negative integer numbers separated by single "."
+/*     character. Stable releases have a major version, minor
+/*     version and patchlevel; experimental releases (snapshots)
+/*     have only major and minor version numbers.
+/* .IP \(bu
+/*     The third part is ignored with a stable release, otherwise
+/*     it is a string with the snapshot release date plus some
+/*     optional information.
+/*
+/*     mail_version_parse() parses a version string.
+/*
+/*     get_mail_version() returns the version string (the value
+/*     of DEF_MAIL_VERSION) that is compiled into the library.
+/*
+/*     check_mail_version() compares the caller's version string
+/*     (usually the value of DEF_MAIL_VERSION) that is compiled
+/*     into the caller, and logs a warning when the strings differ.
+/* DIAGNOSTICS
+/*     In the case of a parsing error, mail_version_parse() returns
+/*     a null pointer, and sets the why argument to a string with
+/*     problem details.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <split_at.h>
+
+/* Global library. */
+
+#include <mail_version.h>
+
+/* mail_version_int - convert integer */
+
+static int mail_version_int(const char *strval)
+{
+    char   *end;
+    int     intval;
+    long    longval;
+
+    errno = 0;
+    intval = longval = strtol(strval, &end, 10);
+    if (*strval == 0 || *end != 0 || errno == ERANGE || longval != intval)
+       intval = (-1);
+    return (intval);
+}
+
+/* mail_version_worker - do the parsing work */
+
+static const char *mail_version_worker(MAIL_VERSION *mp, char *cp)
+{
+    char   *major_field;
+    char   *minor_field;
+    char   *patch_field;
+
+    /*
+     * Program name.
+     */
+    if ((mp->program = mystrtok(&cp, "-")) == 0)
+       return ("no program name");
+
+    /*
+     * Major, minor, patchlevel. If this is a stable release, then we ignore
+     * text after the patchlevel, in case there are vendor extensions.
+     */
+    if ((major_field = mystrtok(&cp, "-")) == 0)
+       return ("missing major version");
+
+    if ((minor_field = split_at(major_field, '.')) == 0)
+       return ("missing minor version");
+    if ((mp->major = mail_version_int(major_field)) < 0)
+       return ("bad major version");
+    patch_field = split_at(minor_field, '.');
+    if ((mp->minor = mail_version_int(minor_field)) < 0)
+       return ("bad minor version");
+
+    if (patch_field == 0)
+       mp->patch = -1;
+    else if ((mp->patch = mail_version_int(patch_field)) < 0)
+       return ("bad patchlevel");
+
+    /*
+     * Experimental release. If this is not a stable release, we take
+     * everything to the end of the string.
+     */
+    if (patch_field != 0)
+       mp->snapshot = 0;
+    else if ((mp->snapshot = mystrtok(&cp, "")) == 0)
+       return ("missing snapshot field");
+
+    return (0);
+}
+
+/* mail_version_parse - driver */
+
+MAIL_VERSION *mail_version_parse(const char *string, const char **why)
+{
+    MAIL_VERSION *mp;
+    char   *saved_string;
+    const char *err;
+
+    mp = (MAIL_VERSION *) mymalloc(sizeof(*mp));
+    saved_string = mystrdup(string);
+    if ((err = mail_version_worker(mp, saved_string)) != 0) {
+       *why = err;
+       myfree(saved_string);
+       myfree((char *) mp);
+       return (0);
+    } else {
+       return (mp);
+    }
+}
+
+/* mail_version_free - destroy version information */
+
+void    mail_version_free(MAIL_VERSION *mp)
+{
+    myfree(mp->program);
+    myfree((char *) mp);
+}
+
+/* get_mail_version - return parsed mail version string */
+
+const char *get_mail_version(void)
+{
+    return (DEF_MAIL_VERSION);
+}
+
+/* check_mail_version - compare caller version with library version */
+
+void    check_mail_version(const char *version_string)
+{
+    if (strcmp(version_string, DEF_MAIL_VERSION) != 0)
+       msg_warn("Postfix library version mis-match: wanted %s, found %s",
+                version_string, DEF_MAIL_VERSION);
+}
+
+#ifdef TEST
+
+#include <unistd.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+
+#define STR(x) vstring_str(x)
+
+/* parse_sample - parse a sample string from argv or stdin */
+
+static void parse_sample(const char *sample)
+{
+    MAIL_VERSION *mp;
+    const char *why;
+
+    mp = mail_version_parse(sample, &why);
+    if (mp == 0) {
+       vstream_printf("ERROR: %s: %s\n", sample, why);
+    } else {
+       vstream_printf("program: %s\t", mp->program);
+       vstream_printf("major: %d\t", mp->major);
+       vstream_printf("minor: %d\t", mp->minor);
+       if (mp->patch < 0)
+           vstream_printf("snapshot: %s\n", mp->snapshot);
+       else
+           vstream_printf("patch: %d\n", mp->patch);
+       mail_version_free(mp);
+    }
+    vstream_fflush(VSTREAM_OUT);
+}
+
+/* main - the main program */
+
+int     main(int argc, char **argv)
+{
+    VSTRING *inbuf = vstring_alloc(1);
+    int     have_tty = isatty(0);
+
+    if (argc > 1) {
+       while (--argc > 0 && *++argv)
+           parse_sample(*argv);
+    } else {
+       for (;;) {
+           if (have_tty) {
+               vstream_printf("> ");
+               vstream_fflush(VSTREAM_OUT);
+           }
+           if (vstring_fgets_nonl(inbuf, VSTREAM_IN) <= 0)
+               break;
+           if (have_tty == 0)
+               vstream_printf("> %s\n", STR(inbuf));
+           if (*STR(inbuf) == 0 || *STR(inbuf) == '#')
+               continue;
+           parse_sample(STR(inbuf));
+       }
+    }
+    vstring_free(inbuf);
+    return (0);
+}
+
+#endif
index b7c89e0f6aa3fa8bc6660e9f3ccb7a1e2fa780df..2f815b66181c77c888390d87c5f94f97fb699166 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20111205"
+#define MAIL_RELEASE_DATE      "20111209"
 #define MAIL_VERSION_NUMBER    "2.9"
 
 #ifdef SNAPSHOT
@@ -67,6 +67,29 @@ extern char *var_mail_release;
 #define MAIL_VERSION_STAMP_ALLOCATE \
     mail_version_stamp = strdup(VAR_MAIL_VERSION "=" DEF_MAIL_VERSION)
 
+ /*
+  * Mail version string parser, plus support to compare the compile-time
+  * version string of a Postfix program with the run-time version string of a
+  * Postfix shared library. When programs are not updated, they may fail in
+  * erratic ways when linked against a newer run-time library. Of course the
+  * right solution is so-number versioning of the Postfix run-time library.
+  */
+typedef struct {
+    char   *program;                   /* postfix */
+    int     major;                     /* 2 */
+    int     minor;                     /* 9 */
+    int     patch;                     /* null */
+    char   *snapshot;                  /* 20111209-nonprod */
+} MAIL_VERSION;
+
+extern MAIL_VERSION *mail_version_parse(const char *, const char **);
+extern void mail_version_free(MAIL_VERSION *);
+extern const char *get_mail_version(void);
+extern void check_mail_version(const char *);
+
+#define MAIL_VERSION_CHECK \
+    check_mail_version(DEF_MAIL_VERSION)
+
 /* LICENSE
 /* .ad
 /* .fi
diff --git a/postfix/src/global/mail_version.in b/postfix/src/global/mail_version.in
new file mode 100644 (file)
index 0000000..1cf75d8
--- /dev/null
@@ -0,0 +1,8 @@
+1
+1-2
+1-2.3
+1-2.3.4.5
+1-2.3.4-5
+1-2.3-5
+1-2.3-5-6
+1-2.3-5.6
diff --git a/postfix/src/global/mail_version.ref b/postfix/src/global/mail_version.ref
new file mode 100644 (file)
index 0000000..5dbc3ab
--- /dev/null
@@ -0,0 +1,16 @@
+> 1
+ERROR: 1: missing major version
+> 1-2
+ERROR: 1-2: missing minor version
+> 1-2.3
+ERROR: 1-2.3: missing snapshot field
+> 1-2.3.4.5
+ERROR: 1-2.3.4.5: bad patchlevel
+> 1-2.3.4-5
+program: 1     major: 2        minor: 3        patch: 4
+> 1-2.3-5
+program: 1     major: 2        minor: 3        snapshot: 5
+> 1-2.3-5-6
+program: 1     major: 2        minor: 3        snapshot: 5-6
+> 1-2.3-5.6
+program: 1     major: 2        minor: 3        snapshot: 5.6
index 53f65bd9eeaaf431d05f8027987c907ab65b067e..a78173916478299a80179251748374aa9ec3e19c 100644 (file)
@@ -92,6 +92,7 @@ event_server.o: ../../include/mail_conf.h
 event_server.o: ../../include/mail_dict.h
 event_server.o: ../../include/mail_params.h
 event_server.o: ../../include/mail_task.h
+event_server.o: ../../include/mail_version.h
 event_server.o: ../../include/msg.h
 event_server.o: ../../include/msg_syslog.h
 event_server.o: ../../include/msg_vstream.h
@@ -278,6 +279,7 @@ multi_server.o: ../../include/mail_conf.h
 multi_server.o: ../../include/mail_dict.h
 multi_server.o: ../../include/mail_params.h
 multi_server.o: ../../include/mail_task.h
+multi_server.o: ../../include/mail_version.h
 multi_server.o: ../../include/msg.h
 multi_server.o: ../../include/msg_syslog.h
 multi_server.o: ../../include/msg_vstream.h
@@ -307,6 +309,7 @@ single_server.o: ../../include/mail_conf.h
 single_server.o: ../../include/mail_dict.h
 single_server.o: ../../include/mail_params.h
 single_server.o: ../../include/mail_task.h
+single_server.o: ../../include/mail_version.h
 single_server.o: ../../include/msg.h
 single_server.o: ../../include/msg_syslog.h
 single_server.o: ../../include/msg_vstream.h
@@ -336,6 +339,7 @@ trigger_server.o: ../../include/mail_conf.h
 trigger_server.o: ../../include/mail_dict.h
 trigger_server.o: ../../include/mail_params.h
 trigger_server.o: ../../include/mail_task.h
+trigger_server.o: ../../include/mail_version.h
 trigger_server.o: ../../include/msg.h
 trigger_server.o: ../../include/msg_syslog.h
 trigger_server.o: ../../include/msg_vstream.h
index 21ff0d5a946d3f1bff0c3919a5dc942c33ef90e6..37d7e097059850a8181f6727ee52302c9b8e51a1 100644 (file)
 #include <timed_ipc.h>
 #include <resolve_local.h>
 #include <mail_flow.h>
+#include <mail_version.h>
 
 /* Process manager. */
 
@@ -577,6 +578,11 @@ NORETURN event_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     if (msg_verbose)
        msg_info("daemon started");
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Initialize from the configuration file. Allow command-line options to
      * override compiled-in defaults or configured parameter values.
index cef01e4017b830de3926306814c18db89af018f3..532eb789e438ecde42628cdb08d7f697d28d6710 100644 (file)
@@ -293,6 +293,11 @@ int     main(int argc, char **argv)
      */
     msg_syslog_init(mail_task(var_procname), LOG_PID, LOG_FACILITY);
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * The mail system must be run by the superuser so it can revoke
      * privileges for selected operations. That's right - it takes privileges
index 6477894f57a7a77ece39bbc30ef8e5504ac7b8bc..0b5e678c614d60b2ea35c2ba13fe1eda02ffc92e 100644 (file)
 #include <timed_ipc.h>
 #include <resolve_local.h>
 #include <mail_flow.h>
+#include <mail_version.h>
 
 /* Process manager. */
 
@@ -573,6 +574,11 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     if (msg_verbose)
        msg_info("daemon started");
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Initialize from the configuration file. Allow command-line options to
      * override compiled-in defaults or configured parameter values.
index 94937eb978bb284b6cc412c7b17f4aa27a51b490..aba479cd51225838ac71caa3bdca93904bd8e9c5 100644 (file)
 #include <timed_ipc.h>
 #include <resolve_local.h>
 #include <mail_flow.h>
+#include <mail_version.h>
 
 /* Process manager. */
 
@@ -456,6 +457,11 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     if (msg_verbose)
        msg_info("daemon started");
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Initialize from the configuration file. Allow command-line options to
      * override compiled-in defaults or configured parameter values.
index 10d6621a21d4f35b07939aa25a130882659f77a5..df3bf2054ff782a87cdd631caef8481a4fdb8f27 100644 (file)
 #include <mail_dict.h>
 #include <resolve_local.h>
 #include <mail_flow.h>
+#include <mail_version.h>
 
 /* Process manager. */
 
@@ -467,6 +468,11 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     if (msg_verbose)
        msg_info("daemon started");
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Initialize from the configuration file. Allow command-line options to
      * override compiled-in defaults or configured parameter values.
index 34336cd7e301382dc3c6072cdfd5741a05c670c6..9b17d0207f3a73988c9f1989d7696d9f80adc750 100644 (file)
@@ -669,6 +669,11 @@ int     main(int argc, char **argv)
     msg_vstream_init(argv[0], VSTREAM_ERR);
     msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Parse JCL.
      */
index 0de2b48ec8ea245bb6669480a717836250fa8ff8..eea582ac605c1bc6457a1ffe844a14e0e4be7a9c 100644 (file)
 /* .IP "\fBldap\fR (read-only)"
 /*     Perform lookups using the LDAP protocol. This is described
 /*     in \fBldap_table\fR(5).
+/* .IP "\fBmemcache\fR (read-write)"
+/*     Perform lookups using the memcache protocol. This is described
+/*     in \fBmemcache_table\fR(5).
 /* .IP "\fBmysql\fR (read-only)"
 /*     Perform lookups using the MYSQL protocol. This is described
 /*     in \fBmysql_table\fR(5).
index a2df01ecec9ea7e5eee987f920d753e7541e8336..84f8e69e0d47a0a8d1e378ee7a7232f4a91d4390 100644 (file)
@@ -265,6 +265,11 @@ int     main(int argc, char **argv)
     msg_syslog_init(mail_task("postdrop"), LOG_PID, LOG_FACILITY);
     set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Parse JCL. This program is set-gid and must sanitize all command-line
      * arguments. The configuration directory argument is validated by the
index c7b8c97ecdd7b05bb3fc1918206380644a0c5bc0..60343668eb526fafaf84315901ab50d70db931f3 100644 (file)
 /*     Table lookup mechanisms:
 /*     cidr_table(5), Associate CIDR pattern with value
 /*     ldap_table(5), Postfix LDAP client
+/*     memcache_table(5), Postfix memcache client
 /*     mysql_table(5), Postfix MYSQL client
 /*     nisplus_table(5), Postfix NIS+ client
 /*     pcre_table(5), Associate PCRE pattern with value
@@ -436,6 +437,11 @@ int     main(int argc, char **argv)
        msg_vstream_init(argv[0], VSTREAM_ERR);
     msg_syslog_init(argv[0], LOG_PID, LOG_FACILITY);
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * The mail system must be run by the superuser so it can revoke
      * privileges for selected operations. That's right - it takes privileges
@@ -524,7 +530,7 @@ int     main(int argc, char **argv)
     /*
      * Run the management script.
      */
-    if (force_single_instance 
+    if (force_single_instance
        || argv_split(var_multi_conf_dirs, "\t\r\n, ")->argc == 0) {
        script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
        if (optind < 1)
index 000ff70d68bd813f3bdf9fee4412e45d1e778b47..67715ae9e71445b4ba79c3a055b09bf3fc8a4ea2 100644 (file)
@@ -208,6 +208,11 @@ int     main(int argc, char **argv)
     msg_syslog_init(tag, LOG_PID, LOG_FACILITY);
     tag = 0;
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Parse switches.
      */
index e956aed9b5d210d923fdc75623ec1fcfffac17ef..19bb02e5b9870209450c6c0046f19652442aead8 100644 (file)
@@ -784,6 +784,11 @@ int     main(int argc, char **argv)
     msg_vstream_init(argv[0], VSTREAM_ERR);
     msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Parse JCL.
      */
@@ -857,7 +862,7 @@ int     main(int argc, char **argv)
     if (strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0)
        msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
     mail_dict_init();
-    if ((query == 0 || strcmp(query, "-") != 0) 
+    if ((query == 0 || strcmp(query, "-") != 0)
        && (postmap_flags & POSTMAP_FLAG_ANY_KEY))
        msg_fatal("specify -b -h or -m only with \"-q -\"");
 
index 30633ae262eaa2c065027674872ad73394a8fd0e..c0ff9df36fa4575dc5c0a50e4fb278ac2b5589e9 100644 (file)
@@ -1658,6 +1658,11 @@ int     main(int argc, char **argv)
        msg_vstream_init(argv[0], VSTREAM_ERR);
     msg_syslog_init(argv[0], LOG_PID, LOG_FACILITY);
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     if ((config_dir = getenv(CONF_ENV_PATH)) != 0
        && strcmp(config_dir, DEF_CONFIG_DIR) != 0)
        msg_fatal("Non-default configuration directory: %s=%s",
index 4dfedabb7d2a8d59e2524fe404f15a8264bef470..d6ed5ccc416fb1b32d8f05c3b9964aacce63014d 100644 (file)
@@ -477,6 +477,11 @@ int     main(int argc, char **argv)
     msg_syslog_init(mail_task("postqueue"), LOG_PID, LOG_FACILITY);
     set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Parse JCL. This program is set-gid and must sanitize all command-line
      * parameters. The configuration directory argument is validated by the
index d7307f8dc165eed98a8c8b17e3c76638cab91ebe..3b79900b8ceaad7e266a534fa2f686d95bb739cd 100644 (file)
@@ -1121,7 +1121,7 @@ int     main(int argc, char **argv)
        VAR_PSC_NSMTP_TTL, DEF_PSC_NSMTP_TTL, &var_psc_nsmtp_ttl, 1, 0,
        VAR_PSC_BARLF_TTL, DEF_PSC_BARLF_TTL, &var_psc_barlf_ttl, 1, 0,
        VAR_PSC_CACHE_RET, DEF_PSC_CACHE_RET, &var_psc_cache_ret, 1, 0,
-       VAR_PSC_CACHE_SCAN, DEF_PSC_CACHE_SCAN, &var_psc_cache_scan, 1, 0,
+       VAR_PSC_CACHE_SCAN, DEF_PSC_CACHE_SCAN, &var_psc_cache_scan, 0, 0,
        VAR_PSC_WATCHDOG, DEF_PSC_WATCHDOG, &var_psc_watchdog, 10, 0,
        0,
     };
index eb5d95a524d1dcd74b6a0f7e31949e897ae9a3e3..f9ad58bcd2c23163220e3ec4c31fb106d4760e25 100644 (file)
@@ -229,6 +229,7 @@ void    psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
               ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, STR(remote_endpt),
               ATTR_TYPE_INT, MAIL_ATTR_FLAGS, TLS_PROXY_FLAG_ROLE_SERVER,
               ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, psc_normal_cmd_time_limit,
+              ATTR_TYPE_STR, MAIL_ATTR_SERVER_ID, MAIL_SERVICE_SMTPD,  /* XXX */
               ATTR_TYPE_END);
     if (vstream_fflush(tlsproxy_stream) != 0) {
        msg_warn("error sending request to %s service: %m", psc_tlsp_service);
index fba2f1a39636c315ef5658d67722e267fa80fbec..7e3b2b98c97c68a9837438fd3d0cf7a24181aa18 100644 (file)
@@ -1137,6 +1137,11 @@ int     main(int argc, char **argv)
     msg_syslog_init(mail_task(argv[0]), LOG_PID, LOG_FACILITY);
     set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Disallow unsafe practices, and refuse to run set-uid (or as the child
      * of a set-uid process). Whenever a privileged wrapper program is
index a1a5dd7928bb9a2a0ca6741b017b60ca2a3a3e25..9560f4840ff599965dd277623e8fd1703e8484eb 100644 (file)
@@ -1016,6 +1016,11 @@ int     main(int argc, char **argv)
     msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
     set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
 
+    /*
+     * Check the Postfix library version as soon as we enable logging.
+     */
+    MAIL_VERSION_CHECK;
+
     /*
      * Some sites mistakenly install Postfix sendmail as set-uid root. Drop
      * set-uid privileges only when root, otherwise some systems will not
index 8a0fd74d712c5218ed511df4e31a0aea721902cc..8195f1b01eb87f9de415b76b297bf29c1f41f772 100644 (file)
@@ -692,7 +692,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
                         timeout = 0,           /* unused */
                         requirecert = (var_tlsp_tls_req_ccert
                                        && var_tlsp_enforce_tls),
-                        serverid = MAIL_SERVICE_SMTPD, /* XXX */
+                        serverid = state->server_id,
                         namaddr = state->remote_endpt,
                         cipher_grade = cipher_grade,
                         cipher_exclusions = STR(cipher_exclusions),
@@ -775,6 +775,7 @@ static void tlsp_get_request_event(int event, char *context)
     VSTREAM *plaintext_stream = state->plaintext_stream;
     int     plaintext_fd = vstream_fileno(plaintext_stream);
     static VSTRING *remote_endpt;
+    static VSTRING *server_id;
     int     req_flags;
     int     timeout;
     int     ready;
@@ -782,8 +783,10 @@ static void tlsp_get_request_event(int event, char *context)
     /*
      * One-time initialization.
      */
-    if (remote_endpt == 0)
+    if (remote_endpt == 0) {
        remote_endpt = vstring_alloc(10);
+       server_id = vstring_alloc(10);
+    }
 
     /*
      * At this point we still manually manage plaintext read/write/timeout
@@ -803,7 +806,8 @@ static void tlsp_get_request_event(int event, char *context)
                     ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
                     ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &req_flags,
                     ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, &timeout,
-                    ATTR_TYPE_END) != 3) {
+                    ATTR_TYPE_STR, MAIL_ATTR_SERVER_ID, server_id,
+                    ATTR_TYPE_END) != 4) {
        msg_warn("%s: receive request attributes: %m", myname);
        event_disable_readwrite(plaintext_fd);
        tlsp_state_free(state);
@@ -835,6 +839,7 @@ static void tlsp_get_request_event(int event, char *context)
      */
     else {
        state->remote_endpt = mystrdup(STR(remote_endpt));
+       state->server_id = mystrdup(STR(server_id));
        msg_info("CONNECT %s %s",
                 (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
                 (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
index 340e02fffc43b43b4ca65a9451ca6eea8d031495..e3e1d11fa38df2a8ed2b84c800799d369642eb8f 100644 (file)
@@ -32,6 +32,7 @@ typedef struct {
     EVENT_NOTIFY_FN ciphertext_timer;  /* kludge */
     int     timeout;                   /* read/write time limit */
     char   *remote_endpt;              /* printable remote endpoint */
+    char   *server_id;                 /* cache management */
     TLS_SESS_STATE *tls_context;       /* llibtls state */
     int     ssl_last_err;              /* TLS I/O state */
 } TLSP_STATE;
index 1dcf5b88966e3b85aad845407a6a437999fac87c..1161b89f5d635684089076f18898bbc4078c132e 100644 (file)
@@ -46,6 +46,9 @@
 /* .IP remote_endpt
 /*     Printable remote endpoint name.
 /*     The destructor will automatically destroy the string.
+/* .IP server_id
+/*     TLS session cache identifier.
+/*     The destructor will automatically destroy the string.
 /* DIAGNOSTICS
 /*     All errors are fatal.
 /* LICENSE
@@ -103,6 +106,7 @@ TLSP_STATE *tlsp_state_create(const char *service,
     state->ciphertext_timer = 0;
     state->timeout = -1;
     state->remote_endpt = 0;
+    state->server_id = 0;
     state->tls_context = 0;
 
     return (state);
@@ -126,6 +130,8 @@ void    tlsp_state_free(TLSP_STATE *state)
        msg_info("DISCONNECT %s", state->remote_endpt);
        myfree(state->remote_endpt);
     }
+    if (state->server_id)
+       myfree(state->server_id);
     if (state->tls_context)
        tls_free_context(state->tls_context);
     myfree((char *) state);
index 13c4048aa133197598299fdee6f25a019a28246c..7ecf8b319c7f46b7abe46b69fadaa30b7ba533a1 100644 (file)
@@ -33,7 +33,7 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        allascii.c load_file.c killme_after.c vstream_tweak.c \
        unix_pass_listen.c unix_pass_trigger.c edit_file.c inet_windowsize.c \
        unix_pass_fd_fix.c dict_cache.c valid_utf_8.c dict_thash.c \
-       ip_match.c nbbio.c stream_pass_connect.c base32_code.c
+       ip_match.c nbbio.c stream_pass_connect.c base32_code.c dict_test.c
 OBJS   = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
        attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -68,7 +68,7 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        allascii.o load_file.o killme_after.o vstream_tweak.o \
        unix_pass_listen.o unix_pass_trigger.o edit_file.o inet_windowsize.o \
        unix_pass_fd_fix.o dict_cache.o valid_utf_8.o dict_thash.o \
-       ip_match.o nbbio.o stream_pass_connect.o base32_code.o
+       ip_match.o nbbio.o stream_pass_connect.o base32_code.o dict_test.o
 HDRS   = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
        dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@@ -1039,6 +1039,17 @@ dict_tcp.o: vbuf.h
 dict_tcp.o: vstream.h
 dict_tcp.o: vstring.h
 dict_tcp.o: vstring_vstream.h
+dict_test.o: argv.h
+dict_test.o: dict.h
+dict_test.o: dict_test.c
+dict_test.o: msg.h
+dict_test.o: msg_vstream.h
+dict_test.o: stringops.h
+dict_test.o: sys_defs.h
+dict_test.o: vbuf.h
+dict_test.o: vstream.h
+dict_test.o: vstring.h
+dict_test.o: vstring_vstream.h
 dict_thash.o: argv.h
 dict_thash.o: dict.h
 dict_thash.o: dict_thash.c
index af41c766385714ba81d368197e05bb74e62e7e9b..0731a2b87fba52b5efb97c7fdf47f5884d56180d 100644 (file)
@@ -401,12 +401,26 @@ void    dict_load_file(const char *dict_name, const char *path)
 
 void    dict_load_fp(const char *dict_name, VSTREAM *fp)
 {
+    const char *myname = "dict_load_fp";
     VSTRING *buf;
     char   *member;
     char   *val;
     int     lineno;
     const char *err;
     struct stat st;
+    DICT_NODE *node;
+    DICT   *dict;
+
+    /*
+     * Instantiate the dictionary even if the file is empty.
+     */
+    if ((node = dict_node(dict_name)) == 0) {
+       if (dict_unknown_allowed == 0)
+           msg_fatal("%s: unknown dictionary: %s", myname, dict_name);
+       dict = dict_ht_open(dict_name, O_CREAT | O_RDWR, 0);
+       dict_register(dict_name, dict);
+    } else
+       dict = node->dict;
 
     buf = vstring_alloc(100);
     lineno = 0;
@@ -417,11 +431,13 @@ void    dict_load_fp(const char *dict_name, VSTREAM *fp)
        if ((err = split_nameval(STR(buf), &member, &val)) != 0)
            msg_fatal("%s, line %d: %s: \"%s\"",
                      VSTREAM_PATH(fp), lineno, err, STR(buf));
-       dict_update(dict_name, member, val);
+       if (msg_verbose > 1)
+           msg_info("%s: %s = %s", myname, member, val);
+       dict->update(dict, member, val);
     }
     vstring_free(buf);
-    dict_handle(dict_name)->owner.uid = st.st_uid;
-    dict_handle(dict_name)->owner.status = (st.st_uid != 0);
+    dict->owner.uid = st.st_uid;
+    dict->owner.status = (st.st_uid != 0);
 }
 
 /* dict_eval_lookup - macro parser call-back routine */
index e8449491dbf316dc5e2d9a25f4fd5eee77738b6b..36d49c89fc48c0e8b2994bfa28cb4486ef8a587b 100644 (file)
@@ -164,6 +164,11 @@ extern int dict_changed(void);
 extern const char *dict_changed_name(void);
 extern const char *dict_flags_str(int);
 
+ /*
+  * Driver for interactive or scripted tests.
+  */
+void    dict_test(int, char **);
+
 /* LICENSE
 /* .ad
 /* .fi
index 766fa00987cc81e507d95d1986d454336f940c09..d5ae3d5a0ba6a10a6ab2dcc6575901c25c851952 100644 (file)
@@ -382,135 +382,11 @@ ARGV   *dict_mapnames()
 #ifdef TEST
 
  /*
-  * Proof-of-concept test program. Create, update or read a database. When
-  * the input is a name=value pair, the database is updated, otherwise the
-  * program assumes that the input specifies a lookup key and prints the
-  * corresponding value.
+  * Proof-of-concept test program.
   */
-
-/* System library. */
-
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-
-/* Utility library. */
-
-#include "vstring.h"
-#include "vstream.h"
-#include "msg_vstream.h"
-#include "vstring_vstream.h"
-
-static NORETURN usage(char *myname)
-{
-    msg_fatal("usage: %s type:file read|write|create [fold] [sync]", myname);
-}
-
 int     main(int argc, char **argv)
 {
-    VSTRING *keybuf = vstring_alloc(1);
-    VSTRING *inbuf = vstring_alloc(1);
-    DICT   *dict;
-    char   *dict_name;
-    int     open_flags;
-    char   *bufp;
-    char   *cmd;
-    const char *key;
-    const char *value;
-    int     ch;
-    int     dict_flags = DICT_FLAG_LOCK | DICT_FLAG_DUP_REPLACE;
-    int     n;
-
-    signal(SIGPIPE, SIG_IGN);
-
-    msg_vstream_init(argv[0], VSTREAM_ERR);
-    while ((ch = GETOPT(argc, argv, "v")) > 0) {
-       switch (ch) {
-       default:
-           usage(argv[0]);
-       case 'v':
-           msg_verbose++;
-           break;
-       }
-    }
-    optind = OPTIND;
-    if (argc - optind < 2)
-       usage(argv[0]);
-    if (strcasecmp(argv[optind + 1], "create") == 0)
-       open_flags = O_CREAT | O_RDWR | O_TRUNC;
-    else if (strcasecmp(argv[optind + 1], "write") == 0)
-       open_flags = O_RDWR;
-    else if (strcasecmp(argv[optind + 1], "read") == 0)
-       open_flags = O_RDONLY;
-    else
-       msg_fatal("unknown access mode: %s", argv[2]);
-    for (n = 2; argv[optind + n]; n++) {
-       if (strcasecmp(argv[optind + 2], "fold") == 0)
-           dict_flags |= DICT_FLAG_FOLD_ANY;
-       else if (strcasecmp(argv[optind + 2], "sync") == 0)
-           dict_flags |= DICT_FLAG_SYNC_UPDATE;
-       else
-           usage(argv[0]);
-    }
-    dict_name = argv[optind];
-    dict = dict_open(dict_name, open_flags, dict_flags);
-    dict_register(dict_name, dict);
-    while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
-       bufp = vstring_str(inbuf);
-       if (!isatty(0)) {
-           vstream_printf("> %s\n", bufp);
-           vstream_fflush(VSTREAM_OUT);
-       }
-       if (*bufp == '#')
-           continue;
-       if ((cmd = mystrtok(&bufp, " ")) == 0) {
-           vstream_printf("usage: del key|get key|put key=value|first|next\n");
-           vstream_fflush(VSTREAM_OUT);
-           continue;
-       }
-       if (dict_changed_name())
-           msg_warn("dictionary has changed");
-       key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0;
-       value = mystrtok(&bufp, " =");
-       if (strcmp(cmd, "del") == 0 && key && !value) {
-           if (dict_del(dict, key))
-               vstream_printf("%s: not found\n", key);
-           else
-               vstream_printf("%s: deleted\n", key);
-       } else if (strcmp(cmd, "get") == 0 && key && !value) {
-           if ((value = dict_get(dict, key)) == 0) {
-               vstream_printf("%s: %s\n", key,
-                              dict_errno == DICT_ERR_RETRY ?
-                              "soft error" : "not found");
-           } else {
-               vstream_printf("%s=%s\n", key, value);
-           }
-       } else if (strcmp(cmd, "put") == 0 && key && value) {
-           dict_put(dict, key, value);
-           vstream_printf("%s=%s\n", key, value);
-       } else if (strcmp(cmd, "first") == 0 && !key && !value) {
-           if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0)
-               vstream_printf("%s=%s\n", key, value);
-           else
-               vstream_printf("%s\n",
-                              dict_errno == DICT_ERR_RETRY ?
-                              "soft error" : "not found");
-       } else if (strcmp(cmd, "next") == 0 && !key && !value) {
-           if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0)
-               vstream_printf("%s=%s\n", key, value);
-           else
-               vstream_printf("%s\n",
-                              dict_errno == DICT_ERR_RETRY ?
-                              "soft error" : "not found");
-       } else {
-           vstream_printf("usage: del key|get key|put key=value|first|next\n");
-       }
-       vstream_fflush(VSTREAM_OUT);
-    }
-    vstring_free(keybuf);
-    vstring_free(inbuf);
-    dict_close(dict);
+    dict_test(argc, argv);
     return (0);
 }
 
diff --git a/postfix/src/util/dict_test.c b/postfix/src/util/dict_test.c
new file mode 100644 (file)
index 0000000..e4f780b
--- /dev/null
@@ -0,0 +1,141 @@
+ /*
+  * Proof-of-concept test program. Create, update or read a database. When
+  * the input is a name=value pair, the database is updated, otherwise the
+  * program assumes that the input specifies a lookup key and prints the
+  * corresponding value.
+  */
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <stringops.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <msg_vstream.h>
+#include <vstring_vstream.h>
+#include <dict.h>
+
+static NORETURN usage(char *myname)
+{
+    msg_fatal("usage: %s type:file read|write|create [fold] [sync]", myname);
+}
+
+void    dict_test(int argc, char **argv)
+{
+    VSTRING *keybuf = vstring_alloc(1);
+    VSTRING *inbuf = vstring_alloc(1);
+    DICT   *dict;
+    char   *dict_name;
+    int     open_flags;
+    char   *bufp;
+    char   *cmd;
+    const char *key;
+    const char *value;
+    int     ch;
+    int     dict_flags = DICT_FLAG_LOCK | DICT_FLAG_DUP_REPLACE;
+    int     n;
+
+    signal(SIGPIPE, SIG_IGN);
+
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+    while ((ch = GETOPT(argc, argv, "v")) > 0) {
+       switch (ch) {
+       default:
+           usage(argv[0]);
+       case 'v':
+           msg_verbose++;
+           break;
+       }
+    }
+    optind = OPTIND;
+    if (argc - optind < 2)
+       usage(argv[0]);
+    if (strcasecmp(argv[optind + 1], "create") == 0)
+       open_flags = O_CREAT | O_RDWR | O_TRUNC;
+    else if (strcasecmp(argv[optind + 1], "write") == 0)
+       open_flags = O_RDWR;
+    else if (strcasecmp(argv[optind + 1], "read") == 0)
+       open_flags = O_RDONLY;
+    else
+       msg_fatal("unknown access mode: %s", argv[2]);
+    for (n = 2; argv[optind + n]; n++) {
+       if (strcasecmp(argv[optind + 2], "fold") == 0)
+           dict_flags |= DICT_FLAG_FOLD_ANY;
+       else if (strcasecmp(argv[optind + 2], "sync") == 0)
+           dict_flags |= DICT_FLAG_SYNC_UPDATE;
+       else
+           usage(argv[0]);
+    }
+    dict_name = argv[optind];
+    dict = dict_open(dict_name, open_flags, dict_flags);
+    dict_register(dict_name, dict);
+    while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
+       bufp = vstring_str(inbuf);
+       if (!isatty(0)) {
+           vstream_printf("> %s\n", bufp);
+           vstream_fflush(VSTREAM_OUT);
+       }
+       if (*bufp == '#')
+           continue;
+       if ((cmd = mystrtok(&bufp, " ")) == 0) {
+           vstream_printf("usage: del key|get key|put key=value|first|next\n");
+           vstream_fflush(VSTREAM_OUT);
+           continue;
+       }
+       if (dict_changed_name())
+           msg_warn("dictionary has changed");
+       key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0;
+       value = mystrtok(&bufp, " =");
+       if (strcmp(cmd, "del") == 0 && key && !value) {
+           if (dict_del(dict, key))
+               vstream_printf("%s: not found\n", key);
+           else
+               vstream_printf("%s: deleted\n", key);
+       } else if (strcmp(cmd, "get") == 0 && key && !value) {
+           if ((value = dict_get(dict, key)) == 0) {
+               vstream_printf("%s: %s\n", key,
+                              dict_errno == DICT_ERR_RETRY ?
+                              "soft error" : "not found");
+           } else {
+               vstream_printf("%s=%s\n", key, value);
+           }
+       } else if (strcmp(cmd, "put") == 0 && key && value) {
+           /* XXX dict_put returns void, so dict_memcache sets dict_errno. */
+           dict_errno = 0;
+           dict_put(dict, key, value);
+           if (dict_errno)
+               vstream_printf("%s: soft error\n", key);
+           else
+               vstream_printf("%s=%s\n", key, value);
+       } else if (strcmp(cmd, "first") == 0 && !key && !value) {
+           if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0)
+               vstream_printf("%s=%s\n", key, value);
+           else
+               vstream_printf("%s\n",
+                              dict_errno == DICT_ERR_RETRY ?
+                              "soft error" : "not found");
+       } else if (strcmp(cmd, "next") == 0 && !key && !value) {
+           if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0)
+               vstream_printf("%s=%s\n", key, value);
+           else
+               vstream_printf("%s\n",
+                              dict_errno == DICT_ERR_RETRY ?
+                              "soft error" : "not found");
+       } else {
+           vstream_printf("usage: del key|get key|put key=value|first|next\n");
+       }
+       vstream_fflush(VSTREAM_OUT);
+    }
+    vstring_free(keybuf);
+    vstring_free(inbuf);
+    dict_close(dict);
+}