diff options
-rw-r--r-- | lib/cache.c | 6 | ||||
-rw-r--r-- | lib/db.c | 47 | ||||
-rw-r--r-- | lib/dbcfg.c | 28 | ||||
-rw-r--r-- | lib/mfdb.h | 5 | ||||
-rw-r--r-- | lib/rate.c | 2 | ||||
-rw-r--r-- | lib/tbf_rate.c | 2 | ||||
-rw-r--r-- | src/mfdbtool.c | 11 | ||||
-rw-r--r-- | src/srvcfg.c | 5 |
8 files changed, 80 insertions, 26 deletions
diff --git a/lib/cache.c b/lib/cache.c index 1a60af18..dba02160 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -78,9 +78,9 @@ cache_get(const char *email) mu_debug(cache_format->debug_handle, MU_DEBUG_TRACE5, ("getting cache info for %s", email)); - db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR, 0600); + db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR); if (!db) { - db = mf_dbm_open(cache_format->dbname, MU_STREAM_READ, 0600); + db = mf_dbm_open(cache_format->dbname, MU_STREAM_READ); if (!db) return mf_failure; readonly = 1; @@ -151,7 +151,7 @@ cache_insert(const char *email, mf_status rc) ("inserting cache info for %s. status=%s (%d), time=%s", email, mf_status_str(rc), rc, format_timestr(res.timestamp, timebuf, sizeof timebuf))); - db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR, 0600); + db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR); if (!db) return; @@ -20,11 +20,13 @@ #include <mailutils/mailutils.h> #include <string.h> -#include "mailutils/alloc.h" +#include <sysexits.h> +#include <sys/stat.h> #include "libmf.h" #include "mfdb.h" +int mf_database_mode = 0600; int ignore_failed_reads_option;//FIXME; struct db_fmt_list { @@ -100,14 +102,14 @@ mf_file_mode_to_safety_criteria(int mode) } mu_dbm_file_t -mf_dbm_open(char *dbname, int access, int mode) +mf_dbm_open(char *dbname, int access) { mu_dbm_file_t db; int rc; rc = mu_dbm_create(dbname, &db, MU_FILE_SAFETY_LINKED_WRDIR | MU_FILE_SAFETY_DIR_IWOTH| - mf_file_mode_to_safety_criteria(mode)); + mf_file_mode_to_safety_criteria(mf_database_mode)); if (rc) { mu_error(_("unable to create database %s: %s"), dbname, mu_strerror (rc)); @@ -122,7 +124,7 @@ mf_dbm_open(char *dbname, int access, int mode) return NULL; } - rc = mu_dbm_open(db, access, mode); + rc = mu_dbm_open(db, access, mf_database_mode); if (rc) { mu_error(_("mu_dbm_open(%s) failed: %s (%s)"), dbname, mu_strerror (rc), mu_strerror (errno)); @@ -140,7 +142,7 @@ db_list_item(char *dbname, char *email, db_item_printer_t fun) struct mu_dbm_datum key, contents; int rc = 1; - db = mf_dbm_open(dbname, MU_STREAM_READ, 0600); + db = mf_dbm_open(dbname, MU_STREAM_READ); if (!db) return 1; memset(&contents, 0, sizeof contents); @@ -213,7 +215,7 @@ db_list_func(struct mu_dbm_datum *key, struct mu_dbm_datum *contents, int db_list(char *dbname, db_item_printer_t fun) { - mu_dbm_file_t db = mf_dbm_open(dbname, MU_STREAM_READ, 0600); + mu_dbm_file_t db = mf_dbm_open(dbname, MU_STREAM_READ); if (!db) return 1; db_enumerate(db, db_list_func, fun); @@ -233,8 +235,8 @@ db_expire_func(struct mu_dbm_datum *key, struct mu_dbm_datum *contents, { struct expire_data *dp = data; if (dp->fun(contents)) { - mu_opool_append(dp->pool, &contents->mu_dsize, - sizeof contents->mu_dsize); + mu_opool_append(dp->pool, &key->mu_dsize, + sizeof key->mu_dsize); mu_opool_append(dp->pool, key->mu_dptr, key->mu_dsize); dp->key_count++; } @@ -252,7 +254,7 @@ db_expire(char *dbname, db_expire_t fun) size_t i; int rc = 0; - db = mf_dbm_open(dbname, MU_STREAM_RDWR, 0600); + db = mf_dbm_open(dbname, MU_STREAM_RDWR); if (!db) return 1; @@ -309,7 +311,7 @@ db_delete(char *dbname, char *id) struct mu_dbm_datum key; int rc; - db = mf_dbm_open(dbname, MU_STREAM_RDWR, 0600); + db = mf_dbm_open(dbname, MU_STREAM_RDWR); if (!db) return 1; memset(&key, 0, sizeof key); @@ -413,14 +415,32 @@ db_compact(char *dbname, db_expire_t fun) const char *file_name; int flags, rc; uid_t uid; + int fd; + struct stat st; mu_debug(debug_handle, MU_DEBUG_TRACE0, ("Compacting database `%s'", dbname)); - odb = mf_dbm_open(dbname, MU_STREAM_READ, 0600); + odb = mf_dbm_open(dbname, MU_STREAM_READ); if (!odb) return 1; + rc = mu_dbm_get_fd(odb, &fd, NULL); + if (rc) { + mu_dbm_destroy(&odb); + mu_error("mu_dbm_get_fd(%s): %s", tmpname, mu_strerror (rc)); + return 1; + } + if (fstat(fd, &st)) { + mu_error("fstat(%s): %s", tmpname, mu_strerror (errno)); + mu_dbm_destroy(&odb); + return 1; + } + if (getuid() != st.st_uid && getgid() != st.st_gid) { + if (switch_to_privs(st.st_uid, st.st_gid, NULL)) + exit(EX_SOFTWARE); + } + umask(0777 & ~ st.st_mode); mu_dbm_get_name(odb, &file_name); tmpname = make_tmp_name(file_name); @@ -431,10 +451,9 @@ db_compact(char *dbname, db_expire_t fun) tmpname, mu_strerror (rc)); return 1; } - mu_dbm_safety_get_owner(odb, &uid); - mu_dbm_safety_set_owner(dat.ndb, uid); + mu_dbm_safety_set_owner(dat.ndb, st.st_uid); - rc = mu_dbm_open(dat.ndb, MU_STREAM_CREAT, 0600); + rc = mu_dbm_open(dat.ndb, MU_STREAM_CREAT, mf_database_mode); if (rc) { mu_error(_("unable to open database %s: %s"), tmpname, mu_strerror (rc)); diff --git a/lib/dbcfg.c b/lib/dbcfg.c index ce2644c0..11999fc1 100644 --- a/lib/dbcfg.c +++ b/lib/dbcfg.c @@ -132,6 +132,22 @@ database_section_parser (enum mu_cfg_section_stage stage, return 0; } +int +cb_database_mode(void *data, mu_config_value_t *arg) +{ + unsigned long mode; + char *end; + if (mu_cfg_assert_value_type(arg, MU_CFG_STRING)) + return 1; + mode = strtoul(arg->v.string, &end, 0); + if (*end || (mode & ~0777)) { + mu_error("%s", _("invalid file mode")); + return 1; + } else + *(int*)data = mode; + return 0; +} + void database_cfg_init() { @@ -142,5 +158,17 @@ database_cfg_init() section->docstring = N_("Define a database."); mu_cfg_section_add_params(section, database_section_param); } +#if 0 +// FIXME: If MU had canned params, I could've done something along these +// lines. Unfortunately, it doesn't + + if (mu_create_canned_param ("database-mode", ¶m) == 0) { + param->type = mu_cfg_callback; + param->callback = cb_database_mode; + param->docstring = + N_("Configure file mode for database files"); + param->argname = N_("mode: octal"); + } +#endif } @@ -34,13 +34,14 @@ typedef int (*dbfmt_enumerator_t)(struct db_format *fmt, void *); extern mu_debug_handle_t db_debug_handle; extern struct db_format *cache_format; +extern int mf_database_mode; struct db_format *cache_format; struct db_format *rate_format; struct db_format *tbf_rate_format; struct db_format *greylist_format; -mu_dbm_file_t mf_dbm_open(char *dbname, int access, int mode); +mu_dbm_file_t mf_dbm_open(char *dbname, int access); int mf_file_mode_to_safety_criteria(int mode); @@ -55,7 +56,7 @@ int db_delete(char *dbname, char *id); int db_compact(char *dbname, db_expire_t fun); void database_cfg_init(void); - +int cb_database_mode(void *data, mu_config_value_t *arg); /* cache.c */ mf_status cache_get(const char *email); @@ -64,7 +64,7 @@ get_rate(char *email, long *ret, unsigned long interval, size_t mincount, mu_debug(rate_format->debug_handle, MU_DEBUG_TRACE5, ("getting rate info for %s", email)); - db = mf_dbm_open(rate_format->dbname, MU_STREAM_RDWR, 0600); + db = mf_dbm_open(rate_format->dbname, MU_STREAM_RDWR); if (!db) return mf_failure; diff --git a/lib/tbf_rate.c b/lib/tbf_rate.c index 6817a7fc..b9348758 100644 --- a/lib/tbf_rate.c +++ b/lib/tbf_rate.c @@ -105,7 +105,7 @@ check_tbf_rate(char *email, int *ret, mu_debug(tbf_rate_format->debug_handle, MU_DEBUG_TRACE5, ("getting TBF rate info for %s", email)); - db = mf_dbm_open(tbf_rate_format->dbname, MU_STREAM_RDWR, 0600);\ + db = mf_dbm_open(tbf_rate_format->dbname, MU_STREAM_RDWR); if (!db) { mu_error(_("mf_dbm_open(%s) failed: %s"), tbf_rate_format->dbname, diff --git a/src/mfdbtool.c b/src/mfdbtool.c index 1571526e..db6bc18c 100644 --- a/src/mfdbtool.c +++ b/src/mfdbtool.c @@ -28,6 +28,7 @@ #include "libmf.h" #include "mfdb.h" +#include "filenames.h" char *state_dir = DEFAULT_STATE_DIR; char *file_option; /* File name for DB management commands */ @@ -140,7 +141,6 @@ db_proc_enumerator(struct db_format *fmt, void *data) void mfdbtool_expire(int argc, char **argv) { - /*FIXME: priv_setup(); */ if (all_option) db_format_enumerate(db_proc_enumerator, db_expire); else { @@ -155,7 +155,6 @@ mfdbtool_expire(int argc, char **argv) void mfdbtool_compact(int argc, char **argv) { - /* FIXME: priv_setup(); */ if (all_option) db_format_enumerate(db_proc_enumerator, db_compact); else { @@ -306,6 +305,10 @@ struct mu_cfg_param mfdbtool_cfg_param[] = { N_("Default database type"), N_("type") }, { "database", mu_cfg_section, NULL, 0, NULL, NULL }, + { "database-mode", mu_cfg_callback, + &mf_database_mode, 0, cb_database_mode, + N_("Configure file mode for database files"), + N_("mode: octal") }, { "state-directory", mu_c_string, &state_dir, 0, NULL, N_("Set program state directory."), N_("dir") }, @@ -359,9 +362,7 @@ main(int argc, char **argv) db_format_setup(); database_cfg_init(); - mf_getopt(&cli, &argc, &argv, capa, 0, - /* FIXME: Use mailfromd.conf somehow? */ - SYSCONFDIR "/mfdbtool.conf"); + mf_getopt(&cli, &argc, &argv, capa, 0, DEFAULT_CONFIG_FILE); if (db_type_str) { mu_url_t dbhint; diff --git a/src/srvcfg.c b/src/srvcfg.c index 1f39921a..57388122 100644 --- a/src/srvcfg.c +++ b/src/srvcfg.c @@ -30,6 +30,7 @@ #include "srvman.h" #include "gacopyz.h" #include "srvcfg.h" +#include "mfdb.h" char *mailfromd_state_dir; int server_flags = 0; @@ -523,6 +524,10 @@ static struct mu_cfg_param srv_cfg_param[] = { N_("Default database type"), N_("type") }, { "database", mu_cfg_section, NULL, 0, NULL, NULL }, + { "database-mode", mu_cfg_callback, + &mf_database_mode, 0, cb_database_mode, + N_("Configure file mode for database files"), + N_("mode: octal") }, { "ehlo-domain", mu_c_string, &ehlo_domain, 0, NULL, N_("Set the domain name for EHLO command.") }, { "mail-from-address", mu_c_string, &mailfrom_address, 0, NULL, |