dbblock Points to an open_db block to be filled in.
lof If TRUE, write to the log for actual open failures (locking failures
are always logged).
+ panic If TRUE, panic on failure to create the db directory
Returns: NULL if the open failed, or the locking failed. After locking
failures, errno is zero.
*/
open_db *
-dbfn_open(uschar *name, int flags, open_db *dbblock, BOOL lof)
+dbfn_open(uschar *name, int flags, open_db *dbblock, BOOL lof, BOOL panic)
{
int rc, save_errno;
BOOL read_only = flags == O_RDONLY;
if ((dbblock->lockfd = Uopen(filename, O_RDWR, EXIMDB_LOCKFILE_MODE)) < 0)
{
created = TRUE;
- (void)directory_make(spool_directory, US"db", EXIMDB_DIRECTORY_MODE, TRUE);
+ (void)directory_make(spool_directory, US"db", EXIMDB_DIRECTORY_MODE, panic);
dbblock->lockfd = Uopen(filename, O_RDWR|O_CREAT, EXIMDB_LOCKFILE_MODE);
}
debug_printf_indent("locking %s\n", filename);
sigalrm_seen = FALSE;
-alarm(EXIMDB_LOCK_TIMEOUT);
+ALARM(EXIMDB_LOCK_TIMEOUT);
rc = fcntl(dbblock->lockfd, F_SETLKW, &lock_data);
-alarm(0);
+ALARM_CLR(0);
if (sigalrm_seen) errno = ETIMEDOUT;
if (rc < 0)
if (Ustrncmp(ent->d_name, name, namelen) == 0)
{
struct stat statbuf;
- Ustrcpy(lastname, ent->d_name);
+ /* Filenames from readdir() are trusted, so use a taint-nonchecking copy */
+ strcpy(CS lastname, CCS ent->d_name);
if (Ustat(filename, &statbuf) >= 0 && statbuf.st_uid != exim_uid)
{
DEBUG(D_hints_lookup) debug_printf_indent("ensuring %s is owned by exim\n", filename);
- if (Uchown(filename, exim_uid, exim_gid))
+ if (exim_chown(filename, exim_uid, exim_gid))
DEBUG(D_hints_lookup) debug_printf_indent("failed setting %s to owned by exim\n", filename);
}
}
void *yield;
EXIM_DATUM key_datum, result_datum;
int klen = Ustrlen(key) + 1;
-uschar * key_copy = store_get(klen);
+uschar * key_copy = store_get(klen, is_tainted(key));
memcpy(key_copy, key, klen);
if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;
-yield = store_get(EXIM_DATUM_SIZE(result_datum));
+/* Assume the data store could have been tainted. Properly, we should
+store the taint status with the data. */
+
+yield = store_get(EXIM_DATUM_SIZE(result_datum), TRUE);
memcpy(yield, EXIM_DATUM_DATA(result_datum), EXIM_DATUM_SIZE(result_datum));
if (length != NULL) *length = EXIM_DATUM_SIZE(result_datum);
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
int klen = Ustrlen(key) + 1;
-uschar * key_copy = store_get(klen);
+uschar * key_copy = store_get(klen, is_tainted(key));
memcpy(key_copy, key, klen);
gptr->time_stamp = time(NULL);
dbfn_delete(open_db *dbblock, const uschar *key)
{
int klen = Ustrlen(key) + 1;
-uschar * key_copy = store_get(klen);
+uschar * key_copy = store_get(klen, is_tainted(key));
+
+DEBUG(D_hints_lookup) debug_printf_indent("dbfn_delete: key=%s\n", key);
memcpy(key_copy, key, klen);
EXIM_DATUM key_datum;
uschar *yield;
value_datum = value_datum; /* dummy; not all db libraries use this */
+DEBUG(D_hints_lookup) debug_printf_indent("dbfn_scan\n");
+
/* Some dbm require an initialization */
if (start) EXIM_DBCREATE_CURSOR(dbblock->dbptr, cursor);
}
start = clock();
- odb = dbfn_open(s, O_RDWR, dbblock + i, TRUE);
+ odb = dbfn_open(s, O_RDWR, dbblock + i, TRUE, TRUE);
stop = clock();
if (odb)