diff --git a/postfix/HISTORY b/postfix/HISTORY index 3e6a0bce7..c84e536aa 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -19029,3 +19029,8 @@ Apologies for any names omitted. Cleanup: restore ability to build without LMDB support; further slmdb API streamlining. Files: util/slmdb.[hc], util/dict_lmdb.c. + + Bugfix: uninitialized variable. File: util/slmdb.c. + + Documentation: added SASL_README example for check_sasl_access. + File: proto/SASL_README.html. diff --git a/postfix/README_FILES/SASL_README b/postfix/README_FILES/SASL_README index ffd51132e..da81b1e0e 100644 --- a/postfix/README_FILES/SASL_README +++ b/postfix/README_FILES/SASL_README @@ -907,6 +907,25 @@ Postfix provides a wide range of SASL authentication configuration options. The next section lists a few that are discussed frequently. See postconf(5) for a complete list. +PPeerr--aaccccoouunntt aacccceessss ccoonnttrrooll + +Postfix can implement policies that depend on the SASL login name (Postfix 2.11 +and later). Typically this is used to HOLD or 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 + permit_sasl_authenticated + ... + + /etc/postfix/sasl_access: + # Use this when smtpd_sasl_local_domain is empty. + username HOLD + # Use this when smtpd_sasl_local_domain=example.com. + username@example.com HOLD + DDeeffaauulltt aauutthheennttiiccaattiioonn ddoommaaiinn Postfix can append a domain name (or any other string) to a SASL login name diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html index 408ad2e4f..5c34030da 100644 --- a/postfix/html/SASL_README.html +++ b/postfix/html/SASL_README.html @@ -1461,6 +1461,30 @@ control over the SASL login name and the envelope sender.

options. The next section lists a few that are discussed frequently. See postconf(5) for a complete list.

+

Per-account access control

+ +

Postfix can implement policies that depend on the SASL login +name (Postfix 2.11 and later). Typically this is used to HOLD or +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
+	permit_sasl_authenticated
+	...
+
+/etc/postfix/sasl_access:
+     # Use this when smtpd_sasl_local_domain is empty.
+     username	HOLD
+     # Use this when smtpd_sasl_local_domain=example.com.
+     username@example.com HOLD
+
+
+

Default authentication domain

Postfix can append a domain name (or any other string) to a diff --git a/postfix/proto/SASL_README.html b/postfix/proto/SASL_README.html index b9104e2a9..1b2511a62 100644 --- a/postfix/proto/SASL_README.html +++ b/postfix/proto/SASL_README.html @@ -1461,6 +1461,30 @@ control over the SASL login name and the envelope sender.

options. The next section lists a few that are discussed frequently. See postconf(5) for a complete list.

+

Per-account access control

+ +

Postfix can implement policies that depend on the SASL login +name (Postfix 2.11 and later). Typically this is used to HOLD or +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
+	permit_sasl_authenticated
+	...
+
+/etc/postfix/sasl_access:
+     # Use this when smtpd_sasl_local_domain is empty.
+     username	HOLD
+     # Use this when smtpd_sasl_local_domain=example.com.
+     username@example.com HOLD
+
+
+

Default authentication domain

