Wietse Venema: > Scott Kitterman: > > Some Debian users aren't thrilled about a behavior change associated with > > the > > 20170611 Berkeley DB 2 DB_CONFIG fix. Apparently [1] something like: > > > > | root@playbox01:~# postmap test/in > > > > used to work, but now there is an error: > > > > | postmap: fatal: open database test/in.db: No such file or directory > > > > [1] in the bug report, I suggested this was a reasonable side effect of the > > change, but not everyone agreed, so I said I'd ask if that could be made to > > work again. > > > > Any feedback on this? > > First test result: > > dbenv->open(dbenv, db_home, path_to_db_file) > > where db_home is set to the parent directory of path_to_db_file. > > Surprisingly, dbenv->open() will APPEND path_to_db_file to db_home, > when path_to_db_file specifies a relative pathname.
This patch applies to Postfix 3.0 and later. The precise problem is with a RELATIVE pathname, the subdirectory is a red herring. Wietse diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' '--exclude=INSTALL' '--exclude=.indent.pro' '--exclude=Makefile.in' -r -bur /var/tmp/postfix-3.3-20171028/src/util/dict_db.c src/util/dict_db.c --- /var/tmp/postfix-3.3-20171028/src/util/dict_db.c 2017-06-13 08:36:39.000000000 -0400 +++ src/util/dict_db.c 2017-12-15 10:13:53.296899529 -0500 @@ -615,6 +615,7 @@ struct stat st; DB *db = 0; char *db_path = 0; + VSTRING *db_base_buf = 0; int lock_fd = -1; int dbfd; @@ -671,6 +672,7 @@ #define FREE_RETURN(e) do { \ DICT *_dict = (e); if (db) DICT_DB_CLOSE(db); \ if (lock_fd >= 0) (void) close(lock_fd); \ + if (db_base_buf) vstring_free(db_base_buf); \ if (db_path) myfree(db_path); return (_dict); \ } while (0) @@ -735,18 +737,22 @@ 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); + db_base_buf = vstring_alloc(100); #if DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \ (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0) - if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0) + if ((errno = db->open(db, 0, sane_basename(db_base_buf, db_path), + 0, type, db_flags, 0644)) != 0) FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, "open database %s: %m", db_path)); #elif (DB_VERSION_MAJOR == 3 || DB_VERSION_MAJOR == 4) - if ((errno = db->open(db, db_path, 0, type, db_flags, 0644)) != 0) + if ((errno = db->open(db, sane_basename(db_base_buf, db_path), 0, + type, db_flags, 0644)) != 0) FREE_RETURN(dict_surrogate(class, path, open_flags, dict_flags, "open database %s: %m", db_path)); #else #error "Unsupported Berkeley DB version" #endif + vstring_free(db_base_buf); if ((errno = db->fd(db, &dbfd)) != 0) msg_fatal("get database file descriptor: %m"); #endif