Revert introduction of alloc_insecure_tainted_data
[exim.git] / src / src / dbstuff.h
index a5905231e448324ef3dae7289a706f78d866882c..510fe4f366d025f1fc06856beaaf5dc4d6ba0aa1 100644 (file)
@@ -323,7 +323,9 @@ before use, but we don't have to free anything after reading data. */
 typedef struct {
        GDBM_FILE gdbm;  /* Database */
        datum lkey;      /* Last key, for scans */
-} EXIM_DB;
+} gdbm_db;
+
+#define EXIM_DB gdbm_db
 
 /* Cursor type, not used with gdbm: just set up a dummy */
 # define EXIM_CURSOR int
@@ -339,15 +341,16 @@ typedef struct {
 
 /* EXIM_DBOPEN - returns a EXIM_DB *, NULL if failed */
 # define EXIM_DBOPEN__(name, dirname, flags, mode, dbpp) \
-     { (*(dbpp)) = (EXIM_DB *) malloc(sizeof(EXIM_DB));\
-       if (*(dbpp) != NULL) { \
-         (*(dbpp))->lkey.dptr = NULL;\
-         (*(dbpp))->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), mode, 0);\
-          if ((*(dbpp))->gdbm == NULL) {\
-              free(*(dbpp));\
-              *(dbpp) = NULL;\
+     { EXIM_DB * dbp = malloc(sizeof(EXIM_DB));\
+       if (dbp) { \
+         dbp->lkey.dptr = NULL;\
+         dbp->gdbm = gdbm_open(CS name, 0, (((flags) & O_CREAT))?GDBM_WRCREAT:(((flags) & (O_RDWR|O_WRONLY))?GDBM_WRITER:GDBM_READER), (mode), 0);\
+          if (!dbp->gdbm) {\
+              free(dbp);\
+              dbp = NULL;\
           }\
        }\
+       *(dbpp) = dbp;\
      }
 
 /* EXIM_DBGET - returns TRUE if successful, FALSE otherwise */
@@ -434,8 +437,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)      \
@@ -508,9 +522,11 @@ after reading data. */
       : (flags) == O_RDWR ? "O_RDWR"   \
       : (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \
       : "??"); \
-  if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB file not permitted", name) \
-      || is_tainted2(dirname, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB directory not permitted", dirname)) \
+  if (is_tainted(name) || is_tainted(dirname)) \
+    { \
+    log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \
     *dbpp = NULL; \
+    } \
   else \
     { EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \
   DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \