diff --git a/postfix/HISTORY b/postfix/HISTORY index d9d9d5b2f..27f13d49d 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -18950,7 +18950,22 @@ Apologies for any names omitted. This is a hard limit built into the OpenLDAP library that causes requests to fail when the number of open read transactions exceeds the limit. When this happens the LMDB - client logs a MDB_READERS_FULL warning and continues with + client logs an MDB_READERS_FULL warning and continues with reduced performance. Files: util/dict_lmdb.c, util/dict_lmdb.h, global/mail_params.h, global/mail_params.c, proto/postconf.proto, proto/LMDB_README.html. + +20130929 + + Security violation: LMDB opens files with read/write access + for lock management purposes. This gives unprivileged + daemon processes read/write file handles for root-owned + files under /etc/postfix. This also breaks when a non-root + process needs to access a root-owned database. Even if + LMDB lock files were world-writable, and kept in a dedicated + directory, they would still violate the principle of least + privilege. For all these reasons, support to create LMDB + files is removed from the postmap and postalias commands. + LMDB files can still be created by unprivileged Postfix + daemon processes under the postfix-owned data_directory. + Files: proto/LMDB_README.html, global/mkmap.c. diff --git a/postfix/README_FILES/INSTALL b/postfix/README_FILES/INSTALL index b04f27d7c..3a473abb1 100644 --- a/postfix/README_FILES/INSTALL +++ b/postfix/README_FILES/INSTALL @@ -277,8 +277,12 @@ The following is an extensive list of names and values. || |known to support it. | |_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | || |Do not build with NIS or NISPLUS support. NIS | -||-DNO_NIS |is not available on some recent Linux or | -|| |Solaris distributions. | +||-DNO_NIS |is not available on some recent Linux | +|| |distributions. | +|_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | +|| |Do not build with NISPLUS support. NISPLUS is | +||-DNO_NISPLUS |not available on some recent Solaris | +|| |distributions. | |_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | || |Do not build with PCRE support. By default, | ||-DNO_PCRE |PCRE support is compiled in when the pcre- | diff --git a/postfix/README_FILES/LMDB_README b/postfix/README_FILES/LMDB_README index 13203e68e..a8c8d022f 100644 --- a/postfix/README_FILES/LMDB_README +++ b/postfix/README_FILES/LMDB_README @@ -4,11 +4,25 @@ PPoossttffiixx OOppeennLLDDAAPP LLMMDDBB HHoowwttoo IInnttrroodduuccttiioonn + Warning: LMDB applications require write access even when the application + itself is read-only. This violates the principle of least privilege, and + causes all kinds of problems when a non-root process needs to query a root- + owned database such as access(5), virtual(5), or transport(5). + + Support to create LMDB databases is no longer available for the postmap(1) + and postalias(1) commands. Instead, consider using cdb: to manage root- + owned databases under the root-owned config_directory (default: /etc/ + postfix) such as access(5), virtual(5), or transport(5). + + Support to create LMDB databases is available only for unprivileged Postfix + daemon processes such as postscreen(8), tlsmgr(8) and verify(8) that manage + postfix-owned databases under the postfix-owned data_directory (default: / + var/lib/postfix). + Postfix uses databases of various kinds to store and look up information. Postfix databases are specified as "type:name". OpenLDAP LMDB implements the Postfix database type "lmdb". The name of a Postfix OpenLDAP LMDB database is -the name of the database file without the ".lmdb" suffix. OpenLDAP LMDB -databases are maintained with the postmap(1) and postalias(1) commands. +the name of the database file without the ".lmdb" suffix. This document describes: @@ -71,9 +85,29 @@ UUnneexxppeecctteedd ffaaiilluurree mmooddeess ooff PPo As documented below, conversion to LMDB introduces a number of failure modes that don't exist with other Postfix databases. Some failure modes have been -eliminated on the course of time. The writeup below reflects the status as of +eliminated in the course of time. The writeup below reflects the status as of of LMDB 0.9.8. +UUnneexxppeecctteedd ""PPeerrmmiissssiioonn ddeenniieedd"" eerrrroorrss.. + +Problem: + A world-readable LMDB database cannot be opened by a process with a UID + that differs from the database file owner, even when an attempt is made to + open the database read-only. This problem does not exist with other Postfix + databases. + +Background: + The LMDB implementation requires write access to maintain read locks, and + perhaps for other purposes. + +Solution: + Consider using cdb: to manage root-owned databases under the root-owned / + etc or config_directory (default: /etc/postfix) such as access(5), virtual + (5), transport(5). Support to create LMDB databases is available only for + unprivileged Postfix daemon processes such as postscreen(8), tlsmgr(8) and + verify(8) that manage postfix-owned databases under the postfix-owned + data_directory (default: /var/lib/postfix). + UUnneexxppeecctteedd ""rreeaaddeerrss ffuullll"" eerrrroorrss.. Problem: @@ -83,7 +117,7 @@ Problem: Background: The LMDB implementation enforces a hard limit on the number of simultaneous read requests for the same database environment. This limit must be - specified with the lmdb_max_readers configuration parameter. + specified in advance with the lmdb_max_readers configuration parameter. Mitigation: Postfix logs a warning suggesting that the lmdb_max_readers parameter value @@ -91,16 +125,15 @@ Mitigation: times while running with reduced performance. Prevention: - Monitor your LMDB files for MDB_READERS_FULL errors and make the necessary - adjustments. Consider using CDB for read-mostly databases. + Monitor your LMDB files for MDB_READERS_FULL errors. After making the + necessary adjustments, restart Postfix. -NNoonn--oobbvviioouuss rreeccoovveerryy wwiitthh ppoossttmmaapp((11))//ppoossttaalliiaass((11))//ttllssmmggrr((88)) ffrroomm aa ccoorrrruupptteedd -ddaattaabbaassee.. +NNoonn--oobbvviioouuss rreeccoovveerryy wwiitthh ppoossttssccrreeeenn((88)),, ttllssmmggrr((88)),, oorr vveerriiffyy((88)) ffrroomm aa +ccoorrrruupptteedd ddaattaabbaassee.. Problem: - You cannot rebuild a corrupted LMDB database simply by re-running postmap - (1) or postalias(1), or by waiting until the tlsmgr(8) daemon restarts. - This problem does not exist with other Postfix databases. + You cannot rebuild a corrupted LMDB database simply by waiting until a + daemon restarts. This problem does not exist with other Postfix databases. Background: The Postfix LMDB database client does not truncate the database file. @@ -112,9 +145,7 @@ Impact: Postfix does not process mail until someone fixes the problem. Recovery: - First delete the ".lmdb" file by hand. Then, rebuild the file with the - postmap(1) or postalias(1) command, or wait until the tlsmgr(8) daemon - restarts. + First delete the ".lmdb" file by hand. Then, restart postfix. Prevention: Arrange your file systems such that they never run out of free space. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 36443c293..55edeb6cc 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -14,6 +14,24 @@ specifies the release date of a stable release or snapshot release. If you upgrade from Postfix 2.9 or earlier, read RELEASE_NOTES-2.10 before proceeding. +Major changes with snapshot 20130929 +==================================== + +Support to create LMDB databases is no longer available for the +postmap(1) and postalias(1) commands. Instead, consider using cdb: +to manage root-owned databases under the root-owned config_directory +(default: /etc/postfix) such as access(5), virtual(5), transport(5). + +The reason is that LMDB applications require write access even when +the application itself is read-only. This violates the principle +of least privilege, and causes all kinds of problems when a non-root +process needs to query a root-owned database. + +Support to create LMDB databases is available only for unprivileged +Postfix daemon processes such as postscreen(8), tlsmgr(8) and +verify(8) that manage postfix-owned databases under the postfix-owned +data_directory (default: /var/lib/postfix). + Major changes with snapshot 20130927 ==================================== diff --git a/postfix/html/INSTALL.html b/postfix/html/INSTALL.html index 22c8d06d4..7eb29a05d 100644 --- a/postfix/html/INSTALL.html +++ b/postfix/html/INSTALL.html @@ -404,7 +404,11 @@ support is compiled in on platforms that are known to support it. -DNO_NIS Do not build with NIS or -NISPLUS support. NIS is not available on some recent Linux or Solaris +NISPLUS support. NIS is not available on some recent Linux +distributions. + + -DNO_NISPLUS Do not build with +NISPLUS support. NISPLUS is not available on some recent Solaris distributions. -DNO_PCRE Do not build with PCRE diff --git a/postfix/html/LMDB_README.html b/postfix/html/LMDB_README.html index 0ca095db9..1c862608d 100644 --- a/postfix/html/LMDB_README.html +++ b/postfix/html/LMDB_README.html @@ -19,12 +19,28 @@

