NDBM: check for bogus name given to create call
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 27 Feb 2022 16:33:24 +0000 (16:33 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 27 Feb 2022 16:49:03 +0000 (16:49 +0000)
doc/doc-txt/ChangeLog
src/src/dbstuff.h
src/src/transports/autoreply.c

index ca219cf51c4461f6781b5d622eeaf37802327d7e..282b14f6f2e226342e89e9ee1aeae5b9ecd0e32b 100644 (file)
@@ -83,6 +83,12 @@ JH/18 Bug 2751: Fix include_directory in redirect routers.  Previously a
 
 JH/19 Support for Berkeley DB versions 1 and 2 is withdrawn.
 
+JH/20 When built with NDBM for hints DB's check for nonexistence of a name
+      supplied as the db file-pair basename.  Previously, if a directory
+      path was given, for example via the autoreply "once" option, the DB
+      file.pag and file.dir files would be created in that directory's
+      parent.
+
 
 Exim version 4.95
 -----------------
index a5905231e448324ef3dae7289a706f78d866882c..296a8e18c663d129246765dd1692230da8181a99 100644 (file)
@@ -434,8 +434,19 @@ interface */
 /* Access functions */
 
 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
-# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
-       *(dbpp) = dbm_open(CS name, flags, mode)
+/* Check that the name given is not present. This catches
+a directory name; otherwise we would create the name.pag and
+name.dir files in the directory's parent. */
+
+# define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp)               \
+       {                                                               \
+       struct stat st;                                                 \
+       *(dbpp) =    !(flags & O_CREAT)                                 \
+                || lstat(CCS (name), &st) != 0 && errno == ENOENT      \
+         ? dbm_open(CS (name), (flags), (mode))                                \
+        : (errno = (st.st_mode & S_IFMT) == S_IFDIR ? EISDIR : EEXIST, \
+          NULL);                                                       \
+       }
 
 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
 # define EXIM_DBGET(db, key, data)      \
index 6110f87bff713e3e9fdd3a4061ca7aecae96dcbd..f630c6eb3e90099d29bc54cb6ddbaaa015914c6a 100644 (file)
@@ -57,27 +57,11 @@ BOOL autoreply_transport_entry(transport_instance *tblock, address_item *addr) {
 #else   /*!MACRO_PREDEF*/
 
 
-/* Default private options block for the autoreply transport. */
+/* Default private options block for the autoreply transport.
+All non-mentioned lements zero/null/false. */
 
 autoreply_transport_options_block autoreply_transport_option_defaults = {
-  NULL,           /* from */
-  NULL,           /* reply_to */
-  NULL,           /* to */
-  NULL,           /* cc */
-  NULL,           /* bcc */
-  NULL,           /* subject */
-  NULL,           /* headers */
-  NULL,           /* text */
-  NULL,           /* file */
-  NULL,           /* logfile */
-  NULL,           /* oncelog */
-  NULL,           /* once_repeat */
-  NULL,           /* never_mail */
-  0600,           /* mode */
-  0,              /* once_file_size */
-  FALSE,          /* file_expand */
-  FALSE,          /* file_optional */
-  FALSE           /* return message */
+  .mode = 0600,
 };
 
 
@@ -362,16 +346,13 @@ else
     return FALSE;
 
   if (oncerepeat)
-    {
-    once_repeat_sec = readconf_readtime(oncerepeat, 0, FALSE);
-    if (once_repeat_sec < 0)
+    if ((once_repeat_sec = readconf_readtime(oncerepeat, 0, FALSE)) < 0)
       {
       addr->transport_return = FAIL;
       addr->message = string_sprintf("Invalid time value \"%s\" for "
         "\"once_repeat\" in %s transport", oncerepeat, tblock->name);
       return FALSE;
       }
-    }
   }
 
 /* If the never_mail option is set, we have to scan all the recipients and