Postfix can append a domain name (or any other string) to a diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index f15342445..90692516b 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 "20131101" +#define MAIL_RELEASE_DATE "20131102" #define MAIL_VERSION_NUMBER "2.11" #ifdef SNAPSHOT diff --git a/postfix/src/util/dict_lmdb.c b/postfix/src/util/dict_lmdb.c index dcacd6efa..1aa8412b6 100644 --- a/postfix/src/util/dict_lmdb.c +++ b/postfix/src/util/dict_lmdb.c @@ -69,6 +69,24 @@ #include #include + /* + * Supported LMDB versions. + * + * LMDB 0.9.9 allows the application to manage locks. This elimimates multiple + * problems: + * + * - The need for a (world-)writable lockfile, which was a show-stopper for + * multiprogrammed applications such as Postfix that consist of privileged + * writer processes and unprivileged reader processes. + * + * - Hard-coded inode numbers (from ftok() output) in lockfile content that + * could prevent automatic crash recovery, and related to that, sub-optimal + * semaphore performance on BSD systems. + */ +#if MDB_VERSION_FULL < MDB_VERINT(0, 9, 9) +#error "Build with LMDB version 0.9.9 or later" +#endif + /* Application-specific. */ typedef struct { @@ -100,7 +118,7 @@ typedef struct { * transactions the number of retries is proportional to the size of the * address space. * - * We do not expise these details to the Postfix user interface. The purpose of + * We do not expose these details to the Postfix user interface. The purpose of * Postfix is to solve problems, not punt them to the user. */ #ifndef SSIZE_T_MAX /* The maximum map size */ diff --git a/postfix/src/util/slmdb.c b/postfix/src/util/slmdb.c index c022d7870..a471c5c0b 100644 --- a/postfix/src/util/slmdb.c +++ b/postfix/src/util/slmdb.c @@ -130,7 +130,8 @@ /* The start of a list of (name, value) pairs, terminated with /* SLMDB_CTL_END. The following text enumerates the symbolic /* request names and the corresponding value types. -/* .RS .IP "SLMDB_CTL_LONGJMP_FN (void (*)(void *, int)) +/* .RS +/* .IP "SLMDB_CTL_LONGJMP_FN (void (*)(void *, int)) /* Application long-jump call-back function pointer. The /* function must not return and is called to repeat a failed /* bulk-mode transaction from the start. The arguments are the @@ -202,51 +203,52 @@ #include /* + * Supported LMDB versions. + * * LMDB 0.9.8 allows the application to update the database size limit - * on-the-fly (typically after an MDB_MAP_FULL error). The only limit that - * remains is imposed by the hardware address space. The implementation is - * supposed to handle databases larger than physical memory. However, at - * some point in time there was no such guarantee for (bulk) transactions - * larger than physical memory. - * - * LMDB 0.9.9 allows the application to manage locks. This elimimates multiple - * problems: - * - * - The need for a (world-)writable lockfile, which is a show-stopper for - * multiprogrammed applications that have privileged writers and - * unprivileged readers. - * - * - Hard-coded inode numbers (in ftok() output) in lockfile content that can - * prevent automatic crash recovery, and related to that, sub-optimal - * semaphore performance on BSD systems. + * on-the-fly, so that it can recover from an MDB_MAP_FULL error; it also + * allows an application to "pick up" a new database size limit on-the-fly, + * so that it can recover from an MDB_MAP_RESIZED error. The database size + * limit that remains is imposed by the hardware address space. The + * implementation is supposed to handle databases larger than physical + * memory. However, this is not necessarily guaranteed for (bulk) + * transactions larger than physical memory. */ -#if MDB_VERSION_FULL < MDB_VERINT(0, 9, 9) -#error "Build with LMDB version 0.9.9 or later" +#if MDB_VERSION_FULL < MDB_VERINT(0, 9, 8) +#error "Build with LMDB version 0.9.8 or later" #endif -#define SLMDB_DEF_API_RETRY_LIMIT 2 /* Retries per dict(3) API call */ -#define SLMDB_DEF_BULK_RETRY_LIMIT \ - (2 * sizeof(size_t) * CHAR_BIT) /* Retries per bulk-mode transaction */ - /* - * The purpose of the error-recovering functions below is to hide LMDB - * quirks (MAP_FULL, MAP_RESIZED, MDB_READERS_FULL), so that the caller can - * pretend that those quirks don't exist, and focus on its own job. + * Error recovery. + * + * The purpose of the slmdb(3) API is to hide LMDB quirks (recoverable + * MAP_FULL, MAP_RESIZED, or MDB_READERS_FULL errors). With these out of the + * way, applications can pretend that those quirks don't exist, and focus on + * their own job. * * - To recover from a single-transaction LMDB error, each wrapper function * uses tail recursion instead of goto. Since LMDB errors are rare, code * clarity is more important than speed. * * - To recover from a bulk-transaction LMDB error, the error-recovery code - * jumps back into the caller to some pre-arranged point (the closest thing - * that C has to exception handling). The application is then expected to - * repeat the bulk transaction from scratch. + * triggers a long jump back into the caller to some pre-arranged point (the + * closest thing that C has to exception handling). The application is then + * expected to repeat the bulk transaction from scratch. */ + /* + * Our default retry attempt limits. We allow a few retries per slmdb(3) API + * call for non-bulk transactions. We allow a number of bulk-transaction + * retries that is proportional to the memory address space. + */ +#define SLMDB_DEF_API_RETRY_LIMIT 2 /* Retries per slmdb(3) API call */ +#define SLMDB_DEF_BULK_RETRY_LIMIT \ + (2 * sizeof(size_t) * CHAR_BIT) /* Retries per bulk-mode transaction */ + /* * We increment the recursion counter each time we try to recover from * error, and reset the recursion counter when returning to the application - * from the slmdb API. + * from the slmdb(3) API. */ #define SLMDB_API_RETURN(slmdb, status) do { \ (slmdb)->api_retry_count = 0; \ @@ -257,7 +259,7 @@ static int slmdb_prepare(SLMDB *slmdb) { - int status; + int status = 0; /* * This is called before accessing the database, or after recovery from @@ -273,7 +275,7 @@ static int slmdb_prepare(SLMDB *slmdb) if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) return (status); if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { - if ((status = mdb_txn_commit(slmdb->txn))) + if ((status = mdb_txn_commit(slmdb->txn)) != 0) return (status); slmdb->txn = 0; } @@ -564,7 +566,7 @@ int slmdb_control(SLMDB *slmdb, int first,...) int reqno; va_start(ap, first); - for (reqno = first; reqno != SLMDB_CTL_END; reqno = va_arg(ap, int)) { + for (reqno = first; status == 0 && reqno != SLMDB_CTL_END; reqno = va_arg(ap, int)) { switch (reqno) { case SLMDB_CTL_LONGJMP_FN: slmdb->longjmp_fn = va_arg(ap, SLMDB_LONGJMP_FN);