Introduction

+

Warning: LMDB applications require write access +even when the application itself is read-only. This violates the +principle of least privilege, and causes all kinds of problems +when a non-root process needs to query a root-owned database such +as access(5), virtual(5), or transport(5).

+ +

Support to create LMDB databases is no longer available for the +postmap(1) and postalias(1) commands. Instead, consider using cdb: +to manage root-owned databases under the root-owned config_directory +(default: /etc/postfix) such as access(5), virtual(5), or +transport(5).

+ +

Support to create LMDB databases is available only for unprivileged +Postfix daemon processes such as postscreen(8), tlsmgr(8) and +verify(8) that manage postfix-owned databases under the postfix-owned +data_directory (default: /var/lib/postfix).

+

Postfix uses databases of various kinds to store and look up information. Postfix databases are specified as "type:name". OpenLDAP LMDB implements the Postfix database type "lmdb". The name of a Postfix OpenLDAP LMDB database is the name -of the database file without the ".lmdb" suffix. OpenLDAP LMDB databases -are maintained with the postmap(1) and postalias(1) commands.

+of the database file without the ".lmdb" suffix.

This document describes:

@@ -117,9 +133,34 @@ databases.

As documented below, conversion to LMDB introduces a number of failure modes that don't exist with other Postfix databases. Some -failure modes have been eliminated on the course of time. +failure modes have been eliminated in the course of time. The writeup below reflects the status as of of LMDB 0.9.8.

