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

Reply via email to