X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdbfn.c;h=be6a47afcd07ecaf12eded9d46cb7888528fa610;hb=4a92bfe6da547eb599b76da068b8b908e1c509b7;hp=3aca1832650440aeed61e6abf16e27f7c60fe791;hpb=54a2a2a9983913a91ccef3aac107a159434a4714;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/dbfn.c b/src/src/dbfn.c index 3aca18326..be6a47afc 100644 --- a/src/src/dbfn.c +++ b/src/src/dbfn.c @@ -3,11 +3,17 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ #include "exim.h" +/* We have buffers holding path names for database files. +PATH_MAX could be used here, but would be wasting memory, as we deal +with database files like $spooldirectory/db/ */ +#define PATHLEN 256 + /* Functions for accessing Exim's hints database, which consists of a number of different DBM files. This module does not contain code for reading DBM files @@ -92,7 +98,7 @@ int rc, save_errno; BOOL read_only = flags == O_RDONLY; BOOL created = FALSE; flock_t lock_data; -uschar dirname[256], filename[256]; +uschar dirname[PATHLEN], filename[PATHLEN]; DEBUG(D_hints_lookup) acl_level++; @@ -122,7 +128,7 @@ if ((dbblock->lockfd = Uopen(filename, O_RDWR, EXIMDB_LOCKFILE_MODE)) < 0) if (dbblock->lockfd < 0) { log_write(0, LOG_MAIN, "%s", - string_open_failed(errno, "database lock file %s", filename)); + string_open_failed("database lock file %s", filename)); errno = 0; /* Indicates locking failure */ DEBUG(D_hints_lookup) acl_level--; return NULL; @@ -195,12 +201,15 @@ but creation of the database file failed. */ if (created && geteuid() == root_uid) { DIR * dd; - uschar *lastname = Ustrrchr(filename, '/') + 1; + uschar path[PATHLEN]; + uschar *lastname; int namelen = Ustrlen(name); + Ustrcpy(path, filename); + lastname = Ustrrchr(path, '/') + 1; *lastname = 0; - if ((dd = exim_opendir(filename))) + if ((dd = exim_opendir(path))) for (struct dirent *ent; ent = readdir(dd); ) if (Ustrncmp(ent->d_name, name, namelen) == 0) { @@ -208,13 +217,13 @@ if (created && geteuid() == root_uid) /* 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) + if (Ustat(path, &statbuf) >= 0 && statbuf.st_uid != exim_uid) { DEBUG(D_hints_lookup) - debug_printf_indent("ensuring %s is owned by exim\n", filename); - if (exim_chown(filename, exim_uid, exim_gid)) + debug_printf_indent("ensuring %s is owned by exim\n", path); + if (exim_chown(path, exim_uid, exim_gid)) DEBUG(D_hints_lookup) - debug_printf_indent("failed setting %s to owned by exim\n", filename); + debug_printf_indent("failed setting %s to owned by exim\n", path); } } @@ -227,12 +236,13 @@ exist. */ if (!dbblock->dbptr) { + errno = save_errno; if (lof && save_errno != ENOENT) - log_write(0, LOG_MAIN, "%s", string_open_failed(save_errno, "DB file %s", + log_write(0, LOG_MAIN, "%s", string_open_failed("DB file %s", filename)); else DEBUG(D_hints_lookup) - debug_printf_indent("%s\n", CS string_open_failed(save_errno, "DB file %s", + debug_printf_indent("%s\n", CS string_open_failed("DB file %s", filename)); (void)close(dbblock->lockfd); errno = save_errno; @@ -331,6 +341,34 @@ return yield; } +/* Read a record. If the length is not as expected then delete it, write +an error log line and return NULL. +Use this for fixed-size records (so not retry or wait records). + +Arguments: + dbblock a pointer to an open database block + key the key of the record to be read + length the expected record length + +Returns: a pointer to the retrieved record, or + NULL if the record is not found/bad +*/ + +void * +dbfn_read_enforce_length(open_db * dbblock, const uschar * key, size_t length) +{ +int rlen; +void * yield = dbfn_read_with_length(dbblock, key, &rlen); + +if (yield) + { + if (rlen == length) return yield; + log_write(0, LOG_MAIN|LOG_PANIC, "Bad db record size for '%s'", key); + dbfn_delete(dbblock, key); + } +return NULL; +} + /************************************************* * Write to database file * @@ -422,7 +460,6 @@ dbfn_scan(open_db *dbblock, BOOL start, EXIM_CURSOR **cursor) { EXIM_DATUM key_datum, value_datum; uschar *yield; -value_datum = value_datum; /* dummy; not all db libraries use this */ DEBUG(D_hints_lookup) debug_printf_indent("dbfn_scan\n");