+

Unexpected "Permission denied" errors.

+ +
+ +
Problem:

A world-readable LMDB database cannot +be opened by a process with a UID that differs from the database +file owner, even when an attempt is made to open the database +read-only. This problem does not exist with other Postfix databases. +

+ +
Background:

The LMDB implementation requires +write access to maintain read locks, and perhaps for other purposes. +

+ +
Solution:

Consider using cdb: to manage root-owned +databases under the root-owned /etc or config_directory +(default: /etc/postfix) such as access(5), virtual(5), +transport(5). Support to create LMDB databases is available only +for unprivileged Postfix daemon processes such as postscreen(8), +tlsmgr(8) and verify(8) that manage postfix-owned databases under +the postfix-owned data_directory (default: /var/lib/postfix). +

+ +
+

Unexpected "readers full" errors.

@@ -130,8 +171,8 @@ exist with other Postfix databases.

Background:

The LMDB implementation enforces a hard limit on the number of simultaneous read requests for the same -database environment. This limit must be specified with the -lmdb_max_readers configuration parameter.

+database environment. This limit must be specified in advance with +the lmdb_max_readers configuration parameter.

Mitigation:

Postfix logs a warning suggesting that the lmdb_max_readers parameter value be increased, and retries @@ -139,8 +180,10 @@ the failed operation for a limited number of times while running with reduced performance.

Prevention:

Monitor your LMDB files for -MDB_READERS_FULL errors and make the necessary adjustments. -Consider using CDB for read-mostly databases.

+MDB_READERS_FULL errors. After making the necessary adjustments, +restart Postfix.

+ + -

Non-obvious recovery with postmap(1)/postalias(1)/tlsmgr(8) -from a corrupted database.

+

Non-obvious recovery with +postscreen(8), tlsmgr(8), or verify(8) from a corrupted database. +

Problem:

You cannot rebuild a corrupted LMDB -database simply by re-running postmap(1) or postalias(1), or by -waiting until the tlsmgr(8) daemon restarts. This problem -does not exist with other Postfix databases.

+database simply by waiting until a daemon restarts. This problem does not exist +with other Postfix databases.

Background:

The Postfix LMDB database client does not truncate the database file. Instead it attempts to create @@ -269,11 +313,12 @@ That is obviously not possible with a corrupted database file.

someone fixes the problem.

Recovery:

First delete the ".lmdb" file by hand. -Then, rebuild the file with the postmap(1) or postalias(1) command, -or wait until the tlsmgr(8) daemon restarts.

-
+Then, restart +postfix.

-
Prevention:
+
Prevention:

Arrange your file systems such that they never run out of free space.

