]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.12-20260227
authorWietse Z Venema <wietse@porcupine.org>
Fri, 27 Feb 2026 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Sat, 28 Feb 2026 02:37:53 +0000 (13:37 +1100)
193 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/INSTALL
postfix/Makefile.in
postfix/README_FILES/AAAREADME
postfix/README_FILES/INSTALL
postfix/README_FILES/NON_BERKELEYDB_README [new file with mode: 0644]
postfix/README_FILES/SASL_README
postfix/README_FILES/SOHO_README
postfix/README_FILES/STANDARD_CONFIGURATION_README
postfix/README_FILES/UUCP_README
postfix/README_FILES/VIRTUAL_README
postfix/RELEASE_NOTES-3.11
postfix/TESTING [new file with mode: 0644]
postfix/conf/access
postfix/conf/aliases
postfix/conf/canonical
postfix/conf/generic
postfix/conf/postfix-files
postfix/conf/postfix-non-bdb-script [new file with mode: 0644]
postfix/conf/postfix-script
postfix/conf/relocated
postfix/conf/transport
postfix/conf/virtual
postfix/html/INSTALL.html
postfix/html/Makefile.in
postfix/html/NON_BERKELEYDB_README.html [new file with mode: 0644]
postfix/html/SASL_README.html
postfix/html/SOHO_README.html
postfix/html/STANDARD_CONFIGURATION_README.html
postfix/html/UUCP_README.html
postfix/html/VIRTUAL_README.html
postfix/html/access.5.html
postfix/html/aliases.5.html
postfix/html/canonical.5.html
postfix/html/cidr_table.5.html
postfix/html/generic.5.html
postfix/html/index.html
postfix/html/ldap_table.5.html
postfix/html/memcache_table.5.html
postfix/html/mongodb_table.5.html
postfix/html/mysql_table.5.html
postfix/html/nbdb_reindexd.8.html [new file with mode: 0644]
postfix/html/nisplus_table.5.html
postfix/html/pcre_table.5.html
postfix/html/pgsql_table.5.html
postfix/html/postalias.1.html
postfix/html/postconf.5.html
postfix/html/postfix-manuals.html
postfix/html/postfix-non-bdb.1.html [new file with mode: 0644]
postfix/html/postfix.1.html
postfix/html/postmap.1.html
postfix/html/regexp_table.5.html
postfix/html/relocated.5.html
postfix/html/socketmap_table.5.html
postfix/html/sqlite_table.5.html
postfix/html/tcp_table.5.html
postfix/html/transport.5.html
postfix/html/virtual.5.html
postfix/makedefs
postfix/man/Makefile.in
postfix/man/man1/postalias.1
postfix/man/man1/postfix-non-bdb.1 [new file with mode: 0644]
postfix/man/man1/postfix.1
postfix/man/man1/postmap.1
postfix/man/man5/access.5
postfix/man/man5/aliases.5
postfix/man/man5/canonical.5
postfix/man/man5/cidr_table.5
postfix/man/man5/generic.5
postfix/man/man5/ldap_table.5
postfix/man/man5/memcache_table.5
postfix/man/man5/mongodb_table.5
postfix/man/man5/mysql_table.5
postfix/man/man5/nisplus_table.5
postfix/man/man5/pcre_table.5
postfix/man/man5/pgsql_table.5
postfix/man/man5/postconf.5
postfix/man/man5/regexp_table.5
postfix/man/man5/relocated.5
postfix/man/man5/socketmap_table.5
postfix/man/man5/sqlite_table.5
postfix/man/man5/tcp_table.5
postfix/man/man5/transport.5
postfix/man/man5/virtual.5
postfix/man/man8/nbdb_reindexd.8 [new file with mode: 0644]
postfix/mantools/dehtml
postfix/mantools/postlink
postfix/proto/INSTALL.html
postfix/proto/Makefile.in
postfix/proto/NON_BERKELEYDB_README.html [new file with mode: 0644]
postfix/proto/SASL_README.html
postfix/proto/STANDARD_CONFIGURATION_README.html
postfix/proto/UUCP_README.html
postfix/proto/VIRTUAL_README.html
postfix/proto/access
postfix/proto/aliases
postfix/proto/canonical
postfix/proto/cidr_table
postfix/proto/generic
postfix/proto/index.html
postfix/proto/ldap_table
postfix/proto/memcache_table
postfix/proto/mongodb_table
postfix/proto/mysql_table
postfix/proto/nisplus_table
postfix/proto/pcre_table
postfix/proto/pgsql_table
postfix/proto/postconf.html.prolog
postfix/proto/postconf.proto
postfix/proto/regexp_table
postfix/proto/relocated
postfix/proto/socketmap_table
postfix/proto/sqlite_table
postfix/proto/stop
postfix/proto/stop.double-cc
postfix/proto/stop.double-history
postfix/proto/stop.double-install-proto-text
postfix/proto/stop.double-proto-html
postfix/proto/stop.spell-cc
postfix/proto/stop.spell-history
postfix/proto/stop.spell-proto-html
postfix/proto/tcp_table
postfix/proto/transport
postfix/proto/virtual
postfix/src/global/Makefile.in
postfix/src/global/allowed_prefix.c [new file with mode: 0644]
postfix/src/global/allowed_prefix.h [new file with mode: 0644]
postfix/src/global/allowed_prefix_test.c [new file with mode: 0644]
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/global/nbdb_clnt.c [new file with mode: 0644]
postfix/src/global/nbdb_clnt.h [new file with mode: 0644]
postfix/src/global/nbdb_redirect.c [new file with mode: 0644]
postfix/src/global/nbdb_redirect.h [new file with mode: 0644]
postfix/src/global/nbdb_redirect_test.c [new file with mode: 0644]
postfix/src/global/nbdb_surrogate.c [new file with mode: 0644]
postfix/src/global/nbdb_surrogate.h [new file with mode: 0644]
postfix/src/global/nbdb_surrogate_test.c [new file with mode: 0644]
postfix/src/global/nbdb_util.c [new file with mode: 0644]
postfix/src/global/nbdb_util.h [new file with mode: 0644]
postfix/src/global/nbdb_util_test.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/Makefile.in [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_index_as.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_index_as.h [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_index_as_test.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_process.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_process.h [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_process_test.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_reindexd.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_reindexd.h [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_safe.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_safe.h [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_safe_test.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_sniffer.c [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_sniffer.h [new file with mode: 0644]
postfix/src/nbdb_reindexd/nbdb_sniffer_test.c [new file with mode: 0644]
postfix/src/postalias/postalias.c
postfix/src/postfix/postfix.c
postfix/src/postmap/postmap.c
postfix/src/postmulti/Makefile.in
postfix/src/posttls-finger/posttls-finger.c
postfix/src/smtp/smtp_connect.c
postfix/src/testing/Makefile.in
postfix/src/testing/mock_dict.c [new file with mode: 0644]
postfix/src/testing/mock_dict.h [new file with mode: 0644]
postfix/src/testing/mock_open_as.c [new file with mode: 0644]
postfix/src/testing/mock_open_as.h [new file with mode: 0644]
postfix/src/testing/mock_spawn_command.c [new file with mode: 0644]
postfix/src/testing/mock_spawn_command.h [new file with mode: 0644]
postfix/src/testing/mock_stat.c [new file with mode: 0644]
postfix/src/testing/mock_stat.h [new file with mode: 0644]
postfix/src/testing/msg_capture.c [new file with mode: 0644]
postfix/src/testing/msg_capture.h [new file with mode: 0644]
postfix/src/tls/tls.h
postfix/src/tls/tls_client.c
postfix/src/tls/tls_misc.c
postfix/src/tls/tls_verify.c
postfix/src/util/Makefile.in
postfix/src/util/dict.h
postfix/src/util/dict_db.c
postfix/src/util/dict_open.c
postfix/src/util/dict_surrogate.c
postfix/src/util/open_as.c
postfix/src/util/open_as.h
postfix/src/util/spawn_command.c
postfix/src/util/spawn_command.h
postfix/src/util/sys_defs.h
postfix/src/util/vstream.h
postfix/src/util/wrap_stat.c [new file with mode: 0644]
postfix/src/util/wrap_stat.h [new file with mode: 0644]

index f645854e9ab1111ca3df77cebe4b6f5ee2b0e987..3faf372e5da740d9e972283a6e16a1d7508c2c9a 100644 (file)
@@ -2,6 +2,7 @@
 -TADDR_MATCH_LIST
 -TADDR_PATTERN
 -TALIAS_TOKEN
+-TALLOWED_PARENT
 -TANVIL_CLNT
 -TANVIL_LOCAL
 -TANVIL_MAX
 -TMKMAP_OPEN_FN
 -TMKMAP_OPEN_INFO
 -TMKMAP_SDBM
+-TMOCK_OPEN_AS_REQ
+-TMOCK_SPAWN_CMD_REQ
+-TMOCK_STAT_REQ
+-TMSG_CAPTURE
 -TMSG_STATS
 -TMULTI_SERVER
 -TMVECT
 -TNAME_CODE
 -TNAME_MASK
 -TNBBIO
+-TNBDB_PATH_SUFFIX
 -TNVTABLE_INFO
 -TOPTIONS
 -TOSSL_DGST
 -Tsize_t
 -Tsockaddr
 -Tsockaddr_storage
+-Tspawn_args
 -Tssize_t
 -Tssl_cipher_stack_t
 -Tssl_comp_stack_t
+-Tstat
 -Ttime_t
 -Ttlsa_filter
 -Tuint16_t
index 75ac447dc464afb128d25b37f608029076405d5e..f59be79a662f712ecdcfd0a8fab643900ffa7173 100644 (file)
@@ -58,7 +58,7 @@ Apologies for any names omitted.
        reflects the current status of the software.
 
        Added -d (don't disconnect) and -c (show running counter)
-       option to te smtp-source test program. These tools are
+       option to the smtp-source test program. These tools are
        great torture tests for the mail software, and for the
        system that it runs on.
 
@@ -30404,3 +30404,145 @@ Apologies for any names omitted.
        that an IPv6 address needs to be enclosed in [] for the
        debug_peer_list and qmqpd_authorized_clients parameters.
        File: proto/postconf.proto.
+
+20260219
+
+       Feature: support to migrate a working Postfix configuration
+       that uses hash: and btree: tables, to an OS that has deleted
+       Berkeley DB support. Files: Makefile.in, conf/postfix-files,
+       conf/postfix-non-bdb-script, conf/postfix-script,
+       global/Makefile.in, global/allowed_prefix.c,
+       global/allowed_prefix.h, global/allowed_prefix_test.c,
+       global/mail_params.c, global/mail_params.h, global/mail_proto.h,
+       global/nbdb_clnt.c, global/nbdb_clnt.h, global/nbdb_redirect.c,
+       global/nbdb_redirect.h, global/nbdb_redirect_test.c,
+       global/nbdb_surrogate.c, global/nbdb_surrogate.h,
+       global/nbdb_surrogate_test.c, global/nbdb_util.c,
+       global/nbdb_util.h, global/nbdb_util_test.c, html/Makefile.in,
+       man/Makefile.in, mantools/postlink, proto/Makefile.in,
+       proto/NON_BERKELEYDB_README.html, proto/postconf.proto,
+       proto/stop, proto/stop.double-cc,
+       proto/stop.double-install-proto-text, proto/stop.spell-cc,
+       proto/stop.spell-history, proto/stop.spell-proto-html,
+       smtp/smtp_connect.c, testing/Makefile.in, testing/mock_open_as.c,
+       testing/mock_open_as.h, testing/mock_spawn_command.c,
+       testing/mock_spawn_command.h, testing/mock_stat.c,
+       testing/mock_stat.h, testing/msg_capture.c, testing/msg_capture.h,
+       util/Makefile.in, util/dict.h, util/dict_open.c,
+       util/dict_surrogate.c, util/open_as.c, util/open_as.h,
+       util/spawn_command.c, util/spawn_command.h, util/vstream.h,
+       util/wrap_stat.c, util/wrap_stat.h.
+
+20260220
+
+       Documentation: TESTING, proto/NON_BERKELEYDB_README.html,
+       proto/stop.spell-proto-html, postfix/postfix.c, conf/postfix-files,
+       mantools/postlink, global/nbdb_clnt.c.
+
+       Portability: testing/msg_capture.c.
+
+       Migration to "No Berkeley DB": update default values
+       for alias_maps and alias_database, and replace the
+       platform-dependent database type with $default_database_type.
+       File: src/util/sys_defs.h.
+
+       Documentation: update obsolete references to "dbm or db"
+       in xxx_table(5) manpages and make text more consistent.
+       Files: proto/cidr_table, proto/ldap_table, proto/memcache_table,
+       proto/mongodb_table, proto/mysql_table, proto/nisplus_table,
+       proto/pcre_table, proto/pgsql_table, proto/regexp_table,
+       proto/socketmap_table, proto/sqlite_table, proto/tcp_table.
+
+       Documentation: made the postmap(1) and postmap(1) manpages
+       more consistent in the discussion of the default_data_base,
+       and moved that text to a more visible location. Files:
+       postalias/postalias.c, postmap/postmap.c.
+
+       Documentation: updated 'man5' manpages for changes in default
+       indexed file types. Files: proto/access, proto/canonical,
+       proto/generic, proto/relocated, proto/transport, proto/virtual.
+
+       Incompatibility: The alias_maps and alias_database parameter
+       default values have changed from hash:/path/to/aliases (or
+       dbm:/path/to/aliases) to $default_database_type:/path/to/aliases.
+       This simplifies the migration away from Berkeley DB. File:
+       util/sys_defs.h.
+
+20260221
+
+       Testing: factored out the mock cdb and lmdb code to make
+       more tests independent of whether the build includes support
+       for cdb and lmdb. Files: global/Makefile.in,
+       global/nbdb_redirect_test.c, global/nbdb_util_test.c,
+       nbdb_reindexd/Makefile.in, nbdb_reindexd/nbdb_index_as_test.c,
+       nbdb_reindexd/nbdb_process_test.c, testing/Makefile.in,
+       testing/mock_dict.c, testing/mock_dict.h.
+
+20260222
+
+       Cleanup: migration service name word-smithing. Files:
+       mantools/postlink, proto/postconf.proto, global/mail_params.h.
+
+       Documentation: missing DEF_SHLIB_DIR in INSTALL. File:
+       proto/install.html.
+
+20260225
+
+       Documentation: examples now use lmdb plus text about implicit
+       types with "postmap /path/to/file" and available explicit types.
+       Files: proto/INSTALL.html, proto/SASL_README.html,
+       proto/STANDARD_CONFIGURATION_README.html, proto/UUCP_README.html,
+       proto/VIRTUAL_README.html.
+
+       Workaround: as of Postfix 3.11, the default alias_maps value
+       contains $default_database_type:/path/to/aliases, instead
+       of a hard-coded type hash. If default_database_type was
+       changed from hash to lmdb (or cdb), then the indexed file
+       /path/to/aliases.lmdb (or /path/to/aliases.cdb) will likely
+       not exist.
+
+       Unfortunately, if  $default_database_type has changed from
+       hash to lmdb (or cdb) Postfix will not try to use
+       hash:/path/to/aliases, and will not trigger compatibility
+       workarounds that are implemented with "enable-redirect" or
+       "enable-reindex". This would be a gap in migration coverage.
+
+       To avoid this, synthesize a stand-alone re-indexing request.
+       Files: conf/postfix-script, proto/NON_BERKELEYDB_README.html.
+       This is needed only for databases specified in alias_maps.
+
+       Postfix works on Linux 7.x kernels. Frank Scheiner. Files:
+       makedefs, util/sys_defs.h.
+
+20260226
+
+       Documentation: update postconf(5) examples: all examples
+       show "lmdb", and mention cdb, hash, etc. as alternatives.
+       File: proto/postconf.proto.
+
+       Cleanup: wordsmithing of recently-edited README files.
+       proto/SASL_README.html, proto/STANDARD_CONFIGURATION_README.html,
+       proto/UUCP_README.html.
+
+       Cleanup: fix HTML validator complaint. File:
+       proto/postconf.html.prolog
+
+       Cleanup: make only one attempt to generate an indexed file
+       for $alias_maps. This creates a status file
+       $config_directory/check-alias-maps-migration-done. File:
+       conf/postfix-script.
+
+20260227
+
+       Documentation: new Appendix with Mailman migration
+       instructions. File: proto/NON_BERKELEYDB_README.html.
+
+       Cleanup: missing #include <stdlib.h>, reported on Solaris 11.4.
+       File: nbdb_reindexd/nbdb_reindexd.c.
+
+       Cleanup: log a fatal error instead of dereferencing a null
+       pointer. Fedor Vorobev. File: util/dict_db.c.
+
+       Bitrot: patches in anticipation of OpenSSL 4. Viktor Dukhovni.
+       Files: posttls-finger/posttls-finger.c, tls/tls_client.c,
+       tls/tls.h, tls/tls_misc.c, tls/tls_verify.c.
index 4bd762bea358b98c6238aa5288eb572a2a2260c9..58519cc9dd6ccfca598e86461c77ed8096b20d9a 100644 (file)
@@ -432,7 +432,7 @@ postconf.5 | less").
     |_____________________|____________________|
     |config_directory    |/etc/postfix        |
     |_____________________|____________________|
-    |default_database_type|lmdb or hash        |
+    |default_database_type|lmdb, cdb, or hash  |
     |_____________________|____________________|
     |default_cache_db_type|lmdb or btree       |
     |_____________________|____________________|
@@ -486,7 +486,7 @@ postconf.5 | less").
     |_________________|_____________________|____________________|
     |DEF_CONFIG_DIR   |config_directory     |/etc/postfix       |
     |_________________|_____________________|____________________|
-    |DEF_DB_TYPE      |default_database_type|lmdb or hash       |
+    |DEF_DB_TYPE      |default_database_type|lmdb, cdb, or hash  |
     |_________________|_____________________|____________________|
     |DEF_CACHE_DB_TYPE|default_cache_db_type|lmdb or btree      |
     |_________________|_____________________|____________________|
@@ -508,9 +508,12 @@ postconf.5 | less").
     |_________________|_____________________|____________________|
     |DEF_SENDMAIL_PATH|sendmail_path       |/usr/sbin/sendmail  |
     |_________________|_____________________|____________________|
+    |DEF_SHLIB_DIR    |shlib_directory     |/usr/lib/postfix    |
+    |_________________|_____________________|____________________|
 
 Note: the data_directory parameter (for caches and pseudo-random numbers) was
-introduced with Postfix version 2.5.
+introduced with Postfix version 2.5; shlib_directory (for shared-library
+objects and database plugins) with Postfix version 3.0.
 
 4.7 - Overriding other compile-time features
 
@@ -542,8 +545,8 @@ The following is an extensive list of names and values.
 |_______________________________|_____________________________________________|
 ||                             |Do not build with Berkeley DB support. By    |
 ||                             |default, Berkeley DB support is compiled in  |
-||                             |on platforms that are known to support this  |
-||-DNO_DB                      |feature. If you override this, then you      |
+||                             |on platforms that have historically supported|
+||-DNO_DB                      |this feature. If you override this, then you |
 ||                             |probably should also override                |
 ||                             |default_database_type or DEF_DB_TYPE as      |
 ||                             |described in section 4.6.                    |
@@ -1080,7 +1083,7 @@ alias_maps" will tell you the exact location of the text file.
 
 First, be sure to update the text file with aliases for root, postmaster and
 "postfix" that forward mail to a real person. Postfix has a sample aliases file
-/etc/postfix/aliases that you can adapt to local conditions.
+/etc/postfix/aliases that you can copy and adapt to local conditions. /p>
 
     /etc/aliases:
        root: you
@@ -1097,6 +1100,13 @@ Finally, build the indexed aliases file with one of the following commands:
     # sendmail -bi
     # postalias /etc/aliases (pathname is system dependent!)
 
+The form "postalias /etc/aliases" builds a default-type indexed file. Use
+"postalias type:/etc/aliases" to specify an explicit type (it should match the
+type in the output from "postconf -x alias_maps").
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "postconf -m".
+
 11 - To chroot or not to chroot
 
 Postfix daemon processes can be configured (via master.cf) to run in a chroot
index a436f732588db18f1b0f7038a62a7a0ed6de17a8..8d7501ada36eed4fb012d236a4828f56cf5de15e 100644 (file)
@@ -12,10 +12,11 @@ DIRS        = src/util src/global src/dns src/tls src/xsasl src/master src/milter \
        src/postsuper src/qmqpd src/spawn src/flush src/verify \
        src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr \
        src/postmulti src/postscreen src/dnsblog src/tlsproxy \
-       src/posttls-finger src/postlogd src/testing
+       src/posttls-finger src/postlogd src/nbdb_reindexd src/testing
 MANDIRS        = proto man html
 LIBEXEC        = libexec/post-install libexec/postfix-script libexec/postfix-wrapper \
-       libexec/postmulti-script libexec/postfix-tls-script
+       libexec/postmulti-script libexec/postfix-non-bdb-script \
+       libexec/postfix-tls-script
 PLUGINS        = meta/dynamicmaps.cf
 META   = meta/main.cf.proto meta/master.cf.proto meta/postfix-files \
        meta/makedefs.out $(PLUGINS)
@@ -86,6 +87,9 @@ meta/postfix-files: conf/postfix-files conf/makedefs.out Makefile
 libexec/postfix-script: conf/postfix-script
        rm -f $@ && ln -f $? $@
 
+libexec/postfix-non-bdb-script: conf/postfix-non-bdb-script
+       rm -f $@ && ln -f $? $@
+
 libexec/postfix-tls-script: conf/postfix-tls-script
        rm -f $@ && ln -f $? $@
 
index 12c1b25792ad8cb4131d98a7d071a362d0c67035..c3c83da7d550b704fb88691b3e5ee2478b7f20da 100644 (file)
@@ -50,6 +50,7 @@ S\bSM\bMT\bTP\bP R\bRe\bel\bla\bay\by a\ban\bnd\bd a\bac\bcc\bce\bes\bss\bs c\bco\bon\bnt\btr\bro\bol\bl
 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)
 
   * DATABASE_README: Lookup table overview
+  * NON_BERKELEYDB_README: Non-Berkeley-DB migration
   * DB_README: Berkeley DB Howto
   * CDB_README: CDB Howto
   * LDAP_README: LDAP Howto
index cd175c73532fd9281c2651aba5e47a82e05f4503..3de4474cf5a3e86b42171bfaf13a8e0c4ffd8916 100644 (file)
@@ -432,7 +432,7 @@ postconf.5 | less").
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
     |config_directory     |/etc/postfix        |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
-    |default_database_type|lmdb or hash        |
+    |default_database_type|lmdb, cdb, or hash  |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
     |default_cache_db_type|lmdb or btree       |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
@@ -486,7 +486,7 @@ postconf.5 | less").
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
     |DEF_CONFIG_DIR   |config_directory     |/etc/postfix        |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
-    |DEF_DB_TYPE      |default_database_type|lmdb or hash        |
+    |DEF_DB_TYPE      |default_database_type|lmdb, cdb, or hash  |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
     |DEF_CACHE_DB_TYPE|default_cache_db_type|lmdb or btree       |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
@@ -508,9 +508,12 @@ postconf.5 | less").
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
     |DEF_SENDMAIL_PATH|sendmail_path        |/usr/sbin/sendmail  |
     |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+    |DEF_SHLIB_DIR    |shlib_directory      |/usr/lib/postfix    |
+    |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
 
 Note: the data_directory parameter (for caches and pseudo-random numbers) was
-introduced with Postfix version 2.5.
+introduced with Postfix version 2.5; shlib_directory (for shared-library
+objects and database plugins) with Postfix version 3.0.
 
 4\b4.\b.7\b7 -\b- O\bOv\bve\ber\brr\bri\bid\bdi\bin\bng\bg o\bot\bth\bhe\ber\br c\bco\bom\bmp\bpi\bil\ble\be-\b-t\bti\bim\bme\be f\bfe\bea\bat\btu\bur\bre\bes\bs
 
@@ -542,8 +545,8 @@ The following is an extensive list of names and values.
 |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
 ||                              |Do not build with Berkeley DB support. By    |
 ||                              |default, Berkeley DB support is compiled in  |
-||                              |on platforms that are known to support this  |
-||-DNO_DB                       |feature. If you override this, then you      |
+||                              |on platforms that have historically supported|
+||-DNO_DB                       |this feature. If you override this, then you |
 ||                              |probably should also override                |
 ||                              |default_database_type or DEF_DB_TYPE as      |
 ||                              |described in section 4.6.                    |
@@ -1080,7 +1083,7 @@ alias_maps" will tell you the exact location of the text file.
 
 First, be sure to update the text file with aliases for root, postmaster and
 "postfix" that forward mail to a real person. Postfix has a sample aliases file
-/etc/postfix/aliases that you can adapt to local conditions.
+/etc/postfix/aliases that you can copy and adapt to local conditions. /p>
 
     /etc/aliases:
         root: you
@@ -1097,6 +1100,13 @@ Finally, build the indexed aliases file with one of the following commands:
     # sendmail -bi
     # postalias /etc/aliases (pathname is system dependent!)
 
+The form "postalias /etc/aliases" builds a default-type indexed file. Use
+"postalias type:/etc/aliases" to specify an explicit type (it should match the
+type in the output from "postconf -x alias_maps").
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
 1\b11\b1 -\b- T\bTo\bo c\bch\bhr\bro\boo\bot\bt o\bor\br n\bno\bot\bt t\bto\bo c\bch\bhr\bro\boo\bot\bt
 
 Postfix daemon processes can be configured (via master.cf) to run in a chroot
diff --git a/postfix/README_FILES/NON_BERKELEYDB_README b/postfix/README_FILES/NON_BERKELEYDB_README
new file mode 100644 (file)
index 0000000..cad0cfe
--- /dev/null
@@ -0,0 +1,476 @@
+P\bPo\bos\bst\btf\bfi\bix\bx N\bNo\bon\bn-\b-B\bBe\ber\brk\bke\bel\ble\bey\by-\b-D\bDB\bB m\bmi\big\bgr\bra\bat\bti\bio\bon\bn
+
+-------------------------------------------------------------------------------
+
+T\bTa\bab\bbl\ble\be o\bof\bf c\bco\bon\bnt\bte\ben\bnt\bts\bs
+
+  * Introduction
+  * Background
+  * Skip this if not building Postfix from source, or if your system still
+    supports Berkeley DB
+  * Migration support level overview
+  * Level 'disable': manual migration
+  * Level 'enable-redirect': database aliasing
+  * Level 'enable-reindex': redirect and automatically generate non-Berkeley-DB
+    indexed files
+  * Addressing errors with automatic indexed file generation
+  * Appendix: Mailman integration
+
+I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
+
+(Please see the Appendix for Mailman integration tips.)
+
+After running the same Postfix configuration for a decade or more, there is a
+rude awakening when you update the OS to a newer version that has deleted its
+support for Berkeley DB. Postfix programs fail to open all hash: and btree:
+tables with messages like this:
+
+    Berkeley DB support for 'hash:/etc/postfix/virtual' is not available
+    for this build; see https://www.postfix.org/NON_BERKELEYDB_README.html
+    for alternatives
+
+This document comes to the rescue, with strategies to migrate an existing
+Postfix configuration that uses Berkeley DB hash: and btree: database files, to
+an OS distribution that has removed Berkeley DB support, with a Postfix
+configuration that uses lmdb: (or a combination of cdb: and lmdb:).
+
+By the way, you don't have to wait until Berkeley DB support is removed; your
+can proactively use the steps described here on a system that still has
+Berkeley DB, to migrate a Postfix configuration from Berkeley DB to lmdb: (or a
+combination of cdb: and lmdb:).
+
+B\bBa\bac\bck\bkg\bgr\bro\bou\bun\bnd\bd
+
+Historically, Postfix has used Berkeley DB hash: and btree: for key-value
+stores, as indicated in the "With Berkeley DB" table column below. In a world
+without Berkeley DB, good replacements are cdb: and lmdb: as indicated in the
+"No Berkeley DB" column.
+
+     _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b 
+    |P\bPu\bur\brp\bpo\bos\bse\be           |W\bWi\bit\bth\bh B\bBe\ber\brk\bke\bel\ble\bey\by D\bDB\bB           |N\bNo\bo B\bBe\ber\brk\bke\bel\ble\bey\by D\bDB\bB            |
+    |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+    |Mostly-static data|                           |default_database_type=lmdb|
+    |such as aliases,  |default_database_type=hash |or                        |
+    |transport_maps,   |                           |default_database_type=cdb |
+    |access tables     |                           |                          |
+    |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+    |Dynamic caches    |                           |                          |
+    |maintained by     |                           |                          |
+    |postscreen(8),    |default_cache_db_type=btree|default_cache_db_type=lmdb|
+    |verify(8), tlsmgr |                           |                          |
+    |(8)               |                           |                          |
+    |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+
+The default values for default_database_type and default_cache_db_type may be
+specified at build time (see the section below, and they may be changed later
+by editing main.cf, for example with the postconf(1) command.)
+
+The sections that follow present three migration strategies with different
+levels of assistance by tooling that was developed for Postfix 3.11 and later.
+
+S\bSk\bki\bip\bp t\bth\bhi\bis\bs i\bif\bf n\bno\bot\bt b\bbu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx f\bfr\bro\bom\bm s\bso\bou\bur\brc\bce\be,\b, o\bor\br i\bif\bf y\byo\bou\bur\br s\bsy\bys\bst\bte\bem\bm s\bst\bti\bil\bll\bl s\bsu\bup\bpp\bpo\bor\brt\bts\bs
+B\bBe\ber\brk\bke\bel\ble\bey\by D\bDB\bB.\b.
+
+Click here to skip to the next section.
+
+On systems that have removed Berkeley DB support, run "make makefiles" with a
+CCARGS value that (also) contains "-DNO_DB", and specify appropriate values for
+default_database_type (lmdb or cdb) and default_cache_db_type (lmdb).
+
+In the examples below, the "..." are place holders any dependencies that you
+build Postfix with, such as CDB, LDAP, LMDB, MySQL/MariaDB, OpenSSL, SASL, and
+so on.
+
+Example 1: use lmdb: for both default_database_type (read-mostly lookup tables)
+and default_cache_db_type (read-write caches). Terminal input is b\bbo\bol\bld\bd, output
+is normal font.
+
+    $ m\bma\bak\bke\be m\bma\bak\bke\bef\bfi\bil\ble\bes\bs C\bCC\bCA\bAR\bRG\bGS\bS=\b="\b"-\b-D\bDN\bNO\bO_\b_D\bDB\bB .\b..\b..\b."\b" \\b\
+        d\bde\bef\bfa\bau\bul\blt\bt_\b_d\bda\bat\bta\bab\bba\bas\bse\be_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb \\b\
+        d\bde\bef\bfa\bau\bul\blt\bt_\b_c\bca\bac\bch\bhe\be_\b_d\bdb\bb_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb .\b..\b..\b. \\b\
+        A\bAU\bUX\bXL\bLI\bIB\bBS\bS.\b..\b..\b.
+
+Example 2: alternative form that produces the same result.
+
+    $ e\bex\bxp\bpo\bor\brt\bt C\bCC\bCA\bAR\bRG\bGS\bS=\b="\b"-\b-D\bDN\bNO\bO_\b_D\bDB\bB .\b..\b..\b."\b"
+    $ e\bex\bxp\bpo\bor\brt\bt d\bde\bef\bfa\bau\bul\blt\bt_\b_d\bda\bat\bta\bab\bba\bas\bse\be_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb
+    $ e\bex\bxp\bpo\bor\brt\bt d\bde\bef\bfa\bau\bul\blt\bt_\b_c\bca\bac\bch\bhe\be_\b_d\bdb\bb_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb
+    $ e\bex\bxp\bpo\bor\brt\bt A\bAU\bUX\bXL\bLI\bIB\bBS\bS.\b..\b..\b.
+    ...
+    $ m\bma\bak\bke\be m\bma\bak\bke\bef\bfi\bil\ble\bes\bs
+
+Another alternative is to use cdb for default_database_type (read-mostly lookup
+tables) and lmdb for default_cache_db_type (read-write caches).
+
+M\bMi\big\bgr\bra\bat\bti\bio\bon\bn s\bsu\bup\bpp\bpo\bor\brt\bt l\ble\bev\bve\bel\bl o\bov\bve\ber\brv\bvi\bie\bew\bw
+
+The goal of the migration is clear: stop using hash: and btree:, and use lmdb:
+or cdb: instead. If your configuration is simple or if you are familiar with
+Postfix configuration, a few "grep" commands will find all the problems, and a
+few edits will be easy to make.
+
+If, on the other hand, you are not familiar with the details of your Postfix
+configuration, then this document provides options where Postfix can help.
+
+Postfix 3.11 introduces multiple levels of migration support. You can use the
+command "postfix non-bdb status" to view the migration support level. This is
+what the default should look like (terminal input is b\bbo\bol\bld\bd, output is normal
+font):
+
+    # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb s\bst\bta\bat\btu\bus\bs
+    disable
+
+In increasing order, the support levels are:
+
+disable (manual migration)
+    You start up Postfix, watch the logging when Postfix programs fail to open
+    a hash: or btree: table, edit Postfix configuration files to use lmdb: or
+    cdb:, then run postmap(1) or postalias(1) commands to create lmdb: or cdb:
+    indexed database files. Use this option if you are familiar with Postfix
+    configuration.
+
+    This will not fix the integration with Mailman versions from before gitlab
+    commit 8fa56b72 (May 2025) and other software that are broken when they
+    want to use "postmap hash:/path/to/file". Mailman uses this to maintain a
+    table with mailing list contact addresses. For that, you need to use the
+    next-up level.
+
+enable-redirect (database aliasing)
+    This level implicitly redirects a request to access hash:/path/to/file to
+    $default_database_type:/path/to/file, and redirects a request to access a
+    btree:/path/to/file to $default_cache_db_type:/path/to/file.
+
+    This still requires manually running postmap(1) or postalias(1) commands,
+    but "fixes" the integration with Mailman versions from before gitlab commit
+    8fa56b72 (May 2025) and other software when they want to use "postmap hash:
+    /path/to/file", and Berkeley DB support is not available. Such commands
+    will implicitly create a new lmdb: or cdb: indexed database file, depending
+    on the default_database_type value.
+
+enable-reindex (aliasing, plus running postmap(1) or postalias(1))
+    This level implements "enable-redirect (database aliasing)", and also runs
+    the postmap(1) or postalias(1) command to create a new lmdb or cdb indexed
+    database file. This uses the nbdb_reindexd(8) daemon.
+
+The levels enable-redirect and enable-reindex leave some technical debt:
+configurations that still say hash: or btree: (even if they use lmdb: or cdb:
+behind the scene).
+
+  * Using these levels gives you extra time to prepare for a long-term
+    configuration change that replaces hard-coded instances of hash: with the
+    value of default_database_type, and that replaces btree: with the value of
+    default_cache_db_type.
+
+  * Depending on your use of other software that wants to use postmap(1) or
+    postalias(1) commands, you may have to permanently the leave the enable-
+    redirect level active.
+
+After this overview, the sections that follow will go into more detail.
+
+L\bLe\bev\bve\bel\bl '\b'd\bdi\bis\bsa\bab\bbl\ble\be'\b':\b: m\bma\ban\bnu\bua\bal\bl m\bmi\big\bgr\bra\bat\bti\bio\bon\bn
+
+To disable all non-Berkeley-DB migration features use the "postfix non-bdb"
+command:
+
+    # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb d\bdi\bis\bsa\bab\bbl\ble\be
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+This will edit main.cf to remove a non_bdb_migration_level setting and the
+level revert to its implicit default (disable), and will edit master.cf to
+remove an entry for the reindex service.
+
+This setting will cause problems with Mailman versions from before gitlab
+commit 8fa56b72 (May 2025) and other software that wants to use "postmap hash:/
+path/to/file" (or similar postalias commands), and Berkeley DB support is no
+longer available. In that case, you will need the "enable-redirect" migration
+support level.
+
+A manual migration process goes like this:
+
+  * Stop Postfix.
+
+  * Make lmdb: the default for both default_database_type (read-mostly lookup
+    tables) and default_cache_db_type (read-write caches):
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf d\bde\bef\bfa\bau\bul\blt\bt_\b_d\bda\bat\bta\bab\bba\bas\bse\be_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb d\bde\bef\bfa\bau\bul\blt\bt_\b_c\bca\bac\bch\bhe\be_\b_d\bdb\bb_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb
+
+  * Alternatively, make cdb: the default for default_database_type (read-mostly
+    lookup tables) and lmdb: the default for default_cache_db_type (read-write
+    caches):
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf d\bde\bef\bfa\bau\bul\blt\bt_\b_d\bda\bat\bta\bab\bba\bas\bse\be_\b_t\bty\byp\bpe\be=\b=c\bcd\bdb\bb d\bde\bef\bfa\bau\bul\blt\bt_\b_c\bca\bac\bch\bhe\be_\b_d\bdb\bb_\b_t\bty\byp\bpe\be=\b=l\blm\bmd\bdb\bb
+
+  * Look for hash: and btree: references in Postfix configuration files.
+    Instead of /etc/postfix use the pathname in the output from "postconf -
+    x config_directory".
+
+    # g\bgr\bre\bep\bp -\b-E\bE -\b-r\br '\b'(\b(h\bha\bas\bsh\bh|\b|b\bbt\btr\bre\bee\be)\b):\b:/\b/'\b' /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx
+
+  * For each instance in the "grep" output :
+
+      o Edit the configuration file and replace "hash" with "lmdb" or "cdb"
+        (use the same value as the output from "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-h\bhx\bx
+        d\bde\bef\bfa\bau\bul\blt\bt_\b_d\bda\bat\bta\bab\bba\bas\bse\be_\b_t\bty\byp\bpe\be") and replace "btree" with "lmdb".
+
+      o If this instance has no source file (only the ".db" file exists),
+        proceed with the next instance of "grep" output.
+
+      o If this instance appears in the output from "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-h\bhP\bPP\bPx\bx '\b'*\b*/\b/*\b*/\b/
+        a\bal\bli\bia\bas\bs_\b_m\bma\bap\bps\bs'\b' |\b| s\bso\bor\brt\bt -\b-u\bu", run the postalias(1) command. If this instance
+        is like "lmdb:/path/to/source":
+
+        # p\bpo\bos\bst\bta\bal\bli\bia\bas\bs l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/s\bso\bou\bur\brc\bce\be
+
+        Instead of "lmdb:" use "cdb:" if the instance is like "cdb:/path/to/
+        source".
+
+      o Otherwise, run the postmap(1) command. If this instance is like "lmdb:/
+        path/to/source":
+
+        # p\bpo\bos\bst\btm\bma\bap\bp l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/s\bso\bou\bur\brc\bce\be
+
+        Instead of "lmdb:" use "cdb:" if this instance is like "cdb:/path/to/
+        source".
+
+  * Start Postfix, watch the log for warnings about files that cannot be
+    opened, find the configuration file that still uses "hash" or "btree", and
+    repeat the steps above.
+
+  * It is now safe to delete the unused ".db" files.
+
+L\bLe\bev\bve\bel\bl '\b'e\ben\bna\bab\bbl\ble\be-\b-r\bre\bed\bdi\bir\bre\bec\bct\bt'\b':\b: d\bda\bat\bta\bab\bba\bas\bse\be a\bal\bli\bia\bas\bsi\bin\bng\bg
+
+To enable this migration support level, use:
+
+    # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb e\ben\bna\bab\bbl\ble\be-\b-r\bre\bed\bdi\bir\bre\bec\bct\bt
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+This postfix non-bdb" command edits main.cf to enable redirection (aliasing)
+from Berkeley DB types "hash" and "btree" to the non-Berkeley-DB types
+specified with $default_database_type and $default_cache_db_type. Custom
+redirection may be configured with non_bdb_custom_mapping. This command also
+edits master.cf to remove an unused nbdb_reindex service entry.
+
+This migration support level will not automatically create non-Berkeley-DB
+indexed database files. Instead, Postfix programs will log an error as they
+fail to open an indexed database file, and will leave it to the system
+administrator to run postmap(1) or postalias(1) to create that file.
+
+For each instance of "hash:/path/to/source" or "btree:/path/to/source" that
+requires manually running postmap(1) or postalias(1):
+
+  * If this instance appears in the output from "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-h\bhP\bPP\bPx\bx '\b'*\b*/\b/*\b*/\b/
+    a\bal\bli\bia\bas\bs_\b_m\bma\bap\bps\bs'\b' |\b| s\bso\bor\brt\bt -\b-u\bu", run the postalias(1) command. If this instance is
+    like "lmdb:/path/to/source":
+
+    # p\bpo\bos\bst\bta\bal\bli\bia\bas\bs l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/s\bso\bou\bur\brc\bce\be
+
+    Instead of "lmdb:" use "cdb:" if the instance is like "cdb:/path/to/
+    source".
+
+  * Otherwise, run the postmap(1) command. If this instance is like "lmdb:/
+    path/to/source":
+
+    # p\bpo\bos\bst\btm\bma\bap\bp l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/s\bso\bou\bur\brc\bce\be
+
+    Instead of "lmdb:" use "cdb:" if this instance is like "cdb:/path/to/
+    source".
+
+This migration support level will fix problems with Mailman versions from
+before May 2025 and other software that wants to use "postmap hash:/path/to/
+file". With database redirection, such commands will implicitly create an
+indexed file for $default_database_type:/path/to/file (similar aliasing happens
+for postalias commands).
+
+The command "postfix non-bdb enable-redirect" will refuse to make any changes
+when default_database_type or default_cache_db_type specify a hash: or btree:
+type.
+
+L\bLe\bev\bve\bel\bl '\b'e\ben\bna\bab\bbl\ble\be-\b-r\bre\bei\bin\bnd\bde\bex\bx'\b':\b: r\bre\bed\bdi\bir\bre\bec\bct\bt a\ban\bnd\bd a\bau\but\bto\bom\bma\bat\bti\bic\bca\bal\bll\bly\by g\bge\ben\bne\ber\bra\bat\bte\be n\bno\bon\bn-\b-B\bBe\ber\brk\bke\bel\ble\bey\by-\b-D\bDB\bB
+i\bin\bnd\bde\bex\bxe\bed\bd f\bfi\bil\ble\bes\bs
+
+NOTE: this level should be used only temporarily to generate most of the non-
+Berkeley-DB indexed files that Postfix needs. Leaving this enabled may expose
+the system to privilege-escalation attacks. There are no security concerns for
+using enable-redirect.
+
+To enable this migration support level, use:
+
+    # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb e\ben\bna\bab\bbl\ble\be-\b-r\bre\bei\bin\bnd\bde\bex\bx
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+This postfix non-bdb command edits main.cf to set the non-Berkeley-DB migration
+support level, and master.cf to add or replace an nbdb-reindex service entry.
+
+The resulting configuration implements not only the functionality of enable-
+redirect, but also automatically creates a non-Berkeley-DB indexed database
+file when a daemon program wants to access a file that does not exist. This
+uses the nbdb_reindexd(8) daemon to run postmap(1) or postalias(1) commands for
+databases that satisfy basic requirements to block privilege-escalation
+attacks. The number of requirements is large, but mainly, database files and
+their parent directory must not allow write access for group or other users,
+and their pathnames must match a list of trusted directory prefixes. The
+complete list of requirements is documented in nbdb_reindexd(8).
+
+This command immediately generates non-Berkeley-DB indexed files for command-
+line programs that lack privileges to send requests to the nbdb_reindexd(8)
+indexing server. This applies to "hash:" and "btree:" tables that are used by
+postqueue(1) and sendmail(1) as configured with authorized_flush_users and
+authorized_mailq_users, and used by sendmail(1) and postdrop(1) as configured
+with authorized_submit_users and local_login_sender_maps.
+
+The command "postfix non-bdb enable-reindex" will refuse to make any changes
+when default_database_type or default_cache_db_type specify a hash: or btree:
+type.
+
+The nbdb_reindexd(8) daemon will log when it successfully runs a postmap(1) or
+postalias(1) command. Examples, for a system with "default_database_type =
+lmdb":
+
+    successfully executed 'postmap lmdb:/etc/postfix/transport' as uid 0
+    successfully executed 'postalias lmdb:/etc/aliases' as uid 0
+
+See the section "Addressing errors with automatic indexed file generation" for
+the most likely errors that Postfix programs may log.
+
+Once there are no more errors from Postfix programs for about 24 hours, turn
+off automatic index generation by reducing the support level to enable-redirect
+with:
+
+    # postfix non-bdb enable-redirect
+    # postfix reload
+
+A\bAd\bdd\bdr\bre\bes\bss\bsi\bin\bng\bg e\ber\brr\bro\bor\brs\bs w\bwi\bit\bth\bh a\bau\but\bto\bom\bma\bat\bti\bic\bc i\bin\bnd\bde\bex\bxe\bed\bd f\bfi\bil\ble\be g\bge\ben\bne\ber\bra\bat\bti\bio\bon\bn
+
+U\bUn\bne\bex\bxp\bpe\bec\bct\bte\bed\bd p\bpa\bat\bth\bhn\bna\bam\bme\be e\ber\brr\bro\bor\brs\bs
+
+Depending on the location of your Postfix lookup tables, Postfix programs may
+log a request to add a trusted directory to the directories listed with
+non_bdb_migration_allow_root_prefixes or non_bdb_migration_allow_user_prefixes.
+
+Example, with line breaks added for readability:
+
+    could not execute command 'postmap lmdb:/path/to/file': table
+    /path/to/file has an unexpected pathname;
+
+    to allow automatic indexing as root, append its parent directory
+    to the non_bdb_migration_allow_root_prefixes setting (current setting
+    is: "/etc /usr/local/etc");
+
+    alternatively, execute the failed command by hand
+
+You have two options:
+
+ 1. If you think that the suggested change is safe, update the setting as
+    proposed and execute "postfix reload".
+
+ 2. Alternatively, you can execute the failed postmap(1) or postalias(1)
+    command by hand, and Postfix will not log the same error again.
+
+A similar request may be logged when a file needs to be indexed as a non-root
+user.
+
+U\bUn\bne\bex\bxp\bpe\bec\bct\bte\bed\bd f\bfi\bil\ble\be o\bor\br d\bdi\bir\bre\bec\bct\bto\bor\bry\by o\bow\bwn\bne\ber\br o\bor\br p\bpe\ber\brm\bmi\bis\bss\bsi\bio\bon\bns\bs
+
+Other errors may be logged when a database file or directory has an unexpected
+owner, or when it is writable by group or by other users.
+
+Example with line breaks added for readability:
+
+    could not execute command 'postmap lmdb:/path/to/file': legacy
+    indexed file '/path/to/file.db' is owned by uid '0', but parent
+    directory '/path/to' is owned or writable by other user;
+
+    to allow automatic indexing, correct the ownership or permissions;
+
+    alternatively, execute the failed command by hand
+
+Again, you have two options:
+
+ 1. Fix the ownership or permission error.
+
+ 2. Execute the failed postmap(1) or postalias(1) command by hand, and Postfix
+    will not log the same error again.
+
+Once there are no more errors from Postfix programs for about 24 hours, turn
+off automatic index generation by reducing the support level to enable-redirect
+with:
+
+    # postfix non-bdb enable-redirect
+    # postfix reload
+
+A\bAp\bpp\bpe\ben\bnd\bdi\bix\bx:\b: M\bMa\bai\bil\blm\bma\ban\bn i\bin\bnt\bte\beg\bgr\bra\bat\bti\bio\bon\bn
+
+This section has instructions to migrate an existing Mailman configuration that
+wants to use commands like "postmap hash:/path/to/file". Mailman uses such
+commands to maintain tables with mailing list contact addresses and domain
+names. This will break on systems that no longer have Berkeley DB support.
+
+Solutions:
+
+  * (Not recommended) Upgrade to a Mailman version that contains gitlab commit
+    8fa56b72 (May 2025). Unfortunately, this has not yet been widely adopted by
+    OS distributions.
+
+  * Avoid Mailman changes, and use Postfix migration support described below.
+    In a nutshell, the postmap command will execute the command "postmap hash:/
+    path/to/file" as if the command specifies lmdb:/path/to/file (or cdb:,
+    depending on Postfix configuration).
+
+With Mailman3 the integration with Postfix using LMTP may look like:
+
+    /var/lib/mailman3/data/postfix_domains      (domain names)
+    /var/lib/mailman3/data/postfix_domains.db   (Berkeley DB hash file)
+    /var/lib/mailman3/data/postfix_lmtp         (transport map)
+    /var/lib/mailman3/data/postfix_lmtp.db      (Berkeley DB hash file)
+
+    Caution: the data directory may contain other files with names ending in
+    ".db" that are not part of the Mailman-Postfix integration. Do not tamper
+    with the other files.
+
+The relevant Postfix migration levels are:
+
+enable-redirect (redirect hash: to lmdb: or cdb:)
+    Command: # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb e\ben\bna\bab\bbl\ble\be-\b-r\bre\bed\bdi\bir\bre\bec\bct\bt
+
+    This will fix the problem that Mailman wants to use commands like "postmap
+    hash:/path/to/postfix_domains" and "postmap hash:/path/to/postfix_lmtp".
+
+    Instead of complaining about an unsupported database type, these postmap
+    commands will implicitly create ".lmdb" indexed files like (lmdb:/path/to/
+    postfix_domains or lmdb:/path/to/postfix_lmtp, or their cdb: versions
+    depending on the Postfix default_database_type setting).
+
+    This will not fix the problem that Postfix wants to use databases like
+    hash:/path/to/postfix_domains and hash::/path/to/postfix_lmtp. With enable-
+    redirect, these will redirect to ".lmdb" indexed files (good) but those
+    files do not yet exist (bad). You will need to create them by hand with
+    commands like:
+
+    # p\bpo\bos\bst\btm\bma\bap\bp l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/p\bpo\bos\bst\btf\bfi\bix\bx_\b_d\bdo\bom\bma\bai\bin\bns\bs
+    # p\bpo\bos\bst\btm\bma\bap\bp l\blm\bmd\bdb\bb:\b:/\b/p\bpa\bat\bth\bh/\b/t\bto\bo/\b/p\bpo\bos\bst\btf\bfi\bix\bx_\b_l\blm\bmt\btp\bp
+
+    After this, no further human action will be needed. When Mailman needs to
+    update these files, it will invoke postmap commands that will work as
+    promised above. Leave the Postfix migration level at enable-reindex until
+    you can upgrade to a newer Mailman version that supports Postfix with non-
+    Berkeley databases.
+
+enable-reindex (also automatically run postmap commands)
+    Command: # p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb e\ben\bna\bab\bbl\ble\be-\b-r\bre\bed\bdi\bir\bre\bec\bct\bt
+
+    In addition to "enable-redirect", Postfix will also try to run commands
+    like "postmap lmdb:/path/to/postfix_domains" and "postmap lmdb:/path/to/
+    postfix_lmtp". There will be some delay depending on the amount of mailing
+    list traffic; you may want to post a test message to make the postmap
+    commands happen sooner.
+
+    Postfix will log the postmap commands (or will log a request to make some
+    configuration changes; see "Addressing errors with automatic indexed file
+    generation" above).
+
+    Note: once these "postmap" commands have completed, you should reduce the
+    migration support level with the command "p\bpo\bos\bst\btf\bfi\bix\bx n\bno\bon\bn-\b-b\bbd\bdb\bb e\ben\bna\bab\bbl\ble\be-\b-r\bre\bed\bdi\bir\bre\bec\bct\bt".
+    For security reasons the enable-reindex level should not be permanently
+    enabled.
+
index 2eb657e604858d829c501e5882726af8eaa2d564..9d0c3ccabfae6468e7ee6640b7f0a2a7014583e9 100644 (file)
@@ -841,7 +841,8 @@ addresses and SASL login names, the Postfix SMTP server can decide if the SASL
 authenticated client is allowed to use a particular envelope sender address:
 
     /etc/postfix/main.cf:
-        s\bsm\bmt\btp\bpd\bd_\b_s\bse\ben\bnd\bde\ber\br_\b_l\blo\bog\bgi\bin\bn_\b_m\bma\bap\bps\bs =\b= h\bha\bas\bsh\bh:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bco\bon\bnt\btr\bro\bol\bll\ble\bed\bd_\b_e\ben\bnv\bve\bel\blo\bop\bpe\be_\b_s\bse\ben\bnd\bde\ber\brs\bs
+        s\bsm\bmt\btp\bpd\bd_\b_s\bse\ben\bnd\bde\ber\br_\b_l\blo\bog\bgi\bin\bn_\b_m\bma\bap\bps\bs =\b=
+            l\blm\bmd\bdb\bb:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bco\bon\bnt\btr\bro\bol\bll\ble\bed\bd_\b_e\ben\bnv\bve\bel\blo\bop\bpe\be_\b_s\bse\ben\bnd\bde\ber\brs\bs
 
         smtpd_recipient_restrictions =
             ...
@@ -860,6 +861,16 @@ envelope address and the SASL login names that own that address:
         @example.net                barney, fred, john@example.com,
     mary@example.com
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bco\bon\bnt\btr\bro\bol\bll\ble\bed\bd_\b_e\ben\bnv\bve\bel\blo\bop\bpe\be_\b_s\bse\ben\bnd\bde\ber\brs\bs" after
+you change the controlled_envelope_senders file, to (re)build a default-type
+indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bco\bon\bnt\btr\bro\bol\bll\ble\bed\bd_\b_e\ben\bnv\bve\bel\blo\bop\bpe\be_\b_s\bse\ben\bnd\bde\ber\brs\bs"
+to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
 With this, the reject_sender_login_mismatch restriction above will reject the
 sender address in the MAIL FROM command if smtpd_sender_login_maps does not
 specify the SMTP client's login name as an owner of that address.
@@ -884,7 +895,7 @@ credentials have been compromised.
     /etc/postfix/main.cf:
         smtpd_recipient_restrictions =
             permit_mynetworks
-            check_sasl_access hash:/etc/postfix/sasl_access
+            check_sasl_access lmdb:/etc/postfix/sasl_access
             permit_sasl_authenticated
             ...
 
@@ -894,6 +905,15 @@ credentials have been compromised.
          # Use this when smtpd_sasl_local_domain=example.com.
          username@example.com HOLD
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_a\bac\bcc\bce\bes\bss\bs" after you change the
+sasl_access file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_a\bac\bcc\bce\bes\bss\bs" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
 D\bDe\bef\bfa\bau\bul\blt\bt a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn d\bdo\bom\bma\bai\bin\bn
 
 Postfix can append a domain name (or any other string) to a SASL login name
@@ -1043,7 +1063,7 @@ username/password information.
         relayhost = [mail.isp.example]
         # Alternative form:
         # relayhost = [mail.isp.example]:submission
-        smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+        smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
 
   * The smtp_sasl_auth_enable setting enables client-side authentication. We
     will configure the client's username and password information in the second
@@ -1094,8 +1114,15 @@ username/password information.
     SASL client passwords. It opens the file as user root before it drops
     privileges, and before entering an optional chroot jail.
 
-  * Use the postmap command whenever you change the /etc/postfix/sasl_passwd
-    file.
+    Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" after changing the
+    sasl_passwd file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" to specify an explicit type.
+
+    The default indexed file type is configured with the default_database_type
+    parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf
+    -\b-m\bm".
 
   * If you specify the "[" and "]" in the relayhost destination, then you must
     use the same form in the smtp_sasl_password_maps file.
@@ -1120,9 +1147,10 @@ final resort.
 
     /etc/postfix/main.cf:
         smtp_sender_dependent_authentication = yes
-        sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
+        sender_dependent_relayhost_maps =
+            lmdb:/etc/postfix/sender_relay
         smtp_sasl_auth_enable = yes
-        smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+        smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
         relayhost = [mail.isp.example]
         # Alternative form:
         # relayhost = [mail.isp.example]:submission
@@ -1141,19 +1169,23 @@ final resort.
         user1@example.com               [mail.example.com]:submission
         user2@example.net               [mail.example.net]
 
+    Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
   * If you are creative, then you can try to combine the two tables into one
     single MySQL database, and configure different Postfix queries to extract
     the appropriate information.
 
-  * Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb
-    files. To find out what lookup tables Postfix supports, use the command
-    "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" after you change the
+    sasl_passwd file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" to specify an explicit type.
 
-  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" whenever you change
-    the sasl_passwd table.
+    The default indexed file type is configured with the default_database_type
+    parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf
+    -\b-m\bm".
 
-  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" whenever you change
-    the sender_relay table.
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" after you change
+    the sender_relay file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" to specify an explicit type.
 
 P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP/\b/L\bLM\bMT\bTP\bP c\bcl\bli\bie\ben\bnt\bt p\bpo\bol\bli\bic\bcy\by -\b- S\bSA\bAS\bSL\bL m\bme\bec\bch\bha\ban\bni\bis\bsm\bm p\bpr\bro\bop\bpe\ber\brt\bti\bie\bes\bs
 
index b88e4a35bb8e0fe99e316ac52b1b7318d60811ff..8c5b538c4d4416532de4fb780a32955771163171 100644 (file)
@@ -77,7 +77,7 @@ this with basic configuration information as discussed in the first half of
 this document.
 
     1 /etc/postfix/main.cf:
-    2     smtp_generic_maps = hash:/etc/postfix/generic
+    2     smtp_generic_maps = lmdb:/etc/postfix/generic
     3
     4 /etc/postfix/generic:
     5     his@localdomain.local             hisaccount@hisisp.example
@@ -94,11 +94,14 @@ When mail is sent to a remote host via SMTP:
     extension of +local (this example assumes that the ISP supports "+" style
     address extensions).
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/g\bge\ben\bne\ber\bri\bic\bc" whenever you change the
-generic table.
+generic file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/
+e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/g\bge\ben\bne\ber\bri\bic\bc" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 S\bSo\bol\blu\but\bti\bio\bon\bn 2\b2:\b: P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.1\b1 a\ban\bnd\bd e\bea\bar\brl\bli\bie\ber\br
 
@@ -116,9 +119,9 @@ this document.
      2     myhostname = hostname.localdomain
      3     mydomain = localdomain
      4
-     5     canonical_maps = hash:/etc/postfix/canonical
+     5     canonical_maps = lmdb:/etc/postfix/canonical
      6
-     7     virtual_alias_maps = hash:/etc/postfix/virtual
+     7     virtual_alias_maps = lmdb:/etc/postfix/virtual
      8
      9 /etc/postfix/canonical:
     10     your-login-name    your-account@your-isp.com
@@ -140,14 +143,18 @@ Translation:
     instead of sending it to the ISP. This part is not required but is
     convenient.
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\ban\bno\bon\bni\bic\bca\bal\bl" whenever you change the
-canonical table.
+canonical file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\ban\bno\bon\bni\bic\bca\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" whenever you change the
-virtual table.
+virtual file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/
+e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
 
 E\bEn\bna\bab\bbl\bli\bin\bng\bg S\bSA\bAS\bSL\bL a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn i\bin\bn t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP/\b/L\bLM\bMT\bTP\bP c\bcl\bli\bie\ben\bnt\bt
 
@@ -174,7 +181,7 @@ username/password information.
         relayhost = [mail.isp.example]
         # Alternative form:
         # relayhost = [mail.isp.example]:submission
-        smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+        smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
 
   * The smtp_sasl_auth_enable setting enables client-side authentication. We
     will configure the client's username and password information in the second
@@ -225,8 +232,15 @@ username/password information.
     SASL client passwords. It opens the file as user root before it drops
     privileges, and before entering an optional chroot jail.
 
-  * Use the postmap command whenever you change the /etc/postfix/sasl_passwd
-    file.
+    Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" after changing the
+    sasl_passwd file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" to specify an explicit type.
+
+    The default indexed file type is configured with the default_database_type
+    parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf
+    -\b-m\bm".
 
   * If you specify the "[" and "]" in the relayhost destination, then you must
     use the same form in the smtp_sasl_password_maps file.
@@ -251,9 +265,10 @@ final resort.
 
     /etc/postfix/main.cf:
         smtp_sender_dependent_authentication = yes
-        sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
+        sender_dependent_relayhost_maps =
+            lmdb:/etc/postfix/sender_relay
         smtp_sasl_auth_enable = yes
-        smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+        smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
         relayhost = [mail.isp.example]
         # Alternative form:
         # relayhost = [mail.isp.example]:submission
@@ -272,17 +287,21 @@ final resort.
         user1@example.com               [mail.example.com]:submission
         user2@example.net               [mail.example.net]
 
+    Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
   * If you are creative, then you can try to combine the two tables into one
     single MySQL database, and configure different Postfix queries to extract
     the appropriate information.
 
-  * Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb
-    files. To find out what lookup tables Postfix supports, use the command
-    "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" after you change the
+    sasl_passwd file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" to specify an explicit type.
 
-  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bsa\bas\bsl\bl_\b_p\bpa\bas\bss\bsw\bwd\bd" whenever you change
-    the sasl_passwd table.
+    The default indexed file type is configured with the default_database_type
+    parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf
+    -\b-m\bm".
 
-  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" whenever you change
-    the sender_relay table.
+  * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" after you change
+    the sender_relay file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/s\bse\ben\bnd\bde\ber\br_\b_r\bre\bel\bla\bay\by" to specify an explicit type.
 
index 592c4a5636ac461359d3f5a5cc43e0af13bc900c..8f751c2c0b84e7ef0befabfcf5c67815e9888646 100644 (file)
@@ -226,7 +226,7 @@ address] as well. All the mail to these two accounts is forwarded to an inside
 address.
 
     1 /etc/postfix/main.cf:
-    2     virtual_alias_maps = hash:/etc/postfix/virtual
+    2     virtual_alias_maps = lmdb:/etc/postfix/virtual
     3
     4 /etc/postfix/virtual:
     5     postmaster      postmaster@example.com
@@ -261,8 +261,8 @@ purpose of the firewall email function.
      9b        permit_mynetworks reject_unauth_destination
     10b        ...spam blocking rules....
 
-    11     relay_recipient_maps = hash:/etc/postfix/relay_recipients
-    12     transport_maps = hash:/etc/postfix/transport
+    11     relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
+    12     transport_maps = lmdb:/etc/postfix/transport
     13
     14 /etc/postfix/relay_recipients:
     15     user1@example.com   x
@@ -293,14 +293,22 @@ Translation:
     "relay" delivery transport, instead of competing with other SMTP deliveries
     for SMTP clients from the default "smtp" delivery transport.
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" whenever you change the
+virtual file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/
+e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/r\bre\bel\bla\bay\by_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bts\bs" whenever you change
-the relay_recipients table.
+the relay_recipients file, to (re)build a default-type indexed file. Execute
+"p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/r\bre\bel\bla\bay\by_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bts\bs" to specify an explicit type.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" whenever you change the
-transport table.
+transport file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" to specify an explicit type.
 
 In some installations, there may be separate instances of Postfix processing
 inbound and outbound mail on a multi-homed firewall. The inbound Postfix
@@ -325,7 +333,7 @@ is also sent to the central mailhost. In order to deliver such accounts
 locally, you can set up virtual aliases as follows:
 
     1 /etc/postfix/main.cf:
-    2     virtual_alias_maps = hash:/etc/postfix/virtual
+    2     virtual_alias_maps = lmdb:/etc/postfix/virtual
     3
     4 /etc/postfix/virtual:
     5     root     root@localhost
@@ -338,7 +346,14 @@ Translation:
     listed in $mydestination, or when it matches $inet_interfaces or
     $proxy_interfaces.
 
-Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after editing the file.
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after editing the virtual
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 R\bRu\bun\bnn\bni\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx b\bbe\beh\bhi\bin\bnd\bd a\ba f\bfi\bir\bre\bew\bwa\bal\bll\bl
 
@@ -356,7 +371,7 @@ this with basic configuration information as discussed in the first half of
 this document.
 
      1 /etc/postfix/main.cf:
-     2     transport_maps = hash:/etc/postfix/transport
+     2     transport_maps = lmdb:/etc/postfix/transport
      3     relayhost =
      4     # Optional for a machine that isn't "always on"
      5     #fallback_relay = [gateway.example.com]
@@ -381,11 +396,14 @@ Translation:
     is turned off. Postfix tries to deliver mail directly, and gives
     undeliverable mail to a gateway.
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" whenever you edit the
-transport table.
+transport file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx a\bas\bs p\bpr\bri\bim\bma\bar\bry\by o\bor\br b\bba\bac\bck\bku\bup\bp M\bMX\bX h\bho\bos\bst\bt f\bfo\bor\br a\ba r\bre\bem\bmo\bot\bte\be s\bsi\bit\bte\be
 
@@ -416,7 +434,7 @@ When your system is SECONDARY MX host for a remote site this is all you need:
     11     # You must specify your NAT/proxy external address.
     12     #proxy_interfaces = 1.2.3.4
     13
-    14     relay_recipient_maps = hash:/etc/postfix/relay_recipients
+    14     relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
     15
     16 /etc/postfix/relay_recipients:
     17     user1@the.backed-up.domain.tld   x
@@ -426,7 +444,7 @@ When your system is SECONDARY MX host for a remote site this is all you need:
 When your system is PRIMARY MX host for a remote site you need the above, plus:
 
     20 /etc/postfix/main.cf:
-    21     transport_maps = hash:/etc/postfix/transport
+    21     transport_maps = lmdb:/etc/postfix/transport
     22
     23 /etc/postfix/transport:
     24     the.backed-up.domain.tld       relay:[their.mail.host.tld]
@@ -454,11 +472,18 @@ Important notes:
 
   * Line 24: The [] forces Postfix to do no MX lookup.
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/r\bre\bel\bla\bay\by_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bts\bs" whenever you change
+the relay_recipients file, to (re)build a default-type indexed file. Execute
+"p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/r\bre\bel\bla\bay\by_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bts\bs" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" whenever you change the
-transport table.
+transport file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" to specify an explicit type.
 
 NOTE for Postfix < 2.2: Do not use the fallback_relay feature when relaying
 mail for a backup or primary MX domain. Mail would loop between the Postfix MX
@@ -563,7 +588,7 @@ this with basic configuration information as discussed in the first half of
 this document.
 
     1 /etc/postfix/main.cf:
-    2     smtp_generic_maps = hash:/etc/postfix/generic
+    2     smtp_generic_maps = lmdb:/etc/postfix/generic
     3
     4 /etc/postfix/generic:
     5     his@localdomain.local             hisaccount@hisisp.example
@@ -580,11 +605,14 @@ When mail is sent to a remote host via SMTP:
     extension of +local (this example assumes that the ISP supports "+" style
     address extensions).
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/g\bge\ben\bne\ber\bri\bic\bc" whenever you change the
-generic table.
+generic file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/
+e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/g\bge\ben\bne\ber\bri\bic\bc" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 S\bSo\bol\blu\but\bti\bio\bon\bn 2\b2:\b: P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.1\b1 a\ban\bnd\bd e\bea\bar\brl\bli\bie\ber\br
 
@@ -602,9 +630,9 @@ this document.
      2     myhostname = hostname.localdomain
      3     mydomain = localdomain
      4
-     5     canonical_maps = hash:/etc/postfix/canonical
+     5     canonical_maps = lmdb:/etc/postfix/canonical
      6
-     7     virtual_alias_maps = hash:/etc/postfix/virtual
+     7     virtual_alias_maps = lmdb:/etc/postfix/virtual
      8
      9 /etc/postfix/canonical:
     10     your-login-name    your-account@your-isp.com
@@ -626,12 +654,16 @@ Translation:
     instead of sending it to the ISP. This part is not required but is
     convenient.
 
-Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
-To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\ban\bno\bon\bni\bic\bca\bal\bl" whenever you change the
-canonical table.
+canonical file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp
+t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\ban\bno\bon\bni\bic\bca\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
 
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" whenever you change the
-virtual table.
+virtual file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/
+e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
 
index 219ba6a93d07c2c4f1b89f914bda30aee6593a18..c9c9e433e17ef262d708a422cc346af4ddd91824 100644 (file)
@@ -49,6 +49,11 @@ for the other side of the story.
     executes the u\buu\bux\bx command without assistance from the shell, so there are no
     problems with shell meta characters in command-line parameters.
 
+  * Enable t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt table lookups:
+
+    /etc/postfix/main.cf:
+        transport_maps = lmdb:/etc/postfix/transport
+
   * Specify that mail for example.com, should be delivered via UUCP, to a host
     named uucp-host:
 
@@ -56,19 +61,17 @@ for the other side of the story.
         example.com     uucp:uucp-host
         .example.com    uucp:uucp-host
 
+    Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
     See the transport(5) manual page for more details.
 
   * Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" whenever you change
-    the t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt file.
-
-  * Enable t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt table lookups:
-
-    /etc/postfix/main.cf:
-        transport_maps = hash:/etc/postfix/transport
+    the t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt file, to (re)build a default-type indexed file. Execute
+    "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/t\btr\bra\ban\bns\bsp\bpo\bor\brt\bt" to specify an explicit type.
 
-    Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb
-    files. To find out what map types Postfix supports, use the command
-    "p\bpo\bos\bst\btc\bco\bon\bnf\b-\b-m\bm".
+    The default indexed file type is configured with the default_database_type
+    parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf
+    -\b-m\bm".
 
   * Add example.com to the list of domains that your site is willing to relay
     mail for.
index e693a0ceb29e6b18f9c577901d3e07e804423ce8..de453bca66271dbe9f30c7b6d05dc4f18add3f49 100644 (file)
@@ -22,8 +22,7 @@ The following topics are covered:
   * Postfix virtual MAILBOX example: separate domains, non-UNIX accounts
   * Non-Postfix mailbox store: separate domains, non-UNIX accounts
   * Mail forwarding domains
-  * Mailing lists
-  * Autoreplies
+  * Hosted mailing list domains
 
 C\bCa\ban\bno\bon\bni\bic\bca\bal\bl v\bve\ber\brs\bsu\bus\bs h\bho\bos\bst\bte\bed\bd v\bve\ber\brs\bsu\bus\bs o\bot\bth\bhe\ber\br d\bdo\bom\bma\bai\bin\bns\bs
 
@@ -56,16 +55,25 @@ ADDRESS_CLASS_README file.
 
 L\bLo\boc\bca\bal\bl f\bfi\bil\ble\bes\bs v\bve\ber\brs\bsu\bus\bs n\bne\bet\btw\bwo\bor\brk\bk d\bda\bat\bta\bab\bba\bas\bse\bes\bs
 
-The examples in this text use table lookups from local files such as DBM or
-Berkeley DB. These are easy to debug with the p\bpo\bos\bst\btm\bma\bap\bp command:
+The examples in this text use table lookups from local files such as lmdb:,
+cdb:, hash:, or dbm:. These are easy to debug with the p\bpo\bos\bst\btm\bma\bap\bp command:
 
-    Example: postmap -q info@example.com hash:/etc/postfix/virtual
+    Example: postmap -q info@example.com /etc/postfix/virtual
 
-See the documentation in LDAP_README, MYSQL_README and PGSQL_README for how to
-replace local files by databases. The reader is strongly advised to make the
-system work with local files before migrating to network databases, and to use
-the p\bpo\bos\bst\btm\bma\bap\bp command to verify that network database lookups produce the exact
-same results as local file lookup.
+The above example assumes that the database is configured in main.cf as
+$default_database_type:/etc/postfix/virtual. Otherwise, use the command
+instead:
+
+    Example: postmap -q info@example.com type:/etc/postfix/virtual
+
+and specify the explicit type that this table uses in main.cf.
+
+You can replace local file lookups with networked (LDAP, SQL etc.) lookups. See
+the documentation in LDAP_README, MYSQL_README, PGSQL_README, etc., for
+examples. The reader is strongly advised to make Postfix work with local files
+before migrating to network databases, and to use the p\bpo\bos\bst\btm\bma\bap\bp command to verify
+that network database lookups produce the exact same results as local file
+lookup.
 
     Example: postmap -q info@example.com ldap:/etc/postfix/virtual.cf
 
@@ -105,7 +113,7 @@ mechanism for the example.com domain.
 
      1 /etc/postfix/main.cf:
      2     virtual_alias_domains = example.com ...other hosted domains...
-     3     virtual_alias_maps = hash:/etc/postfix/virtual
+     3     virtual_alias_maps = lmdb:/etc/postfix/virtual
      4
      5 /etc/postfix/virtual:
      6     postmaster@example.com postmaster
@@ -139,8 +147,16 @@ Notes:
     receive many spam messages, and many bounces for spam messages that were
     sent in the name of anything@example.com.
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after changing the virtual
-file, and execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
+Execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
 
 Note: virtual aliases can resolve to a local address or to a remote address, or
 both. They don't have to resolve to UNIX system accounts on your machine.
@@ -179,11 +195,11 @@ Here is an example of a virtual mailbox domain "example.com":
      1 /etc/postfix/main.cf:
      2     virtual_mailbox_domains = example.com ...more domains...
      3     virtual_mailbox_base = /var/mail/vhosts
-     4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+     4     virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox
      5     virtual_minimum_uid = 100
      6     virtual_uid_maps = static:5000
      7     virtual_gid_maps = static:5000
-     8     virtual_alias_maps = hash:/etc/postfix/virtual
+     8     virtual_alias_maps = lmdb:/etc/postfix/virtual
      9
     10 /etc/postfix/vmailbox:
     11     info@example.com    example.com/info
@@ -242,9 +258,20 @@ Notes:
     explicit domain name on the right-hand side of the virtual alias table
     entries or else mail will go to the wrong domain.
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after changing the virtual
-file, execute "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvm\bma\bai\bil\blb\bbo\box\bx" after changing the vmailbox file,
-and execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
+Execute "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvm\bma\bai\bil\blb\bbo\box\bx" after changing the vmailbox file, to
+(re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/
+v\bvm\bma\bai\bil\blb\bbo\box\bx" to specify an explicit type.
+
+Execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
 
 Note: mail delivery happens with the recipient's UID/GID privileges specified
 with virtual_uid_maps and virtual_gid_maps. Postfix 2.0 and earlier will not
@@ -279,8 +306,8 @@ Postfix delivery agent:
      1 /etc/postfix/main.cf:
      2     virtual_transport = ...see below...
      3     virtual_mailbox_domains = example.com ...more domains...
-     4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
-     5     virtual_alias_maps = hash:/etc/postfix/virtual
+     4     virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox
+     5     virtual_alias_maps = lmdb:/etc/postfix/virtual
      6
      7 /etc/postfix/vmailbox:
      8     info@example.com    whatever
@@ -348,9 +375,20 @@ Notes:
     explicit domain name on the right-hand side of the virtual alias table
     entries or else mail will go to the wrong domain.
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after changing the virtual
-file, execute "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvm\bma\bai\bil\blb\bbo\box\bx" after changing the vmailbox file,
-and execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvm\bma\bai\bil\blb\bbo\box\bx" after changing the vmailbox
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvm\bma\bai\bil\blb\bbo\box\bx" to specify an explicit type.
+
+Execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
 
 M\bMa\bai\bil\bl f\bfo\bor\brw\bwa\bar\brd\bdi\bin\bng\bg d\bdo\bom\bma\bai\bin\bns\bs
 
@@ -360,7 +398,7 @@ example shows how to set up example.com as a mail forwarding domain:
 
      1 /etc/postfix/main.cf:
      2     virtual_alias_domains = example.com ...other hosted domains...
-     3     virtual_alias_maps = hash:/etc/postfix/virtual
+     3     virtual_alias_maps = lmdb:/etc/postfix/virtual
      4
      5 /etc/postfix/virtual:
      6     postmaster@example.com postmaster
@@ -394,13 +432,26 @@ Notes:
     receive many spam messages, and many bounces for spam messages that were
     sent in the name of anything@example.com.
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
 Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after changing the virtual
-file, and execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
+Execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd" after changing the main.cf file.
 
 More details about the virtual alias file are given in the virtual(5) manual
 page, including multiple addresses on the right-hand side.
 
-M\bMa\bai\bil\bli\bin\bng\bg l\bli\bis\bst\bts\bs
+H\bHo\bos\bst\bte\bed\bd m\bma\bai\bil\bli\bin\bng\bg l\bli\bis\bst\bt d\bdo\bom\bma\bai\bin\bns\bs
+
+Note: this section presents a historical approach to run a mailing list based
+on local aliases(5). This approach may still be useful for small mailing lists
+that are managed by hand or with the software like Majordomo. For a more
+contemporary and more scalable approach, see GNU Mailman.
 
 The examples that were given above already show how to direct mail for virtual
 postmaster addresses to a local postmaster. You can use the same method to
@@ -412,18 +463,29 @@ set up virtual aliases that direct virtual addresses to the local delivery
 agent:
 
     /etc/postfix/main.cf:
-        virtual_alias_maps = hash:/etc/postfix/virtual
+        virtual_alias_maps = lmdb:/etc/postfix/virtual
+        virtual_mailbox_domains = example.com
 
     /etc/postfix/virtual:
         listname-request@example.com listname-request
         listname@example.com         listname
         owner-listname@example.com   owner-listname
+        postmaster@example.com       postmaster
 
     /etc/aliases:
         listname: "|/some/where/majordomo/wrapper ..."
         owner-listname: ...
         listname-request: ...
 
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+
+Execute the command "p\bpo\bos\bst\btm\bma\bap\bp /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" after changing the virtual
+file, to (re)build a default-type indexed file. Execute "p\bpo\bos\bst\btm\bma\bap\bp t\bty\byp\bpe\be:\b:/\b/e\bet\btc\bc/\b/
+p\bpo\bos\bst\btf\bfi\bix\bx/\b/v\bvi\bir\brt\btu\bua\bal\bl" to specify an explicit type.
+
+The default indexed file type is configured with the default_database_type
+parameter. To list available explicit types, execute the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
+
 This example assumes that in main.cf, $myorigin is listed under the
 mydestination parameter setting. If that is not the case, specify an explicit
 domain name on the right-hand side of the virtual alias table entries or else
@@ -437,47 +499,8 @@ transport mapping? The reason is that mail for the virtual mailing list would
 be rejected with "User unknown". In order to make the transport mapping work
 one would still need a bunch of virtual alias or virtual mailbox table entries.
 
-  * In case of a virtual alias domain, there would need to be one identity
-    mapping from each mailing list address to itself.
-  * In case of a virtual mailbox domain, there would need to be a dummy mailbox
-    for each mailing list address.
-
-A\bAu\but\bto\bor\bre\bep\bpl\bli\bie\bes\bs
-
-In order to set up an autoreply for virtual recipients while still delivering
-mail as normal, set up a rule in a virtual alias table:
-
-    /etc/postfix/main.cf:
-        virtual_alias_maps = hash:/etc/postfix/virtual
-
-    /etc/postfix/virtual:
-        user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld
-
-This delivers mail to the recipient, and sends a copy of the mail to the
-address that produces automatic replies. The address can be serviced on a
-different machine, or it can be serviced locally by setting up a transport map
-entry that pipes all mail for autoreply.mydomain.tld into some script that
-sends an automatic reply back to the sender.
-
-DO NOT list autoreply.mydomain.tld in mydestination!
-
-    /etc/postfix/main.cf:
-        transport_maps = hash:/etc/postfix/transport
-
-    /etc/postfix/transport:
-        autoreply.mydomain.tld  autoreply:
-
-    /etc/postfix/master.cf:
-        # =============================================================
-        # service type  private unpriv  chroot  wakeup  maxproc command
-        #               (yes)   (yes)   (yes)   (never) (100)
-        # =============================================================
-        autoreply unix  -       n       n       -       -       pipe
-            flags= user=nobody argv=/path/to/autoreply $sender $mailbox
-
-This invokes /path/to/autoreply with the sender address and the user@domain.tld
-recipient address on the command line.
-
-For more information, see the pipe(8) manual page, and the comments in the
-Postfix master.cf file.
+  * In the case of a virtual alias DOMAIN, there would need to be an identity
+    mapping from each mailing list address to an address in a different domain.
+  * In the case of a virtual mailbox DOMAIN, there would need to be a dummy
+    virtual_mailbox_maps for each mailing list address.
 
index 4bbf74e93a72c87fd9816c0891dd683aaef4adc8..65baf51e37fb4ebbc6b6c964ad6d588f3748b0f0 100644 (file)
@@ -29,47 +29,27 @@ IPL can continue with that license.
 Major changes - database
 ------------------------
 
-[Infrastructure 20251226] Tooling to help with the migration away
-from Berkeley DB. 
-
-The new parameter default_cache_db_type controls the default database
-type for address_verify_map and postscreen_cache_map, and can
-eliminate a few hard-coded database types in main.cf. This parameter
-defaults to 'lmdb' if the default_database_type value equals 'lmdb',
-otherwise it assumes the historical value 'btree'.
-
-Sites that build without Berkeley DB are suggested to use one of the
-following commands in their build process:
-
-1 - Make lmdb the default for both default_database_type
-    and default_cache_db_type.
-
-    make makefiles CCARGS="-DNO_DB ..." default_database_type=lmdb \
-       default_cache_db_type=lmdb
+[Incompat 20260220] The alias_maps and alias_database parameter
+default values have changed from hash:/path/to/aliases (or
+dbm:/path/to/aliases) to $default_database_type:/path/to/aliases.
+This simplifies the migration away from Berkeley DB.
 
-2 - Make cdb the default for default_database_type, and make
-    lmdb the default for default_cache_db_type.
+[Infrastructure 20260219] Support to migrate a Postfix configuration
+that uses Berkeley DB hash: or btree: tables, to a configuration
+that uses lmdb: or a combination of cdb: and lmdb:. This is needed
+for (Linux) OS distributions that have removed Berkeley DB support.
+See NON_BERKELEYDB_README for manual and atomatic migratom support.
 
-    make makefiles CCARGS="-DNO_DB ..." default_database_type=cdb \
-       default_cache_db_type=lmdb
+Postfix already supports CDB and LMDB for more than 10 years.  It
+may be a good idea to do the migration before you need to upgrade
+to an OS distribution that no longer supports Berkeley DB.
 
-Postfix hash and btree files can easily be migrated when the source
-file (without the '.db name suffix) is available. Just run
-
-    postmap lmdb:/path/to/file
-
-That does not work for address_verify_map, postscreen_cache_map,
-and the optional smtp_sasl_auth_cache_name. These have no source
-file because they are managed by Postfix daemon processes.
-
-You can either ignore these files (they will be populated again
-over time), or you can copy the existing entries from the existing
-'.db' file to a new '.lmdb' . file. But that is possible only if
-Berkeley DB support is still available. Execute as root:
+[Infrastructure 20251226] Tooling to help with the migration away
+from Berkeley DB. 
 
-   rm -f /path/to/file.lmdb
-   postmap -s btree:/path/to/file | postmap -i lmdb:/path/to/file
-   chown postfix /path/to/file.lmdb
+The new parameter default_cache_db_type controls the default database
+type for address_verify_map, postscreen_cache_map, and
+smtp_sasl_auth_cache_name, previously hard-coded as 'btree'.
 
 [Feature 20250321] Safety: the SQLite client now logs a warning
 when a query uses double quotes instead of the Postfix-recommended
diff --git a/postfix/TESTING b/postfix/TESTING
new file mode 100644 (file)
index 0000000..1e821ff
--- /dev/null
@@ -0,0 +1,17 @@
+Testing is a work in progress.
+
+- As of Postfix 3.11 most new code is covered by tests.
+
+- Many Postfix tests require building with shared=yes and dynamicmaps=no.
+The shared=yes is needed so that test code can overrride internal
+dependencies with mocks; the dynamicmaps=no is needed until there
+is an easy way way to tell dynamicmaps support to not use the system
+dynamicmaps.cf file.
+
+- Historically, many tests in src/util, src/dns, and src/smtpd
+are non-hermetic: they have dependencies on DNS or on local system
+configuration.
+
+- The PTEST test framework needs to be integrated; this fixed many many
+non-hermetic tests in src/util and src/dns. That development stalled
+after postfix-3.8-20220816-nonprod.
index 00ab742c375d4166dbcda67b31094443304a1b60..39b1c0fb53cedcbbac812fea70e3c029089bb8b6 100644 (file)
 #        messages.
 # 
 #        Normally, the access(5) table is specified as a text  file
-#        that  serves  as  input  to  the  postmap(1) command.  The
-#        result, an indexed file in dbm or db format, is  used  for
-#        fast  searching  by  the  mail system. Execute the command
-#        "postmap /etc/postfix/access" to rebuild an  indexed  file
-#        after changing the corresponding text file.
-# 
-#        When  the  table  is provided via other means such as NIS,
-#        LDAP or SQL, the same lookups are  done  as  for  ordinary
-#        indexed files.
+#        that  serves  as input to the postmap(1) command to create
+#        an indexed file for fast lookup.
+# 
+#        Execute  the  command  "postmap  /etc/postfix/access"   to
+#        rebuild  a  default-type  indexed  file after changing the
+#        text file, or execute  "postmap  type:/etc/postfix/access"
+#        to specify an explicit type.
+# 
+#        The  default  indexed  file  type  is  configured with the
+#        default_database_type parameter. Depending on the platform
+#        this  may  be  one of lmdb:, cdb:, hash:, or dbm: (without
+#        the trailing ':').
+# 
+#        When the table is provided via other means  such  as  NIS,
+#        LDAP  or  SQL,  the  same lookups are done as for ordinary
+#        indexed files.  Managing such  databases  is  outside  the
+#        scope of Postfix.
 # 
 #        Alternatively,  the  table  can  be  provided  as  a regu-
 #        lar-expression map where patterns  are  given  as  regular
index f4b853c038c159b84b87e838a23f318a7b604594..85dac1bbdb3fc974c5d416c88ed4daa701ab1336 100644 (file)
@@ -60,20 +60,30 @@ decode:             root
 #        (including domain).
 # 
 #        Normally, the aliases(5) table is specified as a text file
-#        that serves as input  to  the  postalias(1)  command.  The
-#        result,  an  indexed file in dbm or db format, is used for
-#        fast lookup  by  the  mail  system.  Execute  the  command
-#        newaliases  in  order  to  rebuild  the indexed file after
-#        changing the Postfix alias database.
+#        that serves as input to the postalias(1) command to create
+#        an indexed file for fast lookup. The location of this file
+#        is system-dependent. This text will use  /path/to/aliases.
+# 
+#        Execute  the  command  "newaliases  to rebuild the indexed
+#        file after changing the text file. Execute  "postalias  -q
+#        name  /path/to/aliases"  to  query  a default-type indexed
+#        file, or execute "postalias -q name type:/path/to/aliases"
+#        to specify an explicit type.
+# 
+#        The  default  indexed  file  type  is  configured with the
+#        default_database_type parameter. Depending on the platform
+#        this  may  be  one of lmdb:, cdb:, hash:, or dbm: (without
+#        the trailing ':').
 # 
 #        When the table is provided via other means  such  as  NIS,
 #        LDAP  or  SQL,  the  same lookups are done as for ordinary
-#        indexed files.
+#        indexed files.  Managing such  databases  is  outside  the
+#        scope of Postfix.
 # 
-#        Alternatively, the  table  can  be  provided  as  a  regu-
-#        lar-expression  map  where  patterns  are given as regular
-#        expressions. In this case,  the  lookups  are  done  in  a
-#        slightly  different  way as described below under "REGULAR
+#        Alternatively,  the  table  can  be  provided  as  a regu-
+#        lar-expression map where patterns  are  given  as  regular
+#        expressions.  In  this  case,  the  lookups  are done in a
+#        slightly different way as described below  under  "REGULAR
 #        EXPRESSION TABLES".
 # 
 #        Users can control delivery of their own mail by setting up
@@ -87,63 +97,63 @@ decode:             root
 # 
 #                    name: value1, value2, ...
 # 
-#        o      Empty lines and whitespace-only lines are  ignored,
-#               as  are  lines whose first non-whitespace character
+#        o      Empty  lines and whitespace-only lines are ignored,
+#               as are lines whose first  non-whitespace  character
 #               is a `#'.
 # 
-#        o      A logical line starts with non-whitespace  text.  A
-#               line  that starts with whitespace continues a logi-
+#        o      A  logical  line starts with non-whitespace text. A
+#               line that starts with whitespace continues a  logi-
 #               cal line.
 # 
-#        The name is a local address (no domain part).  Use  double
-#        quotes  when the name contains any special characters such
-#        as whitespace, `#', `:', or `@'. The  name  is  folded  to
+#        The  name is a local address (no domain part).  Use double
+#        quotes when the name contains any special characters  such
+#        as  whitespace,  `#',  `:',  or `@'. The name is folded to
 #        lowercase, in order to make database lookups case insensi-
 #        tive.
 # 
-#        In addition, when an alias  exists  for  owner-name,  this
-#        will  override the envelope sender address, so that deliv-
+#        In  addition,  when  an  alias exists for owner-name, this
+#        will override the envelope sender address, so that  deliv-
 #        ery diagnostics are directed to owner-name, instead of the
-#        originator    of    the    message   (for   details,   see
-#        owner_request_special,       expand_owner_alias        and
-#        reset_owner_alias).   This  is  typically  used  to direct
-#        delivery errors to the maintainer of a mailing  list,  who
+#        originator   of   the   message    (for    details,    see
+#        owner_request_special,        expand_owner_alias       and
+#        reset_owner_alias).  This  is  typically  used  to  direct
+#        delivery  errors  to the maintainer of a mailing list, who
 #        is in a better position to deal with mailing list delivery
 #        problems than the originator of the undelivered mail.
 # 
 #        The value contains one or more of the following:
 # 
 #        address
-#               Mail is forwarded to address, which  is  compatible
+#               Mail  is  forwarded to address, which is compatible
 #               with the RFC 822 standard.
 # 
 #        /file/name
-#               Mail  is appended to /file/name. For details on how
-#               a file is written see the sections  "EXTERNAL  FILE
-#               DELIVERY"  and  "DELIVERY  RIGHTS"  in the local(8)
-#               documentation.  Delivery is not limited to  regular
-#               files.   For  example, to dispose of unwanted mail,
+#               Mail is appended to /file/name. For details on  how
+#               a  file  is written see the sections "EXTERNAL FILE
+#               DELIVERY" and "DELIVERY  RIGHTS"  in  the  local(8)
+#               documentation.   Delivery is not limited to regular
+#               files.  For example, to dispose of  unwanted  mail,
 #               deflect it to /dev/null.
 # 
 #        |command
-#               Mail is piped into command. Commands  that  contain
-#               special  characters,  such as whitespace, should be
-#               enclosed between double quotes. For details on  how
-#               a  command is executed see "EXTERNAL COMMAND DELIV-
+#               Mail  is  piped into command. Commands that contain
+#               special characters, such as whitespace,  should  be
+#               enclosed  between double quotes. For details on how
+#               a command is executed see "EXTERNAL COMMAND  DELIV-
 #               ERY" and "DELIVERY RIGHTS" in the local(8) documen-
 #               tation.
 # 
 #               When the command fails, a limited amount of command
-#               output is mailed back  to  the  sender.   The  file
-#               /usr/include/sysexits.h  defines  the expected exit
-#               status codes. For example, use "|exit 67" to  simu-
-#               late  a  "user  unknown"  error,  and  "|exit 0" to
+#               output  is  mailed  back  to  the sender.  The file
+#               /usr/include/sysexits.h defines the  expected  exit
+#               status  codes. For example, use "|exit 67" to simu-
+#               late a "user  unknown"  error,  and  "|exit  0"  to
 #               implement an expensive black hole.
 # 
 #        :include:/file/name
-#               Mail is sent to  the  destinations  listed  in  the
+#               Mail  is  sent  to  the  destinations listed in the
 #               named file.  Lines in :include: files have the same
-#               syntax  as  the  right-hand  side   of   aliases(5)
+#               syntax   as   the  right-hand  side  of  aliases(5)
 #               entries.
 # 
 #               A  destination  can  be  any  destination  that  is
@@ -154,12 +164,12 @@ decode:           root
 # 
 # ADDRESS EXTENSION
 #        When alias database search fails, and the recipient local-
-#        part contains  the  optional  recipient  delimiter  (e.g.,
-#        user+foo),  the  search  is  repeated  for  the unextended
+#        part  contains  the  optional  recipient  delimiter (e.g.,
+#        user+foo), the  search  is  repeated  for  the  unextended
 #        address (e.g., user).
 # 
-#        The  propagate_unmatched_extensions   parameter   controls
-#        whether  an  unmatched  address extension (+foo) is propa-
+#        The   propagate_unmatched_extensions   parameter  controls
+#        whether an unmatched address extension  (+foo)  is  propa-
 #        gated to the result of table lookup.
 # 
 # CASE FOLDING
@@ -167,88 +177,88 @@ decode:           root
 #        to lowercase before database lookup.
 # 
 # REGULAR EXPRESSION TABLES
-#        This  section  describes how the table lookups change when
+#        This section describes how the table lookups  change  when
 #        the table is given in the form of regular expressions. For
-#        a  description  of regular expression lookup table syntax,
-#        see regexp_table(5) or pcre_table(5). NOTE: these  formats
+#        a description of regular expression lookup  table  syntax,
+#        see  regexp_table(5) or pcre_table(5). NOTE: these formats
 #        do not use ":" at the end of a pattern.
 # 
-#        Each  regular  expression  is applied to the entire search
-#        string. Thus, a search string user+foo is  not  broken  up
+#        Each regular expression is applied to  the  entire  search
+#        string.  Thus,  a  search string user+foo is not broken up
 #        into user and foo.
 # 
-#        Regular  expressions are applied in the order as specified
-#        in the table, until a regular  expression  is  found  that
+#        Regular expressions are applied in the order as  specified
+#        in  the  table,  until  a regular expression is found that
 #        matches the search string.
 # 
-#        Lookup  results are the same as with indexed file lookups.
-#        For security reasons there is no support for $1,  $2  etc.
+#        Lookup results are the same as with indexed file  lookups.
+#        For  security  reasons there is no support for $1, $2 etc.
 #        substring interpolation.
 # 
 # SECURITY
-#        The  local(8)  delivery agent disallows regular expression
-#        substitution of $1 etc. in alias_maps, because that  would
+#        The local(8) delivery agent disallows  regular  expression
+#        substitution  of $1 etc. in alias_maps, because that would
 #        open a security hole.
 # 
-#        The  local(8) delivery agent will silently ignore requests
-#        to use the proxymap(8) server within  alias_maps.  Instead
-#        it  will  open the table directly.  Before Postfix version
-#        2.2, the local(8) delivery agent  will  terminate  with  a
+#        The local(8) delivery agent will silently ignore  requests
+#        to  use  the proxymap(8) server within alias_maps. Instead
+#        it will open the table directly.  Before  Postfix  version
+#        2.2,  the  local(8)  delivery  agent will terminate with a
 #        fatal error.
 # 
 # CONFIGURATION PARAMETERS
-#        The  following main.cf parameters are especially relevant.
-#        The text below provides  only  a  parameter  summary.  See
+#        The following main.cf parameters are especially  relevant.
+#        The  text  below  provides  only  a parameter summary. See
 #        postconf(5) for more details including examples.
 # 
 #        alias_database (see 'postconf -d' output)
-#               The  alias databases for local(8) delivery that are
+#               The alias databases for local(8) delivery that  are
 #               updated with "newaliases" or with "sendmail -bi".
 # 
 #        alias_maps (see 'postconf -d' output)
-#               Optional lookup tables that are searched only  with
-#               an  email  address  localpart  (no domain) and that
-#               apply only to local(8) recipients; this  is  unlike
-#               virtual_alias_maps  that  are often searched with a
-#               full email  address  (including  domain)  and  that
-#               apply  to  all  recipients:  local(8), virtual, and
+#               Optional  lookup tables that are searched only with
+#               an email address localpart  (no  domain)  and  that
+#               apply  only  to local(8) recipients; this is unlike
+#               virtual_alias_maps that are often searched  with  a
+#               full  email  address  (including  domain)  and that
+#               apply to all  recipients:  local(8),  virtual,  and
 #               remote.
 # 
 #        allow_mail_to_commands (alias, forward)
-#               Restrict local(8) mail delivery  to  external  com-
+#               Restrict  local(8)  mail  delivery to external com-
 #               mands.
 # 
 #        allow_mail_to_files (alias, forward)
-#               Restrict  local(8) mail delivery to external files.
+#               Restrict local(8) mail delivery to external  files.
 # 
 #        expand_owner_alias (no)
 #               When delivering to an alias "aliasname" that has an
 #               "owner-aliasname" companion alias, set the envelope
-#               sender   address   to   the   expansion   of    the
+#               sender    address   to   the   expansion   of   the
 #               "owner-aliasname" alias.
 # 
 #        propagate_unmatched_extensions (canonical, virtual)
-#               What  address  lookup tables copy an address exten-
+#               What address lookup tables copy an  address  exten-
 #               sion from the lookup key to the lookup result.
 # 
 #        owner_request_special (yes)
 #               Enable special treatment for owner-listname entries
 #               in the aliases(5) file, and don't split owner-list-
-#               name and listname-request address  localparts  when
+#               name  and  listname-request address localparts when
 #               the recipient_delimiter is set to "-".
 # 
 #        recipient_delimiter (empty)
-#               The  set  of  characters that can separate an email
-#               address localpart, user name, or  a  .forward  file
+#               The set of characters that can  separate  an  email
+#               address  localpart,  user  name, or a .forward file
 #               name from its extension.
 # 
 #        Available in Postfix version 2.3 and later:
 # 
 #        frozen_delivered_to (yes)
-#               Update  the  local(8)  delivery agent's idea of the
-#               Delivered-To:    address    (see     prepend_deliv-
-#               ered_header)  only once, at the start of a delivery
-#               attempt; do not update  the  Delivered-To:  address
+#               Update the local(8) delivery agent's  idea  of  the
+#               Delivered-To:     address    (see    prepend_deliv-
+#               ered_header) only once, at the start of a  delivery
+#               attempt;  do  not  update the Delivered-To: address
 #               while expanding aliases or .forward files.
 # 
 # STANDARDS
@@ -261,12 +271,12 @@ decode:           root
 #        postconf(5), configuration parameters
 # 
 # README FILES
-#        Use  "postconf  readme_directory" or "postconf html_direc-
+#        Use "postconf readme_directory" or  "postconf  html_direc-
 #        tory" to locate this information.
 #        DATABASE_README, Postfix lookup table overview
 # 
 # LICENSE
-#        The Secure Mailer license must be  distributed  with  this
+#        The  Secure  Mailer  license must be distributed with this
 #        software.
 # 
 # AUTHOR(S)
index 894fd5bcdcdf8955aa076270f466a6cf80cdd714..5785abaa112494b4ec0ff1a69eaaa5990241d880 100644 (file)
 #        the queue.  The address mapping is recursive.
 # 
 #        Normally, the canonical(5) table is specified  as  a  text
-#        file  that serves as input to the postmap(1) command.  The
-#        result, an indexed file in dbm or db format, is  used  for
-#        fast  searching  by  the  mail system. Execute the command
-#        "postmap /etc/postfix/canonical"  to  rebuild  an  indexed
-#        file after changing the corresponding text file.
-# 
-#        When  the  table  is provided via other means such as NIS,
-#        LDAP or SQL, the same lookups are  done  as  for  ordinary
-#        indexed files.
+#        file  that  serves  as  input to the postmap(1) command to
+#        create an indexed file for fast lookup.
+# 
+#        Execute the command  "postmap  /etc/postfix/canonical"  to
+#        rebuild  a  default-type  indexed  file after changing the
+#        text file, or execute  "postmap  type:/etc/postfix/canoni-
+#        cal" to specify an explicit type.
+# 
+#        The  default  indexed  file  type  is  configured with the
+#        default_database_type parameter. Depending on the platform
+#        this  may  be  one of lmdb:, cdb:, hash:, or dbm: (without
+#        the trailing ':').
+# 
+#        When the table is provided via other means  such  as  NIS,
+#        LDAP  or  SQL,  the  same lookups are done as for ordinary
+#        indexed files.  Managing such  databases  is  outside  the
+#        scope of Postfix.
 # 
 #        Alternatively,  the  table  can  be  provided  as  a regu-
 #        lar-expression map where patterns  are  given  as  regular
index 508e44a42cb3bf3d23c580d1d5cb3775c591ec95..4ebe3dd11e512880183690a1e059899ca73e48ee 100644 (file)
 #        that are used in SMTP protocol commands).
 # 
 #        Normally, the generic(5) table is specified as a text file
-#        that serves as  input  to  the  postmap(1)  command.   The
-#        result,  an  indexed file in dbm or db format, is used for
-#        fast searching by the mail  system.  Execute  the  command
-#        "postmap  /etc/postfix/generic" to rebuild an indexed file
-#        after changing the corresponding text file.
-# 
-#        When the table is provided via other means  such  as  NIS,
-#        LDAP  or  SQL,  the  same lookups are done as for ordinary
-#        indexed files.
+#        that serves as input to the postmap(1) command  to  create
+#        an indexed file for fast lookup.
+# 
+#        Execute  the  command  "postmap  /etc/postfix/generic"  to
+#        rebuild  a default-type indexed file  after  changing  the
+#        text  file, or execute "postmap type:/etc/postfix/generic"
+#        to specify an explicit type.
+# 
+#        The default indexed  file  type  is  configured  with  the
+#        default_database_type parameter. Depending on the platform
+#        this may be one of lmdb:, cdb:, hash:,  or  dbm:  (without
+#        the trailing ':').
+# 
+#        When  the  table  is provided via other means such as NIS,
+#        LDAP or SQL, the same lookups are  done  as  for  ordinary
+#        indexed  files.   Managing  such  databases is outside the
+#        scope of Postfix.
 # 
 #        Alternatively, the  table  can  be  provided  as  a  regu-
 #        lar-expression  map  where  patterns  are given as regular
index 0d3ae794621d8c30935d7a0af4b5a64c60137376..88c3371615039990ee728b31573352b7286cc501 100644 (file)
@@ -99,6 +99,7 @@ $daemon_directory/local:f:root:-:755
 $daemon_directory/main.cf:f:root:-:644:o
 $daemon_directory/master.cf:f:root:-:644:o
 $daemon_directory/master:f:root:-:755
+$daemon_directory/nbdb_reindexd:f:root:-:755
 $daemon_directory/oqmgr:f:root:-:755
 $daemon_directory/pickup:f:root:-:755
 $daemon_directory/pipe:f:root:-:755
@@ -107,6 +108,7 @@ $daemon_directory/post-install:f:root:-:755
 #$daemon_directory/postfix-files:f:root:-:644:o
 #$daemon_directory/postfix-files.d:d:root:-:755:o
 $daemon_directory/postfix-script:f:root:-:755
+$daemon_directory/postfix-non-bdb-script:f:root:-:755
 $daemon_directory/postfix-tls-script:f:root:-:755
 $daemon_directory/postfix-wrapper:f:root:-:755
 $daemon_directory/postmulti-script:f:root:-:755
@@ -172,6 +174,7 @@ $manpage_directory/man1/postalias.1:f:root:-:644
 $manpage_directory/man1/postcat.1:f:root:-:644
 $manpage_directory/man1/postconf.1:f:root:-:644
 $manpage_directory/man1/postdrop.1:f:root:-:644
+$manpage_directory/man1/postfix-non-bdb.1:f:root:-:644
 $manpage_directory/man1/postfix-tls.1:f:root:-:644
 $manpage_directory/man1/postfix.1:f:root:-:644
 $manpage_directory/man1/postkick.1:f:root:-:644
@@ -220,6 +223,7 @@ $manpage_directory/man8/flush.8:f:root:-:644
 $manpage_directory/man8/lmtp.8:f:root:-:644
 $manpage_directory/man8/local.8:f:root:-:644
 $manpage_directory/man8/master.8:f:root:-:644
+$manpage_directory/man8/nbdb_reindexd.8:f:root:-:644
 $manpage_directory/man8/nqmgr.8:f:root:-:644:o
 $manpage_directory/man8/oqmgr.8:f:root:-:644:
 $manpage_directory/man8/pickup.8:f:root:-:644
@@ -310,6 +314,7 @@ $readme_directory/MYSQL_README:f:root:-:644
 $readme_directory/SMTPUTF8_README:f:root:-:644
 $readme_directory/SQLITE_README:f:root:-:644
 $readme_directory/NFS_README:f:root:-:644
+$readme_directory/NON_BERKELEYDB_README:f:root:-:644
 $readme_directory/OVERVIEW:f:root:-:644
 $readme_directory/PACKAGE_README:f:root:-:644
 $readme_directory/PCRE_README:f:root:-:644
@@ -375,6 +380,7 @@ $html_directory/MYSQL_README.html:f:root:-:644
 $html_directory/SMTPUTF8_README.html:f:root:-:644
 $html_directory/SQLITE_README.html:f:root:-:644
 $html_directory/NFS_README.html:f:root:-:644
+$html_directory/NON_BERKELEYDB_README.html:f:root:-:644
 $html_directory/OVERVIEW.html:f:root:-:644
 $html_directory/PACKAGE_README.html:f:root:-:644
 $html_directory/PCRE_README.html:f:root:-:644
@@ -433,6 +439,7 @@ $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
 $html_directory/newaliases.1.html:h:$html_directory/mailq.1.html:-:644
+$html_directory/nbdb_reindexd.8.html:f:root:-:644
 $html_directory/oqmgr.8.html:f:root:-:644
 $html_directory/pcre_table.5.html:f:root:-:644
 $html_directory/pgsql_table.5.html:f:root:-:644
@@ -445,6 +452,7 @@ $html_directory/postconf.5.html:f:root:-:644
 $html_directory/postdrop.1.html:f:root:-:644
 $html_directory/postfix-logo.jpg:f:root:-:644
 $html_directory/postfix-manuals.html:f:root:-:644
+$html_directory/postfix-non-bdb.1.html:f:root:-:644
 $html_directory/postfix-tls.1.html:f:root:-:644
 $html_directory/postfix-wrapper.5.html:f:root:-:644
 $html_directory/postfix.1.html:f:root:-:644
diff --git a/postfix/conf/postfix-non-bdb-script b/postfix/conf/postfix-non-bdb-script
new file mode 100644 (file)
index 0000000..f3b938c
--- /dev/null
@@ -0,0 +1,237 @@
+#!/bin/sh
+
+#++
+# NAME
+#      postfix-non-bdb 1
+# SUMMARY
+#      Postfix non-Berkeley-DB migration
+# SYNOPSIS
+#      \fBpostfix non-bdb\fR \fIsubcommand\fR
+# DESCRIPTION
+#      The "\fBpostfix non-bdb \fIsubcommand\fR" feature edits main.cf
+#      and master.cf, to manage the migration of an existing Postfix
+#      configuration that uses Berkeley DB type "hash:" or "btree:"
+#      tables (which are no longer supported on some OS distributions),
+#      to supported types such as "cdb:" or "lmdb:".
+#
+#      The following subcommands are available:
+# .IP \fBstatus\fR
+#      Reports the non-Berkeley-DB migration status, without making
+#      any changes.
+# .IP \fBdisable\fR
+#      Edits main.cf and master.cf, to turn off the \fBenable-redirect\fR
+#      and \fBenable-reindex\fR features.
+# .sp
+#      This will break integration with other software such as
+#      mailman versions from before May 2025 when they want to
+#      use "postmap hash:/path/to/file", for example, to update a
+#      mailman-maintained table.
+# .IP "\fBenable-redirect\fR (aliasing)"
+#      Edits main.cf and master.cf, to enable redirection (aliasing)
+#      from Berkeley DB types "hash" and "btree" to the non-Berkeley-DB
+#      types specified with $default_database_type and
+#      $default_cache_db_type. Custom redirection may be configured
+#      with non_bdb_custom_mapping.
+# .sp
+#      This configuration will not automatically create non-Berkeley-DB
+#      indexed database files. Instead, Postfix programs will log an
+#      error as they fail to open an indexed database file, and will
+#      leave it to the system administrator to run postmap(1) or
+#      postalias(1) to create that file.
+# .sp
+#      This will fix integration with other software such as mailman
+#      versions from before May 2025 when they want to use "postmap
+#      hash:/path/to/file", for example, to update a mailman-maintained
+#      table.
+# .sp
+#      This subcommand will not make any changes when
+#      default_database_type or default_cache_db_type specify a hash:
+#      or btree: type.
+# .IP \fBenable-reindex\fR
+#      Edits main.cf and master.cf, to implement \fBenable-redirect\fR,
+#      and to automatically create a non-Berkeley-DB indexed database
+#      file when a daemon program wants to access a file that does not
+#      yet exist. This uses the nbdb_reindexd(8) daemon to run postmap(1)
+#      or postalias(1) as described in "SECURITY" below.
+# .sp
+#      This subcommand immediately generates non-Berkeley-DB indexed
+#      files for unprivileged command-line programs that cannot send
+#      requests to the nbdb_reindexd(8) daemon server. This involves
+#      "hash:" and "btree:" tables that are used by postqueue(1) and
+#      sendmail(1) as specified in authorized_flush_users and
+#      authorized_mailq_users, and by sendmail(1) and postdrop(1)
+#      as specified in authorized_submit_users and
+#      local_login_sender_maps.
+# .sp
+#      This subcommand will not make any changes when
+#      default_database_type or default_cache_db_type specify a hash:
+#      or btree: type.
+# .sp
+#      \fINOTE: \fBenable-reindex\fI should be used only temporarily
+#      to generate most of the non-Berkeley-DB indexed files that Postfix
+#      needs. Leaving this enabled may expose the system to
+#      privilege-escalation attacks. There are no security
+#      concerns for using \fBenable-redirect\fR.
+# SECURITY
+# .ad
+# .fi
+#      The nbdb_reindexd(8) daemon automatically generates a
+#      non-Berkeley-DB indexed file only if the database pathname matches
+#      the directory prefixes specified with
+#      non_bdb_migration_allow_root_prefixes (for files that must be
+#      owned by root), or with non_bdb_migration_allow_user_prefixes
+#      (for files that must be owned by a non-root user). Additional
+#      restrictions on file and directory ownership and permissions
+#      are documented in nbdb_reindexd(8).
+# CONFIGURATION PARAMETERS
+# .ad 
+# .fi
+#      The "\fBpostfix non-bdb \fIsubcommand\fR" feature
+#      updates the following configuration parameter:
+# .IP "\fBnon_bdb_migration_level (disable)\fR"
+#      The non-Berkeley-DB migration service level.
+# .PP
+#      Other relevant parameters:
+# .IP "\fBnon_bdb_custom_mapping (empty)\fR"
+#      When non-Berkeley-DB migration is enabled, an optional mapping
+#      from a hash: or btree: type to a non-Berkeley-DB type.
+# .IP "\fBnon_bdb_migration_allow_root_prefixes (see 'postconf -d non_bdb_migration_allow_root_prefixes' output)\fR"
+#      A list of trusted pathname prefixes that must be matched when
+#      the non-Berkeley-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+#      run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with "root" privilege.
+# .IP "\fBnon_bdb_migration_allow_user_prefixes (see 'postconf -d non_bdb_migration_allow_user_prefixes' output)\fR"
+#      A list of trusted pathname prefixes that must be matched when
+#      the non-Berkeley-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+#      run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with non-root privilege.
+# SEE ALSO
+#      nbdb_reindexd(8) reindexing service
+# README FILES
+# .ad
+# .fi
+#      Use "\fBpostconf readme_directory\fR" or
+#      "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+#      NON_BERKELEYDB_README, migration guide
+# LICENSE
+# .ad
+# .fi
+#      The Secure Mailer license must be distributed with this software.
+# HISTORY
+#      The "\fBpostfix non-bdb\fR" command was introduced with Postfix
+#      version 3.11.
+# AUTHOR(S)
+#      Wietse Venema
+#      porcupine.org
+#--
+
+umask 022
+SHELL=/bin/sh
+
+case $command_directory in
+"") echo This script must be run by the postfix command. 1>&2
+    echo Do not run directly. 1>&2 exit 1;; esac
+
+cd $command_directory || {
+    # Let's hope there's a "postlog" somewhere on the PATH
+    FATAL="postlog -p fatal -t $MAIL_LOGTAG/postfix-tls-script"
+    msg="no Postfix command directory '${command_directory}'"
+    $FATAL "$msg" || { echo "$msg" >&2; sleep 1; }
+    exit 1
+}
+
+postconf=$command_directory/postconf
+LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-non-bdb-script"
+INFO="$LOGGER -p info"
+WARN="$LOGGER -p warn"
+ERROR="$LOGGER -p error"
+FATAL="$LOGGER -p fatal"
+
+REINDEX_SVC=nbdb_reindex
+REINDEX_BIN=nbdb_reindexd
+
+# Helper functions.
+
+reindex_for_non_daemons() {
+    # The following tables are needed by unprivileged command-line
+    # tools that cannot send requests to the reindexing service unless
+    # they are run by root.
+    for type_name in `$postconf -h authorized_flush_users \
+        authorized_mailq_users authorized_submit_users \
+        local_login_sender_maps`; \
+    do
+        case $type_name in
+            hash:*|btree:*)
+                $INFO Proactively reindexing $type_name
+                postmap $type_name || exit 1;;
+        esac
+    done
+}
+
+validate_redirect_targets() {
+    # By default, the Berkeley DB type 'hash' will redirect to
+    # $default_database_type, and type 'btree' will redirect to
+    # $default_cache_db_type. Require that the targets are not
+    # Berkeley DB types.
+    for param in default_database_type default_cache_db_type
+    do
+       eval type="`$postconf -h $param`"
+       case $type in
+       hash|btree)
+           $FATAL "parameter $param specifies a Berkeley DB type: '$type'"
+           exit 1;;
+       esac
+    done
+}
+
+# Subcommand implementations.
+
+status() {
+    $postconf -h non_bdb_migration_level
+}
+
+disable_all() {
+    $postconf -X non_bdb_migration_level
+    $postconf -MX ${REINDEX_SVC}/unix
+}
+
+enable_redirect() {
+    validate_redirect_targets
+    $postconf -MX ${REINDEX_SVC}/unix
+    $postconf non_bdb_migration_level=enable-redirect || exit 1
+}
+
+enable_reindex() {
+    validate_redirect_targets
+    reindex_for_non_daemons
+    $postconf -M \
+       ${REINDEX_SVC}/unix="${REINDEX_SVC} unix y n n - 1 ${REINDEX_BIN}" || exit 1
+    $postconf non_bdb_migration_level=enable-reindex || exit 1
+}
+
+usage() {
+    $FATAL "usage: postfix non-bdb enable-redirect (or enable-reindex, or disable)"
+    exit 1
+}
+
+#
+# Parse JCL
+#
+case $# in
+  1) ;;
+  *) usage;;
+esac
+
+case "$1" in
+enable-redirect)
+   enable_redirect;;
+enable-reindex)
+    enable_reindex;;
+disable)
+    disable_all;;
+status)
+    status;;
+*) usage
+esac
+
+exit 0
index de86d382b23eec9ffed77b94249013222e8daa92..e19591a4d95cac1eb63cc278115e6e1996ebd4eb 100755 (executable)
@@ -142,6 +142,7 @@ start|start-fg)
                }
                # Foreground this so it can be stopped. All inodes are cached.
                $daemon_directory/postfix-script check-warn
+               $daemon_directory/postfix-script check-alias-maps-migration
        fi
        $INFO starting the Postfix mail system || exit 1
        case $1 in
@@ -245,6 +246,7 @@ flush)
 check)
 
        $daemon_directory/postfix-script check-fatal || exit 1
+       $daemon_directory/postfix-script check-alias-maps-migration
        $daemon_directory/postfix-script check-warn
        exit 0
        ;;
@@ -298,6 +300,34 @@ check-fatal)
        exit 0
        ;;
 
+check-alias-maps-migration)
+       # This command is NOT part of the public interface.
+
+       # As of Postfix 3.11, the default alias_maps value
+       # contains $default_database_type:/path/to/aliases. When
+       # default_database_type is changed to lmdb or cdb, Postfix
+       # will not generate hash:/path/to/aliases requests that can
+       # be resolved dynamically with enable-redirect or enable-reindex.
+       # 
+       # To avoid this, craft a one-time stand-alone re-indexing request.
+       test -f $config_directory/check-alias-maps-migration-done && exit 0
+       BACKUP_IFS="$IFS"
+       for map in `$command_directory/postconf -hx alias_maps`
+       do
+           echo "$map" | (
+               IFS=: read type path; IFS="$BACKUP_IFS"
+               case "$type" in
+               cdb|lmdb)
+                   test ! -f "$path.$type" -a -f "$path" -a -f "$path.db" && {
+                       $daemon_directory/nbdb_reindexd -S "hash:$path" ||
+                           $WARN "See https://www.postfix.org/NON_BERKELEYDB_README.html for suggestions"
+                   }
+               esac
+           )
+       done
+       touch $config_directory/check-alias-maps-migration-done
+       ;;
+
 check-warn)
        # This command is NOT part of the public interface.
 
@@ -408,9 +438,9 @@ post-install)
        $daemon_directory/post-install "$@"
        ;;
 
-tls)
-       shift
-       $daemon_directory/postfix-tls-script "$@"
+tls|non-bdb)
+       cmd=$1; shift
+       $daemon_directory/postfix-$cmd-script "$@"
        ;;
 
 /*)
@@ -452,7 +482,7 @@ logrotate)
        ;;
 
 *)
-       $FATAL "unknown command: '$1'. Usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration, logrotate)"
+       $FATAL "unknown command: '$1'. Usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration, logrotate, tls, non-bdb)"
        exit 1
        ;;
 
index 891021fa6b338c2577a4cb339cca47cf8cc867fb..e82225b5952a6a9b71cb9cace2e83c242c0f2d10 100644 (file)
 #        messages.
 # 
 #        Normally,  the  relocated(5)  table is specified as a text
-#        file that serves as input to the postmap(1) command.   The
-#        result,  an  indexed file in dbm or db format, is used for
-#        fast searching by the mail  system.  Execute  the  command
-#        "postmap  /etc/postfix/relocated"  to  rebuild  an indexed
-#        file after changing the corresponding relocated table.
-# 
-#        When the table is provided via other means  such  as  NIS,
-#        LDAP  or  SQL,  the  same lookups are done as for ordinary
-#        indexed files.
+#        file that serves as input to  the  postmap(1)  command  to
+#        create an indexed file for fast lookup.
+# 
+#        Execute  the  command  "postmap /etc/postfix/relocated" to
+#        rebuild a default-type indexed  file  after  changing  the
+#        text  file,  or  execute  "postmap type:/etc/postfix/relo-
+#        cated" to specify an explicit type.
+# 
+#        The default indexed  file  type  is  configured  with  the
+#        default_database_type parameter. Depending on the platform
+#        this may be one of lmdb:, cdb:, hash:,  or  dbm:  (without
+#        the trailing ':').
+# 
+#        When  the  table  is provided via other means such as NIS,
+#        LDAP or SQL, the same lookups are  done  as  for  ordinary
+#        indexed  files.   Managing  such  databases is outside the
+#        scope of Postfix.
 # 
 #        Alternatively, the  table  can  be  provided  as  a  regu-
 #        lar-expression  map  where  patterns  are given as regular
index f624da5e014a71fa72302b6362aeec83da249620..ea6d92556e6360b7850b49b5919f859e27da8979 100644 (file)
 #               relayhost, or from the recipient domain.
 # 
 #        Normally, the transport(5) table is specified  as  a  text
-#        file  that serves as input to the postmap(1) command.  The
-#        result, an indexed file in dbm or db format, is  used  for
-#        fast  searching  by  the  mail system. Execute the command
-#        "postmap /etc/postfix/transport"  to  rebuild  an  indexed
-#        file after changing the corresponding transport table.
-# 
-#        When  the  table  is provided via other means such as NIS,
-#        LDAP or SQL, the same lookups are  done  as  for  ordinary
-#        indexed files.
+#        file  that  serves  as  input to the postmap(1) command to
+#        create an indexed file for fast lookup.
+# 
+#        Execute the command  "postmap  /etc/postfix/transport"  to
+#        rebuild  a  default-type  indexed  file after changing the
+#        text file, or  execute  "postmap  type:/etc/postfix/trans-
+#        port" to specify an explicit type.
+# 
+#        The  default  indexed  file  type  is  configured with the
+#        default_database_type parameter. Depending on the platform
+#        this  may  be  one of lmdb:, cdb:, hash:, or dbm: (without
+#        the trailing ':').
+# 
+#        When the table is provided via other means  such  as  NIS,
+#        LDAP  or  SQL,  the  same lookups are done as for ordinary
+#        indexed files.  Managing such  databases  is  outside  the
+#        scope of Postfix.
 # 
 #        Alternatively,  the  table  can  be  provided  as  a regu-
 #        lar-expression map where patterns  are  given  as  regular
index 63799778c8791ebbd48548fbd375f5b65a9af6b5..87b46df2ce6b3854303247500dc877d453674001 100644 (file)
 #        addresses in general.
 # 
 #        Normally, the virtual(5) alias table  is  specified  as  a
-#        text  file that serves as input to the postmap(1) command.
-#        The result, an indexed file in dbm or db format,  is  used
-#        for fast searching by the mail system. Execute the command
-#        "postmap /etc/postfix/virtual" to rebuild an indexed  file
-#        after changing the corresponding text file.
-# 
-#        When  the  table  is provided via other means such as NIS,
-#        LDAP or SQL, the same lookups are  done  as  for  ordinary
-#        indexed files.
+#        text  file  that serves as input to the postmap(1) command
+#        to create an indexed file for fast lookup.
+# 
+#        Execute  the  command  "postmap  /etc/postfix/virtual"  to
+#        rebuild  a  default-type  indexed  file after changing the
+#        text file, or execute "postmap  type:/etc/postfix/virtual"
+#        to specify an explicit type.
+# 
+#        The  default  indexed  file  type  is  configured with the
+#        default_database_type parameter. Depending on the platform
+#        this  may  be  one of lmdb:, cdb:, hash:, or dbm: (without
+#        the trailing ':').
+# 
+#        When the table is provided via other means  such  as  NIS,
+#        LDAP  or  SQL,  the  same lookups are done as for ordinary
+#        indexed files.  Managing such  databases  is  outside  the
+#        scope of Postfix.
 # 
 #        Alternatively,  the  table  can  be  provided  as  a regu-
 #        lar-expression map where patterns  are  given  as  regular
index 7446b7877e4dad2b3d84c305b93442361e1dcd02..62f178e82016527bcaf7c153113daf4b97f8af5e 100644 (file)
@@ -671,7 +671,7 @@ listed below. See the <a href="postconf.5.html">postconf(5)</a> manpage for a de
 
 <tr> <td><a href="postconf.5.html#config_directory">config_directory</a></td> <td>/etc/postfix</td> </tr>
 
-<tr> <td><a href="postconf.5.html#default_database_type">default_database_type</a></td> <td>lmdb or hash</td> </tr>
+<tr> <td><a href="postconf.5.html#default_database_type">default_database_type</a></td> <td>lmdb, cdb, or hash</td> </tr>
 
 <tr> <td><a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a></td> <td>lmdb or btree</td> </tr>
 
@@ -741,7 +741,7 @@ default</th> </tr>
 <td>/etc/postfix</td> </tr>
 
 <tr> <td>DEF_DB_TYPE</td> <td><a href="postconf.5.html#default_database_type">default_database_type</a></td>
-<td>lmdb or hash</td> </tr>
+<td>lmdb, cdb, or hash</td> </tr>
 
 <tr> <td>DEF_CACHE_DB_TYPE</td> <td><a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a></td>
 <td>lmdb or btree</td> </tr>
@@ -773,12 +773,17 @@ default</th> </tr>
 <tr> <td>DEF_SENDMAIL_PATH</td> <td><a href="postconf.5.html#sendmail_path">sendmail_path</a></td>
 <td>/usr/sbin/sendmail</td> </tr>
 
+<tr> <td>DEF_SHLIB_DIR</td> <td><a href="postconf.5.html#shlib_directory">shlib_directory</a></td>
+<td>/usr/lib/postfix</td> </tr>
+
 </table>
 
 </blockquote>
 
 <p> Note: the <a href="postconf.5.html#data_directory">data_directory</a> parameter (for caches and pseudo-random
-numbers) was introduced with Postfix version 2.5. </p>
+numbers) was introduced with Postfix version 2.5; <a href="postconf.5.html#shlib_directory">shlib_directory</a>
+(for shared-library objects and database plugins) with Postfix
+version 3.0. </p>
 
 <h3><a name="build_other">4.7 - Overriding other compile-time
 features</a></h3>
@@ -816,7 +821,7 @@ off Postfix features at compile time:</td> </tr>
 
 <tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley
 DB support. By default, Berkeley DB support is compiled in on
-platforms that are known to support this feature. If you override
+platforms that have historically supported this feature. If you override
 this, then you probably should also override <a href="postconf.5.html#default_database_type">default_database_type</a>
 or DEF_DB_TYPE as described in section 4.6. </td> </tr>
 
@@ -1550,8 +1555,8 @@ the exact location of the text file.  </p>
 
 <p> First, be sure to update the text file with aliases for root,
 postmaster and "postfix" that forward mail to a real person.  Postfix
-has a sample aliases file /etc/postfix/aliases that you can adapt
-to local conditions.  </p>
+has a sample aliases file /etc/postfix/aliases that you can copy
+and adapt to local conditions.  /p>
 
 <blockquote>
 <pre>
@@ -1577,6 +1582,15 @@ following commands: </p>
 </pre>
 </blockquote>
 
+<p> The form "postalias /etc/aliases" builds a default-type indexed
+file. Use "postalias <i>type</i>:/etc/aliases" to specify an explicit
+type (it should match the type in the output from "postconf -x
+<a href="postconf.5.html#alias_maps">alias_maps</a>"). </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <h2><a name="hamlet">11 - To chroot or not to chroot</a></h2>
 
 <p> Postfix daemon processes can be configured (via <a href="master.5.html">master.cf</a>) to
index af931119e32625575f1e8a044ad15c798b06b902..d84b4da072bd58f5ad6a5130055b9c477e1515c1 100644 (file)
@@ -8,14 +8,14 @@ DAEMONS       =  bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
        oqmgr.8.html spawn.8.html flush.8.html virtual.8.html qmqpd.8.html \
        trace.8.html verify.8.html proxymap.8.html anvil.8.html \
        scache.8.html discard.8.html tlsmgr.8.html postscreen.8.html \
-       dnsblog.8.html tlsproxy.8.html postlogd.8.html
+       dnsblog.8.html tlsproxy.8.html postlogd.8.html nbdb_reindexd.8.html
 COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
        postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
        postlog.1.html postdrop.1.html postmap.1.html postmulti.1.html \
        postqueue.1.html postsuper.1.html sendmail.1.html \
        smtp-source.1.html smtp-sink.1.html posttls-finger.1.html \
        qmqp-source.1.html qmqp-sink.1.html \
-       qshape.1.html postfix-tls.1.html makedefs.1.html
+       qshape.1.html postfix-tls.1.html makedefs.1.html postfix-non-bdb.1.html
 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 \
@@ -92,6 +92,10 @@ master.8.html: ../src/master/master.c
        PATH=../mantools:$$PATH; \
        srctoman $? | $(AWK) | $(NROFF) -man | uniq | $(MAN2HTML) | postlink >$@
 
+nbdb_reindexd.8.html: ../src/nbdb_reindexd/nbdb_reindexd.c
+       PATH=../mantools:$$PATH; \
+       srctoman $? | $(AWK) | $(NROFF) -man | uniq | $(MAN2HTML) | postlink >$@
+
 oqmgr.8.html: ../src/oqmgr/qmgr.c
        PATH=../mantools:$$PATH; \
        srctoman $? | sed -e 's/qmgr[^_]/o&/' \
@@ -187,6 +191,10 @@ postfix.1.html: ../src/postfix/postfix.c
        PATH=../mantools:$$PATH; \
        srctoman $? | $(AWK) | $(NROFF) -man | uniq | $(MAN2HTML) | postlink >$@
 
+postfix-non-bdb.1.html: ../conf/postfix-non-bdb-script
+       PATH=../mantools:$$PATH; \
+       srctoman - $? | $(AWK) | $(NROFF) -man | uniq | $(MAN2HTML) | postlink >$@
+
 postfix-tls.1.html: ../conf/postfix-tls-script
        PATH=../mantools:$$PATH; \
        srctoman - $? | $(AWK) | $(NROFF) -man | uniq | $(MAN2HTML) | postlink >$@
diff --git a/postfix/html/NON_BERKELEYDB_README.html b/postfix/html/NON_BERKELEYDB_README.html
new file mode 100644 (file)
index 0000000..655caf9
--- /dev/null
@@ -0,0 +1,684 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "https://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Non-Berkeley-DB migration</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel='stylesheet' type='text/css' href='postfix-doc.css'>
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Non-Berkeley-DB migration</h1>
+
+<hr>
+
+<h2> Table of contents </h2>
+
+<ul>
+
+<li> <a href="#intro">Introduction </a>
+
+<li> <a href="#background">Background </a>
+
+<li> <a href="#build-conf">Skip this if not building Postfix from
+source, or if your system still supports Berkeley DB </a>
+
+<li> <a href="#level-overview"> Migration support level overview </a>
+
+<li> <a href="#disable"> Level 'disable': manual migration </a>
+
+<li> <a href="#enable-redirect"> Level 'enable-redirect': database
+aliasing </a>
+
+<li> <a href="#enable-reindex"> Level 'enable-reindex': redirect
+and automatically generate non-Berkeley-DB indexed files </a>
+
+<li> <a href="#addr-errors">Addressing errors with automatic indexed
+file generation </a>
+
+<li> <a href="#mailman">Appendix: Mailman integration </a>
+
+</ul>
+
+<h2> <a name="intro">Introduction </a> </h2>
+
+<p> (Please see the <a href="#mailman">Appendix</a> for Mailman
+integration tips.) </p>
+
+<p> After running the same Postfix configuration for a decade or
+more, there is a rude awakening when you update the OS to a newer
+version that has deleted its support for Berkeley DB. Postfix
+programs fail to open all <a href="DATABASE_README.html#types">hash</a>: and <a href="DATABASE_README.html#types">btree</a>: tables with messages
+like this: </p>
+
+<blockquote>
+<pre>
+Berkeley DB support for '<a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual' is not available
+for this build; see https://www.postfix.org/<a href="NON_BERKELEYDB_README.html">NON_BERKELEYDB_README</a>.html
+for alternatives
+</pre>
+</blockquote>
+
+<p> This document comes to the rescue, with strategies to migrate
+an existing Postfix configuration that uses Berkeley DB <a href="DATABASE_README.html#types">hash</a>: and
+<a href="DATABASE_README.html#types">btree</a>: database files, to an OS distribution that has removed
+Berkeley DB support, with a Postfix configuration that uses <a href="lmdb_table.5.html">lmdb</a>: (or
+a combination of <a href="CDB_README.html">cdb</a>: and <a href="lmdb_table.5.html">lmdb</a>:). <p>
+
+<p> By the way, you don't have to wait until Berkeley DB support
+is removed; your can proactively use the steps described here on a
+system that still has Berkeley DB, to migrate a Postfix configuration
+from Berkeley DB to <a href="lmdb_table.5.html">lmdb</a>: (or a combination of <a href="CDB_README.html">cdb</a>: and <a href="lmdb_table.5.html">lmdb</a>:).
+
+<h2> <a name="background">Background </a> </h2>
+
+<p> Historically, Postfix has used Berkeley DB <a href="DATABASE_README.html#types">hash</a>: and <a href="DATABASE_README.html#types">btree</a>: for
+key-value stores, as indicated in the "With Berkeley DB" table
+column below. In a world without Berkeley DB, good replacements are
+<a href="CDB_README.html">cdb</a>: and <a href="lmdb_table.5.html">lmdb</a>: as indicated in the "No Berkeley DB" column. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Purpose </th> <th> With Berkeley DB </th> <th> No Berkeley
+DB </th> </tr>
+
+<tr> <td> Mostly-static data such as aliases, <a href="postconf.5.html#transport_maps">transport_maps</a>,
+access tables </td> <td> <a href="postconf.5.html#default_database_type">default_database_type</a>=hash </td> <td>
+<a href="postconf.5.html#default_database_type">default_database_type</a>=lmdb or <a href="postconf.5.html#default_database_type">default_database_type</a>=cdb </td>
+</tr>
+
+<tr> <td> Dynamic caches maintained by <a href="postscreen.8.html">postscreen(8)</a>, <a href="verify.8.html">verify(8)</a>,
+<a href="tlsmgr.8.html">tlsmgr(8)</a> </td> <td> <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=btree </td> <td>
+<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=lmdb </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> The default values for <a href="postconf.5.html#default_database_type">default_database_type</a> and <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>
+may be specified at build time (see the <a href="#build-conf">section
+below</a>, and they may be changed later by editing main.cf, for
+example with the <a href="postconf.1.html">postconf(1)</a> command.) </p>
+
+<p> The sections that follow present three migration strategies
+with different levels of assistance by tooling that was developed
+for Postfix 3.11 and later. </p>
+
+<h2> <a name="build-conf"> Skip this if not building Postfix from
+source, or if your system still supports Berkeley DB. </a> </h2>
+
+<p> <a href="#level-overview">Click here to skip to the next section</a>.
+
+<p> On systems that have removed Berkeley DB support, run "<tt>make
+makefiles</tt>" with a CCARGS value that (also) contains "-DNO_DB",
+and specify appropriate values for <a href="postconf.5.html#default_database_type">default_database_type</a> (lmdb or cdb)
+and <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> (lmdb). </p>
+
+<p> In the examples below, the "<tt>...</tt>" are place holders any
+dependencies that you build Postfix with, such as CDB, LDAP, LMDB,
+MySQL/MariaDB, OpenSSL, SASL, and so on.
+
+<p> Example 1: use <a href="lmdb_table.5.html">lmdb</a>: for both <a href="postconf.5.html#default_database_type">default_database_type</a> (read-mostly
+lookup tables) and <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> (read-write caches). Terminal
+input is <b>bold</b>, output is <tt>normal</tt> font. </p>
+
+<blockquote> <pre>
+$ <b>make makefiles CCARGS="-DNO_DB ..." \
+    <a href="postconf.5.html#default_database_type">default_database_type</a>=lmdb \
+    <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=lmdb ... \
+    AUXLIBS...</b>
+</pre>
+</blockquote>
+
+<p> Example 2: alternative form that produces the same result.
+</p>
+
+<blockquote>
+<pre>
+$ <b>export CCARGS="-DNO_DB ..."</b>
+$ <b>export <a href="postconf.5.html#default_database_type">default_database_type</a>=lmdb</b>
+$ <b>export <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=lmdb</b>
+$ <b>export AUXLIBS...</b>
+...
+$ <b>make makefiles</b>
+</pre>
+</blockquote>
+
+<p> Another alternative is to use cdb for <a href="postconf.5.html#default_database_type">default_database_type</a>
+(read-mostly lookup tables) and lmdb for <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>
+(read-write caches). </p>
+
+<h2> <a name="level-overview"> Migration support level overview </a> </h2>
+
+<p> The goal of the migration is clear: stop using <a href="DATABASE_README.html#types">hash</a>: and <a href="DATABASE_README.html#types">btree</a>:,
+and use <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>: instead. If your configuration is simple or
+if you are familiar with Postfix configuration, a few "<tt>grep</tt>"
+commands will find all the problems, and a few edits will be easy
+to make. </p>
+
+<p> If, on the other hand, you are not familiar with the details of your
+Postfix configuration, then this document provides options where Postfix
+can help. </p>
+
+<p> Postfix 3.11 introduces multiple levels of migration support.
+You can use the command "<tt><a href="postfix-non-bdb.1.html">postfix non-bdb</a> status</tt>" to view
+the migration support level. This is what the default should look
+like (terminal input is <tt><b>bold</b></tt>, output is <tt>normal</tt>
+font): </p>
+
+<blockquote>
+<pre>
+# <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> status</b>
+disable
+</pre>
+</blockquote>
+
+<p> In increasing order, the support levels are: </p>
+
+<dl>
+
+<dt> <a href="#disable">disable</a> (manual migration) </dt>
+
+<dd> <p> You start up Postfix, watch the logging when Postfix
+programs fail to open a <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: table, edit Postfix
+configuration files to use <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>:, then run <a href="postmap.1.html">postmap(1)</a> or
+<a href="postalias.1.html">postalias(1)</a> commands to create <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>: indexed database
+files. Use this option if you are familiar with Postfix configuration.
+</p>
+
+<p> This will not fix the integration with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software that are broken
+when they want to use "<tt>postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i></tt>".
+Mailman uses this to maintain a table with mailing list contact
+addresses. For that, you need to use the next-up level. </p> </dd>
+
+<dt> <a href="#enable-redirect">enable-redirect</a> (database
+aliasing) </dt>
+
+<dd> <p> This level implicitly redirects a request to access
+<a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i> to $<a href="postconf.5.html#default_database_type">default_database_type</a>:<i>/path/to/file</i>,
+and redirects a request to access a <a href="DATABASE_README.html#types">btree</a>:<i>/path/to/file</i> to
+$<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>:<i>/path/to/file</i>.  </p>
+
+<p> This still requires manually running <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>
+commands, but "fixes" the integration with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software when they want
+to use "<tt>postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i>"</tt>, and Berkeley
+DB support is not available. Such commands will implicitly create
+a new <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>: indexed database file, depending on the
+<a href="postconf.5.html#default_database_type">default_database_type</a> value. </p> </dd>
+
+<dt> <a href="#enable-reindex"> enable-reindex </a> (aliasing, plus
+running <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>)</dt>
+
+<dd> <p> This level implements "<tt>enable-redirect</tt> (database
+aliasing)", and also runs the <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command to create
+a new lmdb or cdb indexed database file. This uses the <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>
+daemon. </p>
+
+</dl>
+
+<p> The levels <a href="#enable-redirect">enable-redirect</a> and
+<a href="#enable-reindex"> enable-reindex </a> leave some technical
+debt: configurations that still say <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: (even if
+they use <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>: behind the scene). </p>
+
+<ul>
+
+<li> <p> Using these levels gives you extra time to prepare for a
+long-term configuration change that replaces hard-coded instances of <a href="DATABASE_README.html#types">hash</a>:
+with the value of <a href="postconf.5.html#default_database_type">default_database_type</a>, and that replaces <a href="DATABASE_README.html#types">btree</a>: with
+the value of <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>. </p>
+
+<li> <p> Depending on your use of other software that wants to use
+<a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> commands, you may have to permanently
+the leave the <a href="#enable-redirect">enable-redirect</a> level
+active. </p>
+
+</ul>
+
+<p> After this overview, the sections that follow will go into more
+detail. </p>
+
+<h2> <a name="disable"> Level 'disable': manual migration </a> </h2>
+
+<p> To disable all non-Berkeley-DB migration features use
+the "<tt><a href="postfix-non-bdb.1.html">postfix non-bdb</a></tt>" command:
+
+<blockquote>
+<pre>
+# <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> disable</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> This will edit <a href="postconf.5.html">main.cf</a> to remove a <a href="postconf.5.html#non_bdb_migration_level">non_bdb_migration_level</a> setting
+and the level revert to its implicit default (disable), and will edit
+<a href="master.5.html">master.cf</a> to remove an entry for the <tt>reindex</tt> service. </p>
+
+<p> This setting will cause problems with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software that wants to use
+"<tt>postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i></tt>" (or similar postalias
+commands), and Berkeley DB support is no longer available. In that
+case, you will need the "<tt>enable-redirect</tt>" migration support
+level.
+
+<p> A manual migration process goes like this: </p>
+
+<ul>
+
+<li> <p> Stop Postfix. </p>
+
+<li> <p> Make <a href="lmdb_table.5.html">lmdb</a>: the default for both <a href="postconf.5.html#default_database_type">default_database_type</a>
+(read-mostly lookup tables) and <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> (read-write
+caches): </p>
+
+<pre>
+# <b>postconf <a href="postconf.5.html#default_database_type">default_database_type</a>=lmdb <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=lmdb</b>
+</pre>
+
+<li> <p> Alternatively, make <a href="CDB_README.html">cdb</a>: the default for <a href="postconf.5.html#default_database_type">default_database_type</a>
+(read-mostly lookup tables) and <a href="lmdb_table.5.html">lmdb</a>: the default for
+<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> (read-write caches): </p>
+
+<pre> 
+# <b>postconf <a href="postconf.5.html#default_database_type">default_database_type</a>=cdb <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>=lmdb</b>
+</pre>
+
+<li> <p> Look for <a href="DATABASE_README.html#types">hash</a>: and <a href="DATABASE_README.html#types">btree</a>: references in Postfix
+configuration files. Instead of <tt>/etc/postfix</tt> use the pathname
+in the output from "<tt>postconf -x <a href="postconf.5.html#config_directory">config_directory</a></tt>". </p>
+
+<pre>
+# <b>grep -E -r '(hash|btree):/' /etc/postfix</b>
+</pre>
+
+<li> <p> For each instance in the "<tt>grep</tt>" output : </p>
+
+<ul>
+
+<li> <p> Edit the configuration file and replace "hash" with "lmdb"
+or "cdb" (use the same value as the output from "<tt><b>postconf
+-hx <a href="postconf.5.html#default_database_type">default_database_type</a></b></tt>") and replace "btree" with "lmdb".
+</p>
+
+<li> <p> If this instance has no source file (only the ".db" file
+exists), proceed with the next instance of "<tt>grep</tt>" output.
+</p>
+
+<li> <p> If this instance appears in the output from "<tt><b>postconf
+-hPPx '*/*/alias_maps' | sort -u</b></tt>", run the <a href="postalias.1.html">postalias(1)</a>
+command.  If this instance is like "<tt><a href="lmdb_table.5.html">lmdb</a>:/path/to/source</tt>":
+</p>
+
+<pre>
+# <b>postalias <a href="lmdb_table.5.html">lmdb</a>:/path/to/source</b>
+</pre>
+
+<p> Instead of "<a href="lmdb_table.5.html">lmdb</a>:" use "<a href="CDB_README.html">cdb</a>:" if the instance is like
+"<tt><a href="CDB_README.html">cdb</a>:/path/to/source</tt>". </p>
+
+<li> <p> Otherwise, run the <a href="postmap.1.html">postmap(1)</a> command. If this instance
+is like "<tt><a href="lmdb_table.5.html">lmdb</a>:/path/to/source</tt>": </p>
+
+<pre>
+# <b>postmap <a href="lmdb_table.5.html">lmdb</a>:/path/to/source</b>
+</pre>
+
+<p> Instead of "<a href="lmdb_table.5.html">lmdb</a>:" use "<a href="CDB_README.html">cdb</a>:" if this instance is like
+"<tt><a href="CDB_README.html">cdb</a>:/path/to/source</tt>". </p>
+
+</ul>
+
+<li> <p> Start Postfix, watch the log for warnings about files that
+cannot be opened, find the configuration file that still uses "hash"
+or "btree", and repeat the steps above. </p>
+
+<li> <p> It is now safe to delete the unused ".db" files. </p>
+
+</ul>
+
+<h2> <a name="enable-redirect"> Level 'enable-redirect': database
+aliasing </a> </h2>
+
+<p> To enable this migration support level, use: </p>
+
+<blockquote>
+<pre>
+# <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> This <tt><a href="postfix-non-bdb.1.html">postfix non-bdb</a></tt>" command edits <a href="postconf.5.html">main.cf</a> to enable
+redirection (aliasing) from Berkeley DB types "hash" and "btree"
+to the non-Berkeley-DB types specified with $<a href="postconf.5.html#default_database_type">default_database_type</a>
+and $<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>. Custom redirection may be configured
+with <a href="postconf.5.html#non_bdb_custom_mapping">non_bdb_custom_mapping</a>. This command also edits <a href="master.5.html">master.cf</a> to
+remove an unused <tt>nbdb_reindex</tt> service entry. </p>
+
+<p> This migration support level will not automatically create
+non-Berkeley-DB indexed database files. Instead, Postfix programs
+will log an error as they fail to open an indexed database file,
+and will leave it to the system administrator to run <a href="postmap.1.html">postmap(1)</a> or
+<a href="postalias.1.html">postalias(1)</a> to create that file. </p>
+
+<p> For each instance of "<tt><a href="DATABASE_README.html#types">hash</a>:/path/to/source</tt>" or
+"<tt><a href="DATABASE_README.html#types">btree</a>:/path/to/source</tt>" that requires manually running
+<a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>: </p>
+
+<ul>
+
+<li> <p> If this instance appears in the output from "<tt><b>postconf
+-hPPx '*/*/alias_maps' | sort -u</b></tt>", run the <a href="postalias.1.html">postalias(1)</a>
+command.  If this instance is like "<tt><a href="lmdb_table.5.html">lmdb</a>:/path/to/source</tt>":
+</p>
+
+<pre>
+# <b>postalias <a href="lmdb_table.5.html">lmdb</a>:/path/to/source</b>
+</pre>
+
+<p> Instead of "<a href="lmdb_table.5.html">lmdb</a>:" use "<a href="CDB_README.html">cdb</a>:" if the instance is like
+"<tt><a href="CDB_README.html">cdb</a>:/path/to/source</tt>". </p>
+
+<li> <p> Otherwise, run the <a href="postmap.1.html">postmap(1)</a> command. If this instance
+is like "<tt><a href="lmdb_table.5.html">lmdb</a>:/path/to/source</tt>": </p>
+
+<pre>
+# <b>postmap <a href="lmdb_table.5.html">lmdb</a>:/path/to/source</b>
+</pre>
+
+<p> Instead of "<a href="lmdb_table.5.html">lmdb</a>:" use "<a href="CDB_README.html">cdb</a>:" if this instance is like
+"<tt><a href="CDB_README.html">cdb</a>:/path/to/source</tt>". </p>
+
+</ul>
+
+<p> This migration support level will fix problems with Mailman
+versions from before May 2025 and other software that wants to use
+"<tt>postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i></tt>". With database
+redirection, such commands will implicitly create an indexed file
+for $<a href="postconf.5.html#default_database_type">default_database_type</a>:<i>/path/to/file</i> (similar aliasing
+happens for postalias commands). </p>
+
+<p> The command "<tt><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect</tt>" will
+refuse to make any changes when <a href="postconf.5.html#default_database_type">default_database_type</a> or
+<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> specify a <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: type.
+
+<h2> <a name="enable-reindex"> Level 'enable-reindex': redirect and
+automatically generate non-Berkeley-DB indexed files </a> </h2>
+
+<p> <i> NOTE: this level should be used only temporarily to generate
+most of the non-Berkeley-DB indexed files that Postfix needs.
+Leaving this enabled may expose the system to privilege-escalation
+attacks.  There are no security concerns for using enable-redirect.
+</i> </p>
+
+<p> To enable this migration support level, use: </p>
+
+<blockquote>
+<pre>
+# <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-reindex</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p>This <a href="postfix-non-bdb.1.html">postfix non-bdb</a> command edits <a href="postconf.5.html">main.cf</a> to set the non-Berkeley-DB
+migration support level, and <a href="master.5.html">master.cf</a> to add or replace an
+<tt>nbdb-reindex</tt> service entry. </p>
+
+<p> The resulting configuration implements not only the functionality
+of <a href="#enable-redirect"> enable-redirect</a>, but also
+automatically creates a non-Berkeley-DB indexed database file when
+a daemon program wants to access a file that does not exist. This
+uses the <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> daemon to run <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>
+commands for databases that satisfy basic requirements to block
+privilege-escalation attacks. The number of requirements is large,
+but mainly, database files and their parent directory must not allow
+write access for group or other users, and their pathnames must
+match a list of trusted directory prefixes.  The complete list of
+requirements is documented in <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>.  <p>
+
+This command immediately generates non-Berkeley-DB indexed files
+for command-line programs that lack privileges to send requests to
+the <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> indexing server. This applies to "<a href="DATABASE_README.html#types">hash</a>:" and
+"<a href="DATABASE_README.html#types">btree</a>:" tables that are used by <a href="postqueue.1.html">postqueue(1)</a> and <a href="sendmail.1.html">sendmail(1)</a> as
+configured with <a href="postconf.5.html#authorized_flush_users">authorized_flush_users</a> and <a href="postconf.5.html#authorized_mailq_users">authorized_mailq_users</a>,
+and used by <a href="sendmail.1.html">sendmail(1)</a> and <a href="postdrop.1.html">postdrop(1)</a> as configured with
+<a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> and <a href="postconf.5.html#local_login_sender_maps">local_login_sender_maps</a>.  </p>
+
+<p> The command "<tt><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-reindex</tt>" will
+refuse to make any changes when <a href="postconf.5.html#default_database_type">default_database_type</a> or
+<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> specify a <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: type.
+
+<p> The <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> daemon will log when it successfully runs
+a <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command.  Examples, for a system with
+"<tt><a href="postconf.5.html#default_database_type">default_database_type</a> = lmdb</tt>": </p>
+
+<blockquote>
+<pre>
+successfully executed 'postmap <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport' as uid 0
+successfully executed 'postalias <a href="lmdb_table.5.html">lmdb</a>:/etc/aliases' as uid 0
+</pre>
+</blockquote>
+
+<p> See the section "<a href="addr-errors">Addressing errors
+with automatic indexed file generation</a>" for the most likely
+errors that Postfix programs may log. </p>
+
+<p> Once there are no more errors from Postfix programs for about
+24 hours, turn off automatic index generation by reducing the support
+level to <tt>enable-redirect</tt> with: </p>
+
+<blockquote>
+<pre>
+# <a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect
+# postfix reload
+</pre>
+</blockquote>
+
+<h2> <a name="addr-errors">Addressing errors with automatic
+indexed file generation </a> </h2>
+
+<h3> Unexpected pathname errors </h3>
+
+<p> Depending on the location of your Postfix lookup tables, Postfix
+programs may log a request to add a trusted directory to the
+directories listed with <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a> or
+<a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a>. </p>
+
+<p> Example, with line breaks added for readability: </p>
+
+<blockquote>
+<pre>
+could not execute command 'postmap <a href="lmdb_table.5.html">lmdb</a>:/path/to/file': table
+/path/to/file has an unexpected pathname;
+
+to allow automatic indexing as root, append its parent directory
+to the <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a> setting (current setting
+is: "/etc /usr/local/etc");
+
+alternatively, execute the failed command by hand
+</pre>
+</blockquote>
+
+<p> You have two options: </p>
+
+<ol>
+
+<li> <p> If you think that the suggested change is safe, update the
+setting as proposed and execute "<tt>postfix reload</tt>". </p>
+
+<li> <p> Alternatively, you can execute the failed <a href="postmap.1.html">postmap(1)</a> or
+<a href="postalias.1.html">postalias(1)</a> command by hand, and Postfix will not log the same error
+again. </p>
+
+</ol>
+
+<p> A similar request may be logged when a file needs to be indexed as
+a non-root user. </p>
+
+<h3> Unexpected file or directory owner or permissions </h3>
+
+<p> Other errors may be logged when a database file or directory
+has an unexpected owner, or when it is writable by group or by other
+users. </p>
+
+<p> Example with line breaks added for readability: </p>
+
+<blockquote>
+<pre>
+could not execute command 'postmap <a href="lmdb_table.5.html">lmdb</a>:/path/to/file': legacy
+indexed file '/path/to/file.db' is owned by uid '0', but parent
+directory '/path/to' is owned or writable by other user;
+
+to allow automatic indexing, correct the ownership or permissions;
+
+alternatively, execute the failed command by hand
+</pre>
+</blockquote>
+
+<p> Again, you have two options: </p>
+
+<ol>
+
+<li> <p> Fix the ownership or permission error. </p>
+
+<li> <p> Execute the failed <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command by
+hand, and Postfix will not log the same error again. </p>
+
+</ol>
+
+<p> Once there are no more errors from Postfix programs for about
+24 hours, turn off automatic index generation by reducing the
+support level to <tt>enable-redirect</tt> with: </p>
+
+<blockquote>
+<pre>
+# <a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect
+# postfix reload
+</pre>
+</blockquote>
+
+<h2> <a name="mailman">Appendix: Mailman integration </a> </h2>
+
+<p> This section has instructions to migrate an existing Mailman
+configuration that wants to use commands like "postmap
+<a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i>".  Mailman uses such commands to maintain
+tables with mailing list contact addresses and domain names. This
+will break on systems that no longer have Berkeley DB support. </p>
+
+<p> Solutions: </p>
+
+<ul>
+
+<li> <p> (Not recommended) Upgrade to a Mailman version that contains
+<a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c1321
+4f43c7d32d">gitlab commit 8fa56b72</a> (May 2025). Unfortunately,
+this has not yet been widely adopted by OS distributions. </p>
+
+<li> <p> Avoid Mailman changes, and use Postfix migration support
+described below. In a nutshell, the postmap command will execute
+the command "postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/file</i>" as if the command
+specifies <a href="lmdb_table.5.html">lmdb</a>:<i>/path/to/file</i> (or <a href="CDB_README.html">cdb</a>:, depending on Postfix
+configuration). </p>
+
+</ul>
+
+<p> With Mailman3 the integration with Postfix using LMTP may look
+like: </p>
+
+<blockquote>
+<pre>
+/var/lib/mailman3/data/postfix_domains      (domain names)
+/var/lib/mailman3/data/postfix_domains.db   (Berkeley DB hash file)
+/var/lib/mailman3/data/postfix_lmtp         (transport map)
+/var/lib/mailman3/data/postfix_lmtp.db      (Berkeley DB hash file)
+</pre>
+</blockquote>
+
+<blockquote> <i> Caution: the data directory may contain other files
+with names ending in "<tt>.db</tt>" that are not part of the
+Mailman-Postfix integration. Do not tamper with the other files. </i>
+</blockquote>
+
+<p> The relevant Postfix migration levels are: </p>
+
+<dl> <dt> <a href="#enable-redirect">enable-redirect</a> (redirect hash:
+to <a href="lmdb_table.5.html">lmdb</a>: or <a href="CDB_README.html">cdb</a>:) </dt>
+
+<dd> <p> Command: <tt> # <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect</b></tt> </p>
+
+<p> This will fix the problem that Mailman wants to use commands like
+"<tt>postmap <a href="DATABASE_README.html#types">hash</a>:<i>/path/to/</i>postfix_domains</tt>" and "<tt>postmap
+<a href="DATABASE_README.html#types">hash</a>:<i>/path/to</i>/postfix_lmtp</tt>". </p>
+
+<p> Instead of complaining about an unsupported database type, these
+postmap commands will implicitly create "<tt>.lmdb</tt>" indexed
+files like (<a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_domains or
+<a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_lmtp, or their <a href="CDB_README.html">cdb</a>: versions depending
+on the Postfix <a href="postconf.5.html#default_database_type">default_database_type</a> setting). </p>
+
+<p> This will not fix the problem that Postfix wants to
+use databases like <a href="DATABASE_README.html#types">hash</a>:<i>/path/to</i>/postfix_domains
+and <a href="DATABASE_README.html#types">hash</a>::<i>/path/to</i>/postfix_lmtp. With <a
+href="#enable-redirect">enable-redirect</a>, these will redirect to
+"<tt>.lmdb</tt>" indexed files (good) but those files do not yet exist
+(bad). You will need to create them by hand with commands like: </p>
+
+<pre>
+# <b>postmap <a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_domains</b>
+# <b>postmap <a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_lmtp</b>
+</pre>
+
+<p> After this, no further human action will be needed. When Mailman
+needs to update these files, it will invoke postmap commands that
+will work as promised above. Leave the Postfix migration level at <a
+href="#enable-reindex">enable-reindex</a> until you can upgrade to a
+newer Mailman version that supports Postfix with non-Berkeley
+databases. </p>
+
+</dd>
+
+<dt><a href="#enable-reindex">enable-reindex</a> (also automatically
+run postmap commands)</dt>
+
+<dd> <p> Command: <tt> # <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect</b></tt> </p>
+
+<p> In addition to "<a href="#enable-redirect">enable-redirect</a>",
+Postfix will also try to run commands like "<tt>postmap
+<a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_domains</tt>" and "<tt>postmap
+<a href="lmdb_table.5.html">lmdb</a>:<i>/path/to</i>/postfix_lmtp</tt>". There will be some delay
+depending on the amount of mailing list traffic; you may want to post
+a test message to make the postmap commands happen sooner. </p>
+
+<p> Postfix will log the postmap commands (or will log a request to make
+some configuration changes; see "<a href="addr-errors">Addressing errors
+with automatic indexed file generation</a>" above). </p>
+
+<p> <i>Note: once these "postmap" commands have completed,
+you should reduce the migration support level with the command
+"<b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> enable-redirect</b>".  For security reasons the <a
+href="#enable-reindex">enable-reindex</a> level should not be permanently
+enabled. </i> </p>
+
+</dl>
+
+</body>
+
+</html>
index c47672a50716d9bd106d38c5e7ad374a8f4e48e1..30dd58f11062c8c7aaaa7244e5848ffe666c9a63 100644 (file)
@@ -1377,7 +1377,8 @@ use a particular envelope sender address: </p>
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <strong><a href="postconf.5.html#smtpd_sender_login_maps">smtpd_sender_login_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/controlled_envelope_senders</strong>
+    <strong><a href="postconf.5.html#smtpd_sender_login_maps">smtpd_sender_login_maps</a> = 
+        <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/controlled_envelope_senders</strong>
 
     <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
         ...
@@ -1402,6 +1403,19 @@ names that own that address: </p>
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "<b>postmap
+/etc/postfix/controlled_envelope_senders</b>" after you change the
+controlled_envelope_senders file, to (re)build a default-type indexed
+file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/controlled_envelope_senders</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <p> With this, the <code><a href="postconf.5.html#reject_sender_login_mismatch">reject_sender_login_mismatch</a></code>
 restriction above will reject the sender address in the MAIL FROM
 command if <code><a href="postconf.5.html#smtpd_sender_login_maps">smtpd_sender_login_maps</a></code> does not specify
@@ -1430,7 +1444,7 @@ REJECT mail from accounts whose credentials have been compromised.
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> = 
         <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a> 
-        <a href="postconf.5.html#check_sasl_access">check_sasl_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sasl_access
+        <a href="postconf.5.html#check_sasl_access">check_sasl_access</a> <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sasl_access
         <a href="postconf.5.html#permit_sasl_authenticated">permit_sasl_authenticated</a>
         ...
 
@@ -1442,6 +1456,17 @@ REJECT mail from accounts whose credentials have been compromised.
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/sasl_access</b>"
+after you change the sasl_access file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_access</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <h4><a name="id397172">Default  authentication domain</a></h4>
 
 <p> Postfix can append a domain name (or any other string) to a
@@ -1675,7 +1700,7 @@ second part sets up the username/password information.  </p>
     <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]
     # Alternative form:
     # <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]:submission
-    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sasl_passwd
+    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sasl_passwd
 </pre>
 </blockquote>
 
@@ -1749,8 +1774,16 @@ and before entering an optional chroot jail. </p>
 
 <ul>
 
-<li> <p> Use the <code>postmap</code> command whenever you
-change the <code>/etc/postfix/sasl_passwd</code> file. </p> </li>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
+after changing the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p> </li>
 
 <li> <p> If you specify the "<code>[</code>" and "<code>]</code>"
 in the <code><a href="postconf.5.html#relayhost">relayhost</a></code> destination, then you must use the
@@ -1785,9 +1818,10 @@ resort.  </p>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> = yes
-    <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_relay
+    <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> = 
+        <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sender_relay
     <a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
-    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sasl_passwd
+    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sasl_passwd
     <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]
     # Alternative form:
     # <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]:submission
@@ -1818,19 +1852,25 @@ resort.  </p>
 
 <ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <li> <p> If you are creative, then you can try to combine the two
 tables into one single MySQL database, and configure different
 Postfix queries to extract the appropriate information. </p>
 
-<li> <p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
-
 <li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
-whenever you change the sasl_passwd table. </p>
+after you change the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <li> <p> Execute the command "<b>postmap /etc/postfix/sender_relay</b>"
-whenever you change the sender_relay table. </p>
+after you change the sender_relay file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sender_relay</b>"
+to specify an explicit type.</p>
 
 </ul>
 
index 02d09958098a632966fda911fb8c8fca57a1a3ec..a9fd89f86d50dcaed1aad54b1867b812f90259fc 100644 (file)
@@ -123,7 +123,7 @@ discussed in the first half of this document. </p>
 <blockquote>
 <pre>
 1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-2     <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/generic
+2     <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/generic
 3 
 4 /etc/postfix/generic:
 5     his@localdomain.local             hisaccount@hisisp.example
@@ -148,12 +148,16 @@ that the ISP supports "+" style address extensions). </p>
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/generic</b>"
-whenever you change the generic table. </p>
+whenever you change the generic file, to (re)build a default-type
+indexed file. Execute  "<b>postmap <i>type</i>:/etc/postfix/generic</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <h3>Solution 2: Postfix version 2.1 and earlier </h3>
 
@@ -174,9 +178,9 @@ discussed in the first half of this document. </p>
  2     <a href="postconf.5.html#myhostname">myhostname</a> = hostname.localdomain
  3     <a href="postconf.5.html#mydomain">mydomain</a> = localdomain
  4 
- 5     <a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/canonical
+ 5     <a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/canonical
  6 
- 7     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 7     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  8 
  9 /etc/postfix/canonical:
 10     your-login-name    your-account@your-isp.com
@@ -205,15 +209,21 @@ but is convenient.
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/canonical</b>"
-whenever you change the canonical table. </p>
+whenever you change the canonical file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/canonical</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
-whenever you change the virtual table. </p>
+whenever you change the virtual file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>"
+to specify an explicit type. </p>
 
 <h2><a name="client_sasl_enable">Enabling SASL authentication in the
 Postfix SMTP/LMTP client</a></h2>
@@ -254,7 +264,7 @@ second part sets up the username/password information.  </p>
     <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]
     # Alternative form:
     # <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]:submission
-    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sasl_passwd
+    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sasl_passwd
 </pre>
 </blockquote>
 
@@ -328,8 +338,16 @@ and before entering an optional chroot jail. </p>
 
 <ul>
 
-<li> <p> Use the <code>postmap</code> command whenever you
-change the <code>/etc/postfix/sasl_passwd</code> file. </p> </li>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
+after changing the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p> </li>
 
 <li> <p> If you specify the "<code>[</code>" and "<code>]</code>"
 in the <code><a href="postconf.5.html#relayhost">relayhost</a></code> destination, then you must use the
@@ -364,9 +382,10 @@ resort.  </p>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> = yes
-    <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_relay
+    <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> = 
+        <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sender_relay
     <a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
-    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sasl_passwd
+    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sasl_passwd
     <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]
     # Alternative form:
     # <a href="postconf.5.html#relayhost">relayhost</a> = [mail.isp.example]:submission
@@ -397,19 +416,25 @@ resort.  </p>
 
 <ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <li> <p> If you are creative, then you can try to combine the two
 tables into one single MySQL database, and configure different
 Postfix queries to extract the appropriate information. </p>
 
-<li> <p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
-
 <li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
-whenever you change the sasl_passwd table. </p>
+after you change the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <li> <p> Execute the command "<b>postmap /etc/postfix/sender_relay</b>"
-whenever you change the sender_relay table. </p>
+after you change the sender_relay file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sender_relay</b>"
+to specify an explicit type.</p>
 
 </ul>
 
index 59f996ab46aa2af81e595c4716e7ac4e38c5b191..811a43cd095813f2a442e1164feefe9b0467ea1f 100644 (file)
@@ -326,7 +326,7 @@ All the mail to these two accounts is forwarded to an inside address.
 <blockquote>
 <pre>
 1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-2     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+2     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
 3 
 4 /etc/postfix/virtual:
 5     postmaster      postmaster@example.com
@@ -369,8 +369,8 @@ is the real purpose of the firewall email function. </p>
  9b        <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a> <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>
 10b        ...spam blocking rules....
 <br>
-11     <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relay_recipients
-12     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
+11     <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relay_recipients
+12     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
 13 
 14 /etc/postfix/relay_recipients:
 15     user1@example.com   x
@@ -409,15 +409,27 @@ default "smtp" delivery transport. </p>
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
+whenever you change the virtual file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>"
-whenever you change the relay_recipients table. </p>
+whenever you change the relay_recipients file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/relay_recipients</b>" to specify an explicit
+type.</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the transport table. </p>
+whenever you change the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
 
 <p> In some installations, there may be separate instances of Postfix
 processing inbound and outbound mail on a multi-homed firewall. The
@@ -447,7 +459,7 @@ follows:  </p>
 <blockquote>
 <pre>
 1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-2     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+2     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
 3 
 4 /etc/postfix/virtual:
 5     root     root@localhost
@@ -466,8 +478,16 @@ matches $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or $<a hr
 
 </ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-editing the file. </p>
+editing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <h2><a name="intranet">Running Postfix behind a firewall</a></h2>
 
@@ -489,7 +509,7 @@ discussed in the first half of this document. </p>
 <blockquote>
 <pre>
  1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
- 2     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
+ 2     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
  3     <a href="postconf.5.html#relayhost">relayhost</a> =
  4     # Optional for a machine that isn't "always on"
  5     #<a href="postconf.5.html#fallback_relay">fallback_relay</a> = [gateway.example.com]
@@ -522,12 +542,17 @@ directly, and gives undeliverable mail to a gateway.  </p>
 
 </ul>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/transport</b>"
+whenever you edit the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
-<p> Execute the command "<b>postmap /etc/postfix/transport</b>" whenever
-you edit the transport table. </p>
 
 <h2><a name="backup">Configuring Postfix as primary or backup MX host for a remote site</a></h2>
 
@@ -561,7 +586,7 @@ is all you need: </p>
 11     # You must specify your NAT/proxy external address.
 12     #<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> = 1.2.3.4
 13 
-14     <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relay_recipients
+14     <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relay_recipients
 15 
 16 /etc/postfix/relay_recipients:
 17     user1@the.backed-up.domain.tld   x
@@ -576,7 +601,7 @@ need the above, plus: </p>
 <blockquote>
 <pre>
 20 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-21     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
+21     <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
 22 
 23 /etc/postfix/transport:
 24     the.backed-up.domain.tld       relay:[their.mail.host.tld]
@@ -613,12 +638,22 @@ relay_recipients table. </p>
 
 </ul>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>"
+whenever you change the relay_recipients file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/relay_recipients</b>" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the transport table. </p>
+whenever you change the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
 
 <p> NOTE for Postfix &lt; 2.2: Do not use the <a href="postconf.5.html#fallback_relay">fallback_relay</a> feature
 when relaying mail
@@ -760,7 +795,7 @@ discussed in the first half of this document. </p>
 <blockquote>
 <pre>
 1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-2     <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/generic
+2     <a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/generic
 3 
 4 /etc/postfix/generic:
 5     his@localdomain.local             hisaccount@hisisp.example
@@ -785,12 +820,16 @@ that the ISP supports "+" style address extensions). </p>
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/generic</b>"
-whenever you change the generic table. </p>
+whenever you change the generic file, to (re)build a default-type
+indexed file. Execute  "<b>postmap <i>type</i>:/etc/postfix/generic</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <h3>Solution 2: Postfix version 2.1 and earlier </h3>
 
@@ -811,9 +850,9 @@ discussed in the first half of this document. </p>
  2     <a href="postconf.5.html#myhostname">myhostname</a> = hostname.localdomain
  3     <a href="postconf.5.html#mydomain">mydomain</a> = localdomain
  4 
- 5     <a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/canonical
+ 5     <a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/canonical
  6 
- 7     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 7     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  8 
  9 /etc/postfix/canonical:
 10     your-login-name    your-account@your-isp.com
@@ -842,15 +881,21 @@ but is convenient.
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/canonical</b>"
-whenever you change the canonical table. </p>
+whenever you change the canonical file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/canonical</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
-whenever you change the virtual table. </p>
+whenever you change the virtual file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>"
+to specify an explicit type. </p>
 
 </body>
 
index 4e3c2d2165c6b793fb7390c126d67b7b09ef0aa7..729e93e51ef1b48b58c0e7f34e471e43f5455fce 100644 (file)
@@ -102,6 +102,13 @@ recipients.  The <a href="pipe.8.html">pipe(8)</a> delivery agent executes the <
 command without assistance from the shell, so there are no problems
 with shell meta characters in command-line parameters.  </p>
 
+<li> <p> Enable <b>transport</b> table lookups: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
+</pre>
+
 <li> <p> Specify that mail for <i>example.com</i>, should be
 delivered via UUCP, to a host named <i>uucp-host</i>: </p>
 
@@ -111,21 +118,19 @@ delivered via UUCP, to a host named <i>uucp-host</i>: </p>
     .example.com    uucp:uucp-host
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> See the <a href="transport.5.html">transport(5)</a> manual page for more details. </p>
 
 <li> <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the <b>transport</b> file. </p>
-
-<li> <p> Enable <b>transport</b> table lookups: </p>
-
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
-</pre>
+whenever you change the <b>transport</b> file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/transport</b>" to specify an explicit type.
+</p>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what map
-types Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <li> <p> Add <i>example.com</i> to the list of domains that your site
 is willing to relay mail for. </p>
index 900b07a37b7650703b6f123fc649201341394fd9..56360ae6945b9d788d786e93d177d1f6e57db3c3 100644 (file)
@@ -54,9 +54,7 @@ domains, non-UNIX accounts</a>
 
 <li> <a href="#forwarding">Mail forwarding domains</a>
 
-<li> <a href="#mailing_lists">Mailing lists</a>
-
-<li> <a href="#autoreplies">Autoreplies</a>
+<li> <a href="#mailing_lists">Hosted mailing list domains</a>
 
 </ul>
 
@@ -96,19 +94,31 @@ address class, as defined in the <a href="ADDRESS_CLASS_README.html">ADDRESS_CLA
 <h2><a name="local_vs_database">Local files versus network databases</a></h2>
 
 <p> The examples in this text use table lookups from local files
-such as DBM or Berkeley DB.  These are easy to debug with the
+such as <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. These are easy to debug with the
 <b>postmap</b> command: </p>
 
 <blockquote>
-Example: <tt>postmap -q info@example.com <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual</tt>
+Example: <tt>postmap -q info@example.com /etc/postfix/virtual</tt>
 </blockquote>
 
-<p> See the documentation in <a href="LDAP_README.html">LDAP_README</a>, <a href="MYSQL_README.html">MYSQL_README</a> and <a href="PGSQL_README.html">PGSQL_README</a>
-for how to replace local files by databases. The reader is strongly
-advised to make the system work with local files before migrating
-to network databases, and to use the <b>postmap</b> command to verify
-that network database lookups produce the exact same results as
-local file lookup. </p>
+<p> The above example assumes that the database is configured in
+<a href="postconf.5.html">main.cf</a> as $<a href="postconf.5.html#default_database_type">default_database_type</a>:/etc/postfix/virtual. Otherwise,
+use the command instead: </p>
+
+<blockquote>
+Example: <tt>postmap -q info@example.com
+<i>type</i>:/etc/postfix/virtual</tt>
+</blockquote>
+
+<p> and specify the explicit type that this table uses in <a href="postconf.5.html">main.cf</a>. </p>
+
+<p> You can replace local file lookups with networked (LDAP, SQL
+etc.) lookups. See the documentation in <a href="LDAP_README.html">LDAP_README</a>, <a href="MYSQL_README.html">MYSQL_README</a>,
+<a href="PGSQL_README.html">PGSQL_README</a>, etc., for examples.  The reader is strongly advised
+to make Postfix work with local files before migrating to network
+databases, and to use the <b>postmap</b> command to verify that
+network database lookups produce the exact same results as local
+file lookup. </p>
 
 <blockquote>
 Example: <tt>postmap -q info@example.com <a href="ldap_table.5.html">ldap</a>:/etc/postfix/virtual.cf</tt>
@@ -166,7 +176,7 @@ below shows how to use this mechanism for the example.com domain.
 <pre>
  1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
  2     <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a> = example.com ...other <a href="VIRTUAL_README.html#canonical">hosted domains</a>...
- 3     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 3     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  4 
  5 /etc/postfix/virtual:
  6     postmaster@example.com postmaster
@@ -209,8 +219,18 @@ for spam messages that were sent in the name of anything@example.com.
 
 </ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, and execute the command "<b>postfix
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p>Execute the command "<b>postfix
 reload</b>" after changing the <a href="postconf.5.html">main.cf</a> file. </p>
 
 <p> Note: virtual aliases can resolve to a local address or to a
@@ -259,11 +279,11 @@ section at the top of this document.</p>
  1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
  2     <a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> = example.com ...more domains...
  3     <a href="postconf.5.html#virtual_mailbox_base">virtual_mailbox_base</a> = /var/mail/vhosts
- 4     <a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/vmailbox
+ 4     <a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/vmailbox
  5     <a href="postconf.5.html#virtual_minimum_uid">virtual_minimum_uid</a> = 100
  6     <a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a> = <a href="DATABASE_README.html#types">static</a>:5000
  7     <a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a> = <a href="DATABASE_README.html#types">static</a>:5000
- 8     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 8     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  9 
 10 /etc/postfix/vmailbox:
 11     info@example.com    example.com/info
@@ -338,10 +358,24 @@ the wrong domain. </p>
 
 </ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
-after changing the vmailbox file, and execute the command "<b>postfix
-reload</b>" after changing the <a href="postconf.5.html">main.cf</a> file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute "<b>postmap /etc/postfix/vmailbox</b>" after changing
+the vmailbox file, to (re)build a default-type indexed file. Execute
+"<b>postmap <i>type</i>:/etc/postfix/vmailbox</b>" to specify an
+explicit type. </p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+<a href="postconf.5.html">main.cf</a> file. </p>
 
 <p> Note: mail delivery happens with the recipient's UID/GID
 privileges specified with <a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a> and <a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a>.
@@ -383,8 +417,8 @@ to a non-Postfix delivery agent: </p>
  1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
  2     <a href="postconf.5.html#virtual_transport">virtual_transport</a> = ...see below...
  3     <a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> = example.com ...more domains...
- 4     <a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/vmailbox
- 5     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 4     <a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/vmailbox
+ 5     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  6 
  7 /etc/postfix/vmailbox:
  8     info@example.com    whatever
@@ -473,10 +507,24 @@ the wrong domain. </p>
 
 </ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
-after changing the vmailbox file, and execute the command "<b>postfix
-reload</b>" after changing the <a href="postconf.5.html">main.cf</a> file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute the command "<b>postmap /etc/postfix/vmailbox</b>" after
+changing the vmailbox file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/vmailbox</b>" to
+specify an explicit type.</p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+<a href="postconf.5.html">main.cf</a> file. </p>
 
 <h2><a name="forwarding">Mail forwarding domains</a></h2>
 
@@ -489,7 +537,7 @@ as a mail forwarding domain: </p>
 <pre>
  1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
  2     <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a> = example.com ...other <a href="VIRTUAL_README.html#canonical">hosted domains</a>...
- 3     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+ 3     <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
  4 
  5 /etc/postfix/virtual:
  6     postmaster@example.com postmaster
@@ -533,17 +581,34 @@ for spam messages that were sent in the name of anything@example.com.
 
 </ul>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, and execute the command "<b>postfix
-reload</b>" after changing the <a href="postconf.5.html">main.cf</a> file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+<a href="postconf.5.html">main.cf</a> file. </p>
 
 <p> More details about the virtual alias file are given in the
 <a href="virtual.5.html">virtual(5)</a> manual page, including multiple addresses on the right-hand
 side. </p>
 
-<h2><a name="mailing_lists">Mailing lists</a></h2>
+<h2><a name="mailing_lists">Hosted mailing list domains</a></h2>
+
+<p> <i> Note: this section presents a historical approach to run a
+mailing list based on local <a href="aliases.5.html">aliases(5)</a>. This approach may still be
+useful for small mailing lists that are managed by hand or with the
+software like Majordomo. For a more contemporary and more scalable
+approach, see <a href="https://lists.org"> GNU Mailman</a>. </i>
+</p>
 
-<p> The examples that were given above already show how to direct
+<p>The examples that were given above already show how to direct
 mail for virtual postmaster addresses to a local postmaster. You
 can use the same method to direct mail for any address to a local
 or remote address. </p>
@@ -556,12 +621,14 @@ virtual addresses to the local delivery agent: </p>
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+    <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
+    <a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> = example.com
 
 /etc/postfix/virtual:
     listname-request@example.com listname-request
     listname@example.com         listname
     owner-listname@example.com   owner-listname
+    postmaster@example.com       postmaster
 
 /etc/aliases:
     listname: "|/some/where/majordomo/wrapper ..."
@@ -570,6 +637,17 @@ virtual addresses to the local delivery agent: </p>
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
 <p> This example assumes that in <a href="postconf.5.html">main.cf</a>, $<a href="postconf.5.html#myorigin">myorigin</a> is listed under
 the <a href="postconf.5.html#mydestination">mydestination</a> parameter setting.  If that is not the case,
 specify an explicit domain name on the right-hand side of the
@@ -587,63 +665,15 @@ bunch of virtual alias or virtual mailbox table entries. </p>
 
 <ul>
 
-<li> In case of a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, there would need to be one
-identity mapping from each mailing list address to itself.
+<li> In the case of a virtual alias DOMAIN, there would need to be
+an identity mapping from each mailing list address to an address in a
+different domain.
 
-<li> In case of a <a href="ADDRESS_CLASS_README.html#virtual_mailbox_class">virtual mailbox domain</a>, there would need to be
-a dummy mailbox for each mailing list address.
+<li> In the case of a virtual mailbox DOMAIN, there would need to
+be a dummy <a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> for each mailing list address.
 
 </ul>
 
-<h2><a name="autoreplies">Autoreplies</a></h2>
-
-<p> In order to set up an autoreply for virtual recipients while
-still delivering mail as normal, set up a rule in a virtual alias
-table: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
-
-/etc/postfix/virtual:
-    user@domain.tld user@domain.tld, user@domain.tld@autoreply.<a href="postconf.5.html#mydomain">mydomain</a>.tld
-</pre>
-</blockquote>
-
-<p> This delivers mail to the recipient, and sends a copy of the
-mail to the address that produces automatic replies. The address
-can be serviced on a different machine, or it can be serviced
-locally by setting up a transport map entry that pipes all mail
-for autoreply.<a href="postconf.5.html#mydomain">mydomain</a>.tld into some script that sends an automatic
-reply back to the sender. </p>
-
-<p> DO NOT list autoreply.<a href="postconf.5.html#mydomain">mydomain</a>.tld in <a href="postconf.5.html#mydestination">mydestination</a>! </p>
-
-<blockquote>
-<pre>
-/etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
-
-/etc/postfix/transport:
-    autoreply.<a href="postconf.5.html#mydomain">mydomain</a>.tld  autoreply:
-
-/etc/postfix/<a href="master.5.html">master.cf</a>:
-    # =============================================================
-    # service type  private unpriv  chroot  wakeup  maxproc command
-    #               (yes)   (yes)   (yes)   (never) (100)
-    # =============================================================
-    autoreply unix  -       n       n       -       -       pipe
-        flags= user=nobody argv=/path/to/autoreply $sender $mailbox
-</pre>
-</blockquote>
-
-<p> This invokes /path/to/autoreply with the sender address and
-the user@domain.tld recipient address on the command line. </p>
-
-<p> For more information, see the <a href="pipe.8.html">pipe(8)</a> manual page, and the
-comments in the Postfix <a href="master.5.html">master.cf</a> file. </p>
-
 </body>
 
 </html>
index a349c0e4baf1e8213098f838da1f3dc5ae496c9f..c8c58728bfcfe54a76e9fb6d3e262c769b8876ad 100644 (file)
@@ -25,44 +25,51 @@ ACCESS(5)                                                            ACCESS(5)
        email messages.
 
        Normally,  the  <a href="access.5.html"><b>access</b>(5)</a> table is specified as a text file that serves
-       as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file in <b>dbm</b>
-       or  <b>db</b>  format,  is used for fast searching by the mail system. Execute
-       the command "<b>postmap /etc/postfix/access</b>" to rebuild  an  indexed  file
-       after changing the corresponding text file.
+       as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file  for  fast
+       lookup.
+
+       Execute   the   command  "<b>postmap  /etc/postfix/access</b>"  to  rebuild  a
+       default-type indexed file after changing  the  text  file,  or  execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/access</b>" to specify an explicit type.
+
+       The  default  indexed  file  type  is configured with the <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a> parameter. Depending on the  platform  this  may  be  one  of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When  the  table  is provided via other means such as NIS, LDAP or SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively, the table can be provided as  a  regular-expression  map
-       where  patterns  are  given  as  regular expressions, or lookups can be
+       Alternatively,  the  table  can be provided as a regular-expression map
+       where patterns are given as regular  expressions,  or  lookups  can  be
        directed to a TCP-based server. In those cases, the lookups are done in
-       a  slightly  different way as described below under "REGULAR EXPRESSION
+       a slightly different way as described below under  "REGULAR  EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The search string is folded to lowercase before database lookup. As  of
-       Postfix  2.3,  the search string is not case folded with database types
-       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
+       The  search string is folded to lowercase before database lookup. As of
+       Postfix 2.3, the search string is not case folded with  database  types
+       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        The input format for the <a href="postmap.1.html"><b>postmap</b>(1)</a> command is as follows:
 
        <i>pattern action</i>
-              When  <i>pattern</i>  matches  a  mail address, domain or host address,
+              When <i>pattern</i> matches a mail address,  domain  or  host  address,
               perform the corresponding <i>action</i>.
 
        blank lines and comments
-              Empty lines and whitespace-only lines are ignored, as are  lines
+              Empty  lines and whitespace-only lines are ignored, as are lines
               whose first non-whitespace character is a `#'.
 
        multi-line text
-              A  logical  line  starts  with  non-whitespace text. A line that
+              A logical line starts with  non-whitespace  text.  A  line  that
               starts with whitespace continues a logical line.
 
 <b><a name="email_address_patterns_in_indexed_tables">EMAIL ADDRESS PATTERNS IN INDEXED TABLES</a></b>
-       With lookups from indexed files such as DB or DBM,  or  from  networked
-       tables  such  as  NIS,  LDAP or SQL, patterns are tried in the order as
+       With  lookups  from  indexed files such as DB or DBM, or from networked
+       tables such as NIS, LDAP or SQL, patterns are tried  in  the  order  as
        listed below:
 
        <i>user</i>@<i>domain</i>
@@ -71,13 +78,13 @@ ACCESS(5)                                                            ACCESS(5)
        <i>domain.tld</i>
               Matches <i>domain.tld</i> as the domain part of an email address.
 
-              The pattern <i>domain.tld</i> also matches subdomains,  but  only  when
-              the  string  <b>smtpd_access_maps</b>  is  listed  in  the Postfix <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
+              The  pattern  <i>domain.tld</i>  also matches subdomains, but only when
+              the string <b>smtpd_access_maps</b>  is  listed  in  the  Postfix  <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
               <b><a href="postconf.5.html#parent_domain_matches_subdomains">ent_domain_matches_subdomains</a></b> configuration setting.
 
        <i>.domain.tld</i>
-              Matches subdomains of  <i>domain.tld</i>,  but  only  when  the  string
-              <b>smtpd_access_maps</b>   is   not   listed   in   the   Postfix  <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
+              Matches  subdomains  of  <i>domain.tld</i>,  but  only  when the string
+              <b>smtpd_access_maps</b>  is   not   listed   in   the   Postfix   <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
               <b><a href="postconf.5.html#parent_domain_matches_subdomains">ent_domain_matches_subdomains</a></b> configuration setting.
 
        <i>user</i>@  Matches all mail addresses with the specified user part.
@@ -89,24 +96,24 @@ ACCESS(5)                                                            ACCESS(5)
 
 <b><a name="email_address_extension">EMAIL ADDRESS EXTENSION</a></b>
        When a mail address localpart contains the optional recipient delimiter
-       (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order  becomes:  <i>user+foo</i>@<i>domain</i>,
+       (e.g.,  <i>user+foo</i>@<i>domain</i>),  the  lookup  order becomes: <i>user+foo</i>@<i>domain</i>,
        <i>user</i>@<i>domain</i>, <i>domain</i>, <i>user+foo</i>@, and <i>user</i>@.
 
 <b>HOST NAME/ADDRESS PATTERNS IN INDEXED TABLES</b>
-       With  lookups  from  indexed files such as DB or DBM, or from networked
-       tables such as NIS, LDAP or SQL,  the  following  lookup  patterns  are
+       With lookups from indexed files such as DB or DBM,  or  from  networked
+       tables  such  as  NIS,  LDAP  or SQL, the following lookup patterns are
        examined in the order as listed:
 
        <i>domain.tld</i>
               Matches <i>domain.tld</i>.
 
-              The  pattern  <i>domain.tld</i>  also matches subdomains, but only when
-              the string <b>smtpd_access_maps</b>  is  listed  in  the  Postfix  <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
+              The pattern <i>domain.tld</i> also matches subdomains,  but  only  when
+              the  string  <b>smtpd_access_maps</b>  is  listed  in  the Postfix <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
               <b><a href="postconf.5.html#parent_domain_matches_subdomains">ent_domain_matches_subdomains</a></b> configuration setting.
 
        <i>.domain.tld</i>
-              Matches  subdomains  of  <i>domain.tld</i>,  but  only  when the string
-              <b>smtpd_access_maps</b>  is   not   listed   in   the   Postfix   <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
+              Matches subdomains of  <i>domain.tld</i>,  but  only  when  the  string
+              <b>smtpd_access_maps</b>   is   not   listed   in   the   Postfix  <b><a href="postconf.5.html#parent_domain_matches_subdomains">par</a>-</b>
               <b><a href="postconf.5.html#parent_domain_matches_subdomains">ent_domain_matches_subdomains</a></b> configuration setting.
 
        <i>net.work.addr.ess</i>
@@ -115,16 +122,16 @@ ACCESS(5)                                                            ACCESS(5)
 
        <i>net.work</i>
 
-       <i>net</i>    Matches  a  remote  IPv4  host address or network address range.
-              Specify one to four decimal octets  separated  by  ".".  Do  not
+       <i>net</i>    Matches a remote IPv4 host address  or  network  address  range.
+              Specify  one  to  four  decimal  octets separated by ".". Do not
               specify "[]" , "/", leading zeros, or hexadecimal forms.
 
-              Network  ranges  are  matched  by repeatedly truncating the last
-              ".octet" from a remote IPv4 host address string, until  a  match
+              Network ranges are matched by  repeatedly  truncating  the  last
+              ".octet"  from  a remote IPv4 host address string, until a match
               is found in the access table, or until further truncation is not
               possible.
 
-              NOTE: use the <b>cidr</b> lookup table type to specify  network/netmask
+              NOTE:  use the <b>cidr</b> lookup table type to specify network/netmask
               patterns. See <a href="cidr_table.5.html"><b>cidr_table</b>(5)</a> for details.
 
        <i>net:work:addr:ess</i>
@@ -133,18 +140,18 @@ ACCESS(5)                                                            ACCESS(5)
 
        <i>net:work</i>
 
-       <i>net</i>    Matches  a  remote  IPv6  host address or network address range.
+       <i>net</i>    Matches a remote IPv6 host address  or  network  address  range.
               Specify three to eight hexadecimal octet pairs separated by ":",
-              using  the  compressed  form  "::" for a sequence of zero-valued
-              octet pairs.  Do  not  specify  "[]",  "/",  leading  zeros,  or
+              using the compressed form "::" for  a  sequence  of  zero-valued
+              octet  pairs.  Do  not  specify  "[]",  "/",  leading  zeros, or
               non-compressed forms.
 
-              A  network  range  is  matched by repeatedly truncating the last
-              ":octetpair" from the compressed-form remote IPv6  host  address
-              string,  until  a  match  is found in the access table, or until
+              A network range is matched by  repeatedly  truncating  the  last
+              ":octetpair"  from  the compressed-form remote IPv6 host address
+              string, until a match is found in the  access  table,  or  until
               further truncation is not possible.
 
-              NOTE: use the <b>cidr</b> lookup table type to specify  network/netmask
+              NOTE:  use the <b>cidr</b> lookup table type to specify network/netmask
               patterns. See <a href="cidr_table.5.html"><b>cidr_table</b>(5)</a> for details.
 
               IPv6 support is available in Postfix 2.2 and later.
@@ -153,50 +160,50 @@ ACCESS(5)                                                            ACCESS(5)
        <b>OK</b>     Accept the address etc. that matches the pattern.
 
        <i>all-numerical</i>
-              An  all-numerical result is treated as OK. This format is gener-
+              An all-numerical result is treated as OK. This format is  gener-
               ated  by  address-based  relay  authorization  schemes  such  as
               pop-before-smtp.
 
        For other accept actions, see "OTHER ACTIONS" below.
 
 <b><a name="reject_actions">REJECT ACTIONS</a></b>
-       Postfix  version 2.3 and later support enhanced status codes as defined
-       in <a href="https://tools.ietf.org/html/rfc3463">RFC 3463</a>.  When no code is specified at the beginning  of  the  <i>text</i>
+       Postfix version 2.3 and later support enhanced status codes as  defined
+       in  <a href="https://tools.ietf.org/html/rfc3463">RFC  3463</a>.   When no code is specified at the beginning of the <i>text</i>
        below, Postfix inserts a default enhanced status code of "5.7.1" in the
-       case of reject actions, and "4.7.1" in the case of defer  actions.  See
+       case  of  reject actions, and "4.7.1" in the case of defer actions. See
        "ENHANCED STATUS CODES" below.
 
        <b>4</b><i>NN text</i>
 
        <b>5</b><i>NN text</i>
-              Reject  the  address  etc. that matches the pattern, and respond
-              with the numerical three-digit code and  text.  <b>4</b><i>NN</i>  means  "try
+              Reject the address etc. that matches the  pattern,  and  respond
+              with  the  numerical  three-digit  code and text. <b>4</b><i>NN</i> means "try
               again later", while <b>5</b><i>NN</i> means "do not try again".
 
-              The  following  responses  have  special meaning for the Postfix
+              The following responses have special  meaning  for  the  Postfix
               SMTP server:
 
               <b>421</b> <i>text</i> (Postfix 2.3 and later)
 
               <b>521</b> <i>text</i> (Postfix 2.6 and later)
-                     After responding with the numerical three-digit code  and
-                     text,  disconnect immediately from the SMTP client.  This
-                     frees up SMTP server resources so that they can  be  made
+                     After  responding with the numerical three-digit code and
+                     text, disconnect immediately from the SMTP client.   This
+                     frees  up  SMTP server resources so that they can be made
                      available to another SMTP client.
 
                      Note: The "521" response should be used only with botnets
-                     and other malware where interoperability is  of  no  con-
-                     cern.   The  "send  521  and  disconnect" behavior is NOT
+                     and  other  malware  where interoperability is of no con-
+                     cern.  The "send 521  and  disconnect"  behavior  is  NOT
                      defined in the SMTP standard.
 
        <b>REJECT</b> <i>optional text...</i>
-              Reject the address etc. that matches  the  pattern.  Reply  with
-              "<b>$<a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a></b>  <i>optional  text...</i>"  when  the optional
+              Reject  the  address  etc.  that matches the pattern. Reply with
+              "<b>$<a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a></b> <i>optional  text...</i>"  when  the  optional
               text is specified, otherwise reply with a generic error response
               message.
 
        <b>DEFER</b> <i>optional text...</i>
-              Reject  the  address  etc.  that matches the pattern. Reply with
+              Reject the address etc. that matches  the  pattern.  Reply  with
               "<b>$<a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a></b> <i>optional text...</i>" when the optional text
               is specified, otherwise reply with a generic error response mes-
               sage.
@@ -204,9 +211,9 @@ ACCESS(5)                                                            ACCESS(5)
               This feature is available in Postfix 2.6 and later.
 
        <b>DEFER_IF_REJECT</b> <i>optional text...</i>
-              Defer the request if some later restriction would  result  in  a
+              Defer  the  request  if some later restriction would result in a
               REJECT action. Reply with "<b>$<a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a> 4.7.1</b> <i>optional</i>
-              <i>text...</i>" when the optional text is  specified,  otherwise  reply
+              <i>text...</i>"  when  the  optional text is specified, otherwise reply
               with a generic error response message.
 
               Prior to Postfix 2.6, the SMTP reply code is 450.
@@ -214,9 +221,9 @@ ACCESS(5)                                                            ACCESS(5)
               This feature is available in Postfix 2.1 and later.
 
        <b>DEFER_IF_PERMIT</b> <i>optional text...</i>
-              Defer  the  request if some later restriction would result in an
-              explicit   or    implicit    PERMIT    action.     Reply    with
-              "<b>$<a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a>   4.7.1</b>    <i>optional  text...</i>"  when  the
+              Defer the request if some later restriction would result  in  an
+              explicit    or    implicit    PERMIT    action.     Reply   with
+              "<b>$<a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a>  4.7.1</b>   <i>optional  text...</i>"   when   the
               optional text is specified, otherwise reply with a generic error
               response message.
 
@@ -228,13 +235,13 @@ ACCESS(5)                                                            ACCESS(5)
 
 <b><a name="other_actions">OTHER ACTIONS</a></b>
        <i>restriction...</i>
-              Apply    the   named   UCE   restriction(s)   (<b>permit</b>,   <b>reject</b>,
+              Apply   the   named   UCE   restriction(s)   (<b>permit</b>,    <b>reject</b>,
               <b><a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a></b>, and so on).
 
        <b>BCC</b> <i>user@domain</i>
               Send one copy of the message to the specified recipient.
 
-              If multiple BCC actions are specified within the same SMTP  MAIL
+              If  multiple BCC actions are specified within the same SMTP MAIL
               transaction, with Postfix 3.0 only the last action will be used.
 
               This feature is available in Postfix 3.0 and later.
@@ -243,162 +250,162 @@ ACCESS(5)                                                            ACCESS(5)
               Claim successful delivery and silently discard the message.  Log
               the optional text if specified, otherwise log a generic message.
 
-              Note: this action currently affects all recipients of  the  mes-
-              sage.   To  discard  only  one  recipient without discarding the
+              Note:  this  action currently affects all recipients of the mes-
+              sage.  To discard only  one  recipient  without  discarding  the
               entire message, use the <a href="transport.5.html">transport(5)</a> table to direct mail to the
               <a href="discard.8.html">discard(8)</a> service.
 
               This feature is available in Postfix 2.0 and later.
 
        <b>DUNNO</b>  Pretend that the lookup key was not found. This prevents Postfix
-              from trying substrings of the lookup key (such  as  a  subdomain
+              from  trying  substrings  of the lookup key (such as a subdomain
               name, or a network address subnetwork).
 
               This feature is available in Postfix 2.0 and later.
 
        <b>FILTER</b> <i>transport:destination</i>
               After the message is queued, send the entire message through the
-              specified external content filter. The <i>transport</i> name  specifies
-              the  first  field  of  a  mail delivery agent definition in <a href="master.5.html">mas-
-              ter.cf</a>; the syntax of the next-hop <i>destination</i> is  described  in
-              the  manual  page  of  the  corresponding  delivery agent.  More
-              information about external content filters  is  in  the  Postfix
+              specified  external content filter. The <i>transport</i> name specifies
+              the first field of a mail  delivery  agent  definition  in  <a href="master.5.html">mas-
+              ter.cf</a>;  the  syntax of the next-hop <i>destination</i> is described in
+              the manual page  of  the  corresponding  delivery  agent.   More
+              information  about  external  content  filters is in the Postfix
               <a href="FILTER_README.html">FILTER_README</a> file.
 
-              Note  1: do not use $<i>number</i> regular expression substitutions for
-              <i>transport</i> or <i>destination</i> unless you know  that  the  information
+              Note 1: do not use $<i>number</i> regular expression substitutions  for
+              <i>transport</i>  or  <i>destination</i>  unless you know that the information
               has a trusted origin.
 
-              Note  2:  this  action overrides the <a href="postconf.5.html">main.cf</a> <b><a href="postconf.5.html#content_filter">content_filter</a></b> set-
-              ting, and affects all recipients of the  message.  In  the  case
-              that  multiple  <b>FILTER</b>  actions  fire, only the last one is exe-
+              Note 2: this action overrides the  <a href="postconf.5.html">main.cf</a>  <b><a href="postconf.5.html#content_filter">content_filter</a></b>  set-
+              ting,  and  affects  all  recipients of the message. In the case
+              that multiple <b>FILTER</b> actions fire, only the  last  one  is  exe-
               cuted.
 
               Note 3: the purpose of the FILTER command is to override message
-              routing.   To  override  the  recipient's  <i>transport</i> but not the
+              routing.  To override the  recipient's  <i>transport</i>  but  not  the
               next-hop <i>destination</i>, specify an empty filter <i>destination</i> (Post-
-              fix  2.7  and  later),  or  specify a <i>transport:destination</i> that
-              delivers through a different Postfix instance (Postfix  2.6  and
+              fix 2.7 and later),  or  specify  a  <i>transport:destination</i>  that
+              delivers  through  a different Postfix instance (Postfix 2.6 and
               earlier). Other options are using the recipient-dependent <b><a href="postconf.5.html#transport_maps">trans</a>-</b>
-              <b><a href="postconf.5.html#transport_maps">port_maps</a></b>  or  the  sender-dependent   <b><a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default-</b>
+              <b><a href="postconf.5.html#transport_maps">port_maps</a></b>   or  the  sender-dependent  <b><a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default-</b>
               <b>_transport_maps</a></b> features.
 
               This feature is available in Postfix 2.0 and later.
 
        <b>HOLD</b> <i>optional text...</i>
-              Place  the  message  on  the <b>hold</b> queue, where it will sit until
-              someone either deletes it or releases it for delivery.  Log  the
+              Place the message on the <b>hold</b> queue, where  it  will  sit  until
+              someone  either deletes it or releases it for delivery.  Log the
               optional text if specified, otherwise log a generic message.
 
-              Mail  that is placed on hold can be examined with the <a href="postcat.1.html"><b>postcat</b>(1)</a>
-              command, and can be destroyed or released with the  <a href="postsuper.1.html"><b>postsuper</b>(1)</a>
+              Mail that is placed on hold can be examined with the  <a href="postcat.1.html"><b>postcat</b>(1)</a>
+              command,  and can be destroyed or released with the <a href="postsuper.1.html"><b>postsuper</b>(1)</a>
               command.
 
-              Note:  use  "<b>postsuper -r</b>" to release mail that was kept on hold
-              for  a  significant  fraction  of   <b>$<a href="postconf.5.html#maximal_queue_lifetime">maximal_queue_lifetime</a></b>   or
-              <b>$<a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b>,  or  longer. Use "<b>postsuper -H</b>" only for
+              Note: use "<b>postsuper -r</b>" to release mail that was kept  on  hold
+              for   a   significant  fraction  of  <b>$<a href="postconf.5.html#maximal_queue_lifetime">maximal_queue_lifetime</a></b>  or
+              <b>$<a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b>, or longer. Use "<b>postsuper -H</b>"  only  for
               mail that will not expire within a few delivery attempts.
 
-              Note: this action currently affects all recipients of  the  mes-
+              Note:  this  action currently affects all recipients of the mes-
               sage.
 
               This feature is available in Postfix 2.0 and later.
 
        <b>PREPEND</b> <i>headername: headervalue</i>
-              Prepend  the specified message header to the message.  When more
-              than one PREPEND action executes,  the  first  prepended  header
+              Prepend the specified message header to the message.  When  more
+              than  one  PREPEND  action  executes, the first prepended header
               appears before the second etc. prepended header.
 
-              Note:  this  action  must  execute before the message content is
-              received;   it   cannot    execute    in    the    context    of
+              Note: this action must execute before  the  message  content  is
+              received;    it    cannot    execute    in    the   context   of
               <b><a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a></b>.
 
               This feature is available in Postfix 2.1 and later.
 
        <b>REDIRECT</b> <i>user@domain</i>
-              After  the  message is queued, send the message to the specified
+              After the message is queued, send the message to  the  specified
               address instead of the intended recipient(s).  When multiple <b>RE-</b>
               <b>DIRECT</b> actions fire, only the last one takes effect.
 
-              Note  1:  this action overrides the FILTER action, and currently
+              Note 1: this action overrides the FILTER action,  and  currently
               overrides all recipients of the message.
 
-              Note 2: a REDIRECT address is subject to  canonicalization  (add
-              missing  domain)  but NOT subject to canonical, masquerade, bcc,
+              Note  2:  a REDIRECT address is subject to canonicalization (add
+              missing domain) but NOT subject to canonical,  masquerade,  bcc,
               or virtual alias mapping.
 
               This feature is available in Postfix 2.1 and later.
 
        <b>INFO</b> <i>optional text...</i>
-              Log an informational record with  the  optional  text,  together
-              with  client  information  and  if available, with helo, sender,
+              Log  an  informational  record  with the optional text, together
+              with client information and if  available,  with  helo,  sender,
               recipient and protocol information.
 
               This feature is available in Postfix 3.0 and later.
 
        <b>WARN</b> <i>optional text...</i>
-              Log a warning with  the  optional  text,  together  with  client
-              information  and  if available, with helo, sender, recipient and
+              Log  a  warning  with  the  optional  text, together with client
+              information and if available, with helo, sender,  recipient  and
               protocol information.
 
               This feature is available in Postfix 2.1 and later.
 
 <b><a name="enhanced_status_codes">ENHANCED STATUS CODES</a></b>
-       Postfix version 2.3 and later support enhanced status codes as  defined
-       in  <a href="https://tools.ietf.org/html/rfc3463">RFC  3463</a>.   When an enhanced status code is specified in an access
+       Postfix  version 2.3 and later support enhanced status codes as defined
+       in <a href="https://tools.ietf.org/html/rfc3463">RFC 3463</a>.  When an enhanced status code is specified  in  an  access
        table, it is subject to modification. The following transformations are
-       needed  when the same access table is used for client, helo, sender, or
-       recipient access restrictions; they happen regardless of whether  Post-
+       needed when the same access table is used for client, helo, sender,  or
+       recipient  access restrictions; they happen regardless of whether Post-
        fix replies to a MAIL FROM, RCPT TO or other SMTP command.
 
-       <b>o</b>      When  a sender address matches a REJECT action, the Postfix SMTP
+       <b>o</b>      When a sender address matches a REJECT action, the Postfix  SMTP
               server will transform a recipient DSN status (e.g., 4.1.1-4.1.6)
               into the corresponding sender DSN status, and vice versa.
 
-       <b>o</b>      When  non-address  information  matches a REJECT action (such as
-              the HELO command argument or the client  hostname/address),  the
-              Postfix  SMTP  server  will  transform a sender or recipient DSN
+       <b>o</b>      When non-address information matches a REJECT  action  (such  as
+              the  HELO  command argument or the client hostname/address), the
+              Postfix SMTP server will transform a  sender  or  recipient  DSN
               status into a generic non-address DSN status (e.g., 4.0.0).
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This section describes how the table lookups change when the  table  is
-       given  in the form of regular expressions. For a description of regular
+       This  section  describes how the table lookups change when the table is
+       given in the form of regular expressions. For a description of  regular
        expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to  the  entire
+       Each  pattern  is  a  regular  expression that is applied to the entire
        string being looked up. Depending on the application, that string is an
-       entire client hostname, an entire client IP address, or an entire  mail
-       address.  Thus,  no  parent  domain  or  parent network search is done,
-       <i>user@domain</i> mail addresses are not  broken  up  into  their  <i>user@</i>  and
-       <i>domain</i>  constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
+       entire  client hostname, an entire client IP address, or an entire mail
+       address. Thus, no parent domain  or  parent  network  search  is  done,
+       <i>user@domain</i>  mail  addresses  are  not  broken  up into their <i>user@</i> and
+       <i>domain</i> constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and  <i>foo</i>.
 
-       Patterns are applied in the order as specified in the  table,  until  a
+       Patterns  are  applied  in the order as specified in the table, until a
        pattern is found that matches the search string.
 
-       Actions  are the same as with indexed file lookups, with the additional
-       feature that parenthesized substrings from the pattern can be  interpo-
+       Actions are the same as with indexed file lookups, with the  additional
+       feature  that parenthesized substrings from the pattern can be interpo-
        lated as <b>$1</b>, <b>$2</b> and so on.
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This  section  describes  how the table lookups change when lookups are
-       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
-       client/server  lookup  protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature is not
+       This section describes how the table lookups change  when  lookups  are
+       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
+       client/server lookup protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature  is  not
        available up to and including Postfix version 2.4.
 
-       Each lookup operation uses the entire query string once.  Depending  on
-       the  application,  that  string is an entire client hostname, an entire
-       client IP address, or an entire mail address.  Thus, no  parent  domain
-       or  parent  network  search is done, <i>user@domain</i> mail addresses are not
-       broken up into  their  <i>user@</i>  and  <i>domain</i>  constituent  parts,  nor  is
+       Each  lookup operation uses the entire query string once.  Depending on
+       the application, that string is an entire client  hostname,  an  entire
+       client  IP  address, or an entire mail address.  Thus, no parent domain
+       or parent network search is done, <i>user@domain</i> mail  addresses  are  not
+       broken  up  into  their  <i>user@</i>  and  <i>domain</i>  constituent  parts, nor is
        <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Actions are the same as with indexed file lookups.
 
 <b><a name="example">EXAMPLE</a></b>
-       The  following example uses an indexed file, so that the order of table
-       entries does not matter. The example permits access by  the  client  at
+       The following example uses an indexed file, so that the order of  table
+       entries  does  not  matter. The example permits access by the client at
        address 1.2.3.4 but rejects all other clients in 1.2.3.0/24. Instead of
-       <b>hash</b> lookup tables, some systems use <b>dbm</b>.  Use  the  command  "<b>postconf</b>
+       <b>hash</b>  lookup  tables,  some systems use <b>dbm</b>.  Use the command "<b>postconf</b>
        <b>-m</b>" to find out what lookup tables Postfix supports on your system.
 
        /etc/postfix/<a href="postconf.5.html">main.cf</a>:
@@ -409,7 +416,7 @@ ACCESS(5)                                                            ACCESS(5)
            1.2.3   REJECT
            1.2.3.4 OK
 
-       Execute  the  command  "<b>postmap  /etc/postfix/access</b>" after editing the
+       Execute the command "<b>postmap  /etc/postfix/access</b>"  after  editing  the
        file.
 
 <b><a name="bugs">BUGS</a></b>
index 181dc9e3b200a51b568b9998024098e018f17968..f80933190feb4012cf8cbc72f532f16aa524206e 100644 (file)
@@ -27,21 +27,30 @@ ALIASES(5)                                                          ALIASES(5)
        full email address (including domain).
 
        Normally,  the <a href="aliases.5.html"><b>aliases</b>(5)</a> table is specified as a text file that serves
-       as input to the <a href="postalias.1.html"><b>postalias</b>(1)</a> command. The result, an  indexed  file  in
-       <b>dbm</b>  or  <b>db</b> format, is used for fast lookup by the mail system. Execute
-       the command <b>newaliases</b> in order  to  rebuild  the  indexed  file  after
-       changing the Postfix alias database.
+       as input to the <a href="postalias.1.html"><b>postalias</b>(1)</a> command to create an indexed file for fast
+       lookup.  The  location of this file is system-dependent. This text will
+       use <b>/path/to/aliases</b>.
+
+       Execute the command "<b>newaliases</b>  to  rebuild  the  indexed  file  after
+       changing the text file. Execute "<b>postalias -q</b> <i>name</i> <b>/path/to/aliases</b>" to
+       query a default-type  indexed  file,  or  execute  "<b>postalias  -q</b>  <i>name</i>
+       <i>type</i><b>:/path/to/aliases</b>" to specify an explicit type.
+
+       The  default  indexed  file  type  is configured with the <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a> parameter. Depending on the  platform  this  may  be  one  of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When  the  table  is provided via other means such as NIS, LDAP or SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively, the table can be provided as  a  regular-expression  map
-       where  patterns  are  given  as  regular expressions. In this case, the
-       lookups are done in a slightly different way as described  below  under
+       Alternatively,  the  table  can be provided as a regular-expression map
+       where patterns are given as regular  expressions.  In  this  case,  the
+       lookups  are  done in a slightly different way as described below under
        "REGULAR EXPRESSION TABLES".
 
-       Users  can  control  delivery  of their own mail by setting up <b>.forward</b>
-       files in their home directory.  Lines in per-user <b>.forward</b>  files  have
+       Users can control delivery of their own mail  by  setting  up  <b>.forward</b>
+       files  in  their home directory.  Lines in per-user <b>.forward</b> files have
        the same syntax as the right-hand side of <a href="aliases.5.html"><b>aliases</b>(5)</a> entries.
 
        The format of the alias database input file is as follows:
@@ -50,67 +59,67 @@ ALIASES(5)                                                          ALIASES(5)
 
                    <i>name</i>: <i>value1</i>, <i>value2</i>, <i>...</i>
 
-       <b>o</b>      Empty  lines and whitespace-only lines are ignored, as are lines
+       <b>o</b>      Empty lines and whitespace-only lines are ignored, as are  lines
               whose first non-whitespace character is a `#'.
 
-       <b>o</b>      A logical line starts with  non-whitespace  text.  A  line  that
+       <b>o</b>      A  logical  line  starts  with  non-whitespace text. A line that
               starts with whitespace continues a logical line.
 
-       The  <i>name</i>  is a local address (no domain part).  Use double quotes when
-       the name contains any special characters such as whitespace, `#',  `:',
-       or  `@'.  The  <i>name</i>  is  folded to lowercase, in order to make database
+       The <i>name</i> is a local address (no domain part).  Use double  quotes  when
+       the  name contains any special characters such as whitespace, `#', `:',
+       or `@'. The <i>name</i> is folded to lowercase,  in  order  to  make  database
        lookups case insensitive.
 
-       In addition, when an alias exists for <b>owner-</b><i>name</i>,  this  will  override
-       the  envelope sender address, so that delivery diagnostics are directed
-       to <b>owner-</b><i>name</i>, instead of the originator of the message  (for  details,
-       see  <b><a href="postconf.5.html#owner_request_special">owner_request_special</a></b>,  <b><a href="postconf.5.html#expand_owner_alias">expand_owner_alias</a></b> and <b><a href="postconf.5.html#reset_owner_alias">reset_owner_alias</a></b>).
+       In  addition,  when  an alias exists for <b>owner-</b><i>name</i>, this will override
+       the envelope sender address, so that delivery diagnostics are  directed
+       to  <b>owner-</b><i>name</i>,  instead of the originator of the message (for details,
+       see <b><a href="postconf.5.html#owner_request_special">owner_request_special</a></b>, <b><a href="postconf.5.html#expand_owner_alias">expand_owner_alias</a></b>  and  <b><a href="postconf.5.html#reset_owner_alias">reset_owner_alias</a></b>).
        This is typically used to direct delivery errors to the maintainer of a
-       mailing  list,  who  is  in a better position to deal with mailing list
+       mailing list, who is in a better position to  deal  with  mailing  list
        delivery problems than the originator of the undelivered mail.
 
        The <i>value</i> contains one or more of the following:
 
        <i>address</i>
-              Mail is forwarded to <i>address</i>, which is compatible with  the  <a href="https://tools.ietf.org/html/rfc822">RFC</a>
+              Mail  is  forwarded to <i>address</i>, which is compatible with the <a href="https://tools.ietf.org/html/rfc822">RFC</a>
               <a href="https://tools.ietf.org/html/rfc822">822</a> standard.
 
        <i>/file/name</i>
-              Mail  is  appended  to  <i>/file/name</i>. For details on how a file is
-              written see the sections "EXTERNAL FILE DELIVERY" and  "DELIVERY
-              RIGHTS"  in the <a href="local.8.html"><b>local</b>(8)</a> documentation.  Delivery is not limited
-              to regular files.  For example, to  dispose  of  unwanted  mail,
+              Mail is appended to <i>/file/name</i>. For details on  how  a  file  is
+              written  see the sections "EXTERNAL FILE DELIVERY" and "DELIVERY
+              RIGHTS" in the <a href="local.8.html"><b>local</b>(8)</a> documentation.  Delivery is not  limited
+              to  regular  files.   For  example, to dispose of unwanted mail,
               deflect it to <b>/dev/null</b>.
 
        |<i>command</i>
-              Mail  is piped into <i>command</i>. Commands that contain special char-
-              acters, such as whitespace, should be  enclosed  between  double
-              quotes.  For  details on how a command is executed see "EXTERNAL
+              Mail is piped into <i>command</i>. Commands that contain special  char-
+              acters,  such  as  whitespace, should be enclosed between double
+              quotes. For details on how a command is executed  see  "EXTERNAL
               COMMAND DELIVERY" and "DELIVERY RIGHTS" in the <a href="local.8.html"><b>local</b>(8)</a> documen-
               tation.
 
-              When  the  command  fails, a limited amount of command output is
-              mailed back to the  sender.   The  file  <b>/usr/include/sysexits.h</b>
-              defines  the expected exit status codes. For example, use <b>"|exit</b>
-              <b>67"</b> to simulate a "user unknown" error, and <b>"|exit 0"</b> to  imple-
+              When the command fails, a limited amount of  command  output  is
+              mailed  back  to  the  sender.  The file <b>/usr/include/sysexits.h</b>
+              defines the expected exit status codes. For example, use  <b>"|exit</b>
+              <b>67"</b>  to simulate a "user unknown" error, and <b>"|exit 0"</b> to imple-
               ment an expensive black hole.
 
        <b>:include:</b><i>/file/name</i>
-              Mail  is  sent  to  the  destinations  listed in the named file.
-              Lines in <b>:include:</b> files have the same syntax as the  right-hand
+              Mail is sent to the  destinations  listed  in  the  named  file.
+              Lines  in <b>:include:</b> files have the same syntax as the right-hand
               side of <a href="aliases.5.html"><b>aliases</b>(5)</a> entries.
 
-              A  destination  can be any destination that is described in this
-              manual page. However, delivery to "|<i>command</i>" and  <i>/file/name</i>  is
-              disallowed  by  default.  To enable, edit the <b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_com</a>-</b>
+              A destination can be any destination that is described  in  this
+              manual  page.  However, delivery to "|<i>command</i>" and <i>/file/name</i> is
+              disallowed by default. To enable,  edit  the  <b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_com</a>-</b>
               <b><a href="postconf.5.html#allow_mail_to_commands">mands</a></b> and <b><a href="postconf.5.html#allow_mail_to_files">allow_mail_to_files</a></b> configuration parameters.
 
 <b><a name="address_extension">ADDRESS EXTENSION</a></b>
-       When alias database search fails, and the recipient localpart  contains
-       the  optional  recipient  delimiter  (e.g.,  <i>user+foo</i>),  the  search is
+       When  alias database search fails, and the recipient localpart contains
+       the optional  recipient  delimiter  (e.g.,  <i>user+foo</i>),  the  search  is
        repeated for the unextended address (e.g., <i>user</i>).
 
-       The  <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>  parameter  controls   whether   an
+       The   <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>   parameter  controls  whether  an
        unmatched address extension (<i>+foo</i>) is propagated to the result of table
        lookup.
 
@@ -119,9 +128,9 @@ ALIASES(5)                                                          ALIASES(5)
        before database lookup.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This  section  describes how the table lookups change when the table is
-       given in the form of regular expressions. For a description of  regular
-       expression  lookup  table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
+       This section describes how the table lookups change when the  table  is
+       given  in the form of regular expressions. For a description of regular
+       expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a>  or  <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
        NOTE: these formats do not use ":" at the end of a pattern.
 
        Each regular expression is applied to the entire search string. Thus, a
@@ -134,28 +143,28 @@ ALIASES(5)                                                          ALIASES(5)
        reasons there is no support for <b>$1</b>, <b>$2</b> etc. substring interpolation.
 
 <b><a name="security">SECURITY</a></b>
-       The  <a href="local.8.html"><b>local</b>(8)</a>  delivery agent disallows regular expression substitution
+       The <a href="local.8.html"><b>local</b>(8)</a> delivery agent disallows regular  expression  substitution
        of $1 etc. in <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>, because that would open a security hole.
 
-       The <a href="local.8.html"><b>local</b>(8)</a> delivery agent will silently ignore requests  to  use  the
-       <a href="proxymap.8.html"><b>proxymap</b>(8)</a>  server  within  <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>. Instead it will open the table
+       The  <a href="local.8.html"><b>local</b>(8)</a>  delivery  agent will silently ignore requests to use the
+       <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server within <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>. Instead it will  open  the  table
        directly.  Before Postfix version 2.2, the <a href="local.8.html"><b>local</b>(8)</a> delivery agent will
        terminate with a fatal error.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a>  parameters  are especially relevant.  The text
-       below provides only a  parameter  summary.  See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for  more
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant.   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#alias_database">alias_database</a> (see 'postconf -d' output)</b>
-              The  alias databases for <a href="local.8.html"><b>local</b>(8)</a> delivery that are updated with
+              The alias databases for <a href="local.8.html"><b>local</b>(8)</a> delivery that are updated  with
               "<b>newaliases</b>" or with "<b>sendmail -bi</b>".
 
        <b><a href="postconf.5.html#alias_maps">alias_maps</a> (see 'postconf -d' output)</b>
-              Optional lookup tables that are  searched  only  with  an  email
-              address  localpart  (no  domain) and that apply only to <a href="local.8.html"><b>local</b>(8)</a>
-              recipients; this is unlike  <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a>  that  are  often
-              searched  with  a full email address (including domain) and that
+              Optional  lookup  tables  that  are  searched only with an email
+              address localpart (no domain) and that apply  only  to  <a href="local.8.html"><b>local</b>(8)</a>
+              recipients;  this  is  unlike  <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> that are often
+              searched with a full email address (including domain)  and  that
               apply to all recipients: <a href="local.8.html"><b>local</b>(8)</a>, virtual, and remote.
 
        <b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_commands</a> (alias, forward)</b>
@@ -165,30 +174,30 @@ ALIASES(5)                                                          ALIASES(5)
               Restrict <a href="local.8.html"><b>local</b>(8)</a> mail delivery to external files.
 
        <b><a href="postconf.5.html#expand_owner_alias">expand_owner_alias</a> (no)</b>
-              When  delivering  to  an   alias   "<i>aliasname</i>"   that   has   an
+              When   delivering   to   an   alias   "<i>aliasname</i>"  that  has  an
               "owner-<i>aliasname</i>"  companion  alias,  set  the  envelope  sender
               address to the expansion of the "owner-<i>aliasname</i>" alias.
 
        <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
-              What address lookup tables copy an address  extension  from  the
+              What  address  lookup  tables copy an address extension from the
               lookup key to the lookup result.
 
        <b><a href="postconf.5.html#owner_request_special">owner_request_special</a> (yes)</b>
-              Enable  special  treatment  for  owner-<i>listname</i>  entries  in the
+              Enable special  treatment  for  owner-<i>listname</i>  entries  in  the
               <a href="aliases.5.html"><b>aliases</b>(5)</a>  file,  and  don't  split  owner-<i>listname</i>  and  <i>list-</i>
-              <i>name</i>-request  address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> is
+              <i>name</i>-request address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>  is
               set to "-".
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
-              The set of characters that can separate an email address  local-
+              The  set of characters that can separate an email address local-
               part, user name, or a .forward file name from its extension.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#frozen_delivered_to">frozen_delivered_to</a> (yes)</b>
-              Update  the  <a href="local.8.html"><b>local</b>(8)</a> delivery agent's idea of the Delivered-To:
-              address (see <a href="postconf.5.html#prepend_delivered_header">prepend_delivered_header</a>) only once, at  the  start
-              of  a  delivery attempt; do not update the Delivered-To: address
+              Update the <a href="local.8.html"><b>local</b>(8)</a> delivery agent's idea of  the  Delivered-To:
+              address  (see  <a href="postconf.5.html#prepend_delivered_header">prepend_delivered_header</a>) only once, at the start
+              of a delivery attempt; do not update the  Delivered-To:  address
               while expanding aliases or .forward files.
 
 <b><a name="standards">STANDARDS</a></b>
index 6cef44e8d6742debfc4b13c1c4f7f3f44f8bb56d..561e4998f2dd0b9f2a18c8d3e300014d94b2ce60 100644 (file)
@@ -24,65 +24,72 @@ CANONICAL(5)                                                      CANONICAL(5)
        sive.
 
        Normally, the <a href="canonical.5.html"><b>canonical</b>(5)</a> table is  specified  as  a  text  file  that
-       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file
-       in <b>dbm</b> or <b>db</b> format, is used for fast searching  by  the  mail  system.
-       Execute  the  command  "<b>postmap  /etc/postfix/canonical</b>"  to rebuild an
-       indexed file after changing the corresponding text file.
+       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file for
+       fast lookup.
+
+       Execute the  command  "<b>postmap  /etc/postfix/canonical</b>"  to  rebuild  a
+       default-type  indexed  file  after  changing  the text file, or execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/canonical</b>" to specify an explicit type.
+
+       The default indexed file type  is  configured  with  the  <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a>  parameter.  Depending  on  the  platform  this may be one of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When the table is provided via other means such as NIS,  LDAP  or  SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively,  the  table  can be provided as a regular-expression map
-       where patterns are given as regular  expressions,  or  lookups  can  be
+       Alternatively, the table can be provided as  a  regular-expression  map
+       where  patterns  are  given  as  regular expressions, or lookups can be
        directed to a TCP-based server. In those cases, the lookups are done in
-       a slightly different way as described below under  "REGULAR  EXPRESSION
+       a  slightly  different way as described below under "REGULAR EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
        By  default  the  <a href="canonical.5.html"><b>canonical</b>(5)</a>  mapping  affects  both  message  header
-       addresses (i.e. addresses that  appear  inside  messages)  and  message
-       envelope  addresses  (for  example, the addresses that are used in SMTP
-       protocol commands).  This  is  controlled  with  the  <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b>
+       addresses  (i.e.  addresses  that  appear  inside messages) and message
+       envelope addresses (for example, the addresses that are  used  in  SMTP
+       protocol  commands).  This  is  controlled  with  the <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b>
        parameter.
 
-       NOTE:  Postfix  versions  2.2  and  later  rewrite message headers from
-       remote SMTP clients only if the  client  matches  the  <a href="postconf.5.html#local_header_rewrite_clients">local_header_re</a>-
+       NOTE: Postfix versions 2.2  and  later  rewrite  message  headers  from
+       remote  SMTP  clients  only  if the client matches the <a href="postconf.5.html#local_header_rewrite_clients">local_header_re</a>-
        <a href="postconf.5.html#local_header_rewrite_clients">write_clients</a> parameter, or if the <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> config-
-       uration parameter specifies a non-empty  value.  To  get  the  behavior
-       before    Postfix    2.2,   specify   "<a href="postconf.5.html#local_header_rewrite_clients">local_header_rewrite_clients</a>   =
+       uration  parameter  specifies  a  non-empty  value. To get the behavior
+       before   Postfix   2.2,   specify    "<a href="postconf.5.html#local_header_rewrite_clients">local_header_rewrite_clients</a>    =
        <a href="DATABASE_README.html#types">static</a>:all".
 
-       Typically, one would use the <a href="canonical.5.html"><b>canonical</b>(5)</a> table to replace login  names
+       Typically,  one would use the <a href="canonical.5.html"><b>canonical</b>(5)</a> table to replace login names
        by <i>Firstname.Lastname</i>, or to clean up addresses produced by legacy mail
        systems.
 
-       The <a href="canonical.5.html"><b>canonical</b>(5)</a> mapping is not to be confused with <i>virtual alias</i>  sup-
-       port  or  with  <a href="ADDRESS_REWRITING_README.html#aliases">local  aliasing</a>.  To change the destination but not the
+       The  <a href="canonical.5.html"><b>canonical</b>(5)</a> mapping is not to be confused with <i>virtual alias</i> sup-
+       port or with <a href="ADDRESS_REWRITING_README.html#aliases">local aliasing</a>. To change  the  destination  but  not  the
        headers, use the <a href="virtual.5.html"><b>virtual</b>(5)</a> or <a href="aliases.5.html"><b>aliases</b>(5)</a> map instead.
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The search string is folded to lowercase before database lookup. As  of
-       Postfix  2.3,  the search string is not case folded with database types
-       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
+       The  search string is folded to lowercase before database lookup. As of
+       Postfix 2.3, the search string is not case folded with  database  types
+       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        The input format for the <a href="postmap.1.html"><b>postmap</b>(1)</a> command is as follows:
 
        <i>pattern address</i>
-              When  <i>pattern</i>  matches  a mail address, replace it by the corre-
+              When <i>pattern</i> matches a mail address, replace it  by  the  corre-
               sponding <i>address</i>.
 
        blank lines and comments
-              Empty lines and whitespace-only lines are ignored, as are  lines
+              Empty  lines and whitespace-only lines are ignored, as are lines
               whose first non-whitespace character is a `#'.
 
        multi-line text
-              A  logical  line  starts  with  non-whitespace text. A line that
+              A logical line starts with  non-whitespace  text.  A  line  that
               starts with whitespace continues a logical line.
 
 <b><a name="table_search_order">TABLE SEARCH ORDER</a></b>
-       With lookups from indexed files such as DB or DBM,  or  from  networked
-       tables  such  as  NIS,  LDAP  or SQL, each <i>user</i>@<i>domain</i> query produces a
+       With  lookups  from  indexed files such as DB or DBM, or from networked
+       tables such as NIS, LDAP or SQL,  each  <i>user</i>@<i>domain</i>  query  produces  a
        sequence of query patterns as described below.
 
        Each query pattern is sent to each specified lookup table before trying
@@ -92,13 +99,13 @@ CANONICAL(5)                                                      CANONICAL(5)
               Replace <i>user</i>@<i>domain</i> by <i>address</i>. This form has the highest prece-
               dence.
 
-              This is useful to clean up addresses  produced  by  legacy  mail
-              systems.   It  can  also  be  used to produce <i>Firstname.Lastname</i>
+              This  is  useful  to  clean up addresses produced by legacy mail
+              systems.  It can also  be  used  to  produce  <i>Firstname.Lastname</i>
               style addresses, but see below for a simpler solution.
 
        <i>user address</i>
-              Replace <i>user</i>@<i>site</i> by <i>address</i> when <i>site</i> is  equal  to  $<b><a href="postconf.5.html#myorigin">myorigin</a></b>,
-              when  <i>site</i>  is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it is listed in
+              Replace  <i>user</i>@<i>site</i>  by  <i>address</i> when <i>site</i> is equal to $<b><a href="postconf.5.html#myorigin">myorigin</a></b>,
+              when <i>site</i> is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it is  listed  in
               $<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a></b> or $<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a></b>.
 
               This form is useful for replacing login names by <i>Firstname.Last-</i>
@@ -108,16 +115,16 @@ CANONICAL(5)                                                      CANONICAL(5)
               Replace other addresses in <i>domain</i> by <i>address</i>.  This form has the
               lowest precedence.
 
-              Note: @<i>domain</i> is a wild-card.  When  this  form  is  applied  to
-              recipient  addresses,  the  Postfix SMTP server accepts mail for
-              any recipient in <i>domain</i>, regardless of  whether  that  recipient
-              exists.   This  may  turn  your  mail  system into a backscatter
-              source: Postfix first accepts mail for  non-existent  recipients
-              and  then  tries  to  return that mail as "undeliverable" to the
+              Note:  @<i>domain</i>  is  a  wild-card.  When  this form is applied to
+              recipient addresses, the Postfix SMTP server  accepts  mail  for
+              any  recipient  in  <i>domain</i>, regardless of whether that recipient
+              exists.  This may turn  your  mail  system  into  a  backscatter
+              source:  Postfix  first accepts mail for non-existent recipients
+              and then tries to return that mail  as  "undeliverable"  to  the
               often forged sender address.
 
-              To avoid backscatter with mail for a wild-card  domain,  replace
-              the  wild-card  mapping  with  explicit  1:1  mappings, or add a
+              To  avoid  backscatter with mail for a wild-card domain, replace
+              the wild-card mapping with  explicit  1:1  mappings,  or  add  a
               <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> restriction for that domain:
 
                   <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
@@ -133,10 +140,10 @@ CANONICAL(5)                                                      CANONICAL(5)
 <b><a name="result_address_rewriting">RESULT ADDRESS REWRITING</a></b>
        The lookup result is subject to address rewriting:
 
-       <b>o</b>      When  the  result  has the form @<i>otherdomain</i>, the result becomes
+       <b>o</b>      When the result has the form @<i>otherdomain</i>,  the  result  becomes
               the same <i>user</i> in <i>otherdomain</i>.
 
-       <b>o</b>      When "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to  addresses
+       <b>o</b>      When  "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to addresses
               without "@domain".
 
        <b>o</b>      When "<b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes</b>", append "<b>.$<a href="postconf.5.html#mydomain">mydomain</a></b>" to addresses
@@ -144,38 +151,38 @@ CANONICAL(5)                                                      CANONICAL(5)
 
 <b><a name="address_extension">ADDRESS EXTENSION</a></b>
        When a mail address localpart contains the optional recipient delimiter
-       (e.g.,  <i>user+foo</i>@<i>domain</i>),  the  lookup  order becomes: <i>user+foo</i>@<i>domain</i>,
+       (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order  becomes:  <i>user+foo</i>@<i>domain</i>,
        <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and @<i>domain</i>.
 
-       The  <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>  parameter  controls   whether   an
+       The   <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>   parameter  controls  whether  an
        unmatched address extension (<i>+foo</i>) is propagated to the result of table
        lookup.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This section describes how the table lookups change when the  table  is
-       given  in the form of regular expressions. For a description of regular
+       This  section  describes how the table lookups change when the table is
+       given in the form of regular expressions. For a description of  regular
        expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to  the  entire
-       address  being looked up. Thus, <i>user@domain</i> mail addresses are not bro-
-       ken up into their <i>user</i> and <i>@domain</i> constituent parts, nor  is  <i>user+foo</i>
+       Each  pattern  is  a  regular  expression that is applied to the entire
+       address being looked up. Thus, <i>user@domain</i> mail addresses are not  bro-
+       ken  up  into their <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i>
        broken up into <i>user</i> and <i>foo</i>.
 
-       Patterns  are  applied  in the order as specified in the table, until a
+       Patterns are applied in the order as specified in the  table,  until  a
        pattern is found that matches the search string.
 
-       Results are the same as with indexed file lookups, with the  additional
-       feature  that parenthesized substrings from the pattern can be interpo-
+       Results  are the same as with indexed file lookups, with the additional
+       feature that parenthesized substrings from the pattern can be  interpo-
        lated as <b>$1</b>, <b>$2</b> and so on.
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This section describes how the table lookups change  when  lookups  are
-       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
-       client/server lookup protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature  is  not
+       This  section  describes  how the table lookups change when lookups are
+       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
+       client/server  lookup  protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature is not
        available up to and including Postfix version 2.4.
 
-       Each  lookup operation uses the entire address once.  Thus, <i>user@domain</i>
-       mail addresses are not broken up  into  their  <i>user</i>  and  <i>@domain</i>  con-
+       Each lookup operation uses the entire address once.  Thus,  <i>user@domain</i>
+       mail  addresses  are  not  broken  up  into their <i>user</i> and <i>@domain</i> con-
        stituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
@@ -184,76 +191,76 @@ CANONICAL(5)                                                      CANONICAL(5)
        The table format does not understand quoting conventions.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a>  parameters  are especially relevant.  The text
-       below provides only a  parameter  summary.  See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for  more
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant.   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#canonical_classes">canonical_classes</a>  (envelope_sender, envelope_recipient, header_sender,</b>
+       <b><a href="postconf.5.html#canonical_classes">canonical_classes</a> (envelope_sender, envelope_recipient,  header_sender,</b>
        <b>header_recipient)</b>
               What addresses are subject to <a href="postconf.5.html#canonical_maps">canonical_maps</a> address mapping.
 
        <b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
-              Optional  address  mapping lookup tables for message headers and
+              Optional address mapping lookup tables for message  headers  and
               envelopes.
 
        <b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
-              Optional address mapping lookup tables for envelope  and  header
+              Optional  address  mapping lookup tables for envelope and header
               recipient addresses.
 
        <b><a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> (empty)</b>
-              Optional  address  mapping lookup tables for envelope and header
+              Optional address mapping lookup tables for envelope  and  header
               sender addresses.
 
        <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
-              What address lookup tables copy an address  extension  from  the
+              What  address  lookup  tables copy an address extension from the
               lookup key to the lookup result.
 
        Other parameters of interest:
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  local  network  interface  addresses  that this mail system
+              The local network interface  addresses  that  this  mail  system
               receives mail on.
 
        <b><a href="postconf.5.html#local_header_rewrite_clients">local_header_rewrite_clients</a> (<a href="postconf.5.html#permit_inet_interfaces">permit_inet_interfaces</a>)</b>
-              Rewrite or add message  headers  in  mail  from  these  clients,
-              updating  incomplete addresses with the domain name in $<a href="postconf.5.html#myorigin">myorigin</a>
+              Rewrite  or  add  message  headers  in  mail from these clients,
+              updating incomplete addresses with the domain name in  $<a href="postconf.5.html#myorigin">myorigin</a>
               or $<a href="postconf.5.html#mydomain">mydomain</a>, and adding missing headers.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The remote network interface addresses  that  this  mail  system
-              receives  mail  on by way of a proxy or network address transla-
+              The  remote  network  interface  addresses that this mail system
+              receives mail on by way of a proxy or network  address  transla-
               tion unit.
 
        <b><a href="postconf.5.html#masquerade_classes">masquerade_classes</a> (envelope_sender, header_sender, header_recipient)</b>
               What addresses are subject to address masquerading.
 
        <b><a href="postconf.5.html#masquerade_domains">masquerade_domains</a> (empty)</b>
-              Optional list of  domains  whose  subdomain  structure  will  be
+              Optional  list  of  domains  whose  subdomain  structure will be
               stripped off in email addresses.
 
        <b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
-              Optional  list  of  user names that are not subjected to address
-              masquerading,  even  when  their   addresses   match   $<a href="postconf.5.html#masquerade_domains">masquer</a>-
+              Optional list of user names that are not  subjected  to  address
+              masquerading,   even   when   their  addresses  match  $<a href="postconf.5.html#masquerade_domains">masquer</a>-
               <a href="postconf.5.html#masquerade_domains">ade_domains</a>.
 
        <b><a href="postconf.5.html#mydestination">mydestination</a> ($<a href="postconf.5.html#myhostname">myhostname</a>, localhost.$<a href="postconf.5.html#mydomain">mydomain</a>, localhost)</b>
-              The  list of domains that are delivered via the $<a href="postconf.5.html#local_transport">local_transport</a>
+              The list of domains that are delivered via the  $<a href="postconf.5.html#local_transport">local_transport</a>
               mail delivery transport.
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The domain name that locally-posted mail appears to  come  from,
+              The  domain  name that locally-posted mail appears to come from,
               and that locally posted mail is delivered to.
 
        <b><a href="postconf.5.html#owner_request_special">owner_request_special</a> (yes)</b>
-              Enable  special  treatment  for  owner-<i>listname</i>  entries  in the
+              Enable special  treatment  for  owner-<i>listname</i>  entries  in  the
               <a href="aliases.5.html"><b>aliases</b>(5)</a>  file,  and  don't  split  owner-<i>listname</i>  and  <i>list-</i>
-              <i>name</i>-request  address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> is
+              <i>name</i>-request address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>  is
               set to "-".
 
        <b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
-              Rewrite or add message headers in mail from  remote  clients  if
-              the  <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a>  parameter value is non-empty,
-              updating incomplete addresses with the domain specified  in  the
+              Rewrite  or  add  message headers in mail from remote clients if
+              the <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> parameter value  is  non-empty,
+              updating  incomplete  addresses with the domain specified in the
               <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> parameter, and adding missing head-
               ers.
 
index b754c5a9049f89a14a11435f31b3aee886577220..6d51238d9315997d34de7ff4d649960a562e5606 100644 (file)
@@ -17,10 +17,12 @@ CIDR_TABLE(5)                                                    CIDR_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></b>
        The  Postfix mail system uses optional lookup tables.  These tables are
-       usually in <b>dbm</b> or <b>db</b> format.  Alternatively, lookup tables can be spec-
-       ified in CIDR (Classless Inter-Domain Routing) form. In this case, each
-       input is compared against a list of patterns. When a  match  is  found,
-       the corresponding result is returned and the search is terminated.
+       usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>, or <b><a href="DATABASE_README.html#types">dbm</a>:</b> format.
+
+       Alternatively, lookup  tables  can  be  specified  in  CIDR  (Classless
+       Inter-Domain  Routing)  form.  In  this  case,  each  input is compared
+       against a list of patterns. When a match is  found,  the  corresponding
+       result is returned and the search is terminated.
 
        To  find  out  what types of lookup tables your Postfix system supports
        use the "<b>postconf -m</b>" command.
index b9a4e09910f5ea9930779e36dc01bcefebeb93f5..e24e383b05b558ef95c8a11b77080f7c5405ec86 100644 (file)
@@ -34,44 +34,51 @@ GENERIC(5)                                                          GENERIC(5)
        (for example, the addresses that are used in SMTP protocol commands).
 
        Normally, the <a href="generic.5.html"><b>generic</b>(5)</a> table is specified as a text file that  serves
-       as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file in <b>dbm</b>
-       or <b>db</b> format, is used for fast searching by the  mail  system.  Execute
-       the  command  "<b>postmap /etc/postfix/generic</b>" to rebuild an indexed file
-       after changing the corresponding text file.
+       as  input  to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file for fast
+       lookup.
+
+       Execute  the  command  "<b>postmap  /etc/postfix/generic</b>"  to  rebuild   a
+       default-type  indexed  file  after  changing  the text file, or execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/generic</b>" to specify an explicit type.
+
+       The default indexed file type  is  configured  with  the  <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a>  parameter.  Depending  on  the  platform  this may be one of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When the table is provided via other means such as NIS,  LDAP  or  SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively,  the  table  can be provided as a regular-expression map
-       where patterns are given as regular  expressions,  or  lookups  can  be
+       Alternatively, the table can be provided as  a  regular-expression  map
+       where  patterns  are  given  as  regular expressions, or lookups can be
        directed to a TCP-based server. In those cases, the lookups are done in
-       a slightly different way as described below under  "REGULAR  EXPRESSION
+       a  slightly  different way as described below under "REGULAR EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The  search string is folded to lowercase before database lookup. As of
-       Postfix 2.3, the search string is not case folded with  database  types
-       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
+       The search string is folded to lowercase before database lookup. As  of
+       Postfix  2.3,  the search string is not case folded with database types
+       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        The input format for the <a href="postmap.1.html"><b>postmap</b>(1)</a> command is as follows:
 
        <i>pattern result</i>
-              When <i>pattern</i> matches a mail address, replace it  by  the  corre-
+              When  <i>pattern</i>  matches  a mail address, replace it by the corre-
               sponding <i>result</i>.
 
        blank lines and comments
-              Empty  lines and whitespace-only lines are ignored, as are lines
+              Empty lines and whitespace-only lines are ignored, as are  lines
               whose first non-whitespace character is a `#'.
 
        multi-line text
-              A logical line starts with  non-whitespace  text.  A  line  that
+              A  logical  line  starts  with  non-whitespace text. A line that
               starts with whitespace continues a logical line.
 
 <b><a name="table_search_order">TABLE SEARCH ORDER</a></b>
-       With  lookups  from  indexed files such as DB or DBM, or from networked
-       tables such as NIS, LDAP or SQL,  each  <i>user</i>@<i>domain</i>  query  produces  a
+       With lookups from indexed files such as DB or DBM,  or  from  networked
+       tables  such  as  NIS,  LDAP  or SQL, each <i>user</i>@<i>domain</i> query produces a
        sequence of query patterns as described below.
 
        Each query pattern is sent to each specified lookup table before trying
@@ -82,8 +89,8 @@ GENERIC(5)                                                          GENERIC(5)
               dence.
 
        <i>user address</i>
-              Replace  <i>user</i>@<i>site</i>  by  <i>address</i> when <i>site</i> is equal to $<b><a href="postconf.5.html#myorigin">myorigin</a></b>,
-              when <i>site</i> is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it is  listed  in
+              Replace <i>user</i>@<i>site</i> by <i>address</i> when <i>site</i> is  equal  to  $<b><a href="postconf.5.html#myorigin">myorigin</a></b>,
+              when  <i>site</i>  is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it is listed in
               $<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a></b> or $<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a></b>.
 
        @<i>domain address</i>
@@ -93,10 +100,10 @@ GENERIC(5)                                                          GENERIC(5)
 <b><a name="result_address_rewriting">RESULT ADDRESS REWRITING</a></b>
        The lookup result is subject to address rewriting:
 
-       <b>o</b>      When the result has the form @<i>otherdomain</i>,  the  result  becomes
+       <b>o</b>      When  the  result  has the form @<i>otherdomain</i>, the result becomes
               the same <i>user</i> in <i>otherdomain</i>.
 
-       <b>o</b>      When  "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to addresses
+       <b>o</b>      When "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to  addresses
               without "@domain".
 
        <b>o</b>      When "<b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes</b>", append "<b>.$<a href="postconf.5.html#mydomain">mydomain</a></b>" to addresses
@@ -104,45 +111,45 @@ GENERIC(5)                                                          GENERIC(5)
 
 <b><a name="address_extension">ADDRESS EXTENSION</a></b>
        When a mail address localpart contains the optional recipient delimiter
-       (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order  becomes:  <i>user+foo</i>@<i>domain</i>,
+       (e.g.,  <i>user+foo</i>@<i>domain</i>),  the  lookup  order becomes: <i>user+foo</i>@<i>domain</i>,
        <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and @<i>domain</i>.
 
-       The   <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>   parameter  controls  whether  an
+       The  <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>  parameter  controls   whether   an
        unmatched address extension (<i>+foo</i>) is propagated to the result of table
        lookup.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This  section  describes how the table lookups change when the table is
-       given in the form of regular expressions. For a description of  regular
+       This section describes how the table lookups change when the  table  is
+       given  in the form of regular expressions. For a description of regular
        expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each  pattern  is  a  regular  expression that is applied to the entire
-       address being looked up. Thus, <i>user@domain</i> mail addresses are not  bro-
-       ken  up  into their <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i>
+       Each pattern is a regular expression that  is  applied  to  the  entire
+       address  being looked up. Thus, <i>user@domain</i> mail addresses are not bro-
+       ken up into their <i>user</i> and <i>@domain</i> constituent parts, nor  is  <i>user+foo</i>
        broken up into <i>user</i> and <i>foo</i>.
 
-       Patterns are applied in the order as specified in the  table,  until  a
+       Patterns  are  applied  in the order as specified in the table, until a
        pattern is found that matches the search string.
 
-       Results  are the same as with indexed file lookups, with the additional
-       feature that parenthesized substrings from the pattern can be  interpo-
+       Results are the same as with indexed file lookups, with the  additional
+       feature  that parenthesized substrings from the pattern can be interpo-
        lated as <b>$1</b>, <b>$2</b> and so on.
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This  section  describes  how the table lookups change when lookups are
-       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
-       client/server  lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature is
+       This section describes how the table lookups change  when  lookups  are
+       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
+       client/server lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature  is
        available in Postfix 2.5 and later.
 
-       Each lookup operation uses the entire address once.  Thus,  <i>user@domain</i>
-       mail  addresses  are  not  broken  up  into their <i>user</i> and <i>@domain</i> con-
+       Each  lookup operation uses the entire address once.  Thus, <i>user@domain</i>
+       mail addresses are not broken up  into  their  <i>user</i>  and  <i>@domain</i>  con-
        stituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
 
 <b><a name="example">EXAMPLE</a></b>
-       The following shows a generic mapping with an indexed file.  When  mail
-       is  sent to a remote host via SMTP, this replaces <i>his@localdomain.local</i>
+       The  following shows a generic mapping with an indexed file.  When mail
+       is sent to a remote host via SMTP, this replaces  <i>his@localdomain.local</i>
        by his ISP mail address, replaces <i>her@localdomain.local</i> by her ISP mail
        address, and replaces other local addresses by his ISP account, with an
        address extension of <i>+local</i> (this example assumes that the ISP supports
@@ -156,52 +163,52 @@ GENERIC(5)                                                          GENERIC(5)
            her@localdomain.local   heraccount@herisp.example
            @localdomain.local      hisaccount+local@hisisp.example
 
-       Execute  the  command "<b>postmap /etc/postfix/generic</b>" whenever the table
-       is changed.  Instead of <b>hash</b>, some systems use <b>dbm</b> database  files.  To
-       find  out  what  tables  your system supports use the command "<b>postconf</b>
+       Execute the command "<b>postmap /etc/postfix/generic</b>" whenever  the  table
+       is  changed.   Instead of <b>hash</b>, some systems use <b>dbm</b> database files. To
+       find out what tables your system supports  use  the  command  "<b>postconf</b>
        <b>-m</b>".
 
 <b><a name="bugs">BUGS</a></b>
        The table format does not understand quoting conventions.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant.   The  text
-       below  provides  only  a  parameter  summary.  See <a href="postconf.5.html"><b>postconf</b>(5)</a> for more
+       The  following  <a href="postconf.5.html"><b>main.cf</b></a>  parameters  are especially relevant.  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#smtp_generic_maps">smtp_generic_maps</a> (empty)</b>
-              Optional lookup tables that perform  address  rewriting  in  the
-              Postfix  SMTP  client,  typically  to  transform a locally valid
-              address into a globally valid address when sending  mail  across
+              Optional  lookup  tables  that  perform address rewriting in the
+              Postfix SMTP client, typically  to  transform  a  locally  valid
+              address  into  a globally valid address when sending mail across
               the Internet.
 
        <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
-              What  address  lookup  tables copy an address extension from the
+              What address lookup tables copy an address  extension  from  the
               lookup key to the lookup result.
 
        Other parameters of interest:
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The local network interface  addresses  that  this  mail  system
+              The  local  network  interface  addresses  that this mail system
               receives mail on.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The  remote  network  interface  addresses that this mail system
-              receives mail on by way of a proxy or network  address  transla-
+              The remote network interface addresses  that  this  mail  system
+              receives  mail  on by way of a proxy or network address transla-
               tion unit.
 
        <b><a href="postconf.5.html#mydestination">mydestination</a> ($<a href="postconf.5.html#myhostname">myhostname</a>, localhost.$<a href="postconf.5.html#mydomain">mydomain</a>, localhost)</b>
-              The  list of domains that are delivered via the $<a href="postconf.5.html#local_transport">local_transport</a>
+              The list of domains that are delivered via the  $<a href="postconf.5.html#local_transport">local_transport</a>
               mail delivery transport.
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The domain name that locally-posted mail appears to  come  from,
+              The  domain  name that locally-posted mail appears to come from,
               and that locally posted mail is delivered to.
 
        <b><a href="postconf.5.html#owner_request_special">owner_request_special</a> (yes)</b>
-              Enable  special  treatment  for  owner-<i>listname</i>  entries  in the
+              Enable special  treatment  for  owner-<i>listname</i>  entries  in  the
               <a href="aliases.5.html"><b>aliases</b>(5)</a>  file,  and  don't  split  owner-<i>listname</i>  and  <i>list-</i>
-              <i>name</i>-request  address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> is
+              <i>name</i>-request address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>  is
               set to "-".
 
 <b><a name="see_also">SEE ALSO</a></b>
index c9d07330a312e6206e048ebf7a5fe809c670b804..00a7d0404a586689b87aac2aa9a872ed10fcd98d 100644 (file)
@@ -137,6 +137,8 @@ Per-client/user/etc. access </a>
 
 <li> <a href="DATABASE_README.html"> Lookup table overview </a>
 
+<li> <a href="NON_BERKELEYDB_README.html"> Non-Berkeley-DB migration </a>
+
 <li> <a href="DB_README.html"> Berkeley DB Howto  </a>
 
 <li> <a href="CDB_README.html"> CDB Howto  </a>
index 38875eb5f33a035189f3d9eb496d38442d776a73..77a455e37753327c1d63c65c3deea742fa8c34bd 100644 (file)
@@ -17,34 +17,37 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       Alternatively, lookup tables can be specified as LDAP databases.
+       Alternatively,  lookup  tables  can be specified as LDAP databases.  To
+       find out what types of lookup tables your Postfix system  supports  use
+       the "<b>postconf -m</b>" command.
 
-       In order to use LDAP lookups, define an LDAP source as a  lookup  table
+       In  order  to use LDAP lookups, define an LDAP source as a lookup table
        in <a href="postconf.5.html">main.cf</a>, for example:
 
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="ldap_table.5.html">ldap</a>:/etc/postfix/ldap-aliases.cf
 
-       The  file /etc/postfix/ldap-aliases.cf has the same format as the Post-
-       fix <a href="postconf.5.html">main.cf</a> file, and can specify the parameters  described  below.  An
+       The file /etc/postfix/ldap-aliases.cf has the same format as the  Post-
+       fix  <a href="postconf.5.html">main.cf</a>  file,  and can specify the parameters described below. An
        example is given at the end of this manual.
 
-       This  configuration  method  is  available with Postfix version 2.1 and
-       later.  See the section "OBSOLETE MAIN.CF PARAMETERS" below  for  older
+       This configuration method is available with  Postfix  version  2.1  and
+       later.   See  the section "OBSOLETE MAIN.CF PARAMETERS" below for older
        Postfix versions.
 
-       For  details  about  LDAP  SSL and STARTTLS, see the section on SSL and
+       For details about LDAP SSL and STARTTLS, see the  section  on  SSL  and
        STARTTLS below.
 
 <b><a name="list_membership">LIST MEMBERSHIP</a></b>
-       When using LDAP to store lists  such  as  $<a href="postconf.5.html#mynetworks">mynetworks</a>,  $<a href="postconf.5.html#mydestination">mydestination</a>,
-       $<a href="postconf.5.html#relay_domains">relay_domains</a>,  $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>, etc., it is important to under-
+       When  using  LDAP  to  store lists such as $<a href="postconf.5.html#mynetworks">mynetworks</a>, $<a href="postconf.5.html#mydestination">mydestination</a>,
+       $<a href="postconf.5.html#relay_domains">relay_domains</a>, $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>, etc., it is important to  under-
        stand that the table must store each list member as a separate key. The
-       table  lookup  verifies  the *existence* of the key. See "Postfix lists
+       table lookup verifies the *existence* of the key.  See  "Postfix  lists
        versus tables" in the <a href="DATABASE_README.html">DATABASE_README</a> document for a discussion.
 
-       Do NOT create tables that return the full list of domains in  $<a href="postconf.5.html#mydestination">mydesti</a>-
+       Do  NOT create tables that return the full list of domains in $<a href="postconf.5.html#mydestination">mydesti</a>-
        <a href="postconf.5.html#mydestination">nation</a> or $<a href="postconf.5.html#relay_domains">relay_domains</a> etc., or IP addresses in $<a href="postconf.5.html#mynetworks">mynetworks</a>.
 
        DO create tables with each matching item as a key and with an arbitrary
@@ -61,8 +64,8 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
            result_attribute = domain
 
 <b><a name="general_ldap_parameters">GENERAL LDAP PARAMETERS</a></b>
-       In  the  text  below,  default  values are given in parentheses.  Note:
-       don't use quotes in these variables; at least, not  until  the  Postfix
+       In the text below, default values  are  given  in  parentheses.   Note:
+       don't  use  quotes  in these variables; at least, not until the Postfix
        configuration routines understand how to deal with quoted strings.
 
        <b>server_host (default: localhost)</b>
@@ -70,16 +73,16 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
                   server_host = ldap.example.com
 
-              Depending  on the LDAP client library you're using, it should be
+              Depending on the LDAP client library you're using, it should  be
               possible to specify multiple servers here, with the library try-
-              ing  them  in order should the first one fail. It should also be
+              ing them in order should the first one fail. It should  also  be
               possible to give each server in the list a different port (over-
               riding <b>server_port</b> below), by naming them like
 
                   server_host = ldap.example.com:1444
 
-              NOTE:  this  client  will  reconnect  immediately after a single
-              failure, and will fail a lookup request after a  second  attempt
+              NOTE: this client will  reconnect  immediately  after  a  single
+              failure,  and  will fail a lookup request after a second attempt
               also fails.
 
               With OpenLDAP, a (list of) LDAP URLs can be used to specify both
@@ -88,9 +91,9 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
                   server_host = <a href="ldap_table.5.html">ldap</a>://ldap.example.com:1444
                               <a href="ldap_table.5.html">ldap</a>://ldap2.example.com:1444
 
-              All LDAP URLs accepted by the OpenLDAP  library  are  supported,
-              including  connections  over  UNIX  domain sockets, and LDAP SSL
-              (the last one provided that OpenLDAP was compiled  with  support
+              All  LDAP  URLs  accepted by the OpenLDAP library are supported,
+              including connections over UNIX domain  sockets,  and  LDAP  SSL
+              (the  last  one provided that OpenLDAP was compiled with support
               for SSL):
 
                   server_host = <a href="ldap_table.5.html">ldapi</a>://%2Fsome%2Fpath
@@ -102,7 +105,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
                   server_port = 778
 
        <b>timeout (default: 10 seconds)</b>
-              The  number of seconds a search can take before timing out, e.g.
+              The number of seconds a search can take before timing out,  e.g.
 
                   timeout = 5
 
@@ -116,39 +119,39 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
               <b>%%</b>     This is replaced by a literal '%' character.
 
-              <b>%s</b>     This  is  replaced by the input key.  <a href="https://tools.ietf.org/html/rfc2253">RFC 2253</a> quoting is
-                     used to make sure that the input key does not  add  unex-
+              <b>%s</b>     This is replaced by the input key.  <a href="https://tools.ietf.org/html/rfc2253">RFC 2253</a>  quoting  is
+                     used  to  make sure that the input key does not add unex-
                      pected metacharacters.
 
               <b>%u</b>     When the input key is an address of the form user@domain,
                      <b>%u</b> is replaced by the (<a href="https://tools.ietf.org/html/rfc2253">RFC 2253</a>) quoted local part of the
-                     address.   Otherwise, <b>%u</b> is replaced by the entire search
-                     string.  If the localpart is empty, the  search  is  sup-
+                     address.  Otherwise, <b>%u</b> is replaced by the entire  search
+                     string.   If  the  localpart is empty, the search is sup-
                      pressed and returns no results.
 
               <b>%d</b>     When the input key is an address of the form user@domain,
-                     <b>%d</b> is replaced by the (<a href="https://tools.ietf.org/html/rfc2253">RFC 2253</a>) quoted  domain  part  of
-                     the  address.   Otherwise,  the  search is suppressed and
+                     <b>%d</b>  is  replaced  by the (<a href="https://tools.ietf.org/html/rfc2253">RFC 2253</a>) quoted domain part of
+                     the address.  Otherwise, the  search  is  suppressed  and
                      returns no results.
 
               <b>%[SUD]</b> For the <b>search_base</b> parameter, the upper-case equivalents
-                     of  the  above  expansions  behave  identically  to their
-                     lower-case counter-parts. With the <b>result_format</b>  parame-
-                     ter  (previously called <b>result_filter</b> see the OTHER OBSO-
+                     of the  above  expansions  behave  identically  to  their
+                     lower-case  counter-parts. With the <b>result_format</b> parame-
+                     ter (previously called <b>result_filter</b> see the OTHER  OBSO-
                      LETE FEATURES section and below), they expand to the cor-
                      responding components of input key rather than the result
                      value.
 
-              <b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced  by  the  corre-
-                     sponding  most  significant  component of the input key's
-                     domain. If the input key is  <i>user@mail.example.com</i>,  then
+              <b>%[1-9]</b> The  patterns  %1,  %2, ... %9 are replaced by the corre-
+                     sponding 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
+                     is  unqualified or does not have enough domain components
                      to satisfy all the specified patterns, the search is sup-
                      pressed and returns no results.
 
        <b>query_filter (default: mailacceptinggeneralid=%s)</b>
-              The <a href="https://tools.ietf.org/html/rfc2254">RFC2254</a> filter used to search the directory, where <b>%s</b>  is  a
+              The  <a href="https://tools.ietf.org/html/rfc2254">RFC2254</a>  filter used to search the directory, where <b>%s</b> is a
               substitute for the address Postfix is trying to resolve, e.g.
 
                   query_filter = (&amp;(mail=%s)(paid_up=true))
@@ -158,114 +161,114 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               <b>%%</b>     This is replaced by a literal '%' character. (Postfix 2.2
                      and later).
 
-              <b>%s</b>     This is replaced by the input key.  <a href="https://tools.ietf.org/html/rfc2254">RFC 2254</a>  quoting  is
-                     used  to  make sure that the input key does not add unex-
+              <b>%s</b>     This  is  replaced by the input key.  <a href="https://tools.ietf.org/html/rfc2254">RFC 2254</a> quoting is
+                     used to make sure that the input key does not  add  unex-
                      pected metacharacters.
 
               <b>%u</b>     When the input key is an address of the form user@domain,
                      <b>%u</b> is replaced by the (<a href="https://tools.ietf.org/html/rfc2254">RFC 2254</a>) quoted local part of the
-                     address.  Otherwise, <b>%u</b> is replaced by the entire  search
-                     string.   If  the  localpart is empty, the search is sup-
+                     address.   Otherwise, <b>%u</b> is replaced by the entire search
+                     string.  If the localpart is empty, the  search  is  sup-
                      pressed and returns no results.
 
               <b>%d</b>     When the input key is an address of the form user@domain,
-                     <b>%d</b>  is  replaced  by the (<a href="https://tools.ietf.org/html/rfc2254">RFC 2254</a>) quoted domain part of
-                     the address.  Otherwise, the  search  is  suppressed  and
+                     <b>%d</b> is replaced by the (<a href="https://tools.ietf.org/html/rfc2254">RFC 2254</a>) quoted  domain  part  of
+                     the  address.   Otherwise,  the  search is suppressed and
                      returns no results.
 
               <b>%[SUD]</b> The upper-case equivalents of the above expansions behave
-                     in  the  <b>query_filter</b>  parameter  identically  to   their
-                     lower-case  counter-parts. With the <b>result_format</b> parame-
-                     ter (previously called <b>result_filter</b> see the OTHER  OBSO-
+                     in   the  <b>query_filter</b>  parameter  identically  to  their
+                     lower-case counter-parts. With the <b>result_format</b>  parame-
+                     ter  (previously called <b>result_filter</b> see the OTHER OBSO-
                      LETE FEATURES section and below), they expand to the cor-
                      responding components of input key rather than the result
                      value.
 
-                     The  above  %S,  %U  and %D expansions are available with
+                     The above %S, %U and %D  expansions  are  available  with
                      Postfix 2.2 and later.
 
-              <b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced  by  the  corre-
-                     sponding  most  significant  component of the input key's
-                     domain. If the input key is  <i>user@mail.example.com</i>,  then
+              <b>%[1-9]</b> The  patterns  %1,  %2, ... %9 are replaced by the corre-
+                     sponding 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
+                     is  unqualified or does not have enough domain components
                      to satisfy all the specified patterns, the search is sup-
                      pressed and returns no results.
 
                      The above %1, ..., %9 expansions are available with Post-
                      fix 2.2 and later.
 
-              The  "domain" parameter described below limits the input keys to
-              addresses in matching domains. When the  "domain"  parameter  is
-              non-empty,  LDAP  queries for unqualified addresses or addresses
+              The "domain" parameter described below limits the input keys  to
+              addresses  in  matching  domains. When the "domain" parameter is
+              non-empty, LDAP queries for unqualified addresses  or  addresses
               in non-matching domains are suppressed and return no results.
 
               NOTE: DO NOT put quotes around the <b>query_filter</b> parameter.
 
        <b>result_format (default: %s</b>)
-              Called <b>result_filter</b> in Postfix releases prior to  2.2.   Format
-              template  applied  to  result  attributes. Most commonly used to
-              append (or prepend) text to the result. This parameter  supports
+              Called  <b>result_filter</b>  in Postfix releases prior to 2.2.  Format
+              template applied to result attributes.  Most  commonly  used  to
+              append  (or prepend) text to the result. This parameter supports
               the following '%' expansions:
 
               <b>%%</b>     This is replaced by a literal '%' character. (Postfix 2.2
                      and later).
 
-              <b>%s</b>     This is replaced by the value of  the  result  attribute.
+              <b>%s</b>     This  is  replaced  by the value of the result attribute.
                      When result is empty it is skipped.
 
               <b>%u</b>     When the result attribute value is an address of the form
-                     user@domain, <b>%u</b> is replaced by  the  local  part  of  the
-                     address.  When  the  result  has an empty localpart it is
+                     user@domain,  <b>%u</b>  is  replaced  by  the local part of the
+                     address. When the result has an  empty  localpart  it  is
                      skipped.
 
-              <b>%d</b>     When a result attribute value is an address of  the  form
-                     user@domain,  <b>%d</b>  is  replaced  by the domain part of the
-                     attribute value. When the result  is  unqualified  it  is
+              <b>%d</b>     When  a  result attribute value is an address of the form
+                     user@domain, <b>%d</b> is replaced by the  domain  part  of  the
+                     attribute  value.  When  the  result is unqualified it is
                      skipped.
 
               <b>%[SUD1-9]</b>
-                     The  upper-case  and decimal digit expansions interpolate
-                     the parts of the input key rather than the result.  Their
-                     behavior  is  identical to that described with <b>query_fil-</b>
-                     <b>ter</b>, and in fact  because  the  input  key  is  known  in
-                     advance,  lookups  whose  key  does  not  contain all the
-                     information specified in the  result  template  are  sup-
+                     The upper-case and decimal digit  expansions  interpolate
+                     the  parts of the input key rather than the result. Their
+                     behavior is identical to that described  with  <b>query_fil-</b>
+                     <b>ter</b>,  and  in  fact  because  the  input  key is known in
+                     advance, lookups whose  key  does  not  contain  all  the
+                     information  specified  in  the  result template are sup-
                      pressed and return no results.
 
-                     The  above  %S,  %U,  %D  and  %1, ..., %9 expansions are
+                     The above %S, %U, %D  and  %1,  ...,  %9  expansions  are
                      available with Postfix 2.2 and later.
 
               For example, using "result_format = <a href="smtp.8.html">smtp</a>:[%s]" allows one to use
               a mailHost attribute as the basis of a <a href="transport.5.html">transport(5)</a> table. After
-              applying the result format, multiple values are concatenated  as
-              comma  separated  strings.  The  expansion_limit  and size_limit
-              parameters explained below allow one to restrict the  number  of
-              values  in  the result, which is especially useful for maps that
+              applying  the result format, multiple values are concatenated as
+              comma separated  strings.  The  expansion_limit  and  size_limit
+              parameters  explained  below allow one to restrict the number of
+              values in the result, which is especially useful for  maps  that
               should return a single value.
 
-              The default value <b>%s</b> specifies that each attribute value  should
+              The  default value <b>%s</b> specifies that each attribute value should
               be used as is.
 
-              This  parameter  was  called  <b>result_filter</b>  in Postfix releases
-              prior to 2.2. If no "result_format" is specified, the  value  of
-              "result_filter"  will  be  used  instead before resorting to the
-              default value. This provides compatibility with  old  configura-
+              This parameter was  called  <b>result_filter</b>  in  Postfix  releases
+              prior  to  2.2. If no "result_format" is specified, the value of
+              "result_filter" will be used instead  before  resorting  to  the
+              default  value.  This provides compatibility with old configura-
               tion files.
 
               NOTE: DO NOT put quotes around the result format!
 
        <b>domain (default: no domain list)</b>
-              This  is a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
+              This is a list of domain names, paths to files, or  "<a href="DATABASE_README.html">type:table</a>"
               databases. When specified, only fully qualified search keys with
-              a  *non-empty*  localpart and a matching domain are eligible for
+              a *non-empty* localpart and a matching domain are  eligible  for
               lookup:  'user'  lookups,  bare  domain  lookups  and  "@domain"
-              lookups  are  not  performed.  This can significantly reduce the
+              lookups are not performed. This  can  significantly  reduce  the
               query load on the LDAP server.
 
                   domain = postfix.org, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
 
-              It is best not to use LDAP to store  the  domains  eligible  for
+              It  is  best  not  to use LDAP to store the domains eligible for
               LDAP lookups.
 
               NOTE: DO NOT define this parameter for <a href="local.8.html">local(8)</a> aliases.
@@ -273,87 +276,87 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               This feature is available in Postfix 1.0 and later.
 
        <b>result_attribute (default: maildrop)</b>
-              The  attribute(s)  Postfix  will read from any directory entries
+              The attribute(s) Postfix will read from  any  directory  entries
               returned by the lookup, to be resolved to an email address.
 
                   result_attribute = mailbox, maildrop
 
-              Don't  rely  on  the  default  value   ("maildrop").   Set   the
-              result_attribute  explicitly  in  all  ldap  table configuration
+              Don't   rely   on   the  default  value  ("maildrop").  Set  the
+              result_attribute explicitly  in  all  ldap  table  configuration
               files. This is particularly relevant when no result_attribute is
-              applicable,  e.g.  cases  in  which leaf_result_attribute and/or
+              applicable, e.g. cases  in  which  leaf_result_attribute  and/or
               terminal_result_attribute are used instead. The default value is
-              harmless  if  "maildrop"  is  also  listed as a leaf or terminal
+              harmless if "maildrop" is also listed  as  a  leaf  or  terminal
               result attribute, but it is best to not leave this to chance.
 
        <b>special_result_attribute (default: empty)</b>
-              The attribute(s) of directory entries that can  contain  DNs  or
+              The  attribute(s)  of  directory entries that can contain DNs or
               <a href="https://tools.ietf.org/html/rfc2255">RFC 2255</a> LDAP URLs. If found, a recursive search is performed to
-              retrieve the entry referenced by the DN, or the entries  matched
+              retrieve  the entry referenced by the DN, or the entries matched
               by the URL query.
 
                   special_result_attribute = memberdn
 
-              DN  recursion  retrieves  the same result_attributes as the main
+              DN recursion retrieves the same result_attributes  as  the  main
               query, including the special attributes for further recursion.
 
               URL processing retrieves only those attributes that are included
-              in  both  the URL definition and as result attributes (ordinary,
-              special, leaf or terminal) in the Postfix table definition.   If
-              the  URL  lists  any  of  the table's special result attributes,
-              these are retrieved and used recursively. A URL  that  does  not
-              specify  any  attribute selection, is equivalent (<a href="https://tools.ietf.org/html/rfc2255">RFC 2255</a>) to a
-              URL that selects all attributes,  in  which  case  the  selected
-              attributes  will  be  the  full  set of result attributes in the
+              in both the URL definition and as result  attributes  (ordinary,
+              special,  leaf or terminal) in the Postfix table definition.  If
+              the URL lists any of  the  table's  special  result  attributes,
+              these  are  retrieved  and used recursively. A URL that does not
+              specify any attribute selection, is equivalent (<a href="https://tools.ietf.org/html/rfc2255">RFC 2255</a>)  to  a
+              URL  that  selects  all  attributes,  in which case the selected
+              attributes will be the full set  of  result  attributes  in  the
               Postfix table.
 
               If an LDAP URL attribute-descriptor or the corresponding Postfix
-              LDAP  table  result  attribute  (but  not  both)  uses  <a href="https://tools.ietf.org/html/rfc2255">RFC 2255</a>
-              sub-type options ("attr;option"), the attribute  requested  from
-              the  LDAP  server will include the sub-type option. In all other
-              cases, the URL attribute and  the  table  attribute  must  match
+              LDAP table  result  attribute  (but  not  both)  uses  <a href="https://tools.ietf.org/html/rfc2255">RFC  2255</a>
+              sub-type  options  ("attr;option"), the attribute requested from
+              the LDAP server will include the sub-type option. In  all  other
+              cases,  the  URL  attribute  and  the table attribute must match
               exactly. Attributes with options in both the URL and the Postfix
-              table are requested only when the options  are  identical.  LDAP
-              attribute-descriptor  options  are  very  rarely used, most LDAP
-              users will not need to concern themselves  with  this  level  of
+              table  are  requested  only when the options are identical. LDAP
+              attribute-descriptor options are very  rarely  used,  most  LDAP
+              users  will  not  need  to concern themselves with this level of
               nuanced detail.
 
        <b>terminal_result_attribute (default: empty)</b>
               When one or more terminal result attributes are found in an LDAP
               entry, all other result attributes are ignored and only the ter-
-              minal  result  attributes are returned. This is useful for dele-
+              minal result attributes are returned. This is useful  for  dele-
               gating expansion of group members to a particular host, by using
               an optional "maildrop" attribute on selected groups to route the
-              group to a specific host, where the group is expanded,  possibly
+              group  to a specific host, where the group is expanded, possibly
               via mailing-list manager or other special processing.
 
                   result_attribute =
                   terminal_result_attribute = maildrop
 
-              When   using   terminal   and/or  leaf  result  attributes,  the
-              result_attribute is best set to an empty value when  it  is  not
+              When  using  terminal  and/or  leaf   result   attributes,   the
+              result_attribute  is  best  set to an empty value when it is not
               used, or else explicitly set to the desired value, even if it is
               the default value "maildrop".
 
               This feature is available with Postfix 2.4 or later.
 
        <b>leaf_result_attribute (default: empty)</b>
-              When one or more  special  result  attributes  are  found  in  a
-              non-terminal  (see above) LDAP entry, leaf result attributes are
-              excluded from the expansion of that entry. This is  useful  when
-              expanding  groups  and  the desired mail address attribute(s) of
-              the member objects obtained via DN or  URI  recursion  are  also
+              When  one  or  more  special  result  attributes  are found in a
+              non-terminal (see above) LDAP entry, leaf result attributes  are
+              excluded  from  the expansion of that entry. This is useful when
+              expanding groups and the desired mail  address  attribute(s)  of
+              the  member  objects  obtained  via DN or URI recursion are also
               present in the group object. To only return the attribute values
-              from the leaf objects and not  the  containing  group,  add  the
-              attribute   to  the  leaf_result_attribute  list,  and  not  the
-              result_attribute list,  which  is  always  expanded.  Note,  the
-              default  value  of "result_attribute" is not empty, you may want
+              from  the  leaf  objects  and  not the containing group, add the
+              attribute  to  the  leaf_result_attribute  list,  and  not   the
+              result_attribute  list,  which  is  always  expanded.  Note, the
+              default value of "result_attribute" is not empty, you  may  want
               to set it explicitly empty when using "leaf_result_attribute" to
-              expand  the  group  to  a list of member DN addresses. If groups
+              expand the group to a list of member  DN  addresses.  If  groups
               have both member DN references AND attributes that hold multiple
               string valued rfc822 addresses, then the string attributes go in
-              "result_attribute".  The attributes  that  represent  the  email
-              addresses  of  objects  referenced  via a DN (or LDAP URI) go in
+              "result_attribute".   The  attributes  that  represent the email
+              addresses of objects referenced via a DN (or  LDAP  URI)  go  in
               "leaf_result_attribute".
 
                   result_attribute = memberaddr
@@ -361,20 +364,20 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
                   terminal_result_attribute = maildrop
                   leaf_result_attribute = mail
 
-              When  using  terminal  and/or  leaf   result   attributes,   the
-              result_attribute  is  best  set to an empty value when it is not
+              When   using   terminal   and/or  leaf  result  attributes,  the
+              result_attribute is best set to an empty value when  it  is  not
               used, or else explicitly set to the desired value, even if it is
               the default value "maildrop".
 
               This feature is available with Postfix 2.4 or later.
 
        <b>scope (default: sub)</b>
-              The  LDAP search scope: <b>sub</b>, <b>base</b>, or <b>one</b>.  These translate into
+              The LDAP search scope: <b>sub</b>, <b>base</b>, or <b>one</b>.  These translate  into
               LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE, and LDAP_SCOPE_ONELEVEL.
 
        <b>bind (default: yes)</b>
-              Whether or how to bind to the LDAP server. Newer LDAP  implemen-
-              tations  don't  require clients to bind, which saves time. Exam-
+              Whether  or how to bind to the LDAP server. Newer LDAP implemen-
+              tations don't require clients to bind, which saves  time.  Exam-
               ple:
 
                   # Don't bind
@@ -384,40 +387,40 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
                   # Use SASL bind
                   bind = sasl
 
-              Postfix versions prior to 2.8 only support  "bind  =  no"  which
+              Postfix  versions  prior  to  2.8 only support "bind = no" which
               means don't bind, and "bind = yes" which means do a SIMPLE bind.
-              Postfix 2.8 and later also supports "bind = SASL" when  compiled
+              Postfix  2.8 and later also supports "bind = SASL" when compiled
               with LDAP SASL support as described in <a href="LDAP_README.html">LDAP_README</a>, it also adds
-              the synonyms "bind = none" and "bind = simple" for "bind  =  no"
-              and  "bind  =  yes" respectively. See the SASL section below for
+              the  synonyms  "bind = none" and "bind = simple" for "bind = no"
+              and "bind = yes" respectively. See the SASL  section  below  for
               additional parameters available with "bind = sasl".
 
-              If you do need to bind, you might consider  configuring  Postfix
-              to  connect  to the local machine on a port that's an SSL tunnel
-              to your LDAP server. If your LDAP server doesn't  natively  sup-
-              port  SSL,  put  a  tunnel (wrapper, proxy, whatever you want to
-              call it) on that system too. This should  prevent  the  password
+              If  you  do need to bind, you might consider configuring Postfix
+              to connect to the local machine on a port that's an  SSL  tunnel
+              to  your  LDAP server. If your LDAP server doesn't natively sup-
+              port SSL, put a tunnel (wrapper, proxy,  whatever  you  want  to
+              call  it)  on  that system too. This should prevent the password
               from traversing the network in the clear.
 
        <b>bind_dn (default: empty)</b>
-              If  you  do  have  to  bind, do it with this distinguished name.
+              If you do have to bind, do  it  with  this  distinguished  name.
               Example:
 
                   bind_dn = uid=postfix, dc=your, dc=com
-              With "bind = sasl" (see above) the DN may be optional  for  some
+              With  "bind  = sasl" (see above) the DN may be optional for some
               SASL mechanisms, don't specify a DN if not needed.
 
        <b>bind_pw (default: empty)</b>
-              The  password  for  the distinguished name above. If you have to
-              use this, you probably want to make the map  configuration  file
-              readable  only  by  the  Postfix  user.  When using the obsolete
-              <a href="ldap_table.5.html">ldap</a>:ldapsource syntax, with map parameters in  <a href="postconf.5.html">main.cf</a>,  it  is
-              not  possible  to  securely  store  the  bind  password. This is
-              because <a href="postconf.5.html">main.cf</a> needs  to  be  world  readable  to  allow  local
+              The password for the distinguished name above. If  you  have  to
+              use  this,  you probably want to make the map configuration file
+              readable only by the  Postfix  user.  When  using  the  obsolete
+              <a href="ldap_table.5.html">ldap</a>:ldapsource  syntax,  with  map parameters in <a href="postconf.5.html">main.cf</a>, it is
+              not possible to  securely  store  the  bind  password.  This  is
+              because  <a href="postconf.5.html">main.cf</a>  needs  to  be  world  readable  to allow local
               accounts to submit mail via the sendmail command. Example:
 
                   bind_pw = postfixpw
-              With  "bind = sasl" (see above) the password may be optional for
+              With "bind = sasl" (see above) the password may be optional  for
               some SASL mechanisms, don't specify a password if not needed.
 
        <b>cache (IGNORED with a warning)</b>
@@ -425,38 +428,38 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
        <b>cache_expiry (IGNORED with a warning)</b>
 
        <b>cache_size (IGNORED with a warning)</b>
-              The above parameters are NO LONGER SUPPORTED by Postfix.   Cache
+              The  above parameters are NO LONGER SUPPORTED by Postfix.  Cache
               support has been dropped from OpenLDAP as of release 2.1.13.
 
        <b>recursion_limit (default: 1000)</b>
-              A  limit  on  the  nesting  depth  of  DN and URL special result
+              A limit on the nesting  depth  of  DN  and  URL  special  result
               attribute evaluation. The limit must be a non-zero positive num-
               ber.
 
        <b>expansion_limit (default: 0)</b>
-              A  limit  on  the total number of result elements returned (as a
+              A limit on the total number of result elements  returned  (as  a
               comma separated list) by a lookup against the map.  A setting of
-              zero  disables the limit. Lookups fail with a temporary error if
-              the limit is exceeded.  Setting the  limit  to  1  ensures  that
+              zero disables the limit. Lookups fail with a temporary error  if
+              the  limit  is  exceeded.   Setting  the limit to 1 ensures that
               lookups do not return multiple values.
 
        <b>size_limit (default: $expansion_limit)</b>
-              A  limit  on  the  number of LDAP entries returned by any single
+              A limit on the number of LDAP entries  returned  by  any  single
               LDAP search performed as part of the lookup. A setting of 0 dis-
-              ables  the  limit.   Expansion of DN and URL references involves
-              nested LDAP queries, each of which is  separately  subjected  to
+              ables the limit.  Expansion of DN and  URL  references  involves
+              nested  LDAP  queries,  each of which is separately subjected to
               this limit.
 
-              Note:  even  a  single  LDAP  entry can generate multiple lookup
-              results, via  multiple  result  attributes  and/or  multi-valued
-              result  attributes. This limit caps the per search resource uti-
-              lization on the LDAP server, not the final multiplicity  of  the
-              lookup   result.   It   is  analogous  to  the  "-z"  option  of
+              Note: even a single LDAP  entry  can  generate  multiple  lookup
+              results,  via  multiple  result  attributes  and/or multi-valued
+              result attributes. This limit caps the per search resource  uti-
+              lization  on  the LDAP server, not the final multiplicity of the
+              lookup  result.  It  is  analogous  to  the   "-z"   option   of
               "ldapsearch".
 
        <b>dereference (default: 0)</b>
               When to dereference LDAP aliases. (Note that this has nothing do
-              with  Postfix aliases.) The permitted values are those legal for
+              with Postfix aliases.) The permitted values are those legal  for
               the OpenLDAP/UM LDAP implementations:
 
               0      never
@@ -467,13 +470,13 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
               3      always
 
-              See ldap.h or the ldap_open(3) or ldapsearch(1)  man  pages  for
-              more  information.  And if you're using an LDAP package that has
-              other possible values, please bring it to the attention  of  the
+              See  ldap.h  or  the ldap_open(3) or ldapsearch(1) man pages for
+              more information. And if you're using an LDAP package  that  has
+              other  possible  values, please bring it to the attention of the
               postfix-users@postfix.org mailing list.
 
        <b>chase_referrals (default: 0)</b>
-              Sets  (or  clears)  LDAP_OPT_REFERRALS  (requires LDAP version 3
+              Sets (or clears) LDAP_OPT_REFERRALS  (requires  LDAP  version  3
               support).
 
        <b>version (default: 2)</b>
@@ -483,28 +486,28 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               What level to set for debugging in the OpenLDAP libraries.
 
 <b><a name="ldap_sasl_parameters">LDAP SASL PARAMETERS</a></b>
-       If you're using the OpenLDAP  libraries  compiled  with  SASL  support,
-       Postfix  2.8  and  later  built  with LDAP SASL support as described in
+       If  you're  using  the  OpenLDAP  libraries compiled with SASL support,
+       Postfix 2.8 and later built with LDAP  SASL  support  as  described  in
        <a href="LDAP_README.html">LDAP_README</a> can authenticate to LDAP servers via SASL.
 
-       This enables authentication to the LDAP  server  via  mechanisms  other
-       than  a  simple  password.  The  added flexibility has a cost: it is no
-       longer practical to set an explicit timeout on the duration of an  LDAP
-       bind  operation.  Under  adverse  conditions, whether a SASL bind times
-       out, or if it does, the duration of the timeout is  determined  by  the
+       This  enables  authentication  to  the LDAP server via mechanisms other
+       than a simple password. The added flexibility has  a  cost:  it  is  no
+       longer  practical to set an explicit timeout on the duration of an LDAP
+       bind operation. Under adverse conditions, whether  a  SASL  bind  times
+       out,  or  if  it does, the duration of the timeout is determined by the
        LDAP and SASL libraries.
 
-       It  is best to use tables that use SASL binds via <a href="proxymap.8.html">proxymap(8)</a>, this way
-       the requesting process can time-out the  proxymap  request.  This  also
-       lets  you  tailer the process environment by overriding the <a href="proxymap.8.html">proxymap(8)</a>
-       <a href="postconf.5.html#import_environment">import_environment</a> setting in <a href="master.5.html">master.cf</a>(5).  Special  environment  set-
+       It is best to use tables that use SASL binds via <a href="proxymap.8.html">proxymap(8)</a>, this  way
+       the  requesting  process  can  time-out the proxymap request. This also
+       lets you tailer the process environment by overriding  the  <a href="proxymap.8.html">proxymap(8)</a>
+       <a href="postconf.5.html#import_environment">import_environment</a>  setting  in  <a href="master.5.html">master.cf</a>(5). Special environment set-
        tings may be needed to configure GSSAPI credential caches or other SASL
-       mechanism specific  options.  The  GSSAPI  credentials  used  for  LDAP
-       lookups  may  need  to be different than say those used for the Postfix
+       mechanism  specific  options.  The  GSSAPI  credentials  used  for LDAP
+       lookups may need to be different than say those used  for  the  Postfix
        SMTP client to authenticate to remote servers.
 
-       Using SASL mechanisms requires LDAP protocol  version  3,  the  default
-       protocol  version  is 2 for backwards compatibility. You must set "ver-
+       Using  SASL  mechanisms  requires  LDAP protocol version 3, the default
+       protocol version is 2 for backwards compatibility. You must  set  "ver-
        sion = 3" in addition to "bind = sasl".
 
        The following parameters are relevant to using LDAP with SASL
@@ -519,14 +522,14 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               The SASL authorization identity to assert, if applicable.
 
        <b>sasl_minssf (default: 0)</b>
-              The minimum required sasl security factor required to  establish
+              The  minimum required sasl security factor required to establish
               a connection.
 
 <b><a name="ldap_ssl_and_starttls_parameters">LDAP SSL AND STARTTLS PARAMETERS</a></b>
        If you're using the OpenLDAP libraries compiled with SSL support, Post-
        fix can connect to LDAP SSL servers and can issue the STARTTLS command.
 
-       LDAP  SSL  service  can  be  requested  by  using a LDAP SSL URL in the
+       LDAP SSL service can be requested by  using  a  LDAP  SSL  URL  in  the
        server_host parameter:
 
            server_host = <a href="ldap_table.5.html">ldaps</a>://ldap.example.com:636
@@ -540,87 +543,87 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
            version = 3
 
-       If  any  of the Postfix programs querying the map is configured in <a href="master.5.html">mas-
-       ter.cf</a> to run chrooted, all the certificates and keys involved have  to
-       be  copied  to the chroot jail. Of course, the private keys should only
+       If any of the Postfix programs querying the map is configured  in  <a href="master.5.html">mas-
+       ter.cf</a>  to run chrooted, all the certificates and keys involved have to
+       be copied to the chroot jail. Of course, the private keys  should  only
        be readable by the user "postfix".
 
        The following parameters are relevant to LDAP SSL and STARTTLS:
 
        <b>start_tls (default: no)</b>
-              Whether or not to issue STARTTLS upon connection to the  server.
+              Whether  or not to issue STARTTLS upon connection to the server.
               Don't set this with LDAP SSL (the SSL session is setup automati-
               cally when the TCP connection is opened).
 
        <b>tls_ca_cert_dir (No default; set either this or tls_ca_cert_file)</b>
-              Directory containing X509 Certification  Authority  certificates
-              in  PEM  format  which  are  to  be  recognized by the client in
-              SSL/TLS connections. The files each contain one CA  certificate.
+              Directory  containing  X509 Certification Authority certificates
+              in PEM format which are  to  be  recognized  by  the  client  in
+              SSL/TLS  connections. The files each contain one CA certificate.
               The files are looked up by the CA subject name hash value, which
-              must hence be available. If more than one  CA  certificate  with
-              the  same name hash value exist, the extension must be different
-              (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search  is  performed  in
-              the  ordering of the extension number, regardless of other prop-
-              erties of the certificates. Use the c_rehash utility  (from  the
+              must  hence  be  available. If more than one CA certificate with
+              the same name hash value exist, the extension must be  different
+              (e.g.  9d66eef0.0,  9d66eef0.1  etc). The search is performed in
+              the ordering of the extension number, regardless of other  prop-
+              erties  of  the certificates. Use the c_rehash utility (from the
               OpenSSL distribution) to create the necessary links.
 
        <b>tls_ca_cert_file (No default; set either this or tls_ca_cert_dir)</b>
               File containing the X509 Certification Authority certificates in
-              PEM format which are to be recognized by the client  in  SSL/TLS
+              PEM  format  which are to be recognized by the client in SSL/TLS
               connections. This setting takes precedence over tls_ca_cert_dir.
 
        <b>tls_cert (No default; you must set this)</b>
-              File containing client's X509 certificate  to  be  used  by  the
+              File  containing  client's  X509  certificate  to be used by the
               client in SSL/ TLS connections.
 
        <b>tls_key (No default; you must set this)</b>
-              File  containing  the  private  key  corresponding  to the above
+              File containing the  private  key  corresponding  to  the  above
               tls_cert.
 
        <b>tls_require_cert (default: no)</b>
-              Whether or not to request server's X509  certificate  and  check
-              its  validity  when  establishing SSL/TLS connections.  The sup-
+              Whether  or  not  to request server's X509 certificate and check
+              its validity when establishing SSL/TLS  connections.   The  sup-
               ported values are <b>no</b> and <b>yes</b>.
 
-              With <b>no</b>, the server certificate trust chain is not checked,  but
-              with  OpenLDAP  prior to 2.1.13, the name in the server certifi-
-              cate must still match the LDAP server name. With OpenLDAP  2.0.0
+              With  <b>no</b>, the server certificate trust chain is not checked, but
+              with OpenLDAP prior to 2.1.13, the name in the  server  certifi-
+              cate  must still match the LDAP server name. With OpenLDAP 2.0.0
               to 2.0.11 the server name is not necessarily what you specified,
-              rather it is determined (by reverse lookup) from the IP  address
-              of  the  LDAP  server connection. With OpenLDAP prior to 2.0.13,
+              rather  it is determined (by reverse lookup) from the IP address
+              of the LDAP server connection. With OpenLDAP  prior  to  2.0.13,
               subjectAlternativeName extensions in the LDAP server certificate
-              are  ignored: the server name must match the subject CommonName.
-              The <b>no</b> setting corresponds to the <b>never</b> value of <b>TLS_REQCERT</b>  in
+              are ignored: the server name must match the subject  CommonName.
+              The  <b>no</b> setting corresponds to the <b>never</b> value of <b>TLS_REQCERT</b> in
               LDAP client configuration files.
 
-              Don't  use TLS with OpenLDAP 2.0.x (and especially with x &lt;= 11)
+              Don't use TLS with OpenLDAP 2.0.x (and especially with x &lt;=  11)
               if you can avoid it.
 
               With <b>yes</b>, the server certificate must be issued by a trusted CA,
-              and  not  be expired. The LDAP server name must match one of the
+              and not be expired. The LDAP server name must match one  of  the
               name(s) found in the certificate (see above for OpenLDAP library
-              version  dependent behavior). The <b>yes</b> setting corresponds to the
-              <b>demand</b> value of <b>TLS_REQCERT</b> in LDAP client configuration  files.
+              version dependent behavior). The <b>yes</b> setting corresponds to  the
+              <b>demand</b>  value of <b>TLS_REQCERT</b> in LDAP client configuration files.
 
-              The  "try" and "allow" values of <b>TLS_REQCERT</b> have no equivalents
-              here. They are not available with OpenLDAP 2.0, and in any  case
+              The "try" and "allow" values of <b>TLS_REQCERT</b> have no  equivalents
+              here.  They are not available with OpenLDAP 2.0, and in any case
               have questionable security properties. Either you want TLS veri-
               fied LDAP connections, or you don't.
 
-              The <b>yes</b> value only works correctly with Postfix 2.5  and  later,
+              The  <b>yes</b>  value only works correctly with Postfix 2.5 and later,
               or with OpenLDAP 2.0. Earlier Postfix releases or later OpenLDAP
               releases don't work together with this setting. Support for LDAP
               over TLS was added to Postfix based on the OpenLDAP 2.0 API.
 
        <b>tls_random_file (No default)</b>
               Path of a file to obtain random bits from when /dev/[u]random is
-              not available, to be used by the client in SSL/TLS  connections.
+              not  available, to be used by the client in SSL/TLS connections.
 
        <b>tls_cipher_suite (No default)</b>
               Cipher suite to use in SSL/TLS negotiations.
 
 <b><a name="example">EXAMPLE</a></b>
-       Here's  a  basic  example  for  using LDAP to look up <a href="local.8.html">local(8)</a> aliases.
+       Here's a basic example for using LDAP  to  look  up  <a href="local.8.html">local(8)</a>  aliases.
        Assume that in <a href="postconf.5.html">main.cf</a>, you have:
 
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/aliases,
@@ -631,33 +634,33 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
            server_host = ldap.example.com
            search_base = dc=example, dc=com
 
-       Upon receiving mail for a local address "ldapuser" that isn't found  in
-       the  /etc/aliases database, Postfix will search the LDAP server listen-
-       ing at port 389 on ldap.example.com.  It will bind anonymously,  search
-       for  any  directory  entries  whose mailacceptinggeneralid attribute is
-       "ldapuser", read the "maildrop" attributes of those found, and build  a
-       list  of  their maildrops, which will be treated as <a href="https://tools.ietf.org/html/rfc822">RFC822</a> addresses to
+       Upon  receiving mail for a local address "ldapuser" that isn't found in
+       the /etc/aliases database, Postfix will search the LDAP server  listen-
+       ing  at port 389 on ldap.example.com.  It will bind anonymously, search
+       for any directory entries  whose  mailacceptinggeneralid  attribute  is
+       "ldapuser",  read the "maildrop" attributes of those found, and build a
+       list of their maildrops, which will be treated as <a href="https://tools.ietf.org/html/rfc822">RFC822</a>  addresses  to
        which the message will be delivered.
 
 <b>OBSOLETE MAIN.CF PARAMETERS</b>
-       For backwards compatibility with Postfix version 2.0 and earlier,  LDAP
-       parameters  can  also  be defined in <a href="postconf.5.html">main.cf</a>.  Specify as LDAP source a
-       name that doesn't begin with a slash or a  dot.   The  LDAP  parameters
+       For  backwards compatibility with Postfix version 2.0 and earlier, LDAP
+       parameters can also be defined in <a href="postconf.5.html">main.cf</a>.  Specify as  LDAP  source  a
+       name  that  doesn't  begin  with a slash or a dot.  The LDAP parameters
        will then be accessible as the name you've given the source in its def-
        inition, an underscore, and the name of the parameter.  For example, if
-       the  map is specified as "<a href="ldap_table.5.html">ldap</a>:<i>ldapsource</i>", the "server_host" parameter
+       the map is specified as "<a href="ldap_table.5.html">ldap</a>:<i>ldapsource</i>", the "server_host"  parameter
        below would be defined in <a href="postconf.5.html">main.cf</a> as "<i>ldapsource</i>_server_host".
 
        Note: with this form, the passwords for the LDAP sources are written in
-       <a href="postconf.5.html">main.cf</a>,  which is normally world-readable.  Support for this form will
+       <a href="postconf.5.html">main.cf</a>, which is normally world-readable.  Support for this form  will
        be removed in a future Postfix version.
 
 <b><a name="other_obsolete_features">OTHER OBSOLETE FEATURES</a></b>
        <b>result_filter (No default)</b>
-              For backwards compatibility  with  the  pre  2.2  LDAP  clients,
+              For  backwards  compatibility  with  the  pre  2.2 LDAP clients,
               <b>result_filter</b> can for now be used instead of <b>result_format</b>, when
-              the latter parameter is not  also  set.   The  new  name  better
-              reflects  the  function  of  the  parameter.  This compatibility
+              the  latter  parameter  is  not  also  set.  The new name better
+              reflects the  function  of  the  parameter.  This  compatibility
               interface may be removed in a future release.
 
 <b><a name="see_also">SEE ALSO</a></b>
@@ -674,8 +677,8 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
        The Secure Mailer license must be distributed with this software.
 
 <b>AUTHOR(S)</b>
-       Carsten  Hoeger, Hery Rakotoarisoa, John Hensley, Keith Stevenson, LaM-
-       ont Jones, Liviu Daia, Manuel Guesdon, Mike Mattice, Prabhat  K  Singh,
+       Carsten Hoeger, Hery Rakotoarisoa, John Hensley, Keith Stevenson,  LaM-
+       ont  Jones,  Liviu Daia, Manuel Guesdon, Mike Mattice, Prabhat K Singh,
        Sami Haahtinen, Samuel Tardieu, Victor Duchovni, and many others.
 
                                                                  LDAP_TABLE(5)
index 47c9aa396e0615197ef263ee6ff76a01c1abfbde..570753fefe120cdbfa67c242ac63b6aaeafdd100 100644 (file)
@@ -17,27 +17,28 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       Alternatively, lookup tables can be specified  as  memcache  instances.
-       To  use memcache lookups, define a memcache source as a lookup table in
+       Alternatively, lookup tables can be specified as memcache instances. 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
+       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, update, delete and
-       sequence (first/next) operations. The  sequence  operation  requires  a
+       The Postfix memcache client supports the  lookup,  update,  delete  and
+       sequence  (first/next)  operations.  The  sequence operation requires a
        backup database that supports the operation.
 
 <b><a name="memcache_main_parameters">MEMCACHE MAIN PARAMETERS</a></b>
        <b>memcache (default: inet:localhost:11211)</b>
-              The  memcache  server  (note: singular) that Postfix will try to
-              connect to.  For a TCP server  specify  "inet:"  followed  by  a
+              The memcache server (note: singular) that Postfix  will  try  to
+              connect  to.   For  a  TCP  server specify "inet:" followed by a
               hostname or address, ":", and a port name or number.  Specify an
-              IPv6 address inside "[]".   For  a  UNIX-domain  server  specify
+              IPv6  address  inside  "[]".   For  a UNIX-domain server specify
               "unix:" followed by the socket pathname. Examples:
 
                   memcache = inet:memcache.example.com:11211
@@ -45,15 +46,15 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
                   memcache = inet:[fc00:8d00:189::3]:11211
                   memcache = unix:/path/to/socket
 
-              NOTE:  to  access  a  UNIX-domain  socket  with  the <a href="proxymap.8.html">proxymap(8)</a>
-              server, the socket must be accessible by the unprivileged  post-
+              NOTE: to  access  a  UNIX-domain  socket  with  the  <a href="proxymap.8.html">proxymap(8)</a>
+              server,  the socket must be accessible by the unprivileged post-
               fix user.
 
        <b>backup (default: undefined)</b>
               An optional Postfix database that provides persistent backup for
-              the memcache database. The Postfix memcache client  will  update
-              the  memcache  database whenever it looks up or changes informa-
-              tion in the persistent database. Specify a Postfix  "<a href="DATABASE_README.html">type:table</a>"
+              the  memcache  database. The Postfix memcache client will update
+              the memcache database whenever it looks up or  changes  informa-
+              tion  in the persistent database. Specify a Postfix "<a href="DATABASE_README.html">type:table</a>"
               database. Examples:
 
                   # Non-shared postscreen cache.
@@ -64,65 +65,65 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
 
               Access to remote proxymap servers is under development.
 
-              NOTE  1:  When  sharing  a persistent <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a>
-              cache,     disable     automatic     cache     cleanup      (set
-              *_cache_cleanup_interval  =  0) except with one Postfix instance
+              NOTE 1: When sharing a  persistent  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  or  <a href="verify.8.html"><b>verify</b>(8)</a>
+              cache,      disable     automatic     cache     cleanup     (set
+              *_cache_cleanup_interval = 0) except with one  Postfix  instance
               that will be responsible for cache cleanup.
 
-              NOTE 2: When multiple tables share the same  memcache  database,
-              each  table  should  use  the  <b>key_format</b> feature (see below) to
-              prepend its own unique string to  the  lookup  key.   Otherwise,
+              NOTE  2:  When multiple tables share the same memcache database,
+              each table should use the  <b>key_format</b>  feature  (see  below)  to
+              prepend  its  own  unique  string to the lookup key.  Otherwise,
               automatic <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache cleanup may not work.
 
-              NOTE 3: When the  backup  database  is  accessed  with  "<a href="proxymap.8.html">proxy</a>:"
-              lookups,  the  full backup database name (including the "<a href="proxymap.8.html">proxy</a>:"
+              NOTE  3:  When  the  backup  database  is accessed with "<a href="proxymap.8.html">proxy</a>:"
+              lookups, the full backup database name (including  the  "<a href="proxymap.8.html">proxy</a>:"
               prefix)   must   be   specified   in   the   proxymap   server's
-              <a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a>   or   <a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a>  setting  (depending  on
+              <a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a>  or  <a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a>  setting   (depending   on
               whether the access is read-only or read-write).
 
        <b>flags (default: 0)</b>
-              Optional flags that should  be  stored  along  with  a  memcache
+              Optional  flags  that  should  be  stored  along with a memcache
               update. The flags are ignored when looking up information.
 
        <b>ttl (default: 3600)</b>
               The expiration time in seconds of memcache updates.
 
-              NOTE  1:  When  using  a memcache table as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>ver-</b></a>
-              <a href="verify.8.html"><b>ify</b>(8)</a>  cache  without  persistent  backup,   specify   a   zero
-              *_cache_cleanup_interval  value  with all Postfix instances that
-              use the memcache, 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 memcache table's
+              NOTE 1: When using a memcache table  as  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  or  <a href="verify.8.html"><b>ver-</b></a>
+              <a href="verify.8.html"><b>ify</b>(8)</a>   cache   without   persistent  backup,  specify  a  zero
+              *_cache_cleanup_interval value with all Postfix  instances  that
+              use  the  memcache,  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  memcache  table's
               <b>ttl</b> value.
 
-              NOTE 2: According to memcache protocol  documentation,  a  value
-              greater  than  30 days (2592000 seconds) specifies absolute UNIX
+              NOTE  2:  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><a name="memcache_key_parameters">MEMCACHE KEY PARAMETERS</a></b>
        <b>key_digest (default: empty)</b>
-              After processing the <b>key_format</b> setting, and  before  sending  a
-              request  to  the  memcache server, run the key through the named
-              message digest algorithm and convert  the  result  to  lowercase
-              hexadecimal  characters.  This  prevents a database access error
-              when keys may exceed the  memcache  server's  key  length  limit
+              After  processing  the  <b>key_format</b> setting, and before sending a
+              request to the memcache server, run the key  through  the  named
+              message  digest  algorithm  and  convert the result to lowercase
+              hexadecimal characters. This prevents a  database  access  error
+              when  keys  may  exceed  the  memcache server's key length limit
               (usually, 250 bytes). Specify the name of a message digest algo-
               rithm that is supported by OpenSSL, for example, <b>sha256</b>.
 
-              This feature  is  available  in  Postfix  3.11  and  later,  and
+              This  feature  is  available  in  Postfix  3.11  and  later, and
               requires that Postfix is built with TLS support.
 
        <b>key_format (default: %s)</b>
-              Format  of  the lookup and update keys that the Postfix memcache
-              client sends to the memcache server.  By default, these are  the
-              same  as  the  lookup  and  update keys that the memcache client
+              Format of the lookup and update keys that the  Postfix  memcache
+              client  sends to the memcache server.  By default, these are the
+              same as the lookup and update  keys  that  the  memcache  client
               receives from Postfix applications.
 
-              NOTE 1: The <b>key_format</b> feature is not used for  <b>backup</b>  database
+              NOTE  1:  The <b>key_format</b> feature is not used for <b>backup</b> database
               requests.
 
-              NOTE  2:  When multiple tables share the same memcache database,
-              each table should prepend its own unique string  to  the  lookup
-              key.   Otherwise,  automatic  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  or  <a href="verify.8.html"><b>verify</b>(8)</a> cache
+              NOTE 2: When multiple tables share the same  memcache  database,
+              each  table  should  prepend its own unique string to the lookup
+              key.  Otherwise,  automatic  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  or  <a href="verify.8.html"><b>verify</b>(8)</a>  cache
               cleanup may not work.
 
               Examples:
@@ -138,37 +139,37 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
               <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.  Otherwise, <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
+                     <b>%u</b> is replaced by  the  SQL  quoted  local  part  of  the
+                     address.   Otherwise, <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 warning).
 
               <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.  Other-
-                     wise,  a  lookup  is  silently  suppressed and returns no
+                     wise, 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>   parameter  identically  to  their
+                     in  the  <b>key_format</b>  parameter   identically   to   their
                      lower-case counter-parts.
 
-              <b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced  by  the  corre-
-                     sponding  most  significant  component of the input key's
-                     domain. If the input key is  <i>user@mail.example.com</i>,  then
+              <b>%[1-9]</b> The  patterns  %1,  %2, ... %9 are replaced by the corre-
+                     sponding 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  specified  patterns,  a  lookup is
-                     silently suppressed and returns no results (an update  is
+                     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).
 
        <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  "<a href="DATABASE_README.html">type:table</a>"
-              databases.   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
+              This feature can  significantly  reduce  database  server  load.
+              Specify  a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
+              databases.  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, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
@@ -181,30 +182,30 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
               The maximal memcache reply line length in bytes.
 
        <b>max_try (default: 2)</b>
-              The  number of times to try a memcache command before giving up.
-              The memcache client does not retry a command when  the  memcache
+              The number of times to try a memcache command before giving  up.
+              The  memcache  client does not retry a command when the memcache
               server accepts no connection.
 
        <b>retry_pause (default: 1)</b>
               The time in seconds before retrying a failed memcache command.
 
        <b>timeout (default: 2)</b>
-              The  time limit for sending a memcache command and for receiving
+              The time limit for sending a memcache command and for  receiving
               a memcache reply.
 
 <b><a name="bugs">BUGS</a></b>
-       The Postfix memcache  client  cannot  be  used  for  security-sensitive
+       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">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and  <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b>
+       destinations),  or <b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b>
        <b><a href="postconf.5.html#virtual_mailbox_maps">box_maps</a></b> (these specify UNIX process privileges for "<i>/file/name</i>" desti-
-       nations).  In a typical deployment a memcache database is  writable  by
-       any  process  that  can talk to the memcache server; in contrast, secu-
-       rity-sensitive tables must never be writable by the unprivileged  Post-
+       nations).   In  a typical deployment a memcache database is writable by
+       any process that can talk to the memcache server;  in  contrast,  secu-
+       rity-sensitive  tables must never be writable by the unprivileged Post-
        fix user.
 
        The Postfix memcache client requires additional configuration when used
-       as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache.  For details see  the  <b>backup</b>  and
-       <b>ttl</b>  parameter  discussions  in  the  MEMCACHE  MAIN PARAMETERS section
+       as  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  or  <a href="verify.8.html"><b>verify</b>(8)</a> cache.  For details see the <b>backup</b> and
+       <b>ttl</b> parameter discussions  in  the  MEMCACHE  MAIN  PARAMETERS  section
        above.
 
 <b><a name="see_also">SEE ALSO</a></b>
index 88f5a4d4cf3504c8f195d002ace288335205d8ee..f323d104852d17849fa729e39b74277d1dea55dc 100644 (file)
@@ -17,11 +17,15 @@ MONGODB_TABLE(5)                                              MONGODB_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       Alternatively, lookup tables can be specified as MongoDB databases.  In
-       order to use MongoDB lookups, define a MongoDB source as a lookup table
-       in <a href="postconf.5.html">main.cf</a>, for example:
+       Alternatively, lookup tables can be specified as MongoDB databases.  To
+       find out what types of lookup tables your Postfix system  supports  use
+       the "<b>postconf -m</b>" command.
+
+       In  order  to  use MongoDB lookups, define a MongoDB source as a lookup
+       table in <a href="postconf.5.html">main.cf</a>, for example:
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mongodb_table.5.html">mongodb</a>:/etc/postfix/mongodb-aliases.cf
 
        In this example, the file /etc/postfix/mongodb-aliases.cf has the  same
index 5fecce71e07276327c81bee50d04d0ed23095eb8..136679c38d7c0edf43fe95059da43b77efda13eb 100644 (file)
@@ -17,11 +17,15 @@ MYSQL_TABLE(5)                                                  MYSQL_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       Alternatively, lookup tables can be specified as MySQL  databases.   In
-       order  to use MySQL lookups, define a MySQL source as a lookup table in
-       <a href="postconf.5.html">main.cf</a>, for example:
+       Alternatively,  lookup  tables can be specified as MySQL databases.  To
+       find out what types of lookup tables your Postfix system  supports  use
+       the "<b>postconf -m</b>" command.
+
+       In  order to use MySQL lookups, define a MySQL source as a lookup table
+       in <a href="postconf.5.html">main.cf</a>, for example:
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="mysql_table.5.html">mysql</a>:/etc/postfix/mysql-aliases.cf
 
        The file /etc/postfix/mysql-aliases.cf has the same format as the Post-
diff --git a/postfix/html/nbdb_reindexd.8.html b/postfix/html/nbdb_reindexd.8.html
new file mode 100644 (file)
index 0000000..36529a2
--- /dev/null
@@ -0,0 +1,151 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "https://www.w3.org/TR/html4/loose.dtd">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel='stylesheet' type='text/css' href='postfix-doc.css'>
+<title> Postfix manual - nbdb_reindexd(8) </title>
+</head> <body> <pre>
+NBDB_REINDEXD(8)                                              NBDB_REINDEXD(8)
+
+<b><a name="name">NAME</a></b>
+       nbdb_reindexd - Postfix non-Berkeley-DB migration
+
+<b><a name="synopsis">SYNOPSIS</a></b>
+       <b>nbdb_reindexd</b> [generic Postfix daemon options]
+
+<b><a name="description">DESCRIPTION</a></b>
+       <i>NOTE:  This service should be enabled only temporarily to generate most</i>
+       <i>of the non-Berkeley-DB indexed files that Postfix needs.  Leaving  this</i>
+       <i>service  enabled may expose the system to privilege-escalation attacks.</i>
+
+       The <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> server handles requests to generate  a  non-Berke-
+       ley-DB  indexed  database  file  for  an  existing Berkeley DB database
+       (example: "<a href="DATABASE_README.html#types">hash</a>:/path/to/file" or "<a href="DATABASE_README.html#types">btree</a>:/path/to/file"). It implements
+       the  service  by  running  the  <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command with
+       appropriate privileges.
+
+       The service reports a success status when the  non-Berkeley-DB  indexed
+       file  already  exists.  This  can happen when multiple clients make the
+       same request. When one request is completed successfully,  the  service
+       also reports success for the other requests.
+
+       This service enforces the following safety policy:
+
+       <b>o</b>      The  legacy  Berkeley DB indexed file must exist (file name ends
+              in ".db"). The <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> service  will  use  the  owner"s
+              (uid,  gid)  of  this  file,  when it runs <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postal-</a>
+              <a href="postalias.1.html">ias(1)</a>. It also uses the (uid,gid) for a number of safety checks
+              as described next.
+
+       <b>o</b>      The  non-indexed source file must exist (file name without ".db"
+              suffix). This file is needed as input for <a href="postmap.1.html">postmap(1)</a> or  <a href="postalias.1.html">postal-</a>
+              <a href="postalias.1.html">ias(1)</a>.  The  file  must be owned by "root" or by the above uid,
+              and must not allow "group" or "other" write access.
+
+       <b>o</b>      The parent directory must be owned by "root"  or  by  the  above
+              uid, and it must not allow "group" or "other" write access.
+
+       <b>o</b>      Additionally, the "<a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a>" param-
+              eter limits the source file directory prefixes that are  allowed
+              when  this  service needs to run <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> with
+              "root" privileges.
+
+       <b>o</b>      A  similar  parameter,  "<a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a>",
+              limits  the source file directory prefixes that are allowed when
+              this service needs to  run  <a href="postmap.1.html">postmap(1)</a>  or  <a href="postalias.1.html">postalias(1)</a>  as  an
+              unprivileged user.
+
+<b><a name="security">SECURITY</a></b>
+       The <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> server is security sensitive.  It accepts requests
+       only from processes that can access sockets under $<a href="postconf.5.html#queue_directory">queue_directory</a>/pri-
+       vate  (i.e.,  processes  that run with "root" or "<a href="postconf.5.html#mail_owner">mail_owner</a>" (usually,
+       postfix) privileges).
+
+       The threat is therefore a corrupted Postfix daemon process  that  wants
+       to  elevate privileges, by sending requests with crafted pathnames, and
+       racing against the service by quickly swapping  files  or  directories,
+       hoping  that Postfix will be tricked to overwrite a sensitive file with
+       attacker-controlled data.
+
+       When the service runs <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> as "root", such racing
+       attacks should not be possible if <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a>
+       specifies only prefixes that are already trusted.
+
+       This service could block all requests with crafted pathnames, if  given
+       complete  information  about  all  lookup  tables  that  are referenced
+       through Postfix configuration files. Unfortunately that information was
+       not available at the time that this program was needed.
+
+<b><a name="diagnostics">DIAGNOSTICS</a></b>
+       Problems  and  transactions are logged to syslogd(8) or <a href="postlogd.8.html">postlogd(8)</a>. If
+       an attempt to create an index file fails, this service will attempt  to
+       delete the incomplete file.
+
+<b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
+       Changes to <a href="postconf.5.html">main.cf</a> are not picked up automatically, as <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>
+       processes are long-lived. Use the command "postfix reload" after a con-
+       figuration change.
+
+       The  text  below provides only a parameter summary. See <a href="postconf.5.html">postconf(5)</a> for
+       more details including examples.
+
+<b><a name="service-specific_controls">SERVICE-SPECIFIC CONTROLS</a></b>
+       <b><a href="postconf.5.html#non_bdb_migration_level">non_bdb_migration_level</a> (disable)</b>
+              The non-Berkeley-DB migration service level.
+
+       <b><a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a> (see 'postconf -d  <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migra</a>-</b>
+       <b><a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">tion_allow_root_prefixes</a>' output)</b>
+              A list of trusted pathname prefixes that must  be  matched  when
+              the  non-Berkeley-DB  migration service (<a href="nbdb_reindexd.8.html"><b>nbdb_reindexd</b>(8)</a>) needs
+              to run <a href="postmap.1.html"><b>postmap</b>(1)</a> or <a href="postalias.1.html"><b>postalias</b>(1)</a> commands  with  "root"  privi-
+              lege.
+
+       <b><a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a>  (see 'postconf -d <a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migra</a>-</b>
+       <b><a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">tion_allow_user_prefixes</a>' output)</b>
+              A  list  of  trusted pathname prefixes that must be matched when
+              the non-Berkeley-DB migration service  (<a href="nbdb_reindexd.8.html"><b>nbdb_reindexd</b>(8)</a>)  needs
+              to  run <a href="postmap.1.html"><b>postmap</b>(1)</a> or <a href="postalias.1.html"><b>postalias</b>(1)</a> commands with non-root privi-
+              lege.
+
+<b><a name="miscellaneous_controls">MISCELLANEOUS CONTROLS</a></b>
+       <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  <a href="master.5.html">master.cf</a>  con-
+              figuration files.
+
+       <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
+              The process ID of a Postfix command or daemon process.
+
+       <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
+              The process name of a Postfix command or daemon process.
+
+       <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
+              The syslog facility of Postfix logging.
+
+       <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
+              A  prefix  that  is  prepended  to  the  process  name in syslog
+              records, so that, for example, "smtpd" becomes "prefix/smtpd".
+
+       <b><a href="postconf.5.html#service_name">service_name</a> (read-only)</b>
+              The <a href="master.5.html">master.cf</a> service name of a Postfix daemon process.
+
+<b><a name="see_also">SEE ALSO</a></b>
+       <a href="postfix-non-bdb.1.html">postfix-non-bdb(1)</a>, migration management
+       <a href="postconf.5.html">postconf(5)</a>, configuration parameters
+       <a href="postlogd.8.html">postlogd(8)</a>, Postfix logging
+       syslogd(8), system logging
+
+<b><a name="readme_files">README FILES</a></b>
+       <a href="NON_BERKELEYDB_README.html">NON_BERKELEYDB_README</a>, Non-Berkeley-DB migration guide
+
+<b><a name="license">LICENSE</a></b>
+       The Secure Mailer license must be distributed with this software.
+
+<b><a name="history">HISTORY</a></b>
+       This service was introduced with Postfix version 3.11.
+
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       porcupine.org
+
+                                                              NBDB_REINDEXD(8)
+</pre> </body> </html>
index 302915bb88b899a1fbc958e504c49a7ac43300ad..e06b69c61a396140f71aee1c1ea10805c714b70e 100644 (file)
@@ -16,37 +16,38 @@ NISPLUS_TABLE(5)                                              NISPLUS_TABLE(5)
        <b>postmap -q - "<a href="nisplus_table.5.html">nisplus</a>:[</b><i>name</i><b>=%s];</b><i>name.name.</i><b>"</b> &lt;<i>inputfile</i>
 
 <b><a name="description">DESCRIPTION</a></b>
-       The  Postfix mail system uses optional lookup tables.  These tables are
-       usually in <b>dbm</b> or <b>db</b> format.  Alternatively, lookup tables can be spec-
-       ified as NIS+ databases.
+       The Postfix mail system uses optional lookup tables.  rewriting or mail
+       routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>, or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>  for-
+       mat.
 
-       To  find  out  what types of lookup tables your Postfix system supports
-       use the "<b>postconf -m</b>" command.
+       Alternatively,  lookup  tables  can be specified as NIS+ databases.  To
+       find out what types of lookup tables your Postfix system  supports  use
+       the "<b>postconf -m</b>" command.
 
-       To test Postfix NIS+ lookup tables, use the  "<b>postmap  -q</b>"  command  as
+       To  test  Postfix  NIS+  lookup tables, use the "<b>postmap -q</b>" command as
        described in the SYNOPSIS above.
 
 <b><a name="query_syntax">QUERY SYNTAX</a></b>
-       Most  of the NIS+ query is specified via the NIS+ map name. The general
+       Most of the NIS+ query is specified via the NIS+ map name. The  general
        format of a Postfix NIS+ map name is as follows:
 
            <b><a href="nisplus_table.5.html">nisplus</a>:[</b><i>name</i><b>=%s];</b><i>name.name.name</i><b>.:</b><i>column</i>
 
-       Postfix NIS+ map names differ from what one  normally  would  use  with
+       Postfix  NIS+  map  names  differ from what one normally would use with
        commands such as <b>niscat</b>:
 
-       <b>o</b>      With  each  NIS+  table lookup, "<b>%s</b>" is replaced by a version of
-              the lookup string.  There can be only one  "<b>%s</b>"  instance  in  a
+       <b>o</b>      With each NIS+ table lookup, "<b>%s</b>" is replaced by  a  version  of
+              the  lookup  string.   There  can be only one "<b>%s</b>" instance in a
               Postfix NIS+ map name.
 
-       <b>o</b>      Postfix  NIS+ map names use "<b>;</b>" instead of "<b>,</b>", because the lat-
-              ter character is special in the Postfix <a href="postconf.5.html">main.cf</a>  file.   Postfix
-              replaces  "<b>;</b>"  characters  in  the map name by "<b>,</b>" before making
+       <b>o</b>      Postfix NIS+ map names use "<b>;</b>" instead of "<b>,</b>", because the  lat-
+              ter  character  is special in the Postfix <a href="postconf.5.html">main.cf</a> file.  Postfix
+              replaces "<b>;</b>" characters in the map name  by  "<b>,</b>"  before  making
               NIS+ queries.
 
-       <b>o</b>      The ":<i>column</i>" part in the NIS+ map  name  is  not  part  of  the
+       <b>o</b>      The  ":<i>column</i>"  part  in  the  NIS+  map name is not part of the
               actual NIS+ query. Instead, it specifies the number of the table
-              column that provides the lookup result.  When  no  ":<i>column</i>"  is
+              column  that  provides  the  lookup result. When no ":<i>column</i>" is
               specified the first column (1) is used.
 
 <b><a name="example">EXAMPLE</a></b>
index 887ccd7ba05c0d2216b92e8c494f661c18fe70e1..d66c90974984362b71df61107da8cfbc5aaff9bf 100644 (file)
@@ -20,8 +20,8 @@ PCRE_TABLE(5)                                                    PCRE_TABLE(5)
        <b>postmap -bmq - <a href="pcre_table.5.html">pcre</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
 <b><a name="description">DESCRIPTION</a></b>
-       The  Postfix  mail  system  uses optional tables for address rewriting,
-       mail routing, or access control. These tables are usually in <b>dbm</b> or  <b>db</b>
+       The  Postfix  mail system uses optional tables for address rewriting or
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
        format.
 
        Alternatively,  lookup tables can be specified in Perl Compatible Regu-
index cab95ff899608d095ae6b40a42786c1e4af7f825..09b5adc1bb5619fbc4c0315f76d04a7f711d71e5 100644 (file)
@@ -17,9 +17,13 @@ PGSQL_TABLE(5)                                                  PGSQL_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
+
+       Alternatively,  lookup tables can be specified as PostgreSQL databases.
+       To find out what types of lookup tables your  Postfix  system  supports
+       use the "<b>postconf -m</b>" command.
 
-       Alternatively, lookup tables can be specified as PostgreSQL  databases.
        In  order  to  use  PostgreSQL lookups, define a PostgreSQL source as a
        lookup table in <a href="postconf.5.html">main.cf</a>, for example:
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="pgsql_table.5.html">pgsql</a>:/etc/postfix/pgsql-aliases.cf
index b6ba86167ab76af0dd88cc004d16c4fc1313ad54..9892c15060e8bb02de606e14c8b754044574169b 100644 (file)
@@ -121,41 +121,41 @@ POSTALIAS(1)                                                      POSTALIAS(1)
               The database type. To find out what types are supported, use the
               "<b>postconf -m</b>" command.
 
-              The  <a href="postalias.1.html"><b>postalias</b>(1)</a> command can query any supported file type, but
+              When  no  <i>file</i><b>_</b><i>type</i> is specified, the software uses the database
+              type  specified  via  the  <b><a href="postconf.5.html#default_database_type">default_database_type</a></b>   configuration
+              parameter.   The default value for this parameter depends on the
+              host environment.
+
+              The <a href="postalias.1.html"><b>postalias</b>(1)</a> command can query any supported file type,  but
               it can create only the following file types:
 
-              <b>btree</b>  The output is a btree file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.  This  is
+              <b>btree</b>  The  output is a btree file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.  This is
                      available on systems with support for <b>db</b> databases.
 
-              <b>cdb</b>    The  output  is  one  file  named <i>file</i><b>_</b><i>name</i><b>.cdb</b>.  This is
+              <b>cdb</b>    The output is one  file  named  <i>file</i><b>_</b><i>name</i><b>.cdb</b>.   This  is
                      available on systems with support for <b>cdb</b> databases.
 
               <b>dbm</b>    The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
                      <i>file</i><b>_</b><i>name</i><b>.dir</b>.  This is available on systems with support
                      for <b>dbm</b> databases.
 
-              <b>fail</b>   A table that reliably fails all requests. The lookup  ta-
-                     ble  name  is used for logging only. This table exists to
+              <b>fail</b>   A  table that reliably fails all requests. The lookup ta-
+                     ble name is used for logging only. This table  exists  to
                      simplify Postfix error tests.
 
               <b>hash</b>   The output is a hashed file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.  This is
                      available on systems with support for <b>db</b> databases.
 
-              <b>lmdb</b>   The  output  is a btree-based file, named <i>file</i><b>_</b><i>name</i><b>.lmdb</b>.
-                     <b>lmdb</b> supports concurrent writes and reads from  different
+              <b>lmdb</b>   The output is a btree-based file,  named  <i>file</i><b>_</b><i>name</i><b>.lmdb</b>.
+                     <b>lmdb</b>  supports concurrent writes and reads from different
                      processes,  unlike  other  supported  file-based  tables.
-                     This is available on systems with support for <b>lmdb</b>  data-
+                     This  is available on systems with support for <b>lmdb</b> data-
                      bases.
 
               <b>sdbm</b>   The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
                      <i>file</i><b>_</b><i>name</i><b>.dir</b>.  This is available on systems with support
                      for <b>sdbm</b> databases.
 
-              When  no  <i>file</i><b>_</b><i>type</i> is specified, the software uses the database
-              type  specified  via  the  <b><a href="postconf.5.html#default_database_type">default_database_type</a></b>   configuration
-              parameter.   The default value for this parameter depends on the
-              host environment.
-
        <i>file</i><b>_</b><i>name</i>
               The name of the alias database source file when creating a data-
               base.
index f9558cceea8e8413daa6e7d888ea00d66122d84c..43e11a8dc16d546dd010f9ae7aa1b2cbb879c2f5 100644 (file)
@@ -12,7 +12,7 @@
 
 <script type="text/javascript">
 
-// Kludge for <a href="https://support.google.com/chrome/thread/11993079">https://support.google.com/chrome/thread/11993079</a>
+// See support.google.com/chrome/thread/11993079
 const isChrome = /Chrome/.test(navigator.userAgent)
     && /Google Inc/.test(navigator.vendor);
 const hash = window.location.hash;
@@ -259,7 +259,7 @@ Examples:
 
 <pre>
 <a href="postconf.5.html#address_verify_map">address_verify_map</a> = $<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>:$<a href="postconf.5.html#data_directory">data_directory</a>/verify_cache
-<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="DATABASE_README.html#types">hash</a>:/var/lib/postfix/verify_cache
+<a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="lmdb_table.5.html">lmdb</a>:/var/lib/postfix/verify_cache
 <a href="postconf.5.html#address_verify_map">address_verify_map</a> = <a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/verify_cache
 </pre>
 
@@ -622,10 +622,13 @@ Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#alias_database">alias_database</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/aliases
-<a href="postconf.5.html#alias_database">alias_database</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/mail/aliases
+<a href="postconf.5.html#alias_database">alias_database</a> = $<a href="postconf.5.html#default_database_type">default_database_type</a>:/etc/aliases
+<a href="postconf.5.html#alias_database">alias_database</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/aliases
+<a href="postconf.5.html#alias_database">alias_database</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/mail/aliases
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 
 </DD>
 
@@ -655,12 +658,6 @@ default is to search the local alias database, then the NIS alias
 database.
 </p>
 
-<p>
-If you change the alias database, run "<b>postalias /etc/aliases</b>"
-(or wherever your system stores the mail alias file), or simply
-run "<b>newaliases</b>" to build the necessary DBM or DB file.
-</p>
-
 <p>
 The <a href="local.8.html">local(8)</a> delivery agent disallows regular expression substitution
 of $1 etc. in <a href="postconf.5.html#alias_maps">alias_maps</a>, because that would open a security hole.
@@ -678,10 +675,26 @@ Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/aliases, nis:mail.aliases
-<a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/aliases
+<a href="postconf.5.html#alias_maps">alias_maps</a> = $<a href="postconf.5.html#default_database_type">default_database_type</a>:/etc/aliases, nis:mail.aliases
+<a href="postconf.5.html#alias_maps">alias_maps</a> = $<a href="postconf.5.html#default_database_type">default_database_type</a>:/etc/aliases
+<a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/mail/aliases
+<a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/aliases
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postalias <i>/path/to/aliases</i>" after you
+change the aliases file, to (re)build a default-type indexed file.
+Execute "postalias <i>type:/path/to/aliases</i>" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -1461,13 +1474,6 @@ until a match is found.
 Note: these lookups are recursive.
 </p>
 
-<p>
-If you use this feature, run "<b>postmap /etc/postfix/canonical</b>" to
-build the necessary DBM or DB file after every change. The changes
-will become visible after a minute or so.  Use "<b>postfix reload</b>"
-to eliminate the delay.
-</p>
-
 <p> Note: with Postfix version 2.2, message header address mapping
 happens only when message header address rewriting is enabled: </p>
 
@@ -1491,10 +1497,23 @@ Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="DATABASE_README.html#types">dbm</a>:/etc/postfix/canonical
-<a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/canonical
+<a href="postconf.5.html#canonical_maps">canonical_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/canonical
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/canonical" after you
+change the canonical file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/canonical" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -2040,7 +2059,7 @@ by default. </p>
 <p>
 The default database type for use in <a href="newaliases.1.html">newaliases(1)</a>, <a href="postalias.1.html">postalias(1)</a>
 and <a href="postmap.1.html">postmap(1)</a> commands. On many UNIX systems the default type is
-either <b>dbm</b> or <b>hash</b>. The default setting is frozen
+either <b>lmdb</b> or <b>hash</b>. The default setting is frozen
 when the Postfix system is built.
 </p>
 
@@ -2049,8 +2068,8 @@ Examples:
 </p>
 
 <pre>
+<a href="postconf.5.html#default_database_type">default_database_type</a> = lmdb
 <a href="postconf.5.html#default_database_type">default_database_type</a> = hash
-<a href="postconf.5.html#default_database_type">default_database_type</a> = dbm
 </pre>
 
 
@@ -6358,10 +6377,12 @@ system.  </p>
 <pre>
 <a href="postconf.5.html#local_header_rewrite_clients">local_header_rewrite_clients</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
     <a href="postconf.5.html#permit_sasl_authenticated">permit_sasl_authenticated</a> <a href="postconf.5.html#permit_tls_clientcerts">permit_tls_clientcerts</a>
-    <a href="postconf.5.html#check_address_map">check_address_map</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/pop-before-smtp
+    <a href="postconf.5.html#check_address_map">check_address_map</a> <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/pop-before-smtp
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 
 </DD>
 
@@ -8038,10 +8059,15 @@ tables if CIDR ranges are used. </p>
 <a href="postconf.5.html#mynetworks">mynetworks</a> = !192.168.0.1, 192.168.0.0/28
 <a href="postconf.5.html#mynetworks">mynetworks</a> = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:587::]/64
 <a href="postconf.5.html#mynetworks">mynetworks</a> = $<a href="postconf.5.html#config_directory">config_directory</a>/mynetworks
-<a href="postconf.5.html#mynetworks">mynetworks</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/network_table
+<a href="postconf.5.html#mynetworks">mynetworks</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/network_table
 <a href="postconf.5.html#mynetworks">mynetworks</a> = <a href="cidr_table.5.html">cidr</a>:/etc/postfix/network_table.cidr
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -8124,6 +8150,116 @@ Sendmail compatibility feature that specifies the location of the
 </p>
 
 
+</DD>
+
+<DT><b><a name="non_bdb_custom_mapping">non_bdb_custom_mapping</a>
+(default: empty)</b></DT><DD>
+
+<p> When non-Berkeley-DB migration is enabled, an optional mapping
+from a <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: type to a non-Berkeley-DB type. This mapping
+takes precedence over the default mapping from <a href="DATABASE_README.html#types">hash</a>: to
+$<a href="postconf.5.html#default_database_type">default_database_type</a>, and from <a href="DATABASE_README.html#types">btree</a>: to $<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>.
+</p>
+
+<ul>
+
+<li> <p> Specify a lookup table with a search keys that are a
+Berkeley DB <i>type</i> (without ':') or <i>type:name</i>. </p>
+
+<li> <p> A search key with the form <i>type:name</i> takes precedence
+over <i>type</i> (without ':'). </p>
+
+<li> <p>  The lookup result must always be a non-Berkeley-DB <i>type</i>
+(without ':') and must not contain a <i>:name</i>.  </p>
+
+<li> <p> The mapping table type must not be <b>hash</b> or <b>btree</b>.
+
+</ul>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
+</DD>
+
+<DT><b><a name="non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a>
+(default: see 'postconf -d <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a>' output)</b></DT><DD>
+
+<p> A list of trusted pathname prefixes that must be matched when
+the non-Berkeley-DB migration service (<a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>) needs to
+run <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> commands with "root" privilege.
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
+</DD>
+
+<DT><b><a name="non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a>
+(default: see 'postconf -d <a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a>' output)</b></DT><DD>
+
+<p> A list of trusted pathname prefixes that must be matched when
+the non-Berkeley-DB migration service (<a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>) needs to
+run <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> commands with non-root privilege. </p>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
+</DD>
+
+<DT><b><a name="non_bdb_migration_level">non_bdb_migration_level</a>
+(default: disable)</b></DT><DD>
+
+<p> The non-Berkeley-DB migration service level. You are expected to use
+the command "<b><a href="postfix-non-bdb.1.html">postfix non-bdb</a> <i>name-of-level</i></b>" to correctly
+configure the migration service level (see <a href="postfix-non-bdb.1.html">postfix-non-bdb(1)</a>. </p>
+
+<dl>
+
+<dt><b>disable</b></dt>
+
+<dd> <p> Disable all non-Berkeley-DB migration features. See
+<a href="NON_BERKELEYDB_README.html#disable">NON_BERKELEYDB_README</a> for possible negative implications
+for integration with other software such as mailman. </p> </dd>
+
+<dt><b>enable-redirect</b> (aliasing)</dt>
+
+<dd> <p> Enable redirection (aliasing) from Berkeley DB hash to
+$<a href="postconf.5.html#default_database_type">default_database_type</a>, and from Berkeley DB btree to
+$<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>, but do not automatically create the new cdb
+or lmdb indexed database files that Postfix programs need. See
+<a href="NON_BERKELEYDB_README.html#enable-redirect">NON_BERKELEYDB_README</a> for details and limitations.
+</p> </dd>
+
+<dt><b>enable-reindex</b></dt>
+
+<dd> <p> In addition to enable-redirect, also create a non-Berkeley-DB
+indexed database file when a daemon program wants to access a file
+that does not yet exist. This feature uses the <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>
+daemon to run <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>.   See
+<a href="NON_BERKELEYDB_README.html#enable-reindex">NON_BERKELEYDB_README</a> for details and limitations.
+</p>
+
+<p> <i> NOTE: <b>enable-reindex</b> should be used only temporarily to
+generate most of the non-Berkeley-DB indexed database files that Postfix
+programs need. Leaving this level enabled may expose the system to
+privilege-escalation attacks. There are no security concerns for using
+<b>enable-redirect</b>. </i> </p> </dd>
+
+</dl>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
+</DD>
+
+<DT><b><a name="non_bdb_migration_service_name">non_bdb_migration_service_name</a>
+(default: nbdb_reindex)</b></DT><DD>
+
+<p> The name of a <a href="master.5.html">master.cf</a> service that implements the non-Berkeley-DB
+migration service protocol. </p>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
 </DD>
 
 <DT><b><a name="non_empty_end_of_header_action">non_empty_end_of_header_action</a>
@@ -8155,7 +8291,7 @@ to=&lt;<i>recipient</i>&gt;
 </pre>
 </dd>
 
-<dl>
+</dl>
 
 <p> This feature is available in Postfix &ge; 3.11. </p>
 
@@ -8734,8 +8870,8 @@ The default time unit is h (hours).  </p>
 <p> Persistent storage for the <a href="postscreen.8.html">postscreen(8)</a> server decisions. </p>
 
 <p> To share a <a href="postscreen.8.html">postscreen(8)</a> cache between multiple <a href="postscreen.8.html">postscreen(8)</a>
-instances, use "<a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/path/to/file"
-or "<a href="proxymap.8.html">proxy</a>:<a href="lmdb_table.5.html">lmdb</a>:/path/to/file".
+instances, use "<a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="proxymap.8.html">proxy</a>:<a href="lmdb_table.5.html">lmdb</a>:/path/to/file"
+or "<a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/path/to/file".
 This requires Postfix version 2.9 or later; earlier <a href="proxymap.8.html">proxymap(8)</a>
 implementations don't support cache cleanup. For an alternative
 approach see the <a href="memcache_table.5.html">memcache_table(5)</a> manpage. </p>
@@ -10049,7 +10185,7 @@ syntax.
 
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/rbl_reply
+    <a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/rbl_reply
     <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
         <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
         <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11],
@@ -10071,6 +10207,8 @@ syntax.
         554 $rbl_class $rbl_what blocked using ZEN - see <a href="https://www.spamhaus.org/query/ip/$client_address">https://www.spamhaus.org/query/ip/$client_address</a> for details
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p>
 NOTE: This feature differs from <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> where
 the table search key is only a domain name (no "<i>=address-filter</i>",
@@ -10078,6 +10216,18 @@ no "<i>*weight</i>" factor) and where the lookup result
 should be only a domain name (no free text, no <i>$name</i> variables).
 </p>
 
+<p> Execute the command "postmap /etc/postfix/rbl_reply" after you
+change the rbl_reply file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/rbl_reply" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p>
 This feature is available in Postfix 2.0 and later.
 The "=address-filter" feature is available in Postfix 2.8 and later.
@@ -10225,12 +10375,22 @@ Example:
 </p>
 
 <pre>
-<a href="postconf.5.html#recipient_bcc_maps">recipient_bcc_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/recipient_bcc
+<a href="postconf.5.html#recipient_bcc_maps">recipient_bcc_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/recipient_bcc
 </pre>
 
-<p>
-After a change, run "<b>postmap /etc/postfix/recipient_bcc</b>".
-</p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/recipient_bcc" after
+you change the recipient_bcc file, to (re)build a default-type indexed
+file.  Execute "postmap <i>type</i>:/etc/postfix/recipient_bcc" to
+specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
 
 <p>
 This feature is available in Postfix 2.1 and later.
@@ -10273,9 +10433,24 @@ Example:
 </p>
 
 <pre>
-<a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/recipient_canonical
+<a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/recipient_canonical
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/recipient_canonical"
+after you change the recipient_canonical file, to (re)build a
+default-type indexed file.  Execute "postmap
+<i>type</i>:/etc/postfix/recipient_canonical" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -10400,13 +10575,27 @@ D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home </p>
 <p> Example: </p>
 
 <pre>
-<a href="postconf.5.html#relay_clientcerts">relay_clientcerts</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relay_clientcerts
+<a href="postconf.5.html#relay_clientcerts">relay_clientcerts</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relay_clientcerts
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p>For more fine-grained control, use <a href="postconf.5.html#check_ccert_access">check_ccert_access</a> to select
 an appropriate <a href="access.5.html">access(5)</a> policy for each client.
 See <a href="RESTRICTION_CLASS_README.html">RESTRICTION_CLASS_README</a>.</p>
 
+<p> Execute the command "postmap /etc/postfix/relay_clientcerts"
+after you change the <a href="postconf.5.html#relay_clientcerts">relay_clientcerts</a> file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/relay_clientcerts"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p>This feature is available with Postfix version 2.2.</p>
 
 
@@ -10527,9 +10716,23 @@ Example:
 </p>
 
 <pre>
-<a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relay_recipients
+<a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relay_recipients
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relay_recipients"
+after you change the relay_recipients file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/relay_recipients"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p>
 This feature is available in Postfix 2.0 and later.
 </p>
@@ -10663,21 +10866,28 @@ whitespace or comma. Tables will be searched in the specified order
 until a match is found.
 </p>
 
-<p>
-If you use this feature, run "<b>postmap /etc/postfix/relocated</b>" to
-build the necessary DBM or DB file after change, then "<b>postfix
-reload</b>" to make the changes visible.
-</p>
-
 <p>
 Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#relocated_maps">relocated_maps</a> = <a href="DATABASE_README.html#types">dbm</a>:/etc/postfix/relocated
-<a href="postconf.5.html#relocated_maps">relocated_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relocated
+<a href="postconf.5.html#relocated_maps">relocated_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relocated
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/relocated" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -10695,13 +10905,29 @@ Example:
 
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#relocated_maps">relocated_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relocated
+    <a href="postconf.5.html#relocated_maps">relocated_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/relocated
     <a href="postconf.5.html#relocated_prefix_enable">relocated_prefix_enable</a> = no
 <br>
-<a href="DATABASE_README.html#types">hash</a>:/etc/postfix/relocated:
+/etc/postfix/relocated:
     user@example.com 5.2.1 User account is disabled
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/relocated" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
+<p> This feature is available in Postfix 3.11 and later. </p>
+
 
 </DD>
 
@@ -11078,12 +11304,22 @@ Example:
 </p>
 
 <pre>
-<a href="postconf.5.html#sender_bcc_maps">sender_bcc_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_bcc
+<a href="postconf.5.html#sender_bcc_maps">sender_bcc_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sender_bcc
 </pre>
 
-<p>
-After a change, run "<b>postmap /etc/postfix/sender_bcc</b>".
-</p>
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/sender_bcc" after you
+change the sender_bcc file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/sender_bcc" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
 
 <p>
 This feature is available in Postfix 2.1 and later.
@@ -11131,9 +11367,23 @@ Example:
 </p>
 
 <pre>
-<a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_canonical
+<a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/sender_canonical
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/sender_canonical"
+after you change the sender_canonical file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/sender_canonical"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -11468,7 +11718,7 @@ SMTP servers that reject recipients after the DATA command. Use
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
+    <a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
 </pre>
 </blockquote>
 
@@ -11490,10 +11740,24 @@ SMTP servers that reject recipients after the DATA command. Use
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> Unselective use of the "data" target does no harm, but will
 result in unnecessary "lost connection after DATA" events at remote
 SMTP/LMTP servers. </p>
 
+<p> Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/transport" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 3.0 and later.  </p>
 
 
@@ -12909,7 +13173,7 @@ A non-ASCII next-hop destination is converted into ASCII form
 (Punycode) before making a policy query; lookup tables must answer
 ASCII-form queries. </p>
 
-<li> <p> A fixed-string table (such as <a href="DATABASE_README.html#types">hash</a>:, <a href="DATABASE_README.html#types">btree</a>:, or <a href="lmdb_table.5.html">lmdb</a>:) is
+<li> <p> A fixed-string table (such as <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, or <a href="DATABASE_README.html#types">hash</a>:) is
 also searched with the next-hop ".parent" domains (in a table key,
 prepend a '.' to a parent domain name). These ".parent" domain
 queries are not made with pattern-based lookup tables such as <a href="regexp_table.5.html">regexp</a>:
@@ -12986,7 +13250,7 @@ REQUIRETLS support, but the support is inoperable. </p></dd>
 <li> <p> To match any name below the domain "example.com" specify
 a table entry with the storage key ".example.com" in <a href="DATABASE_README.html">type:table</a>
 lookup tables that need an exact match. This is appropriate, for
-example, with <a href="DATABASE_README.html#types">hash</a>:, <a href="DATABASE_README.html#types">btree</a>: or <a href="lmdb_table.5.html">lmdb</a>:. </p>
+example, with <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>: or <a href="DATABASE_README.html#types">hash</a>:. </p>
 
 <li> <p> Do not specify a match pattern for ".domain" with <a href="regexp_table.5.html">regexp</a>:,
 <a href="pcre_table.5.html">pcre</a>:, <a href="socketmap_table.html">socketmap</a>:, or <a href="tcp_table.5.html">tcp</a>:, as <a href="postconf.5.html#smtp_requiretls_policy">smtp_requiretls_policy</a> will
@@ -13087,7 +13351,7 @@ file for easier maintenance. </p>
         <a href="cidr_table.5.html">cidr</a>:{
             { 0.0.0.0/0 opportunistic },
             { ::/0 opportunistic } },
-        <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/requiretls-per-site
+        <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/requiretls-per-site
         opportunistic+starttls
 </pre>
 <pre>
@@ -13098,6 +13362,21 @@ file for easier maintenance. </p>
     ...
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/requiretls-per-site"
+after you change the requiretls-per-site file, to (re)build a
+default-type indexed file.  Execute "postmap
+<i>type</i>:/etc/postfix/requiretls-per-site" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 </ul>
 
 <p>
@@ -13176,8 +13455,8 @@ passwords, and requires that Postfix is compiled with TLS support.
 <p> Examples: </p>
 
 <pre>
-<a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/sasl_auth_cache
 <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> = <a href="proxymap.8.html">proxy</a>:<a href="lmdb_table.5.html">lmdb</a>:/var/lib/postfix/sasl_auth_cache
+<a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> = <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/sasl_auth_cache
 </pre>
 
 <p> This feature is available in Postfix 2.5 and later. </p>
@@ -14247,7 +14526,7 @@ As in the example above, we show two matching fingerprints: </p>
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/tls_policy
+    <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/tls_policy
     <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> = sha256
 </pre>
 </blockquote>
@@ -14261,6 +14540,20 @@ As in the example above, we show two matching fingerprints: </p>
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/tls_policy" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
@@ -14904,7 +15197,7 @@ Example:
 
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/tls_policy
+    <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/tls_policy
     # Postfix 2.5 and later.
     #
     # The default digest is sha256 with Postfix &ge; 3.6 and
@@ -14928,12 +15221,26 @@ Example:
         match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
 <p> <b>Note:</b> The "hostname" strategy if listed in a non-default
 setting of <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> or in the "match" attribute
 in the policy table can 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. </p>
 
+<p> Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/tls_policy" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
@@ -15298,7 +15605,7 @@ as needed. </p>
 
 <p> Name of the file containing the optional Postfix SMTP client
 TLS session cache. Specify a database type that supports enumeration,
-such as <b>btree</b> or <b>sdbm</b>; there is no need to support
+such as <b>lmdb</b> or <b>btree</b>; there is no need to support
 concurrent access.  The file is created if it does not exist. The <a href="smtp.8.html">smtp(8)</a>
 daemon does not use this parameter directly, rather the cache is
 implemented indirectly in the <a href="tlsmgr.8.html">tlsmgr(8)</a> daemon. This means that
@@ -15321,8 +15628,8 @@ under a non-Postfix directory is redirected to the Postfix-owned
 <p> Example: </p>
 
 <pre>
-<a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> = <a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/smtp_scache
 <a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> = <a href="lmdb_table.5.html">lmdb</a>:/var/lib/postfix/smtp_scache
+<a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> = <a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/smtp_scache
 </pre>
 
 <p> This feature is available in Postfix 2.2 and later.  </p>
@@ -18934,9 +19241,23 @@ Examples:
 <pre>
 <a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> = <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
 <a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> = <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>,
-    <a href="postconf.5.html#check_sender_access">check_sender_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/access
+    <a href="postconf.5.html#check_sender_access">check_sender_access</a> <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/access
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/access" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -19828,7 +20149,7 @@ higher. </p>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
     <a href="postconf.5.html#smtpd_tls_fingerprint_digest">smtpd_tls_fingerprint_digest</a> = sha256
     <a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> =
-        <a href="postconf.5.html#check_ccert_access">check_ccert_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/access,
+        <a href="postconf.5.html#check_ccert_access">check_ccert_access</a> <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/access,
         reject
 </pre>
 <pre>
@@ -19841,6 +20162,20 @@ higher. </p>
 </pre>
 </blockquote>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/access" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
@@ -20245,8 +20580,8 @@ this TLS extension.  See also <a href="postconf.5.html#smtpd_tls_session_cache_t
 <p> Examples: </p>
 
 <pre>
-<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> = <a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/smtpd_scache
 <a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> = <a href="lmdb_table.5.html">lmdb</a>:/var/lib/postfix/smtpd_scache
+<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> = <a href="DATABASE_README.html#types">btree</a>:/var/lib/postfix/smtpd_scache
 </pre>
 
 <p> This feature is available in Postfix 2.2 and later.  </p>
@@ -22664,9 +22999,7 @@ $<a href="postconf.5.html#sender_dependent_default_transport_maps">sender_depend
 <p>
 Specify zero or more "<a href="DATABASE_README.html">type:table</a>" lookup tables, separated by
 whitespace or comma. Tables will be searched in the specified order
-until a match is found.  If you use this
-feature with local files, run "<b>postmap /etc/postfix/transport</b>"
-after making a change.  </p>
+until a match is found.  </p>
 
 <p> Pattern matching of domain names is controlled by the presence
 or absence of "<a href="postconf.5.html#transport_maps">transport_maps</a>" in the <a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a>
@@ -22680,10 +23013,23 @@ Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">dbm</a>:/etc/postfix/transport
-<a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/transport
+<a href="postconf.5.html#transport_maps">transport_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/transport
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/transport" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
@@ -23394,20 +23740,28 @@ until a match is found.
 Note: these lookups are recursive.
 </p>
 
-<p>
-If you use this feature with indexed files, run "<b>postmap
-/etc/postfix/virtual</b>" after changing the file.
-</p>
-
 <p>
 Examples:
 </p>
 
 <pre>
-<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">dbm</a>:/etc/postfix/virtual
-<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
+<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="lmdb_table.5.html">lmdb</a>:/etc/postfix/virtual
 </pre>
 
+<p> Instead of <a href="lmdb_table.5.html">lmdb</a>:, some systems use <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>:. </p>
+
+<p> Execute the command "postmap /etc/postfix/virtual" after you
+change the virtual file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/virtual" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+<a href="postconf.5.html#default_database_type">default_database_type</a> parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 
 </DD>
 
index 4525e7d46b2b9d347c4c97d38aa86605be137481..25cc3ec448388e2b7a8be361e80d9ca8c7fe5307 100644 (file)
@@ -89,6 +89,8 @@ the following convention:  </p>
 
 <li> <a href="postfix.1.html">postfix(1)</a>, Postfix control program 
 
+<li> <a href="postfix-non-bdb.1.html">postfix-non-bdb(1)</a>, Postfix Non-Berkeley-DB migration 
+
 <li> <a href="postfix-tls.1.html">postfix-tls(1)</a>, Postfix TLS management 
 
 <li> <a href="postkick.1.html">postkick(1)</a>, trigger Postfix daemon 
diff --git a/postfix/html/postfix-non-bdb.1.html b/postfix/html/postfix-non-bdb.1.html
new file mode 100644 (file)
index 0000000..08775c7
--- /dev/null
@@ -0,0 +1,137 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "https://www.w3.org/TR/html4/loose.dtd">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel='stylesheet' type='text/css' href='postfix-doc.css'>
+<title> Postfix manual - postfix-non-bdb(1) </title>
+</head> <body> <pre>
+POSTFIX-NON-BDB(1)                                          POSTFIX-NON-BDB(1)
+
+<b><a name="name">NAME</a></b>
+       postfix-non-bdb - Postfix non-Berkeley-DB migration
+
+<b><a name="synopsis">SYNOPSIS</a></b>
+       <b><a href="postfix-non-bdb.1.html">postfix non-bdb</a></b> <i>subcommand</i>
+
+<b><a name="description">DESCRIPTION</a></b>
+       The  "<b>postfix  non-bdb</b> <i>subcommand</i>" feature edits <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a>,
+       to manage the migration of an existing Postfix configuration that  uses
+       Berkeley  DB  type "<a href="DATABASE_README.html#types">hash</a>:" or "<a href="DATABASE_README.html#types">btree</a>:" tables (which are no longer sup-
+       ported on some OS distributions), to supported types such as "<a href="CDB_README.html">cdb</a>:"  or
+       "<a href="lmdb_table.5.html">lmdb</a>:".
+
+       The following subcommands are available:
+
+       <b>status</b> Reports the non-Berkeley-DB migration status, without making any
+              changes.
+
+       <b>disable</b>
+              Edits <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a>, to turn off the <b>enable-redirect</b> and
+              <b>enable-reindex</b> features.
+
+              This  will break integration with other software such as mailman
+              versions from before May 2025 when they  want  to  use  "postmap
+              <a href="DATABASE_README.html#types">hash</a>:/path/to/file", for example, to update a mailman-maintained
+              table.
+
+       <b>enable-redirect</b> (aliasing)
+              Edits <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a>, to  enable  redirection  (aliasing)
+              from Berkeley DB types "hash" and "btree" to the non-Berkeley-DB
+              types     specified     with     $<a href="postconf.5.html#default_database_type">default_database_type</a>      and
+              $<a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a>.  Custom  redirection  may  be configured
+              with <a href="postconf.5.html#non_bdb_custom_mapping">non_bdb_custom_mapping</a>.
+
+              This configuration will not automatically create non-Berkeley-DB
+              indexed  database  files.  Instead, Postfix programs will log an
+              error as they fail to open an indexed database  file,  and  will
+              leave  it  to  the  system  administrator  to  run <a href="postmap.1.html">postmap(1)</a> or
+              <a href="postalias.1.html">postalias(1)</a> to create that file.
+
+              This will fix integration with other software  such  as  mailman
+              versions  from  before  May  2025 when they want to use "postmap
+              <a href="DATABASE_README.html#types">hash</a>:/path/to/file", for example, to update a mailman-maintained
+              table.
+
+              This  subcommand  will  not  make any changes when <a href="postconf.5.html#default_database_type">default_data</a>-
+              <a href="postconf.5.html#default_database_type">base_type</a> or <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> specify  a  <a href="DATABASE_README.html#types">hash</a>:  or  <a href="DATABASE_README.html#types">btree</a>:
+              type.
+
+       <b>enable-reindex</b>
+              Edits  <a href="postconf.5.html">main.cf</a>  and <a href="master.5.html">master.cf</a>, to implement <b>enable-redirect</b>, and
+              to automatically create a non-Berkeley-DB indexed database  file
+              when  a  daemon program wants to access a file that does not yet
+              exist. This uses the <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> daemon to  run  <a href="postmap.1.html">postmap(1)</a>
+              or <a href="postalias.1.html">postalias(1)</a> as described in "SECURITY" below.
+
+              This  subcommand  immediately  generates non-Berkeley-DB indexed
+              files for unprivileged command-line programs  that  cannot  send
+              requests  to  the  <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> daemon server. This involves
+              "<a href="DATABASE_README.html#types">hash</a>:" and "<a href="DATABASE_README.html#types">btree</a>:" tables that are used  by  <a href="postqueue.1.html">postqueue(1)</a>  and
+              <a href="sendmail.1.html">sendmail(1)</a>  as  specified  in <a href="postconf.5.html#authorized_flush_users">authorized_flush_users</a> and <a href="postconf.5.html#authorized_mailq_users">autho</a>-
+              <a href="postconf.5.html#authorized_mailq_users">rized_mailq_users</a>, and by <a href="sendmail.1.html">sendmail(1)</a> and <a href="postdrop.1.html">postdrop(1)</a> as  speci-
+              fied in <a href="postconf.5.html#authorized_submit_users">authorized_submit_users</a> and <a href="postconf.5.html#local_login_sender_maps">local_login_sender_maps</a>.
+
+              This  subcommand  will  not  make any changes when <a href="postconf.5.html#default_database_type">default_data</a>-
+              <a href="postconf.5.html#default_database_type">base_type</a> or <a href="postconf.5.html#default_cache_db_type">default_cache_db_type</a> specify  a  <a href="DATABASE_README.html#types">hash</a>:  or  <a href="DATABASE_README.html#types">btree</a>:
+              type.
+
+              <i>NOTE:</i> <b>enable-reindex</b> <i>should be used only temporarily to generate</i>
+              <i>most of the non-Berkeley-DB indexed files  that  Postfix  needs.</i>
+              <i>Leaving  this enabled may expose the system to privilege-escala-</i>
+              <i>tion  attacks.  There  are  no  security  concerns   for   using</i>
+              <b>enable-redirect</b>.
+
+<b><a name="security">SECURITY</a></b>
+       The  <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>  daemon automatically generates a non-Berkeley-DB
+       indexed file only if the database pathname matches the  directory  pre-
+       fixes  specified  with <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a> (for files
+       that must be owned by root), or with  <a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_pre</a>-
+       <a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">fixes</a>  (for  files  that  must be owned by a non-root user). Additional
+       restrictions on file and directory ownership and permissions are  docu-
+       mented in <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a>.
+
+<b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
+       The "<b><a href="postfix-non-bdb.1.html">postfix non-bdb</a></b> <i>subcommand</i>" feature updates the following configu-
+       ration parameter:
+
+       <b><a href="postconf.5.html#non_bdb_migration_level">non_bdb_migration_level</a> (disable)</b>
+              The non-Berkeley-DB migration service level.
+
+       Other relevant parameters:
+
+       <b><a href="postconf.5.html#non_bdb_custom_mapping">non_bdb_custom_mapping</a> (empty)</b>
+              When non-Berkeley-DB migration is enabled, an  optional  mapping
+              from a <a href="DATABASE_README.html#types">hash</a>: or <a href="DATABASE_README.html#types">btree</a>: type to a non-Berkeley-DB type.
+
+       <b><a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migration_allow_root_prefixes</a>  (see 'postconf -d <a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">non_bdb_migra</a>-</b>
+       <b><a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">tion_allow_root_prefixes</a>' output)</b>
+              A  list  of  trusted pathname prefixes that must be matched when
+              the non-Berkeley-DB migration service  (<a href="nbdb_reindexd.8.html"><b>nbdb_reindexd</b>(8)</a>)  needs
+              to  run  <a href="postmap.1.html"><b>postmap</b>(1)</a>  or <a href="postalias.1.html"><b>postalias</b>(1)</a> commands with "root" privi-
+              lege.
+
+       <b><a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migration_allow_user_prefixes</a> (see 'postconf -d  <a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">non_bdb_migra</a>-</b>
+       <b><a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">tion_allow_user_prefixes</a>' output)</b>
+              A list of trusted pathname prefixes that must  be  matched  when
+              the  non-Berkeley-DB  migration service (<a href="nbdb_reindexd.8.html"><b>nbdb_reindexd</b>(8)</a>) needs
+              to run <a href="postmap.1.html"><b>postmap</b>(1)</a> or <a href="postalias.1.html"><b>postalias</b>(1)</a> commands with non-root  privi-
+              lege.
+
+<b><a name="see_also">SEE ALSO</a></b>
+       <a href="nbdb_reindexd.8.html">nbdb_reindexd(8)</a> reindexing service
+
+<b><a name="readme_files">README FILES</a></b>
+       <a href="NON_BERKELEYDB_README.html">NON_BERKELEYDB_README</a>, migration guide
+
+<b><a name="license">LICENSE</a></b>
+       The Secure Mailer license must be distributed with this software.
+
+<b><a name="history">HISTORY</a></b>
+       The "<b><a href="postfix-non-bdb.1.html">postfix non-bdb</a></b>" command was introduced with Postfix version 3.11.
+
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       porcupine.org
+
+                                                            POSTFIX-NON-BDB(1)
+</pre> </body> </html>
index 73c33598c3e860f6f7488a5e7d5fa787978b9258..791e0543a39fd5c900403b306c641411c99499a1 100644 (file)
@@ -97,7 +97,14 @@ POSTFIX(1)                                                          POSTFIX(1)
               command specified with $<a href="postconf.5.html#maillog_file_compressor">maillog_file_compressor</a>.  This will  not
               rotate /dev/* files.
 
-              This feature is available in Postfix 3.4 and later.
+       <b>non-bdb</b> <i>subcommand</i>
+              Migrate  a  Postfix configuration that uses Berkeley DB <a href="DATABASE_README.html#types">hash</a>: or
+              <a href="DATABASE_README.html#types">btree</a>: tables, to a configuration that uses <a href="lmdb_table.5.html">lmdb</a>: or a  combina-
+              tion of <a href="CDB_README.html">cdb</a>: and <a href="lmdb_table.5.html">lmdb</a>:. This is needed because some (Linux) dis-
+              tributions  have  removed  Berkeley  DB  support.    See   post-
+              fix-nbdb(1) for documentation.
+
+              This feature is available in Postfix 3.11 and later.
 
        <b>tls</b> <i>subcommand</i>
               Enable  opportunistic  TLS in the Postfix SMTP client or server,
@@ -326,6 +333,7 @@ POSTFIX(1)                                                          POSTFIX(1)
        <a href="postconf.1.html">postconf(1)</a>, Postfix configuration utility
        <a href="postdrop.1.html">postdrop(1)</a>, Postfix mail posting utility
        <a href="postfix.1.html">postfix(1)</a>, Postfix control program
+       <a href="postfix-non-bdb.1.html">postfix-non-bdb(1)</a>, Postfix Non-Berkeley-DB migration
        <a href="postfix-tls.1.html">postfix-tls(1)</a>, Postfix TLS management
        <a href="postkick.1.html">postkick(1)</a>, trigger Postfix daemon
        <a href="postlock.1.html">postlock(1)</a>, Postfix-compatible locking
index ed0d8b28f6a4c70379be450a37059367f2461f2c..7640579f4993e138c988317d6fa8dba6b59883f4 100644 (file)
@@ -199,54 +199,55 @@ POSTMAP(1)                                                          POSTMAP(1)
               The database type. To find out what types are supported, use the
               "<b>postconf -m</b>" command.
 
+              When  no  <i>file</i><b>_</b><i>type</i> is specified, the software uses the database
+              type  specified  via  the  <b><a href="postconf.5.html#default_database_type">default_database_type</a></b>   configuration
+              parameter.   The default value for this parameter depends on the
+              host environment.
+
               The <a href="postmap.1.html"><b>postmap</b>(1)</a> command can query any supported file type, but it
               can create only the following file types:
 
-              <b>btree</b>  The output file is  a  btree  file,  named  <i>file</i><b>_</b><i>name</i><b>.db</b>.
-                     This  is  available  on systems with support for <b>db</b> data-
+              <b>btree</b>  The  output  file  is  a  btree file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
+                     This is available on systems with support  for  <b>db</b>  data-
                      bases.
 
-              <b>cdb</b>    The output consists of  one  file,  named  <i>file</i><b>_</b><i>name</i><b>.cdb</b>.
-                     This  is  available on systems with support for <b>cdb</b> data-
+              <b>cdb</b>    The  output  consists  of  one file, named <i>file</i><b>_</b><i>name</i><b>.cdb</b>.
+                     This is available on systems with support for  <b>cdb</b>  data-
                      bases.
 
               <b>dbm</b>    The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
                      <i>file</i><b>_</b><i>name</i><b>.dir</b>.  This is available on systems with support
                      for <b>dbm</b> databases.
 
-              <b>fail</b>   A table that reliably fails all requests. The lookup  ta-
-                     ble  name  is used for logging only. This table exists to
+              <b>fail</b>   A  table that reliably fails all requests. The lookup ta-
+                     ble name is used for logging only. This table  exists  to
                      simplify Postfix error tests.
 
-              <b>hash</b>   The output file is a  hashed  file,  named  <i>file</i><b>_</b><i>name</i><b>.db</b>.
-                     This  is  available  on systems with support for <b>db</b> data-
+              <b>hash</b>   The  output  file  is  a hashed file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
+                     This is available on systems with support  for  <b>db</b>  data-
                      bases.
 
-              <b>lmdb</b>   The output is a btree-based file,  named  <i>file</i><b>_</b><i>name</i><b>.lmdb</b>.
-                     <b>lmdb</b>  supports concurrent writes and reads from different
+              <b>lmdb</b>   The  output  is a btree-based file, named <i>file</i><b>_</b><i>name</i><b>.lmdb</b>.
+                     <b>lmdb</b> supports concurrent writes and reads from  different
                      processes,  unlike  other  supported  file-based  tables.
-                     This  is available on systems with support for <b>lmdb</b> data-
+                     This is available on systems with support for <b>lmdb</b>  data-
                      bases.
 
               <b>sdbm</b>   The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
                      <i>file</i><b>_</b><i>name</i><b>.dir</b>.  This is available on systems with support
                      for <b>sdbm</b> databases.
 
-              When no <i>file</i><b>_</b><i>type</i> is specified, the software uses  the  database
-              type   specified  via  the  <b><a href="postconf.5.html#default_database_type">default_database_type</a></b>  configuration
-              parameter.
-
        <i>file</i><b>_</b><i>name</i>
               The name of the lookup table source file when rebuilding a data-
               base.
 
 <b><a name="diagnostics">DIAGNOSTICS</a></b>
-       Problems  are  logged to the standard error stream and to <b>syslogd</b>(8) or
+       Problems are logged to the standard error stream and to  <b>syslogd</b>(8)  or
        <a href="postlogd.8.html"><b>postlogd</b>(8)</a>.  No output means that no problems were detected. Duplicate
        entries are skipped and are flagged with a warning.
 
        <a href="postmap.1.html"><b>postmap</b>(1)</a> terminates with zero exit status in case of success (includ-
-       ing successful "<b>postmap -q</b>" lookup) and terminates with  non-zero  exit
+       ing  successful  "<b>postmap -q</b>" lookup) and terminates with non-zero exit
        status in case of failure.
 
 <b><a name="environment">ENVIRONMENT</a></b>
@@ -257,12 +258,12 @@ POSTMAP(1)                                                          POSTMAP(1)
               Enable verbose logging for debugging purposes.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
-       gram.  The text below provides only  a  parameter  summary.  See  <a href="postconf.5.html"><b>post-</b></a>
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to  this  pro-
+       gram.   The  text  below  provides  only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
        <a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
 
        <b><a href="postconf.5.html#berkeley_db_create_buffer_size">berkeley_db_create_buffer_size</a> (16777216)</b>
-              The  per-table I/O buffer size for programs that create Berkeley
+              The per-table I/O buffer size for programs that create  Berkeley
               DB hash or btree tables.
 
        <b><a href="postconf.5.html#berkeley_db_read_buffer_size">berkeley_db_read_buffer_size</a> (131072)</b>
@@ -270,7 +271,7 @@ POSTMAP(1)                                                          POSTMAP(1)
               hash or btree tables.
 
        <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 <a href="master.5.html">master.cf</a> con-
+              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
               figuration files.
 
        <b><a href="postconf.5.html#default_database_type">default_database_type</a> (see 'postconf -d' output)</b>
@@ -278,19 +279,19 @@ POSTMAP(1)                                                          POSTMAP(1)
               and <a href="postmap.1.html"><b>postmap</b>(1)</a> commands.
 
        <b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
-              The  list  of  environment  variables  that a privileged Postfix
-              process will  import  from  a  non-Postfix  parent  process,  or
+              The list of environment  variables  that  a  privileged  Postfix
+              process  will  import  from  a  non-Postfix  parent  process, or
               name=value environment overrides.
 
        <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
-              Enable  preliminary SMTPUTF8 support for the protocols described
+              Enable preliminary SMTPUTF8 support for the protocols  described
               in <a href="https://tools.ietf.org/html/rfc6531">RFC 6531</a>, <a href="https://tools.ietf.org/html/rfc6532">RFC 6532</a>, and <a href="https://tools.ietf.org/html/rfc6533">RFC 6533</a>.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              A prefix that  is  prepended  to  the  process  name  in  syslog
+              A  prefix  that  is  prepended  to  the  process  name in syslog
               records, so that, for example, "smtpd" becomes "prefix/smtpd".
 
        Available in Postfix 2.11 and later:
index e3798eea8a45b74bbd8ab9e5640a15c6c954ebf2..43c3fd7a228f56d471c793fccff6e6a8e430db36 100644 (file)
@@ -16,8 +16,8 @@ REGEXP_TABLE(5)                                                REGEXP_TABLE(5)
        <b>postmap -q - <a href="regexp_table.5.html">regexp</a>:/etc/postfix/</b><i>filename</i> &lt;<i>inputfile</i>
 
 <b><a name="description">DESCRIPTION</a></b>
-       The  Postfix  mail  system  uses optional tables for address rewriting,
-       mail routing, or access control. These tables are usually in <b>dbm</b> or  <b>db</b>
+       The  Postfix  mail system uses optional tables for address rewriting or
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
        format.
 
        Alternatively,  lookup tables can be specified in POSIX regular expres-
index 7f04aa0c4da5c73c656ced175e7da802b69698ad..8d587e46f21bf7bb621c7253318f7e80049d2137 100644 (file)
@@ -18,103 +18,110 @@ RELOCATED(5)                                                      RELOCATED(5)
        in "user has moved to <i>new</i><b>_</b><i>location</i>" bounce messages.
 
        Normally, the <a href="relocated.5.html"><b>relocated</b>(5)</a> table is  specified  as  a  text  file  that
-       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file
-       in <b>dbm</b> or <b>db</b> format, is used for fast searching  by  the  mail  system.
-       Execute  the  command  "<b>postmap  /etc/postfix/relocated</b>"  to rebuild an
-       indexed file after changing the corresponding relocated table.
+       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file for
+       fast lookup.
+
+       Execute the  command  "<b>postmap  /etc/postfix/relocated</b>"  to  rebuild  a
+       default-type  indexed  file  after  changing  the text file, or execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/relocated</b>" to specify an explicit type.
+
+       The default indexed file type  is  configured  with  the  <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a>  parameter.  Depending  on  the  platform  this may be one of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When the table is provided via other means such as NIS,  LDAP  or  SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively,  the  table  can be provided as a regular-expression map
-       where patterns are given as regular  expressions,  or  lookups  can  be
-       directed  to a TCP-based server. In those case, the lookups are done in
-       a slightly different way as described below under  "REGULAR  EXPRESSION
+       Alternatively, the table can be provided as  a  regular-expression  map
+       where  patterns  are  given  as  regular expressions, or lookups can be
+       directed to a TCP-based server. In those case, the lookups are done  in
+       a  slightly  different way as described below under "REGULAR EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
        Table lookups are case insensitive.
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The  search string is folded to lowercase before database lookup. As of
-       Postfix 2.3, the search string is not case folded with  database  types
-       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
+       The search string is folded to lowercase before database lookup. As  of
+       Postfix  2.3,  the search string is not case folded with database types
+       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        <b>o</b>      By default, Postfix will prepend a hard-coded prefix "5.1.6 User
-              has  moved  to  " to a table lookup result, and the format for a
+              has moved to " to a table lookup result, and the  format  for  a
               table entry is as follows:
 
                    <i>pattern      new</i><b>_</b><i>location</i>
 
-              Where <i>new</i><b>_</b><i>location</i> specifies  contact  information  such  as  an
-              email  address, or perhaps a street address or telephone number.
+              Where  <i>new</i><b>_</b><i>location</i>  specifies  contact  information  such as an
+              email address, or perhaps a street address or telephone  number.
 
-       <b>o</b>      Postfix 3.11 and later can  optionally  disable  the  hard-coded
-              prefix.  Specify  "<a href="postconf.5.html#relocated_prefix_enable">relocated_prefix_enable</a> = no" in <a href="postconf.5.html">main.cf</a>, and
-              specify <a href="postconf.5.html#relocated_maps">relocated_maps</a> entries with your own <a href="https://tools.ietf.org/html/rfc3463">RFC  3463</a>-compliant
+       <b>o</b>      Postfix  3.11  and  later  can optionally disable the hard-coded
+              prefix. Specify "<a href="postconf.5.html#relocated_prefix_enable">relocated_prefix_enable</a> = no" in  <a href="postconf.5.html">main.cf</a>,  and
+              specify  <a href="postconf.5.html#relocated_maps">relocated_maps</a> entries with your own <a href="https://tools.ietf.org/html/rfc3463">RFC 3463</a>-compliant
               enhanced status code and text, for example:
 
                    <i>pattern</i>      5.1.6 Mailbox has moved to user@example
                    <i>pattern</i>      5.2.0 Mailbox is unavailable
                    <i>pattern</i>      5.2.1 Mailbox is disabled
 
-       <b>o</b>      Empty  lines and whitespace-only lines are ignored, as are lines
+       <b>o</b>      Empty lines and whitespace-only lines are ignored, as are  lines
               whose first non-whitespace character is a `#'.
 
-       <b>o</b>      A logical line starts with  non-whitespace  text.  A  line  that
+       <b>o</b>      A  logical  line  starts  with  non-whitespace text. A line that
               starts with whitespace continues a logical line.
 
 <b><a name="table_search_order">TABLE SEARCH ORDER</a></b>
-       With  lookups  from  indexed files such as DB or DBM, or from networked
-       tables such as NIS, LDAP or SQL, patterns are tried  in  the  order  as
+       With lookups from indexed files such as DB or DBM,  or  from  networked
+       tables  such  as  NIS,  LDAP or SQL, patterns are tried in the order as
        listed below:
 
        <i>user</i>@<i>domain</i>
-              Matches  <i>user</i>@<i>domain</i>.  This  form  has precedence over all other
+              Matches <i>user</i>@<i>domain</i>. This form has  precedence  over  all  other
               forms.
 
        <i>user</i>   Matches <i>user</i>@<i>site</i> when <i>site</i> is $<b><a href="postconf.5.html#myorigin">myorigin</a></b>, when <i>site</i> is listed in
-              $<b><a href="postconf.5.html#mydestination">mydestination</a></b>,  or  when  <i>site</i> is listed in $<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a></b> or
+              $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when <i>site</i> is listed  in  $<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a></b>  or
               $<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a></b>.
 
        @<i>domain</i>
-              Matches other addresses in <i>domain</i>.  This  form  has  the  lowest
+              Matches  other  addresses  in  <i>domain</i>.  This form has the lowest
               precedence.
 
 <b><a name="address_extension">ADDRESS EXTENSION</a></b>
        When a mail address localpart contains the optional recipient delimiter
-       (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order  becomes:  <i>user+foo</i>@<i>domain</i>,
+       (e.g.,  <i>user+foo</i>@<i>domain</i>),  the  lookup  order becomes: <i>user+foo</i>@<i>domain</i>,
        <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and @<i>domain</i>.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This  section  describes how the table lookups change when the table is
-       given in the form of regular expressions or when lookups  are  directed
-       to  a  TCP-based server. For a description of regular expression lookup
-       table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>. For  a  description
+       This section describes how the table lookups change when the  table  is
+       given  in  the form of regular expressions or when lookups are directed
+       to a TCP-based server. For a description of regular  expression  lookup
+       table  syntax,  see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>. For a description
        of the TCP client/server table lookup protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This
        feature is available in Postfix 2.5 and later.
 
-       Each pattern is a regular expression that  is  applied  to  the  entire
-       address  being looked up. Thus, <i>user@domain</i> mail addresses are not bro-
-       ken up into their <i>user</i> and <i>@domain</i> constituent parts, nor  is  <i>user+foo</i>
+       Each  pattern  is  a  regular  expression that is applied to the entire
+       address being looked up. Thus, <i>user@domain</i> mail addresses are not  bro-
+       ken  up  into their <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i>
        broken up into <i>user</i> and <i>foo</i>.
 
-       Patterns  are  applied  in the order as specified in the table, until a
+       Patterns are applied in the order as specified in the  table,  until  a
        pattern is found that matches the search string.
 
-       Results are the same as with indexed file lookups, with the  additional
-       feature  that parenthesized substrings from the pattern can be interpo-
+       Results  are the same as with indexed file lookups, with the additional
+       feature that parenthesized substrings from the pattern can be  interpo-
        lated as <b>$1</b>, <b>$2</b> and so on.
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This section describes how the table lookups change  when  lookups  are
-       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
-       client/server lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature  is
+       This  section  describes  how the table lookups change when lookups are
+       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
+       client/server  lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature is
        available in Postfix 2.5 and later.
 
-       Each  lookup operation uses the entire address once.  Thus, <i>user@domain</i>
-       mail addresses are not broken up  into  their  <i>user</i>  and  <i>@domain</i>  con-
+       Each lookup operation uses the entire address once.  Thus,  <i>user@domain</i>
+       mail  addresses  are  not  broken  up  into their <i>user</i> and <i>@domain</i> con-
        stituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
@@ -123,8 +130,8 @@ RELOCATED(5)                                                      RELOCATED(5)
        The table format does not understand quoting conventions.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a>  parameters  are especially relevant.  The text
-       below provides only a  parameter  summary.  See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for  more
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant.   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#relocated_maps">relocated_maps</a> (empty)</b>
@@ -134,26 +141,26 @@ RELOCATED(5)                                                      RELOCATED(5)
        Available with Postfix version 3.11 and later:
 
        <b><a href="postconf.5.html#relocated_prefix_enable">relocated_prefix_enable</a> (yes)</b>
-              Prepend the prefix "<b>5.1.6 User has  moved  to</b>  "  to  all  relo-
+              Prepend  the  prefix  "<b>5.1.6  User  has  moved to</b> " to all relo-
               cated_maps lookup results.
 
        Other parameters of interest:
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  local  network  interface  addresses  that this mail system
+              The local network interface  addresses  that  this  mail  system
               receives mail on.
 
        <b><a href="postconf.5.html#mydestination">mydestination</a> ($<a href="postconf.5.html#myhostname">myhostname</a>, localhost.$<a href="postconf.5.html#mydomain">mydomain</a>, localhost)</b>
-              The list of domains that are delivered via the  $<a href="postconf.5.html#local_transport">local_transport</a>
+              The  list of domains that are delivered via the $<a href="postconf.5.html#local_transport">local_transport</a>
               mail delivery transport.
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The  domain  name that locally-posted mail appears to come from,
+              The domain name that locally-posted mail appears to  come  from,
               and that locally posted mail is delivered to.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The remote network interface addresses  that  this  mail  system
-              receives  mail  on by way of a proxy or network address transla-
+              The  remote  network  interface  addresses that this mail system
+              receives mail on by way of a proxy or network  address  transla-
               tion unit.
 
 <b><a name="see_also">SEE ALSO</a></b>
index ecc1156e9d2d8fc81f9824463fe44d53adb917af..d38de3640ed63a9386369c1a393f319cbaf7ed53 100644 (file)
@@ -18,30 +18,31 @@ SOCKETMAP_TABLE(5)                                          SOCKETMAP_TABLE(5)
        <b>postmap -q - <a href="socketmap_table.html">socketmap</a>:unix:</b><i>pathname</i><b>:</b><i>name</i> &lt;<i>inputfile</i>
 
 <b><a name="description">DESCRIPTION</a></b>
-       The  Postfix  mail  system  uses optional tables for address rewriting,
-       mail routing or policy lookup.
+       The  Postfix  mail system uses optional tables for address rewriting or
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       The Postfix socketmap client expects TCP endpoint  names  of  the  form
-       <b>inet:</b><i>host</i><b>:</b><i>port</i><b>:</b><i>name</i>,  or  UNIX-domain  endpoints of the form <b>unix:</b><i>path-</i>
+       The  Postfix  socketmap  client  expects TCP endpoint names of the form
+       <b>inet:</b><i>host</i><b>:</b><i>port</i><b>:</b><i>name</i>, or UNIX-domain endpoints of  the  form  <b>unix:</b><i>path-</i>
        <i>name</i><b>:</b><i>name</i>.  In both cases, <i>name</i> specifies the name field in a socketmap
        client request (see "REQUEST FORMAT" below).
 
 <b><a name="protocol">PROTOCOL</a></b>
        Socketmaps use a simple protocol: the client sends one request, and the
-       server sends one reply.  Each request and each reply are  sent  as  one
+       server  sends  one  reply.  Each request and each reply are sent as one
        netstring object.
 
 <b><a name="request_format">REQUEST FORMAT</a></b>
-       The  socketmap  protocol supports only the lookup request.  The request
+       The socketmap protocol supports only the lookup request.   The  request
        has the following form:
 
        <i>name</i> &lt;<b>space</b>&gt; <i>key</i>
               Search the named socketmap for the specified key.
 
-       Postfix will not generate partial search  keys  such  as  domain  names
-       without  one  or more subdomains, network addresses without one or more
-       least-significant octets, or email  addresses  without  the  localpart,
-       address  extension  or domain portion. This behavior is also found with
+       Postfix  will  not  generate  partial  search keys such as domain names
+       without one or more subdomains, network addresses without one  or  more
+       least-significant  octets,  or  email  addresses without the localpart,
+       address extension or domain portion. This behavior is also  found  with
        <a href="cidr_table.5.html">cidr</a>:, <a href="pcre_table.5.html">pcre</a>:, and <a href="regexp_table.5.html">regexp</a>: tables.
 
 <b><a name="reply_format">REPLY FORMAT</a></b>
@@ -58,27 +59,27 @@ SOCKETMAP_TABLE(5)                                          SOCKETMAP_TABLE(5)
        <b>TIMEOUT</b> &lt;<b>space</b>&gt; <i>reason</i>
 
        <b>PERM</b> &lt;<b>space</b>&gt; <i>reason</i>
-              The request failed. The reason,  if  non-empty,  is  descriptive
+              The  request  failed.  The  reason, if non-empty, is descriptive
               text.
 
 <b><a name="protocol_limits">PROTOCOL LIMITS</a></b>
-       The  Postfix  socketmap client requires that replies are no longer than
-       100000 bytes (not including the netstring  encapsulation).  This  limit
-       can  be changed with the <a href="postconf.5.html#socketmap_max_reply_size">socketmap_max_reply_size</a> configuration parame-
+       The Postfix socketmap client requires that replies are no  longer  than
+       100000  bytes  (not  including the netstring encapsulation). This limit
+       can be changed with the <a href="postconf.5.html#socketmap_max_reply_size">socketmap_max_reply_size</a> configuration  parame-
        ter (Postfix 3.10 and later).
 
        The Postfix socketmap client enforces a 100s time limit to connect to a
-       socketmap  server, to send a request, and to receive a reply. It closes
-       an idle connection after 10s, and closes  an  active  connection  after
+       socketmap server, to send a request, and to receive a reply. It  closes
+       an  idle  connection  after  10s, and closes an active connection after
        100s. These limits are not (yet) configurable.
 
 <b><a name="security">SECURITY</a></b>
-       This  map  cannot  be  used for security-sensitive information, because
+       This map cannot be used  for  security-sensitive  information,  because
        neither the connection nor the server are authenticated.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
        <b><a href="postconf.5.html#socketmap_max_reply_size">socketmap_max_reply_size</a> (100000)</b>
-              The maximum allowed reply size  from  a  socketmap  server,  not
+              The  maximum  allowed  reply  size  from a socketmap server, not
               including the netstring encapsulation.
 
 <b><a name="see_also">SEE ALSO</a></b>
index 56836d43ca6a9681694054887f17cd225a51e280..f481807f31b03d444c9047fc354f1c7187f8b29c 100644 (file)
@@ -17,11 +17,15 @@ SQLITE_TABLE(5)                                                SQLITE_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       Alternatively, lookup tables can be specified as SQLite databases.   In
-       order  to use SQLite lookups, define an SQLite source as a lookup table
-       in <a href="postconf.5.html">main.cf</a>, for example:
+       Alternatively,  lookup tables can be specified as SQLite databases.  To
+       find out what types of lookup tables your Postfix system  supports  use
+       the "<b>postconf -m</b>" command.
+
+       In order to use SQLite lookups, define an SQLite source as a lookup ta-
+       ble in <a href="postconf.5.html">main.cf</a>, for example:
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="sqlite_table.5.html">sqlite</a>:/etc/postfix/sqlite-aliases.cf
 
        The file /etc/postfix/sqlite-aliases.cf has  the  same  format  as  the
index 8311ac4ab2e7dbf0476aa160516710c2cf1f3653..5315023236035df0b7bdedf1a703dac02f82975a 100644 (file)
@@ -17,14 +17,12 @@ TCP_TABLE(5)                                                      TCP_TABLE(5)
 
 <b><a name="description">DESCRIPTION</a></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.  Alterna-
-       tively, table lookups can be directed to a TCP server.
+       mail routing. These tables are usually in <b><a href="lmdb_table.5.html">lmdb</a>:</b>, <b><a href="CDB_README.html">cdb</a>:</b>, <b><a href="DATABASE_README.html#types">hash</a>:</b>,  or  <b><a href="DATABASE_README.html#types">dbm</a>:</b>
+       format.
 
-       To  find  out  what types of lookup tables your Postfix system supports
-       use the "<b>postconf -m</b>" command.
-
-       To test lookup tables, use the "<b>postmap -q</b>" command as described in the
-       SYNOPSIS above.
+       Alternatively,  table lookups can be directed to a TCP server.  To test
+       lookup tables, use the "<b>postmap -q</b>" command as described in the  SYNOP-
+       SIS above.
 
 <b><a name="protocol_description">PROTOCOL DESCRIPTION</a></b>
        The TCP map class implements a very simple protocol: the client sends a
index 9407a6512b688e02f7f809c220dc8ae6dbebb75c..f59a020621e3cb11453a3cc932fa6d633eb79b65 100644 (file)
@@ -61,50 +61,57 @@ TRANSPORT(5)                                                      TRANSPORT(5)
               <b><a href="postconf.5.html#relayhost">relayhost</a></b>, or from the recipient domain.
 
        Normally,  the  <a href="transport.5.html"><b>transport</b>(5)</a>  table  is  specified  as a text file that
-       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file
-       in  <b>dbm</b>  or  <b>db</b>  format, is used for fast searching by the mail system.
-       Execute the command  "<b>postmap  /etc/postfix/transport</b>"  to  rebuild  an
-       indexed file after changing the corresponding transport table.
+       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file for
+       fast lookup.
+
+       Execute  the  command  "<b>postmap  /etc/postfix/transport</b>"  to  rebuild a
+       default-type indexed file after changing  the  text  file,  or  execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/transport</b>" to specify an explicit type.
+
+       The  default  indexed  file  type  is configured with the <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a> parameter. Depending on the  platform  this  may  be  one  of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When  the  table  is provided via other means such as NIS, LDAP or SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively, the table can be provided as  a  regular-expression  map
-       where  patterns  are  given  as  regular expressions, or lookups can be
-       directed to a TCP-based server. In those case, the lookups are done  in
-       a  slightly  different way as described below under "REGULAR EXPRESSION
+       Alternatively,  the  table  can be provided as a regular-expression map
+       where patterns are given as regular  expressions,  or  lookups  can  be
+       directed  to a TCP-based server. In those case, the lookups are done in
+       a slightly different way as described below under  "REGULAR  EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The search string is folded to lowercase before database lookup. As  of
-       Postfix  2.3,  the search string is not case folded with database types
-       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
+       The  search string is folded to lowercase before database lookup. As of
+       Postfix 2.3, the search string is not case folded with  database  types
+       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        The input format for the <a href="postmap.1.html"><b>postmap</b>(1)</a> command is as follows:
 
        <i>pattern result</i>
-              When  <i>pattern</i>  matches  the recipient address or domain, use the
+              When <i>pattern</i> matches the recipient address or  domain,  use  the
               corresponding <i>result</i>.
 
        blank lines and comments
-              Empty lines and whitespace-only lines are ignored, as are  lines
+              Empty  lines and whitespace-only lines are ignored, as are lines
               whose first non-whitespace character is a `#'.
 
        multi-line text
-              A  logical  line  starts  with  non-whitespace text. A line that
+              A logical line starts with  non-whitespace  text.  A  line  that
               starts with whitespace continues a logical line.
 
        The <i>pattern</i> specifies an email address, a domain name, or a domain name
        hierarchy, as described in section "TABLE SEARCH ORDER".
 
-       The  <i>result</i> is of the form <i>transport:nexthop</i> and specifies how or where
+       The <i>result</i> is of the form <i>transport:nexthop</i> and specifies how or  where
        to deliver mail. This is described in section "RESULT FORMAT".
 
 <b><a name="table_search_order">TABLE SEARCH ORDER</a></b>
-       With lookups from indexed files such as DB or DBM,  or  from  networked
-       tables  such  as  NIS,  LDAP or SQL, patterns are tried in the order as
+       With  lookups  from  indexed files such as DB or DBM, or from networked
+       tables such as NIS, LDAP or SQL, patterns are tried  in  the  order  as
        listed below:
 
        <i>user+extension@domain transport</i>:<i>nexthop</i>
@@ -118,35 +125,35 @@ TRANSPORT(5)                                                      TRANSPORT(5)
               Deliver mail for <i>domain</i> through <i>transport</i> to <i>nexthop</i>.
 
        <i>.domain transport</i>:<i>nexthop</i>
-              Deliver  mail  for  any subdomain of <i>domain</i> through <i>transport</i> to
+              Deliver mail for any subdomain of <i>domain</i>  through  <i>transport</i>  to
               <i>nexthop</i>. This applies only when the string <b><a href="postconf.5.html#transport_maps">transport_maps</a></b> is not
               listed  in  the  <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a></b>  configuration
               setting.  Otherwise, a domain name matches itself and its subdo-
               mains.
 
        <b>*</b> <i>transport</i>:<i>nexthop</i>
-              The  special pattern <b>*</b> represents any address (i.e. it functions
-              as the wild-card pattern, and is  unique  to  Postfix  transport
+              The special pattern <b>*</b> represents any address (i.e. it  functions
+              as  the  wild-card  pattern,  and is unique to Postfix transport
               tables).
 
-       Note    1:    the    null   recipient   address   is   looked   up   as
+       Note   1:   the   null   recipient   address   is    looked    up    as
        <b>$<a href="postconf.5.html#empty_address_recipient">empty_address_recipient</a></b>@<b>$<a href="postconf.5.html#myhostname">myhostname</a></b> (default: mailer-daemon@hostname).
 
-       Note  2:  <i>user@domain</i>  or  <i>user+extension@domain</i> lookup is available in
+       Note 2: <i>user@domain</i> or <i>user+extension@domain</i>  lookup  is  available  in
        Postfix 2.0 and later.
 
 <b><a name="result_format">RESULT FORMAT</a></b>
-       The lookup result is of  the  form  <i>transport</i><b>:</b><i>nexthop</i>.   The  <i>transport</i>
-       field  specifies  a  mail delivery transport such as <b>smtp</b> or <b>local</b>. The
+       The  lookup  result  is  of  the form <i>transport</i><b>:</b><i>nexthop</i>.  The <i>transport</i>
+       field specifies a mail delivery transport such as <b>smtp</b>  or  <b>local</b>.  The
        <i>nexthop</i> field specifies where and how to deliver mail.
 
-       The transport field specifies the name of  a  mail  delivery  transport
-       (the  first  name  of a mail delivery service entry in the Postfix <a href="master.5.html"><b>mas-</b>
+       The  transport  field  specifies  the name of a mail delivery transport
+       (the first name of a mail delivery service entry in  the  Postfix  <a href="master.5.html"><b>mas-</b>
        <b>ter.cf</b></a> file).
 
-       The nexthop field usually specifies one recipient domain  or  hostname.
+       The  nexthop  field usually specifies one recipient domain or hostname.
        In the case of the Postfix SMTP/LMTP client, the nexthop field may con-
-       tain a list of nexthop destinations separated by  comma  or  whitespace
+       tain  a  list  of nexthop destinations separated by comma or whitespace
        (Postfix 3.5 and later).
 
        The syntax of a nexthop destination is transport dependent.  With SMTP,
@@ -154,19 +161,19 @@ TRANSPORT(5)                                                      TRANSPORT(5)
        (mail exchanger) DNS lookups with [<i>host</i>] or [<i>host</i>]:<i>port</i>. The [] form is
        required when you specify an IP address instead of a hostname.
 
-       A null <i>transport</i> and null <i>nexthop</i> field means "do not change": use  the
-       delivery  transport and nexthop information that would be used when the
+       A  null <i>transport</i> and null <i>nexthop</i> field means "do not change": use the
+       delivery transport and nexthop information that would be used when  the
        entire transport table did not exist.
 
        A non-null <i>transport</i> field with a null <i>nexthop</i> field resets the nexthop
        information to the recipient domain.
 
-       A  null <i>transport</i> field with non-null <i>nexthop</i> field does not modify the
+       A null <i>transport</i> field with non-null <i>nexthop</i> field does not modify  the
        transport information.
 
 <b><a name="examples">EXAMPLES</a></b>
-       In order to deliver internal mail directly, while using  a  mail  relay
-       for  all other mail, specify a null entry for internal destinations (do
+       In  order  to  deliver internal mail directly, while using a mail relay
+       for all other mail, specify a null entry for internal destinations  (do
        not change the delivery transport or the nexthop information) and spec-
        ify a wildcard for all other destinations.
 
@@ -174,51 +181,51 @@ TRANSPORT(5)                                                      TRANSPORT(5)
             <b>.my.domain   :</b>
             <b>*            <a href="smtp.8.html">smtp</a>:outbound-relay.my.domain</b>
 
-       In  order  to send mail for <b>example.com</b> and its subdomains via the <b>uucp</b>
+       In order to send mail for <b>example.com</b> and its subdomains via  the  <b>uucp</b>
        transport to the UUCP host named <b>example</b>:
 
             <b>example.com      uucp:example</b>
             <b>.example.com     uucp:example</b>
 
-       When no nexthop destination is specified, Postfix  uses  (from  low  to
-       high  precedence):  the  recipient  domain,  the nexthop specified with
-       <a href="postconf.5.html#relayhost">relayhost</a>, with <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> (for remote  deliveries
+       When  no  nexthop  destination  is specified, Postfix uses (from low to
+       high precedence): the recipient  domain,  the  nexthop  specified  with
+       <a href="postconf.5.html#relayhost">relayhost</a>,  with <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> (for remote deliveries
        only), with the transport for the address domain class (see DESCRIPTION
-       above), or  with  <a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a>  (for  remote
-       deliveries   only).   For  example,  the  following  directs  mail  for
-       <i>user</i>@<b>example.com</b> via the <b>slow</b> transport to a mail exchanger  for  <b>exam-</b>
-       <b>ple.com</b>.  The  <b>slow</b>  transport  could  be configured to run at most one
+       above),  or  with  <a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a>  (for remote
+       deliveries  only).  For  example,  the  following  directs   mail   for
+       <i>user</i>@<b>example.com</b>  via  the <b>slow</b> transport to a mail exchanger for <b>exam-</b>
+       <b>ple.com</b>. The <b>slow</b> transport could be configured  to  run  at  most  one
        delivery process at a time:
 
             <b>example.com      slow:</b>
 
        When no transport is specified, Postfix uses the transport that matches
-       the  address  domain  class  (see  DESCRIPTION above), or the transport
-       specified  with  <a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a>  (for   remote
-       deliveries  only). The following sends all mail for <b>example.com</b> and its
+       the address domain class (see  DESCRIPTION  above),  or  the  transport
+       specified   with  <a href="postconf.5.html#sender_dependent_default_transport_maps">sender_dependent_default_transport_maps</a>  (for  remote
+       deliveries only). The following sends all mail for <b>example.com</b> and  its
        subdomains to host <b>gateway.example.com</b>:
 
             <b>example.com      :[gateway.example.com]</b>
             <b>.example.com     :[gateway.example.com]</b>
 
-       In the above example, the [] suppress MX lookups.  This  prevents  mail
+       In  the  above example, the [] suppress MX lookups.  This prevents mail
        routing loops when your machine is primary MX host for <b>example.com</b>.
 
-       In  the case of delivery via SMTP or LMTP, one may specify <i>host</i>:<i>service</i>
+       In the case of delivery via SMTP or LMTP, one may specify  <i>host</i>:<i>service</i>
        instead of just a host:
 
             <b>example.com      <a href="smtp.8.html">smtp</a>:bar.example:2025</b>
 
-       This directs mail for <i>user</i>@<b>example.com</b> to host <b>bar.example</b>  port  <b>2025</b>.
-       Instead  of  a  numerical  port a symbolic name may be used. Specify []
+       This  directs  mail for <i>user</i>@<b>example.com</b> to host <b>bar.example</b> port <b>2025</b>.
+       Instead of a numerical port a symbolic name may  be  used.  Specify  []
        around the hostname if MX lookups must be disabled.
 
-       Deliveries via SMTP or LMTP support multiple destinations  (Postfix  &gt;=
+       Deliveries  via  SMTP or LMTP support multiple destinations (Postfix &gt;=
        3.5):
 
             <b>example.com      <a href="smtp.8.html">smtp</a>:bar.example, foo.example</b>
 
-       This  tries  to  deliver  to  <b>bar.example</b>  before  trying to deliver to
+       This tries to deliver  to  <b>bar.example</b>  before  trying  to  deliver  to
        <b>foo.example</b>.
 
        The error mailer can be used to bounce mail:
@@ -228,16 +235,16 @@ TRANSPORT(5)                                                      TRANSPORT(5)
        This causes all mail for <i>user</i>@<i>anything</i><b>.example.com</b> to be bounced.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This section describes how the table lookups change when the  table  is
-       given  in the form of regular expressions. For a description of regular
+       This  section  describes how the table lookups change when the table is
+       given in the form of regular expressions. For a description of  regular
        expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to  the  entire
-       address  being  looked up. Thus, <i>some.domain.hierarchy</i> is not looked up
-       via  its  parent  domains,  nor  is  <i>user+foo@domain</i>   looked   up   as
+       Each  pattern  is  a  regular  expression that is applied to the entire
+       address being looked up. Thus, <i>some.domain.hierarchy</i> is not  looked  up
+       via   its   parent   domains,  nor  is  <i>user+foo@domain</i>  looked  up  as
        <i>user@domain</i>.
 
-       Patterns  are  applied  in the order as specified in the table, until a
+       Patterns are applied in the order as specified in the  table,  until  a
        pattern is found that matches the search string.
 
        The <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a> server disallows regular expression substitution
@@ -245,32 +252,32 @@ TRANSPORT(5)                                                      TRANSPORT(5)
        a security hole (Postfix version 2.3 and later).
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This section describes how the table lookups change  when  lookups  are
-       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
-       client/server lookup protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature  is  not
+       This  section  describes  how the table lookups change when lookups are
+       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
+       client/server  lookup  protocol, see <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.  This feature is not
        available up to and including Postfix version 2.4.
 
-       Each  lookup  operation  uses the entire recipient address once.  Thus,
-       <i>some.domain.hierarchy</i> is not looked up via its parent domains,  nor  is
+       Each lookup operation uses the entire recipient  address  once.   Thus,
+       <i>some.domain.hierarchy</i>  is  not looked up via its parent domains, nor is
        <i>user+foo@domain</i> looked up as <i>user@domain</i>.
 
        Results are the same as with indexed file lookups.
 
 <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a>  parameters  are especially relevant.  The text
-       below provides only a  parameter  summary.  See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for  more
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are  especially  relevant.   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#empty_address_recipient">empty_address_recipient</a> (MAILER-DAEMON)</b>
               The recipient of mail addressed to the null address.
 
        <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf -d' output)</b>
-              A  list of Postfix features where the pattern "example.com" also
-              matches subdomains  of  example.com,  instead  of  requiring  an
+              A list of Postfix features where the pattern "example.com"  also
+              matches  subdomains  of  example.com,  instead  of  requiring an
               explicit ".example.com" pattern.
 
        <b><a href="postconf.5.html#transport_maps">transport_maps</a> (empty)</b>
-              Optional  lookup  tables with mappings from recipient address to
+              Optional lookup tables with mappings from recipient  address  to
               (message delivery transport, next-hop destination).
 
 <b><a name="see_also">SEE ALSO</a></b>
index f9f1b7362254041ef303e8417d00dbb8cf3f3609..97b2560d4cef986e6a31085d3055e970e8cd4dda 100644 (file)
@@ -47,75 +47,82 @@ VIRTUAL(5)                                                          VIRTUAL(5)
        header and envelope addresses in general.
 
        Normally,  the  <a href="virtual.5.html"><b>virtual</b>(5)</a> alias table is specified as a text file that
-       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command.  The result, an indexed file
-       in  <b>dbm</b>  or  <b>db</b>  format, is used for fast searching by the mail system.
-       Execute  the  command  "<b>postmap  /etc/postfix/virtual</b>"  to  rebuild  an
-       indexed file after changing the corresponding text file.
+       serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command to create an indexed file for
+       fast lookup.
+
+       Execute   the  command  "<b>postmap  /etc/postfix/virtual</b>"  to  rebuild  a
+       default-type indexed file after changing  the  text  file,  or  execute
+       "<b>postmap</b> <i>type</i><b>:/etc/postfix/virtual</b>" to specify an explicit type.
+
+       The  default  indexed  file  type  is configured with the <a href="postconf.5.html#default_database_type">default_data</a>-
+       <a href="postconf.5.html#default_database_type">base_type</a> parameter. Depending on the  platform  this  may  be  one  of
+       <a href="lmdb_table.5.html">lmdb</a>:, <a href="CDB_README.html">cdb</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="DATABASE_README.html#types">dbm</a>: (without the trailing ':').
 
        When  the  table  is provided via other means such as NIS, LDAP or SQL,
-       the same lookups are done as for ordinary indexed files.
+       the same lookups are done as for ordinary indexed files.  Managing such
+       databases is outside the scope of Postfix.
 
-       Alternatively, the table can be provided as  a  regular-expression  map
-       where  patterns  are  given  as  regular expressions, or lookups can be
-       directed to a TCP-based server. In those case, the lookups are done  in
-       a  slightly  different way as described below under "REGULAR EXPRESSION
+       Alternatively,  the  table  can be provided as a regular-expression map
+       where patterns are given as regular  expressions,  or  lookups  can  be
+       directed  to a TCP-based server. In those case, the lookups are done in
+       a slightly different way as described below under  "REGULAR  EXPRESSION
        TABLES" or "TCP-BASED TABLES".
 
 <b><a name="case_folding">CASE FOLDING</a></b>
-       The search string is folded to lowercase before database lookup. As  of
-       Postfix  2.3,  the search string is not case folded with database types
-       such as <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both  upper  and
+       The  search string is folded to lowercase before database lookup. As of
+       Postfix 2.3, the search string is not case folded with  database  types
+       such  as  <a href="regexp_table.5.html">regexp</a>: or <a href="pcre_table.5.html">pcre</a>: whose lookup fields can match both upper and
        lower case.
 
 <b><a name="table_format">TABLE FORMAT</a></b>
        The input format for the <a href="postmap.1.html"><b>postmap</b>(1)</a> command is as follows:
 
        <i>pattern address, address, ...</i>
-              When  <i>pattern</i>  matches  a mail address, replace it by the corre-
+              When <i>pattern</i> matches a mail address, replace it  by  the  corre-
               sponding <i>address</i>.
 
        blank lines and comments
-              Empty lines and whitespace-only lines are ignored, as are  lines
+              Empty  lines and whitespace-only lines are ignored, as are lines
               whose first non-whitespace character is a `#'.
 
        multi-line text
-              A  logical  line  starts  with  non-whitespace text. A line that
+              A logical line starts with  non-whitespace  text.  A  line  that
               starts with whitespace continues a logical line.
 
 <b><a name="table_search_order">TABLE SEARCH ORDER</a></b>
-       With lookups from indexed files such as DB or DBM,  or  from  networked
-       tables  such  as  NIS,  LDAP  or SQL, each <i>user</i>@<i>domain</i> query produces a
+       With  lookups  from  indexed files such as DB or DBM, or from networked
+       tables such as NIS, LDAP or SQL,  each  <i>user</i>@<i>domain</i>  query  produces  a
        sequence of query patterns as described below.
 
        Each query pattern is sent to each specified lookup table before trying
        the next query pattern, until a match is found.
 
        <i>user</i>@<i>domain address, address, ...</i>
-              Redirect  mail  for  <i>user</i>@<i>domain</i>  to <i>address</i>.  This form has the
+              Redirect mail for <i>user</i>@<i>domain</i> to <i>address</i>.   This  form  has  the
               highest precedence.
 
        <i>user address, address, ...</i>
-              Redirect mail for <i>user</i>@<i>site</i> to <i>address</i> when  <i>site</i>  is  equal  to
-              $<b><a href="postconf.5.html#myorigin">myorigin</a></b>,  when <i>site</i> is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it is
+              Redirect  mail  for  <i>user</i>@<i>site</i>  to <i>address</i> when <i>site</i> is equal to
+              $<b><a href="postconf.5.html#myorigin">myorigin</a></b>, when <i>site</i> is listed in $<b><a href="postconf.5.html#mydestination">mydestination</a></b>, or when it  is
               listed in $<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a></b> or $<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a></b>.
 
-              This functionality overlaps with the functionality of the  local
-              <i>aliases</i>(5)  database.  The difference is that <a href="virtual.5.html"><b>virtual</b>(5)</a> mapping
+              This  functionality overlaps with the functionality of the local
+              <i>aliases</i>(5) database. The difference is that  <a href="virtual.5.html"><b>virtual</b>(5)</a>  mapping
               can be applied to non-local addresses.
 
        @<i>domain address, address, ...</i>
-              Redirect mail for other users in <i>domain</i> to <i>address</i>.   This  form
+              Redirect  mail  for other users in <i>domain</i> to <i>address</i>.  This form
               has the lowest precedence.
 
-              Note:  @<i>domain</i>  is a wild-card. With this form, the Postfix SMTP
-              server accepts mail for any recipient in <i>domain</i>,  regardless  of
-              whether  that  recipient exists.  This may turn your mail system
-              into a  backscatter  source:  Postfix  first  accepts  mail  for
-              non-existent  recipients  and  then tries to return that mail as
+              Note: @<i>domain</i> is a wild-card. With this form, the  Postfix  SMTP
+              server  accepts  mail for any recipient in <i>domain</i>, regardless of
+              whether that recipient exists.  This may turn your  mail  system
+              into  a  backscatter  source:  Postfix  first  accepts  mail for
+              non-existent recipients and then tries to return  that  mail  as
               "undeliverable" to the often forged sender address.
 
-              To avoid backscatter with mail for a wild-card  domain,  replace
-              the  wild-card  mapping  with  explicit  1:1  mappings, or add a
+              To  avoid  backscatter with mail for a wild-card domain, replace
+              the wild-card mapping with  explicit  1:1  mappings,  or  add  a
               <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> restriction for that domain:
 
                   <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
@@ -131,11 +138,11 @@ VIRTUAL(5)                                                          VIRTUAL(5)
 <b><a name="result_address_rewriting">RESULT ADDRESS REWRITING</a></b>
        The lookup result is subject to address rewriting:
 
-       <b>o</b>      When  the  result  has the form @<i>otherdomain</i>, the result becomes
-              the same <i>user</i> in <i>otherdomain</i>.  This works  only  for  the  first
+       <b>o</b>      When the result has the form @<i>otherdomain</i>,  the  result  becomes
+              the  same  <i>user</i>  in  <i>otherdomain</i>.  This works only for the first
               address in a multi-address lookup result.
 
-       <b>o</b>      When  "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to addresses
+       <b>o</b>      When "<b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a>=yes</b>", append "<b>@$<a href="postconf.5.html#myorigin">myorigin</a></b>" to  addresses
               without "@domain".
 
        <b>o</b>      When "<b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes</b>", append "<b>.$<a href="postconf.5.html#mydomain">mydomain</a></b>" to addresses
@@ -143,26 +150,26 @@ VIRTUAL(5)                                                          VIRTUAL(5)
 
 <b><a name="address_extension">ADDRESS EXTENSION</a></b>
        When a mail address localpart contains the optional recipient delimiter
-       (e.g., <i>user+foo</i>@<i>domain</i>), the  lookup  order  becomes:  <i>user+foo</i>@<i>domain</i>,
+       (e.g.,  <i>user+foo</i>@<i>domain</i>),  the  lookup  order becomes: <i>user+foo</i>@<i>domain</i>,
        <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and @<i>domain</i>.
 
-       The   <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>   parameter  controls  whether  an
+       The  <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>  parameter  controls   whether   an
        unmatched address extension (<i>+foo</i>) is propagated to the result of a ta-
        ble lookup.
 
 <b><a name="virtual_alias_domains">VIRTUAL ALIAS DOMAINS</a></b>
-       Besides  virtual  aliases,  the virtual alias table can also be used to
-       implement <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domains</a>.  With  a  virtual  alias  domain,  all
+       Besides virtual aliases, the virtual alias table can also  be  used  to
+       implement  virtual  alias  domains.  With  a  <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, all
        recipient addresses are aliased to addresses in other domains.
 
-       Virtual  alias  domains are not to be confused with the virtual mailbox
-       domains that are implemented with the Postfix <a href="virtual.8.html"><b>virtual</b>(8)</a> mail  delivery
-       agent.  With  virtual  mailbox domains, each recipient address can have
+       Virtual alias domains are not to be confused with the  virtual  mailbox
+       domains  that are implemented with the Postfix <a href="virtual.8.html"><b>virtual</b>(8)</a> mail delivery
+       agent. With <a href="ADDRESS_CLASS_README.html#virtual_mailbox_class">virtual mailbox domains</a>, each recipient  address  can  have
        its own mailbox.
 
-       With a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, the virtual domain has its own  user  name
-       space.  Local (i.e. non-virtual) usernames are not visible in a virtual
-       alias domain. In particular, local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local  mailing  lists
+       With  a  <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, the virtual domain has its own user name
+       space. Local (i.e. non-virtual) usernames are not visible in a  virtual
+       alias  domain.  In particular, local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists
        are not visible as <i>localname@virtual-alias.domain</i>.
 
        Support for a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a> looks like:
@@ -170,7 +177,7 @@ VIRTUAL(5)                                                          VIRTUAL(5)
        /etc/postfix/<a href="postconf.5.html">main.cf</a>:
            <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/virtual
 
-       Note:  some  systems use <b>dbm</b> databases instead of <b>hash</b>.  See the output
+       Note: some systems use <b>dbm</b> databases instead of <b>hash</b>.  See  the  output
        from "<b>postconf -m</b>" for available database types.
 
        /etc/postfix/virtual:
@@ -180,46 +187,46 @@ VIRTUAL(5)                                                          VIRTUAL(5)
            <i>user2@virtual-alias.domain      address2, address3</i>
 
        The <i>virtual-alias.domain anything</i> entry is required for a virtual alias
-       domain.  <b>Without  this  entry,  mail  is  rejected  with  "relay access</b>
+       domain. <b>Without  this  entry,  mail  is  rejected  with  "relay  access</b>
        <b>denied", or bounces with "mail loops back to myself".</b>
 
-       Do not specify <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a> names in the <a href="postconf.5.html"><b>main.cf</a>  <a href="postconf.5.html#mydestination">mydestination</a></b>
+       Do  not specify <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a> names in the <a href="postconf.5.html"><b>main.cf</a> <a href="postconf.5.html#mydestination">mydestination</a></b>
        or <b><a href="postconf.5.html#relay_domains">relay_domains</a></b> configuration parameters.
 
-       With  a  <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, the Postfix SMTP server accepts mail for
+       With a <a href="ADDRESS_CLASS_README.html#virtual_alias_class">virtual alias domain</a>, the Postfix SMTP server accepts  mail  for
        <i>known-user@virtual-alias.domain</i>, and rejects mail for <i>unknown-user</i>@<i>vir-</i>
        <i>tual-alias.domain</i> as undeliverable.
 
-       Instead  of  specifying  the  virtual  alias  domain  name via the <b><a href="postconf.5.html#virtual_alias_maps">vir</a>-</b>
-       <b><a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a></b> table, you may also specify it  via  the  <a href="postconf.5.html"><b>main.cf</a>  <a href="postconf.5.html#virtual_alias_domains">vir-</b>
+       Instead of specifying the  virtual  alias  domain  name  via  the  <b><a href="postconf.5.html#virtual_alias_maps">vir</a>-</b>
+       <b><a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a></b>  table,  you  may  also specify it via the <a href="postconf.5.html"><b>main.cf</a> <a href="postconf.5.html#virtual_alias_domains">vir-</b>
        <b>tual_alias_domains</a></b> configuration parameter.  This latter parameter uses
        the same syntax as the <a href="postconf.5.html"><b>main.cf</a> <a href="postconf.5.html#mydestination">mydestination</a></b> configuration parameter.
 
 <b><a name="regular_expression_tables">REGULAR EXPRESSION TABLES</a></b>
-       This section describes how the table lookups change when the  table  is
-       given  in the form of regular expressions. For a description of regular
+       This  section  describes how the table lookups change when the table is
+       given in the form of regular expressions. For a description of  regular
        expression lookup table syntax, see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
-       Each pattern is a regular expression that  is  applied  to  the  entire
-       address  being looked up. Thus, <i>user@domain</i> mail addresses are not bro-
-       ken up into their <i>user</i> and <i>@domain</i> constituent parts, nor  is  <i>user+foo</i>
+       Each  pattern  is  a  regular  expression that is applied to the entire
+       address being looked up. Thus, <i>user@domain</i> mail addresses are not  bro-
+       ken  up  into their <i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i>
        broken up into <i>user</i> and <i>foo</i>.
 
-       Patterns  are  applied  in the order as specified in the table, until a
+       Patterns are applied in the order as specified in the  table,  until  a
        pattern is found that matches the search string.
 
-       Results are the same as with indexed file lookups, with the  additional
-       feature  that parenthesized substrings from the pattern can be interpo-
+       Results  are the same as with indexed file lookups, with the additional
+       feature that parenthesized substrings from the pattern can be  interpo-
        lated as <b>$1</b>, <b>$2</b> and so on.
 
 <b><a name="tcp-based_tables">TCP-BASED TABLES</a></b>
-       This section describes how the table lookups change  when  lookups  are
-       directed   to  a  TCP-based  server.  For  a  description  of  the  TCP
-       client/server lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature  is
+       This  section  describes  how the table lookups change when lookups are
+       directed  to  a  TCP-based  server.  For  a  description  of  the   TCP
+       client/server  lookup  protocol,  see  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.   This  feature is
        available in Postfix 2.5 and later.
 
-       Each  lookup operation uses the entire address once.  Thus, <i>user@domain</i>
-       mail addresses are not broken up  into  their  <i>user</i>  and  <i>@domain</i>  con-
+       Each lookup operation uses the entire address once.  Thus,  <i>user@domain</i>
+       mail  addresses  are  not  broken  up  into their <i>user</i> and <i>@domain</i> con-
        stituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and <i>foo</i>.
 
        Results are the same as with indexed file lookups.
@@ -234,43 +241,43 @@ VIRTUAL(5)                                                          VIRTUAL(5)
 
        <b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> ($<a href="postconf.5.html#virtual_maps">virtual_maps</a>)</b>
               Optional lookup tables that are often searched with a full email
-              address (including domain) and that  apply  to  all  recipients:
-              <a href="local.8.html"><b>local</b>(8)</a>,  virtual,  and  remote; this is unlike <a href="postconf.5.html#alias_maps">alias_maps</a> that
-              are only searched with an email address  localpart  (no  domain)
+              address  (including  domain)  and  that apply to all recipients:
+              <a href="local.8.html"><b>local</b>(8)</a>, virtual, and remote; this is  unlike  <a href="postconf.5.html#alias_maps">alias_maps</a>  that
+              are  only  searched  with an email address localpart (no domain)
               and that apply only to <a href="local.8.html"><b>local</b>(8)</a> recipients.
 
        <b><a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a> ($<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a>)</b>
-              Postfix  is the final destination for the specified list of vir-
+              Postfix is the final destination for the specified list of  vir-
               tual alias domains, that is, domains for which all addresses are
               aliased to addresses in other local or remote domains.
 
        <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
-              What  address  lookup  tables copy an address extension from the
+              What address lookup tables copy an address  extension  from  the
               lookup key to the lookup result.
 
        Other parameters of interest:
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The local network interface  addresses  that  this  mail  system
+              The  local  network  interface  addresses  that this mail system
               receives mail on.
 
        <b><a href="postconf.5.html#mydestination">mydestination</a> ($<a href="postconf.5.html#myhostname">myhostname</a>, localhost.$<a href="postconf.5.html#mydomain">mydomain</a>, localhost)</b>
-              The  list of domains that are delivered via the $<a href="postconf.5.html#local_transport">local_transport</a>
+              The list of domains that are delivered via the  $<a href="postconf.5.html#local_transport">local_transport</a>
               mail delivery transport.
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The domain name that locally-posted mail appears to  come  from,
+              The  domain  name that locally-posted mail appears to come from,
               and that locally posted mail is delivered to.
 
        <b><a href="postconf.5.html#owner_request_special">owner_request_special</a> (yes)</b>
-              Enable  special  treatment  for  owner-<i>listname</i>  entries  in the
+              Enable special  treatment  for  owner-<i>listname</i>  entries  in  the
               <a href="aliases.5.html"><b>aliases</b>(5)</a>  file,  and  don't  split  owner-<i>listname</i>  and  <i>list-</i>
-              <i>name</i>-request  address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> is
+              <i>name</i>-request address localparts when the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>  is
               set to "-".
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The remote network interface addresses  that  this  mail  system
-              receives  mail  on by way of a proxy or network address transla-
+              The  remote  network  interface  addresses that this mail system
+              receives mail on by way of a proxy or network  address  transla-
               tion unit.
 
 <b><a name="see_also">SEE ALSO</a></b>
index 605fc9663d75dc3267835f379fa34a779359fb1f..2e303bbc3254939b85e3313e63ed65c200fe39e9 100644 (file)
@@ -642,7 +642,7 @@ EOF
                : ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
                : ${PLUGIN_LD="${CC-gcc} -shared"}
                ;;
-    Linux.[3456].*)
+    Linux.[34567].*)
                SYSTYPE=LINUX$RELEASE_MAJOR
                case "$CCARGS" in
                 *-DNO_DB*) ;;
index 40a52363cd4c77acd3c05b5699a186b8f414fecd..d7cba1569be41b1d9c96d449d89d0f171242f0e4 100644 (file)
@@ -8,11 +8,12 @@ DAEMONS       = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
        man8/oqmgr.8 man8/spawn.8 man8/flush.8 man8/virtual.8 man8/qmqpd.8 \
        man8/verify.8 man8/trace.8 man8/proxymap.8 man8/anvil.8 \
        man8/scache.8 man8/discard.8 man8/tlsmgr.8 man8/postscreen.8 \
-       man8/dnsblog.8 man8/tlsproxy.8 man8/postlogd.8
+       man8/dnsblog.8 man8/tlsproxy.8 man8/postlogd.8 man8/nbdb_reindexd.8
 COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
        man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
        man1/postmap.1 man1/postmulti.1 man1/postqueue.1 man1/postsuper.1 \
-       man1/sendmail.1 man1/mailq.1 man1/newaliases.1 man1/postfix-tls.1
+       man1/sendmail.1 man1/mailq.1 man1/newaliases.1 man1/postfix-tls.1 \
+       man1/postfix-non-bdb.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 \
@@ -91,6 +92,11 @@ man8/master.8: ../src/master/master.c
            (cmp -s junk $? || mv junk $?) && rm -f junk
        ../mantools/srctoman $? >$@
 
+man8/nbdb_reindexd.8: ../src/nbdb_reindexd/nbdb_reindexd.c
+       ../mantools/fixman ../proto/postconf.proto $? >junk && \
+           (cmp -s junk $? || mv junk $?) && rm -f junk
+       ../mantools/srctoman $? >$@
+
 man8/oqmgr.8: ../src/oqmgr/qmgr.c
        ../mantools/fixman ../proto/postconf.proto $? >junk && \
            (cmp -s junk $? || mv junk $?) && rm -f junk
@@ -207,6 +213,11 @@ man1/postfix.1: ../src/postfix/postfix.c
            (cmp -s junk $? || mv junk $?) && rm -f junk
        ../mantools/srctoman $? >$@
 
+man1/postfix-non-bdb.1: ../conf/postfix-non-bdb-script
+       ../mantools/fixman ../proto/postconf.proto $? >junk && \
+           (cmp -s junk $? || mv junk $?) && rm -f junk
+       ../mantools/srctoman - $? >$@
+
 man1/postfix-tls.1: ../conf/postfix-tls-script
        ../mantools/fixman ../proto/postconf.proto $? >junk && \
            (cmp -s junk $? || mv junk $?) && rm -f junk
index 10ee1fb518e3592a3076eea0e721f9697d7f4cde..ad8f8ba97405b51a5fb7ab2ba1f3dd42cf425aec 100644 (file)
@@ -124,6 +124,11 @@ Arguments:
 The database type. To find out what types are supported, use
 the "\fBpostconf \-m\fR" command.
 
+When no \fIfile_type\fR is specified, the software uses the database
+type specified via the \fBdefault_database_type\fR configuration
+parameter.
+The default value for this parameter depends on the host environment.
+
 The \fBpostalias\fR(1) command can query any supported file type,
 but it can create only the following file types:
 .RS
@@ -153,11 +158,6 @@ This is available on systems with support for \fBlmdb\fR databases.
 The output consists of two files, named \fIfile_name\fB.pag\fR and
 \fIfile_name\fB.dir\fR.
 This is available on systems with support for \fBsdbm\fR databases.
-.PP
-When no \fIfile_type\fR is specified, the software uses the database
-type specified via the \fBdefault_database_type\fR configuration
-parameter.
-The default value for this parameter depends on the host environment.
 .RE
 .IP \fIfile_name\fR
 The name of the alias database source file when creating a database.
diff --git a/postfix/man/man1/postfix-non-bdb.1 b/postfix/man/man1/postfix-non-bdb.1
new file mode 100644 (file)
index 0000000..5a71238
--- /dev/null
@@ -0,0 +1,143 @@
+.TH POSTFIX-NON-BDB 1 
+.ad
+.fi
+.SH NAME
+postfix-non-bdb
+\-
+Postfix non\-Berkeley\-DB migration
+.SH "SYNOPSIS"
+.na
+.nf
+\fBpostfix non\-bdb\fR \fIsubcommand\fR
+.SH DESCRIPTION
+.ad
+.fi
+The "\fBpostfix non\-bdb \fIsubcommand\fR" feature edits main.cf
+and master.cf, to manage the migration of an existing Postfix
+configuration that uses Berkeley DB type "hash:" or "btree:"
+tables (which are no longer supported on some OS distributions),
+to supported types such as "cdb:" or "lmdb:".
+
+The following subcommands are available:
+.IP \fBstatus\fR
+Reports the non\-Berkeley\-DB migration status, without making
+any changes.
+.IP \fBdisable\fR
+Edits main.cf and master.cf, to turn off the \fBenable\-redirect\fR
+and \fBenable\-reindex\fR features.
+.sp
+This will break integration with other software such as
+mailman versions from before May 2025 when they want to
+use "postmap hash:/path/to/file", for example, to update a
+mailman\-maintained table.
+.IP "\fBenable\-redirect\fR (aliasing)"
+Edits main.cf and master.cf, to enable redirection (aliasing)
+from Berkeley DB types "hash" and "btree" to the non\-Berkeley\-DB
+types specified with $default_database_type and
+$default_cache_db_type. Custom redirection may be configured
+with non_bdb_custom_mapping.
+.sp
+This configuration will not automatically create non\-Berkeley\-DB
+indexed database files. Instead, Postfix programs will log an
+error as they fail to open an indexed database file, and will
+leave it to the system administrator to run postmap(1) or
+postalias(1) to create that file.
+.sp
+This will fix integration with other software such as mailman
+versions from before May 2025 when they want to use "postmap
+hash:/path/to/file", for example, to update a mailman\-maintained
+table.
+.sp
+This subcommand will not make any changes when
+default_database_type or default_cache_db_type specify a hash:
+or btree: type.
+.IP \fBenable\-reindex\fR
+Edits main.cf and master.cf, to implement \fBenable\-redirect\fR,
+and to automatically create a non\-Berkeley\-DB indexed database
+file when a daemon program wants to access a file that does not
+yet exist. This uses the nbdb_reindexd(8) daemon to run postmap(1)
+or postalias(1) as described in "SECURITY" below.
+.sp
+This subcommand immediately generates non\-Berkeley\-DB indexed
+files for unprivileged command\-line programs that cannot send
+requests to the nbdb_reindexd(8) daemon server. This involves
+"hash:" and "btree:" tables that are used by postqueue(1) and
+sendmail(1) as specified in authorized_flush_users and
+authorized_mailq_users, and by sendmail(1) and postdrop(1)
+as specified in authorized_submit_users and
+local_login_sender_maps.
+.sp
+This subcommand will not make any changes when
+default_database_type or default_cache_db_type specify a hash:
+or btree: type.
+.sp
+\fINOTE: \fBenable\-reindex\fI should be used only temporarily
+to generate most of the non\-Berkeley\-DB indexed files that Postfix
+needs. Leaving this enabled may expose the system to
+privilege\-escalation attacks. There are no security
+concerns for using \fBenable\-redirect\fR.
+.SH "SECURITY"
+.na
+.nf
+.ad
+.fi
+The nbdb_reindexd(8) daemon automatically generates a
+non\-Berkeley\-DB indexed file only if the database pathname matches
+the directory prefixes specified with
+non_bdb_migration_allow_root_prefixes (for files that must be
+owned by root), or with non_bdb_migration_allow_user_prefixes
+(for files that must be owned by a non\-root user). Additional
+restrictions on file and directory ownership and permissions
+are documented in nbdb_reindexd(8).
+.SH "CONFIGURATION PARAMETERS"
+.na
+.nf
+.ad
+.fi
+The "\fBpostfix non\-bdb \fIsubcommand\fR" feature
+updates the following configuration parameter:
+.IP "\fBnon_bdb_migration_level (disable)\fR"
+The non\-Berkeley\-DB migration service level.
+.PP
+Other relevant parameters:
+.IP "\fBnon_bdb_custom_mapping (empty)\fR"
+When non\-Berkeley\-DB migration is enabled, an optional mapping
+from a hash: or btree: type to a non\-Berkeley\-DB type.
+.IP "\fBnon_bdb_migration_allow_root_prefixes (see 'postconf -d non_bdb_migration_allow_root_prefixes' output)\fR"
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with "root" privilege.
+.IP "\fBnon_bdb_migration_allow_user_prefixes (see 'postconf -d non_bdb_migration_allow_user_prefixes' output)\fR"
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with non\-root privilege.
+.SH "SEE ALSO"
+.na
+.nf
+nbdb_reindexd(8) reindexing service
+.SH "README FILES"
+.na
+.nf
+.ad
+.fi
+Use "\fBpostconf readme_directory\fR" or
+"\fBpostconf html_directory\fR" to locate this information.
+.na
+.nf
+NON_BERKELEYDB_README, migration guide
+.SH "LICENSE"
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH HISTORY
+.ad
+.fi
+The "\fBpostfix non\-bdb\fR" command was introduced with Postfix
+version 3.11.
+.SH "AUTHOR(S)"
+.na
+.nf
+Wietse Venema
+porcupine.org
index da39dc5cae6d7728e67eced488c4b8e78a5b9cfb..60294483b9f4d1376a3e5574ecca873b7bc99c76 100644 (file)
@@ -95,7 +95,14 @@ $maillog_file_rotate_suffix, and by compressing the file
 with the command specified with $maillog_file_compressor.
 This will not rotate /dev/* files.
 .sp
-This feature is available in Postfix 3.4 and later.
+.IP "\fBnon\-bdb\fR \fIsubcommand\fR"
+Migrate a Postfix configuration that uses Berkeley DB hash:
+or btree: tables, to a configuration that uses lmdb: or a
+combination of cdb: and lmdb:. This is needed because some
+(Linux) distributions have removed Berkeley DB support.
+See postfix\-nbdb(1) for documentation.
+.sp
+This feature is available in Postfix 3.11 and later.
 .IP "\fBtls\fR \fIsubcommand\fR"
 Enable opportunistic TLS in the Postfix SMTP client or
 server, and manage Postfix SMTP server TLS private keys and
@@ -297,6 +304,7 @@ postcat(1), examine Postfix queue file
 postconf(1), Postfix configuration utility
 postdrop(1), Postfix mail posting utility
 postfix(1), Postfix control program
+postfix\-non\-bdb(1), Postfix Non\-Berkeley\-DB migration
 postfix\-tls(1), Postfix TLS management
 postkick(1), trigger Postfix daemon
 postlock(1), Postfix\-compatible locking
index 3dd7a386468cfe9c9e9fd3f4f6dc19b7771306b1..2f74f5e2c45666cb2fcb90b590752e309bf9b677 100644 (file)
@@ -217,6 +217,11 @@ Arguments:
 The database type. To find out what types are supported, use
 the "\fBpostconf \-m\fR" command.
 
+When no \fIfile_type\fR is specified, the software uses the database
+type specified via the \fBdefault_database_type\fR configuration
+parameter.
+The default value for this parameter depends on the host environment.
+
 The \fBpostmap\fR(1) command can query any supported file type,
 but it can create only the following file types:
 .RS
@@ -246,10 +251,6 @@ This is available on systems with support for \fBlmdb\fR databases.
 The output consists of two files, named \fIfile_name\fB.pag\fR and
 \fIfile_name\fB.dir\fR.
 This is available on systems with support for \fBsdbm\fR databases.
-.PP
-When no \fIfile_type\fR is specified, the software uses the database
-type specified via the \fBdefault_database_type\fR configuration
-parameter.
 .RE
 .IP \fIfile_name\fR
 The name of the lookup table source file when rebuilding a database.
index efbde6204fc465727d8b6e42f02c96cae5fd9ded..fe5de3b47dfd4faff93d24a1cfb616479a070e9f 100644 (file)
@@ -24,14 +24,22 @@ Postfix SMTP server.  See \fBheader_checks\fR(5) or
 email messages.
 
 Normally, the \fBaccess\fR(5) table is specified as a text file
-that serves as input to the \fBpostmap\fR(1) command.
-The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-is used for fast searching by the mail system. Execute the
-command "\fBpostmap /etc/postfix/access\fR" to rebuild an
-indexed file after changing the corresponding text file.
+that serves as input to the \fBpostmap\fR(1) command to create
+an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/access\fR" to
+rebuild a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/access\fR" to
+specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
index c06f513dec6003967b350cb90be4135d6059212a..dc44546c20ec45465130eac10552f9b00c748755 100644 (file)
@@ -28,14 +28,24 @@ table is often searched with a full email address (including
 domain).
 
 Normally, the \fBaliases\fR(5) table is specified as a text file
-that serves as input to the \fBpostalias\fR(1) command. The
-result, an indexed file in \fBdbm\fR or \fBdb\fR format, is
-used for fast lookup by the mail system. Execute the command
-\fBnewaliases\fR in order to rebuild the indexed file after
-changing the Postfix alias database.
+that serves as input to the \fBpostalias\fR(1) command to create
+an indexed file for fast lookup. The location of this file is
+system\-dependent. This text will use \fB/path/to/aliases\fR.
+
+Execute the command "\fBnewaliases\fR to rebuild the indexed
+file after changing the text file. Execute "\fBpostalias \-q
+\fIname\fB /path/to/aliases\fR" to query a default\-type indexed
+file, or execute "\fBpostalias \-q \fIname\fB
+\fItype\fB:/path/to/aliases\fR" to specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions. In
index 8776f3b7d0a81ff8106871815616f3435d4d3cc2..a9eb267d6f69dbd6a6edb7385da50763407b6718 100644 (file)
@@ -22,14 +22,22 @@ local and non\-local addresses. The mapping is used by the
 queue.  The address mapping is recursive.
 
 Normally, the \fBcanonical\fR(5) table is specified as a text file
-that serves as input to the \fBpostmap\fR(1) command.
-The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-is used for fast searching by the mail system. Execute the command
-"\fBpostmap /etc/postfix/canonical\fR" to rebuild an indexed
-file after changing the corresponding text file.
+that serves as input to the \fBpostmap\fR(1) command to create
+an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/canonical\fR" to
+rebuild a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/canonical\fR"
+to specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
index 66a7a59c1a6f141e63cb68a9a0d488945536fd87..e1466a5b85a868a133f6104c954c2ea98ee3667c 100644 (file)
@@ -15,7 +15,9 @@ format of Postfix CIDR tables
 .ad
 .fi
 The Postfix mail system uses optional lookup tables.
-These tables are usually in \fBdbm\fR or \fBdb\fR format.
+These tables are usually in \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR,
+or \fBdbm:\fR format.
+
 Alternatively, lookup tables can be specified in CIDR
 (Classless Inter\-Domain Routing) form. In this case, each
 input is compared against a list of patterns. When a match
index b474530315819b176c8ad574b224dd29cfe16086..a9d06ad5622f4395204aeca832cda72049195354 100644 (file)
@@ -36,14 +36,21 @@ are used in SMTP protocol commands).
 
 Normally, the \fBgeneric\fR(5) table is specified as a
 text file that serves as input to the \fBpostmap\fR(1)
-command.  The result, an indexed file in \fBdbm\fR or
-\fBdb\fR format, is used for fast searching by the mail
-system. Execute the command "\fBpostmap /etc/postfix/generic\fR"
-to rebuild an indexed file after changing the corresponding
-text file.
+command to create an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/generic\fR" to
+rebuild  a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/generic\fR"
+to specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
index d5048b4e780a22add1c97e62afc620a91463d8d7..cbd3bbfe7c0b30b874e53a83d4c8359dbaca78e4 100644 (file)
@@ -16,9 +16,11 @@ Postfix LDAP client configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as LDAP databases.
+To find out what types of lookup tables your Postfix system
+supports use the "\fBpostconf \-m\fR" command.
 
 In order to use LDAP lookups, define an LDAP source as a lookup
 table in main.cf, for example:
index 8d90a3df3c89f09de660fc2ee8d2cff0c8fbb304..a560af512bdfe206e41a06420cc7e1bf6d507c31 100644 (file)
@@ -16,10 +16,10 @@ Postfix memcache client configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as memcache
-instances.  To use memcache lookups, define a memcache
+instances. To use memcache lookups, define a memcache
 source as a lookup table in main.cf, for example:
 
 .nf
index cfbedf37abbfbb01300e9287e253902a67592fd7..f513ee4f70dbd90a1f624ff31a1a80e65e3f70de 100644 (file)
@@ -16,10 +16,14 @@ Postfix MongoDB client configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as MongoDB
-databases.  In order to use MongoDB lookups, define a MongoDB
+databases.
+To find out what types of lookup tables your Postfix system
+supports use the "\fBpostconf \-m\fR" command.
+
+In order to use MongoDB lookups, define a MongoDB
 source as a lookup table in main.cf, for example:
 .nf
     alias_maps = mongodb:/etc/postfix/mongodb\-aliases.cf
index 20244ec30325588038f5956a3958c8e597a887cd..d32a94cc188924b9ca9ec44a1e2beac39649e038 100644 (file)
@@ -16,9 +16,12 @@ Postfix MySQL/MariaDB client configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as MySQL databases.
+To find out what types of lookup tables your Postfix system
+supports use the "\fBpostconf \-m\fR" command.
+
 In order to use MySQL lookups, define a MySQL source as a lookup
 table in main.cf, for example:
 .nf
index 79176a17c1ffe16072b9cc81204d5f6f2cd67c37..9ed2e43b2c05cca582e13d218914c47c6d250f56 100644 (file)
@@ -15,10 +15,11 @@ Postfix NIS+ client
 .ad
 .fi
 The Postfix mail system uses optional lookup tables.
-These tables are usually in \fBdbm\fR or \fBdb\fR format.
+rewriting or mail routing. These tables are usually in
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
+
 Alternatively, lookup tables can be specified as NIS+
 databases.
-
 To find out what types of lookup tables your Postfix system
 supports use the "\fBpostconf \-m\fR" command.
 
index a112e7f68aa6617b0f46ac954a763908e47a1455..6e781cd8f4c2eb3a5b48c82f56a489a59cb1aeab 100644 (file)
@@ -19,8 +19,8 @@ format of Postfix PCRE tables
 .ad
 .fi
 The Postfix mail system uses optional tables for address
-rewriting, mail routing, or access control. These tables
-are usually in \fBdbm\fR or \fBdb\fR format.
+rewriting or mail routing. These tables are usually in
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified in Perl Compatible
 Regular Expression form. In this case, each input is compared
index 1deaa3fe89a01c8cca5a21b20d66551908a97585..fa94c2cf959861907cb9ea30b33d727ef6ae9dda 100644 (file)
@@ -16,10 +16,14 @@ Postfix PostgreSQL client configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as PostgreSQL
-databases.  In order to use PostgreSQL lookups, define a
+databases.
+To find out what types of lookup tables your Postfix system
+supports use the "\fBpostconf \-m\fR" command.
+
+In order to use PostgreSQL lookups, define a
 PostgreSQL source as a lookup table in main.cf, for example:
 .nf
     alias_maps = pgsql:/etc/postfix/pgsql\-aliases.cf
index 3a172c0ecd57807ba6cff23f09a02e5e3bffa0f6..57ef2015c79673f658678f4e84e50b02b8f37268 100644 (file)
@@ -160,7 +160,7 @@ Examples:
 .nf
 .na
 address_verify_map = $default_cache_db_type:$data_directory/verify_cache
-address_verify_map = hash:/var/lib/postfix/verify_cache
+address_verify_map = lmdb:/var/lib/postfix/verify_cache
 address_verify_map = btree:/var/lib/postfix/verify_cache
 .fi
 .ad
@@ -351,10 +351,13 @@ Examples:
 .PP
 .nf
 .na
-alias_database = hash:/etc/aliases
-alias_database = hash:/etc/mail/aliases
+alias_database = $default_database_type:/etc/aliases
+alias_database = lmdb:/etc/aliases
+alias_database = lmdb:/etc/mail/aliases
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 .SH alias_maps (default: see "postconf \-d" output)
 Optional lookup tables that are searched only with an email address
 localpart (no domain) and that apply only to \fBlocal\fR(8) recipients;
@@ -374,10 +377,6 @@ The default list is system dependent.  On systems with NIS, the
 default is to search the local alias database, then the NIS alias
 database.
 .PP
-If you change the alias database, run "\fBpostalias /etc/aliases\fR"
-(or wherever your system stores the mail alias file), or simply
-run "\fBnewaliases\fR" to build the necessary DBM or DB file.
-.PP
 The \fBlocal\fR(8) delivery agent disallows regular expression substitution
 of $1 etc. in alias_maps, because that would open a security hole.
 .PP
@@ -390,10 +389,26 @@ Examples:
 .PP
 .nf
 .na
-alias_maps = hash:/etc/aliases, nis:mail.aliases
-alias_maps = hash:/etc/aliases
+alias_maps = $default_database_type:/etc/aliases, nis:mail.aliases
+alias_maps = $default_database_type:/etc/aliases
+alias_maps = lmdb:/etc/mail/aliases
+alias_maps = lmdb:/etc/aliases
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postalias \fI/path/to/aliases\fR" after you
+change the aliases file, to (re)build a default\-type indexed file.
+Execute "postalias \fItype:/path/to/aliases\fR" to specify an explicit
+type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH allow_mail_to_commands (default: alias, forward)
 Restrict \fBlocal\fR(8) mail delivery to external commands.  The default
 is to disallow delivery to "|command" in :include:  files (see
@@ -847,11 +862,6 @@ whitespace or comma. Tables will be searched in the specified order
 until a match is found.
 Note: these lookups are recursive.
 .PP
-If you use this feature, run "\fBpostmap /etc/postfix/canonical\fR" to
-build the necessary DBM or DB file after every change. The changes
-will become visible after a minute or so.  Use "\fBpostfix reload\fR"
-to eliminate the delay.
-.PP
 Note: with Postfix version 2.2, message header address mapping
 happens only when message header address rewriting is enabled:
 .IP \(bu
@@ -871,10 +881,23 @@ Examples:
 .PP
 .nf
 .na
-canonical_maps = dbm:/etc/postfix/canonical
-canonical_maps = hash:/etc/postfix/canonical
+canonical_maps = lmdb:/etc/postfix/canonical
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/canonical" after you
+change the canonical file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/canonical" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH cleanup_replace_stray_cr_lf (default: yes)
 Replace each stray <CR> or <LF> character in message
 content with a space character, to prevent outbound SMTP smuggling,
@@ -1237,15 +1260,15 @@ This feature is available in Postfix >= 3.11.
 .SH default_database_type (default: see "postconf \-d" output)
 The default database type for use in \fBnewaliases\fR(1), \fBpostalias\fR(1)
 and \fBpostmap\fR(1) commands. On many UNIX systems the default type is
-either \fBdbm\fR or \fBhash\fR. The default setting is frozen
+either \fBlmdb\fR or \fBhash\fR. The default setting is frozen
 when the Postfix system is built.
 .PP
 Examples:
 .PP
 .nf
 .na
+default_database_type = lmdb
 default_database_type = hash
-default_database_type = dbm
 .fi
 .ad
 .SH default_delivery_slot_cost (default: 5)
@@ -3860,10 +3883,12 @@ system.
 .na
 local_header_rewrite_clients = permit_mynetworks,
     permit_sasl_authenticated permit_tls_clientcerts
-    check_address_map hash:/etc/postfix/pop\-before\-smtp
+    check_address_map lmdb:/etc/postfix/pop\-before\-smtp
 .fi
 .ad
 .in -4
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
 .SH local_login_sender_maps (default: static:*)
 A list of lookup tables that are searched by the UNIX login name,
 and that return a list of allowed envelope sender patterns separated
@@ -4951,10 +4976,15 @@ mynetworks = 127.0.0.0/8 168.100.189.0/28
 mynetworks = !192.168.0.1, 192.168.0.0/28
 mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:587::]/64
 mynetworks = $config_directory/mynetworks
-mynetworks = hash:/etc/postfix/network_table
+mynetworks = lmdb:/etc/postfix/network_table
 mynetworks = cidr:/etc/postfix/network_table.cidr
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH mynetworks_style (default: Postfix >= 3.0: host, Postfix < 3.0: subnet)
 The method to generate the default value for the mynetworks parameter.
 This is the list of trusted networks for relay access control etc.
@@ -4999,6 +5029,74 @@ This feature is available in Postfix 2.0 and later.
 Sendmail compatibility feature that specifies the location of the
 \fBnewaliases\fR(1) command. This command can be used to rebuild the
 \fBlocal\fR(8) \fBaliases\fR(5) database.
+.SH non_bdb_custom_mapping (default: empty)
+When non\-Berkeley\-DB migration is enabled, an optional mapping
+from a hash: or btree: type to a non\-Berkeley\-DB type. This mapping
+takes precedence over the default mapping from hash: to
+$default_database_type, and from btree: to $default_cache_db_type.
+.IP \(bu
+Specify a lookup table with a search keys that are a
+Berkeley DB \fItype\fR (without ':') or \fItype:name\fR.
+.IP \(bu
+A search key with the form \fItype:name\fR takes precedence
+over \fItype\fR (without ':').
+.IP \(bu
+The lookup result must always be a non\-Berkeley\-DB \fItype\fR
+(without ':') and must not contain a \fI:name\fR.
+.IP \(bu
+The mapping table type must not be \fBhash\fR or \fBbtree\fR.
+.br
+.PP
+This feature is available in Postfix >= 3.11.
+.SH non_bdb_migration_allow_root_prefixes (default: see 'postconf \-d non_bdb_migration_allow_root_prefixes' output)
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with "root" privilege.
+.PP
+This feature is available in Postfix >= 3.11.
+.SH non_bdb_migration_allow_user_prefixes (default: see 'postconf \-d non_bdb_migration_allow_user_prefixes' output)
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with non\-root privilege.
+.PP
+This feature is available in Postfix >= 3.11.
+.SH non_bdb_migration_level (default: disable)
+The non\-Berkeley\-DB migration service level. You are expected to use
+the command "\fBpostfix non\-bdb \fIname\-of\-level\fR\fR" to correctly
+configure the migration service level (see postfix\-non\-\fBbdb\fR(1).
+.IP "\fBdisable\fR"
+Disable all non\-Berkeley\-DB migration features. See
+NON_BERKELEYDB_README#disable for possible negative implications
+for integration with other software such as mailman.
+.br
+.IP "\fBenable\-redirect\fR (aliasing)"
+Enable redirection (aliasing) from Berkeley DB hash to
+$default_database_type, and from Berkeley DB btree to
+$default_cache_db_type, but do not automatically create the new cdb
+or lmdb indexed database files that Postfix programs need. See
+NON_BERKELEYDB_README#enable\-redirect for details and limitations.
+.br
+.IP "\fBenable\-reindex\fR"
+In addition to enable\-redirect, also create a non\-Berkeley\-DB
+indexed database file when a daemon program wants to access a file
+that does not yet exist. This feature uses the \fBnbdb_reindexd\fR(8)
+daemon to run \fBpostmap\fR(1) or \fBpostalias\fR(1).   See
+NON_BERKELEYDB_README#enable\-reindex for details and limitations.
+.PP
+\fI NOTE: \fBenable\-reindex\fR should be used only temporarily to
+generate most of the non\-Berkeley\-DB indexed database files that Postfix
+programs need. Leaving this level enabled may expose the system to
+privilege\-escalation attacks. There are no security concerns for using
+\fBenable\-redirect\fR. \fR
+.br
+.br
+.PP
+This feature is available in Postfix >= 3.11.
+.SH non_bdb_migration_service_name (default: nbdb_reindex)
+The name of a master.cf service that implements the non\-Berkeley\-DB
+migration service protocol.
+.PP
+This feature is available in Postfix >= 3.11.
 .SH non_empty_end_of_header_action (default: fix_quietly)
 How the \fBcleanup\fR(8) daemon will process a message when the primary
 message header is terminated with a non\-empty line.
@@ -5033,6 +5131,7 @@ to=<\fIrecipient\fR>
 .fi
 .ad
 .br
+.br
 .PP
 This feature is available in Postfix >= 3.11.
 .SH non_fqdn_reject_code (default: 504)
@@ -5433,8 +5532,8 @@ This feature is available in Postfix 2.8.
 Persistent storage for the \fBpostscreen\fR(8) server decisions.
 .PP
 To share a \fBpostscreen\fR(8) cache between multiple \fBpostscreen\fR(8)
-instances, use "postscreen_cache_map = proxy:btree:/path/to/file"
-or "proxy:lmdb:/path/to/file".
+instances, use "postscreen_cache_map = proxy:lmdb:/path/to/file"
+or "proxy:btree:/path/to/file".
 This requires Postfix version 2.9 or later; earlier \fBproxymap\fR(8)
 implementations don't support cache cleanup. For an alternative
 approach see the \fBmemcache_table\fR(5) manpage.
@@ -6225,7 +6324,7 @@ Example:
 .nf
 .na
 /etc/postfix/main.cf:
-    rbl_reply_maps = hash:/etc/postfix/rbl_reply
+    rbl_reply_maps = lmdb:/etc/postfix/rbl_reply
     smtpd_recipient_restrictions =
         permit_mynetworks,
         reject_rbl_client \fIsecret\fR.zen.dq.spamhaus.net=127.0.0.[2..11],
@@ -6250,11 +6349,25 @@ Example:
 .fi
 .ad
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
 NOTE: This feature differs from postscreen_dnsbl_reply_map where
 the table search key is only a domain name (no "\fI=address\-filter\fR",
 no "\fI*weight\fR" factor) and where the lookup result
 should be only a domain name (no free text, no \fI$name\fR variables).
 .PP
+Execute the command "postmap /etc/postfix/rbl_reply" after you
+change the rbl_reply file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/rbl_reply" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 2.0 and later.
 The "=address\-filter" feature is available in Postfix 2.8 and later.
 .SH readme_directory (default: see "postconf \-d" output)
@@ -6354,11 +6467,23 @@ Example:
 .PP
 .nf
 .na
-recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
+recipient_bcc_maps = lmdb:/etc/postfix/recipient_bcc
 .fi
 .ad
 .PP
-After a change, run "\fBpostmap /etc/postfix/recipient_bcc\fR".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/recipient_bcc" after
+you change the recipient_bcc file, to (re)build a default\-type indexed
+file.  Execute "postmap \fItype\fR:/etc/postfix/recipient_bcc" to
+specify an explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .PP
 This feature is available in Postfix 2.1 and later.
 .SH recipient_canonical_classes (default: envelope_recipient, header_recipient)
@@ -6381,9 +6506,24 @@ Example:
 .PP
 .nf
 .na
-recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
+recipient_canonical_maps = lmdb:/etc/postfix/recipient_canonical
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/recipient_canonical"
+after you change the recipient_canonical file, to (re)build a
+default\-type indexed file.  Execute "postmap
+\fItype\fR:/etc/postfix/recipient_canonical" to specify an explicit
+type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH recipient_delimiter (default: empty)
 The set of characters that can separate an email address
 localpart, user name, or a .forward file name from its extension.
@@ -6485,14 +6625,28 @@ Example:
 .PP
 .nf
 .na
-relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+relay_clientcerts = lmdb:/etc/postfix/relay_clientcerts
 .fi
 .ad
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
 For more fine\-grained control, use check_ccert_access to select
 an appropriate \fBaccess\fR(5) policy for each client.
 See RESTRICTION_CLASS_README.
 .PP
+Execute the command "postmap /etc/postfix/relay_clientcerts"
+after you change the relay_clientcerts file, to (re)build a default\-type
+indexed file.  Execute "postmap \fItype\fR:/etc/postfix/relay_clientcerts"
+to specify an explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available with Postfix version 2.2.
 .SH relay_destination_concurrency_limit (default: $default_destination_concurrency_limit)
 The maximal number of parallel deliveries to the same destination
@@ -6571,10 +6725,24 @@ Example:
 .PP
 .nf
 .na
-relay_recipient_maps = hash:/etc/postfix/relay_recipients
+relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
 .fi
 .ad
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/relay_recipients"
+after you change the relay_recipients file, to (re)build a default\-type
+indexed file.  Execute "postmap \fItype\fR:/etc/postfix/relay_recipients"
+to specify an explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 2.0 and later.
 .SH relay_transport (default: relay)
 The default mail delivery transport and next\-hop destination for
@@ -6662,18 +6830,27 @@ Specify zero or more "type:name" lookup tables, separated by
 whitespace or comma. Tables will be searched in the specified order
 until a match is found.
 .PP
-If you use this feature, run "\fBpostmap /etc/postfix/relocated\fR" to
-build the necessary DBM or DB file after change, then "\fBpostfix
-reload\fR" to make the changes visible.
-.PP
 Examples:
 .PP
 .nf
 .na
-relocated_maps = dbm:/etc/postfix/relocated
-relocated_maps = hash:/etc/postfix/relocated
+relocated_maps = lmdb:/etc/postfix/relocated
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/relocated" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH relocated_prefix_enable (default: yes)
 Prepend the prefix "\fB5.1.6 User has moved to \fR" to all
 relocated_maps lookup results. With "relocated_prefix_enable =
@@ -6685,13 +6862,29 @@ Example:
 .nf
 .na
 /etc/postfix/main.cf:
-    relocated_maps = hash:/etc/postfix/relocated
+    relocated_maps = lmdb:/etc/postfix/relocated
     relocated_prefix_enable = no
 .br
-hash:/etc/postfix/relocated:
+/etc/postfix/relocated:
     user@example.com 5.2.1 User account is disabled
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/relocated" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
+This feature is available in Postfix 3.11 and later.
 .SH remote_header_rewrite_domain (default: empty)
 Rewrite or add message headers in mail from remote clients if
 the remote_header_rewrite_domain parameter value is non\-empty,
@@ -6951,11 +7144,23 @@ Example:
 .PP
 .nf
 .na
-sender_bcc_maps = hash:/etc/postfix/sender_bcc
+sender_bcc_maps = lmdb:/etc/postfix/sender_bcc
 .fi
 .ad
 .PP
-After a change, run "\fBpostmap /etc/postfix/sender_bcc\fR".
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/sender_bcc" after you
+change the sender_bcc file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/sender_bcc" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .PP
 This feature is available in Postfix 2.1 and later.
 .SH sender_canonical_classes (default: envelope_sender, header_sender)
@@ -6981,9 +7186,23 @@ Example:
 .PP
 .nf
 .na
-sender_canonical_maps = hash:/etc/postfix/sender_canonical
+sender_canonical_maps = lmdb:/etc/postfix/sender_canonical
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/sender_canonical"
+after you change the sender_canonical file, to (re)build a default\-type
+indexed file.  Execute "postmap \fItype\fR:/etc/postfix/sender_canonical"
+to specify an explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH sender_dependent_default_transport_maps (default: empty)
 A sender\-dependent override for the global default_transport
 parameter setting. The tables are searched by the envelope sender
@@ -7221,7 +7440,7 @@ transport_maps to apply this feature selectively:
 .nf
 .na
 /etc/postfix/main.cf:
-    transport_maps = hash:/etc/postfix/transport
+    transport_maps = lmdb:/etc/postfix/transport
 .fi
 .ad
 .in -4
@@ -7248,10 +7467,24 @@ transport_maps to apply this feature selectively:
 .ad
 .in -4
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
 Unselective use of the "data" target does no harm, but will
 result in unnecessary "lost connection after DATA" events at remote
 SMTP/LMTP servers.
 .PP
+Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/transport" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 3.0 and later.
 .SH smtp_always_send_ehlo (default: yes)
 Always send EHLO at the start of an SMTP session.
@@ -8246,7 +8479,7 @@ A non\-ASCII next\-hop destination is converted into ASCII form
 (Punycode) before making a policy query; lookup tables must answer
 ASCII\-form queries.
 .IP \(bu
-A fixed\-string table (such as hash:, btree:, or lmdb:) is
+A fixed\-string table (such as lmdb:, cdb:, or hash:) is
 also searched with the next\-hop ".parent" domains (in a table key,
 prepend a '.' to a parent domain name). These ".parent" domain
 queries are not made with pattern\-based lookup tables such as regexp:
@@ -8336,7 +8569,7 @@ Notes:
 To match any name below the domain "example.com" specify
 a table entry with the storage key ".example.com" in type:table
 lookup tables that need an exact match. This is appropriate, for
-example, with hash:, btree: or lmdb:.
+example, with lmdb:, cdb: or hash:.
 .IP \(bu
 Do not specify a match pattern for ".domain" with regexp:,
 pcre:, socketmap:, or tcp:, as smtp_requiretls_policy will
@@ -8445,7 +8678,7 @@ file for easier maintenance.
         cidr:{
             { 0.0.0.0/0 opportunistic },
             { ::/0 opportunistic } },
-        hash:/etc/postfix/requiretls\-per\-site
+        lmdb:/etc/postfix/requiretls\-per\-site
         opportunistic+starttls
 .sp
 /etc/postfix/requiretls\-per\-site:
@@ -8455,6 +8688,20 @@ file for easier maintenance.
     ...
 .fi
 .ad
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/requiretls\-per\-site"
+after you change the requiretls\-per\-site file, to (re)build a
+default\-type indexed file.  Execute "postmap
+\fItype\fR:/etc/postfix/requiretls\-per\-site" to specify an explicit
+type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .br
 .PP
 LMTP client examples. See REQUIRETLS_README for discussion.
@@ -8518,8 +8765,8 @@ Examples:
 .PP
 .nf
 .na
-smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
 smtp_sasl_auth_cache_name = proxy:lmdb:/var/lib/postfix/sasl_auth_cache
+smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
 .fi
 .ad
 .PP
@@ -9353,7 +9600,7 @@ As in the example above, we show two matching fingerprints:
 .nf
 .na
 /etc/postfix/main.cf:
-    smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+    smtp_tls_policy_maps = lmdb:/etc/postfix/tls_policy
     smtp_tls_fingerprint_digest = sha256
 .fi
 .ad
@@ -9370,6 +9617,20 @@ As in the example above, we show two matching fingerprints:
 .ad
 .in -4
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/tls_policy" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 2.5 and later.
 .SH smtp_tls_fingerprint_digest (default: see "postconf \-d" output)
 The message digest algorithm used to construct remote SMTP server
@@ -9959,7 +10220,7 @@ Example:
 .nf
 .na
 /etc/postfix/main.cf:
-    smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+    smtp_tls_policy_maps = lmdb:/etc/postfix/tls_policy
     # Postfix 2.5 and later.
     #
     # The default digest is sha256 with Postfix >= 3.6 and
@@ -9986,12 +10247,26 @@ Example:
 .fi
 .ad
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
 \fBNote:\fR The "hostname" strategy if listed in a non\-default
 setting of smtp_tls_secure_cert_match or in the "match" attribute
 in the policy table can 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.
 .PP
+Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/tls_policy" to specify
+an explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 2.3 and later.
 .SH smtp_tls_protocols (default: see 'postconf \-d' output)
 TLS protocols that the Postfix SMTP client will use with
@@ -10331,7 +10606,7 @@ This feature is available in Postfix 3.4 and later.
 .SH smtp_tls_session_cache_database (default: empty)
 Name of the file containing the optional Postfix SMTP client
 TLS session cache. Specify a database type that supports enumeration,
-such as \fBbtree\fR or \fBsdbm\fR; there is no need to support
+such as \fBlmdb\fR or \fBbtree\fR; there is no need to support
 concurrent access.  The file is created if it does not exist. The \fBsmtp\fR(8)
 daemon does not use this parameter directly, rather the cache is
 implemented indirectly in the \fBtlsmgr\fR(8) daemon. This means that
@@ -10355,8 +10630,8 @@ Example:
 .PP
 .nf
 .na
-smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
 smtp_tls_session_cache_database = lmdb:/var/lib/postfix/smtp_scache
+smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
 .fi
 .ad
 .PP
@@ -13105,9 +13380,23 @@ Examples:
 .na
 smtpd_sender_restrictions = reject_unknown_sender_domain
 smtpd_sender_restrictions = reject_unknown_sender_domain,
-    check_sender_access hash:/etc/postfix/access
+    check_sender_access lmdb:/etc/postfix/access
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/access" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH smtpd_service_name (default: smtpd)
 The internal service that \fBpostscreen\fR(8) hands off allowed
 connections to. In a future version there may be different
@@ -13883,7 +14172,7 @@ Example: client\-certificate access table, with sha256 fingerprints:
 /etc/postfix/main.cf:
     smtpd_tls_fingerprint_digest = sha256
     smtpd_client_restrictions =
-        check_ccert_access hash:/etc/postfix/access,
+        check_ccert_access lmdb:/etc/postfix/access,
         reject
 .sp
 /etc/postfix/access:
@@ -13896,6 +14185,20 @@ Example: client\-certificate access table, with sha256 fingerprints:
 .ad
 .in -4
 .PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/access" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
+.PP
 This feature is available in Postfix 2.5 and later.
 .SH smtpd_tls_key_file (default: $smtpd_tls_cert_file)
 File with the Postfix SMTP server RSA private key in PEM format.
@@ -14251,8 +14554,8 @@ Examples:
 .PP
 .nf
 .na
-smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
 smtpd_tls_session_cache_database = lmdb:/var/lib/postfix/smtpd_scache
+smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
 .fi
 .ad
 .PP
@@ -15929,9 +16232,7 @@ $sender_dependent_default_transport_maps, or the recipient domain.
 .PP
 Specify zero or more "type:table" lookup tables, separated by
 whitespace or comma. Tables will be searched in the specified order
-until a match is found.  If you use this
-feature with local files, run "\fBpostmap /etc/postfix/transport\fR"
-after making a change.
+until a match is found.
 .PP
 Pattern matching of domain names is controlled by the presence
 or absence of "transport_maps" in the parent_domain_matches_subdomains
@@ -15944,10 +16245,23 @@ Examples:
 .PP
 .nf
 .na
-transport_maps = dbm:/etc/postfix/transport
-transport_maps = hash:/etc/postfix/transport
+transport_maps = lmdb:/etc/postfix/transport
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/transport" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH transport_minimum_delivery_slots (default: $default_minimum_delivery_slots)
 A transport\-specific override for the default_minimum_delivery_slots
 parameter value, where \fItransport\fR is the master.cf name of
@@ -16389,17 +16703,27 @@ whitespace or comma. Tables will be searched in the specified order
 until a match is found.
 Note: these lookups are recursive.
 .PP
-If you use this feature with indexed files, run "\fBpostmap
-/etc/postfix/virtual\fR" after changing the file.
-.PP
 Examples:
 .PP
 .nf
 .na
-virtual_alias_maps = dbm:/etc/postfix/virtual
-virtual_alias_maps = hash:/etc/postfix/virtual
+virtual_alias_maps = lmdb:/etc/postfix/virtual
 .fi
 .ad
+.PP
+Instead of lmdb:, some systems use cdb:, hash:, or dbm:.
+.PP
+Execute the command "postmap /etc/postfix/virtual" after you
+change the virtual file, to (re)build a default\-type indexed file.
+Execute "postmap \fItype\fR:/etc/postfix/virtual" to specify an
+explicit type.
+.PP
+The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf \-m".
+.PP
+Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay.
 .SH virtual_alias_recursion_limit (default: 1000)
 The maximal nesting depth of virtual alias expansion.  Currently
 the recursion limit is applied only to the left branch of the
index 91c6f23a3f330b4a689dd8d5feab578f6ffe1ea7..f13b8354db9f545ab3a56c7b6f7a7b82a55a8fb4 100644 (file)
@@ -15,8 +15,8 @@ format of Postfix regular expression tables
 .ad
 .fi
 The Postfix mail system uses optional tables for address
-rewriting, mail routing, or access control. These tables
-are usually in \fBdbm\fR or \fBdb\fR format.
+rewriting or mail routing. These tables are usually in
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified in POSIX regular
 expression form. In this case, each input is compared against a
index ecc77748e0997692752fd29d9f2d07c4295e5c76..1e8bea353f5a87f6f49b4946d9b9bdf4cb7eaebb 100644 (file)
@@ -16,14 +16,22 @@ The optional \fBrelocated\fR(5) table provides the information that is
 used in "user has moved to \fInew_location\fR" bounce messages.
 
 Normally, the \fBrelocated\fR(5) table is specified as a text file
-that serves as input to the \fBpostmap\fR(1) command.
-The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-is used for fast searching by the mail system. Execute the command
-"\fBpostmap /etc/postfix/relocated\fR" to rebuild an indexed
-file after changing the corresponding relocated table.
+that serves as input to the \fBpostmap\fR(1) command to create
+an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/relocated\fR" to
+rebuild a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/relocated\fR" to
+specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
index 693bb60eab897bee726664de9529e0ea7dc18c97..620d20f5310dc1ed98c581d14f687b043f50f79e 100644 (file)
@@ -19,7 +19,8 @@ Postfix socketmap table lookup client
 .ad
 .fi
 The Postfix mail system uses optional tables for address
-rewriting, mail routing or policy lookup.
+rewriting or mail routing. These tables are usually in
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 The Postfix socketmap client expects TCP endpoint names of
 the form \fBinet:\fIhost\fB:\fIport\fB:\fIname\fR, or
index c0655976b9ccc0106c644505dacbf7ed1cd2d44d..7e878a18d395792097b97fcfc16e514992774a2e 100644 (file)
@@ -16,9 +16,12 @@ Postfix SQLite configuration
 .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.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
 Alternatively, lookup tables can be specified as SQLite databases.
+To find out what types of lookup tables your Postfix system
+supports use the "\fBpostconf \-m\fR" command.
+
 In order to use SQLite lookups, define an SQLite source as a lookup
 table in main.cf, for example:
 .nf
index 02a79898fe74cb45958afa67c8184262a03b3bb4..bd743f7f58a87bfa579df7ecfe5c46850f72e613 100644 (file)
@@ -16,12 +16,9 @@ Postfix client/server table lookup protocol
 .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, table lookups
-can be directed to a TCP server.
-
-To find out what types of lookup tables your Postfix system
-supports use the "\fBpostconf \-m\fR" command.
+\fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 
+Alternatively, table lookups can be directed to a TCP server.
 To test lookup tables, use the "\fBpostmap \-q\fR" command as
 described in the SYNOPSIS above.
 .SH "PROTOCOL DESCRIPTION"
index 88f5b24ed01b493cc5fb1fe13100c8abba3e5172..c0a99729969b26dd1f24476ea0ae376f8d607b81 100644 (file)
@@ -59,14 +59,22 @@ destination is taken from \fBtransport_maps\fR,
 \fBrelayhost\fR, or from the recipient domain.
 .PP
 Normally, the \fBtransport\fR(5) table is specified as a text file
-that serves as input to the \fBpostmap\fR(1) command.
-The result, an indexed file in \fBdbm\fR or \fBdb\fR format, is used
-for fast searching by the mail system. Execute the command
-"\fBpostmap /etc/postfix/transport\fR" to rebuild an indexed
-file after changing the corresponding transport table.
+that serves as input to the \fBpostmap\fR(1) command to create
+an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/transport\fR" to
+rebuild a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/transport\fR" to
+specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
index 15f87d93abd4f5f573d4a2ddbfad28f9dd67bb81..a2e120e8a23f1c6207bc106b1172d18095fc3063 100644 (file)
@@ -48,14 +48,22 @@ Use \fBcanonical\fR(5)
 mapping to rewrite header and envelope addresses in general.
 
 Normally, the \fBvirtual\fR(5) alias table is specified as a text file
-that serves as input to the \fBpostmap\fR(1) command.
-The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-is used for fast searching by the mail system. Execute the command
-"\fBpostmap /etc/postfix/virtual\fR" to rebuild an indexed
-file after changing the corresponding text file.
+that serves as input to the \fBpostmap\fR(1) command to create
+an indexed file for fast lookup.
+
+Execute the command "\fBpostmap /etc/postfix/virtual\fR" to
+rebuild a default\-type indexed file after changing the text file,
+or execute "\fBpostmap \fItype\fB:/etc/postfix/virtual\fR" to
+specify an explicit type.
+
+The default indexed file type is configured with the
+default_database_type parameter. Depending on the platform this
+may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+\&':').
 
 When the table is provided via other means such as NIS, LDAP
 or SQL, the same lookups are done as for ordinary indexed files.
+Managing such databases is outside the scope of Postfix.
 
 Alternatively, the table can be provided as a regular\-expression
 map where patterns are given as regular expressions, or lookups
diff --git a/postfix/man/man8/nbdb_reindexd.8 b/postfix/man/man8/nbdb_reindexd.8
new file mode 100644 (file)
index 0000000..af459ca
--- /dev/null
@@ -0,0 +1,167 @@
+.TH NBDB_REINDEXD 8 
+.ad
+.fi
+.SH NAME
+nbdb_reindexd
+\-
+Postfix non\-Berkeley\-DB migration
+.SH "SYNOPSIS"
+.na
+.nf
+\fBnbdb_reindexd\fR [generic Postfix daemon options]
+.SH DESCRIPTION
+.ad
+.fi
+\fINOTE: This service should be enabled only temporarily to
+generate most of the non\-Berkeley\-DB indexed files that Postfix
+needs. Leaving this service enabled may expose the system to
+privilege\-escalation attacks.\fR
+
+The nbdb_reindexd(8) server handles requests to generate
+a non\-Berkeley\-DB indexed database file for an existing Berkeley
+DB database (example: "hash:/path/to/file" or
+"btree:/path/to/file"). It implements the service by running
+the postmap(1) or postalias(1) command with appropriate
+privileges.
+
+The service reports a success status when the non\-Berkeley\-DB
+indexed file already exists. This can happen when multiple clients
+make the same request. When one request is completed successfully,
+the service also reports success for the other requests.
+
+This service enforces the following safety policy:
+.IP \(bu
+The legacy Berkeley DB indexed file must exist (file name ends in
+".db"). The nbdb_reindexd(8) service will use the owner"s (uid,
+gid) of this file, when it runs postmap(1) or postalias(1). It
+also uses the (uid,gid) for a number of safety checks as
+described next.
+.IP \(bu
+The non\-indexed source file must exist (file name without
+".db"  suffix). This file is needed as input for postmap(1)
+or postalias(1). The file must be owned by "root" or by the
+above uid, and must not allow "group" or "other" write access.
+.IP \(bu
+The parent directory must be owned by "root" or by the above uid,
+and it must not allow "group" or "other" write access.
+.IP \(bu
+Additionally, the "non_bdb_migration_allow_root_prefixes"
+parameter limits the source file directory prefixes that are
+allowed when this service needs to run postmap(1) or postalias(1)
+with "root" privileges.
+.IP \(bu
+A similar parameter, "non_bdb_migration_allow_user_prefixes",
+limits the source file directory prefixes that are allowed when
+this service needs to run postmap(1) or postalias(1) as an
+unprivileged user.
+.SH "SECURITY"
+.na
+.nf
+.ad
+.fi
+The nbdb_reindexd(8) server is security sensitive.  It accepts
+requests only from processes that can access sockets under
+$queue_directory/private (i.e., processes that run with "root"
+or "mail_owner" (usually, postfix) privileges).
+
+The threat is therefore a corrupted Postfix daemon process that
+wants to elevate privileges, by sending requests with crafted
+pathnames, and racing against the service by quickly swapping
+files or directories, hoping that Postfix will be tricked to
+overwrite a sensitive file with attacker\-controlled data.
+
+When the service runs postmap(1) or postalias(1) as
+"root", such racing attacks should not be possible if
+non_bdb_migration_allow_root_prefixes specifies only prefixes
+that are already trusted.
+
+This service could block all requests with crafted pathnames,
+if given complete information about all lookup tables that are
+referenced through Postfix configuration files. Unfortunately
+that information was not available at the time that this program
+was needed.
+.SH DIAGNOSTICS
+.ad
+.fi
+Problems and transactions are logged to syslogd(8) or
+postlogd(8). If an attempt to create an index file fails, this
+service will attempt to delete the incomplete file.
+.SH "CONFIGURATION PARAMETERS"
+.na
+.nf
+.ad
+.fi
+Changes to main.cf are not picked up automatically, as
+nbdb_reindexd(8) processes are long\-lived. Use the command
+"postfix reload" after a configuration change.
+
+The text below provides only a parameter summary. See
+postconf(5) for more details including examples.
+.SH "SERVICE-SPECIFIC CONTROLS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBnon_bdb_migration_level (disable)\fR"
+The non\-Berkeley\-DB migration service level.
+.IP "\fBnon_bdb_migration_allow_root_prefixes (see 'postconf -d non_bdb_migration_allow_root_prefixes' output)\fR"
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with "root" privilege.
+.IP "\fBnon_bdb_migration_allow_user_prefixes (see 'postconf -d non_bdb_migration_allow_user_prefixes' output)\fR"
+A list of trusted pathname prefixes that must be matched when
+the non\-Berkeley\-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with non\-root privilege.
+.SH "MISCELLANEOUS CONTROLS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+The default location of the Postfix main.cf and master.cf
+configuration files.
+.IP "\fBprocess_id (read\-only)\fR"
+The process ID of a Postfix command or daemon process.
+.IP "\fBprocess_name (read\-only)\fR"
+The process name of a Postfix command or daemon process.
+.IP "\fBsyslog_facility (mail)\fR"
+The syslog facility of Postfix logging.
+.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
+A prefix that is prepended to the process name in syslog
+records, so that, for example, "smtpd" becomes "prefix/smtpd".
+.IP "\fBservice_name (read\-only)\fR"
+The master.cf service name of a Postfix daemon process.
+.SH "SEE ALSO"
+.na
+.nf
+postfix\-non\-bdb(1), migration management
+postconf(5), configuration parameters
+postlogd(8), Postfix logging
+syslogd(8), system logging
+.SH "README FILES"
+.na
+.nf
+.ad
+.fi
+Use "\fBpostconf readme_directory\fR" or
+"\fBpostconf html_directory\fR" to locate this information.
+.na
+.nf
+NON_BERKELEYDB_README, Non\-Berkeley\-DB migration guide
+.SH "LICENSE"
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH HISTORY
+.ad
+.fi
+.ad
+.fi
+This service was introduced with Postfix version 3.11.
+.SH "AUTHOR(S)"
+.na
+.nf
+Wietse Venema
+porcupine.org
index 9289a88ea2bf868d37a150dd0f6a17bf62a1aec1..0b93dc16d14db0bc778a57fcab7c86fc46abde79 100755 (executable)
@@ -6,4 +6,4 @@ do
     /*) lynx -width=256 -dump file://$i;;
      *) lynx -width=256 -dump file://`pwd`/$i;;
     esac
-done | grep -v 'file:///'
+done | grep -E -v '(file|https?)://'
index a464b9f79f4d554520364f2c73797a9914d6ac0e..2296e408e01a8a2389aed00f07881ac89b15f0b6 100755 (executable)
@@ -63,7 +63,7 @@ while (<>) {
     }
     s;\bautho[-</bB>]*\n*[ <bB>]*rized_flush_users\b;<a href="postconf.5.html#authorized_flush_users">$&</a>;g;
     s;\bautho[-</bB>]*\n*[ <bB>]*rized_mailq_users\b;<a href="postconf.5.html#authorized_mailq_users">$&</a>;g;
-    s;\bautho[-</bB>]*\n*[ <bB>]*rized_submit_users\b;<a href="postconf.5.html#authorized_submit_users">$&</a>;g;
+    s;\bautho[-</bB>]*\n*[ <bB>]*rized_sub[-</bB>]*\n*[ <bB>]*mit_users\b;<a href="postconf.5.html#authorized_submit_users">$&</a>;g;
     s;\bautho[-</bB>]*\n*[ <bB>]*rized_verp_clients\b;<a href="postconf.5.html#authorized_verp_clients">$&</a>;g;
     s;\bdebugger_command\b;<a href="postconf.5.html#debugger_command">$&</a>;g;
     s;\b2bounce_notice_recipi[-</bB>]*\n*[ <bB>]*ent\b;<a href="postconf.5.html#2bounce_notice_recipient">$&</a>;g;
@@ -822,6 +822,12 @@ while (<>) {
     s;\benable_threaded_bounces\b;<a href="postconf.5.html#enable_threaded_bounces">$&</a>;g;
     s;\bknown_tcp_ports\b;<a href="postconf.5.html#known_tcp_ports">$&</a>;g;
 
+    s;\bnon_bdb_migra[-</Bb>]*\n* *[<Bb>]*tion_[-</Bb>]*\n* *[<Bb>]*allow_root_prefixes\b;<a href="postconf.5.html#non_bdb_migration_allow_root_prefixes">$&</a>;g;
+    s;\bnon_bdb_migra[-</Bb>]*\n* *[<Bb>]*tion_[-</Bb>]*\n* *[<Bb>]*allow_user_pre[-</Bb>]*\n* *[<Bb>]*fixes\b;<a href="postconf.5.html#non_bdb_migration_allow_user_prefixes">$&</a>;g;
+    s;\bnon_bdb_migration_level\b;<a href="postconf.5.html#non_bdb_migration_level">$&</a>;g;
+    s;\bnon_bdb_custom_mapping\b;<a href="postconf.5.html#non_bdb_custom_mapping">$&</a>;g;
+    s;\bnon_bdb_migration_service_name\b;<a href="postconf.5.html#non_bdb_migration_service_name">$&</a>;g;
+
     # Transport-dependent magical parameters.
     # Note: Accept non-italic "transport" prefix for content that has been
     # converted from troff in C sources. Tooling doesn't support bold+italic.
@@ -865,6 +871,7 @@ while (<>) {
     s/[<bB>]*lmtp[<\/bB>]*\(8\)/<a href="lmtp.8.html">$&<\/a>/g;
     s/[<bB>]*local[<\/bB>]*\(8\)/<a href="local.8.html">$&<\/a>/g;
     s/[<bB>]*mas[-<\/bB>]*\n* *[<bB>]*ter[<\/bB>]*\(8\)/<a href="master.8.html">$&<\/a>/g;
+    s/[<bB>]*nbdb_reindexd[<\/bB>]*\(8\)/<a href="nbdb_reindexd.8.html">$&<\/a>/g;
     s/[<bB>]*pickup[<\/bB>]*\(8\)/<a href="pickup.8.html">$&<\/a>/g;
     s/[<bB>]*pipe[<\/bB>]*\(8\)/<a href="pipe.8.html">$&<\/a>/g;
     s/[<bB>]*postlogd[<\/bB>]*\(8\)/<a href="postlogd.8.html">$&<\/a>/g;
@@ -883,12 +890,13 @@ while (<>) {
     s/[<bB>]*triv[-<\/bB>]*\n* *[<bB>]*ial-[<\/bB>]*\n* *[<bB>]*re[-<\/bB>]*\n*[ <bB>]*write[<\/bB>]*\(8\)/<a href="trivial-rewrite.8.html">$&<\/a>/g;
     s/[<bB>]*mailq[<\/bB>]*\(1\)/<a href="mailq.1.html">$&<\/a>/g;
     s/[<bB>]*newaliases[<\/bB>]*\(1\)/<a href="newaliases.1.html">$&<\/a>/g;
-    s/[<bB>]*postalias[<\/bB>]*\(1\)/<a href="postalias.1.html">$&<\/a>/g;
+    s/[<bB>]*postal[-<\/bB>]*\n* *[<bB>]*ias[<\/bB>]*\(1\)/<a href="postalias.1.html">$&<\/a>/g;
     s/[<bB>]*postcat[<\/bB>]*\(1\)/<a href="postcat.1.html">$&<\/a>/g;
     s/[<bB>]*post[-<\/bB>]*\n*[ <bB>]*conf[<\/bB>]*\(1\)/<a href="postconf.1.html">$&<\/a>/g;
     s/[<bB>]*postdrop[<\/bB>]*\(1\)/<a href="postdrop.1.html">$&<\/a>/g;
     s/[<bB>]*post[-<\/bB>]*\n* *[<bB>]*fix[<\/bB>]*\(1\)/<a href="postfix.1.html">$&<\/a>/g;
     s/[<bB>]*post[-<\/bB>]*\n* *[<bB>]*fix-tls[<\/bB>]*\(1\)/<a href="postfix-tls.1.html">$&<\/a>/g;
+    s/[<bB>]*postfix-non-bdb[<\/bB>]*\(1\)/<a href="postfix-non-bdb.1.html">$&<\/a>/g;
     s/[<bB>]*postkick[<\/bB>]*\(1\)/<a href="postkick.1.html">$&<\/a>/g;
     s/[<bB>]*postlock[<\/bB>]*\(1\)/<a href="postlock.1.html">$&<\/a>/g;
     s/[<bB>]*postlog[<\/bB>]*\(1\)/<a href="postlog.1.html">$&<\/a>/g;
@@ -943,7 +951,7 @@ while (<>) {
 
     # Hyperlink README document names
 
-    s/\b([A-Z][A-Z0-9_]*)[-]*\n*[ ]*([A-Z0-9_]*_README)\b/<a href="$1$2.html">$&<\/a>/g;
+    s/\b(([A-Z][A-Z0-9_]*)[-]*\n*[ ]*([A-Z0-9_]*_README))(#[-a-zA-Z0-9_]+)?\b/<a href="$2$3.html$4">$1<\/a>/g;
     s/\bINSTALL\b/<a href="$&.html">$&<\/a>/g;
     s/\bOVERVIEW\b/<a href="$&.html">$&<\/a>/g;
     s/\btype:table\b/<a href="DATABASE_README.html">type:table<\/a>/g;
@@ -1189,7 +1197,7 @@ while (<>) {
     s;\bpostlog_service_name\b;<a href="postconf.5.html#postlog_service_name">$&</a>;g;
     s;\bpostlogd_watchdog_timeout\b;<a href="postconf.5.html#postlogd_watchdog_timeout">$&</a>;g;
 
-    s;\blocal_login_sender_maps\b;<a href="postconf.5.html#local_login_sender_maps">$&</a>;g;
+    s;\blocal_[-</bB>]*\n*[ <bB>]*login_[-</bB>]*\n*[ <bB>]*sender_maps\b;<a href="postconf.5.html#local_login_sender_maps">$&</a>;g;
     s;\bempty_address_local_login_sender_maps_lookup_key\b;<a href="postconf.5.html#empty_address_local_login_sender_maps_lookup_key">$&</a>;g;
 
     s;\buse_srv_lookup\b;<a href="postconf.5.html#use_srv_lookup">$&</a>;g;
@@ -1265,6 +1273,8 @@ while (<>) {
     s/\b(postfix  *tls)\b/<a href="postfix-tls.1.html">$1<\/a>/g;
     s/\b(local\s*aliasing)\b/<a href="ADDRESS_REWRITING_README.html#aliases">$1<\/a>/g;
     s/\b(virtual\s*aliasing)\b/<a href="ADDRESS_REWRITING_README.html#virtual">$1<\/a>/g;
+    s/\b(postfix non-bdb)\b/<a href="postfix-non-bdb.1.html">$1<\/a>/g;
+    #s/\b(postfix tls)\b/<a href="postfix-tls.1.html">$1<\/a>/g;
 
     # Hyperlink map types.
 
index 3bc012c8c3b3ba3d31f4be5d64019f72225972e4..0c936260126f0e87da3b9d61834c5330f3c02085 100644 (file)
@@ -671,7 +671,7 @@ listed below. See the postconf(5) manpage for a description
 
 <tr> <td>config_directory</td> <td>/etc/postfix</td> </tr>
 
-<tr> <td>default_database_type</td> <td>lmdb or hash</td> </tr>
+<tr> <td>default_database_type</td> <td>lmdb, cdb, or hash</td> </tr>
 
 <tr> <td>default_cache_db_type</td> <td>lmdb or btree</td> </tr>
 
@@ -741,7 +741,7 @@ default</th> </tr>
 <td>/etc/postfix</td> </tr>
 
 <tr> <td>DEF_DB_TYPE</td> <td>default_database_type</td>
-<td>lmdb or hash</td> </tr>
+<td>lmdb, cdb, or hash</td> </tr>
 
 <tr> <td>DEF_CACHE_DB_TYPE</td> <td>default_cache_db_type</td>
 <td>lmdb or btree</td> </tr>
@@ -773,12 +773,17 @@ default</th> </tr>
 <tr> <td>DEF_SENDMAIL_PATH</td> <td>sendmail_path</td>
 <td>/usr/sbin/sendmail</td> </tr>
 
+<tr> <td>DEF_SHLIB_DIR</td> <td>shlib_directory</td>
+<td>/usr/lib/postfix</td> </tr>
+
 </table>
 
 </blockquote>
 
 <p> Note: the data_directory parameter (for caches and pseudo-random
-numbers) was introduced with Postfix version 2.5. </p>
+numbers) was introduced with Postfix version 2.5; shlib_directory
+(for shared-library objects and database plugins) with Postfix
+version 3.0. </p>
 
 <h3><a name="build_other">4.7 - Overriding other compile-time
 features</a></h3>
@@ -816,7 +821,7 @@ off Postfix features at compile time:</td> </tr>
 
 <tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley
 DB support. By default, Berkeley DB support is compiled in on
-platforms that are known to support this feature. If you override
+platforms that have historically supported this feature. If you override
 this, then you probably should also override default_database_type
 or DEF_DB_TYPE as described in section 4.6. </td> </tr>
 
@@ -1550,8 +1555,8 @@ the exact location of the text file.  </p>
 
 <p> First, be sure to update the text file with aliases for root,
 postmaster and "postfix" that forward mail to a real person.  Postfix
-has a sample aliases file /etc/postfix/aliases that you can adapt
-to local conditions.  </p>
+has a sample aliases file /etc/postfix/aliases that you can copy
+and adapt to local conditions.  /p>
 
 <blockquote>
 <pre>
@@ -1577,6 +1582,15 @@ following commands: </p>
 </pre>
 </blockquote>
 
+<p> The form "postalias /etc/aliases" builds a default-type indexed
+file. Use "postalias <i>type</i>:/etc/aliases" to specify an explicit
+type (it should match the type in the output from "postconf -x
+alias_maps"). </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <h2><a name="hamlet">11 - To chroot or not to chroot</a></h2>
 
 <p> Postfix daemon processes can be configured (via master.cf) to
index 1dc1dec576dc15ac8ab6d3e79049c731d32f128d..c1c8764508e64f01ee03ccfce85d0d3a4a94f686 100644 (file)
@@ -34,6 +34,7 @@ HTML  = ../html/ADDRESS_CLASS_README.html \
        ../html/MONGODB_README.html \
        ../html/MULTI_INSTANCE_README.html \
        ../html/MYSQL_README.html ../html/NFS_README.html \
+       ../html/NON_BERKELEYDB_README.html \
        ../html/OVERVIEW.html \
        ../html/PACKAGE_README.html ../html/PCRE_README.html \
        ../html/PGSQL_README.html \
@@ -87,6 +88,7 @@ README        = ../README_FILES/ADDRESS_CLASS_README \
        ../README_FILES/MONGODB_README \
        ../README_FILES/MULTI_INSTANCE_README \
        ../README_FILES/MYSQL_README ../README_FILES/NFS_README \
+       ../README_FILES/NON_BERKELEYDB_README \
        ../README_FILES/OVERVIEW \
        ../README_FILES/PACKAGE_README ../README_FILES/PCRE_README \
        ../README_FILES/PGSQL_README \
@@ -264,6 +266,9 @@ clobber:
 ../html/NFS_README.html: NFS_README.html
        $(DETAB) $? | $(POSTLINK) >$@
 
+../html/NON_BERKELEYDB_README.html: NON_BERKELEYDB_README.html
+       $(DETAB) $? | $(POSTLINK) >$@
+
 ../html/OVERVIEW.html: OVERVIEW.html
        $(DETAB) $? | $(POSTLINK) >$@
 
@@ -456,6 +461,9 @@ clobber:
 ../README_FILES/NFS_README: NFS_README.html
        $(DETAB) $? | $(HT2READ) >$@
 
+../README_FILES/NON_BERKELEYDB_README: NON_BERKELEYDB_README.html
+       $(DETAB) $? | $(HT2READ) >$@
+
 ../README_FILES/OVERVIEW: OVERVIEW.html
        $(DETAB) $? | $(HT2READ) >$@
 
diff --git a/postfix/proto/NON_BERKELEYDB_README.html b/postfix/proto/NON_BERKELEYDB_README.html
new file mode 100644 (file)
index 0000000..458889f
--- /dev/null
@@ -0,0 +1,684 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "https://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Non-Berkeley-DB migration</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link rel='stylesheet' type='text/css' href='postfix-doc.css'>
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Non-Berkeley-DB migration</h1>
+
+<hr>
+
+<h2> Table of contents </h2>
+
+<ul>
+
+<li> <a href="#intro">Introduction </a>
+
+<li> <a href="#background">Background </a>
+
+<li> <a href="#build-conf">Skip this if not building Postfix from
+source, or if your system still supports Berkeley DB </a>
+
+<li> <a href="#level-overview"> Migration support level overview </a>
+
+<li> <a href="#disable"> Level 'disable': manual migration </a>
+
+<li> <a href="#enable-redirect"> Level 'enable-redirect': database
+aliasing </a>
+
+<li> <a href="#enable-reindex"> Level 'enable-reindex': redirect
+and automatically generate non-Berkeley-DB indexed files </a>
+
+<li> <a href="#addr-errors">Addressing errors with automatic indexed
+file generation </a>
+
+<li> <a href="#mailman">Appendix: Mailman integration </a>
+
+</ul>
+
+<h2> <a name="intro">Introduction </a> </h2>
+
+<p> (Please see the <a href="#mailman">Appendix</a> for Mailman
+integration tips.) </p>
+
+<p> After running the same Postfix configuration for a decade or
+more, there is a rude awakening when you update the OS to a newer
+version that has deleted its support for Berkeley DB. Postfix
+programs fail to open all hash: and btree: tables with messages
+like this: </p>
+
+<blockquote>
+<pre>
+Berkeley DB support for 'hash:/etc/postfix/virtual' is not available
+for this build; see https://www.postfix.org/NON_BERKELEYDB_README.html
+for alternatives
+</pre>
+</blockquote>
+
+<p> This document comes to the rescue, with strategies to migrate
+an existing Postfix configuration that uses Berkeley DB hash: and
+btree: database files, to an OS distribution that has removed
+Berkeley DB support, with a Postfix configuration that uses lmdb: (or
+a combination of cdb: and lmdb:). <p>
+
+<p> By the way, you don't have to wait until Berkeley DB support
+is removed; your can proactively use the steps described here on a
+system that still has Berkeley DB, to migrate a Postfix configuration
+from Berkeley DB to lmdb: (or a combination of cdb: and lmdb:).
+
+<h2> <a name="background">Background </a> </h2>
+
+<p> Historically, Postfix has used Berkeley DB hash: and btree: for
+key-value stores, as indicated in the "With Berkeley DB" table
+column below. In a world without Berkeley DB, good replacements are
+cdb: and lmdb: as indicated in the "No Berkeley DB" column. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Purpose </th> <th> With Berkeley DB </th> <th> No Berkeley
+DB </th> </tr>
+
+<tr> <td> Mostly-static data such as aliases, transport_maps,
+access tables </td> <td> default_database_type=hash </td> <td>
+default_database_type=lmdb or default_database_type=cdb </td>
+</tr>
+
+<tr> <td> Dynamic caches maintained by postscreen(8), verify(8),
+tlsmgr(8) </td> <td> default_cache_db_type=btree </td> <td>
+default_cache_db_type=lmdb </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> The default values for default_database_type and default_cache_db_type
+may be specified at build time (see the <a href="#build-conf">section
+below</a>, and they may be changed later by editing main.cf, for
+example with the postconf(1) command.) </p>
+
+<p> The sections that follow present three migration strategies
+with different levels of assistance by tooling that was developed
+for Postfix 3.11 and later. </p>
+
+<h2> <a name="build-conf"> Skip this if not building Postfix from
+source, or if your system still supports Berkeley DB. </a> </h2>
+
+<p> <a href="#level-overview">Click here to skip to the next section</a>.
+
+<p> On systems that have removed Berkeley DB support, run "<tt>make
+makefiles</tt>" with a CCARGS value that (also) contains "-DNO_DB",
+and specify appropriate values for default_database_type (lmdb or cdb)
+and default_cache_db_type (lmdb). </p>
+
+<p> In the examples below, the "<tt>...</tt>" are place holders any
+dependencies that you build Postfix with, such as CDB, LDAP, LMDB,
+MySQL/MariaDB, OpenSSL, SASL, and so on.
+
+<p> Example 1: use lmdb: for both default_database_type (read-mostly
+lookup tables) and default_cache_db_type (read-write caches). Terminal
+input is <b>bold</b>, output is <tt>normal</tt> font. </p>
+
+<blockquote> <pre>
+$ <b>make makefiles CCARGS="-DNO_DB ..." \
+    default_database_type=lmdb \
+    default_cache_db_type=lmdb ... \
+    AUXLIBS...</b>
+</pre>
+</blockquote>
+
+<p> Example 2: alternative form that produces the same result.
+</p>
+
+<blockquote>
+<pre>
+$ <b>export CCARGS="-DNO_DB ..."</b>
+$ <b>export default_database_type=lmdb</b>
+$ <b>export default_cache_db_type=lmdb</b>
+$ <b>export AUXLIBS...</b>
+...
+$ <b>make makefiles</b>
+</pre>
+</blockquote>
+
+<p> Another alternative is to use cdb for default_database_type
+(read-mostly lookup tables) and lmdb for default_cache_db_type
+(read-write caches). </p>
+
+<h2> <a name="level-overview"> Migration support level overview </a> </h2>
+
+<p> The goal of the migration is clear: stop using hash: and btree:,
+and use lmdb: or cdb: instead. If your configuration is simple or
+if you are familiar with Postfix configuration, a few "<tt>grep</tt>"
+commands will find all the problems, and a few edits will be easy
+to make. </p>
+
+<p> If, on the other hand, you are not familiar with the details of your
+Postfix configuration, then this document provides options where Postfix
+can help. </p>
+
+<p> Postfix 3.11 introduces multiple levels of migration support.
+You can use the command "<tt>postfix non-bdb status</tt>" to view
+the migration support level. This is what the default should look
+like (terminal input is <tt><b>bold</b></tt>, output is <tt>normal</tt>
+font): </p>
+
+<blockquote>
+<pre>
+# <b>postfix non-bdb status</b>
+disable
+</pre>
+</blockquote>
+
+<p> In increasing order, the support levels are: </p>
+
+<dl>
+
+<dt> <a href="#disable">disable</a> (manual migration) </dt>
+
+<dd> <p> You start up Postfix, watch the logging when Postfix
+programs fail to open a hash: or btree: table, edit Postfix
+configuration files to use lmdb: or cdb:, then run postmap(1) or
+postalias(1) commands to create lmdb: or cdb: indexed database
+files. Use this option if you are familiar with Postfix configuration.
+</p>
+
+<p> This will not fix the integration with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software that are broken
+when they want to use "<tt>postmap hash:<i>/path/to/file</i></tt>".
+Mailman uses this to maintain a table with mailing list contact
+addresses. For that, you need to use the next-up level. </p> </dd>
+
+<dt> <a href="#enable-redirect">enable-redirect</a> (database
+aliasing) </dt>
+
+<dd> <p> This level implicitly redirects a request to access
+hash:<i>/path/to/file</i> to $default_database_type:<i>/path/to/file</i>,
+and redirects a request to access a btree:<i>/path/to/file</i> to
+$default_cache_db_type:<i>/path/to/file</i>.  </p>
+
+<p> This still requires manually running postmap(1) or postalias(1)
+commands, but "fixes" the integration with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software when they want
+to use "<tt>postmap hash:<i>/path/to/file</i>"</tt>, and Berkeley
+DB support is not available. Such commands will implicitly create
+a new lmdb: or cdb: indexed database file, depending on the
+default_database_type value. </p> </dd>
+
+<dt> <a href="#enable-reindex"> enable-reindex </a> (aliasing, plus
+running postmap(1) or postalias(1))</dt>
+
+<dd> <p> This level implements "<tt>enable-redirect</tt> (database
+aliasing)", and also runs the postmap(1) or postalias(1) command to create
+a new lmdb or cdb indexed database file. This uses the nbdb_reindexd(8)
+daemon. </p>
+
+</dl>
+
+<p> The levels <a href="#enable-redirect">enable-redirect</a> and
+<a href="#enable-reindex"> enable-reindex </a> leave some technical
+debt: configurations that still say hash: or btree: (even if
+they use lmdb: or cdb: behind the scene). </p>
+
+<ul>
+
+<li> <p> Using these levels gives you extra time to prepare for a
+long-term configuration change that replaces hard-coded instances of hash:
+with the value of default_database_type, and that replaces btree: with
+the value of default_cache_db_type. </p>
+
+<li> <p> Depending on your use of other software that wants to use
+postmap(1) or postalias(1) commands, you may have to permanently
+the leave the <a href="#enable-redirect">enable-redirect</a> level
+active. </p>
+
+</ul>
+
+<p> After this overview, the sections that follow will go into more
+detail. </p>
+
+<h2> <a name="disable"> Level 'disable': manual migration </a> </h2>
+
+<p> To disable all non-Berkeley-DB migration features use
+the "<tt>postfix non-bdb</tt>" command:
+
+<blockquote>
+<pre>
+# <b>postfix non-bdb disable</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> This will edit main.cf to remove a non_bdb_migration_level setting
+and the level revert to its implicit default (disable), and will edit
+master.cf to remove an entry for the <tt>reindex</tt> service. </p>
+
+<p> This setting will cause problems with Mailman versions from
+before <a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c13214f43c7d32d">gitlab
+commit 8fa56b72</a> (May 2025) and other software that wants to use
+"<tt>postmap hash:<i>/path/to/file</i></tt>" (or similar postalias
+commands), and Berkeley DB support is no longer available. In that
+case, you will need the "<tt>enable-redirect</tt>" migration support
+level.
+
+<p> A manual migration process goes like this: </p>
+
+<ul>
+
+<li> <p> Stop Postfix. </p>
+
+<li> <p> Make lmdb: the default for both default_database_type
+(read-mostly lookup tables) and default_cache_db_type (read-write
+caches): </p>
+
+<pre>
+# <b>postconf default_database_type=lmdb default_cache_db_type=lmdb</b>
+</pre>
+
+<li> <p> Alternatively, make cdb: the default for default_database_type
+(read-mostly lookup tables) and lmdb: the default for
+default_cache_db_type (read-write caches): </p>
+
+<pre> 
+# <b>postconf default_database_type=cdb default_cache_db_type=lmdb</b>
+</pre>
+
+<li> <p> Look for hash: and btree: references in Postfix
+configuration files. Instead of <tt>/etc/postfix</tt> use the pathname
+in the output from "<tt>postconf -x config_directory</tt>". </p>
+
+<pre>
+# <b>grep -E -r '(hash|btree):/' /etc/postfix</b>
+</pre>
+
+<li> <p> For each instance in the "<tt>grep</tt>" output : </p>
+
+<ul>
+
+<li> <p> Edit the configuration file and replace "hash" with "lmdb"
+or "cdb" (use the same value as the output from "<tt><b>postconf
+-hx default_database_type</b></tt>") and replace "btree" with "lmdb".
+</p>
+
+<li> <p> If this instance has no source file (only the ".db" file
+exists), proceed with the next instance of "<tt>grep</tt>" output.
+</p>
+
+<li> <p> If this instance appears in the output from "<tt><b>postconf
+-hPPx '*/*/alias_maps' | sort -u</b></tt>", run the postalias(1)
+command.  If this instance is like "<tt>lmdb:/path/to/source</tt>":
+</p>
+
+<pre>
+# <b>postalias lmdb:/path/to/source</b>
+</pre>
+
+<p> Instead of "lmdb:" use "cdb:" if the instance is like
+"<tt>cdb:/path/to/source</tt>". </p>
+
+<li> <p> Otherwise, run the postmap(1) command. If this instance
+is like "<tt>lmdb:/path/to/source</tt>": </p>
+
+<pre>
+# <b>postmap lmdb:/path/to/source</b>
+</pre>
+
+<p> Instead of "lmdb:" use "cdb:" if this instance is like
+"<tt>cdb:/path/to/source</tt>". </p>
+
+</ul>
+
+<li> <p> Start Postfix, watch the log for warnings about files that
+cannot be opened, find the configuration file that still uses "hash"
+or "btree", and repeat the steps above. </p>
+
+<li> <p> It is now safe to delete the unused ".db" files. </p>
+
+</ul>
+
+<h2> <a name="enable-redirect"> Level 'enable-redirect': database
+aliasing </a> </h2>
+
+<p> To enable this migration support level, use: </p>
+
+<blockquote>
+<pre>
+# <b>postfix non-bdb enable-redirect</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> This <tt>postfix non-bdb</tt>" command edits main.cf to enable
+redirection (aliasing) from Berkeley DB types "hash" and "btree"
+to the non-Berkeley-DB types specified with $default_database_type
+and $default_cache_db_type. Custom redirection may be configured
+with non_bdb_custom_mapping. This command also edits master.cf to
+remove an unused <tt>nbdb_reindex</tt> service entry. </p>
+
+<p> This migration support level will not automatically create
+non-Berkeley-DB indexed database files. Instead, Postfix programs
+will log an error as they fail to open an indexed database file,
+and will leave it to the system administrator to run postmap(1) or
+postalias(1) to create that file. </p>
+
+<p> For each instance of "<tt>hash:/path/to/source</tt>" or
+"<tt>btree:/path/to/source</tt>" that requires manually running
+postmap(1) or postalias(1): </p>
+
+<ul>
+
+<li> <p> If this instance appears in the output from "<tt><b>postconf
+-hPPx '*/*/alias_maps' | sort -u</b></tt>", run the postalias(1)
+command.  If this instance is like "<tt>lmdb:/path/to/source</tt>":
+</p>
+
+<pre>
+# <b>postalias lmdb:/path/to/source</b>
+</pre>
+
+<p> Instead of "lmdb:" use "cdb:" if the instance is like
+"<tt>cdb:/path/to/source</tt>". </p>
+
+<li> <p> Otherwise, run the postmap(1) command. If this instance
+is like "<tt>lmdb:/path/to/source</tt>": </p>
+
+<pre>
+# <b>postmap lmdb:/path/to/source</b>
+</pre>
+
+<p> Instead of "lmdb:" use "cdb:" if this instance is like
+"<tt>cdb:/path/to/source</tt>". </p>
+
+</ul>
+
+<p> This migration support level will fix problems with Mailman
+versions from before May 2025 and other software that wants to use
+"<tt>postmap hash:<i>/path/to/file</i></tt>". With database
+redirection, such commands will implicitly create an indexed file
+for $default_database_type:<i>/path/to/file</i> (similar aliasing
+happens for postalias commands). </p>
+
+<p> The command "<tt>postfix non-bdb enable-redirect</tt>" will
+refuse to make any changes when default_database_type or
+default_cache_db_type specify a hash: or btree: type.
+
+<h2> <a name="enable-reindex"> Level 'enable-reindex': redirect and
+automatically generate non-Berkeley-DB indexed files </a> </h2>
+
+<p> <i> NOTE: this level should be used only temporarily to generate
+most of the non-Berkeley-DB indexed files that Postfix needs.
+Leaving this enabled may expose the system to privilege-escalation
+attacks.  There are no security concerns for using enable-redirect.
+</i> </p>
+
+<p> To enable this migration support level, use: </p>
+
+<blockquote>
+<pre>
+# <b>postfix non-bdb enable-reindex</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p>This postfix non-bdb command edits main.cf to set the non-Berkeley-DB
+migration support level, and master.cf to add or replace an
+<tt>nbdb-reindex</tt> service entry. </p>
+
+<p> The resulting configuration implements not only the functionality
+of <a href="#enable-redirect"> enable-redirect</a>, but also
+automatically creates a non-Berkeley-DB indexed database file when
+a daemon program wants to access a file that does not exist. This
+uses the nbdb_reindexd(8) daemon to run postmap(1) or postalias(1)
+commands for databases that satisfy basic requirements to block
+privilege-escalation attacks. The number of requirements is large,
+but mainly, database files and their parent directory must not allow
+write access for group or other users, and their pathnames must
+match a list of trusted directory prefixes.  The complete list of
+requirements is documented in nbdb_reindexd(8).  <p>
+
+This command immediately generates non-Berkeley-DB indexed files
+for command-line programs that lack privileges to send requests to
+the nbdb_reindexd(8) indexing server. This applies to "hash:" and
+"btree:" tables that are used by postqueue(1) and sendmail(1) as
+configured with authorized_flush_users and authorized_mailq_users,
+and used by sendmail(1) and postdrop(1) as configured with
+authorized_submit_users and local_login_sender_maps.  </p>
+
+<p> The command "<tt>postfix non-bdb enable-reindex</tt>" will
+refuse to make any changes when default_database_type or
+default_cache_db_type specify a hash: or btree: type.
+
+<p> The nbdb_reindexd(8) daemon will log when it successfully runs
+a postmap(1) or postalias(1) command.  Examples, for a system with
+"<tt>default_database_type = lmdb</tt>": </p>
+
+<blockquote>
+<pre>
+successfully executed 'postmap lmdb:/etc/postfix/transport' as uid 0
+successfully executed 'postalias lmdb:/etc/aliases' as uid 0
+</pre>
+</blockquote>
+
+<p> See the section "<a href="addr-errors">Addressing errors
+with automatic indexed file generation</a>" for the most likely
+errors that Postfix programs may log. </p>
+
+<p> Once there are no more errors from Postfix programs for about
+24 hours, turn off automatic index generation by reducing the support
+level to <tt>enable-redirect</tt> with: </p>
+
+<blockquote>
+<pre>
+# postfix non-bdb enable-redirect
+# postfix reload
+</pre>
+</blockquote>
+
+<h2> <a name="addr-errors">Addressing errors with automatic
+indexed file generation </a> </h2>
+
+<h3> Unexpected pathname errors </h3>
+
+<p> Depending on the location of your Postfix lookup tables, Postfix
+programs may log a request to add a trusted directory to the
+directories listed with non_bdb_migration_allow_root_prefixes or
+non_bdb_migration_allow_user_prefixes. </p>
+
+<p> Example, with line breaks added for readability: </p>
+
+<blockquote>
+<pre>
+could not execute command 'postmap lmdb:/path/to/file': table
+/path/to/file has an unexpected pathname;
+
+to allow automatic indexing as root, append its parent directory
+to the non_bdb_migration_allow_root_prefixes setting (current setting
+is: "/etc /usr/local/etc");
+
+alternatively, execute the failed command by hand
+</pre>
+</blockquote>
+
+<p> You have two options: </p>
+
+<ol>
+
+<li> <p> If you think that the suggested change is safe, update the
+setting as proposed and execute "<tt>postfix reload</tt>". </p>
+
+<li> <p> Alternatively, you can execute the failed postmap(1) or
+postalias(1) command by hand, and Postfix will not log the same error
+again. </p>
+
+</ol>
+
+<p> A similar request may be logged when a file needs to be indexed as
+a non-root user. </p>
+
+<h3> Unexpected file or directory owner or permissions </h3>
+
+<p> Other errors may be logged when a database file or directory
+has an unexpected owner, or when it is writable by group or by other
+users. </p>
+
+<p> Example with line breaks added for readability: </p>
+
+<blockquote>
+<pre>
+could not execute command 'postmap lmdb:/path/to/file': legacy
+indexed file '/path/to/file.db' is owned by uid '0', but parent
+directory '/path/to' is owned or writable by other user;
+
+to allow automatic indexing, correct the ownership or permissions;
+
+alternatively, execute the failed command by hand
+</pre>
+</blockquote>
+
+<p> Again, you have two options: </p>
+
+<ol>
+
+<li> <p> Fix the ownership or permission error. </p>
+
+<li> <p> Execute the failed postmap(1) or postalias(1) command by
+hand, and Postfix will not log the same error again. </p>
+
+</ol>
+
+<p> Once there are no more errors from Postfix programs for about
+24 hours, turn off automatic index generation by reducing the
+support level to <tt>enable-redirect</tt> with: </p>
+
+<blockquote>
+<pre>
+# postfix non-bdb enable-redirect
+# postfix reload
+</pre>
+</blockquote>
+
+<h2> <a name="mailman">Appendix: Mailman integration </a> </h2>
+
+<p> This section has instructions to migrate an existing Mailman
+configuration that wants to use commands like "postmap
+hash:<i>/path/to/file</i>".  Mailman uses such commands to maintain
+tables with mailing list contact addresses and domain names. This
+will break on systems that no longer have Berkeley DB support. </p>
+
+<p> Solutions: </p>
+
+<ul>
+
+<li> <p> (Not recommended) Upgrade to a Mailman version that contains
+<a
+href="https://gitlab.com/mailman/mailman/-/commit/8fa56b72dccd318c171b7f373c1321
+4f43c7d32d">gitlab commit 8fa56b72</a> (May 2025). Unfortunately,
+this has not yet been widely adopted by OS distributions. </p>
+
+<li> <p> Avoid Mailman changes, and use Postfix migration support
+described below. In a nutshell, the postmap command will execute
+the command "postmap hash:<i>/path/to/file</i>" as if the command
+specifies lmdb:<i>/path/to/file</i> (or cdb:, depending on Postfix
+configuration). </p>
+
+</ul>
+
+<p> With Mailman3 the integration with Postfix using LMTP may look
+like: </p>
+
+<blockquote>
+<pre>
+/var/lib/mailman3/data/postfix_domains      (domain names)
+/var/lib/mailman3/data/postfix_domains.db   (Berkeley DB hash file)
+/var/lib/mailman3/data/postfix_lmtp         (transport map)
+/var/lib/mailman3/data/postfix_lmtp.db      (Berkeley DB hash file)
+</pre>
+</blockquote>
+
+<blockquote> <i> Caution: the data directory may contain other files
+with names ending in "<tt>.db</tt>" that are not part of the
+Mailman-Postfix integration. Do not tamper with the other files. </i>
+</blockquote>
+
+<p> The relevant Postfix migration levels are: </p>
+
+<dl> <dt> <a href="#enable-redirect">enable-redirect</a> (redirect hash:
+to lmdb: or cdb:) </dt>
+
+<dd> <p> Command: <tt> # <b>postfix non-bdb enable-redirect</b></tt> </p>
+
+<p> This will fix the problem that Mailman wants to use commands like
+"<tt>postmap hash:<i>/path/to/</i>postfix_domains</tt>" and "<tt>postmap
+hash:<i>/path/to</i>/postfix_lmtp</tt>". </p>
+
+<p> Instead of complaining about an unsupported database type, these
+postmap commands will implicitly create "<tt>.lmdb</tt>" indexed
+files like (lmdb:<i>/path/to</i>/postfix_domains or
+lmdb:<i>/path/to</i>/postfix_lmtp, or their cdb: versions depending
+on the Postfix default_database_type setting). </p>
+
+<p> This will not fix the problem that Postfix wants to
+use databases like hash:<i>/path/to</i>/postfix_domains
+and hash::<i>/path/to</i>/postfix_lmtp. With <a
+href="#enable-redirect">enable-redirect</a>, these will redirect to
+"<tt>.lmdb</tt>" indexed files (good) but those files do not yet exist
+(bad). You will need to create them by hand with commands like: </p>
+
+<pre>
+# <b>postmap lmdb:<i>/path/to</i>/postfix_domains</b>
+# <b>postmap lmdb:<i>/path/to</i>/postfix_lmtp</b>
+</pre>
+
+<p> After this, no further human action will be needed. When Mailman
+needs to update these files, it will invoke postmap commands that
+will work as promised above. Leave the Postfix migration level at <a
+href="#enable-reindex">enable-reindex</a> until you can upgrade to a
+newer Mailman version that supports Postfix with non-Berkeley
+databases. </p>
+
+</dd>
+
+<dt><a href="#enable-reindex">enable-reindex</a> (also automatically
+run postmap commands)</dt>
+
+<dd> <p> Command: <tt> # <b>postfix non-bdb enable-redirect</b></tt> </p>
+
+<p> In addition to "<a href="#enable-redirect">enable-redirect</a>",
+Postfix will also try to run commands like "<tt>postmap
+lmdb:<i>/path/to</i>/postfix_domains</tt>" and "<tt>postmap
+lmdb:<i>/path/to</i>/postfix_lmtp</tt>". There will be some delay
+depending on the amount of mailing list traffic; you may want to post
+a test message to make the postmap commands happen sooner. </p>
+
+<p> Postfix will log the postmap commands (or will log a request to make
+some configuration changes; see "<a href="addr-errors">Addressing errors
+with automatic indexed file generation</a>" above). </p>
+
+<p> <i>Note: once these "postmap" commands have completed,
+you should reduce the migration support level with the command
+"<b>postfix non-bdb enable-redirect</b>".  For security reasons the <a
+href="#enable-reindex">enable-reindex</a> level should not be permanently
+enabled. </i> </p>
+
+</dl>
+
+</body>
+
+</html>
index bf1dd473c390d0eaac8560786e5d7b61a5e1fb2f..5a85ea742175bc853f6e7806318254e64fd75ad1 100644 (file)
@@ -1377,7 +1377,8 @@ use a particular envelope sender address: </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    <strong>smtpd_sender_login_maps = hash:/etc/postfix/controlled_envelope_senders</strong>
+    <strong>smtpd_sender_login_maps = 
+        lmdb:/etc/postfix/controlled_envelope_senders</strong>
 
     smtpd_recipient_restrictions =
         ...
@@ -1402,6 +1403,19 @@ names that own that address: </p>
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "<b>postmap
+/etc/postfix/controlled_envelope_senders</b>" after you change the
+controlled_envelope_senders file, to (re)build a default-type indexed
+file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/controlled_envelope_senders</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <p> With this, the <code>reject_sender_login_mismatch</code>
 restriction above will reject the sender address in the MAIL FROM
 command if <code>smtpd_sender_login_maps</code> does not specify
@@ -1430,7 +1444,7 @@ REJECT mail from accounts whose credentials have been compromised.
 /etc/postfix/main.cf:
     smtpd_recipient_restrictions = 
        permit_mynetworks 
-       check_sasl_access hash:/etc/postfix/sasl_access
+       check_sasl_access lmdb:/etc/postfix/sasl_access
        permit_sasl_authenticated
        ...
 
@@ -1442,6 +1456,17 @@ REJECT mail from accounts whose credentials have been compromised.
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/sasl_access</b>"
+after you change the sasl_access file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_access</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
+
 <h4><a name="id397172">Default  authentication domain</a></h4>
 
 <p> Postfix can append a domain name (or any other string) to a
@@ -1675,7 +1700,7 @@ second part sets up the username/password information.  </p>
     relayhost = [mail.isp.example]
     # Alternative form:
     # relayhost = [mail.isp.example]:submission
-    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+    smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
 </pre>
 </blockquote>
 
@@ -1749,8 +1774,16 @@ and before entering an optional chroot jail. </p>
 
 <ul>
 
-<li> <p> Use the <code>postmap</code> command whenever you
-change the <code>/etc/postfix/sasl_passwd</code> file. </p> </li>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
+after changing the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p> </li>
 
 <li> <p> If you specify the "<code>[</code>" and "<code>]</code>"
 in the <code>relayhost</code> destination, then you must use the
@@ -1785,9 +1818,10 @@ resort.  </p>
 <pre>
 /etc/postfix/main.cf:
     smtp_sender_dependent_authentication = yes
-    sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
+    sender_dependent_relayhost_maps = 
+        lmdb:/etc/postfix/sender_relay
     smtp_sasl_auth_enable = yes
-    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+    smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
     relayhost = [mail.isp.example]
     # Alternative form:
     # relayhost = [mail.isp.example]:submission
@@ -1818,19 +1852,25 @@ resort.  </p>
 
 <ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <li> <p> If you are creative, then you can try to combine the two
 tables into one single MySQL database, and configure different
 Postfix queries to extract the appropriate information. </p>
 
-<li> <p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
-
 <li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
-whenever you change the sasl_passwd table. </p>
+after you change the sasl_passwd file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sasl_passwd</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <li> <p> Execute the command "<b>postmap /etc/postfix/sender_relay</b>"
-whenever you change the sender_relay table. </p>
+after you change the sender_relay file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/sender_relay</b>"
+to specify an explicit type.</p>
 
 </ul>
 
index f89ffc90540c8fbfc3a790de123c2cd882b43ab9..872e959cc18f70d54e268dcbdad7cc547ef9ccad 100644 (file)
@@ -326,7 +326,7 @@ All the mail to these two accounts is forwarded to an inside address.
 <blockquote>
 <pre>
 1 /etc/postfix/main.cf:
-2     virtual_alias_maps = hash:/etc/postfix/virtual
+2     virtual_alias_maps = lmdb:/etc/postfix/virtual
 3 
 4 /etc/postfix/virtual:
 5     postmaster      postmaster@example.com
@@ -369,8 +369,8 @@ is the real purpose of the firewall email function. </p>
  9b        permit_mynetworks reject_unauth_destination
 10b        ...spam blocking rules....
 <br>
-11     relay_recipient_maps = hash:/etc/postfix/relay_recipients
-12     transport_maps = hash:/etc/postfix/transport
+11     relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
+12     transport_maps = lmdb:/etc/postfix/transport
 13 
 14 /etc/postfix/relay_recipients:
 15     user1@example.com   x
@@ -409,15 +409,27 @@ default "smtp" delivery transport. </p>
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
+whenever you change the virtual file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>"
-whenever you change the relay_recipients table. </p>
+whenever you change the relay_recipients file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/relay_recipients</b>" to specify an explicit
+type.</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the transport table. </p>
+whenever you change the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
 
 <p> In some installations, there may be separate instances of Postfix
 processing inbound and outbound mail on a multi-homed firewall. The
@@ -447,7 +459,7 @@ follows:  </p>
 <blockquote>
 <pre>
 1 /etc/postfix/main.cf:
-2     virtual_alias_maps = hash:/etc/postfix/virtual
+2     virtual_alias_maps = lmdb:/etc/postfix/virtual
 3 
 4 /etc/postfix/virtual:
 5     root     root@localhost
@@ -466,8 +478,16 @@ matches $inet_interfaces or $proxy_interfaces. </p>
 
 </ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-editing the file. </p>
+editing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <h2><a name="intranet">Running Postfix behind a firewall</a></h2>
 
@@ -489,7 +509,7 @@ discussed in the first half of this document. </p>
 <blockquote>
 <pre>
  1 /etc/postfix/main.cf:
- 2     transport_maps = hash:/etc/postfix/transport
+ 2     transport_maps = lmdb:/etc/postfix/transport
  3     relayhost =
  4     # Optional for a machine that isn't "always on"
  5     #fallback_relay = [gateway.example.com]
@@ -522,12 +542,17 @@ directly, and gives undeliverable mail to a gateway.  </p>
 
 </ul>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/transport</b>"
+whenever you edit the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
-<p> Execute the command "<b>postmap /etc/postfix/transport</b>" whenever
-you edit the transport table. </p>
 
 <h2><a name="backup">Configuring Postfix as primary or backup MX host for a remote site</a></h2>
 
@@ -561,7 +586,7 @@ is all you need: </p>
 11     # You must specify your NAT/proxy external address.
 12     #proxy_interfaces = 1.2.3.4
 13 
-14     relay_recipient_maps = hash:/etc/postfix/relay_recipients
+14     relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
 15 
 16 /etc/postfix/relay_recipients:
 17     user1@the.backed-up.domain.tld   x
@@ -576,7 +601,7 @@ need the above, plus: </p>
 <blockquote>
 <pre>
 20 /etc/postfix/main.cf:
-21     transport_maps = hash:/etc/postfix/transport
+21     transport_maps = lmdb:/etc/postfix/transport
 22 
 23 /etc/postfix/transport:
 24     the.backed-up.domain.tld       relay:[their.mail.host.tld]
@@ -613,12 +638,22 @@ relay_recipients table. </p>
 
 </ul>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>"
+whenever you change the relay_recipients file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/relay_recipients</b>" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the transport table. </p>
+whenever you change the transport file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/transport</b>"
+to specify an explicit type. </p>
 
 <p> NOTE for Postfix &lt; 2.2: Do not use the fallback_relay feature
 when relaying mail
@@ -760,7 +795,7 @@ discussed in the first half of this document. </p>
 <blockquote>
 <pre>
 1 /etc/postfix/main.cf:
-2     smtp_generic_maps = hash:/etc/postfix/generic
+2     smtp_generic_maps = lmdb:/etc/postfix/generic
 3 
 4 /etc/postfix/generic:
 5     his@localdomain.local             hisaccount@hisisp.example
@@ -785,12 +820,16 @@ that the ISP supports "+" style address extensions). </p>
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/generic</b>"
-whenever you change the generic table. </p>
+whenever you change the generic file, to (re)build a default-type
+indexed file. Execute  "<b>postmap <i>type</i>:/etc/postfix/generic</b>"
+to specify an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <h3>Solution 2: Postfix version 2.1 and earlier </h3>
 
@@ -811,9 +850,9 @@ discussed in the first half of this document. </p>
  2     myhostname = hostname.localdomain
  3     mydomain = localdomain
  4 
- 5     canonical_maps = hash:/etc/postfix/canonical
+ 5     canonical_maps = lmdb:/etc/postfix/canonical
  6 
- 7     virtual_alias_maps = hash:/etc/postfix/virtual
+ 7     virtual_alias_maps = lmdb:/etc/postfix/virtual
  8 
  9 /etc/postfix/canonical:
 10     your-login-name    your-account@your-isp.com
@@ -842,15 +881,21 @@ but is convenient.
 
 </ul>
 
-<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
-tables Postfix supports, use the command "<b>postconf -m</b>".  </p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
 
 <p> Execute the command "<b>postmap /etc/postfix/canonical</b>"
-whenever you change the canonical table. </p>
+whenever you change the canonical file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/canonical</b>"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
-whenever you change the virtual table. </p>
+whenever you change the virtual file, to (re)build a default-type
+indexed file. Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>"
+to specify an explicit type. </p>
 
 </body>
 
index a63771056e64b2474934d639558d48d4f0de018d..494f66845fb40d93dfc3636f952029cd1cb176bb 100644 (file)
@@ -102,6 +102,13 @@ recipients.  The pipe(8) delivery agent executes the <b>uux</b>
 command without assistance from the shell, so there are no problems
 with shell meta characters in command-line parameters.  </p>
 
+<li> <p> Enable <b>transport</b> table lookups: </p>
+
+<pre>
+/etc/postfix/main.cf:
+    transport_maps = lmdb:/etc/postfix/transport
+</pre>
+
 <li> <p> Specify that mail for <i>example.com</i>, should be
 delivered via UUCP, to a host named <i>uucp-host</i>: </p>
 
@@ -111,21 +118,19 @@ delivered via UUCP, to a host named <i>uucp-host</i>: </p>
     .example.com    uucp:uucp-host
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> See the transport(5) manual page for more details. </p>
 
 <li> <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
-whenever you change the <b>transport</b> file. </p>
-
-<li> <p> Enable <b>transport</b> table lookups: </p>
-
-<pre>
-/etc/postfix/main.cf:
-    transport_maps = hash:/etc/postfix/transport
-</pre>
+whenever you change the <b>transport</b> file, to (re)build a
+default-type indexed file. Execute "<b>postmap
+<i>type</i>:/etc/postfix/transport</b>" to specify an explicit type.
+</p>
 
-<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
-<b>dbm</b> files instead of <b>db</b> files. To find out what map
-types Postfix supports, use the command "<b>postconf -m</b>". </p>
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types, 
+execute the command "<b>postconf -m</b>".</p>
 
 <li> <p> Add <i>example.com</i> to the list of domains that your site
 is willing to relay mail for. </p>
index d42efcc18ae68dd57c502d1e094d9bfec7fcb5ff..77f6afcb3490730ff1193f256f78e308f4bd3314 100644 (file)
@@ -54,9 +54,7 @@ domains, non-UNIX accounts</a>
 
 <li> <a href="#forwarding">Mail forwarding domains</a>
 
-<li> <a href="#mailing_lists">Mailing lists</a>
-
-<li> <a href="#autoreplies">Autoreplies</a>
+<li> <a href="#mailing_lists">Hosted mailing list domains</a>
 
 </ul>
 
@@ -96,19 +94,31 @@ address class, as defined in the ADDRESS_CLASS_README file. </p>
 <h2><a name="local_vs_database">Local files versus network databases</a></h2>
 
 <p> The examples in this text use table lookups from local files
-such as DBM or Berkeley DB.  These are easy to debug with the
+such as lmdb:, cdb:, hash:, or dbm:. These are easy to debug with the
 <b>postmap</b> command: </p>
 
 <blockquote>
-Example: <tt>postmap -q info@example.com hash:/etc/postfix/virtual</tt>
+Example: <tt>postmap -q info@example.com /etc/postfix/virtual</tt>
 </blockquote>
 
-<p> See the documentation in LDAP_README, MYSQL_README and PGSQL_README
-for how to replace local files by databases. The reader is strongly
-advised to make the system work with local files before migrating
-to network databases, and to use the <b>postmap</b> command to verify
-that network database lookups produce the exact same results as
-local file lookup. </p>
+<p> The above example assumes that the database is configured in
+main.cf as $default_database_type:/etc/postfix/virtual. Otherwise,
+use the command instead: </p>
+
+<blockquote>
+Example: <tt>postmap -q info@example.com
+<i>type</i>:/etc/postfix/virtual</tt>
+</blockquote>
+
+<p> and specify the explicit type that this table uses in main.cf. </p>
+
+<p> You can replace local file lookups with networked (LDAP, SQL
+etc.) lookups. See the documentation in LDAP_README, MYSQL_README,
+PGSQL_README, etc., for examples.  The reader is strongly advised
+to make Postfix work with local files before migrating to network
+databases, and to use the <b>postmap</b> command to verify that
+network database lookups produce the exact same results as local
+file lookup. </p>
 
 <blockquote>
 Example: <tt>postmap -q info@example.com ldap:/etc/postfix/virtual.cf</tt>
@@ -166,7 +176,7 @@ below shows how to use this mechanism for the example.com domain.
 <pre>
  1 /etc/postfix/main.cf:
  2     virtual_alias_domains = example.com ...other hosted domains...
- 3     virtual_alias_maps = hash:/etc/postfix/virtual
+ 3     virtual_alias_maps = lmdb:/etc/postfix/virtual
  4 
  5 /etc/postfix/virtual:
  6     postmaster@example.com postmaster
@@ -209,8 +219,18 @@ for spam messages that were sent in the name of anything@example.com.
 
 </ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, and execute the command "<b>postfix
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p>Execute the command "<b>postfix
 reload</b>" after changing the main.cf file. </p>
 
 <p> Note: virtual aliases can resolve to a local address or to a
@@ -259,11 +279,11 @@ section at the top of this document.</p>
  1 /etc/postfix/main.cf:
  2     virtual_mailbox_domains = example.com ...more domains...
  3     virtual_mailbox_base = /var/mail/vhosts
- 4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ 4     virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox
  5     virtual_minimum_uid = 100
  6     virtual_uid_maps = static:5000
  7     virtual_gid_maps = static:5000
- 8     virtual_alias_maps = hash:/etc/postfix/virtual
+ 8     virtual_alias_maps = lmdb:/etc/postfix/virtual
  9 
 10 /etc/postfix/vmailbox:
 11     info@example.com    example.com/info
@@ -338,10 +358,24 @@ the wrong domain. </p>
 
 </ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
-after changing the vmailbox file, and execute the command "<b>postfix
-reload</b>" after changing the main.cf file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute "<b>postmap /etc/postfix/vmailbox</b>" after changing
+the vmailbox file, to (re)build a default-type indexed file. Execute
+"<b>postmap <i>type</i>:/etc/postfix/vmailbox</b>" to specify an
+explicit type. </p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+main.cf file. </p>
 
 <p> Note: mail delivery happens with the recipient's UID/GID
 privileges specified with virtual_uid_maps and virtual_gid_maps.
@@ -383,8 +417,8 @@ to a non-Postfix delivery agent: </p>
  1 /etc/postfix/main.cf:
  2     virtual_transport = ...see below...
  3     virtual_mailbox_domains = example.com ...more domains...
- 4     virtual_mailbox_maps = hash:/etc/postfix/vmailbox
- 5     virtual_alias_maps = hash:/etc/postfix/virtual
+ 4     virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox
+ 5     virtual_alias_maps = lmdb:/etc/postfix/virtual
  6 
  7 /etc/postfix/vmailbox:
  8     info@example.com    whatever
@@ -473,10 +507,24 @@ the wrong domain. </p>
 
 </ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
-after changing the vmailbox file, and execute the command "<b>postfix
-reload</b>" after changing the main.cf file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute the command "<b>postmap /etc/postfix/vmailbox</b>" after
+changing the vmailbox file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/vmailbox</b>" to
+specify an explicit type.</p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+main.cf file. </p>
 
 <h2><a name="forwarding">Mail forwarding domains</a></h2>
 
@@ -489,7 +537,7 @@ as a mail forwarding domain: </p>
 <pre>
  1 /etc/postfix/main.cf:
  2     virtual_alias_domains = example.com ...other hosted domains...
- 3     virtual_alias_maps = hash:/etc/postfix/virtual
+ 3     virtual_alias_maps = lmdb:/etc/postfix/virtual
  4 
  5 /etc/postfix/virtual:
  6     postmaster@example.com postmaster
@@ -533,17 +581,34 @@ for spam messages that were sent in the name of anything@example.com.
 
 </ul>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
-changing the virtual file, and execute the command "<b>postfix
-reload</b>" after changing the main.cf file. </p>
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
+<p> Execute the command "<b>postfix reload</b>" after changing the
+main.cf file. </p>
 
 <p> More details about the virtual alias file are given in the
 virtual(5) manual page, including multiple addresses on the right-hand
 side. </p>
 
-<h2><a name="mailing_lists">Mailing lists</a></h2>
+<h2><a name="mailing_lists">Hosted mailing list domains</a></h2>
+
+<p> <i> Note: this section presents a historical approach to run a
+mailing list based on local aliases(5). This approach may still be
+useful for small mailing lists that are managed by hand or with the
+software like Majordomo. For a more contemporary and more scalable
+approach, see <a href="https://lists.org"> GNU Mailman</a>. </i>
+</p>
 
-<p> The examples that were given above already show how to direct
+<p>The examples that were given above already show how to direct
 mail for virtual postmaster addresses to a local postmaster. You
 can use the same method to direct mail for any address to a local
 or remote address. </p>
@@ -556,12 +621,14 @@ virtual addresses to the local delivery agent: </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    virtual_alias_maps = hash:/etc/postfix/virtual
+    virtual_alias_maps = lmdb:/etc/postfix/virtual
+    virtual_mailbox_domains = example.com
 
 /etc/postfix/virtual:
     listname-request@example.com listname-request
     listname@example.com         listname
     owner-listname@example.com   owner-listname
+    postmaster@example.com       postmaster
 
 /etc/aliases:
     listname: "|/some/where/majordomo/wrapper ..."
@@ -570,6 +637,17 @@ virtual addresses to the local delivery agent: </p>
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, to (re)build a default-type indexed file.
+Execute "<b>postmap <i>type</i>:/etc/postfix/virtual</b>" to specify
+an explicit type.</p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "<b>postconf -m</b>".</p>
+
 <p> This example assumes that in main.cf, $myorigin is listed under
 the mydestination parameter setting.  If that is not the case,
 specify an explicit domain name on the right-hand side of the
@@ -587,63 +665,15 @@ bunch of virtual alias or virtual mailbox table entries. </p>
 
 <ul>
 
-<li> In case of a virtual alias domain, there would need to be one
-identity mapping from each mailing list address to itself.
+<li> In the case of a virtual alias DOMAIN, there would need to be
+an identity mapping from each mailing list address to an address in a
+different domain.
 
-<li> In case of a virtual mailbox domain, there would need to be
-a dummy mailbox for each mailing list address.
+<li> In the case of a virtual mailbox DOMAIN, there would need to
+be a dummy virtual_mailbox_maps for each mailing list address.
 
 </ul>
 
-<h2><a name="autoreplies">Autoreplies</a></h2>
-
-<p> In order to set up an autoreply for virtual recipients while
-still delivering mail as normal, set up a rule in a virtual alias
-table: </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    virtual_alias_maps = hash:/etc/postfix/virtual
-
-/etc/postfix/virtual:
-    user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld
-</pre>
-</blockquote>
-
-<p> This delivers mail to the recipient, and sends a copy of the
-mail to the address that produces automatic replies. The address
-can be serviced on a different machine, or it can be serviced
-locally by setting up a transport map entry that pipes all mail
-for autoreply.mydomain.tld into some script that sends an automatic
-reply back to the sender. </p>
-
-<p> DO NOT list autoreply.mydomain.tld in mydestination! </p>
-
-<blockquote>
-<pre>
-/etc/postfix/main.cf:
-    transport_maps = hash:/etc/postfix/transport
-
-/etc/postfix/transport:
-    autoreply.mydomain.tld  autoreply:
-
-/etc/postfix/master.cf:
-    # =============================================================
-    # service type  private unpriv  chroot  wakeup  maxproc command
-    #               (yes)   (yes)   (yes)   (never) (100)
-    # =============================================================
-    autoreply unix  -       n       n       -       -       pipe
-        flags= user=nobody argv=/path/to/autoreply $sender $mailbox
-</pre>
-</blockquote>
-
-<p> This invokes /path/to/autoreply with the sender address and
-the user@domain.tld recipient address on the command line. </p>
-
-<p> For more information, see the pipe(8) manual page, and the
-comments in the Postfix master.cf file. </p>
-
 </body>
 
 </html>
index 999e9682cd4e784f2bc2737768a29d4978140ea6..6d43f4537f1497ad8b43490b3160819fd3fc2e49 100644 (file)
 #      email messages.
 #
 #      Normally, the \fBaccess\fR(5) table is specified as a text file
-#      that serves as input to the \fBpostmap\fR(1) command.
-#      The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-#      is used for fast searching by the mail system. Execute the
-#      command "\fBpostmap /etc/postfix/access\fR" to rebuild an
-#      indexed file after changing the corresponding text file.
+#      that serves as input to the \fBpostmap\fR(1) command to create
+#      an indexed file for fast lookup.
+#
+#      Execute the command "\fBpostmap /etc/postfix/access\fR" to
+#      rebuild a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/access\fR" to
+#      specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index 22e20e91ede3382ba53dccc76fb309472c6d2703..8f7da1fa0c920df9748fc9dcc1f7aba6ae198ba3 100644 (file)
 #      domain).
 #
 #      Normally, the \fBaliases\fR(5) table is specified as a text file
-#      that serves as input to the \fBpostalias\fR(1) command. The
-#      result, an indexed file in \fBdbm\fR or \fBdb\fR format, is
-#      used for fast lookup by the mail system. Execute the command
-#      \fBnewaliases\fR in order to rebuild the indexed file after
-#      changing the Postfix alias database.
+#      that serves as input to the \fBpostalias\fR(1) command to create
+#      an indexed file for fast lookup. The location of this file is
+#      system-dependent. This text will use \fB/path/to/aliases\fR.
+#
+#      Execute the command "\fBnewaliases\fR to rebuild the indexed
+#      file after changing the text file. Execute "\fBpostalias -q
+#      \fIname\fB /path/to/aliases\fR" to query a default-type indexed
+#      file, or execute "\fBpostalias -q \fIname\fB
+#      \fItype\fB:/path/to/aliases\fR" to specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions. In
index 5ffc8d1810ffc9171af6f6f5aff3818d290c0797..a3e729eff7ba9bb27f13c18aebeac22399316f1a 100644 (file)
 #      queue.  The address mapping is recursive.
 #
 #      Normally, the \fBcanonical\fR(5) table is specified as a text file
-#      that serves as input to the \fBpostmap\fR(1) command.
-#      The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-#      is used for fast searching by the mail system. Execute the command
-#      "\fBpostmap /etc/postfix/canonical\fR" to rebuild an indexed
-#      file after changing the corresponding text file.
+#      that serves as input to the \fBpostmap\fR(1) command to create
+#      an indexed file for fast lookup.
+#
+#      Execute the command "\fBpostmap /etc/postfix/canonical\fR" to
+#      rebuild a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/canonical\fR"
+#      to specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index 5dad4dc455a8118c9bfd04b001f7e37224547e4c..dc5292306424b7cec4fb86f929d24b12087e611e 100644 (file)
@@ -9,7 +9,9 @@
 #      \fBpostmap -q - cidr:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional lookup tables.
-#      These tables are usually in \fBdbm\fR or \fBdb\fR format.
+#      These tables are usually in \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR,
+#      or \fBdbm:\fR format.
+#
 #      Alternatively, lookup tables can be specified in CIDR
 #      (Classless Inter-Domain Routing) form. In this case, each
 #      input is compared against a list of patterns. When a match
index dc0ad417723583ecd0359b13415ab190376890d5..fa6676532fa85805794fa1306691fb77b25c0950 100644 (file)
 #
 #      Normally, the \fBgeneric\fR(5) table is specified as a
 #      text file that serves as input to the \fBpostmap\fR(1)
-#      command.  The result, an indexed file in \fBdbm\fR or
-#      \fBdb\fR format, is used for fast searching by the mail
-#      system. Execute the command "\fBpostmap /etc/postfix/generic\fR"
-#      to rebuild an indexed file after changing the corresponding
-#      text file.
+#      command to create an indexed file for fast lookup. 
+#
+#      Execute the command "\fBpostmap /etc/postfix/generic\fR" to
+#      rebuild  a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/generic\fR"
+#      to specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index c9d07330a312e6206e048ebf7a5fe809c670b804..00a7d0404a586689b87aac2aa9a872ed10fcd98d 100644 (file)
@@ -137,6 +137,8 @@ Per-client/user/etc. access </a>
 
 <li> <a href="DATABASE_README.html"> Lookup table overview </a>
 
+<li> <a href="NON_BERKELEYDB_README.html"> Non-Berkeley-DB migration </a>
+
 <li> <a href="DB_README.html"> Berkeley DB Howto  </a>
 
 <li> <a href="CDB_README.html"> CDB Howto  </a>
index 79047755dcff95c216c532e34169fee5a44fcde7..732ea7d7bf8b89766883a4680c98eea6ef6dba09 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as LDAP databases.
+#      To find out what types of lookup tables your Postfix system
+#      supports use the "\fBpostconf -m\fR" command.
 #
 #      In order to use LDAP lookups, define an LDAP source as a lookup
 #      table in main.cf, for example:
index 6d424039467b93bacaa2d8798793a0310b5a5ae8..0eb629d5286400a461f4bab5d831c794f9fecac1 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as memcache
-#      instances.  To use memcache lookups, define a memcache
+#      instances. To use memcache lookups, define a memcache
 #      source as a lookup table in main.cf, for example:
 #
 # .nf
index 81dfc8e4da4bbd6185c2909ad1b89fcb563a6181..08a8eaa651616a96e40960cacd19abf74cf698a4 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as MongoDB
-#      databases.  In order to use MongoDB lookups, define a MongoDB
+#      databases.  
+#      To find out what types of lookup tables your Postfix system
+#      supports use the "\fBpostconf -m\fR" command.
+#
+#      In order to use MongoDB lookups, define a MongoDB
 #      source as a lookup table in main.cf, for example:
 # .nf
 #          alias_maps = mongodb:/etc/postfix/mongodb-aliases.cf
index 278a14689634bf4e4fdf825a1a493b84efaaefd4..3a0a8226c2a3edc952b17bacb463db6ad549ea98 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as MySQL databases.
+#      To find out what types of lookup tables your Postfix system
+#      supports use the "\fBpostconf -m\fR" command.
+#
 #      In order to use MySQL lookups, define a MySQL source as a lookup
 #      table in main.cf, for example:
 # .nf
index 2c8aefca4047877d776e4eb9ae7ebd5371848698..62d254a9ebc6310620c9c0ca3af54c400d177066 100644 (file)
@@ -9,10 +9,11 @@
 #      \fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB" <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional lookup tables.
-#      These tables are usually in \fBdbm\fR or \fBdb\fR format.
+#      rewriting or mail routing. These tables are usually in
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
+#
 #      Alternatively, lookup tables can be specified as NIS+
 #      databases.
-#
 #      To find out what types of lookup tables your Postfix system
 #      supports use the "\fBpostconf -m\fR" command.
 #
index 8b59cc2dc5dc518aef709a8ebb7c5dac7662ac1c..f128e4c76b62c260e518039c81fcedbbdad420c5 100644 (file)
@@ -13,8 +13,8 @@
 #      \fBpostmap -bmq - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
-#      rewriting, mail routing, or access control. These tables
-#      are usually in \fBdbm\fR or \fBdb\fR format.
+#      rewriting or mail routing. These tables are usually in
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified in Perl Compatible
 #      Regular Expression form. In this case, each input is compared
index edc50b619c0ba2e40ae5b760e7834fb69ead5c6f..826661ee645596601574dcca02bca8b3211d92b8 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as PostgreSQL
-#      databases.  In order to use PostgreSQL lookups, define a
+#      databases.  
+#      To find out what types of lookup tables your Postfix system
+#      supports use the "\fBpostconf -m\fR" command.
+#
+#      In order to use PostgreSQL lookups, define a
 #      PostgreSQL source as a lookup table in main.cf, for example:
 # .nf
 #          alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf
index 07116951969dc649245dcbd4747d08f65520f256..c1db394b7e06dd306bdeee53e5a9006de75b37d5 100644 (file)
@@ -12,7 +12,7 @@
 
 <script type="text/javascript">
 
-// Kludge for https://support.google.com/chrome/thread/11993079
+// See support.google.com/chrome/thread/11993079
 const isChrome = /Chrome/.test(navigator.userAgent)
     && /Google Inc/.test(navigator.vendor);
 const hash = window.location.hash;
index c65829ff8080a48a681ba24370b8309cac7ce060..6c3ae28a5432db624a65ec23426fbdb0877ea440 100644 (file)
@@ -236,7 +236,7 @@ Examples:
 
 <pre>
 address_verify_map = $default_cache_db_type:$data_directory/verify_cache
-address_verify_map = hash:/var/lib/postfix/verify_cache
+address_verify_map = lmdb:/var/lib/postfix/verify_cache
 address_verify_map = btree:/var/lib/postfix/verify_cache
 </pre>
 
@@ -483,10 +483,13 @@ Examples:
 </p>
 
 <pre>
-alias_database = hash:/etc/aliases
-alias_database = hash:/etc/mail/aliases
+alias_database = $default_database_type:/etc/aliases
+alias_database = lmdb:/etc/aliases
+alias_database = lmdb:/etc/mail/aliases
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 %PARAM alias_maps see "postconf -d" output
 
 <p>
@@ -511,12 +514,6 @@ The default list is system dependent.  On systems with NIS, the
 default is to search the local alias database, then the NIS alias
 database.
 </p>
-
-<p>
-If you change the alias database, run "<b>postalias /etc/aliases</b>"
-(or wherever your system stores the mail alias file), or simply
-run "<b>newaliases</b>" to build the necessary DBM or DB file.
-</p>
   
 <p>
 The local(8) delivery agent disallows regular expression substitution
@@ -535,10 +532,26 @@ Examples:
 </p>
 
 <pre>
-alias_maps = hash:/etc/aliases, nis:mail.aliases
-alias_maps = hash:/etc/aliases
+alias_maps = $default_database_type:/etc/aliases, nis:mail.aliases
+alias_maps = $default_database_type:/etc/aliases
+alias_maps = lmdb:/etc/mail/aliases
+alias_maps = lmdb:/etc/aliases
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postalias <i>/path/to/aliases</i>" after you
+change the aliases file, to (re)build a default-type indexed file.
+Execute "postalias <i>type:/path/to/aliases</i>" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM allow_mail_to_commands alias, forward
 
 <p>
@@ -828,13 +841,6 @@ until a match is found.
 Note: these lookups are recursive.
 </p>
 
-<p>
-If you use this feature, run "<b>postmap /etc/postfix/canonical</b>" to
-build the necessary DBM or DB file after every change. The changes
-will become visible after a minute or so.  Use "<b>postfix reload</b>"
-to eliminate the delay.
-</p>
-
 <p> Note: with Postfix version 2.2, message header address mapping
 happens only when message header address rewriting is enabled: </p>
 
@@ -858,10 +864,23 @@ Examples:
 </p>
 
 <pre>
-canonical_maps = dbm:/etc/postfix/canonical
-canonical_maps = hash:/etc/postfix/canonical
+canonical_maps = lmdb:/etc/postfix/canonical
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/canonical" after you
+change the canonical file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/canonical" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM canonical_classes envelope_sender, envelope_recipient, header_sender, header_recipient
 
 <p> What addresses are subject to canonical_maps address mapping.
@@ -974,7 +993,7 @@ debug_peer_list = example.com
 <p>
 The default database type for use in newaliases(1), postalias(1)
 and postmap(1) commands. On many UNIX systems the default type is
-either <b>dbm</b> or <b>hash</b>. The default setting is frozen
+either <b>lmdb</b> or <b>hash</b>. The default setting is frozen
 when the Postfix system is built.
 </p>
 
@@ -983,8 +1002,8 @@ Examples:
 </p>
 
 <pre>
+default_database_type = lmdb
 default_database_type = hash
-default_database_type = dbm
 </pre>
 
 %PARAM default_delivery_slot_cost 5
@@ -3223,10 +3242,15 @@ mynetworks = 127.0.0.0/8 168.100.189.0/28
 mynetworks = !192.168.0.1, 192.168.0.0/28
 mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:587::]/64 
 mynetworks = $config_directory/mynetworks
-mynetworks = hash:/etc/postfix/network_table
+mynetworks = lmdb:/etc/postfix/network_table
 mynetworks = cidr:/etc/postfix/network_table.cidr
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Configuration changes will become visible after a minute or so.
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM myorigin $myhostname
 
 <p>
@@ -3588,7 +3612,7 @@ syntax.
 
 <pre>
 /etc/postfix/main.cf:
-    rbl_reply_maps = hash:/etc/postfix/rbl_reply
+    rbl_reply_maps = lmdb:/etc/postfix/rbl_reply
     smtpd_recipient_restrictions =
         permit_mynetworks, 
         reject_rbl_client <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11],
@@ -3610,6 +3634,8 @@ syntax.
         554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details 
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p>
 NOTE: This feature differs from postscreen_dnsbl_reply_map where
 the table search key is only a domain name (no "<i>=address-filter</i>",
@@ -3617,6 +3643,19 @@ no "<i>*weight</i>" factor) and where the lookup result
 should be only a domain name (no free text, no <i>$name</i> variables).
 </p>
 
+<p> Execute the command "postmap /etc/postfix/rbl_reply" after you
+change the rbl_reply file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/rbl_reply" to specify an 
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
+
 <p>
 This feature is available in Postfix 2.0 and later.
 The "=address-filter" feature is available in Postfix 2.8 and later.
@@ -3745,12 +3784,23 @@ Example:
 </p>
 
 <pre>
-recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
+recipient_bcc_maps = lmdb:/etc/postfix/recipient_bcc
 </pre>
 
-<p>
-After a change, run "<b>postmap /etc/postfix/recipient_bcc</b>".
-</p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/recipient_bcc" after
+you change the recipient_bcc file, to (re)build a default-type indexed
+file.  Execute "postmap <i>type</i>:/etc/postfix/recipient_bcc" to
+specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 
 <p>
 This feature is available in Postfix 2.1 and later.
@@ -3773,9 +3823,25 @@ Example:
 </p>
 
 <pre>
-recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
+recipient_canonical_maps = lmdb:/etc/postfix/recipient_canonical
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/recipient_canonical"
+after you change the recipient_canonical file, to (re)build a
+default-type indexed file.  Execute "postmap
+<i>type</i>:/etc/postfix/recipient_canonical" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
+
 %PARAM recipient_delimiter
 
 <p> The set of characters that can separate an email address
@@ -3919,9 +3985,23 @@ Example:
 </p>
 
 <pre>
-relay_recipient_maps = hash:/etc/postfix/relay_recipients
+relay_recipient_maps = lmdb:/etc/postfix/relay_recipients
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relay_recipients"
+after you change the relay_recipients file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/relay_recipients"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p>
 This feature is available in Postfix 2.0 and later.
 </p>
@@ -4005,21 +4085,28 @@ whitespace or comma. Tables will be searched in the specified order
 until a match is found.
 </p>
 
-<p>
-If you use this feature, run "<b>postmap /etc/postfix/relocated</b>" to
-build the necessary DBM or DB file after change, then "<b>postfix
-reload</b>" to make the changes visible.
-</p>
-
 <p>
 Examples:
 </p>
 
 <pre>
-relocated_maps = dbm:/etc/postfix/relocated
-relocated_maps = hash:/etc/postfix/relocated
+relocated_maps = lmdb:/etc/postfix/relocated
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/relocated" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM relocated_prefix_enable  yes
 
 <p> Prepend the prefix "<b>5.1.6 User has moved to </b>" to all
@@ -4033,13 +4120,29 @@ Example:
 
 <pre>
 /etc/postfix/main.cf:
-    relocated_maps = hash:/etc/postfix/relocated
+    relocated_maps = lmdb:/etc/postfix/relocated
     relocated_prefix_enable = no
 <br>
-hash:/etc/postfix/relocated:
+/etc/postfix/relocated:
     user@example.com 5.2.1 User account is disabled
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/relocated" after you
+change the relocated file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/relocated" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
+<p> This feature is available in Postfix 3.11 and later. </p>
+
 %PARAM require_home_directory no
 
 <p>
@@ -4141,12 +4244,22 @@ Example:
 </p>
 
 <pre>
-sender_bcc_maps = hash:/etc/postfix/sender_bcc
+sender_bcc_maps = lmdb:/etc/postfix/sender_bcc
 </pre>
 
-<p>
-After a change, run "<b>postmap /etc/postfix/sender_bcc</b>".
-</p>
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/sender_bcc" after you
+change the sender_bcc file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/sender_bcc" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
 
 <p>
 This feature is available in Postfix 2.1 and later.
@@ -4175,9 +4288,23 @@ Example:
 </p>
 
 <pre>
-sender_canonical_maps = hash:/etc/postfix/sender_canonical
+sender_canonical_maps = lmdb:/etc/postfix/sender_canonical
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/sender_canonical"
+after you change the sender_canonical file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/sender_canonical"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM smtp_always_send_ehlo yes
 
 <p>
@@ -7019,9 +7146,23 @@ Examples:
 <pre>
 smtpd_sender_restrictions = reject_unknown_sender_domain
 smtpd_sender_restrictions = reject_unknown_sender_domain,
-    check_sender_access hash:/etc/postfix/access
+    check_sender_access lmdb:/etc/postfix/access
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/access" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM smtpd_timeout normal: 300s, overload: 10s
 
 <p> When the Postfix SMTP server wants to send an SMTP server
@@ -7183,9 +7324,7 @@ $sender_dependent_default_transport_maps, or the recipient domain.
 <p>
 Specify zero or more "type:table" lookup tables, separated by
 whitespace or comma. Tables will be searched in the specified order
-until a match is found.  If you use this
-feature with local files, run "<b>postmap /etc/postfix/transport</b>"
-after making a change.  </p>
+until a match is found.  </p>
 
 <p> Pattern matching of domain names is controlled by the presence
 or absence of "transport_maps" in the parent_domain_matches_subdomains
@@ -7199,10 +7338,23 @@ Examples:
 </p>
 
 <pre>
-transport_maps = dbm:/etc/postfix/transport
-transport_maps = hash:/etc/postfix/transport
+transport_maps = lmdb:/etc/postfix/transport
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/transport" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM transport_retry_time 60s
 
 <p>
@@ -7456,20 +7608,28 @@ until a match is found.
 Note: these lookups are recursive.
 </p>
 
-<p>
-If you use this feature with indexed files, run "<b>postmap
-/etc/postfix/virtual</b>" after changing the file.
-</p>
-
 <p>
 Examples:
 </p>
 
 <pre>
-virtual_alias_maps = dbm:/etc/postfix/virtual
-virtual_alias_maps = hash:/etc/postfix/virtual
+virtual_alias_maps = lmdb:/etc/postfix/virtual
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/virtual" after you
+change the virtual file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/virtual" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 %PARAM virtual_alias_recursion_limit 1000
 
 <p>
@@ -9725,10 +9885,12 @@ system.  </p>
 <pre>
 local_header_rewrite_clients = permit_mynetworks, 
     permit_sasl_authenticated permit_tls_clientcerts
-    check_address_map hash:/etc/postfix/pop-before-smtp 
+    check_address_map lmdb:/etc/postfix/pop-before-smtp 
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 %PARAM smtpd_tls_cert_file
 
 <p> File with the Postfix SMTP server RSA certificate in PEM format.
@@ -10088,8 +10250,8 @@ this TLS extension.  See also smtpd_tls_session_cache_timeout. </p>
 <p> Examples: </p>
 
 <pre>
-smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
 smtpd_tls_session_cache_database = lmdb:/var/lib/postfix/smtpd_scache
+smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
 </pre>
 
 <p> This feature is available in Postfix 2.2 and later.  </p>
@@ -10145,13 +10307,27 @@ D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home </p>
 <p> Example: </p>
 
 <pre>
-relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+relay_clientcerts = lmdb:/etc/postfix/relay_clientcerts
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p>For more fine-grained control, use check_ccert_access to select
 an appropriate access(5) policy for each client.
 See RESTRICTION_CLASS_README.</p>
 
+<p> Execute the command "postmap /etc/postfix/relay_clientcerts"
+after you change the relay_clientcerts file, to (re)build a default-type
+indexed file.  Execute "postmap <i>type</i>:/etc/postfix/relay_clientcerts"
+to specify an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p>This feature is available with Postfix version 2.2.</p>
 
 %PARAM smtpd_tls_cipherlist
@@ -10440,7 +10616,7 @@ problems. Use of loglevel 4 is strongly discouraged. </p>
 
 <p> Name of the file containing the optional Postfix SMTP client
 TLS session cache. Specify a database type that supports enumeration,
-such as <b>btree</b> or <b>sdbm</b>; there is no need to support
+such as <b>lmdb</b> or <b>btree</b>; there is no need to support
 concurrent access.  The file is created if it does not exist. The smtp(8)
 daemon does not use this parameter directly, rather the cache is
 implemented indirectly in the tlsmgr(8) daemon. This means that
@@ -10463,8 +10639,8 @@ data_directory, and a warning is logged. </p>
 <p> Example: </p>
 
 <pre>
-smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
 smtp_tls_session_cache_database = lmdb:/var/lib/postfix/smtp_scache
+smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
 </pre>
 
 <p> This feature is available in Postfix 2.2 and later.  </p>
@@ -11791,7 +11967,7 @@ Example:
 
 <pre>
 /etc/postfix/main.cf:
-    smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+    smtp_tls_policy_maps = lmdb:/etc/postfix/tls_policy
     # Postfix 2.5 and later.
     #
     # The default digest is sha256 with Postfix &ge; 3.6 and
@@ -11815,12 +11991,26 @@ Example:
         match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> <b>Note:</b> The "hostname" strategy if listed in a non-default
 setting of smtp_tls_secure_cert_match or in the "match" attribute
 in the policy table can 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. </p>
 
+<p> Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/tls_policy" to specify
+an explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 %PARAM smtp_tls_mandatory_protocols see "postconf -d" output
@@ -13074,7 +13264,7 @@ As in the example above, we show two matching fingerprints: </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+    smtp_tls_policy_maps = lmdb:/etc/postfix/tls_policy
     smtp_tls_fingerprint_digest = sha256
 </pre>
 </blockquote>
@@ -13088,6 +13278,20 @@ As in the example above, we show two matching fingerprints: </p>
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/tls_policy" after you
+change the tls_policy file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/tls_policy" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 %PARAM lmtp_tls_fingerprint_cert_match
@@ -13172,7 +13376,7 @@ higher. </p>
 /etc/postfix/main.cf:
     smtpd_tls_fingerprint_digest = sha256
     smtpd_client_restrictions =
-        check_ccert_access hash:/etc/postfix/access,
+        check_ccert_access lmdb:/etc/postfix/access,
         reject
 </pre>
 <pre>
@@ -13185,6 +13389,20 @@ higher. </p>
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/access" after you
+change the access file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/access" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 %PARAM lmtp_pix_workaround_maps
@@ -14293,8 +14511,8 @@ passwords, and requires that Postfix is compiled with TLS support.
 <p> Examples: </p>
 
 <pre>
-smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
 smtp_sasl_auth_cache_name = proxy:lmdb:/var/lib/postfix/sasl_auth_cache
+smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
 </pre>
 
 <p> This feature is available in Postfix 2.5 and later. </p>
@@ -14678,8 +14896,8 @@ patch for Postfix 2.6. </p>
 <p> Persistent storage for the postscreen(8) server decisions. </p>
 
 <p> To share a postscreen(8) cache between multiple postscreen(8)
-instances, use "postscreen_cache_map = proxy:btree:/path/to/file"
-or "proxy:lmdb:/path/to/file".
+instances, use "postscreen_cache_map = proxy:lmdb:/path/to/file"
+or "proxy:btree:/path/to/file".
 This requires Postfix version 2.9 or later; earlier proxymap(8)
 implementations don't support cache cleanup. For an alternative
 approach see the memcache_table(5) manpage. </p>
@@ -16665,7 +16883,7 @@ transport_maps to apply this feature selectively:  </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    transport_maps = hash:/etc/postfix/transport
+    transport_maps = lmdb:/etc/postfix/transport
 </pre>
 </blockquote>
 
@@ -16687,10 +16905,24 @@ transport_maps to apply this feature selectively:  </p>
 </pre>
 </blockquote>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
 <p> Unselective use of the "data" target does no harm, but will
 result in unnecessary "lost connection after DATA" events at remote
 SMTP/LMTP servers. </p>
 
+<p> Execute the command "postmap /etc/postfix/transport" after you
+change the transport file, to (re)build a default-type indexed file.
+Execute "postmap <i>type</i>:/etc/postfix/transport" to specify an
+explicit type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 <p> This feature is available in Postfix 3.0 and later.  </p>
 
 %PARAM lmtp_address_verify_target rcpt
@@ -19774,7 +20006,7 @@ A non-ASCII next-hop destination is converted into ASCII form
 (Punycode) before making a policy query; lookup tables must answer
 ASCII-form queries. </p>
 
-<li> <p> A fixed-string table (such as hash:, btree:, or lmdb:) is
+<li> <p> A fixed-string table (such as lmdb:, cdb:, or hash:) is
 also searched with the next-hop ".parent" domains (in a table key,
 prepend a '.' to a parent domain name). These ".parent" domain
 queries are not made with pattern-based lookup tables such as regexp:
@@ -19851,7 +20083,7 @@ REQUIRETLS support, but the support is inoperable. </p></dd>
 <li> <p> To match any name below the domain "example.com" specify
 a table entry with the storage key ".example.com" in type:table
 lookup tables that need an exact match. This is appropriate, for
-example, with hash:, btree: or lmdb:. </p>
+example, with lmdb:, cdb: or hash:. </p>
 
 <li> <p> Do not specify a match pattern for ".domain" with regexp:,
 pcre:, socketmap:, or tcp:, as smtp_requiretls_policy will
@@ -19952,7 +20184,7 @@ file for easier maintenance. </p>
         cidr:{
             { 0.0.0.0/0 opportunistic },
             { ::/0 opportunistic } },
-       hash:/etc/postfix/requiretls-per-site
+       lmdb:/etc/postfix/requiretls-per-site
        opportunistic+starttls
 </pre>
 <pre>
@@ -19963,6 +20195,21 @@ file for easier maintenance. </p>
     ...
 </pre>
 
+<p> Instead of lmdb:, some systems use cdb:, hash:, or dbm:. </p>
+
+<p> Execute the command "postmap /etc/postfix/requiretls-per-site"
+after you change the requiretls-per-site file, to (re)build a
+default-type indexed file.  Execute "postmap
+<i>type</i>:/etc/postfix/requiretls-per-site" to specify an explicit
+type. </p>
+
+<p> The default indexed file type is configured with the
+default_database_type parameter. To list available explicit types,
+execute the command "postconf -m". </p>
+
+<p> Configuration changes will become visible after a minute or so. 
+Use "postfix reload" to eliminate the delay. </p>
+
 </ul>
 
 <p>
@@ -20294,7 +20541,7 @@ to=&lt;<i>recipient</i>&gt;
 </pre>
 </dd>
 
-<dl>
+</dl>
 
 <p> This feature is available in Postfix &ge; 3.11. </p>
 
@@ -20305,3 +20552,93 @@ postscreen_cache_map. Before Postfix 3.11 those caches used btree
 by default. </p>
 
 <p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_bdb_migration_allow_root_prefixes see 'postconf -d non_bdb_migration_allow_root_prefixes' output
+
+<p> A list of trusted pathname prefixes that must be matched when
+the non-Berkeley-DB migration service (nbdb_reindexd(8)) needs to
+run postmap(1) or postalias(1) commands with "root" privilege.
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_bdb_migration_allow_user_prefixes see 'postconf -d non_bdb_migration_allow_user_prefixes' output
+
+<p> A list of trusted pathname prefixes that must be matched when
+the non-Berkeley-DB migration service (nbdb_reindexd(8)) needs to
+run postmap(1) or postalias(1) commands with non-root privilege. </p>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_bdb_custom_mapping empty
+
+<p> When non-Berkeley-DB migration is enabled, an optional mapping
+from a hash: or btree: type to a non-Berkeley-DB type. This mapping
+takes precedence over the default mapping from hash: to
+$default_database_type, and from btree: to $default_cache_db_type.
+</p>
+
+<ul>
+
+<li> <p> Specify a lookup table with a search keys that are a
+Berkeley DB <i>type</i> (without ':') or <i>type:name</i>. </p>
+
+<li> <p> A search key with the form <i>type:name</i> takes precedence
+over <i>type</i> (without ':'). </p>
+
+<li> <p>  The lookup result must always be a non-Berkeley-DB <i>type</i>
+(without ':') and must not contain a <i>:name</i>.  </p>
+
+<li> <p> The mapping table type must not be <b>hash</b> or <b>btree</b>.
+
+</ul>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_bdb_migration_level disable
+
+<p> The non-Berkeley-DB migration service level. You are expected to use
+the command "<b>postfix non-bdb <i>name-of-level</i></b>" to correctly
+configure the migration service level (see postfix-non-bdb(1). </p>
+
+<dl>
+
+<dt><b>disable</b></dt>
+
+<dd> <p> Disable all non-Berkeley-DB migration features. See
+NON_BERKELEYDB_README#disable for possible negative implications
+for integration with other software such as mailman. </p> </dd>
+
+<dt><b>enable-redirect</b> (aliasing)</dt>
+
+<dd> <p> Enable redirection (aliasing) from Berkeley DB hash to
+$default_database_type, and from Berkeley DB btree to
+$default_cache_db_type, but do not automatically create the new cdb
+or lmdb indexed database files that Postfix programs need. See
+NON_BERKELEYDB_README#enable-redirect for details and limitations.
+</p> </dd>
+
+<dt><b>enable-reindex</b></dt>
+
+<dd> <p> In addition to enable-redirect, also create a non-Berkeley-DB
+indexed database file when a daemon program wants to access a file
+that does not yet exist. This feature uses the nbdb_reindexd(8)
+daemon to run postmap(1) or postalias(1).   See
+NON_BERKELEYDB_README#enable-reindex for details and limitations.
+</p>
+
+<p> <i> NOTE: <b>enable-reindex</b> should be used only temporarily to
+generate most of the non-Berkeley-DB indexed database files that Postfix
+programs need. Leaving this level enabled may expose the system to
+privilege-escalation attacks. There are no security concerns for using
+<b>enable-redirect</b>. </i> </p> </dd>
+
+</dl>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_bdb_migration_service_name nbdb_reindex
+
+<p> The name of a master.cf service that implements the non-Berkeley-DB
+migration service protocol. </p>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
index c8e738f2ac6b709bc782b13f07a85893251b92b5..419e4599137e8777888098796ef1314b4727ab35 100644 (file)
@@ -9,8 +9,8 @@
 #      \fBpostmap -q - regexp:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
-#      rewriting, mail routing, or access control. These tables
-#      are usually in \fBdbm\fR or \fBdb\fR format.
+#      rewriting or mail routing. These tables are usually in
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified in POSIX regular
 #      expression form. In this case, each input is compared against a
index f90c9146cda9d0363c9b27e3f4f1bc456c9bc7d6..c604fcb63d8c441462d870519638f8f2fded333b 100644 (file)
 #      used in "user has moved to \fInew_location\fR" bounce messages.
 #
 #      Normally, the \fBrelocated\fR(5) table is specified as a text file
-#      that serves as input to the \fBpostmap\fR(1) command.
-#      The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-#      is used for fast searching by the mail system. Execute the command
-#      "\fBpostmap /etc/postfix/relocated\fR" to rebuild an indexed
-#      file after changing the corresponding relocated table.
+#      that serves as input to the \fBpostmap\fR(1) command to create
+#      an indexed file for fast lookup.
+#
+#      Execute the command "\fBpostmap /etc/postfix/relocated\fR" to
+#      rebuild a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/relocated\fR" to
+#      specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index 47205b735ffcd4c96406ab0b87a498ce1ff769b4..b9e46b0c088cb7b569cf9ea535a22abb992c2f6c 100644 (file)
@@ -13,7 +13,8 @@
 #      \fBpostmap -q - socketmap:unix:\fIpathname\fB:\fIname\fB <\fIinputfile\fR
 # DESCRIPTION
 #      The Postfix mail system uses optional tables for address
-#      rewriting, mail routing or policy lookup.
+#      rewriting or mail routing. These tables are usually in
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      The Postfix socketmap client expects TCP endpoint names of
 #      the form \fBinet:\fIhost\fB:\fIport\fB:\fIname\fR, or
index a4edf72e89302f25ddcfe9723b43bfa7b6e7eabd..ec226600c32716f267b3e836e99b8a12e743df95 100644 (file)
 # 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.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
 #      Alternatively, lookup tables can be specified as SQLite databases.
+#      To find out what types of lookup tables your Postfix system
+#      supports use the "\fBpostconf -m\fR" command.
+#
 #      In order to use SQLite lookups, define an SQLite source as a lookup
 #      table in main.cf, for example:
 # .nf
index 55646792fcf37422e07d293dfddc6ac631c37072..423d4f3b87086209edfd92f94f1b0b879491132a 100644 (file)
@@ -1707,3 +1707,7 @@ sts
 jF
 jM
 jP
+subcommand
+CLI
+Fedor
+Vorobev
index df20b9258d42cdb37b3b8517f9234783f79b033a..40fe40e68e2d2af9938d106c8e4dcf8694a49ab4 100644 (file)
@@ -352,3 +352,7 @@ void  void pol_stats_revert POL_STATS pstats
  feature feature etc where 
  policies policy policy domain If null this defaults to the
 bounce  bounce defer trace 
+dict_open  dict_open looks up our DICT_OPEN_INFO with dict_fn and mkmap_fn
+mkmap_open  mkmap_open looks up our DICT_OPEN_INFO with dict_fn and mkmap_fn
+ typedef struct MSG_CAPTURE MSG_CAPTURE 
+MSG_CAPTURE  MSG_CAPTURE msg_capt_create ssize_t init_size 
index b6a2c6f60551cd291d0707b9f78690ffe8b84225..f7dc6c0435f3250583da7ef327add58cac258d53 100644 (file)
@@ -221,3 +221,10 @@ proto  proto socketmap_table qmqpd qmqpd c tls tls_misc c
  src dns dns h 
  postconf postconf hc postconf postconf_master c 
  PPx proxy_read_maps Files postconf postconf hc 
+proto  proto stop proto stop double cc 
+ proto stop spell proto html postfix postfix c
+ postalias postalias c postmap postmap c 
+ proto stop spell proto html postfix postfix c conf postfix files
+ proto stop spell proto html postfix postfix c conf postfix files 
+ File nbdb_reindexd nbdb_reindexd c 
+ tls tls h tls tls_misc c tls tls_verify c 
index 555de899dcb76a2a2c32634bfdf1340cb0507b72..332d13d69638f98f7c2308fa51c27b76f988ffea 100644 (file)
@@ -47,5 +47,6 @@ Inbound SMTP smuggling don t strip extra CR in CR LF CR CR LF
  pattern number number number text 
 to  to the lookup result With Postfix 3 11 and later specify
  has moved to to a table lookup result and the format for a
+after stripping whitespace between the the value and the 
 after stripping whitespace betwen the the value and the 
 after stripping whitespace between the the value and the 
index 33f973d941e68dc5f5da4a44579f19245e614763..5397d2b83f0c679087cc938d4d13dc7806d3f415 100644 (file)
@@ -382,3 +382,5 @@ tt  tt tls i level i requiretls noencryption tt or
 smtp_requiretls_policy smtp_requiretls_policy inline 
  xn mumble mumble Punycode A label form that Postfix needs This works around a limitation that may be eliminated in a future Postfix version 
 in tt tt p 
+mynetworks mynetworks lmdb etc postfix network_table
+ 25 enable redirect redirect hash to lmdb or cdb 
index 57e7c41b616caf38e59576de980f5c3cbbddb92a..192c871aac9ee887bc56c11272f216146c8005cd 100644 (file)
@@ -1891,3 +1891,26 @@ fhHjoqvx
 joqvx
 ajRv
 allparams
+BERKELEYDB
+Chari
+MIGR
+Matchers
+Mockable
+NBDB
+Postmap
+REINDEX
+Sndump
+Un
+bdb
+cust
+ig
+maxtry
+mockable
+nbdb
+rdr
+reindex
+reindexd
+reindexed
+reindexing
+surr
+whoami
index b119d41794d0f878c385f9b5af220c5a6eebc66d..9738b63b086985168a53cc7078b9fb7f26999ae4 100644 (file)
@@ -127,3 +127,5 @@ MAXDNAME
 unbroke
 PPx
 unbroke
+smithing
+Scheiner
index cd491eb9540050d3531c14694e441cb69579982e..c8ad5577fe0a7bb692b6d948cd6ddb00c1018fbc 100644 (file)
@@ -405,3 +405,12 @@ noencryption
 nomatch
 nostarttls
 mariadb
+BERKELEYDB
+bdb
+gitlab
+nbdb
+reindex
+reindexd
+hPP
+hPPx
+hx
index d1ddb8151ef8079ea100b19f3bedf78a8d581229..9c39ba0bbae38ea533986dff5e3f9dbb450493f3 100644 (file)
 # 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, table lookups
-#      can be directed to a TCP server.
-#
-#      To find out what types of lookup tables your Postfix system
-#      supports use the "\fBpostconf -m\fR" command.
+#      \fBlmdb:\fR, \fBcdb:\fR, \fBhash:\fR, or \fBdbm:\fR format.
 #
+#      Alternatively, table lookups can be directed to a TCP server.
 #      To test lookup tables, use the "\fBpostmap -q\fR" command as
 #      described in the SYNOPSIS above.
 # PROTOCOL DESCRIPTION
index 3354113d280ab43f00d72759f56d43f17da5a238..90c5b2ea265f272f0e10757c02a1df0d0d4d26f2 100644 (file)
 #      \fBrelayhost\fR, or from the recipient domain.
 # .PP
 #      Normally, the \fBtransport\fR(5) table is specified as a text file
-#      that serves as input to the \fBpostmap\fR(1) command.
-#      The result, an indexed file in \fBdbm\fR or \fBdb\fR format, is used
-#      for fast searching by the mail system. Execute the command
-#      "\fBpostmap /etc/postfix/transport\fR" to rebuild an indexed
-#      file after changing the corresponding transport table.
+#      that serves as input to the \fBpostmap\fR(1) command to create
+#      an indexed file for fast lookup.
+#
+#      Execute the command "\fBpostmap /etc/postfix/transport\fR" to
+#      rebuild a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/transport\fR" to
+#      specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index 0affd82f1d44b32b8b997182c65131d9ad9f4c71..c4153be99146382d6c495e4405570067365ce034 100644 (file)
 #      mapping to rewrite header and envelope addresses in general.
 #
 #      Normally, the \fBvirtual\fR(5) alias table is specified as a text file
-#      that serves as input to the \fBpostmap\fR(1) command.
-#      The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-#      is used for fast searching by the mail system. Execute the command
-#      "\fBpostmap /etc/postfix/virtual\fR" to rebuild an indexed
-#      file after changing the corresponding text file.
+#      that serves as input to the \fBpostmap\fR(1) command to create
+#      an indexed file for fast lookup.
+#
+#      Execute the command "\fBpostmap /etc/postfix/virtual\fR" to
+#      rebuild a default-type indexed file after changing the text file,
+#      or execute "\fBpostmap \fItype\fB:/etc/postfix/virtual\fR" to
+#      specify an explicit type.
+#
+#      The default indexed file type is configured with the
+#      default_database_type parameter. Depending on the platform this
+#      may be one of lmdb:, cdb:, hash:, or dbm: (without the trailing
+#       ':').
 #
 #      When the table is provided via other means such as NIS, LDAP
 #      or SQL, the same lookups are done as for ordinary indexed files.
+#      Managing such databases is outside the scope of Postfix.
 #
 #      Alternatively, the table can be provided as a regular-expression
 #      map where patterns are given as regular expressions, or lookups
index a57ef1446247b8d094117e60473ac5ec2ad79fb5..5c993bf961d4b169524ba45f159e563dbd1ad111 100644 (file)
@@ -38,7 +38,8 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        info_log_addr_form.c sasl_mech_filter.c login_sender_match.c \
        test_main.c compat_level.c config_known_tcp_ports.c \
        hfrom_format.c rfc2047_code.c ascii_header_text.c sendopts.c \
-       pol_stats.c
+       pol_stats.c nbdb_clnt.c nbdb_util.c allowed_prefix.c \
+       nbdb_redirect.c nbdb_surrogate.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 \
@@ -78,7 +79,8 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        info_log_addr_form.o sasl_mech_filter.o login_sender_match.o \
        test_main.o compat_level.o config_known_tcp_ports.o \
        hfrom_format.o rfc2047_code.o ascii_header_text.o sendopts.o \
-       pol_stats.o
+       pol_stats.o nbdb_clnt.o nbdb_util.o allowed_prefix.o \
+       nbdb_redirect.o nbdb_surrogate.o
 # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
 # When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
 # otherwise it sets the PLUGIN_* macros.
@@ -116,9 +118,12 @@ HDRS       = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        info_log_addr_form.h sasl_mech_filter.h login_sender_match.h \
        test_main.h compat_level.h config_known_tcp_ports.h \
        hfrom_format.h rfc2047_code.h ascii_header_text.h sendopts.h \
-       pol_stats.h
+       pol_stats.h nbdb_clnt.h nbdb_util.h allowed_prefix.h \
+       nbdb_redirect.h nbdb_surrogate.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c dict_sqlite_test.c \
-       ehlo_mask_test.c haproxy_srvr_test.c sendopts_test.c pol_stats_test.c
+       ehlo_mask_test.c haproxy_srvr_test.c sendopts_test.c pol_stats_test.c \
+       allowed_prefix_test.c nbdb_util_test.c nbdb_redirect_test.c \
+       nbdb_surrogate_test.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
 INCL   =
@@ -135,7 +140,10 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
        fold_addr smtp_reply_footer mail_addr_map normalize_mailhost_addr \
        haproxy_srvr_test map_search delivered_hdr login_sender_match_test \
        compat_level config_known_tcp_ports hfrom_format rfc2047_code \
-       ascii_header_text sendopts_test dict_sqlite_test pol_stats_test
+       ascii_header_text sendopts_test dict_sqlite_test pol_stats_test \
+       allowed_prefix_test nbdb_util_test nbdb_redirect_test \
+       nbdb_surrogate_test
+TESTLIB        = $(LIB_DIR)/libtesting.a
 
 LIBS   = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
 LIB_DIR        = ../../lib
@@ -420,6 +428,18 @@ pol_stats_test: pol_stats_test.c pol_stats.o $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c pol_stats.o $(LIB) $(LIBS) \
            $(SYSLIBS)
 
+allowed_prefix_test: allowed_prefix_test.o $(TESTLIB) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIB) $(LIB) $(LIBS) $(SYSLIBS)
+
+nbdb_util_test: nbdb_util_test.o $(TESTLIB) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIB) $(LIB) $(LIBS) $(SYSLIBS)
+
+nbdb_redirect_test: nbdb_redirect_test.o $(TESTLIB) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIB) $(LIB) $(LIBS) $(SYSLIBS)
+
+nbdb_surrogate_test: nbdb_surrogate_test.o $(TESTLIB) $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(TESTLIB) $(LIB) $(LIBS) $(SYSLIBS)
+
 config_known_tcp_ports: config_known_tcp_ports.c $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
@@ -433,7 +453,10 @@ tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
        normalize_mailhost_addr_test test_haproxy_srvr map_search_test \
        delivered_hdr_test test_login_sender_match compat_level_test \
        config_known_tcp_ports_test hfrom_format_test rfc2047_code_test \
-       ascii_header_text_test test_sendopts test_dict_sqlite test_pol_stats
+       ascii_header_text_test test_sendopts test_dict_sqlite test_pol_stats \
+       test_allowed_prefix nbdb_tests
+
+nbdb_tests: test_nbdb_util test_nbdb_redirect test_nbdb_surrogate
 
 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
@@ -808,6 +831,18 @@ test_dict_sqlite: update dict_sqlite_test
 test_pol_stats: update pol_stats_test
        $(SHLIB_ENV) $(VALGRIND) ./pol_stats_test
 
+test_allowed_prefix: update allowed_prefix_test
+       $(SHLIB_ENV) $(VALGRIND) ./allowed_prefix_test
+
+test_nbdb_util: update nbdb_util_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_util_test
+
+test_nbdb_redirect: update nbdb_redirect_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_redirect_test
+
+test_nbdb_surrogate: update nbdb_surrogate_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_surrogate_test
+
 clean:
        rm -f *.o $(LIB) *core $(TESTPROG) junk $(MAPS)
 
@@ -854,6 +889,30 @@ addr_match_list.o: ../../include/vbuf.h
 addr_match_list.o: ../../include/vstring.h
 addr_match_list.o: addr_match_list.c
 addr_match_list.o: addr_match_list.h
+allowed_prefix.o: ../../include/argv.h
+allowed_prefix.o: ../../include/check_arg.h
+allowed_prefix.o: ../../include/htable.h
+allowed_prefix.o: ../../include/msg.h
+allowed_prefix.o: ../../include/mymalloc.h
+allowed_prefix.o: ../../include/split_at.h
+allowed_prefix.o: ../../include/stringops.h
+allowed_prefix.o: ../../include/sys_defs.h
+allowed_prefix.o: ../../include/vbuf.h
+allowed_prefix.o: ../../include/vstring.h
+allowed_prefix.o: allowed_prefix.c
+allowed_prefix.o: allowed_prefix.h
+allowed_prefix_test.o: ../../include/argv.h
+allowed_prefix_test.o: ../../include/check_arg.h
+allowed_prefix_test.o: ../../include/msg.h
+allowed_prefix_test.o: ../../include/msg_capture.h
+allowed_prefix_test.o: ../../include/msg_vstream.h
+allowed_prefix_test.o: ../../include/stringops.h
+allowed_prefix_test.o: ../../include/sys_defs.h
+allowed_prefix_test.o: ../../include/vbuf.h
+allowed_prefix_test.o: ../../include/vstream.h
+allowed_prefix_test.o: ../../include/vstring.h
+allowed_prefix_test.o: allowed_prefix.h
+allowed_prefix_test.o: allowed_prefix_test.c
 anvil_clnt.o: ../../include/attr.h
 anvil_clnt.o: ../../include/attr_clnt.h
 anvil_clnt.o: ../../include/check_arg.h
@@ -2051,6 +2110,7 @@ mail_params.o: mail_params.h
 mail_params.o: mail_proto.h
 mail_params.o: mail_version.h
 mail_params.o: mynetworks.h
+mail_params.o: nbdb_util.h
 mail_params.o: own_inet_addr.h
 mail_params.o: recipient_list.h
 mail_params.o: verp_sender.h
@@ -2386,6 +2446,141 @@ namadr_list.o: ../../include/vbuf.h
 namadr_list.o: ../../include/vstring.h
 namadr_list.o: namadr_list.c
 namadr_list.o: namadr_list.h
+nbdb_clnt.o: ../../include/argv.h
+nbdb_clnt.o: ../../include/attr.h
+nbdb_clnt.o: ../../include/check_arg.h
+nbdb_clnt.o: ../../include/connect.h
+nbdb_clnt.o: ../../include/dict.h
+nbdb_clnt.o: ../../include/htable.h
+nbdb_clnt.o: ../../include/iostuff.h
+nbdb_clnt.o: ../../include/msg.h
+nbdb_clnt.o: ../../include/myflock.h
+nbdb_clnt.o: ../../include/mymalloc.h
+nbdb_clnt.o: ../../include/nvtable.h
+nbdb_clnt.o: ../../include/sys_defs.h
+nbdb_clnt.o: ../../include/vbuf.h
+nbdb_clnt.o: ../../include/vstream.h
+nbdb_clnt.o: ../../include/vstring.h
+nbdb_clnt.o: mail_params.h
+nbdb_clnt.o: mail_proto.h
+nbdb_clnt.o: nbdb_clnt.c
+nbdb_clnt.o: nbdb_clnt.h
+nbdb_clnt.o: nbdb_util.h
+nbdb_redirect.o: ../../include/argv.h
+nbdb_redirect.o: ../../include/check_arg.h
+nbdb_redirect.o: ../../include/dict.h
+nbdb_redirect.o: ../../include/dict_cdb.h
+nbdb_redirect.o: ../../include/dict_db.h
+nbdb_redirect.o: ../../include/dict_lmdb.h
+nbdb_redirect.o: ../../include/mkmap.h
+nbdb_redirect.o: ../../include/msg.h
+nbdb_redirect.o: ../../include/myflock.h
+nbdb_redirect.o: ../../include/mymalloc.h
+nbdb_redirect.o: ../../include/name_code.h
+nbdb_redirect.o: ../../include/stringops.h
+nbdb_redirect.o: ../../include/sys_defs.h
+nbdb_redirect.o: ../../include/vbuf.h
+nbdb_redirect.o: ../../include/vstream.h
+nbdb_redirect.o: ../../include/vstring.h
+nbdb_redirect.o: mail_params.h
+nbdb_redirect.o: nbdb_clnt.h
+nbdb_redirect.o: nbdb_redirect.c
+nbdb_redirect.o: nbdb_redirect.h
+nbdb_redirect.o: nbdb_util.h
+nbdb_redirect_test.o: ../../include/argv.h
+nbdb_redirect_test.o: ../../include/check_arg.h
+nbdb_redirect_test.o: ../../include/dict.h
+nbdb_redirect_test.o: ../../include/dict_cdb.h
+nbdb_redirect_test.o: ../../include/dict_db.h
+nbdb_redirect_test.o: ../../include/dict_inline.h
+nbdb_redirect_test.o: ../../include/dict_lmdb.h
+nbdb_redirect_test.o: ../../include/mkmap.h
+nbdb_redirect_test.o: ../../include/mock_dict.h
+nbdb_redirect_test.o: ../../include/msg.h
+nbdb_redirect_test.o: ../../include/msg_capture.h
+nbdb_redirect_test.o: ../../include/msg_vstream.h
+nbdb_redirect_test.o: ../../include/myflock.h
+nbdb_redirect_test.o: ../../include/mymalloc.h
+nbdb_redirect_test.o: ../../include/stringops.h
+nbdb_redirect_test.o: ../../include/sys_defs.h
+nbdb_redirect_test.o: ../../include/vbuf.h
+nbdb_redirect_test.o: ../../include/vstream.h
+nbdb_redirect_test.o: ../../include/vstring.h
+nbdb_redirect_test.o: mail_params.h
+nbdb_redirect_test.o: nbdb_redirect.h
+nbdb_redirect_test.o: nbdb_redirect_test.c
+nbdb_redirect_test.o: nbdb_util.h
+nbdb_surrogate.o: ../../include/argv.h
+nbdb_surrogate.o: ../../include/check_arg.h
+nbdb_surrogate.o: ../../include/dict.h
+nbdb_surrogate.o: ../../include/dict_db.h
+nbdb_surrogate.o: ../../include/mkmap.h
+nbdb_surrogate.o: ../../include/msg.h
+nbdb_surrogate.o: ../../include/myflock.h
+nbdb_surrogate.o: ../../include/sys_defs.h
+nbdb_surrogate.o: ../../include/vbuf.h
+nbdb_surrogate.o: ../../include/vstream.h
+nbdb_surrogate.o: ../../include/vstring.h
+nbdb_surrogate.o: nbdb_surrogate.c
+nbdb_surrogate.o: nbdb_surrogate.h
+nbdb_surrogate_test.o: ../../include/argv.h
+nbdb_surrogate_test.o: ../../include/check_arg.h
+nbdb_surrogate_test.o: ../../include/dict.h
+nbdb_surrogate_test.o: ../../include/dict_db.h
+nbdb_surrogate_test.o: ../../include/mkmap.h
+nbdb_surrogate_test.o: ../../include/msg.h
+nbdb_surrogate_test.o: ../../include/msg_capture.h
+nbdb_surrogate_test.o: ../../include/msg_vstream.h
+nbdb_surrogate_test.o: ../../include/myflock.h
+nbdb_surrogate_test.o: ../../include/mymalloc.h
+nbdb_surrogate_test.o: ../../include/stringops.h
+nbdb_surrogate_test.o: ../../include/sys_defs.h
+nbdb_surrogate_test.o: ../../include/vbuf.h
+nbdb_surrogate_test.o: ../../include/vstream.h
+nbdb_surrogate_test.o: ../../include/vstring.h
+nbdb_surrogate_test.o: mail_params.h
+nbdb_surrogate_test.o: nbdb_surrogate.h
+nbdb_surrogate_test.o: nbdb_surrogate_test.c
+nbdb_surrogate_test.o: nbdb_util.h
+nbdb_util.o: ../../include/argv.h
+nbdb_util.o: ../../include/check_arg.h
+nbdb_util.o: ../../include/dict.h
+nbdb_util.o: ../../include/dict_cdb.h
+nbdb_util.o: ../../include/dict_db.h
+nbdb_util.o: ../../include/dict_lmdb.h
+nbdb_util.o: ../../include/mkmap.h
+nbdb_util.o: ../../include/msg.h
+nbdb_util.o: ../../include/myflock.h
+nbdb_util.o: ../../include/mymalloc.h
+nbdb_util.o: ../../include/name_code.h
+nbdb_util.o: ../../include/split_at.h
+nbdb_util.o: ../../include/stringops.h
+nbdb_util.o: ../../include/sys_defs.h
+nbdb_util.o: ../../include/vbuf.h
+nbdb_util.o: ../../include/vstream.h
+nbdb_util.o: ../../include/vstring.h
+nbdb_util.o: mail_params.h
+nbdb_util.o: nbdb_redirect.h
+nbdb_util.o: nbdb_surrogate.h
+nbdb_util.o: nbdb_util.c
+nbdb_util.o: nbdb_util.h
+nbdb_util_test.o: ../../include/argv.h
+nbdb_util_test.o: ../../include/check_arg.h
+nbdb_util_test.o: ../../include/dict.h
+nbdb_util_test.o: ../../include/mock_dict.h
+nbdb_util_test.o: ../../include/msg.h
+nbdb_util_test.o: ../../include/msg_capture.h
+nbdb_util_test.o: ../../include/msg_vstream.h
+nbdb_util_test.o: ../../include/myflock.h
+nbdb_util_test.o: ../../include/stringops.h
+nbdb_util_test.o: ../../include/sys_defs.h
+nbdb_util_test.o: ../../include/vbuf.h
+nbdb_util_test.o: ../../include/vstream.h
+nbdb_util_test.o: ../../include/vstring.h
+nbdb_util_test.o: mail_params.h
+nbdb_util_test.o: nbdb_redirect.h
+nbdb_util_test.o: nbdb_util.h
+nbdb_util_test.o: nbdb_util_test.c
 normalize_mailhost_addr.o: ../../include/check_arg.h
 normalize_mailhost_addr.o: ../../include/inet_proto.h
 normalize_mailhost_addr.o: ../../include/msg.h
diff --git a/postfix/src/global/allowed_prefix.c b/postfix/src/global/allowed_prefix.c
new file mode 100644 (file)
index 0000000..178f250
--- /dev/null
@@ -0,0 +1,129 @@
+/*++
+/* NAME
+/*     allowed_prefix 3
+/* SUMMARY
+/*     Match a pathname against a list of allowed parent directories
+/* SYNOPSIS
+/*     #include <allowed_prefix.h>
+/*
+/*     ALLOWED_PREFIX *allowed_prefix_create(const char *prefixes)
+/*
+/*     bool    allowed_prefix_match(
+/*     ALLOWED_PREFIX *tp,
+/*     const char *candidate_path)
+/*
+/*     void    allowed_prefix_free(ALLOWED_PREFIX *tp)
+/* DESCRIPTION
+/*     This module matches an absolute candidate pathname against a
+/*     list of allowed absolute parent directory names. The matching
+/*     is based solely on string comparisons.
+/*
+/*     The matcher will not match relative pathnames, and logs a warning
+/*     if it encounters one in its inputs.
+/*
+/*     allowed_prefix_create() instantiates an allowed parent matcher
+/*     and returns a pointer to the result. The input must be a list
+/*     of directory absolute pathnames separated by comma or whitespace.
+/*
+/*     allowed_prefix_match() matches a candidate absolute pathname
+/*     against an ALLOWED_PREFIX instance.
+/*
+/*     allowed_prefix_free() destroys an ALLOWED_PREFIX instance.
+/* BUGS
+/*     Does not collapse multiple instances of '/' in the middle of a
+/*     pathname.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <htable.h>
+#include <msg.h>
+#include <mymalloc.h>
+#include <split_at.h>
+#include <stringops.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+
+/* decline_request_with - shared nagging code */
+
+static bool decline_request_with(const char *what, const char *path)
+{
+    msg_warn("request to allowlist prefix with %s: '%s'", what, path);
+    return (false);
+}
+
+/* allowed_prefix_create - instantiate an allowed parent matcher */
+
+ALLOWED_PREFIX *allowed_prefix_create(const char *prefixes)
+{
+    ALLOWED_PREFIX *tp;
+    char   *bp, *prefix, *saved_prefixes;
+    size_t  len;
+
+    bp = saved_prefixes = mystrdup(prefixes);
+    tp = argv_alloc(5);
+    while ((prefix = mystrtok(&bp, CHARS_COMMA_SP)) != 0) {
+       if (*prefix != '/') {
+           (void) decline_request_with("relative pathname",prefix);
+           continue;
+       }
+       /* Trim trailing '/'. */
+       for (len = strlen(prefix); len > 0; len--) {
+           if (prefix[len - 1] != '/')
+               break;
+       }
+       prefix[len] = 0;
+       argv_add(tp, prefix, (char *) 0);
+    }
+    myfree(saved_prefixes);
+    return (tp);
+}
+
+/* allowed_prefix_match - match candidate against allowed prefixes */
+
+bool    allowed_prefix_match(ALLOWED_PREFIX *tp, const char *candidate_path)
+{
+    char  **cpp;
+    ssize_t len;
+
+    if (*candidate_path != '/')
+       return (decline_request_with("relative pathname", candidate_path));
+    if (strstr(candidate_path, "/../") != 0)
+       return (decline_request_with("'/../'", candidate_path));
+
+    /*
+     * The number of allowed prefixes will be limited. linear search will be
+     * OK.
+     */
+    for (cpp = tp->argv; *cpp; cpp++) {
+       len = strlen(*cpp);
+       if (strncmp(*cpp, candidate_path, len) == 0
+           && candidate_path[len] == '/')
+           return (true);
+    }
+    return (false);
+}
+
+/* allowed_prefix_free - destroy allowed parent matcher */
+
+void    allowed_prefix_free(ALLOWED_PREFIX *tp)
+{
+    argv_free(tp);
+}
diff --git a/postfix/src/global/allowed_prefix.h b/postfix/src/global/allowed_prefix.h
new file mode 100644 (file)
index 0000000..0ca75c3
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _ALLOWED_PARENT_H_INCLUDED_
+#define _ALLOWED_PARENT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     allowed_prefix 3h
+/* SUMMARY
+/*     Match a pathname against a list of allowed parent directories
+/* SYNOPSIS
+/*     #include <allowed_prefix.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <argv.h>
+
+ /*
+  * External interface.
+  */
+typedef ARGV ALLOWED_PREFIX;
+extern ALLOWED_PREFIX *allowed_prefix_create(const char *);
+extern bool allowed_prefix_match(ALLOWED_PREFIX *, const char *);
+extern void allowed_prefix_free(ALLOWED_PREFIX *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/global/allowed_prefix_test.c b/postfix/src/global/allowed_prefix_test.c
new file mode 100644 (file)
index 0000000..38261f5
--- /dev/null
@@ -0,0 +1,183 @@
+/*++
+/* NAME
+/*     allowed_prefix_test 1t
+/* SUMMARY
+/*     allowed_prefix unit test
+/* SYNOPSIS
+/*     ./allowed_prefix_test
+/* DESCRIPTION
+/*     allowed_prefix_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <stringops.h>
+#include <msg_vstream.h>
+#include <vstring.h>
+#include <vstream.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+
+ /*
+  * Testing library.
+  */
+#include <msg_capture.h>
+
+ /*
+  * Test structure. Some tests may bring their own.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+    const char *candidate;
+    const char *parents;
+    const bool want_match;
+    const char *want_warning;
+} TEST_CASE;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+#define bool_to_text(b) ((b) ? "true" : "false")
+
+/* test_allowed_prefixes - generic test wrapper */
+
+static int test_allowed_prefixes(const TEST_CASE *tp)
+{
+    MSG_CAPTURE *capture = msg_capt_create(100);
+    ALLOWED_PREFIX *ap;
+    bool    got_match;
+    const char *got_warning;
+
+    /* Run the test with captured VSTREAM_ERR stream. */
+    msg_capt_start(capture);
+    ap = allowed_prefix_create(tp->parents);
+    got_match = allowed_prefix_match(ap, tp->candidate);
+    allowed_prefix_free(ap);
+    msg_capt_stop(capture);
+
+    /* Verify the results. */
+    got_warning = msg_capt_expose(capture);
+    if (tp->want_warning == 0 && *got_warning != 0) {
+       msg_warn("got warning ``%s'', want ``null''", got_warning);
+       return (FAIL);
+    }
+    if (tp->want_warning != 0
+       && strstr(got_warning, tp->want_warning) == 0) {
+       msg_warn("got warning ``%s'', want ``%s''",
+                got_warning, tp->want_warning);
+       return (FAIL);
+    }
+    if (tp->want_match != got_match) {
+       msg_warn("got match ``%s'', want ``%s''",
+                bool_to_text(got_match), bool_to_text(tp->want_match));
+       return (FAIL);
+    }
+    msg_capt_free(capture);
+    return (PASS);
+}
+
+ /*
+  * The list of test cases.
+  */
+static const TEST_CASE test_cases[] = {
+    {.label = "all_absolute_non_root_with_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix /etc/other, /foo/bar",
+       .candidate = "/etc/other/foo",
+       .want_match = true,
+    },
+    {.label = "all_absolute_non_root_no_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix /etc/other, /foo/bar",
+       .candidate = "/etc/foo/other",
+       .want_match = false,
+    },
+    {.label = "all_absolute_root_candidate_short_overlap",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix /etc/other, /foo/bar",
+       .candidate = "/",
+       .want_match = false,
+    },
+    {.label = "all_absolute_root_parent_with_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix, /, /foo/bar",
+       .candidate = "/whatever",
+       .want_match = true,
+    },
+    {.label = "one_relative_root_parent_with_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix foo /foo/bar",
+       .candidate = "/foo/bar/whatever",
+       .want_match = true,
+       .want_warning = "to allowlist prefix with relative pathname: 'foo'",
+    },
+    {.label = "absolute_parent_relative_candidate_no_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix /etc/other /foo/bar",
+       .candidate = "bar",
+       .want_match = false,
+       .want_warning = "to allowlist prefix with relative pathname: 'bar'",
+    },
+    {.label = "absolute_parent_dot_dot_candidate_no_match",
+       .action = test_allowed_prefixes,
+       .parents = "/etc/postfix /etc/other /foo/bar",
+       .candidate = "/etc/postfix/../other",
+       .want_match = false,
+       .want_warning = "allowlist prefix with '/../': '/etc/postfix/../other'",
+    },
+    {.label = "trusted_root_directory_allows_all",
+       .action = test_allowed_prefixes,
+       .parents = "/ /foo/bar",
+       .candidate = "/whatever",
+       .want_match = true,
+    },
+
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
index 3cdaa9a661f6781aad223fa37b7097c3dcae521f..6f7a00e50f733ec64678c22452370e6ef887020c 100644 (file)
 /*     bool    var_relay_before_rcpt_checks;
 /*     bool    var_respectful_logging;
 /*     char    *var_known_tcp_ports;
+/*
+/*     char    *var_nbdb_level;
+/*     char    *var_nbdb_service;
+/*     char    *var_nbdb_cust_map;
 /* DESCRIPTION
 /*     This module (actually the associated include file) defines
 /*     the names and defaults of all mail configuration parameters.
 #include <verp_sender.h>
 #include <own_inet_addr.h>
 #include <mail_params.h>
+#include <nbdb_util.h>
 #include <compat_level.h>
 #include <config_known_tcp_ports.h>
 
@@ -396,6 +401,10 @@ char   *var_dnssec_probe;
 bool    var_respectful_logging;
 char   *var_known_tcp_ports;
 
+char   *var_nbdb_level;
+char   *var_nbdb_service;
+char   *var_nbdb_cust_map;
+
 const char null_format_string[1] = "";
 
  /*
@@ -863,6 +872,9 @@ void    mail_params_init()
        VAR_SMTPUTF8_AUTOCLASS, DEF_SMTPUTF8_AUTOCLASS, &var_smtputf8_autoclass, 1, 0,
        VAR_DROP_HDRS, DEF_DROP_HDRS, &var_drop_hdrs, 0, 0,
        VAR_INFO_LOG_ADDR_FORM, DEF_INFO_LOG_ADDR_FORM, &var_info_log_addr_form, 1, 0,
+       VAR_NBDB_LEVEL, DEF_NBDB_LEVEL, &var_nbdb_level, 1, 0,
+       VAR_NBDB_SERVICE, DEF_NBDB_SERVICE, &var_nbdb_service, 0, 0,
+       VAR_NBDB_CUST_MAP, DEF_NBDB_CUST_MAP, &var_nbdb_cust_map, 0, 0,
        0,
     };
     static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
@@ -1102,4 +1114,9 @@ void    mail_params_init()
        msg_fatal("file %s/%s: parameters %s and %s: %s",
                  var_config_dir, MAIN_CONF_FILE,
                  VAR_VERP_DELIMS, VAR_VERP_FILTER, cp);
+
+    /*
+     * Non-Berkeley-DB migration support.
+     */
+    nbdb_util_init(var_nbdb_level);
 }
index e9251363c4e1ee700f084baa7e94eb492a2a6e46..9d68c0f252b0ae66dd4657a49057fc305d2adb55 100644 (file)
@@ -4618,6 +4618,34 @@ extern bool var_smtpd_hide_client_session;
 #define DEF_SMTPD_REJECT_FILTER_MAPS   ""
 extern char *var_smtpd_reject_filter_maps;
 
+ /*
+  * Non-Berkeley-DB migration.
+  */
+#define NBDB_LEV_NAME_NONE     "disable"
+#define NBDB_LEV_NAME_REDIRECT "enable-redirect"
+#define NBDB_LEV_NAME_REINDEX  "enable-reindex"
+
+#define VAR_NBDB_LEVEL         "non_bdb_migration_level"
+#define DEF_NBDB_LEVEL         NBDB_LEV_NAME_NONE
+extern char *var_nbdb_level;
+
+#define VAR_NBDB_CUST_MAP      "non_bdb_custom_mapping"
+#define DEF_NBDB_CUST_MAP      ""
+extern char *var_nbdb_cust_map;
+
+#define VAR_NBDB_SERVICE       "non_bdb_migration_service_name"
+#define DEF_NBDB_SERVICE       "nbdb_reindex"
+extern char *var_nbdb_service;
+
+#define VAR_NBDB_ALLOW_ROOT_PFXS       "non_bdb_migration_allow_root_prefixes"
+#define DEF_NBDB_ALLOW_ROOT_PFXS       "/etc /usr/local/etc"
+extern char *var_nbdb_allow_root_pfxs;
+
+#define VAR_NBDB_ALLOW_USER_PFXS       "non_bdb_migration_allow_user_prefixes"
+#define DEF_NBDB_ALLOW_USER_PFXS       "$" VAR_DATA_DIR " /var/lib/mailman" \
+                                       " /var/lib/mailman3"
+extern char *var_nbdb_allow_user_pfxs;
+
 /* LICENSE
 /* .ad
 /* .fi
index 010bc05bfbb136e19cbe5931de50b016ab7b2393..4c3f33966c1be979a34e71e2cb7f0bfd6af215da 100644 (file)
@@ -319,6 +319,13 @@ extern char *mail_pathname(const char *, const char *);
   */
 #define MAIL_ATTR_SERVER_NAME  "server_name"
 
+ /*
+  * Non-Berkeley-DB migration.
+  */
+#define MAIL_ATTR_PROTO_NBDB_REINDEX   "nbdb_reindex"  /* Re-index protocol */
+#define MAIL_ATTR_NBDB_TYPE            "nbdb_type"     /* maptype */
+#define MAIL_ATTR_NBDB_PATH            "nbdb_path"     /* mapname */
+
 /* LICENSE
 /* .ad
 /* .fi
index 817d31e8eb1a5311052862e56ece4429ed3fdf11..e15a9d4c74b5c8cea6439ff69a2fb09873c166db 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      "20260218"
+#define MAIL_RELEASE_DATE      "20260227"
 #define MAIL_VERSION_NUMBER    "3.12"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/global/nbdb_clnt.c b/postfix/src/global/nbdb_clnt.c
new file mode 100644 (file)
index 0000000..fbbd145
--- /dev/null
@@ -0,0 +1,167 @@
+/*++
+/* NAME
+/*     nbdb_clnt 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration client
+/* SYNOPSIS
+/*     #include <nbdb_clnt.h>
+/*
+/*     void    nbdb_clnt_request(
+/*     const char *type,
+r*     const char *source_path,
+/*     int maxtry,
+/*     int timeout,
+/*     int delay,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     nbdb_clnt_request() asks the reindexing server to index a source
+/*     file using a non-legacy database type. The result is one of
+/*     the following:
+/* .IP NBDB_STAT_OK
+/*     The request was successful.
+/* .IP NBDB_STAT_ERROR
+/*     The request failed. A description of the problem is returned
+/*     in \fBwhy\fR.
+/*
+/*     Arguments:
+/* .IP type
+/*     A legacy database type. The reindexing server will map it
+/*     to a non-legacy type.
+/* .IP path
+/*     The pathname of the database source file (no '.db' suffix).
+/* .IP maxtry
+/*     The number of attempts to make before giving up.
+/* .IP timeout
+/*     The time limit (seconds) to connect, write, or read.
+/*     Specify enough time to index a large table.
+/* .IP delay
+/*     The amount of time (seconds) between retries.
+/* .IP Implicit inputs:
+/*     var_nbdb_service, nbdb_reindex service name.
+/* .IP why
+/*     Storage that is updated with an applicable error description.
+/* SEE ALSO
+/*     nbdb_reindexd(8) reindexing server.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <attr.h>
+#include <connect.h>
+#include <msg.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <mail_proto.h>
+#include <nbdb_clnt.h>
+
+#define STR(x) vstring_str(x)
+
+/* try_one - single request attempt */
+
+static int try_one(const char *service_path, const char *type,
+                    const char *path, int timeout, int delay, VSTRING *why)
+{
+    int     fd;
+    VSTREAM *reindexd_stream = 0;
+    int     status;
+
+#define NBDB_MIGR_CLNT_RETURN(x) do { \
+       if (reindexd_stream) \
+           vstream_fclose(reindexd_stream); \
+       return (x); \
+    } while (0)
+
+    if ((fd = LOCAL_CONNECT(service_path, BLOCKING, timeout)) < 0) {
+       vstring_sprintf(why, "connection to %s service: %m", service_path);
+       NBDB_MIGR_CLNT_RETURN(NBDB_STAT_ERROR);
+    }
+    reindexd_stream = vstream_fdopen(fd, O_RDWR);
+    vstream_control(reindexd_stream,
+                   CA_VSTREAM_CTL_TIMEOUT(timeout),
+                   CA_VSTREAM_CTL_START_DEADLINE,
+                   CA_VSTREAM_CTL_END);
+    /* Enforce the server protocol type. */
+    if (attr_scan(reindexd_stream, ATTR_FLAG_STRICT,
+                 RECV_ATTR_STREQ(MAIL_ATTR_PROTO,
+                                 MAIL_ATTR_PROTO_NBDB_REINDEX),
+                 ATTR_TYPE_END) != 0) {
+       vstring_sprintf(why, "error receiving %s service initial response",
+                       service_path);
+       NBDB_MIGR_CLNT_RETURN(NBDB_STAT_ERROR);
+    }
+    /* Send the reindexing request. */
+    attr_print(reindexd_stream, ATTR_FLAG_NONE,
+              SEND_ATTR_STR(MAIL_ATTR_NBDB_TYPE, type),
+              SEND_ATTR_STR(MAIL_ATTR_NBDB_PATH, path),
+              ATTR_TYPE_END);
+    /* Do not flush the stream yet (would clobber errno). */
+    if (vstream_ferror(reindexd_stream) != 0) {
+       vstring_sprintf(why, "error sending request to %s service: %m",
+                       service_path);
+       NBDB_MIGR_CLNT_RETURN(NBDB_STAT_ERROR);
+    }
+    /* Receive the reindexing status. */
+    if (attr_scan(reindexd_stream, ATTR_FLAG_STRICT,
+                 RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
+                 RECV_ATTR_STR(MAIL_ATTR_WHY, why),
+                 ATTR_TYPE_END) != 2) {
+       vstring_sprintf(why, "error receiving response from %s service: %m",
+                       service_path);
+       NBDB_MIGR_CLNT_RETURN(NBDB_STAT_ERROR);
+    }
+    NBDB_MIGR_CLNT_RETURN(status);
+}
+
+/* nbdb_clnt_request - send a request and don't hang forever */
+
+int     nbdb_clnt_request(const char *type, const char *path,
+                                 int max_try, int timeout, int delay,
+                                 VSTRING *why)
+{
+    VSTRING *service_path = vstring_alloc(100);
+    int     status;
+    int     count;
+
+    /*
+     * A custom client endpoint that tries only a few times and that may be
+     * called by:
+     * 
+     * - A daemon process. This should keep running if the reindexing service is
+     * unavailable, and needs to specify a relative service pathname in case
+     * it is chrooted.
+     * 
+     * - A command-line process. This almost always needs to specify an absolute
+     * pathname. This usage is limited to the super-user.
+     */
+    vstring_sprintf(service_path, "%s/%s", MAIL_CLASS_PRIVATE,
+                   var_nbdb_service);
+    if (access(STR(service_path), F_OK) != 0)
+       vstring_sprintf(service_path, "%s/%s/%s", var_queue_dir,
+                       MAIL_CLASS_PRIVATE, var_nbdb_service);
+    for (count = 0; count < max_try; count++) {
+       status = try_one(STR(service_path), type, path, timeout, delay, why);
+       if (status == NBDB_STAT_OK)
+           break;
+       if (count < max_try - 1)
+           sleep(delay);
+    }
+    vstring_free(service_path);
+    return (status);
+}
diff --git a/postfix/src/global/nbdb_clnt.h b/postfix/src/global/nbdb_clnt.h
new file mode 100644 (file)
index 0000000..a4670b0
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _NBDB_CLNT_H_INCLUDED_
+#define _NBDB_CLNT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_clnt 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration client
+/* SYNOPSIS
+/*     #include <nbdb_clnt.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <nbdb_util.h>
+
+extern int nbdb_clnt_request(const char *, const char *, int, int, int, VSTRING *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/global/nbdb_redirect.c b/postfix/src/global/nbdb_redirect.c
new file mode 100644 (file)
index 0000000..9d3495d
--- /dev/null
@@ -0,0 +1,310 @@
+/*++
+/* NAME
+/*     nbdb_redirect 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration support
+/* SYNOPSIS
+/*     #include <nbdb_redirect.h>
+/*
+/*     void    nbdb_rdr_init(int level)
+/* DESCRIPTION
+/*     This module contains code that may be called by command-line
+/*     tools and by clients of the non-Berkeley-DB migration service.
+/*
+/*     nbdb_rdr_init() destructively registers surrogate dict_open()
+/*     and mkmap_open() handlers for legacy types 'hash' and 'btree',
+/*     that map these type names to $var_db_type and $var_cache_db_type,
+/*     respectively, and that may send requests to a reindexing
+/*     server. The mapping from legacy to non-legacy type names is
+/*     implemented by nbdb_map_leg_type().
+/* SEE ALSO
+/*     nbdb_reindexd(8), helper daemon to reindex legacy tables
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict_cdb.h>
+#include <dict_db.h>
+#include <dict.h>
+#include <dict_lmdb.h>
+#include <mkmap.h>
+#include <msg.h>
+#include <mymalloc.h>
+#include <name_code.h>
+#include <stringops.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_clnt.h>
+#include <nbdb_redirect.h>
+#include <nbdb_util.h>
+
+ /*
+  * SLMs.
+  */
+#define STR(x) vstring_str(x)
+
+ /*
+  * Application-specific.
+  */
+
+static VSTRING *why = 0;
+
+/* call_nbdb_reindexd - wrapper for nbdb_reindexd client */
+
+static DICT *call_nbdb_reindexd(const char *leg_type, const char *name,
+                                       int open_flags, int dict_flags)
+{
+    DICT   *surrogate;
+    VSTRING *why;
+    int     nbdb_stat;
+
+    /*
+     * TODO(wietse) make this go away.
+     */
+#define MAX_TRY 2
+#define TIMEOUT 30
+#define DELAY 1
+
+
+    why = vstring_alloc(100);
+    switch (nbdb_stat = nbdb_clnt_request(leg_type, name, MAX_TRY, TIMEOUT,
+                                         DELAY, why)) {
+    case NBDB_STAT_OK:
+       if (msg_verbose)
+           msg_info("%s: delegated '%s:%s'", __func__, leg_type, name);
+       surrogate = 0;
+       break;
+    case NBDB_STAT_ERROR:
+       msg_warn("Non-Berkeley-DB migration error: %s", STR(why));
+       surrogate =
+           dict_surrogate(leg_type, name, open_flags, dict_flags,
+                          "Non-Berkeley-DB migration error: %s", STR(why));
+       break;
+    default:
+       msg_warn("Non-Berkeley-DB migration error: malformed "
+                "bad reindexing status: %d", nbdb_stat);
+       surrogate = dict_surrogate(leg_type, name, open_flags, dict_flags,
+                                  "Non-Berkeley-DB migration error: "
+                                  "bad reindexing server status: %d",
+                                  nbdb_stat);
+    }
+    vstring_free(why);
+    return (surrogate);
+}
+
+ /*
+  * Code to redirect dict_open() requests to non-legacy database types. This
+  * code may be called from daemon processes, and therefore all errors are
+  * handled by creating a surrogate database instance that returns an error
+  * status for each request, and that logs why.
+  * 
+  * Program flow:
+  * 
+  * - A client program calls dict_open().
+  * 
+  * - dict_open() looks up "our" DICT_OPEN_INFO with dict_fn and mkmap_fn
+  * members that resolve to functions in this code module.
+  * 
+  * - dict_open() calls our DICT_OPEN_INFO.dict_fn() function which calls the
+  * dict_xxx_open() method of the non-legacy type. That function returns a
+  * DICT object for the non-legacy implementation (typically, cdb or lmdb).
+  */
+
+/* nbdb_dict_open - redirect dict_open() to non-Berkeley-DB type */
+
+static DICT *nbdb_dict_open(const char *leg_type, const char *name,
+                                   int open_flags, int dict_flags)
+{
+    const DICT_OPEN_INFO *open_info;
+    const char *non_leg_type;
+    char   *non_leg_index_path;
+    const char *non_leg_suffix;
+    int     stat_res, saved_errno;
+    DICT   *surrogate;
+    struct stat st;
+
+    if (why == 0)
+       why = vstring_alloc(100);
+
+    /*
+     * Look up the type mapping, which may depend on the database name.
+     */
+    non_leg_type = nbdb_map_leg_type(leg_type, name, &open_info, why);
+    if (non_leg_type == 0) {
+       msg_warn("non-Berkeley-DB type mapping lookup error for '%s:%s': %s",
+                leg_type, name, STR(why));
+       return (dict_surrogate(leg_type, name, open_flags, dict_flags,
+                              "Berkeley DB type mapping lookup error for "
+                              "'%s:%s': %s", leg_type, name, STR(why)));
+    }
+
+    /*
+     * Do not delegate dict_open() requests to create an indexed file (this
+     * is typical for daemon-maintained caches). If a process does not have
+     * permissions to create the indexed file, then the nbdb reindexing
+     * service must not create it for them.
+     */
+    if ((open_flags & O_CREAT) == 0
+       && nbdb_level >= NBDB_LEV_CODE_REINDEX) {
+
+       /*
+        * If the non-legacy indexed file does not already exist, call the
+        * nbdb reindexing service to create a non-legacy indexed file, and
+        * then access the indexed file directly. The service will enforce a
+        * safety policy based on the ownership of the legacy indexed file.
+        */
+       if ((non_leg_suffix = nbdb_find_non_leg_suffix(non_leg_type)) == 0) {
+           msg_warn("non-Berkeley-DB mapped type '%s' has no known pathname "
+                    "suffix", non_leg_type);
+           return (dict_surrogate(leg_type, name, open_flags, dict_flags,
+                                  "non-Berkeley-DB mapped type '%s' has no "
+                                  "known pathname suffix", non_leg_type));
+       }
+       non_leg_index_path = concatenate(name, non_leg_suffix, (char *) 0);
+       stat_res = stat (non_leg_index_path, &st);
+
+       saved_errno = errno;
+       myfree(non_leg_index_path);
+       if (stat_res < 0 && saved_errno == ENOENT
+           && (surrogate = call_nbdb_reindexd(leg_type, name, open_flags,
+                                              dict_flags)) != 0)
+           return (surrogate);
+    }
+    return (open_info->dict_fn(name, open_flags, dict_flags));
+}
+
+/* nbdb_dict_hash_open - map hash legacy type to non-legacy type */
+
+static DICT *nbdb_dict_hash_open(const char *name, int open_flags, int dict_flags)
+{
+    return (nbdb_dict_open(DICT_TYPE_HASH, name, open_flags, dict_flags));
+}
+
+/* nbdb_dict_btree_open - map btree legacy type to non-legacy type */
+
+static DICT *nbdb_dict_btree_open(const char *name, int open_flags, int dict_flags)
+{
+    return (nbdb_dict_open(DICT_TYPE_BTREE, name, open_flags, dict_flags));
+}
+
+ /*
+  * Code that is used by postmap and postalias bulk create and incremental
+  * mode, to redirect requests with a legacy type name to a non-legacy type.
+  * These requests are always executed without delegation to a privileged
+  * daemon. If the user does not have permission to create or update the
+  * table, then the request is invalid. As this code is called from
+  * command-line tools, all errors are fatal.
+  * 
+  * Limitation: because this code does not call the reindexing service, this
+  * will not work for postmap and postalias incremental updates ("postmap -i"
+  * etc.) when a database has not yet been reindexed. Fortunately, Postfix
+  * itself does not make incremental non-cache updates.
+  * 
+  * Program flow:
+  * 
+  * - The postmap or postalias commands call mkmap_open().
+  * 
+  * - mkmap_open() looks up "our" DICT_OPEN_INFO with dict_fn and mkmap_fn
+  * members that resolve to functions in this code module.
+  * 
+  * - mkmap_open() calls our DICT_OPEN_INFO.mkmap_fn() function which calls the
+  * mkmap_xxx_open() method of the non-legacy type. That function returns a
+  * MKMAP object with function pointers for the non-legacy implementation
+  * (typically, cdb or lmdb).
+  * 
+  * - mkmap_open() then calls MKMAP.open() (in bulk and incremental mode), and
+  * calls other MKMAP function members as appropriate, for example to manage
+  * a lock.
+  */
+
+/* nbdb_mkmap_open - redirect legacy type to non-legacy */
+
+static MKMAP *nbdb_mkmap_open(const char *leg_type, const char *name)
+{
+    const DICT_OPEN_INFO *open_info;
+    const char *non_leg_type;
+
+    if (why == 0)
+       why = vstring_alloc(100);
+
+    /*
+     * Look up the legacy type to non-legacy type mapping, which may depend
+     * on the database name. Errors are fatal.
+     */
+    non_leg_type = nbdb_map_leg_type(leg_type, name, &open_info, why);
+    if (non_leg_type == 0)
+       msg_fatal("non_bdb migration mapping lookup error for '%s': %s",
+                 leg_type, STR(why));
+    if (open_info->mkmap_fn == 0)
+       msg_fatal("no 'map create' support for non_bdb mapped type: %s",
+                 non_leg_type);
+    return (open_info->mkmap_fn(name));
+}
+
+/* nbdb_mkmap_hash_open - map hash legacy type to non-legacy type */
+
+static MKMAP *nbdb_mkmap_hash_open(const char *path)
+{
+    return (nbdb_mkmap_open(DICT_TYPE_HASH, path));
+}
+
+/* nbdb_mkmap_btree_open - map btree legacy type to non-legacy type */
+
+static MKMAP *nbdb_mkmap_btree_open(const char *path)
+{
+    return (nbdb_mkmap_open(DICT_TYPE_BTREE, path));
+}
+
+ /*
+  * Surrogate hash: and btree: support for dict_open(). These handlers will
+  * typically redirect hash: requests to the default database type (for
+  * mostly-constant tables) and will redirect btree: requests to the default
+  * cache type (mostly for daemon cache).
+  */
+static const DICT_OPEN_INFO nbdb_info[] = {
+    DICT_TYPE_HASH, nbdb_dict_hash_open, nbdb_mkmap_hash_open,
+    DICT_TYPE_BTREE, nbdb_dict_btree_open, nbdb_mkmap_btree_open,
+    0,
+};
+
+/* nbdb_rdr_init - redirect legacy open() requests to nbdb handlers */
+
+void    nbdb_rdr_init(void)
+{
+    const DICT_OPEN_INFO *info;
+
+    /*
+     * Un-register each legacy type handler. This is needed if the system was
+     * built without -DNO_DB). Then, register the forward-compatibility
+     * handlers.
+     */
+    if (nbdb_level >= NBDB_LEV_CODE_REDIRECT) {
+       for (info = nbdb_info; info->type; info++) {
+           if (dict_open_lookup(info->type) != 0)
+               dict_open_unregister(info->type);
+           if (msg_verbose)
+               msg_info("%s: installing custom handlers for '%s'",
+                        __func__, info->type);
+           dict_open_register(info);
+       }
+    }
+}
diff --git a/postfix/src/global/nbdb_redirect.h b/postfix/src/global/nbdb_redirect.h
new file mode 100644 (file)
index 0000000..2694326
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _NBDB_REDIRECT_H_INCLUDED_
+#define _NBDB_REDIRECT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_redirect 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration support
+/* SYNOPSIS
+/*     #include <nbdb_redirect.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * External API.
+  */
+extern void nbdb_rdr_init(void);
+
+#define NBDB_LEGACY_SUFFIX     ".db"
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/global/nbdb_redirect_test.c b/postfix/src/global/nbdb_redirect_test.c
new file mode 100644 (file)
index 0000000..ae9dc62
--- /dev/null
@@ -0,0 +1,391 @@
+/*++
+/* NAME
+/*      nbdb_redirect_test 1t
+/* SUMMARY
+/*      nbdb_redirect unit test
+/* SYNOPSIS
+/*      ./nbdb_redirect_test
+/* DESCRIPTION
+/*      nbdb_redirect_test runs and logs each configured test, reports if
+/*      a test is a PASS or FAIL, and returns an exit status of zero if
+/*      all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*      The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*      Wietse Venema
+/*      porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict_cdb.h>
+#include <dict_db.h>
+#include <dict.h>
+#include <dict_inline.h>
+#include <dict_lmdb.h>
+#include <mkmap.h>
+#include <msg.h>
+#include <msg_vstream.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <vstream.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_util.h>
+#include <nbdb_redirect.h>
+
+ /*
+  * Testing library.
+  */
+#include <msg_capture.h>
+#include <mock_dict.h>
+
+#define PASS    (0)
+#define FAIL    (1)
+
+#define STR(x) vstring_str(x)
+
+char   *var_nbdb_cust_map = DEF_NBDB_CUST_MAP;
+
+ /*
+  * Tests that a dict_open() request for 'hash' or 'btree' will redirect to
+  * $default_database_type or $default_cache_db_type. These use mock cdb and
+  * lmdb clients that will respond with their type when queried for "whoami".
+  * 
+  * The redirect unit tests do not cover the 'bulk create' code paths; those
+  * will be tested with postmap/postalias 'whole program' tests.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+} TEST_CASE;
+
+static void setup_common_mock_open_info(void)
+{
+    nbdb_level = NBDB_LEV_CODE_REDIRECT;
+
+    nbdb_reindexing_lockout = 0;
+    setup_mock_cdb("{{whoami = mock cdb}}");
+    setup_mock_lmdb("{{whoami = mock lmdb}}");
+    nbdb_rdr_init();
+}
+
+static int redirects_dict_open_hash_to_def_db_type(const TEST_CASE *tp)
+{
+    const char *got_whoami;
+    DICT   *dict;
+    int     status = PASS;
+    const char *want_whoami;
+
+    /*
+     * Setup. Use the mapping hash->cdb.
+     */
+    setup_common_mock_open_info();
+    var_db_type = "cdb";
+
+    /*
+     * Verify that 'hash' redirects to $default_database_type ('cdb').
+     */
+    want_whoami = "mock cdb";
+    dict = dict_open3(DICT_TYPE_HASH, "ignored", O_RDONLY, 0);
+    if ((got_whoami = dict_get(dict, "whoami")) == 0) {
+       msg_warn("'whoami' query returned 'not found'");
+       status = FAIL;
+    } else if (strstr(got_whoami, want_whoami) == 0) {
+       msg_warn("unexpected result; got: '%s', want: '%s'",
+                got_whoami, want_whoami);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    return (status);
+}
+
+static int redirects_dict_open_btree_to_def_cache_db_type(const TEST_CASE *tp)
+{
+    const char *got_whoami;
+    DICT   *dict;
+    int     status = PASS;
+    const char *want_whoami;
+
+    /*
+     * Setup. Use the mapping btree->lmdb.
+     */
+    setup_common_mock_open_info();
+    var_cache_db_type = "lmdb";
+
+    /*
+     * Verify that 'btree' redirects to $default_cache_db_type ('lmdb').
+     */
+    want_whoami = "mock lmdb";
+    dict = dict_open3(DICT_TYPE_BTREE, "ignored", O_RDONLY, 0);
+    if ((got_whoami = dict_get(dict, "whoami")) == 0) {
+       msg_warn("'whoami' query returned 'not found'");
+       status = FAIL;
+    } else if (strstr(got_whoami, "mock lmdb") == 0) {
+       msg_warn("unexpected result; got: '%s', want: '%s'",
+                got_whoami, want_whoami);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    return (status);
+}
+
+static int redirects_mkmap_open_hash_to_def_db_type(const TEST_CASE *tp)
+{
+    const char *got_whoami;
+    MKMAP  *mkmap;
+    int     status = PASS;
+    const char *want_whoami;
+
+    /*
+     * Setup. Use the mapping hash->cdb.
+     */
+    setup_common_mock_open_info();
+    var_db_type = "cdb";
+
+    /*
+     * Verify that mkmap_open("hash"...) redirects to $default_database_type
+     * ('cdb').
+     */
+    want_whoami = "mock cdb";
+    mkmap = mkmap_open(DICT_TYPE_HASH, "ignored", O_RDONLY, 0);
+    if ((got_whoami = dict_get(mkmap->dict, "whoami")) == 0) {
+       msg_warn("'whoami' query returned 'not found'");
+       status = FAIL;
+    } else if (strstr(got_whoami, want_whoami) == 0) {
+       msg_warn("unexpected result; got: '%s', want: '%s'",
+                got_whoami, want_whoami);
+       status = FAIL;
+    }
+    mkmap_close(mkmap);
+
+    return (status);
+}
+
+static int redirects_mkmap_open_btree_to_def_cache_db_type(const TEST_CASE *tp)
+{
+    const char *got_whoami;
+    MKMAP  *mkmap;
+    int     status = PASS;
+    const char *want_whoami;
+
+    /*
+     * Setup. Use the mapping btree->lmdb.
+     */
+    setup_common_mock_open_info();
+    var_cache_db_type = "lmdb";
+
+    /*
+     * Verify that mkmap_open("btree"...) redirects to $default_cache_db_type
+     * ('lmdb').
+     */
+    want_whoami = "mock lmdb";
+    mkmap = mkmap_open(DICT_TYPE_BTREE, "ignored", O_RDONLY, 0);
+    if ((got_whoami = dict_get(mkmap->dict, "whoami")) == 0) {
+       msg_warn("'whoami' query returned 'not found'");
+       status = FAIL;
+    } else if (strstr(got_whoami, want_whoami) == 0) {
+       msg_warn("unexpected result; got: '%s', want: '%s'",
+                got_whoami, want_whoami);
+       status = FAIL;
+    }
+    mkmap_close(mkmap);
+
+    return (status);
+}
+
+static int nbdb_dict_xxx_open_handles_mapping_error(const TEST_CASE *tp)
+{
+    DICT   *dict;
+    int     status = PASS;
+    MSG_CAPTURE *capture;
+    const char *got_warning;
+    const char *want_warning;
+
+    /*
+     * Setup.
+     */
+    nbdb_util_init("enable-reindex");
+    dict_allow_surrogate = 1;
+    capture = msg_capt_create(100);
+
+    /*
+     * Run the test for nbdb_dict_hash_open().
+     */
+    var_db_type = "foo";
+
+    msg_capt_start(capture);
+    dict = dict_open3(DICT_TYPE_HASH, "ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+
+    got_warning = msg_capt_expose(capture);
+    want_warning = "unsupported database type: 'foo'";
+
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("unexpected hash redirect; got: non-surrogate "
+                "dictionary, want: surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning, want_warning) == 0) {
+       msg_warn("got unexpected warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    /*
+     * Run the test for nbdb_dict_btree_open().
+     */
+    var_cache_db_type = "bar";
+
+    msg_capt_start(capture);
+    dict = dict_open3(DICT_TYPE_BTREE, "ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+
+    got_warning = msg_capt_expose(capture);
+    want_warning = "unsupported database type: 'bar'";
+
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("unexpected btree redirect; got: non-surrogate "
+                "dictionary, want: surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning, want_warning) == 0) {
+       msg_warn("got unexpected warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    msg_capt_free(capture);
+    return (status);
+}
+
+static int nbdb_dict_xxx_open_handles_no_suffix_error(const TEST_CASE *tp)
+{
+    DICT   *dict;
+    int     status = PASS;
+    MSG_CAPTURE *capture;
+    const char *got_warning;
+    const char *want_warning;
+
+    /*
+     * Setup.
+     */
+    nbdb_util_init("enable-reindex");
+    dict_allow_surrogate = 1;
+    capture = msg_capt_create(100);
+
+    /*
+     * Run the test for nbdb_dict_hash_open().
+     */
+    var_db_type = "static";
+
+    msg_capt_start(capture);
+    dict = dict_open3(DICT_TYPE_HASH, "ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+
+    got_warning = msg_capt_expose(capture);
+    want_warning = "'static' has no known pathname suffix";
+
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("unexpected hash redirect; got: non-surrogate "
+                "dictionary, want: surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning, want_warning) == 0) {
+       msg_warn("got unexpected warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    /*
+     * Run the test for nbdb_dict_btree_open().
+     */
+    var_cache_db_type = "static";
+
+    msg_capt_start(capture);
+    dict = dict_open3(DICT_TYPE_BTREE, "ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+
+    got_warning = msg_capt_expose(capture);
+    want_warning = "'static' has no known pathname suffix";
+
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("unexpected btree redirect; got: non-surrogate "
+                "dictionary, want: surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning, want_warning) == 0) {
+       msg_warn("got unexpected warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+
+    msg_capt_free(capture);
+    return (status);
+}
+
+ /*
+  * TODO(wietse) also verify the msg_fatal() calls. That requires conversion
+  * to PTEST.
+  */
+static const TEST_CASE test_cases[] = {
+    {.label = "redirects_dict_open_hash_to_def_db_type",
+       redirects_dict_open_hash_to_def_db_type,
+    },
+    {.label = "redirects_dict_open_btree_to_def_cache_db_type",
+       redirects_dict_open_btree_to_def_cache_db_type,
+    },
+    {.label = "redirects_mkmap_open_hash_to_def_db_type",
+       redirects_mkmap_open_hash_to_def_db_type,
+    },
+    {.label = "redirects_mkmap_open_btree_to_def_cache_db_type",
+       redirects_mkmap_open_btree_to_def_cache_db_type,
+    },
+    {.label = "nbdb_dict_xxx_open_handles_mapping_error",
+       nbdb_dict_xxx_open_handles_mapping_error,
+    },
+    {.label = "nbdb_dict_xxx_open_handles_no_suffix_error",
+       nbdb_dict_xxx_open_handles_no_suffix_error,
+    },
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/global/nbdb_surrogate.c b/postfix/src/global/nbdb_surrogate.c
new file mode 100644 (file)
index 0000000..77c9451
--- /dev/null
@@ -0,0 +1,113 @@
+/*++
+/* NAME
+/*     nbdb_surrogate 3
+/* SUMMARY
+/*     surrogate Berkeley DB handlers that log hints
+/* SYNOPSIS
+/*     #include <nbdb_surrogate.h>
+/*
+/*     void    nbdb_surr_init()
+/* DESCRIPTION
+/*     nbdb_surr_init() installs dict_open() and mkmap_open() surrogates
+/*     for Berkeley DB types 'hash' and 'btree. These handlers log that
+/*     Berkeley DB support is unavailable and provide a link to the
+/*     NON_BERKELEYDB_README web page. The dict_open() handlers return
+/*     a pointer to DICT instance that fails all requests, and the
+/*     mkmap_open() handlers terminate the process.
+/*
+/*     This code does not require prior initialization with
+/*     mail_conf_read() or mail_params_init().
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+#include <dict_db.h>
+#include <mkmap.h>
+#include <msg.h>
+
+ /*
+  * Global library.
+  */
+#include <nbdb_surrogate.h>
+
+ /*
+  * Inform the user that Berkeley DB is gone, and offer alternatives.
+  */
+static const char boilerplate[] =
+"Berkeley DB support for '%s:%s' is not available for this OS distribution; "
+"see https://www.postfix.org/NON_BERKELEYDB_README.html for alternatives";
+
+/* surrogate dict_{hash,btree}_open() */
+
+static DICT *surrogate_dict_bdb_open(const char *type, const char *name,
+                                            int open_flags, int dict_flags)
+{
+    return (dict_surrogate(type, name, open_flags, dict_flags, boilerplate,
+                          type, name));
+}
+
+static DICT *surrogate_dict_hash_open(const char *name, int open_flags,
+                                             int dict_flags)
+{
+    return (surrogate_dict_bdb_open(DICT_TYPE_HASH, name, open_flags,
+                                   dict_flags));
+}
+
+static DICT *surrogate_dict_btree_open(const char *name, int open_flags,
+                                              int dict_flags)
+{
+    return (surrogate_dict_bdb_open(DICT_TYPE_BTREE, name, open_flags,
+                                   dict_flags));
+}
+
+/* surrogates for mkmap_{hash,btree}_open() */
+
+static MKMAP *surrogate_mkmap_bdb_open(const char *type, const char *path)
+{
+    msg_fatal(boilerplate, type, path);
+}
+
+static MKMAP *surrogate_mkmap_hash_open(const char *path)
+{
+    return (surrogate_mkmap_bdb_open(DICT_TYPE_HASH, path));
+}
+
+static MKMAP *surrogate_mkmap_btree_open(const char *path)
+{
+    return (surrogate_mkmap_bdb_open(DICT_TYPE_BTREE, path));
+}
+
+static const DICT_OPEN_INFO surrogate_bdb_info[] = {
+    {DICT_TYPE_HASH, surrogate_dict_hash_open, surrogate_mkmap_hash_open},
+    {DICT_TYPE_BTREE, surrogate_dict_btree_open, surrogate_mkmap_btree_open},
+};
+
+/* nbdb_surr_init - register the above surrogates */
+
+void    nbdb_surr_init(void)
+{
+    const DICT_OPEN_INFO *open_info;
+
+    for (open_info = surrogate_bdb_info; open_info->type; open_info++) {
+       if (dict_open_lookup(open_info->type) != 0)
+           dict_open_unregister(open_info->type);
+       if (msg_verbose)
+           msg_info("%s: installing custom hanndlers for '%s'",
+                    __func__, open_info->type);
+       dict_open_register(open_info);
+    }
+}
diff --git a/postfix/src/global/nbdb_surrogate.h b/postfix/src/global/nbdb_surrogate.h
new file mode 100644 (file)
index 0000000..9c75f37
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _NBDB_SURROGATE_H_
+#define _NBDB_SURROGATE_H_
+
+/*++
+/* NAME
+/*     nbdb_surrogate 3h
+/* SUMMARY
+/*     surrogate Berkeley DB handlers that log hints
+/* SYNOPSIS
+/*     #include <nbdb_surrogate.h>
+/* DESCRIPTION
+* .nf
+
+ /*
+  * External interface.
+  */
+extern void nbdb_surr_init(void);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/global/nbdb_surrogate_test.c b/postfix/src/global/nbdb_surrogate_test.c
new file mode 100644 (file)
index 0000000..f110068
--- /dev/null
@@ -0,0 +1,172 @@
+/*++
+/* NAME
+/*      nbdb_surrogate_test 1t
+/* SUMMARY
+/*      nbdb_surrogate unit test
+/* SYNOPSIS
+/*      ./nbdb_surrogate_test
+/* DESCRIPTION
+/*      nbdb_surrogate_test runs and logs each configured test, reports if
+/*      a test is a PASS or FAIL, and returns an exit status of zero if
+/*      all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*      The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*      Wietse Venema
+/*      porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict_db.h>
+#include <dict.h>
+#include <mkmap.h>
+#include <msg.h>
+#include <msg_vstream.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <vstream.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_util.h>
+#include <nbdb_surrogate.h>
+
+ /*
+  * Testing library.
+  */
+#include <msg_capture.h>
+
+ /*
+  * Application-specific.
+  */
+int     dict_allow_surrogate = 1;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+#define STR(x) vstring_str(x)
+
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+} TEST_CASE;
+
+static int redirects_dict_open_hash_to_surrogate(const TEST_CASE *tp)
+{
+    MSG_CAPTURE *capture = msg_capt_create(100);
+    DICT   *dict;
+    int     status = PASS;
+    const char *want_warning = "support for 'hash:ignored' is not available";
+    const char *got_warning;
+
+    /*
+     * Setup.
+     */
+    nbdb_surr_init();
+
+    /*
+     * Test and verify.
+     */
+    msg_capt_start(capture);
+    dict = dict_open("hash:ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("dict_open(\"hash:...\", ...) did not return surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning = msg_capt_expose(capture),
+                     want_warning) == 0) {
+       msg_warn("got warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+    msg_capt_free(capture);
+
+    return (status);
+}
+
+static int redirects_dict_open_btree_to_surrogate(const TEST_CASE *tp)
+{
+    MSG_CAPTURE *capture = msg_capt_create(100);
+    DICT   *dict;
+    int     status = PASS;
+    const char *want_warning = "support for 'btree:ignored' is not available";
+    const char *got_warning;
+
+    /*
+     * Setup.
+     */
+    nbdb_surr_init();
+
+    /*
+     * Test and verify.
+     */
+    msg_capt_start(capture);
+    dict = dict_open("btree:ignored", O_RDONLY, 0);
+    msg_capt_stop(capture);
+    if ((dict->flags & DICT_FLAG_SURROGATE) == 0) {
+       msg_warn("dict_open(\"btree:...\", ...) did not return surrogate");
+       status = FAIL;
+    } else if (strstr(got_warning = msg_capt_expose(capture),
+                     want_warning) == 0) {
+       msg_warn("got warning: '%s', want: '%s'",
+                got_warning, want_warning);
+       status = FAIL;
+    }
+    dict_close(dict);
+    msg_capt_free(capture);
+
+    return (status);
+}
+
+ /*
+  * TODO(wietse) also verify the msg_fatal() calls. That requires conversion
+  * to PTEST.
+  */
+static const TEST_CASE test_cases[] = {
+    {.label = "redirects_dict_open_hash_to_surrogate",
+       redirects_dict_open_hash_to_surrogate,
+    },
+    {.label = "redirects_dict_open_btree_to_surrogate",
+       redirects_dict_open_btree_to_surrogate,
+    },
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/global/nbdb_util.c b/postfix/src/global/nbdb_util.c
new file mode 100644 (file)
index 0000000..6e194f8
--- /dev/null
@@ -0,0 +1,293 @@
+/*++
+/* NAME
+/*     nbdb_util 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration support
+/* SYNOPSIS
+/*     #include <nbdb_util.h>
+/*
+/*     int     nbdb_level;
+/*     bool    nbdb_reindexing_lockout;
+/*
+/*     void    nbdb_util_init(const char *level_name)
+/*
+/*     int     nbdb_is_legacy_type(const char *type)
+/*
+/*     const char *nbdb_find_non_leg_suffix(const char *non_leg_type)
+/*
+/*     const char *nbdb_map_leg_type(
+/*     const char *leg_type,
+/*     const char *name,
+/*     const DICT_OPEN_INFO **open_info,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     This module contains utilities that may be called by clients
+/*     and servers of the non-Berkeley-DB migration service.
+/*
+/*     nbdb_is_legacy_type() returns true if the specified database
+/*     type is a Berkeley DB type ('hash' or 'btree').
+/*
+/*     nbdb_find_non_leg_suffix() returns the database pathname suffix
+/*     for the specified non-legacy database, or null if no suffix
+/*     was found.
+/*
+/*     nbdb_map_leg_type() implements the mapping from expected legacy
+/*     type names to expected non-legacy type names. This supports
+/*     a user-defined mapping override, indexed by legacy type or legacy
+/*     type:name. nbdb_map_leg_type() returns null in case of error:
+/*     a table lookup error, an unexpected input type, or an unexpected
+/*     output type.
+/* .IP leg_type
+/*     A legacy database type to be mapped to a non-legacy type.
+/* .IP name
+/*     A database name.
+/* .IP open_info
+/*     Null pointer, or pointer to DICT_OPEN_INFO pointer with function
+/*     pointers to open the non-legacy database.
+/* .IP why
+/*     Storage for descriptive text in case of error.
+/* .PP
+/*
+/*     nbdb_util_init() converts the non-Berkeley-DB migration level
+/*     from text to internal form, and updates the nbdb_level global
+/*     variable:
+/* .IP "redirect (internal form: NBDB_LEV_CODE_REDIRECT)"
+/*     Enables the mapping from legacy Berkeley DB types to preferred
+/*     types.
+/* .IP "reindex (internal form: NBDB_LEV_CODE_REINDEX)"
+/*     As "redirect", but also makes requests to a reindexing service
+/*     if the non-legacy indexed file does not exist.
+/*     Exception: calling a reindexing service will remain disabled
+/*     if the process sets nbdb_reindexing_lockout to 'true'.
+/* SEE ALSO
+/*     nbdb_reindexd(8), helper daemon to reindex legacy tables
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <string.h>
+#include <errno.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict_cdb.h>
+#include <dict_db.h>
+#include <dict.h>
+#include <dict_lmdb.h>
+#include <mkmap.h>
+#include <msg.h>
+#include <mymalloc.h>
+#include <name_code.h>
+#include <split_at.h>
+#include <stringops.h>
+#include <vstring.h>
+#include <stringops.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_util.h>
+#include <nbdb_redirect.h>
+#include <nbdb_surrogate.h>
+
+ /*
+  * Application-specific.
+  */
+int     nbdb_level;
+bool    nbdb_reindexing_lockout;
+
+ /*
+  * Mapping from legacy type to non-legacy.
+  */
+static DICT *nbdb_cust_map;
+
+ /*
+  * Mapping from non-legacy type to pathname suffix. This should be provided
+  * by individual table implementations, but that would require changes to
+  * the dict/mkmap plugin API.
+  */
+typedef struct {
+    const char *type;
+    const char *suffix;
+} NBDB_PATH_SUFFIX;
+
+static const NBDB_PATH_SUFFIX nbdb_path_suffixes[] = {
+    DICT_TYPE_CDB, ".cdb",
+    DICT_TYPE_LMDB, ".lmdb",
+    0, 0,                              /* Default case */
+};
+
+ /*
+  * SLMs.
+  */
+#define STR(x) vstring_str(x)
+
+/* nbdb_map_leg_type - map legacy type to non-legacy type, null means error */
+
+const char *nbdb_map_leg_type(const char *leg_type, const char *name,
+                                     const DICT_OPEN_INFO **open_info,
+                                     VSTRING *why)
+{
+    static VSTRING *type_name = 0;
+    const char *non_leg_type = 0;
+    const DICT_OPEN_INFO *my_open_info;
+
+    if (type_name == 0)
+       type_name = vstring_alloc(100);
+
+    /*
+     * Sanity check.
+     */
+    if (!nbdb_is_legacy_type(leg_type)) {
+       vstring_sprintf(why, "request to map from non-Berkeley-DB type: '%s'",
+                       leg_type);
+       return (0);
+    }
+    /* Search for custom mapping with the type:name. */
+    if (nbdb_cust_map != 0) {
+       vstring_sprintf(type_name, "%s:%s", leg_type, name);
+       if ((non_leg_type = dict_get(nbdb_cust_map, STR(type_name))) == 0
+           && nbdb_cust_map->error == 0)
+           /* Search with the 'bare' type only. */
+           non_leg_type = dict_get(nbdb_cust_map, leg_type);
+       if (non_leg_type == 0 && nbdb_cust_map->error != 0) {
+           vstring_sprintf(why, "%s:%s lookup error for '%s'",
+                           nbdb_cust_map->type, nbdb_cust_map->name,
+                           STR(type_name));
+           return (0);
+       }
+    }
+
+    /*
+     * No custom mapping: use the default.
+     */
+    if (non_leg_type == 0) {
+       if (strcmp(leg_type, DICT_TYPE_HASH) == 0) {
+           non_leg_type = (var_db_type);
+       } else if (strcmp(leg_type, DICT_TYPE_BTREE) == 0) {
+           non_leg_type = (var_cache_db_type);
+       } else {
+           msg_panic("%s: no default mapping for Berkeley DB type: '%s'",
+                     __func__, leg_type);
+       }
+    }
+
+    /*
+     * More sanity checks.
+     */
+    if (!allalnum(non_leg_type)) {
+       vstring_sprintf(why, "bad non-legacy database type syntax: '%s'",
+                       non_leg_type);
+       return (0);
+    }
+    if (nbdb_is_legacy_type(non_leg_type)) {
+       vstring_sprintf(why, "mapping from '%s' to legacy type '%s'",
+                       leg_type, non_leg_type);
+       return (0);
+    }
+    if ((my_open_info = dict_open_lookup(non_leg_type)) == 0) {
+       vstring_sprintf(why, "mapping to unsupported database type: '%s'",
+                       non_leg_type);
+       return (0);
+    }
+    if (open_info != 0)
+       *open_info = my_open_info;
+    return (non_leg_type);
+}
+
+/* nbdb_is_legacy_type - sanity check */
+
+int     nbdb_is_legacy_type(const char *leg_type)
+{
+    return (strcmp(leg_type, DICT_TYPE_HASH) == 0
+           || strcmp(leg_type, DICT_TYPE_BTREE) == 0);
+}
+
+/* nbdb_find_non_leg_suffix - find file suffix for non-legacy type */
+
+const char *nbdb_find_non_leg_suffix(const char *non_leg_type)
+{
+    const NBDB_PATH_SUFFIX *sp;
+
+    for (sp = nbdb_path_suffixes; sp->type != 0; sp++)
+       if (strcmp(non_leg_type, sp->type) == 0)
+           break;
+    return (sp->suffix);
+}
+
+/* nbdb_util_init - redirect legacy open() requests to nbdb handlers */
+
+void    nbdb_util_init(const char *level_name)
+{
+    static NAME_CODE nbdb_level_table[] = {
+       NBDB_LEV_NAME_NONE, NBDB_LEV_CODE_NONE,
+       NBDB_LEV_NAME_REDIRECT, NBDB_LEV_CODE_REDIRECT,
+       NBDB_LEV_NAME_REINDEX, NBDB_LEV_CODE_REINDEX,
+       0, -1,
+    };
+
+    /*
+     * Convert the non-Berkeley-DB migration level to internal form. If
+     * migration support is disabled, then do not tun the code below.
+     */
+    nbdb_level = name_code(nbdb_level_table, NAME_CODE_FLAG_NONE, level_name);
+    if (nbdb_level == NBDB_LEV_CODE_ERROR)
+       msg_fatal("invalid non-Berkeley-DB migration level: '%s'", level_name);
+    if (nbdb_level == NBDB_LEV_CODE_NONE) {
+#ifdef NO_DB
+       nbdb_surr_init();
+#endif
+       return;
+    }
+
+    /*
+     * Initialize the custom legacy to non-legacy mapping. Discard an
+     * existing mapping, to simplify testing. To avoid a dependency loop,
+     * this mapping should never use a legacy database type.
+     */
+    if (nbdb_cust_map) {
+       dict_close(nbdb_cust_map);
+       nbdb_cust_map = 0;
+    }
+    if (*var_nbdb_cust_map) {
+       char   *map_type = mystrdup(var_nbdb_cust_map);
+       char   *map_name = split_at(map_type, ':');
+
+       if (map_name != 0 && (strcmp(map_type, DICT_TYPE_HASH) == 0
+                             || strcmp(map_type, DICT_TYPE_BTREE) == 0)) {
+           nbdb_cust_map = dict_surrogate(map_type, map_name,
+                                          O_RDONLY, DICT_FLAG_LOCK,
+                                       "%s must not use legacy type: '%s'",
+                                          VAR_NBDB_CUST_MAP,
+                                          map_type);
+       } else {
+           nbdb_cust_map = dict_open(var_nbdb_cust_map, O_RDONLY,
+                                     DICT_FLAG_LOCK
+                                     | DICT_FLAG_FOLD_FIX
+                                     | DICT_FLAG_UTF8_REQUEST);
+       }
+       myfree(map_type);
+    }
+
+    /*
+     * If this process does not provide the reindexing service, turn on the
+     * forward-compatibility redirection for legacy database types and
+     * reindexing server callouts.
+     * 
+     * The reindexing server should never attempt to use legacy database types,
+     * and should never be calling reindexing service client code.
+     */
+    if (!nbdb_reindexing_lockout)
+       nbdb_rdr_init();
+}
diff --git a/postfix/src/global/nbdb_util.h b/postfix/src/global/nbdb_util.h
new file mode 100644 (file)
index 0000000..3f363c8
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _NBDB_UTIL_H_INCLUDED_
+#define _NBDB_UTIL_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_util 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration utilities
+/* SYNOPSIS
+/*     #include <nbdb_util.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+Utility library. */
+#include <dict.h>
+
+ /*
+  * External API.
+  */
+#define NBDB_STAT_OK   0
+#define NBDB_STAT_ERROR        1
+
+extern int nbdb_level;
+extern bool nbdb_reindexing_lockout;
+
+extern void nbdb_util_init(const char *);
+extern int nbdb_is_legacy_type(const char *);
+extern const char *nbdb_find_non_leg_suffix(const char *);
+extern const char *nbdb_map_leg_type(const char *, const char *,
+                                       const DICT_OPEN_INFO **, VSTRING *);
+
+#define NBDB_LEGACY_SUFFIX     ".db"
+
+ /*
+  * Migration level internal forms.
+  */
+#define NBDB_LEV_CODE_ERROR    (-1)
+#define NBDB_LEV_CODE_NONE     (0)
+#define NBDB_LEV_CODE_REDIRECT (1)
+#define NBDB_LEV_CODE_REINDEX  (2)
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/global/nbdb_util_test.c b/postfix/src/global/nbdb_util_test.c
new file mode 100644 (file)
index 0000000..f41fe47
--- /dev/null
@@ -0,0 +1,448 @@
+/*++
+/* NAME
+/*     nbdb_util_test 1t
+/* SUMMARY
+/*     nbdb_util unit test
+/* SYNOPSIS
+/*     ./nbdb_util_test
+/* DESCRIPTION
+/*     nbdb_util_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <stringops.h>
+#include <msg_vstream.h>
+#include <vstring.h>
+#include <vstream.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_util.h>
+#include <nbdb_redirect.h>
+
+ /*
+  * Testing library.
+  */
+#include <mock_dict.h>
+#include <msg_capture.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+#define PASS    (0)
+#define FAIL    (1)
+
+#define BOOL_TO_TEXT(b) ((b) ? "true" : "false")
+
+ /*
+  * Scaffolding.
+  */
+
+char   *var_nbdb_cust_map = DEF_NBDB_CUST_MAP;
+
+/* dummy nbdb_rdr_init() support */
+
+void    nbdb_rdr_init(void)
+{
+}
+
+ /*
+  * tests for nbdb_util_init(),
+  */
+struct nbdb_util_init_test {
+    const char *label;
+    int     (*action) (const struct nbdb_util_init_test *);
+    const char *in_level;
+    bool    in_reindexing_lockout;
+    int     want_level;
+};
+
+#define STR_OR_NULL(s) ((s) ? (s) : "(null)")
+
+static int test_nbdb_util_init(const struct nbdb_util_init_test * tp)
+{
+    nbdb_util_init(tp->in_level);
+    if (nbdb_level != tp->want_level) {
+       msg_warn("unexpected nbdb_level, got: %d, want: %d",
+                nbdb_level, tp->want_level);
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+static const struct nbdb_util_init_test nbdb_util_init_tests[] = {
+    {.label = "nbdb_util_init_level_none",
+       .action = test_nbdb_util_init,
+       .in_level = "disable",
+       .want_level = NBDB_LEV_CODE_NONE,
+    },
+    {.label = "nbdb_util_init_level_redirect",
+       .action = test_nbdb_util_init,
+       .in_level = "enable-redirect",
+       .want_level = NBDB_LEV_CODE_REDIRECT,
+    },
+    {.label = "nbdb_util_init_level_reindex",
+       .action = test_nbdb_util_init,
+       .in_level = "enable-reindex",
+       .want_level = NBDB_LEV_CODE_REINDEX,
+    },
+    {.label = "nbdb_util_init_level_reindexing_with_lockout",
+       .action = test_nbdb_util_init,
+       .in_level = "enable-reindex",
+       .in_reindexing_lockout = true,
+       .want_level = NBDB_LEV_CODE_REINDEX,
+    },
+    /* TODO: trap msg_fatal() call after bad level name. */
+    {0},
+};
+
+ /*
+  * Tests for nbdb_is_legacy_type().
+  */
+struct nbdb_is_legacy_type_test {
+    const char *label;
+    int     (*action) (const struct nbdb_is_legacy_type_test *);
+    const char *in_type;
+    bool    want_result;
+};
+
+static int test_nbdb_is_legacy_type(const struct nbdb_is_legacy_type_test * tp)
+{
+    bool    got_result;
+
+    got_result = nbdb_is_legacy_type(tp->in_type);
+    if (got_result != tp->want_result) {
+       msg_warn("unexpected result; got '%s', want: ''%s'",
+                BOOL_TO_TEXT(got_result), BOOL_TO_TEXT(tp->want_result));
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+static const struct nbdb_is_legacy_type_test nbdb_is_legacy_type_tests[] = {
+    {.label = "nbdb_is_legacy_type_hash_true",
+       .action = test_nbdb_is_legacy_type,
+       .in_type = "hash",
+       .want_result = true,
+    },
+    {.label = "nbdb_is_legacy_type_btree_true",
+       .action = test_nbdb_is_legacy_type,
+       .in_type = "btree",
+       .want_result = true,
+    },
+    {.label = "nbdb_is_legacy_type_lmdb_false",
+       .action = test_nbdb_is_legacy_type,
+       .in_type = "lmdb",
+       .want_result = false,
+    },
+    {.label = "nbdb_is_legacy_type_cdb_false",
+       .action = test_nbdb_is_legacy_type,
+       .in_type = "cdb",
+       .want_result = false,
+    },
+    {0},
+};
+
+ /*
+  * Tests for find_non_leg_suffix().
+  */
+struct find_non_leg_suffix_test {
+    const char *label;
+    int     (*action) (const struct find_non_leg_suffix_test *);
+    const char *in_type;
+    const char *want_suffix;
+};
+
+#define STR_OR_NULL(s) ((s) ? (s) : "(null)")
+
+static int test_find_non_leg_suffix(const struct find_non_leg_suffix_test * tp)
+{
+    const char *got_suffix;
+
+    got_suffix = nbdb_find_non_leg_suffix(tp->in_type);
+    if (!got_suffix != !tp->want_suffix) {
+       msg_warn("unexpected suffix; got: '%s', want: '%s'",
+                STR_OR_NULL(got_suffix), STR_OR_NULL(tp->want_suffix));
+       return (FAIL);
+    }
+    if (got_suffix && strcmp(got_suffix, tp->want_suffix) != 0) {
+       msg_warn("unexpected suffix; got: '%s', want: '%s'",
+                got_suffix, tp->want_suffix);
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+static const struct find_non_leg_suffix_test find_non_leg_suffix_tests[] = {
+    {.label = "find_non_leg_suffix_lmdb",
+       .action = test_find_non_leg_suffix,
+       .in_type = "lmdb",
+       .want_suffix = ".lmdb",
+    },
+    {.label = "find_non_leg_suffix_cdb",
+       .action = test_find_non_leg_suffix,
+       .in_type = "cdb",
+       .want_suffix = ".cdb",
+    },
+    {.label = "find_non_leg_suffix_hash",
+       .action = test_find_non_leg_suffix,
+       .in_type = "hash",
+       .want_suffix = 0,
+    },
+    {.label = "find_non_leg_suffix_btree",
+       .action = test_find_non_leg_suffix,
+       .in_type = "btree",
+       .want_suffix = 0,
+    },
+    {0},
+};
+
+ /*
+  * Tests for map_leg_type().
+  */
+struct map_leg_type_test {
+    const char *label;
+    int     (*action) (const struct map_leg_type_test *);
+    const char *in_db_type;
+    const char *in_cache_db_type;
+    const char *in_custom_map;
+    const char *in_type;
+    const char *in_name;
+    const char *want_type;
+    const char *want_why;
+    const char *want_warning;
+};
+
+static int test_map_leg_type(const struct map_leg_type_test * tp)
+{
+    VSTRING *got_why = vstring_alloc(100);
+    MSG_CAPTURE *capture = msg_capt_create(100);
+    char   *saved_db_type = var_db_type;
+    char   *saved_cache_db_type = var_cache_db_type;
+    char   *saved_cust_map = var_nbdb_cust_map;
+    const char *got_type;
+    const char *got_warning;
+    int     status = PASS;
+
+    /* Setup. */
+    setup_mock_cdb("{{x = x}}");
+    setup_mock_lmdb("{{x = x}}");
+    dict_allow_surrogate = 1;
+    var_nbdb_cust_map = (char *) tp->in_custom_map;
+    var_db_type = (char *) tp->in_db_type;
+    var_cache_db_type = (char *) tp->in_cache_db_type;
+
+    msg_capt_start(capture);
+    nbdb_util_init("enable-redirect");
+    got_type = nbdb_map_leg_type(tp->in_type, tp->in_name,
+                                (const DICT_OPEN_INFO **) 0, got_why);
+    msg_capt_stop(capture);
+    got_warning = msg_capt_expose(capture);
+
+    /* Verify results. */
+    if (!LEN(got_why) != !tp->want_why) {
+       msg_warn("got error text: `%s', want: `%s'",
+                STR(got_why), STR_OR_NULL(tp->want_why));
+       status = FAIL;
+    } else if (tp->want_why && strstr(STR(got_why), tp->want_why) == 0) {
+       msg_warn("got error text: `%s', want: `%s'",
+                STR(got_why), tp->want_why);
+       status = FAIL;
+    } else if (!tp->want_warning != !got_warning[0]) {
+       msg_warn("got warning: '%s', want: '%s'",
+                got_warning, STR_OR_NULL(tp->want_warning));
+       status = FAIL;
+    } else if (tp->want_warning && strstr(got_warning, tp->want_warning) == 0) {
+       msg_warn("got warning: '%s', want: '%s'",
+                got_warning, tp->want_warning);
+       status = FAIL;
+    } else if (!got_type != !tp->want_type) {
+       msg_warn("got unexpected type: '%s', want: '%s'",
+                STR_OR_NULL(got_type), STR_OR_NULL(tp->want_type));
+       status = FAIL;
+    } else if (got_type && strcmp(got_type, tp->want_type) != 0) {
+       msg_warn("got unexpected type: '%s', want: '%s'",
+                got_type, tp->want_type);
+       status = FAIL;
+    }
+    var_nbdb_cust_map = saved_cust_map;
+    var_db_type = saved_db_type;
+    var_cache_db_type = saved_cache_db_type;
+    vstring_free(got_why);
+    msg_capt_free(capture);
+    return (status);
+}
+
+static const struct map_leg_type_test map_leg_type_tests[] = {
+    {"map_leg_type:default_hash_to_cdb",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = "cdb",
+    },
+    {"map_leg_type:default_btree_to_lmdb",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "",
+       .in_type = "btree",
+       .in_name = "/some/where/blah",
+       .want_type = "lmdb",
+    },
+    {"map_leg_type:custom_hash_with_path_to_lmdb",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{hash:/some/where/blah = lmdb}}",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = "lmdb",
+    },
+    {"map_leg_type:custom_btree_with_path_to_cdb",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{btree:/some/where/blah = cdb}}",
+       .in_type = "btree",
+       .in_name = "/some/where/blah",
+       .want_type = "cdb",
+    },
+    {"map_leg_type:custom_hash_to_lmdb",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{hash = lmdb}}",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = "lmdb",
+    },
+    {"map_leg_type:custom_mapping_type_must_not_use_hash",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "hash:/whatever",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = 0,
+       .want_why = "lookup error for 'hash:/some/where/blah'",
+       .want_warning = "mapping must not use legacy type: 'hash'"
+    },
+    {"map_leg_type:custom_mapping_type_must_not_use_btree",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "btree:/whatever",
+       .in_type = "btree",
+       .in_name = "/some/where/blah",
+       .want_type = 0,
+       .want_why = "lookup error for 'btree:/some/where/blah'",
+       .want_warning = "mapping must not use legacy type: 'btree'",
+    },
+    {"map_leg_type:custom_hash_to_composite",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{hash = proxy:lmdb}}",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = 0,
+       .want_why = "bad non-legacy database type syntax: 'proxy:lmdb'",
+    },
+    {"map_leg_type:custom_hash_to_legacy",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{hash = btree}}",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = 0,
+       .want_why = "mapping from 'hash' to legacy type 'btree'",
+    },
+    {"map_leg_type:custom_hash_to_unsupported",
+       .action = test_map_leg_type,
+       .in_db_type = "cdb",
+       .in_cache_db_type = "lmdb",
+       .in_custom_map = "inline:{{hash = foo}}",
+       .in_type = "hash",
+       .in_name = "/some/where/blah",
+       .want_type = 0,
+       .want_why = "unsupported database type: 'foo'",
+    },
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    int     pass = 0;
+    int     fail = 0;
+
+#define RUN_TEST(tp) do { \
+       int     test_failed; \
+       msg_info("RUN  %s", tp->label); \
+       test_failed = tp->action(tp); \
+       if (test_failed) { \
+           msg_info("FAIL %s", tp->label); \
+           fail++; \
+       } else { \
+           msg_info("PASS %s", tp->label); \
+           pass++; \
+       } \
+    } while (0)
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+    /* nbdb_util_init tests. */
+    {
+       const struct nbdb_util_init_test *tp;
+
+       for (tp = nbdb_util_init_tests; tp->label != 0; tp++)
+           RUN_TEST(tp);
+    }
+    /* nbdb_is_legacy_type() tests. */
+    {
+       const struct nbdb_is_legacy_type_test *tp;
+
+       for (tp = nbdb_is_legacy_type_tests; tp->label != 0; tp++)
+           RUN_TEST(tp);
+    }
+    /* find_non_leg_suffix() tests. */
+    {
+       const struct find_non_leg_suffix_test *tp;
+
+       for (tp = find_non_leg_suffix_tests; tp->label != 0; tp++)
+           RUN_TEST(tp);
+    }
+    /* map_leg_type() tests. */
+    {
+       const struct map_leg_type_test *tp;
+
+       for (tp = map_leg_type_tests; tp->label != 0; tp++)
+           RUN_TEST(tp);
+    }
+
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/nbdb_reindexd/Makefile.in b/postfix/src/nbdb_reindexd/Makefile.in
new file mode 100644 (file)
index 0000000..0b23340
--- /dev/null
@@ -0,0 +1,261 @@
+SHELL  = /bin/sh
+SRCS   = nbdb_reindexd.c nbdb_sniffer.c nbdb_safe.c \
+       nbdb_index_as.c nbdb_process.c
+OBJS   = nbdb_reindexd.o nbdb_sniffer.o nbdb_safe.o \
+       nbdb_index_as.o nbdb_process.o
+HDRS   = nbdb_reindexd.h nbdb_sniffer.h nbdb_safe.h \
+       nbdb_index_as.h nbdb_process.h
+TESTSRC        = nbdb_sniffer_test.c nbdb_safe_test.c
+DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+PROG   = nbdb_reindexd
+TESTPROG= nbdb_sniffer_test nbdb_safe_test nbdb_index_as_test nbdb_process_test
+TESTLIB        = ../../lib/libtesting.a
+INC_DIR        = ../../include
+LIBS   = ../../lib/lib$(LIB_PREFIX)master$(LIB_SUFFIX) \
+       ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
+       ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+$(PROG):       $(OBJS) $(LIBS)
+       $(CC) $(CFLAGS) $(SHLIB_RPATH) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
+
+$(OBJS): ../../conf/makedefs.out
+
+Makefile: Makefile.in
+       cat ../../conf/makedefs.out $? >$@
+
+test:  $(TESTPROG)
+
+tests: test_nbdb_sniffer test_nbdb_safe test_nbdb_index_as test_nbdb_process
+
+root_tests:
+
+update: ../../libexec/$(PROG)
+
+../../libexec/$(PROG): $(PROG)
+       cp $(PROG) ../../libexec
+
+clean:
+       rm -f *.o *core $(PROG) $(TESTPROG) junk 
+
+tidy:  clean
+
+SNIFFER_TEST_OBJ = nbdb_sniffer.o $(TESTLIB)
+
+nbdb_sniffer_test: nbdb_sniffer_test.o $(SNIFFER_TEST_OBJ) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(SNIFFER_TEST_OBJ) $(LIBS) $(SYSLIBS)
+
+test_nbdb_sniffer: nbdb_sniffer_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_sniffer_test
+
+SAFE_TEST_OBJ = nbdb_safe.o
+
+nbdb_safe_test: nbdb_safe_test.o $(SAFE_TEST_OBJ) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(SAFE_TEST_OBJ) $(LIBS) $(SYSLIBS)
+
+test_nbdb_safe: nbdb_safe_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_safe_test
+
+INDEX_AS_TEST_OBJ = nbdb_index_as.o $(TESTLIB)
+
+nbdb_index_as_test: nbdb_index_as_test.o $(INDEX_AS_TEST_OBJ) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(INDEX_AS_TEST_OBJ) $(LIBS) $(SYSLIBS)
+
+test_nbdb_index_as: nbdb_index_as_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_index_as_test
+
+PROCESS_TEST_OBJ = nbdb_process.o nbdb_index_as.o nbdb_sniffer.o nbdb_safe.o \
+        $(TESTLIB)
+
+nbdb_process_test: nbdb_process_test.o $(PROCESS_TEST_OBJ) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $@.o $(PROCESS_TEST_OBJ) $(LIBS) $(SYSLIBS)
+
+test_nbdb_process: nbdb_process_test
+       $(SHLIB_ENV) $(VALGRIND) ./nbdb_process_test
+
+depend: $(MAKES)
+       (sed '1,/^# do not edit/!d' Makefile.in; \
+       set -e; for i in [a-z][a-z0-9]*.c; do \
+           $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
+           -e 's/o: \.\//o: /' -e p -e '}' ; \
+       done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+       @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+nbdb_index_as.o: ../../include/argv.h
+nbdb_index_as.o: ../../include/check_arg.h
+nbdb_index_as.o: ../../include/dict.h
+nbdb_index_as.o: ../../include/iostuff.h
+nbdb_index_as.o: ../../include/mail_params.h
+nbdb_index_as.o: ../../include/mail_parm_split.h
+nbdb_index_as.o: ../../include/myflock.h
+nbdb_index_as.o: ../../include/nbdb_util.h
+nbdb_index_as.o: ../../include/spawn_command.h
+nbdb_index_as.o: ../../include/stringops.h
+nbdb_index_as.o: ../../include/sys_defs.h
+nbdb_index_as.o: ../../include/vbuf.h
+nbdb_index_as.o: ../../include/vstream.h
+nbdb_index_as.o: ../../include/vstring.h
+nbdb_index_as.o: nbdb_index_as.c
+nbdb_index_as.o: nbdb_index_as.h
+nbdb_index_as_test.o: ../../include/argv.h
+nbdb_index_as_test.o: ../../include/check_arg.h
+nbdb_index_as_test.o: ../../include/dict.h
+nbdb_index_as_test.o: ../../include/mock_spawn_command.h
+nbdb_index_as_test.o: ../../include/msg.h
+nbdb_index_as_test.o: ../../include/msg_vstream.h
+nbdb_index_as_test.o: ../../include/myflock.h
+nbdb_index_as_test.o: ../../include/nbdb_util.h
+nbdb_index_as_test.o: ../../include/spawn_command.h
+nbdb_index_as_test.o: ../../include/stringops.h
+nbdb_index_as_test.o: ../../include/sys_defs.h
+nbdb_index_as_test.o: ../../include/vbuf.h
+nbdb_index_as_test.o: ../../include/vstream.h
+nbdb_index_as_test.o: ../../include/vstring.h
+nbdb_index_as_test.o: nbdb_index_as.h
+nbdb_index_as_test.o: nbdb_index_as_test.c
+nbdb_process.o: ../../include/allowed_prefix.h
+nbdb_process.o: ../../include/argv.h
+nbdb_process.o: ../../include/attr.h
+nbdb_process.o: ../../include/check_arg.h
+nbdb_process.o: ../../include/dict.h
+nbdb_process.o: ../../include/htable.h
+nbdb_process.o: ../../include/mail_params.h
+nbdb_process.o: ../../include/msg.h
+nbdb_process.o: ../../include/myflock.h
+nbdb_process.o: ../../include/mymalloc.h
+nbdb_process.o: ../../include/nbdb_util.h
+nbdb_process.o: ../../include/nvtable.h
+nbdb_process.o: ../../include/spawn_command.h
+nbdb_process.o: ../../include/sys_defs.h
+nbdb_process.o: ../../include/vbuf.h
+nbdb_process.o: ../../include/vstream.h
+nbdb_process.o: ../../include/vstring.h
+nbdb_process.o: ../../include/wrap_stat.h
+nbdb_process.o: nbdb_index_as.h
+nbdb_process.o: nbdb_process.c
+nbdb_process.o: nbdb_process.h
+nbdb_process.o: nbdb_reindexd.h
+nbdb_process.o: nbdb_safe.h
+nbdb_process.o: nbdb_sniffer.h
+nbdb_process_test.o: ../../include/allowed_prefix.h
+nbdb_process_test.o: ../../include/argv.h
+nbdb_process_test.o: ../../include/check_arg.h
+nbdb_process_test.o: ../../include/dict.h
+nbdb_process_test.o: ../../include/dict_cdb.h
+nbdb_process_test.o: ../../include/dict_lmdb.h
+nbdb_process_test.o: ../../include/mail_params.h
+nbdb_process_test.o: ../../include/mkmap.h
+nbdb_process_test.o: ../../include/mock_dict.h
+nbdb_process_test.o: ../../include/mock_open_as.h
+nbdb_process_test.o: ../../include/mock_spawn_command.h
+nbdb_process_test.o: ../../include/mock_stat.h
+nbdb_process_test.o: ../../include/msg.h
+nbdb_process_test.o: ../../include/msg_capture.h
+nbdb_process_test.o: ../../include/msg_vstream.h
+nbdb_process_test.o: ../../include/myflock.h
+nbdb_process_test.o: ../../include/nbdb_util.h
+nbdb_process_test.o: ../../include/open_as.h
+nbdb_process_test.o: ../../include/spawn_command.h
+nbdb_process_test.o: ../../include/stringops.h
+nbdb_process_test.o: ../../include/sys_defs.h
+nbdb_process_test.o: ../../include/vbuf.h
+nbdb_process_test.o: ../../include/vstream.h
+nbdb_process_test.o: ../../include/vstring.h
+nbdb_process_test.o: nbdb_index_as.h
+nbdb_process_test.o: nbdb_process.h
+nbdb_process_test.o: nbdb_process_test.c
+nbdb_process_test.o: nbdb_safe.h
+nbdb_reindexd.o: ../../include/allowed_prefix.h
+nbdb_reindexd.o: ../../include/argv.h
+nbdb_reindexd.o: ../../include/attr.h
+nbdb_reindexd.o: ../../include/check_arg.h
+nbdb_reindexd.o: ../../include/dict.h
+nbdb_reindexd.o: ../../include/htable.h
+nbdb_reindexd.o: ../../include/iostuff.h
+nbdb_reindexd.o: ../../include/mail_conf.h
+nbdb_reindexd.o: ../../include/mail_params.h
+nbdb_reindexd.o: ../../include/mail_proto.h
+nbdb_reindexd.o: ../../include/mail_server.h
+nbdb_reindexd.o: ../../include/mail_task.h
+nbdb_reindexd.o: ../../include/mail_version.h
+nbdb_reindexd.o: ../../include/msg.h
+nbdb_reindexd.o: ../../include/msg_vstream.h
+nbdb_reindexd.o: ../../include/myflock.h
+nbdb_reindexd.o: ../../include/mymalloc.h
+nbdb_reindexd.o: ../../include/nbdb_util.h
+nbdb_reindexd.o: ../../include/nvtable.h
+nbdb_reindexd.o: ../../include/set_eugid.h
+nbdb_reindexd.o: ../../include/split_at.h
+nbdb_reindexd.o: ../../include/sys_defs.h
+nbdb_reindexd.o: ../../include/vbuf.h
+nbdb_reindexd.o: ../../include/vstream.h
+nbdb_reindexd.o: ../../include/vstring.h
+nbdb_reindexd.o: ../../include/wrap_stat.h
+nbdb_reindexd.o: nbdb_index_as.h
+nbdb_reindexd.o: nbdb_process.h
+nbdb_reindexd.o: nbdb_reindexd.c
+nbdb_reindexd.o: nbdb_reindexd.h
+nbdb_reindexd.o: nbdb_safe.h
+nbdb_reindexd.o: nbdb_sniffer.h
+nbdb_safe.o: ../../include/allowed_prefix.h
+nbdb_safe.o: ../../include/argv.h
+nbdb_safe.o: ../../include/check_arg.h
+nbdb_safe.o: ../../include/mail_conf.h
+nbdb_safe.o: ../../include/mail_params.h
+nbdb_safe.o: ../../include/sys_defs.h
+nbdb_safe.o: ../../include/vbuf.h
+nbdb_safe.o: ../../include/vstring.h
+nbdb_safe.o: ../../include/wrap_stat.h
+nbdb_safe.o: nbdb_reindexd.h
+nbdb_safe.o: nbdb_safe.c
+nbdb_safe.o: nbdb_safe.h
+nbdb_safe_test.o: ../../include/allowed_prefix.h
+nbdb_safe_test.o: ../../include/argv.h
+nbdb_safe_test.o: ../../include/check_arg.h
+nbdb_safe_test.o: ../../include/mail_conf.h
+nbdb_safe_test.o: ../../include/mail_params.h
+nbdb_safe_test.o: ../../include/msg.h
+nbdb_safe_test.o: ../../include/msg_vstream.h
+nbdb_safe_test.o: ../../include/stringops.h
+nbdb_safe_test.o: ../../include/sys_defs.h
+nbdb_safe_test.o: ../../include/vbuf.h
+nbdb_safe_test.o: ../../include/vstream.h
+nbdb_safe_test.o: ../../include/vstring.h
+nbdb_safe_test.o: nbdb_safe.h
+nbdb_safe_test.o: nbdb_safe_test.c
+nbdb_sniffer.o: ../../include/allowed_prefix.h
+nbdb_sniffer.o: ../../include/argv.h
+nbdb_sniffer.o: ../../include/check_arg.h
+nbdb_sniffer.o: ../../include/dict.h
+nbdb_sniffer.o: ../../include/mail_params.h
+nbdb_sniffer.o: ../../include/msg.h
+nbdb_sniffer.o: ../../include/myflock.h
+nbdb_sniffer.o: ../../include/nbdb_util.h
+nbdb_sniffer.o: ../../include/open_as.h
+nbdb_sniffer.o: ../../include/readlline.h
+nbdb_sniffer.o: ../../include/resolve_clnt.h
+nbdb_sniffer.o: ../../include/stringops.h
+nbdb_sniffer.o: ../../include/sys_defs.h
+nbdb_sniffer.o: ../../include/tok822.h
+nbdb_sniffer.o: ../../include/vbuf.h
+nbdb_sniffer.o: ../../include/vstream.h
+nbdb_sniffer.o: ../../include/vstring.h
+nbdb_sniffer.o: nbdb_reindexd.h
+nbdb_sniffer.o: nbdb_sniffer.c
+nbdb_sniffer.o: nbdb_sniffer.h
+nbdb_sniffer_test.o: ../../include/check_arg.h
+nbdb_sniffer_test.o: ../../include/mock_open_as.h
+nbdb_sniffer_test.o: ../../include/msg.h
+nbdb_sniffer_test.o: ../../include/msg_vstream.h
+nbdb_sniffer_test.o: ../../include/open_as.h
+nbdb_sniffer_test.o: ../../include/stringops.h
+nbdb_sniffer_test.o: ../../include/sys_defs.h
+nbdb_sniffer_test.o: ../../include/vbuf.h
+nbdb_sniffer_test.o: ../../include/vstream.h
+nbdb_sniffer_test.o: ../../include/vstring.h
+nbdb_sniffer_test.o: nbdb_sniffer.h
+nbdb_sniffer_test.o: nbdb_sniffer_test.c
diff --git a/postfix/src/nbdb_reindexd/nbdb_index_as.c b/postfix/src/nbdb_reindexd/nbdb_index_as.c
new file mode 100644 (file)
index 0000000..e86d825
--- /dev/null
@@ -0,0 +1,172 @@
+/*++
+/* NAME
+/*     nbdb_index_as 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_index_as.h>
+/*
+/*     int     nbdb_index_as(
+/*     const char *command,
+/*     const char *new_type,
+/*     const char *source_path,
+/*     uid_t    uid,
+/*     gid_t    gid,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     nbdb_index_as() runs a command with the specified effective
+/*     uid and gid, to create an indexed file from a source file.
+/*     The command is killed after 100s. A limited amount of command
+/*     output is returned after failure.
+/*
+/*     The result value is one of the following:
+/* .IP NBDB_STAT_OK
+/*     The request was successful.
+/* .IP NBDB_STAT_ERROR
+/*     The request failed. A description of the problem is returned
+/*     in \fBwhy\fR.
+/* .PP
+/*     Arguments:
+/* .IP command
+/*     Run this command, "postmap" or "postalias".
+/* .IP new_type
+/*     Create an indexed file of this type.
+/* .IP source_path
+/*     The pathname of the Berkeley DB source file.
+/* .IP uid, gid
+/*     Run the command with these effective uid and gid,
+/* .IP why
+/*     Storage that is updated with an applicable error description.
+/* SEE ALSO
+/*     nbdb_index_as_test(1t), unit test
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+ /*
+  * Utility library.
+  */
+#include <argv.h>
+#include <iostuff.h>
+#include <spawn_command.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <mail_parm_split.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_index_as.h>
+#include <nbdb_util.h>
+
+#define STR(x)  vstring_str(x)
+
+/* nbdb_index_as - index a database with specified type and privileges */
+
+int     nbdb_index_as(const char *command, const char *new_type,
+               const char *source_path, uid_t uid, gid_t gid, VSTRING *why)
+{
+    VSTRING *command_path;
+    VSTRING *command_arg;
+    char   *cmd_argv[3];
+    ARGV   *export_env;
+    static int devnull_fd = -1;
+    int     cmd_out[2];
+    int     status;
+
+    /*
+     * Redirect the command's stdin to /dev/null. If we are going to do this
+     * in multiple programs, then we should make it a library feature.
+     */
+    if (devnull_fd < 0 && (devnull_fd = open("/dev/null", O_RDWR, 0)) < 0) {
+       vstring_sprintf(why, "open /dev/null O_RDWR: %m");
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Redirect the command's stdout and stderr to a pipe. See comments in
+     * pipe_command.c for a similar strategy to capture a limited amount of
+     * command output.
+     */
+    if (pipe(cmd_out) < 0) {
+       vstring_sprintf(why, "create %s output pipe: %m", command);
+       return (NBDB_STAT_ERROR);
+    }
+    non_blocking(cmd_out[0], NON_BLOCKING);    /* us */
+    non_blocking(cmd_out[1], NON_BLOCKING);    /* them */
+
+    /*
+     * Run the command with a generous time limit. If we kill the command
+     * then we leave behind a broken database.
+     * 
+     * TODO(wietse) extend spawn_command() with an option to return instead of
+     * terminating after fork() or wait() failure, maybe with fake command
+     * output, and certainly without file descriptor leaks.
+     */
+    cmd_argv[0] = STR(vstring_sprintf(command_path = vstring_alloc(100),
+                                     "%s/%s", var_command_dir, command));
+    cmd_argv[1] = STR(vstring_sprintf(command_arg = vstring_alloc(100),
+                                     "%s:%s", new_type, source_path));
+    cmd_argv[2] = 0;
+    export_env = mail_parm_split(VAR_EXPORT_ENVIRON, var_export_environ);
+    status = spawn_command(CA_SPAWN_CMD_STDIN(devnull_fd),
+                          CA_SPAWN_CMD_STDOUT(cmd_out[1]),
+                          CA_SPAWN_CMD_STDERR(cmd_out[1]),
+                          CA_SPAWN_CMD_ARGV(cmd_argv),
+                          CA_SPAWN_CMD_UID(uid),
+                          CA_SPAWN_CMD_GID(gid),
+                          CA_SPAWN_CMD_EXPORT(export_env->argv),
+                          CA_SPAWN_CMD_TIME_LIMIT(100),
+                          CA_SPAWN_CMD_END);
+
+    /*
+     * If the command failed, capture a limited amount of command output.
+     */
+    close(cmd_out[1]);                         /* them */
+    if (status != 0) {
+       ssize_t count;
+
+#define NBDB_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+       VSTRING_RESET(why);
+       VSTRING_SPACE(why, VSTREAM_BUFSIZE);
+       errno = 0;
+       if (read_wait(cmd_out[0], 0) < 0 ||
+           (count = peekfd(cmd_out[0])) <= 0 ||
+           (count = read(cmd_out[0], STR(why),
+                         NBDB_MIN(count, vstring_avail(why)))) <= 0) {
+           vstring_sprintf(why, "(%s failure reason unavailable: %m)",
+                           command);
+       } else {
+           /* Apply some basic hygiene. */
+           vstring_set_payload_size(why, count);
+           VSTRING_TERMINATE(why);
+           (void) translit(STR(why), "\b\r\n", "__");
+       }
+    }
+    close(cmd_out[0]);                         /* us */
+    vstring_free(command_arg);
+    vstring_free(command_path);
+    argv_free(export_env);
+
+    return (status == 0 ? NBDB_STAT_OK : NBDB_STAT_ERROR);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_index_as.h b/postfix/src/nbdb_reindexd/nbdb_index_as.h
new file mode 100644 (file)
index 0000000..d01b443
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _NBDB_INDEX_AS_H_INCLUDED_
+#define _NBDB_INDEX_AS_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_index_as.h 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_index_as.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <nbdb_util.h>
+
+ /*
+  * Internal API.
+  */
+extern int nbdb_index_as(const char *, const char *, const char *,
+                                uid_t, gid_t, VSTRING *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/nbdb_reindexd/nbdb_index_as_test.c b/postfix/src/nbdb_reindexd/nbdb_index_as_test.c
new file mode 100644 (file)
index 0000000..0b05eb6
--- /dev/null
@@ -0,0 +1,198 @@
+/*++
+/* NAME
+/*     nbdb_index_as_test 1t
+/* SUMMARY
+/*     index_as unit test
+/* SYNOPSIS
+/*     ./nbdb_index_as_test
+/* DESCRIPTION
+/*     index_as_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <msg_vstream.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <spawn_command.h>
+
+ /*
+  * Global library.
+  */
+#include <nbdb_util.h>
+
+ /*
+  * Testing library.
+  */
+#include <mock_spawn_command.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_index_as.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+ /*
+  * Scaffolding for parameter dependencies.
+  */
+char   *var_command_dir = DEF_COMMAND_DIR;
+char   *var_export_environ = "TZ MAIL_CONFIG LANG";
+
+ /*
+  * Test structure. Some tests may bring their own.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+
+    /*
+     * nbdb_index_as() mock dependencies.
+     */
+    MOCK_SPAWN_CMD_REQ mock_spawn;
+
+    /*
+     * nbdb_index_as() inputs and expected outputs.
+     */
+    struct index_info {
+       const char *in_command;
+       const char *in_new_type;
+       const char *in_source_path;
+       uid_t   in_uid;
+       gid_t   in_gid;
+       int     want_status;
+       const char *want_why;
+    }       index;
+} TEST_CASE;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+/* test_nbdb_index_as */
+
+static int test_nbdb_index_as(const TEST_CASE *tp)
+{
+    int     got_status;
+    VSTRING *got_why;
+    int     pass = 1;
+
+    setup_mock_spawn_command(&tp->mock_spawn);
+    got_why = vstring_alloc(100);
+    got_status =
+       nbdb_index_as(tp->index.in_command, tp->index.in_new_type,
+                     tp->index.in_source_path, tp->index.in_uid,
+                     tp->index.in_gid, got_why);
+
+    if (got_status != tp->index.want_status) {
+       msg_warn("got status '%d', want '%d'", got_status,
+                tp->index.want_status);
+       pass = 0;
+    } else if (got_status != 0
+              && strstr(STR(got_why), tp->index.want_why) == 0) {
+       msg_warn("got reason '%s' want '%s'", STR(got_why),
+                tp->index.want_why);
+       pass = 0;
+    }
+    vstring_free(got_why);
+    return (pass ? PASS : FAIL);
+}
+
+ /*
+  * The list of test cases.
+  */
+static const TEST_CASE test_cases[] = {
+    {.label = "normal_completion",
+       .action = test_nbdb_index_as,
+       .mock_spawn = {
+           .want_args = {
+               .argv = (char *[]) {DEF_COMMAND_DIR "/postmap", "lmdb:/path/to/foo", 0,},
+               .uid = 0,
+               .gid = 0,
+               .export = (char *[]) {"TZ", "MAIL_CONFIG", "LANG", 0,},
+               .time_limit = 100,
+           },
+           .out_status = NBDB_STAT_OK,
+           .out_text = 0,
+       },
+       .index = {
+           .in_command = "postmap",
+           .in_new_type = "lmdb",
+           .in_source_path = "/path/to/foo",
+           .in_uid = 0,
+           .in_gid = 0,
+           .want_status = NBDB_STAT_OK,
+           .want_why = 0,
+       },
+    },
+    {.label = "propagates_non_zero_status_and_text",
+       .action = test_nbdb_index_as,
+       .mock_spawn = {
+           .want_args = {
+               .argv = (char *[]) {DEF_COMMAND_DIR "/postmap", "lmdb:/path/to/foo", 0,},
+               .uid = 0,
+               .gid = 0,
+               .export = (char *[]) {"TZ", "MAIL_CONFIG", "LANG", 0,},
+               .time_limit = 100,
+           },
+           .out_status = NBDB_STAT_ERROR,
+           .out_text = "sorry, I cannot do that",
+       },
+       .index = {
+           .in_command = "postmap",
+           .in_new_type = "lmdb",
+           .in_source_path = "/path/to/foo",
+           .in_uid = 0,
+           .in_gid = 0,
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "I cannot do that",
+       },
+    },
+
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_process.c b/postfix/src/nbdb_reindexd/nbdb_process.c
new file mode 100644 (file)
index 0000000..0ad6ef1
--- /dev/null
@@ -0,0 +1,221 @@
+/*++
+/* NAME
+/*     nbdb_process 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_process.h>
+/*
+/*     int nbdb_process(
+/*     const char *legacy_type,
+/*     const char *source_path,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     nbdb_process() integrates the safety policy and content policy,
+/*     and calls spawn_command() to generate an indexed file for
+/*     $non_legacy_type:$source_path.
+/*
+/*     The result value is NBDB_MIGR_OK (success) or NBDB_MIGR_ERROR
+/*     (failure).
+/*
+/*     Arguments:
+/* .IP new_type
+/*     A non-legacy database type.
+/* .P source_path
+/*     The pathname for the source text file (no database suffix).
+/* .IP why
+/*     Storage for descriptive text in case of error.
+/* SEE ALSO
+/*     nbdb_safe(3), safety policy
+/*     nbdb_sniffer(3), content policy
+/*     nbdb_process_test(1t), unit test
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <libgen.h>                    /* dirname() */
+
+ /*
+  * Utility library.
+  */
+#include <attr.h>
+#include <msg.h>
+#include <spawn_command.h>
+#include <vstring.h>
+#include <wrap_stat.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+#include <mail_params.h>
+#include <nbdb_util.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_reindexd.h>
+#include <nbdb_safe.h>
+#include <nbdb_sniffer.h>
+#include <nbdb_index_as.h>
+#include <nbdb_process.h>
+
+#define STR(x) vstring_str(x)
+
+/* nbdb_process - main processing flow */
+
+int     nbdb_process(const char *leg_type, const char *source_path,
+                            VSTRING *why)
+{
+    const char *new_type;
+    struct stat source_st;
+    static VSTRING *new_idx_path;
+    struct stat new_idx_st;
+    static VSTRING *leg_idx_path;
+    struct stat leg_idx_st;
+    static VSTRING *parent_dir_buf;
+    struct stat parent_dir_st;
+    char   *parent_dir;
+    const char *new_suffix;
+    const char *index_cmd;
+    int     status;
+
+    if (new_idx_path == 0) {
+       new_idx_path = vstring_alloc(100);
+       leg_idx_path = vstring_alloc(100);
+       parent_dir_buf = vstring_alloc(100);
+    }
+
+    /*
+     * First things first.
+     */
+    if (nbdb_level < NBDB_LEV_CODE_REINDEX) {
+       vstring_sprintf(why, "the %s service is disabled", var_servname);
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * nbdb_map_leg_type() will allow only mapping from an expected Berkeley
+     * DB type to an expected non-Berkeley-DB type.
+     */
+    if ((new_type = nbdb_map_leg_type(leg_type, source_path,
+                                 (const DICT_OPEN_INFO **) 0, why)) == 0) {
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Look up the non-legacy pathname suffix and build the pathname that
+     * needs to be created. If no suffix exists then the client is in error.
+     */
+    if ((new_suffix = nbdb_find_non_leg_suffix(new_type)) == 0) {
+       vstring_sprintf(why, "non-Berkeley-DB type '%s' has no known suffix",
+                       new_type);
+       return (NBDB_STAT_ERROR);
+    }
+    vstring_sprintf(new_idx_path, "%s%s", source_path, new_suffix);
+
+    /*
+     * If the target indexed pathname already exists, then do nothing. All
+     * indexing requests are handled sequentially (to avoid collisions), and
+     * the client may have connected to this service before the file was
+     * indexed.
+     */
+    if (stat (STR(new_idx_path), &new_idx_st) == 0 && new_idx_st.st_size > 0) {
+       msg_info("target file '%s' already exists, skipping this request",
+                STR(new_idx_path));
+       return (NBDB_STAT_OK);
+    }
+
+    /*
+     * Require that the legacy indexed file exists. We need this to determine
+     * the owner's (uid, gid) to run the postmap or postalias command with.
+     */
+    vstring_sprintf(leg_idx_path, "%s%s", source_path, NBDB_LEGACY_SUFFIX);
+    if (stat (STR(leg_idx_path), &leg_idx_st) < 0) {
+       vstring_sprintf(why, "look up status for legacy indexed file '%s': %m",
+                       STR(leg_idx_path));
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Require that the source path exists. We need it as input for indexing,
+     * and will reject the request if the source has unsafe permissions for
+     * the uid that we would run postmap or postalias with.
+     */
+    if (stat (source_path, &source_st) < 0) {
+       vstring_sprintf(why, "look up status for source file '%s': %m",
+                       source_path);
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Require that the parent directory exists. We will reject the request
+     * if the directory has unsafe permissions for the uid that we would run
+     * postmap or postalias with.
+     */
+    vstring_strcpy(parent_dir_buf, source_path);
+    parent_dir = dirname(STR(parent_dir_buf));
+    if (stat (parent_dir, &parent_dir_st) < 0) {
+       vstring_sprintf(why, "look up status for parent directory '%s': %m",
+                       parent_dir);
+       return (NBDB_STAT_ERROR);
+    }
+
+    /*
+     * Should we run postmap or postalias? Open the source file with the same
+     * (uid, gid) as the postmap or postalias commands would, so that we can
+     * detect permission errors quickly.
+     * 
+     * Note: we do this before the file allowlist/owner/permission safety
+     * checks, so that we can log the concrete postmap or postalias command
+     * if a safety check fails.
+     */
+    if ((index_cmd = nbdb_get_index_cmd_as(source_path, leg_idx_st.st_uid,
+                                          leg_idx_st.st_gid, why)) == 0)
+       return (NBDB_STAT_ERROR);
+
+    /*
+     * Allow indexing as the legacy indexed file owner if it is considered
+     * "safe".
+     */
+    if (!nbdb_safe_to_index_as_legacy_index_owner(source_path, &source_st,
+                                            STR(leg_idx_path), &leg_idx_st,
+                                        parent_dir, &parent_dir_st, why)) {
+       status = NBDB_STAT_ERROR;
+    }
+
+    /*
+     * Finally!
+     */
+    else {
+       status = nbdb_index_as(index_cmd, new_type, source_path,
+                              leg_idx_st.st_uid, leg_idx_st.st_gid, why);
+       if (status != NBDB_STAT_OK)
+           /* Don't leave behind a broken indexed file. */
+           (void) unlink(STR(new_idx_path));
+    }
+
+    /*
+     * If the command failed, or was not safe to execute automatically, give
+     * the user the concrete command so that they could run it by hand.
+     */
+    if (status == NBDB_STAT_OK) {
+       msg_info("successfully executed '%s %s:%s' as uid %d",
+                index_cmd, new_type, source_path, leg_idx_st.st_uid);
+    } else {
+       vstring_sprintf_prepend(why, "could not execute command '%s %s:%s': ",
+                               index_cmd, new_type, source_path);
+       vstring_strcat(why,
+                    "; alternatively, execute the failed command by hand");
+    }
+    return (status);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_process.h b/postfix/src/nbdb_reindexd/nbdb_process.h
new file mode 100644 (file)
index 0000000..384eb8e
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _NBDB_PROCESS_H_INCLUDED_
+#define _NBDB_PROCESS_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_process.h 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_process.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <nbdb_util.h>
+
+ /*
+  * Internal API.
+  */
+extern int nbdb_process(const char *, const char *, VSTRING *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/nbdb_reindexd/nbdb_process_test.c b/postfix/src/nbdb_reindexd/nbdb_process_test.c
new file mode 100644 (file)
index 0000000..1aa953a
--- /dev/null
@@ -0,0 +1,577 @@
+/*++
+/* NAME
+/*     nbdb_process_test 1t
+/* SUMMARY
+/*     nbdb_process unit test
+/* SYNOPSIS
+/*     ./nbdb_process_test
+/* DESCRIPTION
+/*     nbdb_process_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict_cdb.h>
+#include <dict_lmdb.h>
+#include <msg.h>
+#include <msg_vstream.h>
+#include <mock_dict.h>
+#include <mock_stat.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+#include <nbdb_util.h>
+#include <mail_params.h>
+#include <msg_capture.h>
+
+ /*
+  * Testing library.
+  */
+#include <mock_spawn_command.h>
+#include <mock_stat.h>
+#include <mock_open_as.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_index_as.h>
+#include <nbdb_safe.h>
+#include <nbdb_index_as.h>
+#include <nbdb_process.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+ /*
+  * Scaffolding for static parameter dependencies.
+  */
+char   *var_command_dir = DEF_COMMAND_DIR;
+char   *var_export_environ = "TZ MAIL_CONFIG LANG";
+char   *var_servname = "nbdb_reindexd";
+char   *var_db_type = DICT_TYPE_CDB;
+char   *var_cache_db_type = DICT_TYPE_LMDB;
+char   *var_nbdb_cust_map = DEF_NBDB_CUST_MAP;
+
+ /*
+  * Test-dependent configuration parameters.
+  */
+bool    var_nbdb_enable = 0;
+
+char   *var_nbdb_allow_root_pfxs = DEF_NBDB_ALLOW_ROOT_PFXS;
+char   *var_nbdb_allow_user_pfxs = DEF_NBDB_ALLOW_USER_PFXS;
+
+ALLOWED_PREFIX *parsed_allow_root_pfxs;
+ALLOWED_PREFIX *parsed_allow_user_pfxs;
+
+ /*
+  * Test structure. TODO(wietse) readability problem: there are many test
+  * inputs, their values have a lot of overlap, and the tests data are far
+  * away from the code that uses it. For readability sake, consider using
+  * dedicated test-case functions with test data in local variables.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+
+    /*
+     * Mock dependencies.
+     */
+    MOCK_STAT_REQ mock_stat_source;
+    MOCK_STAT_REQ mock_stat_leg_idx;
+    MOCK_STAT_REQ mock_stat_parent;
+    MOCK_STAT_REQ mock_stat_new_idx;
+    MOCK_OPEN_AS_REQ mock_open;
+    MOCK_SPAWN_CMD_REQ mock_spawn;
+
+    /*
+     * nbdb_process() inputs and expected outputs.
+     */
+    struct {
+       const char *in_new_type;
+       const char *in_source_path;
+       int     want_status;
+       const char *want_why;
+       const char *want_msg;
+    }       process;
+
+    /*
+     * Configuration parameter settings.
+     */
+    struct {
+       const char *migr_level;
+       const char *allow_root_pfxs;
+       const char *allow_user_pfxs;
+    }       params;
+} TEST_CASE;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+/* test_nbdb_process */
+
+static int test_nbdb_process(const TEST_CASE *tp)
+{
+    MSG_CAPTURE *capture;
+    const char *got_msg;
+    int     got_status;
+    VSTRING *got_why;
+    int     pass = 1;
+
+    nbdb_util_init(tp->params.migr_level);
+    setup_mock_cdb("{{x = x}}");
+    setup_mock_lmdb("{{x = x}}");
+    if (nbdb_level >= NBDB_LEV_CODE_REINDEX) {
+       var_nbdb_allow_root_pfxs = (char *) tp->params.allow_root_pfxs;
+       var_nbdb_allow_user_pfxs = (char *) tp->params.allow_user_pfxs;
+
+       parsed_allow_root_pfxs = allowed_prefix_create(var_nbdb_allow_root_pfxs);
+       parsed_allow_user_pfxs = allowed_prefix_create(var_nbdb_allow_user_pfxs);
+
+       setup_mock_stat(&tp->mock_stat_source);
+       setup_mock_stat(&tp->mock_stat_leg_idx);
+       setup_mock_stat(&tp->mock_stat_parent);
+       setup_mock_stat(&tp->mock_stat_new_idx);
+       setup_mock_vstream_fopen_as(&tp->mock_open);
+       setup_mock_spawn_command(&tp->mock_spawn);
+    }
+    capture = msg_capt_create(100);
+    got_why = vstring_alloc(100);
+
+    msg_capt_start(capture);
+    got_status =
+       nbdb_process(tp->process.in_new_type, tp->process.in_source_path,
+                    got_why);
+    msg_capt_stop(capture);
+    got_msg = msg_capt_expose(capture);
+
+    if (tp->process.want_why == 0 && LEN(got_why) > 0) {
+       msg_warn("got unexpected reason '%s', want (none)", STR(got_why));
+       pass = 0;
+    }
+    if (tp->process.want_msg == 0 && *got_msg != 0) {
+       msg_warn("got unexpected message '%s', want (none)", got_msg);
+       pass = 0;
+    }
+    if (tp->process.want_msg && strstr(got_msg, tp->process.want_msg) == 0) {
+       msg_warn("got unexpected message '%s', want '%s'",
+                got_msg, tp->process.want_msg);
+       pass = 0;
+    }
+    if (got_status != tp->process.want_status) {
+       msg_warn("got status '%d', want '%d'", got_status,
+                tp->process.want_status);
+       pass = 0;
+    } else if (got_status != 0
+              && strstr(STR(got_why), tp->process.want_why) == 0) {
+       msg_warn("got reason '%s', want '%s'", STR(got_why),
+                tp->process.want_why);
+       pass = 0;
+    }
+    vstring_free(got_why);
+    msg_capt_free(capture);
+    if (nbdb_level >= NBDB_LEV_CODE_REINDEX) {
+       allowed_prefix_free(parsed_allow_root_pfxs);
+       allowed_prefix_free(parsed_allow_user_pfxs);
+    }
+    return (pass ? PASS : FAIL);
+}
+
+ /*
+  * The list of test cases. If you want to figure out what the tests do, the
+  * data below shows their recipe.
+  */
+static const TEST_CASE test_cases[] = {
+
+    {.label = "normal_completion",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 0,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .mock_spawn = {
+           .want_args = {
+               .argv = (char *[]) {DEF_COMMAND_DIR "/postmap", "cdb:/path/to/file", 0,},
+               .uid = 0,
+               .gid = 0,
+               .export = (char *[]) {"TZ", "MAIL_CONFIG", "LANG", 0,},
+               .time_limit = 100,
+           },
+           .out_status = 0,
+           .out_text = 0,
+       },
+       .params = {
+           .allow_root_pfxs = "/path/to",
+           .allow_user_pfxs = "/home/foo",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_OK,
+           .want_why = 0,
+           .want_msg = "successfully executed",
+       },
+    },
+
+    {.label = "respects_migr_level_disable",
+       .action = test_nbdb_process,
+       .params = {
+           .migr_level = "disable",
+       },
+       .process = {
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "service is disabled",
+       },
+    },
+
+    {.label = "propagates_nbdb_index_as_error",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 0,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .mock_spawn = {
+           .want_args = {
+               .argv = (char *[]) {DEF_COMMAND_DIR "/postmap", "cdb:/path/to/file", 0,},
+               .uid = 0,
+               .gid = 0,
+               .export = (char *[]) {"TZ", "MAIL_CONFIG", "LANG", 0,},
+               .time_limit = 100,
+           },
+           .out_status = NBDB_STAT_ERROR,
+           .out_text = "sorry, I cannot do that",
+       },
+       .params = {
+           .allow_root_pfxs = "/path/to",
+           .allow_user_pfxs = "/home/foo",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "cannot do that",
+       },
+    },
+
+    {.label = "propagates_nbdb_safe_to_index_error",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IWGRP,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 0,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .params = {
+           .allow_root_pfxs = "/path/to",
+           .allow_user_pfxs = "/home/foo",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "owned or writable by other user",
+       },
+    },
+
+    {.label = "propagates_nbdb_sniffer_error",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 0,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 0,
+           .want_gid = 0,
+           .out_errno = EACCES,
+           .out_data = 0,
+       },
+       .params = {
+           .allow_root_pfxs = "/path/to",
+           .allow_user_pfxs = "/home/foo",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "open lookup table source file /path/to/file",
+       },
+    },
+
+    /*
+     * Pathname prefix safety is enforced by nbdb_safe_to_index_as_xxx but it
+     * is important enough to have its own end-to-end test.
+     */
+    {.label = "respects_allow_root_prefix",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {
+               .st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,
+           },
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {
+               .st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,
+           },
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {
+               .st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,
+           },
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 1,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .params = {
+           .allow_root_pfxs = "/other/path",
+           .allow_user_pfxs = "/home/foo",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "could not execute command 'postmap cdb:/path/to/file': table /path/to/file has an unexpected pathname",
+       },
+    },
+
+    {.label = "normal_completion_non_root_case",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 1,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .mock_spawn = {
+           .want_args = {
+               .argv = (char *[]) {DEF_COMMAND_DIR "/postmap", "cdb:/path/to/file", 0,},
+               .uid = 1,
+               .gid = 0,
+               .export = (char *[]) {"TZ", "MAIL_CONFIG", "LANG", 0,},
+               .time_limit = 100,
+           },
+           .out_status = 0,
+           .out_text = 0,
+       },
+       .params = {
+           .allow_root_pfxs = "/somewhere",
+           .allow_user_pfxs = "/path/to",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_OK,
+           .want_why = 0,
+           .want_msg = "successfully executed",
+       },
+    },
+
+    {.label = "respects_allow_user_prefix",
+       .action = test_nbdb_process,
+       .mock_stat_source = {
+           .want_path = "/path/to/file",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_leg_idx = {
+           .want_path = "/path/to/file.db",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_parent = {
+           .want_path = "/path/to",
+           .out_errno = 0,
+           .out_st = {.st_mode = S_IRWXU,.st_uid = 1,.st_gid = 0,},
+       },
+       .mock_stat_new_idx = {
+           .want_path = "/path/to/file.cdb",
+           .out_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "/path/to/file",
+           .want_uid = 0,
+           .want_gid = 0,
+           .out_errno = 0,
+           .out_data = "foo bar\nfoo :bar",
+       },
+       .params = {
+           .allow_root_pfxs = "/somewhere",
+           .allow_user_pfxs = "/other/path",
+           .migr_level = "enable-reindex",
+       },
+       .process = {
+           .in_new_type = "hash",
+           .in_source_path = "/path/to/file",
+           .want_status = NBDB_STAT_ERROR,
+           .want_why = "unexpected pathname",
+       },
+    },
+
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_reindexd.c b/postfix/src/nbdb_reindexd/nbdb_reindexd.c
new file mode 100644 (file)
index 0000000..1b02fc9
--- /dev/null
@@ -0,0 +1,311 @@
+/*++
+/* NAME
+/*     nbdb_reindexd 8
+/* SUMMARY
+/*     Postfix non-Berkeley-DB migration
+/* SYNOPSIS
+/*     \fBnbdb_reindexd\fR [generic Postfix daemon options]
+/* DESCRIPTION
+/*     \fINOTE: This service should be enabled only temporarily to
+/*     generate most of the non-Berkeley-DB indexed files that Postfix
+/*     needs. Leaving this service enabled may expose the system to
+/*     privilege-escalation attacks.\fR
+/*
+/*     The nbdb_reindexd(8) server handles requests to generate
+/*     a non-Berkeley-DB indexed database file for an existing Berkeley
+/*     DB database (example: "hash:/path/to/file" or
+/*     "btree:/path/to/file"). It implements the service by running
+/*     the postmap(1) or postalias(1) command with appropriate
+/*     privileges.
+/*
+/*     The service reports a success status when the non-Berkeley-DB
+/*     indexed file already exists. This can happen when multiple clients
+/*     make the same request. When one request is completed successfully,
+/*     the service also reports success for the other requests.
+/*
+/*     This service enforces the following safety policy:
+/* .IP \(bu
+/*     The legacy Berkeley DB indexed file must exist (file name ends in
+/*     ".db"). The nbdb_reindexd(8) service will use the owner"s (uid,
+/*     gid) of this file, when it runs postmap(1) or postalias(1). It
+/*     also uses the (uid,gid) for a number of safety checks as
+/*     described next.
+/* .IP \(bu
+/*     The non-indexed source file must exist (file name without
+/*     ".db"  suffix). This file is needed as input for postmap(1)
+/*     or postalias(1). The file must be owned by "root" or by the
+/*     above uid, and must not allow "group" or "other" write access.
+/* .IP \(bu
+/*     The parent directory must be owned by "root" or by the above uid,
+/*     and it must not allow "group" or "other" write access.
+/* .IP \(bu
+/*     Additionally, the "non_bdb_migration_allow_root_prefixes"
+/*     parameter limits the source file directory prefixes that are
+/*     allowed when this service needs to run postmap(1) or postalias(1)
+/*     with "root" privileges.
+/* .IP \(bu
+/*     A similar parameter, "non_bdb_migration_allow_user_prefixes",
+/*     limits the source file directory prefixes that are allowed when
+/*     this service needs to run postmap(1) or postalias(1) as an
+/*     unprivileged user.
+/* SECURITY
+/* .ad
+/* .fi
+/*     The nbdb_reindexd(8) server is security sensitive.  It accepts
+/*     requests only from processes that can access sockets under
+/*     $queue_directory/private (i.e., processes that run with "root"
+/*     or "mail_owner" (usually, postfix) privileges).
+/*
+/*     The threat is therefore a corrupted Postfix daemon process that
+/*     wants to elevate privileges, by sending requests with crafted
+/*     pathnames, and racing against the service by quickly swapping
+/*     files or directories, hoping that Postfix will be tricked to
+/*     overwrite a sensitive file with attacker-controlled data.
+/*
+/*     When the service runs postmap(1) or postalias(1) as
+/*     "root", such racing attacks should not be possible if
+/*     non_bdb_migration_allow_root_prefixes specifies only prefixes
+/*     that are already trusted.
+/*
+/*     This service could block all requests with crafted pathnames,
+/*     if given complete information about all lookup tables that are
+/*     referenced through Postfix configuration files. Unfortunately
+/*     that information was not available at the time that this program
+/*     was needed.
+/* DIAGNOSTICS
+/*     Problems and transactions are logged to syslogd(8) or
+/*     postlogd(8). If an attempt to create an index file fails, this
+/*     service will attempt to delete the incomplete file.
+/* CONFIGURATION PARAMETERS
+/* .ad
+/* .fi
+/*     Changes to main.cf are not picked up automatically, as
+/*     nbdb_reindexd(8) processes are long-lived. Use the command
+/*     "postfix reload" after a configuration change.
+/*
+/*     The text below provides only a parameter summary. See
+/*     postconf(5) for more details including examples.
+/* SERVICE-SPECIFIC CONTROLS
+/* .ad
+/* .fi
+/* .IP "\fBnon_bdb_migration_level (disable)\fR"
+/*     The non-Berkeley-DB migration service level.
+/* .IP "\fBnon_bdb_migration_allow_root_prefixes (see 'postconf -d non_bdb_migration_allow_root_prefixes' output)\fR"
+/*     A list of trusted pathname prefixes that must be matched when
+/*     the non-Berkeley-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+/*     run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with "root" privilege.
+/* .IP "\fBnon_bdb_migration_allow_user_prefixes (see 'postconf -d non_bdb_migration_allow_user_prefixes' output)\fR"
+/*     A list of trusted pathname prefixes that must be matched when
+/*     the non-Berkeley-DB migration service (\fBnbdb_reindexd\fR(8)) needs to
+/*     run \fBpostmap\fR(1) or \fBpostalias\fR(1) commands with non-root privilege.
+/* MISCELLANEOUS CONTROLS
+/* .ad
+/* .fi
+/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+/*     The default location of the Postfix main.cf and master.cf
+/*     configuration files.
+/* .IP "\fBprocess_id (read-only)\fR"
+/*     The process ID of a Postfix command or daemon process.
+/* .IP "\fBprocess_name (read-only)\fR"
+/*     The process name of a Postfix command or daemon process.
+/* .IP "\fBsyslog_facility (mail)\fR"
+/*     The syslog facility of Postfix logging.
+/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
+/*     A prefix that is prepended to the process name in syslog
+/*     records, so that, for example, "smtpd" becomes "prefix/smtpd".
+/* .IP "\fBservice_name (read-only)\fR"
+/*     The master.cf service name of a Postfix daemon process.
+/* SEE ALSO
+/*     postfix-non-bdb(1), migration management
+/*     postconf(5), configuration parameters
+/*     postlogd(8), Postfix logging
+/*     syslogd(8), system logging
+/* README FILES
+/* .ad
+/* .fi
+/*     Use "\fBpostconf readme_directory\fR" or
+/*     "\fBpostconf html_directory\fR" to locate this information.
+/* .na
+/* .nf
+/*     NON_BERKELEYDB_README, Non-Berkeley-DB migration guide
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* HISTORY
+/* .ad
+/* .fi
+/*     This service was introduced with Postfix version 3.11.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+ /*
+  * Utility library.
+  */
+#include <attr.h>
+#include <msg.h>
+#include <set_eugid.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <wrap_stat.h>
+#include <split_at.h>
+#include <msg_vstream.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+#include <mail_params.h>
+#include <mail_proto.h>
+#include <mail_task.h>
+#include <mail_version.h>
+#include <nbdb_util.h>
+
+/* Single-threaded server skeleton. */
+
+#include <mail_server.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_index_as.h>
+#include <nbdb_process.h>
+#include <nbdb_reindexd.h>
+#include <nbdb_safe.h>
+#include <nbdb_sniffer.h>
+
+char   *var_nbdb_allow_root_pfxs;
+char   *var_nbdb_allow_user_pfxs;
+
+ALLOWED_PREFIX *parsed_allow_root_pfxs;
+ALLOWED_PREFIX *parsed_allow_user_pfxs;
+
+#define STR(x) vstring_str(x)
+
+/* nbdb_service - CLI or RPC protocol wrapper */
+
+static void nbdb_service(VSTREAM *stream, char *service, char **argv)
+{
+    static VSTRING *leg_type;
+    static VSTRING *source_path;
+    static VSTRING *why;
+    int     status;
+
+    if (leg_type == 0) {
+       leg_type = vstring_alloc(10);
+       source_path = vstring_alloc(100);
+       why = vstring_alloc(100);
+    } else {
+       VSTRING_RESET(why);
+       VSTRING_TERMINATE(why);
+    }
+
+    /*
+     * Command-line mode (a.k.a. stand-alone).
+     */
+    if (stream == VSTREAM_IN) {
+       char   *path;
+
+       msg_vstream_init(mail_task(var_procname), VSTREAM_ERR);
+       if (*argv == 0 || argv[1] != 0)
+           msg_fatal("stand-alone mode requires one type:/path argument");
+       vstring_strcpy(leg_type, *argv);
+       if ((path = split_at(STR(leg_type), ':')) == 0 || *path != '/')
+           msg_fatal("stand-alone mode called with bad argument: '%s'", *argv);
+       if ((status = nbdb_process(STR(leg_type), path, why)) != 0)
+           msg_warn("stand-alone request to re-index '%s:%s' failed: %s",
+                    STR(leg_type), path, STR(why));
+       exit(status != 0);
+    }
+
+    /*
+     * Daemon mode.
+     */
+    attr_print(stream, ATTR_FLAG_NONE,
+              SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_NBDB_REINDEX),
+              ATTR_TYPE_END);
+    if (attr_scan(stream, ATTR_FLAG_STRICT,
+                 RECV_ATTR_STR(MAIL_ATTR_NBDB_TYPE, leg_type),
+                 RECV_ATTR_STR(MAIL_ATTR_NBDB_PATH, source_path),
+                 ATTR_TYPE_END) != 2)
+       return;
+    status = nbdb_process(STR(leg_type), STR(source_path), why);
+    if (status != NBDB_STAT_OK)
+       msg_warn("request to index %s:%s failed: %s",
+                STR(leg_type), STR(source_path), STR(why));
+    attr_print(stream, ATTR_FLAG_NONE,
+              SEND_ATTR_INT(MAIL_ATTR_STATUS, status),
+              SEND_ATTR_STR(MAIL_ATTR_WHY, STR(why)),
+              ATTR_TYPE_END);
+}
+
+/* post_init - late initialization */
+
+static void post_init(char *unused_name, char **unused_argv)
+{
+
+    /*
+     * Drop root privileges most of the time. Modern UNIX-like systems will
+     * prevent a process with mail_owner privs from manipulating this process
+     * which still runs with a real uid of root.
+     */
+    set_eugid(var_owner_uid, var_owner_gid);
+
+    /*
+     * Initialize the allowed pathname prefix matcher.
+     */
+    parsed_allow_root_pfxs = allowed_prefix_create(var_nbdb_allow_root_pfxs);
+    parsed_allow_user_pfxs = allowed_prefix_create(var_nbdb_allow_user_pfxs);
+
+    /*
+     * TODO(wietse) alternatively, maybe run "proxymap -Sndump-xxxx" commands
+     * while privileged, so that the result cannot be manipulated by a
+     * compromised non-root process. Unfortunately, proxymap still does find
+     * lookup tables in "domain" matchlists of LDAP, SQL, etc. clients.
+     */
+}
+
+ /*
+  * Fingerprint executables and core dumps.
+  */
+MAIL_VERSION_STAMP_DECLARE;
+
+int     main(int argc, char **argv)
+{
+
+    /*
+     * var_nbdb_enable and var_nbdb_cust_map are used in many programs,
+     * therefore they are managed by mail_params.c.
+     */
+    static const CONFIG_STR_TABLE str_table[] = {
+       VAR_NBDB_ALLOW_ROOT_PFXS, DEF_NBDB_ALLOW_ROOT_PFXS, &var_nbdb_allow_root_pfxs, 0, 0,
+       VAR_NBDB_ALLOW_USER_PFXS, DEF_NBDB_ALLOW_USER_PFXS, &var_nbdb_allow_user_pfxs, 0, 0,
+       0,
+    };
+
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
+    /*
+     * Disable sending database reindexing requests.
+     */
+    nbdb_reindexing_lockout = true;
+
+    single_server_main(argc, argv, nbdb_service,
+                      CA_MAIL_SERVER_STR_TABLE(str_table),
+                      CA_MAIL_SERVER_POST_INIT(post_init),
+                      CA_MAIL_SERVER_PRIVILEGED,
+                      CA_MAIL_SERVER_SOLITARY,
+                      0);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_reindexd.h b/postfix/src/nbdb_reindexd/nbdb_reindexd.h
new file mode 100644 (file)
index 0000000..9bf752e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _NBDB_REINDEXD_H_INCLUDED_
+#define _NBDB_REINDEXD_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_reindexd.h 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_reindexd.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+
+ /*
+  * Internal API.
+  */
+extern ALLOWED_PREFIX *parsed_allow_root_pfxs;
+extern ALLOWED_PREFIX *parsed_allow_user_pfxs;
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/nbdb_reindexd/nbdb_safe.c b/postfix/src/nbdb_reindexd/nbdb_safe.c
new file mode 100644 (file)
index 0000000..621f5e6
--- /dev/null
@@ -0,0 +1,164 @@
+/*++
+/* NAME
+/*     nbdb_safe 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_safe.h>
+/*
+/*     bool    nbdb_safe_for_uid(
+/*     uid_t   uid,
+/*     const struct stat *st)
+/*
+/*     bool    nbdb_safe_to_index_as_legacy_index_owner(
+/*     const char *source_path,
+/*     const struct stat *source_st,
+/*     const char *leg_idx_path,
+/*     const struct stat *leg_idx_st,
+/*     const char *parent_dir,
+/*     const struct stat *parent_dir_st,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     nbdb_safe_for_uid() determines if the file or directory properties
+/*     in "st" are safe for a process that runs with "uid". That is,
+/*     the file or directory is owned "root" or by "uid", and does not
+/*     allow 'group' or 'other' write access.  This predicate ignores
+/*     the safety of other pathname components. It is a good idea to
+/*     trust only a limited number of pathname prefixes.
+/*
+/*     nbdb_safe_to_index_as_legacy_index_owner() determines
+/*     if a Berkeley DB source file and parent directory are 'safe'
+/*     for the uid of the Berkeley DB indexed file.
+/* .PP
+/*     Arguments:
+/* .IP source_path, source_st
+/*     Berkeley DB source file pathname and metadata.
+/*  .IP leg_idx_path, leg_idx_st
+/*     Berkeley DB indexed file pathname and metadata.
+/* .IP parent_dir, parent_dir_st
+/*     Parent directory pathname and metadata.
+/* .IP why
+/*     Storage that is updated with an applicable error description.
+/* SEE ALSO
+/*     nbdb_sniffer_test(1t), unit test
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <sys/stat.h>
+
+ /*
+  * Utility library.
+  */
+#include <wrap_stat.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+#include <mail_conf.h>
+#include <mail_params.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_safe.h>
+#include <nbdb_reindexd.h>
+
+/* nbdb_safe_for_uid - owned by the user or root, not group or other writable */
+
+bool    nbdb_safe_for_uid(uid_t uid, const struct stat *st)
+{
+
+    /*
+     * This "safe for" predicate is weaker than the one used in by Chari et
+     * al. in "Where do you want to go today?", which checks every pathname
+     * component (including pathname components in symlink targets). For this
+     * reason, the root user must have additional constraints on the pathname
+     * prefix.
+     */
+    return ((st->st_uid == 0 || uid == st->st_uid)
+           && (st->st_mode & (S_IWGRP | S_IWOTH)) == 0);
+}
+
+/* nbdb_safe_to_index_as_legacy_index_owner - OK to run postmap/postalias */
+
+bool    nbdb_safe_to_index_as_legacy_index_owner(
+                     const char *source_path, const struct stat *source_st,
+                   const char *leg_idx_path, const struct stat *leg_idx_st,
+                  const char *parent_dir, const struct stat *parent_dir_st,
+                                                        VSTRING *why)
+{
+    uid_t   runas_uid;
+
+    /*
+     * Run postmap or postalias as the legacy indexed file owner, if the
+     * source file, legacy indexed file, and parent directory are safe for
+     * that user, with pathname constraints for 'root' or non-root.
+     */
+    runas_uid = leg_idx_st->st_uid;
+
+    /*
+     * Allow root-privileged execution only for authorized pathnames. This
+     * prevents a corrupted Postfix daemon from submitting requests with
+     * pathnames that appear to be owned by root, under a directory that is
+     * in part under their control, and then run a race attack against us.
+     */
+    if (runas_uid == 0) {
+       if (!allowed_prefix_match(parsed_allow_root_pfxs, source_path)) {
+           vstring_sprintf(why, "table %s has an unexpected pathname; to "
+                           "allow automatic indexing as root, append its "
+                           "parent directory to the '%s' setting "
+                           "(current setting is: \"%s\")",
+                           source_path, VAR_NBDB_ALLOW_ROOT_PFXS,
+                           var_nbdb_allow_root_pfxs);
+           return (false);
+       }
+    } else {
+       if (!allowed_prefix_match(parsed_allow_user_pfxs, source_path)) {
+           vstring_sprintf(why, "table %s has an unexpected pathname; to "
+                        "allow automatic indexing as non-root, append its "
+                           "parent directory to the '%s' setting "
+                           "(current setting is: \"%s\")",
+                           source_path, VAR_NBDB_ALLOW_USER_PFXS,
+                           var_nbdb_allow_user_pfxs);
+           return (false);
+       }
+    }
+
+    /*
+     * Allow automated indexing only if the source file and parent directory
+     * are not writable by other users.
+     */
+    if (!nbdb_safe_for_uid(runas_uid, source_st)) {
+       vstring_sprintf(why, "legacy indexed file '%s' is owned by "
+                       "uid '%d', but source file '%s' is owned or "
+                       "writable by other user; to allow automatic "
+                       "indexing, correct the ownership or permissions",
+                       leg_idx_path, (int) runas_uid, source_path);
+       return (false);
+    }
+    if (!nbdb_safe_for_uid(runas_uid, parent_dir_st)) {
+       vstring_sprintf(why, "legacy indexed file '%s' is owned by "
+                       "uid '%d', but parent directory '%s' is "
+                       "owned or writable by other user; to allow "
+                       "automatic indexing, correct the ownership or"
+                       "permissions", leg_idx_path, (int) runas_uid,
+                       parent_dir);
+       return (false);
+    }
+
+    /*
+     * No objections.
+     */
+    return (true);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_safe.h b/postfix/src/nbdb_reindexd/nbdb_safe.h
new file mode 100644 (file)
index 0000000..754d3e7
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef _NBDB_SAFE_H_INCLUDED_
+#define _NBDB_SAFE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_safe.h 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_safe.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <sys/stat.h>
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * Internal API.
+  */
+extern bool nbdb_safe_for_uid(uid_t, const struct stat *);
+extern bool nbdb_safe_to_index_as_legacy_index_owner(
+                                         const char *, const struct stat *,
+                                         const char *, const struct stat *,
+                                         const char *, const struct stat *,
+                                                            VSTRING *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/nbdb_reindexd/nbdb_safe_test.c b/postfix/src/nbdb_reindexd/nbdb_safe_test.c
new file mode 100644 (file)
index 0000000..91b7801
--- /dev/null
@@ -0,0 +1,358 @@
+/*++
+/*     nbdb_safe_test 1t
+/* SUMMARY
+/*     nbdb_safe unit test
+/* SYNOPSIS
+/*     ./nbdb_safe_test
+/* DESCRIPTION
+/*     nbdb_safe_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <msg_vstream.h>
+#include <stringops.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <allowed_prefix.h>
+#include <mail_conf.h>
+#include <mail_params.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_safe.h>
+
+ /*
+  * Scaffolding.
+  */
+ALLOWED_PREFIX *parsed_allow_root_pfxs;
+ALLOWED_PREFIX *parsed_allow_user_pfxs;
+
+char   *var_nbdb_allow_root_pfxs;
+char   *var_nbdb_allow_user_pfxs;
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+ /*
+  * Test structure.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+    bool    want_bool;
+    /* nbdb_safe_for_uid inputs. */
+    uid_t   uid;
+    struct stat st;
+    /* nbdb_safe_to_index_as_legacy_index_owner inputs. */
+    const char *source_path;
+    struct stat source_st;
+    const char *leg_idx_path;
+    struct stat leg_idx_st;
+    const char *parent_dir;
+    struct stat parent_dir_st;
+    const char *allow_root_pfxs;
+    const char *allow_user_pfxs;
+    const char *want_why;
+} TEST_CASE;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+/* test_nbdb_safe_for_uid - single-line vote */
+
+static int test_nbdb_safe_for_uid(const TEST_CASE *tp)
+{
+    bool    got_bool;
+
+    /* Run the code under test. */
+    got_bool = nbdb_safe_for_uid(tp->uid, &tp->st);
+
+#define bool_to_text(b) ((b) ? "true" : "false")
+
+    /* Verify the result. */
+    if (got_bool != tp->want_bool) {
+       msg_warn("got result: `%s', want `%s''",
+                bool_to_text(got_bool), bool_to_text(tp->want_bool));
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+/* test_nbdb_safe_to_index_as_legacy_index_owner - majority vote */
+
+static int test_nbdb_safe_to_index_as_legacy_index_owner(const TEST_CASE *tp)
+{
+    static VSTRING *got_why;
+    bool    got_bool;
+
+    if (got_why == 0)
+       got_why = vstring_alloc(100);
+
+    /* Run the code under test. */
+    VSTRING_RESET(got_why);
+    var_nbdb_allow_root_pfxs = (char *) tp->allow_root_pfxs;
+    var_nbdb_allow_user_pfxs = (char *) tp->allow_user_pfxs;
+    parsed_allow_root_pfxs = allowed_prefix_create(var_nbdb_allow_root_pfxs);
+    parsed_allow_user_pfxs = allowed_prefix_create(var_nbdb_allow_user_pfxs);
+    got_bool = nbdb_safe_to_index_as_legacy_index_owner(
+                                           tp->source_path, &tp->source_st,
+                                         tp->leg_idx_path, &tp->leg_idx_st,
+                                        tp->parent_dir, &tp->parent_dir_st,
+                                                       got_why);
+    allowed_prefix_free(parsed_allow_root_pfxs);
+    allowed_prefix_free(parsed_allow_user_pfxs);
+
+#define STR_OR_NULL(s) (((s) && *(s)) ? (s) : "(null)")
+
+    /* Verify the result. */
+    if (!LEN(got_why) != !tp->want_why) {
+       msg_warn("got warning: '%s', want: %s",
+                STR_OR_NULL(STR(got_why)), STR_OR_NULL(tp->want_why));
+       return (FAIL);
+    }
+    if (tp->want_why && strstr(STR(got_why), tp->want_why) == 0) {
+       msg_warn("got warning: '%s', want: '%s'",
+                STR(got_why), tp->want_why);
+       return (FAIL);
+    }
+    if (got_bool != tp->want_bool) {
+       msg_warn("got result: '%s', want: '%s'",
+                bool_to_text(got_bool), bool_to_text(tp->want_bool));
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+ /*
+  * The list of test cases.
+  * 
+  * TODO(wietse) Almost all tests take a 'good' test case and make one small
+  * mutation. Figure out a way to mutate a copy of a 'good' test cases, and
+  * store only the delta. That would make tests much more readable.
+  */
+static const TEST_CASE test_cases[] = {
+
+    /*
+     * nbdb_safe_for_uid tests.
+     */
+    {.label = "test_safe_for_root:good_configuration",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 0,.st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .want_bool = true,
+    },
+    {.label = "test_safe_for_root:not_owned_by_root",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 0,.st = {.st_uid = 1,.st_mode = S_IRWXU,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_root:group_writable",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 0,.st = {.st_uid = 0,.st_mode = S_IWGRP,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_root:other_writable",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 0,.st = {.st_uid = 0,.st_mode = S_IWOTH,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_non_root:good_root_owned_configuration",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .want_bool = true,
+    },
+    {.label = "test_safe_for_non_root:good_user_owned_configuration",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 1,.st_mode = S_IRWXU,},
+       .want_bool = true,
+    },
+    {.label = "test_safe_for_non_root:root_owned_group_write",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 0,.st_mode = S_IWGRP,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_non_root:root_owned_other_write",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 0,.st_mode = S_IWOTH,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_non_root:user_owned_group_write",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 1,.st_mode = S_IWGRP,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_non_root:user_owned_other_write",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 1,.st_mode = S_IWOTH,},
+       .want_bool = false,
+    },
+    {.label = "test_safe_for_non_root:other_owned",
+       .action = test_nbdb_safe_for_uid,
+       .uid = 1,.st = {.st_uid = 2,.st_mode = 0,},
+       .want_bool = false,
+    },
+
+    /*
+     * The above tests cover all nbdb_safe_for_uid code paths. The tests
+     * below do not need to cover all those code paths again, just enough to
+     * demonstrate that nbdb_safe_to_index_as_legacy_index_owner() will
+     * propagate nbdb_safe_for_uid() results properly.
+     */
+
+    /* nbdb_safe_to_index_as_legacy_index_owner tests. */
+    {.label = "safe_to_index_as_root:good_configuration",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = true,
+    },
+    /* nbdb_safe_to_index_as_legacy_index_owner tests. */
+    {.label = "safe_to_index_as_root:bad_pathname_prefix",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/posttfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "table /etc/postfix/access has an unexpected pathname",
+    },
+    {.label = "safe_to_index_as_root:bad_source_owner",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 1,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix/access' is owned or writable by other user",
+    },
+    {.label = "safe_to_index_as_root:source_group_write",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IWGRP,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix/access' is owned or writable by other user",
+    },
+    {.label = "safe_to_index_as_root:source_other_write",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IWOTH,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix/access' is owned or writable by other user",
+    },
+    {.label = "safe_to_index_as_root:bad_parent_owner",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 1,.st_mode = S_IRWXU,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix' is owned or writable by other user",
+    },
+    {.label = "safe_to_index_as_root:parent_group_write",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IWGRP,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix' is owned or writable by other user",
+    },
+    {.label = "safe_to_index_as_root:parent_other_write",
+       .action = test_nbdb_safe_to_index_as_legacy_index_owner,
+       .source_path = "/etc/postfix/access",
+       .source_st = {.st_uid = 0,.st_mode = S_IRWXU,},
+       .leg_idx_path = "/etc/postfix/access.db",
+       .leg_idx_st = {.st_uid = 0,},
+       .parent_dir = "/etc/postfix",
+       .parent_dir_st = {.st_uid = 0,.st_mode = S_IWOTH,},
+       .allow_root_pfxs = "/etc/postfix",
+       .allow_user_pfxs = "",
+       .want_bool = false,
+       .want_why = "'/etc/postfix' is owned or writable by other user",
+    },
+    /* TODO(wietse) tests for non-root user. */
+
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_sniffer.c b/postfix/src/nbdb_reindexd/nbdb_sniffer.c
new file mode 100644 (file)
index 0000000..adf0add
--- /dev/null
@@ -0,0 +1,223 @@
+/*++
+/* NAME
+/*     nbdb_sniffer 3
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_sniffer.h>
+/*
+/*     bool    nbdb_parse_as_postmap(VSTRING *line_buffer)
+/*
+/*     bool    nbdb_parse_as_postalias(VSTRING *line_buffer)
+/*
+/*     const char *nbdb_get_index_cmd_as(
+/*     const char *source_path,
+/*     uid_t   uid,
+/*     gid_t   gid,
+/*     VSTRING *why)
+/* DESCRIPTION
+/*     nbdb_parse_as_postmap() determines if a text line buffer contains
+/*     valid input for the "postmap" command. nbdb_parse_as_postalias()
+/*     does a similar thing for "postalias". Both functions modify
+/*     their input.
+/*
+/*     nbdb_get_index_cmd_as() examines the first handful lines of an
+/*     Berkeley DB source file, and returns "postmap", "postalias",
+/*     or null in case of a file open error.
+/* .PP
+/*     Arguments:
+/* .IP line_buffer
+/*     The input sample. This will be parsed destructively.
+/*  .IP source_path
+/*     Berkeley DB source file pathname.
+/* .IP uid, gid
+/*     The privileges used for opening the Berkeley DB source file.
+/* .IP why
+/*     Storage that is updated with an applicable error description.
+/* SEE ALSO
+/*     nbdb_sniffer_test(1t), unit test
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <ctype.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <open_as.h>
+#include <readlline.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+#include <nbdb_util.h>
+#include <tok822.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_reindexd.h>
+#include <nbdb_sniffer.h>
+
+#define STR(x) vstring_str(x)
+
+/* nbdb_parse_as_postmap - sniff a source line and parse as key space value */
+
+bool    nbdb_parse_as_postmap(VSTRING *line_buffer)
+{
+    int     in_quotes = 0;
+    char   *key;
+    char   *value;
+
+    /*
+     * Split on the first whitespace character, then trim leading and
+     * trailing whitespace from key and value. Note that postalias does not
+     * require a space after the ':'.
+     */
+    for (value = STR(line_buffer); *value; value++) {
+       if (*value == '\\') {
+           if (*++value == 0)
+               break;
+       } else if (ISSPACE(*value)) {
+           if (!in_quotes)
+               break;
+       } else if (*value == '"') {
+           in_quotes = !in_quotes;
+       }
+    }
+
+    /*
+     * Keys should not contain an unbalanced double quote (input that is
+     * skipped by postmap and dict_thash).
+     */
+    if (in_quotes)
+       return (false);
+    if (*value)
+       *value++ = 0;
+    while (ISSPACE(*value))
+       value++;
+    trimblanks(value, 0)[0] = 0;
+    key = STR(line_buffer);
+
+    /*
+     * Input should be in "key whitespace value" form (other input is skipped
+     * by postmap and dict_thash). Empty keys are not allowed because some
+     * lookup tables did not support that. Additionally, the Postfix lookup
+     * table API does not allow empty values. Instead, programs are supposed
+     * to return a "not found" result.
+     */
+    if (*key == 0 || *value == 0)
+       return (false);
+
+    /*
+     * Postmap and dict_thash accept keys ending in ':' but also log
+     * warnings. Flag keys as 'postmap' format only if we have positive
+     * evidence of well-formed input.
+     */
+    if (key[strlen(key) - 1] == ':')
+       return (false);
+
+    return (true);
+}
+
+/* nbdb_parse_as_postalias - sniff a source line and parse as key ':' value */
+
+bool    nbdb_parse_as_postalias(VSTRING *line_buffer)
+{
+    TOK822 *tok_list;
+    TOK822 *colon;
+    bool    retval;
+
+    /*
+     * The postalias format requires a ':' between key and value. Do a quick
+     * check to eliminate obvious cases without actually parsing the input.
+     */
+    if (strchr(STR(line_buffer), ':') == 0)
+       return (false);
+
+    /*
+     * Tokenize the input, so that we do the right thing when a quoted
+     * localpart contains special characters such as ":" and so on.
+     */
+    if ((tok_list = tok822_scan(STR(line_buffer), (TOK822 **) 0)) == 0)
+       return (false);
+
+    /*
+     * Enforce the key:value format. Disallow missing keys, multi-address
+     * keys, or missing values. In order to specify an empty string or value,
+     * enclose it in double quotes. Note: postalias format does not require
+     * space after ':'.
+     */
+    retval = !((colon = tok822_find_type(tok_list, ':')) == 0
+              || colon->prev == 0 || colon->next == 0
+              || tok822_rfind_type(colon, ','));
+    tok822_free_tree(tok_list);
+    return (retval);
+}
+
+/* get_index_cmd_as - sniff the table format: postmap, or postalias, or error */
+
+const char *nbdb_get_index_cmd_as(const char *source_path, uid_t uid, gid_t gid,
+                                         VSTRING *why)
+{
+    VSTREAM *fp;
+
+    /*
+     * Some lookup tables may contain sensitive information (passwords, etc.)
+     * and should not be world-readable. If a process with index owner
+     * privilege cannot open this source file, then it also cannot index this
+     * table with the postmap or postalias command.
+     */
+    if ((fp = vstream_fopen_as(source_path, O_RDONLY, 0, uid, gid)) == 0) {
+       vstring_sprintf(why, "open lookup table source file %s as uid=%d "
+                       "gid=%d: %m", source_path, (int) uid, (int) gid);
+       return (0);
+    } else {
+       VSTRING *line_buffer = vstring_alloc(100);
+       VSTRING *copy = vstring_alloc(100);
+       int     postmap_score = 0;
+       int     postalias_score = 0;
+
+       /*
+        * TODO(wietse) Eliminating 'format sniffing' code would require
+        * matching the source_path against the values of $alias_maps and
+        * $alias_database for every master.cf service. Such information is
+        * available from postconf(1).
+        */
+#define NO_LINENO      ((int *) 0)
+#define NO_LAST_LINE   ((int *) 0)
+
+       while (readllines(line_buffer, fp, NO_LINENO, NO_LAST_LINE)) {
+           vstring_strcpy(copy, STR(line_buffer));
+           if (nbdb_parse_as_postmap(copy))
+               postmap_score += 1;
+           if (nbdb_parse_as_postalias(line_buffer))
+               postalias_score += 1;
+           if (postmap_score + postalias_score == 10)
+               break;
+       }
+       vstream_fclose(fp);
+       vstring_free(line_buffer);
+       vstring_free(copy);
+       if (postalias_score > postmap_score)
+           return "postalias";
+       else
+           return ("postmap");
+    }
+}
diff --git a/postfix/src/nbdb_reindexd/nbdb_sniffer.h b/postfix/src/nbdb_reindexd/nbdb_sniffer.h
new file mode 100644 (file)
index 0000000..296727f
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _NBDB_SNIFFER_H_INCLUDED_
+#define _NBDB_SNIFFER_H_INCLUDED_
+
+/*++
+/* NAME
+/*     nbdb_sniffer.h 3h
+/* SUMMARY
+/*     Non-Berkeley-DB migration service
+/* SYNOPSIS
+/*     #include <nbdb_sniffer.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <unistd.h>
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+
+ /*
+  * Internal API.
+  */
+extern bool nbdb_parse_as_postmap(VSTRING *);
+extern bool nbdb_parse_as_postalias(VSTRING *);
+const char *nbdb_get_index_cmd_as(const char *, uid_t, gid_t, VSTRING *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/nbdb_reindexd/nbdb_sniffer_test.c b/postfix/src/nbdb_reindexd/nbdb_sniffer_test.c
new file mode 100644 (file)
index 0000000..f418d33
--- /dev/null
@@ -0,0 +1,331 @@
+/*++
+/* NAME
+/*     nbdb_sniffer_test 1t
+/* SUMMARY
+/*     nbdb_sniffer unit test
+/* SYNOPSIS
+/*     ./nbdb_sniffer_test
+/* DESCRIPTION
+/*     nbdb_sniffer_test runs and logs each configured test, reports if
+/*     a test is a PASS or FAIL, and returns an exit status of zero if
+/*     all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <msg_vstream.h>
+#include <open_as.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+
+ /*
+  * Testing library.
+  */
+#include <mock_open_as.h>
+
+ /*
+  * Application-specific.
+  */
+#include <nbdb_sniffer.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+ /*
+  * Test structure. Some tests may bring their own.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+
+    /*
+     * nbdb_parse_as_xxx() inputs and expectations.
+     */
+    struct {
+       const char *in_line;
+       bool    out_want_postmap;
+       bool    out_want_postalias;
+    }       parse_as;
+
+    /*
+     * nbdb_get_index_cmd_as() mock dependencies.
+     */
+    MOCK_OPEN_AS_REQ mock_open;
+
+    /*
+     * nbdb_get_index_cmd_as() inputs and expectations.
+     */
+    struct {
+       const char *in_path;
+       uid_t   in_uid;
+       gid_t   in_gid;
+       const char *want_cmd;
+       const char *want_why;
+       int     want_errno;
+    }       index_cmd;
+} TEST_CASE;
+
+#define PASS    (0)
+#define FAIL    (1)
+
+/* test_parse_line - single-line vote */
+
+static int test_parse_line(const TEST_CASE *tp)
+{
+    bool    got_postmap, got_postalias;
+    VSTRING *buffer;
+
+    buffer = vstring_alloc(strlen(tp->parse_as.in_line));
+    vstring_strcpy(buffer, tp->parse_as.in_line);
+    got_postmap = nbdb_parse_as_postmap(buffer);
+
+    vstring_strcpy(buffer, tp->parse_as.in_line);
+    got_postalias = nbdb_parse_as_postalias(buffer);
+    vstring_free(buffer);
+
+#define bool_to_text(b) ((b) ? "true" : "false")
+
+    /* Verify the results. */
+    if (got_postmap != tp->parse_as.out_want_postmap) {
+       msg_warn("got postmap: `%s', want `%s''",
+                bool_to_text(got_postmap),
+                bool_to_text(tp->parse_as.out_want_postmap));
+       return (FAIL);
+    }
+    if (got_postalias != tp->parse_as.out_want_postalias) {
+       msg_warn("got postalias: `%s', want `%s''",
+                bool_to_text(got_postalias),
+                bool_to_text(tp->parse_as.out_want_postalias));
+       return (FAIL);
+    }
+    return (PASS);
+}
+
+/* test_index_command - multi-line vote */
+
+static int test_index_command(const TEST_CASE *tp)
+{
+    static VSTRING *msg_buf;
+    static VSTRING *got_why;
+    const char *got_cmd;
+
+    if (msg_buf == 0) {
+       msg_buf = vstring_alloc(100);
+       got_why = vstring_alloc(100);
+    }
+    /* Run the test with fake file data. */
+    VSTRING_RESET(got_why);
+    setup_mock_vstream_fopen_as(&tp->mock_open);
+    got_cmd = nbdb_get_index_cmd_as(tp->index_cmd.in_path,
+                                   tp->index_cmd.in_uid,
+                                   tp->index_cmd.in_gid,
+                                   got_why);
+
+#define CMD_OR_NULL(s) ((s) ? (s) : "(null)")
+
+    /* Verify the results. */
+    if (!got_cmd != !tp->index_cmd.want_cmd) {
+       msg_warn("got command: `%s', want `%s''",
+                CMD_OR_NULL(got_cmd), CMD_OR_NULL(tp->index_cmd.want_cmd));
+       return (FAIL);
+    }
+    if (tp->index_cmd.want_cmd == 0) {
+       if (LEN(got_why) == 0
+           || strstr(STR(got_why), tp->index_cmd.want_why) == 0) {
+           msg_warn("got warning: '%s', want: '%s'",
+                    STR(got_why), tp->index_cmd.want_why);
+           return (FAIL);
+       }
+       if (tp->index_cmd.want_errno != errno) {
+           msg_warn("got errno: '%s', want: '%s'",
+                    strerror(errno), strerror(tp->index_cmd.want_errno));
+           return (FAIL);
+       }
+    } else {
+       if (tp->index_cmd.want_errno != 0)
+           msg_panic("want non-null result AND errno=%d",
+                     tp->index_cmd.want_errno);
+       if (strcmp(got_cmd, tp->index_cmd.want_cmd) != 0) {
+           msg_warn("got command ``%s'', want ``%s''",
+                    got_cmd, tp->index_cmd.want_cmd);
+           return (FAIL);
+       }
+    }
+    return (PASS);
+}
+
+ /*
+  * The list of test cases.
+  */
+static const TEST_CASE test_cases[] = {
+
+    /*
+     * Line-level tests.
+     */
+    {.label = "key_space_value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "foo bar",
+           .out_want_postmap = true,
+           .out_want_postalias = false,
+       },
+    },
+    {.label = "colon_in_quoted_key_space_text",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "\"foobar:\" baz",
+           .out_want_postmap = true,
+           .out_want_postalias = false,
+       },
+    },
+    {.label = "quoted_key_colon_value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "\"foo bar\":baz",
+           .out_want_postmap = false,
+           .out_want_postalias = true,
+       },
+    },
+    {.label = "key_space_colon_text",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "foo :bar",
+           .out_want_postmap = true,
+           .out_want_postalias = true,
+       },
+    },
+    {.label = "key_colon_value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "foo:bar",
+           .out_want_postmap = false,
+           .out_want_postalias = true,
+       },
+    },
+    {.label = "colon_value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = ":bar",
+           .out_want_postmap = false,
+           .out_want_postalias = false,
+       },
+    },
+    {.label = "key_without value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "bar",
+           .out_want_postmap = false,
+           .out_want_postalias = false,
+       },
+    },
+    {.label = "key_colon_without value",
+       .action = test_parse_line,
+       .parse_as = {
+           .in_line = "bar:",
+           .out_want_postmap = false,
+           .out_want_postalias = false,
+       },
+    },
+
+    /*
+     * File-level tests (multiple lines with majority voting).
+     */
+    {.label = "file_open_error_enoent",
+       .action = test_index_command,
+       .index_cmd = {
+           .in_path = "path/to/file",
+           .want_why = "open lookup table source file",
+           .want_errno = ENOENT,
+       },
+       .mock_open = {
+           .want_path = "path/to/file",
+           .out_data = 0,
+           .out_errno = ENOENT,
+       },
+    },
+    {.label = "file_open_error_eacces",
+       .action = test_index_command,
+       .index_cmd = {
+           .in_path = "path/to/file",
+           .in_uid = 1,
+           .want_why = "open lookup table source file",
+           .want_errno = EACCES,
+       },
+       .mock_open = {
+           .want_path = "path/to/file",
+           .want_uid = 1,
+           .out_errno = EACCES,
+       },
+    },
+    {.label = "mostly_postmap",
+       .action = test_index_command,
+       .index_cmd = {
+           .in_path = "path/to/file",
+           .want_cmd = "postmap",
+       },
+       .mock_open = {
+           .want_path = "path/to/file",
+           .out_data = "foo:bar\nfoo bar\nfoo :bar",
+       },
+    },
+    {.label = "mostly_postalias",
+       .action = test_index_command,
+       .index_cmd = {
+           .in_path = "path/to/file",
+           .want_cmd = "postalias",
+       },
+       .mock_open = {
+           .want_path = "path/to/file",
+           .out_data = "foo:bar\n\"foo bar\":baz\nfoo :bar",
+       },
+    },
+
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    const TEST_CASE *tp;
+    int     pass = 0;
+    int     fail = 0;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label != 0; tp++) {
+       int     test_failed;
+
+       msg_info("RUN  %s", tp->label);
+       test_failed = tp->action(tp);
+       if (test_failed) {
+           msg_info("FAIL %s", tp->label);
+           fail++;
+       } else {
+           msg_info("PASS %s", tp->label);
+           pass++;
+       }
+    }
+    msg_info("PASS=%d FAIL=%d", pass, fail);
+    exit(fail != 0);
+}
index 710b3add094fcff5b47586b66e15592a33dd61f6..eff1efbd421975a00e14c34be91530f5cc189620 100644 (file)
 /*     The database type. To find out what types are supported, use
 /*     the "\fBpostconf -m\fR" command.
 /*
+/*     When no \fIfile_type\fR is specified, the software uses the database
+/*     type specified via the \fBdefault_database_type\fR configuration
+/*     parameter.
+/*     The default value for this parameter depends on the host environment.
+/*
 /*     The \fBpostalias\fR(1) command can query any supported file type,
 /*     but it can create only the following file types:
 /* .RS
 /*     The output consists of two files, named \fIfile_name\fB.pag\fR and
 /*     \fIfile_name\fB.dir\fR.
 /*     This is available on systems with support for \fBsdbm\fR databases.
-/* .PP
-/*     When no \fIfile_type\fR is specified, the software uses the database
-/*     type specified via the \fBdefault_database_type\fR configuration
-/*     parameter.
-/*     The default value for this parameter depends on the host environment.
 /* .RE
 /* .IP \fIfile_name\fR
 /*     The name of the alias database source file when creating a database.
index 92f93c848b450c460c152efb92c230aeb1d6f067..0904c5be76cc23f3f4e01e8a3cf42ef92b892b1e 100644 (file)
 /*     with the command specified with $maillog_file_compressor.
 /*     This will not rotate /dev/* files.
 /* .sp
-/*     This feature is available in Postfix 3.4 and later.
+/* .IP "\fBnon-bdb\fR \fIsubcommand\fR"
+/*     Migrate a Postfix configuration that uses Berkeley DB hash:
+/*     or btree: tables, to a configuration that uses lmdb: or a
+/*     combination of cdb: and lmdb:. This is needed because some
+/*     (Linux) distributions have removed Berkeley DB support.
+/*     See postfix-nbdb(1) for documentation.
+/* .sp
+/*     This feature is available in Postfix 3.11 and later.
 /* .IP "\fBtls\fR \fIsubcommand\fR"
 /*     Enable opportunistic TLS in the Postfix SMTP client or
 /*     server, and manage Postfix SMTP server TLS private keys and
 /*     postconf(1), Postfix configuration utility
 /*     postdrop(1), Postfix mail posting utility
 /*     postfix(1), Postfix control program
+/*     postfix-non-bdb(1), Postfix Non-Berkeley-DB migration
 /*     postfix-tls(1), Postfix TLS management
 /*     postkick(1), trigger Postfix daemon
 /*     postlock(1), Postfix-compatible locking
index eaecf319bc2e123c30ab3e03ab8b3d6610d20cfe..7b9c8e64ca049e9990c92e02bc9c8159a473da6b 100644 (file)
 /*     The database type. To find out what types are supported, use
 /*     the "\fBpostconf -m\fR" command.
 /*
+/*     When no \fIfile_type\fR is specified, the software uses the database
+/*     type specified via the \fBdefault_database_type\fR configuration
+/*     parameter.
+/*     The default value for this parameter depends on the host environment.
+/*
 /*     The \fBpostmap\fR(1) command can query any supported file type,
 /*     but it can create only the following file types:
 /* .RS
 /*     The output consists of two files, named \fIfile_name\fB.pag\fR and
 /*     \fIfile_name\fB.dir\fR.
 /*     This is available on systems with support for \fBsdbm\fR databases.
-/* .PP
-/*     When no \fIfile_type\fR is specified, the software uses the database
-/*     type specified via the \fBdefault_database_type\fR configuration
-/*     parameter.
 /* .RE
 /* .IP \fIfile_name\fR
 /*     The name of the lookup table source file when rebuilding a database.
index cbb6020a391d2a4cb231440c9f98876f87af599e..a1b05c2d545066dcbfb7ea5b062de3cf9f52fd84 100644 (file)
@@ -102,6 +102,10 @@ depend: $(MAKES)
        @$(EXPORT) make -f Makefile.in Makefile 1>&2
 
 # do not edit below this line - it is generated by 'make depend'
+fake_strcmp.o: ../../include/mail_params.h
+fake_strcmp.o: ../../include/msg.h
+fake_strcmp.o: ../../include/sys_defs.h
+fake_strcmp.o: fake_strcmp.c
 postmulti.o: ../../include/argv.h
 postmulti.o: ../../include/check_arg.h
 postmulti.o: ../../include/clean_env.h
index b4f0ed1f99da0810ad0ca2d5f51486bbbcade210..d058bc4deafd6ff3e1fde8335d807ba74218b432 100644 (file)
@@ -693,7 +693,7 @@ static void print_stack(STATE *state, x509_stack_t *sk, int trustout)
     for (i = 0; i < sk_X509_num(sk); i++) {
        X509   *cert = sk_X509_value(sk, i);
        char    buf[CCERT_BUFSIZ];
-       X509_NAME *xn;
+       const X509_NAME *xn;
        char   *digest;
 
        if ((xn = X509_get_subject_name(cert)) != 0) {
index 5b2eb1d52447ae726dd9bd8bfa229f0ab640f62c..62ff23ca2a3e5d4d4be5d8bd01dcd280bc5fe800 100644 (file)
@@ -552,7 +552,7 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
                       STR(iter->host));
            return (0);
        }
-       break;
+       break;
     case SMTP_REQTLS_POLICY_ACT_OPP_TLS:
        if (tls->level == TLS_LEV_NONE) {
            if (state->tls_stats)
index 0377886f1f72a3fc63a743295743ef89b35a4359..4534831c4747abbbdf55d751617d9b2a637f4f77 100644 (file)
@@ -1,9 +1,12 @@
 SHELL  = /bin/sh
-SRCS   = nosleep.c dict_test_helper.c
-LIB_OBJ        = dict_test_helper.o
+SRCS   = nosleep.c dict_test_helper.c mock_open_as.c mock_spawn_command.c \
+       mock_stat.c msg_capture.c mock_dict.c
+LIB_OBJ        = dict_test_helper.o mock_open_as.o mock_spawn_command.o \
+       mock_stat.o msg_capture.o mock_dict.o
 MOCK_OBJ=
 TEST_OBJ=
-HDRS   = dict_test_helper.h
+HDRS   = dict_test_helper.h mock_open_as.h mock_spawn_command.h \
+       mock_stat.h msg_capture.h mock_dict.h
 TESTSRC        =
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -87,4 +90,52 @@ dict_test_helper.o: ../../include/vstream.h
 dict_test_helper.o: ../../include/vstring.h
 dict_test_helper.o: dict_test_helper.c
 dict_test_helper.o: dict_test_helper.h
+mock_dict.o: ../../include/argv.h
+mock_dict.o: ../../include/check_arg.h
+mock_dict.o: ../../include/dict.h
+mock_dict.o: ../../include/dict_cdb.h
+mock_dict.o: ../../include/dict_inline.h
+mock_dict.o: ../../include/dict_lmdb.h
+mock_dict.o: ../../include/mkmap.h
+mock_dict.o: ../../include/myflock.h
+mock_dict.o: ../../include/mymalloc.h
+mock_dict.o: ../../include/sys_defs.h
+mock_dict.o: ../../include/vbuf.h
+mock_dict.o: ../../include/vstream.h
+mock_dict.o: ../../include/vstring.h
+mock_dict.o: mock_dict.c
+mock_dict.o: mock_dict.h
+mock_open_as.o: ../../include/check_arg.h
+mock_open_as.o: ../../include/msg.h
+mock_open_as.o: ../../include/open_as.h
+mock_open_as.o: ../../include/sys_defs.h
+mock_open_as.o: ../../include/vbuf.h
+mock_open_as.o: ../../include/vstream.h
+mock_open_as.o: ../../include/vstring.h
+mock_open_as.o: mock_open_as.c
+mock_open_as.o: mock_open_as.h
+mock_spawn_command.o: ../../include/check_arg.h
+mock_spawn_command.o: ../../include/msg.h
+mock_spawn_command.o: ../../include/spawn_command.h
+mock_spawn_command.o: ../../include/stringops.h
+mock_spawn_command.o: ../../include/sys_defs.h
+mock_spawn_command.o: ../../include/vbuf.h
+mock_spawn_command.o: ../../include/vstring.h
+mock_spawn_command.o: mock_spawn_command.c
+mock_spawn_command.o: mock_spawn_command.h
+mock_stat.o: ../../include/htable.h
+mock_stat.o: ../../include/msg.h
+mock_stat.o: ../../include/sys_defs.h
+mock_stat.o: ../../include/wrap_stat.h
+mock_stat.o: mock_stat.c
+mock_stat.o: mock_stat.h
+msg_capture.o: ../../include/check_arg.h
+msg_capture.o: ../../include/msg.h
+msg_capture.o: ../../include/mymalloc.h
+msg_capture.o: ../../include/sys_defs.h
+msg_capture.o: ../../include/vbuf.h
+msg_capture.o: ../../include/vstream.h
+msg_capture.o: ../../include/vstring.h
+msg_capture.o: msg_capture.c
+msg_capture.o: msg_capture.h
 nosleep.o: nosleep.c
diff --git a/postfix/src/testing/mock_dict.c b/postfix/src/testing/mock_dict.c
new file mode 100644 (file)
index 0000000..d3f56b7
--- /dev/null
@@ -0,0 +1,116 @@
+/*++
+/* NAME
+/*      mock_dict 3
+/* SUMMARY
+/*      mock tables
+/* SYNOPSIS
+/*      $include <mock_dict.h>
+/*
+/*     setup_mock_cdb(const char *name_payload)
+/*
+/*     setup_mock_lmdb(const char *name_payload)
+/* DESCRIPTION
+/*      setup_mock_cdb (or setup_mock_lmdb) instantiates a mock cdb
+/*      (or lmdb) table with a name_payload that uses inline: syntax.
+/* LICENSE
+/* .ad
+/* .fi
+/*      The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*      Wietse Venema
+/*      porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+#include <dict_cdb.h>
+#include <dict_inline.h>
+#include <dict_lmdb.h>
+#include <mkmap.h>
+#include <mymalloc.h>
+
+ /*
+  * Global library.
+  */
+
+ /*
+  * Testing library.
+  */
+#include <mock_dict.h>
+
+static char *mock_cdb_name_payload;
+
+static DICT *mock_dict_cdb_open(const char *dict_name, int open_flags,
+                                       int dict_flags)
+{
+    return (dict_open3(DICT_TYPE_INLINE, mock_cdb_name_payload,
+                      open_flags, dict_flags));
+}
+
+static MKMAP *mock_mkmap_cdb_open(const char *path)
+{
+    MKMAP  *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
+
+    mkmap->open = mock_dict_cdb_open;
+    mkmap->after_open = 0;
+    mkmap->after_close = 0;
+    return (mkmap);
+}
+
+static const DICT_OPEN_INFO mock_cdb_info = {
+    "cdb", mock_dict_cdb_open, mock_mkmap_cdb_open,
+};
+
+void    setup_mock_cdb(const char *name_payload)
+{
+    if (mock_cdb_name_payload != 0)
+       myfree(mock_cdb_name_payload);
+
+    mock_cdb_name_payload = mystrdup(name_payload);
+
+    if (dict_open_lookup(mock_cdb_info.type))
+       dict_open_unregister(mock_cdb_info.type);
+    dict_open_register(&mock_cdb_info);
+}
+
+static char *mock_lmdb_name_payload;
+
+static DICT *mock_dict_lmdb_open(const char *dict_name, int open_flags,
+                                        int dict_flags)
+{
+    return (dict_open3(DICT_TYPE_INLINE, mock_lmdb_name_payload,
+                      open_flags, dict_flags));
+}
+
+static MKMAP *mock_mkmap_lmdb_open(const char *path)
+{
+    MKMAP  *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
+
+    mkmap->open = mock_dict_lmdb_open;
+    mkmap->after_open = 0;
+    mkmap->after_close = 0;
+    return (mkmap);
+}
+
+static const DICT_OPEN_INFO mock_lmdb_info = {
+    "lmdb", mock_dict_lmdb_open, mock_mkmap_lmdb_open,
+};
+
+void    setup_mock_lmdb(const char *name_payload)
+{
+    if (mock_lmdb_name_payload != 0)
+       myfree(mock_lmdb_name_payload);
+
+    mock_lmdb_name_payload = mystrdup(name_payload);
+
+    if (dict_open_lookup(mock_lmdb_info.type))
+       dict_open_unregister(mock_lmdb_info.type);
+    dict_open_register(&mock_lmdb_info);
+}
diff --git a/postfix/src/testing/mock_dict.h b/postfix/src/testing/mock_dict.h
new file mode 100644 (file)
index 0000000..8ec0db9
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _MOCK_DICT_H_INCLUDED_
+#define _MOCK_DICT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     mock_dict 3h
+/* SUMMARY
+/*     mock tables
+/* SYNOPSIS
+/*     #include <mock_dict.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * External interface.
+  */
+extern void setup_mock_cdb(const char *);
+extern void setup_mock_lmdb(const char *);
+
+/* LICENSE
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/testing/mock_open_as.c b/postfix/src/testing/mock_open_as.c
new file mode 100644 (file)
index 0000000..3a6a70a
--- /dev/null
@@ -0,0 +1,102 @@
+/*++
+/* NAME
+/*     mock_open_as 3
+/* SUMMARY
+/*     test scaffolding
+/* SYNOPSIS
+/*     #include <mock_open_as.h>
+/*
+/*     typedef struct MOCK_OPEN_AS_REQ {
+/* in +4
+/*     const char *want_path,
+/*     uid_t   want_uid,
+/*     gid_t   want_gid,
+/*     const char *out_data,
+/*     int     out_errno)
+/* .in -4
+/*     } MOCK_OPEN_AS_REQ;
+/*
+/*     void    setup_mock_vstream_fopen_as(const MOCK_OPEN_AS_REQ *request)
+/* DESCRIPTION
+/*     This module provides a mock vstream_fopen_as() implementation
+/*     that returns static results for expected calls.
+/*
+/*     setup_mock_vstream_fopen_as() makes a shallow copy of its input:
+/* .IP want_path, want_uid, want_gid
+/*     The expected vstream_fopen_as() arguments. If the mock
+/*     vstream_fopen_as() is called with an unexpected argument, the
+/*     mock terminates the test with a fatal error.
+/* .IP out_data
+/*     The data that can be read from the stream returned by
+/*     vstream_fopen_as().
+/*  .IP out_errno
+/*     If not NULL, vstream_fopen_as() will return NULL and set errno
+/*     to the value of this argument.
+/* SEE ALSO
+/*     open_as(3), the real thing
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <open_as.h>
+#include <vstring.h>
+
+ /*
+  * Application-specific.
+  */
+#include <mock_open_as.h>
+
+static MOCK_OPEN_AS_REQ mock_req;
+
+/* setup_mock_vstream_fopen_as - set up expectation */
+
+void    setup_mock_vstream_fopen_as(const MOCK_OPEN_AS_REQ *request)
+{
+    mock_req = *request;
+}
+
+/* vstream_fopen_as - fake implementation */
+
+VSTREAM *vstream_fopen_as(const char *path, int flags, mode_t mode,
+                                 uid_t uid, gid_t gid)
+{
+    VSTREAM *stream;
+    VSTRING *data_buffer;
+
+    /* TODO(wietse) replace with match_str() and match_decimal(). */
+    if (strcmp(path, mock_req.want_path) != 0)
+       msg_fatal("vstream_fopen: got path '%s', want '%s'",
+                 path, mock_req.want_path);
+    if (uid != mock_req.want_uid)
+       msg_fatal("vstream_fopen: got uid '%d', want '%d'",
+                 (int) uid, (int) mock_req.want_uid);
+    if (gid != mock_req.want_gid)
+       msg_fatal("vstream_fopen: got gid '%d', want '%d'",
+                 (int) gid, (int) mock_req.want_gid);
+
+    if (mock_req.out_errno != 0) {
+       errno = mock_req.out_errno;
+       return (0);
+    }
+    data_buffer = vstring_alloc(strlen(mock_req.out_data));
+    vstring_strcpy(data_buffer, mock_req.out_data);
+    stream = vstream_memopen(data_buffer, flags);
+    vstream_control(stream, CA_VSTREAM_CTL_OWN_VSTRING, CA_VSTREAM_CTL_END);
+    return (stream);
+}
diff --git a/postfix/src/testing/mock_open_as.h b/postfix/src/testing/mock_open_as.h
new file mode 100644 (file)
index 0000000..daba391
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _MOCK_OPEN_AS_H_INCLUDED_
+#define _MOCK_OPEN_AS_H_INCLUDED_
+
+/*++
+/* NAME
+/*     mock_open_as 3h
+/* SUMMARY
+/*     fake open_as
+/* SYNOPSIS
+/*     #include <mock_open_as.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <unistd.h>
+
+ /*
+  * Utility library.
+  */
+#include <open_as.h>
+#include <vstream.h>
+
+ /*
+  * External interface.
+  */
+typedef struct MOCK_OPEN_AS_REQ {
+    const char *want_path;
+    uid_t   want_uid;
+    gid_t   want_gid;
+    const char *out_data;
+    int     out_errno;
+} MOCK_OPEN_AS_REQ;
+
+extern void setup_mock_vstream_fopen_as(const MOCK_OPEN_AS_REQ *);
+
+/* LICENSE
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/testing/mock_spawn_command.c b/postfix/src/testing/mock_spawn_command.c
new file mode 100644 (file)
index 0000000..e6c4dde
--- /dev/null
@@ -0,0 +1,198 @@
+/*++
+/* NAME
+/*     mock_spawn_command 3t
+/* SUMMARY
+/*     spawn_command() mocker
+/* SYNOPSIS
+/*     #include <mock_spawn_command.h>
+/*
+/*     typedef struct MOCK_SPAWN_CMD_REQ {
+/*     struct spawn_args *want_args;
+/*     int     out_status;
+/*     const char *out_text;
+P/*
+/*     void    setup_mock_spawn_command(const MOCK_SPAWN_CMD_REQ *request)
+/* DESCRIPTION
+/*     setup_mock_spawn_command() instantiates a spawn_command() mocker,
+/*     that given the expected inputs, will produce the specified
+/*     outputs, without any additional dependencies or side effects.
+/*
+/*     This implementation supports only one instance of expectations
+/*     and outputs, and makes a shallow copy of its inputs:
+/* .IP want_args
+/*     The inputs that the mock spawn_command() instance must
+/*     receive. Otherwise, The mocker will terminate the test.
+/* .IP out_status
+/*     The spawn_command() result value.
+/* .IP out_text
+/*     Pointer to null-terminated text that will be written to the
+/*     simulated command's standard error stream.
+/* SEE ALSO
+/*     spawn_command(3), command spawner
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <stringops.h>
+
+ /*
+  * Testing library.
+  */
+#include <mock_spawn_command.h>
+
+ /*
+  * Input expectations and outputs. For now we support only one instance.
+  */
+static MOCK_SPAWN_CMD_REQ mock_req;
+
+void    setup_mock_spawn_command(const MOCK_SPAWN_CMD_REQ *request)
+{
+
+    /*
+     * Validate the output requirements.
+     */
+    if (request->out_status == 0) {
+       if (request->out_text != 0)
+           msg_fatal("setup_spawn_command: out_status is zero, but out_text "
+                     "is not null");
+    } else {
+       if (request->out_text == 0 || *request->out_text == 0) {
+           msg_fatal("setup_spawn_command: out_status is not zero, but "
+                     "out_text is null or empty");
+       }
+    }
+
+    /*
+     * Make a shallow copy of the arguments.
+     */
+    mock_req = *request;
+}
+
+ /*
+  * Matchers. TODO(wietse)  factor out.
+  */
+typedef void PRINTFLIKE(1, 2) (*MATCH_WARN) (const char *,...);
+
+#define STR_OR_NULL(s)          ((s) ? (s) : "(null)")
+#define NOT_NULL_OR_NULL(arg)   ((arg) ? "(not null)" : "(null)")
+
+/* match_decimal - match integers, report difference in decimal */
+
+static bool match_decimal(const char *what, MATCH_WARN warn, int want, int got)
+{
+    if (want != got) {
+       if (warn)
+           warn("%s: want %d, got %d", what, want, got);
+       return (false);
+    }
+    return (true);
+}
+
+/* match_str - match null-terminated strings */
+
+static int match_str(const char *what, MATCH_WARN warn,
+                            const char *want, const char *got)
+{
+    if (want == 0 && got == 0)
+       return (true);
+    if (!want != !got) {
+       if (warn)
+           warn("%s: want '%s', got '%s'", what, STR_OR_NULL(want),
+                STR_OR_NULL(got));
+       return (false);
+    }
+    if (strcmp(got, want) != 0) {
+       if (warn)
+           warn("%s: want %s, got %s", what, want, got);
+       return (false);
+    }
+    return (true);
+}
+
+/* match_cpp - match (char **) instances */
+
+static bool match_cpp(const char *what, MATCH_WARN warn,
+                             char **want, char **got)
+{
+    char  **wpp, **gpp;
+
+    if (want == 0 && got == 0)
+       return (true);
+    if (!want != !got) {
+       if (warn)
+           warn("%s: want %s, got %s", what, NOT_NULL_OR_NULL(want),
+                NOT_NULL_OR_NULL(got));
+       return (false);
+    }
+    for (wpp = want, gpp = got; /* void */ ; wpp++, gpp++) {
+       if (*wpp == 0 && *gpp == 0) {
+           return (true);
+       } else if (*wpp == 0 || *gpp == 0) {
+           if (warn)
+               warn("%s: want '%s', got '%s'",
+                    what, STR_OR_NULL(*wpp), STR_OR_NULL(*gpp));
+           return (false);
+       } else if (!match_str(what, warn, *gpp, *wpp)) {
+           return (false);
+       }
+    }
+    return (true);
+}
+
+/* match_spawn_args - compare expected against actual */
+
+static bool match_spawn_args(MATCH_WARN warn, struct spawn_args *want,
+                                    struct spawn_args *got)
+{
+    return (match_cpp("argv", warn, want->argv, got->argv)
+           && match_str("command", warn,
+                        want->command, got->command)
+           && match_decimal("uid", warn, want->uid, got->uid)
+           && match_cpp("env", warn, want->env, got->env)
+           && match_cpp("export", warn,
+                        want->export, got->export)
+           && match_str("shell", warn, want->shell, got->shell)
+           && match_decimal("time_limit", warn,
+                            want->time_limit, got->time_limit));
+}
+
+/* spawn_command - mock */
+
+int     spawn_command(int key,...)
+{
+    struct spawn_args got_args;
+    va_list ap;
+
+    va_start(ap, key);
+    get_spawn_args(&got_args, key, ap);
+    va_end(ap);
+
+    /*
+     * Match spawn_command() arguments against expectations or terminate.
+     */
+    if (!match_spawn_args(msg_warn, &mock_req.want_args, &got_args))
+       msg_fatal("spawn_command called with unexpected argument");
+
+    /* Now output some info as if the command was executed. */
+    if (mock_req.out_status != 0)
+       write(got_args.stderr_fd, mock_req.out_text, strlen(mock_req.out_text));
+    return (mock_req.out_status);
+}
diff --git a/postfix/src/testing/mock_spawn_command.h b/postfix/src/testing/mock_spawn_command.h
new file mode 100644 (file)
index 0000000..d1ff39d
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _MOCK_SPAWN_COMMAND_H_INCLUDED_
+#define _MOCK_SPAWN_COMMAND_H_INCLUDED_
+
+/*++
+/* NAME
+/*     mock_spawn_command.h 3h
+/* SUMMARY
+/*     spawn_command() mocker
+/* SYNOPSIS
+/*     #include <mock_spawn_command.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <spawn_command.h>
+
+ /*
+  * External API.
+  */
+typedef struct MOCK_SPAWN_CMD_REQ {
+    struct spawn_args want_args;
+    int     out_status;
+    const char *out_text;
+} MOCK_SPAWN_CMD_REQ;
+
+extern void setup_mock_spawn_command(const MOCK_SPAWN_CMD_REQ *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/testing/mock_stat.c b/postfix/src/testing/mock_stat.c
new file mode 100644 (file)
index 0000000..8690d21
--- /dev/null
@@ -0,0 +1,113 @@
+/*++
+/* NAME
+/*     mock_stat 3
+/* SUMMARY
+/*     test scaffolding
+/* SYNOPSIS
+/*     #include <mock_stat.h>
+/*
+/*     typedef struct MOCK_STAT_REQ {
+/* .in +4
+/*     const char *want_path;
+/*     int out_errno;
+/*     struct stat st;
+/* .in -4
+/*     } MOCK_STAT_REQ;
+/*
+/*     void    setup_mock_stat(const MOCK_STAT_REQ *request)
+/*
+/*     void    teardown_mock_stat(void)
+/* DESCRIPTION
+/*     This module provides a mock stat() implementation that returns
+/*     static results for expected calls.
+/*
+/*     setup_mock_stat() adds a mapping from pathname to struct
+/*     stat_info pointer. It is an error to enter multiple mappings
+/*     for one pathname. If makes a shallow copy ig its input:
+/* .IP want_path
+/*     The lookup key for file status information.
+/* .IP out_errno
+/*     If non-zero, mock stat() will return -1 and set the global
+/*     errno variable.
+/* .IP st
+/*     File status information, ignored when out_errno is non-zero.
+/* .PP
+/*     teardown_mock_stat() destroys all mappings entered with
+/*     setup_mock_stat().
+/*
+/*     The mock stat() function looks up the MOCK_STAT_REQ information
+/*     for a pathname and terminates the test if the pathname is not
+/*     expected. If the mapping contains a non-zero out_errno value,
+/*     it simulates an error, sets the global errno value, and returns
+/*     -1.  Otherwise it copies the stat_info.st value to the storage
+/*     provided with the st argument.
+/* SEE ALSO
+/*     stat(2), the real thing
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+ /*
+  * Utility library.
+  */
+#include <htable.h>
+#include <msg.h>
+#include <wrap_stat.h>
+
+ /*
+  * Test library.
+  */
+#include <mock_stat.h>
+
+ /*
+  * Application-specific.
+  */
+static HTABLE *mock_stat_table;
+
+/* setup_mock_stat - add path-to-status mapping */
+
+void    setup_mock_stat(const MOCK_STAT_REQ *request)
+{
+    if (mock_stat_table == 0)
+       mock_stat_table = htable_create(10);
+    htable_enter(mock_stat_table, request->want_path, (void *) request);
+}
+
+/* teardown_mock_stat - destroy all path-to-status mappings */
+
+void    teardown_mock_stat(void)
+{
+    if (mock_stat_table) {
+       htable_free(mock_stat_table, (void (*) (void *)) 0);
+       mock_stat_table = 0;
+    }
+}
+
+/* stat - mock stat() implementation */
+
+int stat(const char *path, struct stat *st) {
+    MOCK_STAT_REQ *mock_info;
+
+    if ((mock_info = (MOCK_STAT_REQ *) htable_find(mock_stat_table, path)) == 0)
+       msg_fatal("mock stat: unexpected pathname: '%s'", path);
+
+    if (mock_info->out_errno != 0) {
+       errno = mock_info->out_errno;
+       return (-1);
+    } else {
+       *st = mock_info->out_st;
+       return (0);
+    }
+}
diff --git a/postfix/src/testing/mock_stat.h b/postfix/src/testing/mock_stat.h
new file mode 100644 (file)
index 0000000..a7d2ed1
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _MOCK_STAT_H_INCLUDED_
+#define _MOCK_STAT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     mock_stat 3h
+/* SUMMARY
+/*     mock stat
+/* SYNOPSIS
+/*     #include <mock_stat.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <sys/stat.h>
+#include <unistd.h>
+
+ /*
+  * External interface.
+  */
+typedef struct MOCK_STAT_REQ {
+    const char *want_path;
+    struct stat out_st;
+    int     out_errno;
+} MOCK_STAT_REQ;
+
+extern void setup_mock_stat(const MOCK_STAT_REQ *);
+extern void teardown_mock_stat(void);
+
+/* LICENSE
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
diff --git a/postfix/src/testing/msg_capture.c b/postfix/src/testing/msg_capture.c
new file mode 100644 (file)
index 0000000..38e7c38
--- /dev/null
@@ -0,0 +1,130 @@
+/*++
+/* NAME
+/*     msg_capture 3
+/* SUMMARY
+/*     message capture support
+/* SYNOPSIS
+/*     #include <msg_capture.h>
+/*
+/*     typedef struct MSG_CAPTURE MSG_CAPTURE;
+/*
+/*     MSG_CAPTURE *msg_capt_create(ssize_t init_size)
+/*
+/*     void    msg_capt_start(MSG_CAPTURE *mp)
+/*
+/*     void    msg_capt_stop(MSG_CAPTURE *mp)
+/*
+/*     const char *msg_capt_expose(MSG_CAPTURE *mp)
+/*
+/*     void    msg_capt_free(MSG_CAPTURE *mp)
+/* DESCRIPTION
+/*     This module captures msg(3) logging by temporarily redirecting
+/*     VSTREAM_ER to a buffer.
+/*
+/*     msg_capt_create() creates a MSG_CAPTURE instance.
+/*
+/*     msg_capt_start() starts "recording" msg(3) output. It is an
+/*     error to call this function while a recording is in progress.
+/*
+/*     msg_capt_stop() stops a "recording". It is an error to call this
+/*     function while no recording is in progress.
+/*
+/*     msg_capt_expose() exposes the contents of a recording as a
+/*     null-terminated string. It is an error to call this function
+/*     while a recording is in progress.
+/*
+/*     msg_capt_free() destroys a MSG_CAPTURE instance.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <string.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <mymalloc.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Testing library.
+  */
+#include <msg_capture.h>
+
+ /*
+  * TODO(wietse) make this a proper VSTREAM interface or test helper API.
+  */
+
+/* vstream_swap - capture output for testing */
+
+static void vstream_swap(VSTREAM *one, VSTREAM *two)
+{
+    VSTREAM save;
+
+    save = *one;
+    *one = *two;
+    *two = save;
+}
+
+struct MSG_CAPTURE {
+    VSTRING *buffer;
+    VSTREAM *stream;
+};
+
+MSG_CAPTURE *msg_capt_create(ssize_t init_size)
+{
+    MSG_CAPTURE *mp;
+
+    mp = (MSG_CAPTURE *) mymalloc(sizeof(*mp));
+    mp->buffer = vstring_alloc(init_size);
+    mp->stream = 0;
+    return (mp);
+}
+
+void    msg_capt_start(MSG_CAPTURE *mp)
+{
+    if (mp->stream != 0)
+       msg_panic("%s: capture is in progress", __func__);
+    VSTRING_RESET(mp->buffer);
+    VSTRING_TERMINATE(mp->buffer);
+    if ((mp->stream = vstream_memopen(mp->buffer, O_WRONLY)) == 0)
+       msg_fatal("open memory stream: %m");
+    vstream_swap(VSTREAM_ERR, mp->stream);
+}
+
+void    msg_capt_stop(MSG_CAPTURE *mp)
+{
+    if (mp->stream == 0)
+       msg_panic("%s: no capture in progress", __func__);
+    vstream_swap(mp->stream, VSTREAM_ERR);
+    if (vstream_fclose(mp->stream))
+       msg_fatal("close memory stream: %m");
+    mp->stream = 0;
+    VSTRING_TERMINATE(mp->buffer);
+}
+
+const char *msg_capt_expose(MSG_CAPTURE *mp)
+{
+    if (mp->stream != 0)
+       msg_panic("%s: capture is in progress", __func__);
+    return (vstring_str(mp->buffer));
+}
+
+void    msg_capt_free(MSG_CAPTURE *mp)
+{
+    if (mp->stream != 0)
+       msg_capt_stop(mp);
+    vstring_free(mp->buffer);
+    myfree((void *) mp);
+}
diff --git a/postfix/src/testing/msg_capture.h b/postfix/src/testing/msg_capture.h
new file mode 100644 (file)
index 0000000..164e3b1
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _MSB_CAPTURE_H_INCLUDED_
+#define _MSB_CAPTURE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     msg_capture 3h
+/* SUMMARY
+/*     message capture support
+/* SYNOPSIS
+/*     #include <msg_capture.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * External API.
+  */
+typedef struct MSG_CAPTURE MSG_CAPTURE;
+
+extern MSG_CAPTURE *msg_capt_create(ssize_t init_size);
+extern void msg_capt_start(MSG_CAPTURE *mp);
+extern void msg_capt_stop(MSG_CAPTURE *mp);
+extern const char *msg_capt_expose(MSG_CAPTURE *mp);
+extern void msg_capt_free(MSG_CAPTURE *mp);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif
index 8162bdc2977fdfdbe1897b21d4791938d3079b31..3326ffe366f6590a5c365b475b597f3ef8cafd88 100644 (file)
@@ -133,6 +133,14 @@ extern const char *str_tls_level(int);
     SSL_group_to_name((ssl), SSL_get_negotiated_group(ssl))
 #else
 #define TLS_GROUP_NAME(ssl) ((const char *)0)
+#endif
+
+#if OPENSSL_VERSION_PREREQ(4,0)
+#define TLS_ADD1_HOST   SSL_add1_dnsname
+#define TLS_SET1_HOST   SSL_set1_dnsname
+#else
+#define TLS_ADD1_HOST   SSL_add1_host
+#define TLS_SET1_HOST   SSL_set1_host
 #endif
 
  /*
@@ -268,7 +276,7 @@ typedef struct {
     VSTREAM *stream;                   /* Blocking-mode SMTP session */
     /* DANE TLSA trust input and verification state */
     const TLS_DANE *dane;              /* DANE TLSA digests */
-    X509   *errorcert;                 /* Error certificate closest to leaf */
+    const X509 *errorcert;             /* Error certificate closest to leaf */
     int     errordepth;                        /* Chain depth of error cert */
     int     errorcode;                 /* First error at error depth */
     int     must_fail;                 /* Failed to load trust settings */
index a721376884473e584e5262a3102f311b2c22479e..1fad4d7e575def06571766e8524388d4a0b1467d 100644 (file)
@@ -517,7 +517,7 @@ static void add_namechecks(TLS_SESS_STATE *TLScontext,
 #endif
 
        if (!match_subdomain) {
-           if (SSL_add1_host(ssl, name))
+           if (TLS_ADD1_HOST(ssl, name))
                ++namechecks_count;
            else
                msg_warn("%s: error loading match name: \"%s\"",
@@ -525,7 +525,7 @@ static void add_namechecks(TLS_SESS_STATE *TLScontext,
        } else {
            char   *dot_name = concatenate(".", name, (char *) 0);
 
-           if (SSL_add1_host(ssl, dot_name))
+           if (TLS_ADD1_HOST(ssl, dot_name))
                ++namechecks_count;
            else
                msg_warn("%s: error loading match name: \"%s\"",
index bfba476ca30215675285c55e1e33cd112850c58f..a9d2916ef2910a9307735548b489a51adfae535b 100644 (file)
@@ -1424,7 +1424,7 @@ void    tls_free_context(TLS_SESS_STATE *TLScontext)
     if (TLScontext->srvr_sig_dgst)
        myfree((void *) TLScontext->srvr_sig_dgst);
     if (TLScontext->errorcert)
-       X509_free(TLScontext->errorcert);
+       X509_free((X509 *) TLScontext->errorcert);
     if (TLScontext->ffail_type)
        myfree(TLScontext->ffail_type);
 
index 9c7191c456eeeb166064647023ce61452975112e..e6ff29ff1096822ac5f6221661e36717292cd6d6 100644 (file)
 /* update_error_state - safely stash away error state */
 
 static void update_error_state(X509_STORE_CTX *ctx, TLS_SESS_STATE *TLScontext,
-                                 int depth, X509 *errorcert, int errorcode)
+                                 int depth, const X509 *errorcert, int errorcode)
 {
 
     /*
@@ -148,9 +148,9 @@ static void update_error_state(X509_STORE_CTX *ctx, TLS_SESS_STATE *TLScontext,
      * being there until later.
      */
     if (TLScontext->errorcert != 0)
-       X509_free(TLScontext->errorcert);
+       X509_free((X509 *) TLScontext->errorcert);
     if (errorcert != 0)
-       X509_up_ref(errorcert);
+        X509_up_ref((X509 *) errorcert);
     TLScontext->errorcert = errorcert;
     TLScontext->errorcode = errorcode;
     TLScontext->errordepth = depth;
@@ -161,7 +161,7 @@ static void update_error_state(X509_STORE_CTX *ctx, TLS_SESS_STATE *TLScontext,
 int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
 {
     char    buf[CCERT_BUFSIZ];
-    X509   *cert;
+    const X509 *cert;
     int     err;
     int     depth;
     SSL    *con;
@@ -221,7 +221,7 @@ void    tls_log_verify_error(TLS_SESS_STATE *TLScontext,
 {
     char    buf[CCERT_BUFSIZ];
     int     err = TLScontext->errorcode;
-    X509   *cert = TLScontext->errorcert;
+    const X509 *cert = TLScontext->errorcert;
     int     depth = TLScontext->errordepth;
 
 #ifdef USE_TLSRPT
@@ -371,20 +371,20 @@ void    tls_log_verify_error(TLS_SESS_STATE *TLScontext,
 
 /* tls_text_name - extract certificate property value by name */
 
-static char *tls_text_name(X509_NAME *name, int nid, const char *label,
+static char *tls_text_name(const X509_NAME *name, int nid, const char *label,
                                const TLS_SESS_STATE *TLScontext, int gripe)
 {
     const char *myname = "tls_text_name";
     int     pos;
-    X509_NAME_ENTRY *entry;
-    ASN1_STRING *entry_str;
+    const X509_NAME_ENTRY *entry;
+    const ASN1_STRING *entry_str;
     int     asn1_type;
     int     utf8_length;
     unsigned char *utf8_value;
     int     ch;
     unsigned char *cp;
 
-    if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
+    if (name == 0 || (pos = X509_NAME_get_index_by_NID((X509_NAME *) name, nid, -1)) < 0) {
        if (gripe != DONT_GRIPE) {
            msg_warn("%s: %s: peer certificate has no %s",
                     myname, TLScontext->namaddr, label);
@@ -513,7 +513,7 @@ char   *tls_peer_CN(X509 *peercert, const TLS_SESS_STATE *TLScontext)
 
 char   *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext)
 {
-    X509_NAME *name;
+    const X509_NAME *name;
     char   *cn;
 
     name = X509_get_issuer_name(peer);
index 292b473fd92b3c1f9b3b50b5f939325d3dc2357e..c70cf5c3a2196556025eb54033b43f8e2a2e7eb8 100644 (file)
@@ -48,7 +48,7 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        inet_addr_sizes.c quote_for_json.c mystrerror.c \
        sane_sockaddr_to_hostaddr.c normalize_ws.c valid_uri_scheme.c \
        clean_ascii_cntrl_space.c normalize_v4mapped_addr.c ossl_digest.c \
-       mac_midna.c
+       mac_midna.c wrap_stat.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 \
@@ -97,7 +97,7 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
        quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
        normalize_ws.o valid_uri_scheme.o clean_ascii_cntrl_space.o \
-       normalize_v4mapped_addr.o ossl_digest.o mac_midna.o
+       normalize_v4mapped_addr.o ossl_digest.o mac_midna.o wrap_stat.o
 # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
 # When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
 # otherwise it sets the PLUGIN_* macros.
@@ -132,7 +132,7 @@ HDRS        = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
        inet_prefix_top.h inet_addr_sizes.h valid_uri_scheme.h \
        clean_ascii_cntrl_space.h normalize_v4mapped_addr.h ossl_digest.h \
-       mac_midna.h
+       mac_midna.h wrap_stat.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 DEFS   = -I. -D$(SYSTYPE)
@@ -2646,11 +2646,14 @@ nvtable.o: mymalloc.h
 nvtable.o: nvtable.c
 nvtable.o: nvtable.h
 nvtable.o: sys_defs.h
+open_as.o: check_arg.h
 open_as.o: msg.h
 open_as.o: open_as.c
 open_as.o: open_as.h
 open_as.o: set_eugid.h
 open_as.o: sys_defs.h
+open_as.o: vbuf.h
+open_as.o: vstream.h
 open_limit.o: iostuff.h
 open_limit.o: open_limit.c
 open_limit.o: sys_defs.h
@@ -3135,6 +3138,9 @@ watchdog.o: posix_signals.h
 watchdog.o: sys_defs.h
 watchdog.o: watchdog.c
 watchdog.o: watchdog.h
+wrap_stat.o: sys_defs.h
+wrap_stat.o: wrap_stat.c
+wrap_stat.o: wrap_stat.h
 write_buf.o: iostuff.h
 write_buf.o: msg.h
 write_buf.o: sys_defs.h
index 36def9b3c7758612d7d7207f12ddf8217c100d43..0e689192ed142c70248b19f421b268f1da558f7e 100644 (file)
@@ -132,6 +132,7 @@ extern void dict_free(DICT *);
 #define DICT_FLAG_UTF8_ACTIVE  (1<<20) /* UTF-8 proxy layer is present */
 #define DICT_FLAG_SRC_RHS_IS_FILE \
                                (1<<21) /* Map source RHS is a file */
+#define DICT_FLAG_SURROGATE    (1<22)  /* This is a surrogate dictionary */
 
 #define DICT_FLAG_UTF8_MASK    (DICT_FLAG_UTF8_REQUEST)
 
@@ -219,6 +220,7 @@ typedef const DICT_OPEN_INFO *(*DICT_OPEN_EXTEND_FN) (const char *);
 extern DICT *dict_open(const char *, int, int);
 extern DICT *dict_open3(const char *, const char *, int, int);
 extern void dict_open_register(const DICT_OPEN_INFO *);
+extern void dict_open_unregister(const char *);
 extern const DICT_OPEN_INFO *dict_open_lookup(const char *);
 extern DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN);
 
index 87177fd55ecd80c061a9574dcfbf733d6cb1d166..30efe568f47de63fb274b7d0923827da3cbae025 100644 (file)
@@ -446,8 +446,10 @@ static int dict_db_sequence(DICT *dict, int function,
      */
     switch (function) {
     case DICT_SEQ_FUN_FIRST:
-       if (dict_db->cursor == 0)
-           DICT_DB_CURSOR(db, &(dict_db->cursor));
+       if (dict_db->cursor == 0
+           && (status = DICT_DB_CURSOR(db, &(dict_db->cursor))) != 0)
+           msg_fatal("error [%d] initializing cursor for %s: %m",
+                     status, dict_db->dict.name);
        db_function = DB_FIRST;
        break;
     case DICT_SEQ_FUN_NEXT:
index a6327853a1d84f045dcdee92a81d81daa78e171e..05e4175c7be04eb9c706bfde579cb0bd9f96ab17 100644 (file)
@@ -52,6 +52,9 @@
 /*     void    dict_open_register(open_info)
 /*     DICT_OPEN_INFO *open_info;
 /*
+/*     void    dict_open_unregister(dict_type)
+/*     const char *dict_type;
+/*
 /*     const DICT_OPEN_INFO *dict_open_lookup(dict_type)
 /*     const char *dict_type;
 /*
 /*     associated data structures.
 /*
 /*     dict_open_register() adds support for a new dictionary type.
-/*     NOTE: this function does not copy its argument.
+/*     NOTE: this function does not copy its argument. It is an error
+/*     to add an existing type.
+/*
+/*     dict_open_unregister() removes support for a dictionary type.
+/*     NOTE: it is an error to delete a non-existent type.
 /*
 /*     dict_open_lookup() returns a pointer to the DICT_OPEN_INFO
 /*     for the specified dictionary type, or a null pointer if the
 /*     be lifted.
 /* DIAGNOSTICS
 /*     Fatal error: open error, unsupported dictionary type, attempt to
-/*     update non-writable dictionary.
+/*     update non-writable dictionary, attempt to unregister a type
+/*     that is not registered.
 /*
 /*     The lookup routine returns non-null when the request is
 /*     satisfied. The update, delete and sequence routines return
@@ -564,6 +572,19 @@ void    dict_open_register(const DICT_OPEN_INFO *dp)
     (void) htable_enter(dict_open_hash, dp->type, (void *) dp);
 }
 
+/* dict_open_unregister - unregister dictionary type */
+
+void    dict_open_unregister(const char *dict_type)
+{
+    const char *myname = "dict_open_unregister";
+
+    if (msg_verbose > 1)
+       msg_info("%s: %s", myname, dict_type);
+    if (NEED_DICT_OPEN_INIT())
+       dict_open_init();
+    htable_delete(dict_open_hash, dict_type, (void (*) (void *)) 0);
+}
+
 /* dict_open_lookup - look up DICT_OPEN_INFO for dictionary type */
 
 const DICT_OPEN_INFO *dict_open_lookup(const char *dict_type)
@@ -573,6 +594,8 @@ const DICT_OPEN_INFO *dict_open_lookup(const char *dict_type)
 
     if (msg_verbose > 1)
        msg_info("%s: %s", myname, dict_type);
+    if (NEED_DICT_OPEN_INIT())
+       dict_open_init();
     if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0
        && dict_open_extend_hook != 0
        && (dp = dict_open_extend_hook(dict_type)) != 0)
index 8d81c7085e84f93a7be668993b37de583db8cfa3..f15e1576fe40313d7526e01b71f47399013a3d05 100644 (file)
@@ -4,7 +4,7 @@
 /* SUMMARY
 /*     surrogate table for graceful "open" failure
 /* SYNOPSIS
-/*     #include <dict_surrogate.h>
+/*     #include <dict.h>
 /*
 /*     DICT    *dict_surrogate(dict_type, dict_name,
 /*                             open_flags, dict_flags,
@@ -169,7 +169,7 @@ DICT   *dict_surrogate(const char *dict_type, const char *dict_name,
     }
     dp->dict.sequence = dict_surrogate_sequence;
     dp->dict.close = dict_surrogate_close;
-    dp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
+    dp->dict.flags = dict_flags | DICT_FLAG_PATTERN | DICT_FLAG_SURROGATE;
     dp->dict.owner.status = DICT_OWNER_TRUSTED;
     buf = vstring_alloc(10);
     errno = saved_errno;
index 0fa84b797c7cc0786599318e4496dd6e089e9be5..744bb816186537fb9858863862920900c3be43b7 100644 (file)
 /*     const char *path;
 /*     int     mode;
 /*     uid_t   euid;
+/*
+/*     int     vstream_fopen_as(path, flags, mode, euid, egid)
+/*     const char *path;
+/*     int     flags;
+/*     mode_t  mode;
+/*     uid_t   euid;
 /*     gid_t   egid;
 /* DESCRIPTION
 /*     open_as() opens the named \fIpath\fR with the named \fIflags\fR
 /*     and \fImode\fR, and with the effective rights specified by \fIeuid\fR
 /*     and \fIegid\fR.  A -1 result means the open failed.
+/*
+/*     vstream_fopen_as() implements a VSTREAM wrapper with the same
+/*     functionality.
 /* DIAGNOSTICS
 /*     Fatal error: no permission to change privilege level.
 /* SEE ALSO
@@ -29,6 +38,9 @@
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -42,6 +54,7 @@
 #include "msg.h"
 #include "set_eugid.h"
 #include "open_as.h"
+#include "vstream.h"
 
 /* open_as - open file as user */
 
@@ -68,3 +81,15 @@ int     open_as(const char *path, int flags, int mode, uid_t euid, gid_t egid)
 
     return (fd);
 }
+
+/* vstream_fopen_as - VSTREAM wrapper */
+
+VSTREAM *vstream_fopen_as(const char *path, int flags, mode_t mode,
+                                 uid_t euid, gid_t egid)
+{
+    int     fd;
+
+    if ((fd = open(path, flags, mode)) < 0)
+       return (0);
+    return (vstream_fdopen(fd, flags));
+}
index 308e0094f3a50b6d46f0fc6a73e94f5c5b904612..35159bfe8b0ea0e852c563a12e11c95e493374f2 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+
  /* External interface. */
 
 extern int open_as(const char *, int, int, uid_t, gid_t);
+extern VSTREAM *vstream_fopen_as(const char *, int, mode_t, uid_t, gid_t);
 
 /* LICENSE
 /* .ad
@@ -25,6 +31,9 @@ extern int open_as(const char *, int, int, uid_t, gid_t);
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 90fb223a0e2cf87bf56cc5723740df34a3eb4347..86aad69c543503f99e88ccbad1b716bbffacd59e 100644 (file)
@@ -6,8 +6,13 @@
 /* SYNOPSIS
 /*     #include <spawn_command.h>
 /*
-/*     WAIT_STATUS_T spawn_command(key, value, ...)
+/*     WAIT_STATUS_T spawn_command(key, ...)
 /*     int     key;
+/* AUXILIARY FUNCTIONS
+/*     get_spawn_args(
+/*     struct spawn_args *args,
+/*     int     key,
+/*     va_list ap)
 /* DESCRIPTION
 /*     spawn_command() runs a command in a child process and returns
 /*     the command exit status.
 
 /* Application-specific. */
 
-struct spawn_args {
-    char  **argv;                      /* argument vector */
-    char   *command;                   /* or a plain string */
-    int     stdin_fd;                  /* read stdin here */
-    int     stdout_fd;                 /* write stdout here */
-    int     stderr_fd;                 /* write stderr here */
-    uid_t   uid;                       /* privileges */
-    gid_t   gid;                       /* privileges */
-    char  **env;                       /* extra environment */
-    char  **export;                    /* exportable environment */
-    char   *shell;                     /* command shell */
-    int     time_limit;                        /* command time limit */
-};
-
 /* get_spawn_args - capture the variadic argument list */
 
-static void get_spawn_args(struct spawn_args * args, int init_key, va_list ap)
+void    get_spawn_args(struct spawn_args *args, int init_key, va_list ap)
 {
     const char *myname = "get_spawn_args";
     int     key;
index 7d16413775834f9feffbcaef10cd322ac5b40c94..7951a8b6e2e7565fdbfbb6828692ffea09d019f4 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * System library.
+  */
+#include <stdarg.h>
+
  /*
   * Utility library.
   */
@@ -52,6 +57,25 @@ CHECK_CPTR_HELPER_DCL(CA_SPAWN_CMD, char);
 
 extern WAIT_STATUS_T spawn_command(int,...);
 
+ /*
+  * Internal API, needed by fake_spawn_command().
+  */
+struct spawn_args {
+    char  **argv;                      /* argument vector */
+    char   *command;                   /* or a plain string */
+    int     stdin_fd;                  /* read stdin here */
+    int     stdout_fd;                 /* write stdout here */
+    int     stderr_fd;                 /* write stderr here */
+    uid_t   uid;                       /* privileges */
+    gid_t   gid;                       /* privileges */
+    char  **env;                       /* extra environment */
+    char  **export;                    /* exportable environment */
+    char   *shell;                     /* command shell */
+    int     time_limit;                        /* command time limit */
+};
+
+extern void get_spawn_args(struct spawn_args *, int, va_list);
+
 /* LICENSE
 /* .ad
 /* .fi
index 76c495ce92efded0af8c0c838aeda964de22b324..493ede2adde30c936aa34de1877576c9bbd9427b 100644 (file)
 #define HAS_SA_LEN
 #define NATIVE_DB_TYPE "hash"
 #if (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 104250000)
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"        /* sendmail 8.10 */
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"      /* sendmail 8.10 */
 #endif
 #if (defined(OpenBSD) && OpenBSD >= 200006)
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"        /* OpenBSD 2.7 */
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"      /* OpenBSD 2.7 */
 #endif
 #ifndef ALIAS_DB_MAP
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #endif
 #define GETTIMEOFDAY(t)        gettimeofday(t,(struct timezone *) 0)
 #define ROOT_PATH      "/bin:/usr/bin:/sbin:/usr/sbin"
 #define HAS_DB
 #define HAS_SA_LEN
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
 #define ROOT_PATH      "/bin:/usr/bin:/sbin:/usr/sbin"
 #define USE_STATFS
 /* might be set by makedef */
 #ifdef HAS_DB
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #else
 #define HAS_DBM
 #define        NATIVE_DB_TYPE  "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #endif
 extern int optind;
 extern char *optarg;
@@ -340,7 +340,7 @@ extern int h_errno;
 #define HAVE_BASENAME
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/var/adm/sendmail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/var/adm/sendmail/aliases"
 extern int optind;                     /* XXX use <getopt.h> */
 extern char *optarg;                   /* XXX use <getopt.h> */
 extern int opterr;                     /* XXX use <getopt.h> */
@@ -386,7 +386,7 @@ extern int opterr;                  /* XXX use <getopt.h> */
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 extern int optind;
 extern char *optarg;
 extern int opterr;
@@ -430,7 +430,7 @@ extern int opterr;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #ifndef NO_NISPLUS
@@ -510,7 +510,7 @@ extern int opterr;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -540,7 +540,7 @@ extern int opterr;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE     "dbm"
-#define ALIAS_DB_MAP    DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP    "$default_database_type:/etc/mail/aliases"
 #ifndef NO_NIS
 #define HAS_NIS */
 #endif
@@ -582,7 +582,7 @@ extern int opterr;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -635,7 +635,7 @@ extern int opterr;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -680,7 +680,7 @@ extern int initgroups(const char *, int);
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -721,7 +721,7 @@ extern int initgroups(const char *, int);
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -763,7 +763,7 @@ extern int initgroups(const char *, int);
   * LINUX.
   */
 #if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5) \
-       || defined(LINUX6)
+       || defined(LINUX6) || defined(LINUX7)
 #define SUPPORTED
 #define UINT32_TYPE    unsigned int
 #define UINT16_TYPE    unsigned short
@@ -776,7 +776,7 @@ extern int initgroups(const char *, int);
 #define HAS_FSYNC
 #define HAS_DB
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -852,7 +852,7 @@ extern int initgroups(const char *, int);
 #define HAS_FSYNC
 #define HAS_DB
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -885,7 +885,7 @@ extern int initgroups(const char *, int);
 #define HAS_FSYNC
 #define HAS_DB
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 #ifndef NO_NIS
 #define HAS_NIS
 #endif
@@ -950,7 +950,7 @@ extern int initgroups(const char *, int);
 #define DEF_MAILBOX_LOCK "fcntl, dotlock"
 #define HAS_FSYNC
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"
 #define ROOT_PATH      "/usr/bin:/sbin:/usr/sbin"
 #define MISSING_SETENV
 #ifndef NO_NIS
@@ -989,7 +989,7 @@ extern int h_errno;                 /* <netdb.h> imports too much stuff */
 #define DEF_MAILBOX_LOCK "fcntl, dotlock"
 #define HAS_FSYNC
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"
 #define ROOT_PATH      "/usr/bin:/sbin:/usr/sbin"
 #define MISSING_SETENV
 #ifndef NO_NIS
@@ -1034,7 +1034,7 @@ extern int h_errno;                       /* <netdb.h> imports too much stuff */
 #define MISSING_RLIMIT_FSIZE
 #define GETTIMEOFDAY(t)        gettimeofday(t,(struct timezone *) 0)
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/usr/lib/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/usr/lib/aliases"
 #define ROOT_PATH      "/bin:/usr/bin:/etc"
 #define _PATH_BSHELL   "/bin/sh"
 #define _PATH_MAILDIR  "/usr/mail"
@@ -1181,7 +1181,7 @@ typedef unsigned short mode_t;
 #define USE_SYS_SOCKIO_H
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/var/adm/sendmail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/var/adm/sendmail/aliases"
 extern int optind;                     /* XXX use <getopt.h> */
 extern char *optarg;                   /* XXX use <getopt.h> */
 extern int opterr;                     /* XXX use <getopt.h> */
@@ -1210,7 +1210,7 @@ extern int opterr;                        /* XXX use <getopt.h> */
 #define DEF_MAILBOX_LOCK "fcntl, dotlock"
 #define HAS_FSYNC
 #define NATIVE_DB_TYPE "hash"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/aliases"
 /* Uncomment the following line if you have NIS package installed */
 /* #define HAS_NIS */
 #define USE_SYS_SOCKIO_H
@@ -1242,7 +1242,7 @@ extern int h_errno;
 #define HAS_FSYNC
 #define HAS_DBM
 #define NATIVE_DB_TYPE "dbm"
-#define ALIAS_DB_MAP   DEF_DB_TYPE ":/etc/mail/aliases"
+#define ALIAS_DB_MAP   "$default_database_type:/etc/mail/aliases"
 #define DBM_NO_TRAILING_NULL
 #ifndef NO_NIS
 #define HAS_NIS
index d308253f87dcda1b63bdfde8b5af4eabc953e8a4..fe82d64622871ef171ed9e55c99031f40c2a2032 100644 (file)
@@ -179,6 +179,7 @@ extern void vstream_control(VSTREAM *, int,...);
 #define CA_VSTREAM_CTL_SWAP_FD(v)      VSTREAM_CTL_SWAP_FD, CHECK_PTR(VSTREAM_CTL, VSTREAM, (v))
 #define CA_VSTREAM_CTL_START_DEADLINE  VSTREAM_CTL_START_DEADLINE
 #define CA_VSTREAM_CTL_STOP_DEADLINE   VSTREAM_CTL_STOP_DEADLINE
+#define CA_VSTREAM_CTL_OWN_VSTRING     VSTREAM_CTL_OWN_VSTRING
 #define CA_VSTREAM_CTL_MIN_DATA_RATE(v)        VSTREAM_CTL_MIN_DATA_RATE, CHECK_VAL(VSTREAM_CTL, int, (v))
 
 CHECK_VAL_HELPER_DCL(VSTREAM_CTL, ssize_t);
diff --git a/postfix/src/util/wrap_stat.c b/postfix/src/util/wrap_stat.c
new file mode 100644 (file)
index 0000000..321913a
--- /dev/null
@@ -0,0 +1,59 @@
+/*++
+/* NAME
+/*     wrap_stat 3
+/* SUMMARY
+/*     mockable stat/lstat wrappers
+/* SYNOPSIS
+/*     #include <wrap_stat.h>
+/*
+/*     int     wrap_stat(
+/*     const char *path,
+/*     struct stat *st)
+/*
+/*     int     wrap_lstat(
+/*     const char *path,
+/*     struct stat *st)
+/* DESCRIPTION
+/*     This module is a NOOP when the NO_MOCK_WRAPPERS macro is
+/*     defined.
+/*
+/*     By default this module redirects stat() and lstat() calls to
+/*     the above listed wrapper functions that may be overridden with
+/*     mocks. This arrangement prevents mock stat() or lstat() functions
+/*     from interfering with stat() or lstat() calls made by system
+/*     libraries or by third-party libraries.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <sys/stat.h>
+
+ /*
+  * Utility library.
+  */
+#include <wrap_stat.h>
+
+/* wrap_stat - mockable wrapper */
+
+int     wrap_stat(const char *path, struct stat *st)
+{
+#undef stat
+    return (stat (path, st));
+}
+
+/* wrap_lstat - mockable wrapper */
+
+int     wrap_lstat(const char *path, struct stat *st)
+{
+#undef lstat
+    return (lstat(path, st));
+}
diff --git a/postfix/src/util/wrap_stat.h b/postfix/src/util/wrap_stat.h
new file mode 100644 (file)
index 0000000..dcdddd1
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _WRAP_STAT_H_INCLUDED_
+#define _WRAP_STAT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     wrap_stat 3h
+/* SUMMARY
+/*     mockable stat/lstat wrappers
+/* SYNOPSIS
+/*     #include <wrap_stat.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <sys/stat.h>
+
+ /*
+  * Mockable API.
+  */
+#ifndef NO_MOCK_WRAPPERS
+extern int wrap_stat(const char *, struct stat *);
+extern int wrap_lstat(const char *, struct stat *);
+
+#define stat(path, st) wrap_stat(path, st)
+#define lstat(path, st) wrap_lstat(path, st)
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif