diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-10 23:21:10 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-10 23:21:10 +0200 |
commit | ae50faba68eaa72fcdc7e2245a39a756a2eb8a09 (patch) | |
tree | efbe64e79fff03c8b24cc3e3e419265efbe8b623 /src | |
parent | cd5329d57b030186f20c069cb0dc9f6b7490f5d4 (diff) | |
download | mailfromd-ae50faba68eaa72fcdc7e2245a39a756a2eb8a09.tar.gz mailfromd-ae50faba68eaa72fcdc7e2245a39a756a2eb8a09.tar.bz2 |
Improve handling of database security flags.
* src/builtin/db.bi (db_prop)<hint>: New member.
(dbprop): Accept additional "hint" argument.
(_mf_dbm_open): Rename to _open_dbm (all uses changed). Get safety flags
from the created DB and augment them with bits deduced from the file mode.
* src/srvcfg.c (mf_srvcfg_flush): Add default parameters to the database
URL hint.
Diffstat (limited to 'src')
-rw-r--r-- | src/builtin/db.bi | 96 | ||||
-rw-r--r-- | src/srvcfg.c | 7 |
2 files changed, 74 insertions, 29 deletions
diff --git a/src/builtin/db.bi b/src/builtin/db.bi index 7c683f27..d70a5d70 100644 --- a/src/builtin/db.bi +++ b/src/builtin/db.bi @@ -21,6 +21,7 @@ struct db_prop { /* Database properties */ char *pat; /* Database name pattern */ mode_t mode; /* File mode */ int null; /* Null byte */ + mu_url_t hint; /* Hint to use instead of the default one */ }; static mu_list_t db_prop_list; @@ -65,14 +66,26 @@ strtomode(char *str, mode_t *pmode) return 0; } -/* #pragma dbprop <name> [null] [mode] */ -MF_PRAGMA(dbprop, 3, 4) +static int +is_url(const char *p) +{ + for (; *p && c_isalnum(*p); p++) + ; + return *p == ':'; +} + +/* #pragma dbprop <name> [null] [mode] [hint] + At least one of the bracketed parameters must be present. Two or more + parameters can be given in arbitrary order. + */ +MF_PRAGMA(dbprop, 3, 5) { int null = 0; mode_t mode = DEFAULT_DB_MODE; struct db_prop *prop; int rc; char *pat; + mu_url_t hint = NULL; --argc; pat = *++argv; @@ -88,6 +101,13 @@ MF_PRAGMA(dbprop, 3, 4) parse_error(_("bad numeric file mode")); return; } + } else if (is_url(p)) { + rc = mu_url_create(&hint, p); + if (rc) { + parse_error(_("not a valid URL: %s"), + mu_strerror(rc)); + return; + } } else if (rc = strtomode(p, &mode)) { parse_error(_("bad symbolic file mode (near %s)"), p + rc - 1); @@ -117,6 +137,7 @@ MF_PRAGMA(dbprop, 3, 4) } prop->mode = mode; prop->null = null; + prop->hint = hint; } const struct db_prop * @@ -144,17 +165,28 @@ db_prop_lookup(const char *name) } int -_mf_dbm_open(mu_dbm_file_t *pdb, char *dbname, int access, int mode) +_open_dbm(mu_dbm_file_t *pdb, char *dbname, int access, int mode, + mu_url_t hint) { mu_dbm_file_t db; int rc; - int sflg = MU_FILE_SAFETY_LINKED_WRDIR | - MU_FILE_SAFETY_DIR_IWOTH; + int sflg; + mu_url_t url; - rc = mu_dbm_create(dbname, &db); + if (!hint) + hint = mu_dbm_get_hint(); + rc = mu_url_create_hint(&url, dbname, 0, hint); + if (rc) { + mu_error(_("cannot create database URL for %s: %s"), + dbname, mu_strerror(rc)); + return rc; + } + rc = mu_dbm_create_from_url(url, &db); + mu_url_destroy(&url); if (rc) return rc; + mu_dbm_safety_get_flags(db, &sflg); mu_dbm_safety_set_flags(db, sflg | mf_file_mode_to_safety_criteria(mode)); rc = mu_dbm_safety_check(db); @@ -164,7 +196,7 @@ _mf_dbm_open(mu_dbm_file_t *pdb, char *dbname, int access, int mode) mu_dbm_destroy(&db); return rc; } - /* FIXME: Safety checking */ + rc = mu_dbm_open(db, access, mode); if (rc) { mu_dbm_destroy(&db); @@ -190,8 +222,8 @@ dbmap_lookup(eval_environ_t env, char *dbname, const char *keystr, if (!defval) defval = ""; - rc = _mf_dbm_open(&db, dbname, MU_STREAM_READ, - prop ? prop->mode : 0); + rc = _open_dbm(&db, dbname, MU_STREAM_READ, + prop ? prop->mode : 0, prop ? prop->hint : NULL); if (rc) MF_THROW(mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -270,9 +302,10 @@ MF_DEFUN(dbput, VOID, STRING dbname, STRING keystr, STRING value, struct mu_dbm_datum contents; const struct db_prop *prop = db_prop_lookup(dbname); - rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR, - MF_OPTVAL(mode, - (prop ? prop->mode : DEFAULT_DB_MODE))); + rc = _open_dbm(&db, dbname, MU_STREAM_RDWR, + MF_OPTVAL(mode, + (prop ? prop->mode : DEFAULT_DB_MODE)), + prop ? prop->hint : NULL); if (rc) MF_THROW(mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -313,9 +346,10 @@ MF_DEFUN(dbinsert, VOID, STRING dbname, STRING keystr, STRING value, const struct db_prop *prop = db_prop_lookup(dbname); const char *errstr; - rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR, - MF_OPTVAL(mode, - (prop ? prop->mode : DEFAULT_DB_MODE))); + rc = _open_dbm(&db, dbname, MU_STREAM_RDWR, + MF_OPTVAL(mode, + (prop ? prop->mode : DEFAULT_DB_MODE)), + prop ? prop->hint : NULL); if (rc) MF_THROW(mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -356,9 +390,10 @@ MF_DEFUN(dbdel, VOID, STRING dbname, STRING keystr, OPTIONAL, NUMBER null, int rc; const struct db_prop *prop = db_prop_lookup(dbname); - rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR, - MF_OPTVAL(mode, - (prop ? prop->mode : DEFAULT_DB_MODE))); + rc = _open_dbm(&db, dbname, MU_STREAM_RDWR, + MF_OPTVAL(mode, + (prop ? prop->mode : DEFAULT_DB_MODE)), + prop ? prop->hint : NULL); MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -441,8 +476,10 @@ MF_DEFUN(dbfirst, NUMBER, STRING dbname) struct db_tab *dbt = MF_GET_DATA; mu_dbm_file_t db; struct mu_dbm_datum key; + const struct db_prop *prop = db_prop_lookup(dbname); - rc = _mf_dbm_open(&db, dbname, MU_STREAM_READ, 0); + rc = _open_dbm(&db, dbname, MU_STREAM_READ, 0, + prop ? prop->hint : NULL); MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -594,10 +631,11 @@ do_greylist_traditional(eval_environ_t env, char *email, long interval) int readonly = 0; time_t now; - rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600); + rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600, + NULL); if (rc) { - rc = _mf_dbm_open(&db, greylist_format->dbname, - MU_STREAM_READ, 0); + rc = _open_dbm(&db, greylist_format->dbname, + MU_STREAM_READ, 0600, NULL); readonly = 1; } MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -719,10 +757,11 @@ do_greylist_ct(eval_environ_t env, char *email, long interval) int readonly = 0; time_t now; - rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600); + rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600, + NULL); if (rc) { - rc = _mf_dbm_open(&db, greylist_format->dbname, - MU_STREAM_READ, 0); + rc = _open_dbm(&db, greylist_format->dbname, + MU_STREAM_READ, 0600, NULL); readonly = 1; } MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), @@ -818,10 +857,11 @@ is_greylisted_ct(eval_environ_t env, char *email) int readonly = 0; time_t now; - rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600); + rc = _open_dbm(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600, + NULL); if (rc) { - rc = _mf_dbm_open(&db, greylist_format->dbname, - MU_STREAM_READ, 0); + rc = _open_dbm(&db, greylist_format->dbname, + MU_STREAM_READ, 0600, NULL); readonly = 1; } MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"), diff --git a/src/srvcfg.c b/src/srvcfg.c index 4030a4e6..ff99b45a 100644 --- a/src/srvcfg.c +++ b/src/srvcfg.c @@ -870,13 +870,18 @@ mf_srvcfg_flush() if (db_type_str) { mu_url_t dbhint; int rc; + static char const *defparam[] = { "linkwrdir", "awrdir" }; if ((rc = mu_url_create_null(&dbhint)) || - (rc = mu_url_set_scheme(dbhint, db_type_str))) { + (rc = mu_url_set_scheme(dbhint, db_type_str)) || + (rc = mu_url_add_param(dbhint, + MU_ARRAY_SIZE(defparam), + defparam))) { mu_error(_("cannot initialize DBM hint: %s"), mu_strerror(rc)); exit(EX_SOFTWARE); } + mu_url_destroy(&mu_dbm_hint); mu_dbm_hint = dbhint; } |