diff --git a/postfix/makedefs b/postfix/makedefs index a731c04c2..b75c572dd 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -48,7 +48,10 @@ # are known to support it. # .IP \fB-DNO_NIS\fR # Do not build with NIS or NISPLUS support. Support for NIS -# is unavailable on some recent Linux and Solaris distributions. +# is unavailable on some recent Linux distributions. +# .IP \fB-DNO_NISPLUS\fR +# Do not build with NISPLUS support. Support for NISPLUS +# is unavailable on some recent Solaris distributions. # .IP \fB-DNO_PCRE\fR # Do not build with PCRE support. # By default, PCRE support is compiled in when the \fBpcre-config\fR @@ -214,6 +217,10 @@ case "$SYSTEM.$RELEASE" in case $RELEASE in 5.[0-8]|5.[0-8].*) CCARGS="$CCARGS -DNO_CLOSEFROM -DNO_DEV_URANDOM -DNO_FUTIMESAT -DSTREAM_CONNECTIONS";; esac + # Somewhere NISPLUS went away. + case $RELEASE in + 5.[0-9][0-9]*) CCARGS="$CCARGS -DNO_NISPLUS";; + esac # Work around broken str*casecmp(). Do it all here instead # of having half the solution in the sys_defs.h file. CCARGS="$CCARGS -Dstrcasecmp=fix_strcasecmp \ diff --git a/postfix/proto/INSTALL.html b/postfix/proto/INSTALL.html index 93200249c..383e9faec 100644 --- a/postfix/proto/INSTALL.html +++ b/postfix/proto/INSTALL.html @@ -404,7 +404,11 @@ support is compiled in on platforms that are known to support it. -DNO_NIS Do not build with NIS or -NISPLUS support. NIS is not available on some recent Linux or Solaris +NISPLUS support. NIS is not available on some recent Linux +distributions. + + -DNO_NISPLUS Do not build with +NISPLUS support. NISPLUS is not available on some recent Solaris distributions. -DNO_PCRE Do not build with PCRE diff --git a/postfix/proto/LMDB_README.html b/postfix/proto/LMDB_README.html index 1744a8fa1..9c148b092 100644 --- a/postfix/proto/LMDB_README.html +++ b/postfix/proto/LMDB_README.html @@ -19,12 +19,28 @@

Introduction

+

Warning: LMDB applications require write access +even when the application itself is read-only. This violates the +principle of least privilege, and causes all kinds of problems +when a non-root process needs to query a root-owned database such +as access(5), virtual(5), or transport(5).

+ +

Support to create LMDB databases is no longer available for the +postmap(1) and postalias(1) commands. Instead, consider using cdb: +to manage root-owned databases under the root-owned config_directory +(default: /etc/postfix) such as access(5), virtual(5), or +transport(5).

+ +

Support to create LMDB databases is available only for unprivileged +Postfix daemon processes such as postscreen(8), tlsmgr(8) and +verify(8) that manage postfix-owned databases under the postfix-owned +data_directory (default: /var/lib/postfix).

+

Postfix uses databases of various kinds to store and look up information. Postfix databases are specified as "type:name". OpenLDAP LMDB implements the Postfix database type "lmdb". The name of a Postfix OpenLDAP LMDB database is the name -of the database file without the ".lmdb" suffix. OpenLDAP LMDB databases -are maintained with the postmap(1) and postalias(1) commands.

+of the database file without the ".lmdb" suffix.

This document describes:

@@ -117,9 +133,34 @@ databases.

As documented below, conversion to LMDB introduces a number of failure modes that don't exist with other Postfix databases. Some -failure modes have been eliminated on the course of time. +failure modes have been eliminated in the course of time. The writeup below reflects the status as of of LMDB 0.9.8.

+

Unexpected "Permission denied" errors.

+ +
+ +
Problem:

A world-readable LMDB database cannot +be opened by a process with a UID that differs from the database +file owner, even when an attempt is made to open the database +read-only. This problem does not exist with other Postfix databases. +

+ +
Background:

The LMDB implementation requires +write access to maintain read locks, and perhaps for other purposes. +

+ +
Solution:

Consider using cdb: to manage root-owned +databases under the root-owned /etc or config_directory +(default: /etc/postfix) such as access(5), virtual(5), +transport(5). Support to create LMDB databases is available only +for unprivileged Postfix daemon processes such as postscreen(8), +tlsmgr(8) and verify(8) that manage postfix-owned databases under +the postfix-owned data_directory (default: /var/lib/postfix). +

