Prereq: "3.2.1" diff -cr --new-file /var/tmp/postfix-3.2.1/src/global/mail_version.h ./src/global/mail_version.h *** /var/tmp/postfix-3.2.1/src/global/mail_version.h 2017-06-10 16:32:26.000000000 -0400 --- ./src/global/mail_version.h 2017-06-13 13:28:36.000000000 -0400 *************** *** 20,27 **** * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ ! #define MAIL_RELEASE_DATE "20170610" ! #define MAIL_VERSION_NUMBER "3.2.1" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE --- 20,27 ---- * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ ! #define MAIL_RELEASE_DATE "20170613" ! #define MAIL_VERSION_NUMBER "3.2.2" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -cr --new-file /var/tmp/postfix-3.2.1/HISTORY ./HISTORY *** /var/tmp/postfix-3.2.1/HISTORY 2017-06-10 16:47:26.000000000 -0400 --- ./HISTORY 2017-06-13 13:30:40.000000000 -0400 *************** *** 22979,22981 **** --- 22979,22994 ---- It's supposed to be 7bit, therefore quoted-printable encoding is not expected. Problem reported by Griff. File: bounce/bounce_notify_util.c. + + 20170611 + + Security: Berkeley DB 2 and later try to read settings from + a file DB_CONFIG in the current directory. This undocumented + feature may introduce undisclosed vulnerabilities resulting + in privilege escalation with Postfix set-gid programs + (postdrop, postqueue) before they chdir to the Postfix queue + directory, and with the postmap and postalias commands + depending on whether the user's current directory is writable + by other users. This fix does not change Postfix behavior + for Berkeley DB < 3, but reduces file create performance + for Berkeley DB 3 .. 4.6. File: util/dict_db.c. diff -cr --new-file /var/tmp/postfix-3.2.1/src/util/dict_db.c ./src/util/dict_db.c *** /var/tmp/postfix-3.2.1/src/util/dict_db.c 2014-12-06 20:35:33.000000000 -0500 --- ./src/util/dict_db.c 2017-06-13 12:12:21.000000000 -0400 *************** *** 122,127 **** --- 122,130 ---- typedef struct { DICT dict; /* generic members */ DB *db; /* open db file */ + #if DB_VERSION_MAJOR > 2 + DB_ENV *dbenv; + #endif #if DB_VERSION_MAJOR > 1 DBC *cursor; /* dict_db_sequence() */ #endif *************** *** 553,558 **** --- 556,564 ---- if (DICT_DB_CLOSE(dict_db->db) < 0) msg_info("close database %s: %m (possible Berkeley DB bug)", dict_db->dict.name); + #if DB_VERSION_MAJOR > 2 + dict_db->dbenv->close(dict_db->dbenv, 0); + #endif if (dict_db->key_buf) vstring_free(dict_db->key_buf); if (dict_db->val_buf) *************** *** 562,567 **** --- 568,611 ---- dict_free(dict); } + #if DB_VERSION_MAJOR > 2 + + /* dict_db_new_env - workaround for undocumented ./DB_CONFIG read */ + + static DB_ENV *dict_db_new_env(const char *db_path) + { + VSTRING *db_home_buf; + DB_ENV *dbenv; + u_int32_t cache_size_gbytes; + u_int32_t cache_size_bytes; + int ncache; + + if ((errno = db_env_create(&dbenv, 0)) != 0) + msg_fatal("create DB environment: %m"); + #if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 7) + if ((errno = dbenv->get_cachesize(dbenv, &cache_size_gbytes, + &cache_size_bytes, &ncache)) != 0) + msg_fatal("get DB cache size: %m"); + if (cache_size_gbytes == 0 && cache_size_bytes < dict_db_cache_size) { + if ((errno = dbenv->set_cache_max(dbenv, cache_size_gbytes, + dict_db_cache_size)) != 0) + msg_fatal("set DB max cache size %d: %m", dict_db_cache_size); + if ((errno = dbenv->set_cachesize(dbenv, cache_size_gbytes, + dict_db_cache_size, ncache)) != 0) + msg_fatal("set DB cache size %d: %m", dict_db_cache_size); + } + #endif + /* XXX db_home is also the default directory for the .db file. */ + db_home_buf = vstring_alloc(100); + if ((errno = dbenv->open(dbenv, sane_dirname(db_home_buf, db_path), + DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE, 0)) != 0) + msg_fatal("open DB environment: %m"); + vstring_free(db_home_buf); + return (dbenv); + } + + #endif + /* dict_db_open - open data base */ static DICT *dict_db_open(const char *class, const char *path, int open_flags, *************** *** 578,583 **** --- 622,631 ---- int db_flags; #endif + #if DB_VERSION_MAJOR > 2 + DB_ENV *dbenv; + + #endif /* * Mismatches between #include file and library are a common cause for *************** *** 681,692 **** db_flags |= DB_CREATE; if (open_flags & O_TRUNC) db_flags |= DB_TRUNCATE; ! if ((errno = db_create(&db, 0, 0)) != 0) msg_fatal("create DB database: %m"); if (db == 0) msg_panic("db_create null result"); - if ((errno = db->set_cachesize(db, 0, dict_db_cache_size, 0)) != 0) - msg_fatal("set DB cache size %d: %m", dict_db_cache_size); if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0) msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM); #if DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \ --- 729,738 ---- db_flags |= DB_CREATE; if (open_flags & O_TRUNC) db_flags |= DB_TRUNCATE; ! if ((errno = db_create(&db, dbenv = dict_db_new_env(db_path), 0)) != 0) msg_fatal("create DB database: %m"); if (db == 0) msg_panic("db_create null result"); if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0) msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM); #if DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \ *************** *** 743,748 **** --- 789,797 ---- if (dict_flags & DICT_FLAG_FOLD_FIX) dict_db->dict.fold_buf = vstring_alloc(10); dict_db->db = db; + #if DB_VERSION_MAJOR > 2 + dict_db->dbenv = dbenv; + #endif #if DB_VERSION_MAJOR > 1 dict_db->cursor = 0; #endif