Import Debian changes 4.89-2+deb9u4
[hcoop/debian/exim4.git] / src / dbfn.c
index 4a1c20f..c9c6fb7 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -141,14 +141,14 @@ if (sigalrm_seen) errno = ETIMEDOUT;
 if (rc < 0)
   {
   log_write(0, LOG_MAIN|LOG_PANIC, "Failed to get %s lock for %s: %s",
-    read_only? "read" : "write", buffer,
-    (errno == ETIMEDOUT)? "timed out" : strerror(errno));
+    read_only ? "read" : "write", buffer,
+    errno == ETIMEDOUT ? "timed out" : strerror(errno));
   (void)close(dbblock->lockfd);
   errno = 0;       /* Indicates locking failure */
   return NULL;
   }
 
-DEBUG(D_hints_lookup) debug_printf("locked %s\n", buffer);
+DEBUG(D_hints_lookup) debug_printf("locked  %s\n", buffer);
 
 /* At this point we have an opened and locked separate lock file, that is,
 exclusive access to the database, so we can go ahead and open it. If we are
@@ -164,7 +164,7 @@ DEBUG(D_hints_lookup) debug_printf("EXIM_DBOPEN(%s)\n", buffer);
 EXIM_DBOPEN(buffer, flags, EXIMDB_MODE, &(dbblock->dbptr));
 DEBUG(D_hints_lookup) debug_printf("returned from EXIM_DBOPEN\n");
 
-if (dbblock->dbptr == NULL && errno == ENOENT && flags == O_RDWR)
+if (!dbblock->dbptr && errno == ENOENT && flags == O_RDWR)
   {
   DEBUG(D_hints_lookup)
     debug_printf("%s appears not to exist: trying to create\n", buffer);
@@ -199,8 +199,7 @@ if (created && geteuid() == root_uid)
   *lastname = 0;
   dd = opendir(CS buffer);
 
-  while ((ent = readdir(dd)) != NULL)
-    {
+  while ((ent = readdir(dd)))
     if (Ustrncmp(ent->d_name, name, namelen) == 0)
       {
       struct stat statbuf;
@@ -212,7 +211,6 @@ if (created && geteuid() == root_uid)
           DEBUG(D_hints_lookup) debug_printf("failed setting %s to owned by exim\n", buffer);
         }
       }
-    }
 
   closedir(dd);
   }
@@ -220,10 +218,9 @@ if (created && geteuid() == root_uid)
 /* If the open has failed, return NULL, leaving errno set. If lof is TRUE,
 log the event - also for debugging - but not if the file just doesn't exist. */
 
-if (dbblock->dbptr == NULL)
+if (!dbblock->dbptr)
   {
   if (save_errno != ENOENT)
-    {
     if (lof)
       log_write(0, LOG_MAIN, "%s", string_open_failed(save_errno, "DB file %s",
         buffer));
@@ -231,7 +228,6 @@ if (dbblock->dbptr == NULL)
       DEBUG(D_hints_lookup)
         debug_printf("%s", CS string_open_failed(save_errno, "DB file %s\n",
           buffer));
-    }
   (void)close(dbblock->lockfd);
   errno = save_errno;
   return NULL;
@@ -239,8 +235,10 @@ if (dbblock->dbptr == NULL)
 
 DEBUG(D_hints_lookup)
   debug_printf("opened hints database %s: flags=%s\n", buffer,
-    (flags == O_RDONLY)? "O_RDONLY" : (flags == O_RDWR)? "O_RDWR" :
-    (flags == (O_RDWR|O_CREAT))? "O_RDWR|O_CREAT" : "??");
+    flags == O_RDONLY ? "O_RDONLY"
+    : flags == O_RDWR ? "O_RDWR"
+    : flags == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT"
+    : "??");
 
 /* Pass back the block containing the opened database handle and the open fd
 for the lock. */
@@ -267,6 +265,7 @@ dbfn_close(open_db *dbblock)
 {
 EXIM_DBCLOSE(dbblock->dbptr);
 (void)close(dbblock->lockfd);
+DEBUG(D_hints_lookup) debug_printf("closed hints database and lockfile\n");
 }
 
 
@@ -294,17 +293,21 @@ Returns: a pointer to the retrieved record, or
 */
 
 void *
-dbfn_read_with_length(open_db *dbblock, uschar *key, int *length)
+dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
 {
 void *yield;
 EXIM_DATUM key_datum, result_datum;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
 
 DEBUG(D_hints_lookup) debug_printf("dbfn_read: key=%s\n", key);
 
 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(result_datum);      /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 
 if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;
 
@@ -334,18 +337,22 @@ Returns:    the yield of the underlying dbm or db "write" function. If this
 */
 
 int
-dbfn_write(open_db *dbblock, uschar *key, void *ptr, int length)
+dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
 {
 EXIM_DATUM key_datum, value_datum;
 dbdata_generic *gptr = (dbdata_generic *)ptr;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
 gptr->time_stamp = time(NULL);
 
 DEBUG(D_hints_lookup) debug_printf("dbfn_write: key=%s\n", key);
 
 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(value_datum);       /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 EXIM_DATUM_DATA(value_datum) = CS ptr;
 EXIM_DATUM_SIZE(value_datum) = length;
 return EXIM_DBPUT(dbblock->dbptr, key_datum, value_datum);
@@ -366,12 +373,16 @@ Returns: the yield of the underlying dbm or db "delete" function.
 */
 
 int
-dbfn_delete(open_db *dbblock, uschar *key)
+dbfn_delete(open_db *dbblock, const uschar *key)
 {
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
 EXIM_DATUM key_datum;
 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require clearing */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 return EXIM_DBDEL(dbblock->dbptr, key_datum);
 }