+ +
+

Unexpected "readers full" errors.

@@ -130,8 +171,8 @@ exist with other Postfix databases.

Background:

The LMDB implementation enforces a hard limit on the number of simultaneous read requests for the same -database environment. This limit must be specified with the -lmdb_max_readers configuration parameter.

+database environment. This limit must be specified in advance with +the lmdb_max_readers configuration parameter.

Mitigation:

Postfix logs a warning suggesting that the lmdb_max_readers parameter value be increased, and retries @@ -139,8 +180,10 @@ the failed operation for a limited number of times while running with reduced performance.

Prevention:

Monitor your LMDB files for -MDB_READERS_FULL errors and make the necessary adjustments. -Consider using CDB for read-mostly databases.

+MDB_READERS_FULL errors. After making the necessary adjustments, +restart Postfix.

+ + -

Non-obvious recovery with postmap(1)/postalias(1)/tlsmgr(8) -from a corrupted database.

+

Non-obvious recovery with +postscreen(8), tlsmgr(8), or verify(8) from a corrupted database. +

Problem:

You cannot rebuild a corrupted LMDB -database simply by re-running postmap(1) or postalias(1), or by -waiting until the tlsmgr(8) daemon restarts. This problem -does not exist with other Postfix databases.

+database simply by waiting until a daemon restarts. This problem does not exist +with other Postfix databases.

Background:

The Postfix LMDB database client does not truncate the database file. Instead it attempts to create @@ -269,11 +313,12 @@ That is obviously not possible with a corrupted database file.

someone fixes the problem.

Recovery:

First delete the ".lmdb" file by hand. -Then, rebuild the file with the postmap(1) or postalias(1) command, -or wait until the tlsmgr(8) daemon restarts.

-
+Then, restart +postfix.

-
Prevention:
+
Prevention:

Arrange your file systems such that they never run out of free space.

diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 390f78563..41a11f1f0 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20130928" +#define MAIL_RELEASE_DATE "20130929" #define MAIL_VERSION_NUMBER "2.11" #ifdef SNAPSHOT diff --git a/postfix/src/global/mkmap_open.c b/postfix/src/global/mkmap_open.c index e53b093b3..c4b1c45fd 100644 --- a/postfix/src/global/mkmap_open.c +++ b/postfix/src/global/mkmap_open.c @@ -102,7 +102,29 @@ static const MKMAP_OPEN_INFO mkmap_types[] = { DICT_TYPE_HASH, mkmap_hash_open, DICT_TYPE_BTREE, mkmap_btree_open, #endif -#ifdef HAS_LMDB + + /* + * LMDB readers open the LMDB lock file O_RDWR. This complicates + * database sharing between processes that run with different effective + * UIDs. + * + * For example, this violates the Postfix security model as it passes a + * read-write file handle for a root-owned file under /etc/postfix into a + * non-root daemon process. + * + * This also totally breaks non-root access for root-owned databases by + * non-daemon processes. + * + * Even if LMDB lock files were kept under /tmp or /var/run, those files + * would still have to be world-writable, and that would still violate + * the principle of least privilege. + * + * For all these reasons, LMDB is supported only for caches that are + * maintained by non-root daemon processes such as postscreen(8), + * tlsmgr(8) or verify(8). All the effort to recover from bogus LMDB + * errors was good for something. + */ +#ifdef notdef DICT_TYPE_LMDB, mkmap_lmdb_open, #endif DICT_TYPE_FAIL, mkmap_fail_open, @@ -165,7 +187,7 @@ MKMAP *mkmap_open(const char *type, const char *path, */ for (mp = mkmap_types; /* void */ ; mp++) { if (mp->type == 0) - msg_fatal("unsupported map type: %s", type); + msg_fatal("unsupported map type for this operation: %s", type); if (strcmp(type, mp->type) == 0) break; } diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 04814a537..6edde1e56 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -433,7 +433,9 @@ extern int opterr; #define ALIAS_DB_MAP DEF_DB_TYPE ":/etc/mail/aliases" #ifndef NO_NIS #define HAS_NIS +#ifndef NO_NISPLUS #define HAS_NISPLUS +#endif /* NO_NISPLUS */ #endif #define USE_SYS_SOCKIO_H /* Solaris 2.5, changed sys/ioctl.h */ #define GETTIMEOFDAY(t) gettimeofday(t)