aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cache.c6
-rw-r--r--lib/db.c47
-rw-r--r--lib/dbcfg.c28
-rw-r--r--lib/mfdb.h5
-rw-r--r--lib/rate.c2
-rw-r--r--lib/tbf_rate.c2
-rw-r--r--src/mfdbtool.c11
-rw-r--r--src/srvcfg.c5
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;
diff --git a/lib/db.c b/lib/db.c
index c5282c60..d5e85129 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -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", &param) == 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
}
diff --git a/lib/mfdb.h b/lib/mfdb.h
index 387c3e6a..4bdc705a 100644
--- a/lib/mfdb.h
+++ b/lib/mfdb.h
@@ -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);
diff --git a/lib/rate.c b/lib/rate.c
index 9e06905e..84e46f6c 100644
--- a/lib/rate.c
+++ b/lib/rate.c
@@ -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,

Return to:

Send suggestions and report system problems to the System administrator.