Sharing an installed copy of dovecot between several users each running a daemon within their own account (or using the same binaries for a system daemon and a user daemon) is difficult because the compile-time directory PKG_STATEDIR (typically /var/lib/dovecot) is hard-coded as the location of things like the ssl-parameters.dat file and the replicator database. Replace all these uses of PKG_STATEDIR with a state_dir setting which defaults to PKG_STATEDIR but can be overridden in dovecot.conf, in the same way base_dir can be used to override PKG_RUNDIR. Signed-off-by: <chris@arachsys.com> --- src/config/Makefile.am | 1 - src/doveadm/doveadm-instance.c | 10 ++++------ src/doveadm/doveadm-mount.c | 3 +-- src/doveadm/doveadm-settings.c | 2 -- src/doveadm/doveadm-settings.h | 1 - src/lib-master/master-instance.h | 2 ++ src/lib-master/master-service-settings.c | 2 -- src/lib-master/master-service-settings.h | 1 - src/lib-master/master-service.c | 6 ++---- src/login-common/ssl-proxy-openssl.c | 3 ++- src/master/main.c | 11 ++++------- src/master/master-settings.c | 6 ++---- src/master/master-settings.h | 1 - src/replication/replicator/replicator-settings.c | 2 -- src/replication/replicator/replicator-settings.h | 1 - src/replication/replicator/replicator.c | 16 +++++----------- src/ssl-params/main.c | 5 ++--- src/ssl-params/ssl-params-settings.c | 2 -- src/ssl-params/ssl-params-settings.h | 1 - 19 files changed, 24 insertions(+), 52 deletions(-) diff --git a/src/config/Makefile.am b/src/config/Makefile.am --- a/src/config/Makefile.am +++ b/src/config/Makefile.am @@ -9,6 +9,7 @@ -I$(top_srcdir)/src/lib-settings \ -I$(top_srcdir)/src/lib-master \ -DPKG_RUNDIR=\""$(rundir)"\" \ + -DPKG_STATEDIR=\""$(statedir)"\" \ -DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \ -DEXAMPLE_CONFIG_DIR=\""$(exampledir)"\" \ -DMODULEDIR=\""$(moduledir)"\" \ diff --git a/src/doveadm/doveadm-instance.c b/src/doveadm/doveadm-instance.c --- a/src/doveadm/doveadm-instance.c +++ b/src/doveadm/doveadm-instance.c @@ -48,7 +48,7 @@ struct master_instance_list *list; struct master_instance_list_iter *iter; const struct master_instance *inst; - const char *pidfile_path; + const char *instance_path, *pidfile_path; bool show_config = FALSE; int c; @@ -71,7 +71,8 @@ doveadm_print_header_simple("running"); } - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(doveadm_settings->state_dir, "/instances", NULL); + list = master_instance_list_init(instance_path); iter = master_instance_list_iterate_init(list); while ((inst = master_instance_iterate_list_next(iter)) != NULL) { if (argv[0] != NULL && strcmp(argv[0], inst->name) != 0) @@ -99,13 +100,14 @@ { struct master_instance_list *list; const struct master_instance *inst; - const char *base_dir; + const char *base_dir, *instance_path; int ret; if (argc != 2) instance_cmd_help(cmd_instance_remove); - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(doveadm_settings->state_dir, "/instances", NULL); + list = master_instance_list_init(instance_path); inst = master_instance_list_find_by_name(list, argv[1]); base_dir = inst != NULL ? inst->base_dir : argv[1]; if ((ret = master_instance_list_remove(list, base_dir)) < 0) { diff --git a/src/doveadm/doveadm-mount.c b/src/doveadm/doveadm-mount.c --- a/src/doveadm/doveadm-mount.c +++ b/src/doveadm/doveadm-mount.c @@ -13,7 +13,8 @@ { const char *perm_path, *state_path; - perm_path = t_strconcat(PKG_STATEDIR"/"MOUNTPOINT_LIST_FNAME, NULL); + perm_path = t_strconcat(doveadm_settings->state_dir, + "/"MOUNTPOINT_LIST_FNAME, NULL); state_path = t_strconcat(doveadm_settings->base_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); return mountpoint_list_init(perm_path, state_path); diff --git a/src/doveadm/doveadm-settings.c b/src/doveadm/doveadm-settings.c --- a/src/doveadm/doveadm-settings.c +++ b/src/doveadm/doveadm-settings.c @@ -53,6 +53,7 @@ static const struct setting_define doveadm_setting_defines[] = { DEF(SET_STR, base_dir), + DEF(SET_STR, state_dir), DEF(SET_STR, mail_plugins), DEF(SET_STR, mail_plugin_dir), DEF(SET_STR, doveadm_socket_path), @@ -70,6 +71,7 @@ const struct doveadm_settings doveadm_default_settings = { .base_dir = PKG_RUNDIR, + .state_dir = PKG_STATEDIR, .mail_plugins = "", .mail_plugin_dir = MODULEDIR, .doveadm_socket_path = "doveadm-server", diff --git a/src/doveadm/doveadm-settings.h b/src/doveadm/doveadm-settings.h --- a/src/doveadm/doveadm-settings.h +++ b/src/doveadm/doveadm-settings.h @@ -3,6 +3,7 @@ struct doveadm_settings { const char *base_dir; + const char *state_dir; const char *mail_plugins; const char *mail_plugin_dir; const char *doveadm_socket_path; diff --git a/src/lib-master/master-instance.h b/src/lib-master/master-instance.h --- a/src/lib-master/master-instance.h +++ b/src/lib-master/master-instance.h @@ -1,8 +1,6 @@ #ifndef MASTER_INSTANCE_H #define MASTER_INSTANCE_H -#define MASTER_INSTANCE_PATH PKG_STATEDIR"/instances" - struct master_instance_list; struct master_instance { diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -33,6 +33,7 @@ master_service_settings_check(void *_set, pool_t pool, const char **error_r); static const struct setting_define master_service_setting_defines[] = { + DEF(SET_STR, state_dir), DEF(SET_STR, log_path), DEF(SET_STR, info_log_path), DEF(SET_STR, debug_log_path), @@ -47,6 +48,7 @@ }; static const struct master_service_settings master_service_default_settings = { + .state_dir = PKG_STATEDIR, .log_path = "syslog", .info_log_path = "", .debug_log_path = "", diff --git a/src/lib-master/master-service-settings.h b/src/lib-master/master-service-settings.h --- a/src/lib-master/master-service-settings.h +++ b/src/lib-master/master-service-settings.h @@ -7,6 +7,7 @@ struct master_service; struct master_service_settings { + const char *state_dir; const char *log_path; const char *info_log_path; const char *debug_log_path; diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -332,9 +332,11 @@ { struct master_instance_list *list; const struct master_instance *inst; - const char *path; + const char *instance_path, *path; - list = master_instance_list_init(MASTER_INSTANCE_PATH); + instance_path = t_strconcat(master_service->set->state_dir, + "/instances", NULL); + list = master_instance_list_init(instance_path); inst = master_instance_list_find_by_name(list, name); if (inst != NULL) { path = t_strdup_printf("%s/dovecot.conf", inst->base_dir); diff --git a/src/login-common/ssl-proxy-openssl.c b/src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c +++ b/src/login-common/ssl-proxy-openssl.c @@ -152,8 +152,7 @@ static void ssl_params_corrupted(void) { - i_fatal("Corrupted SSL parameters file: " - PKG_STATEDIR"/ssl-parameters.dat"); + i_fatal("Corrupted SSL parameters file: ssl-parameters.dat"); } static void read_next(struct ssl_parameters *params, void *data, size_t size) diff --git a/src/master/main.c b/src/master/main.c --- a/src/master/main.c +++ b/src/master/main.c @@ -311,7 +311,7 @@ struct mountpoint_list *mountpoints; const char *perm_path, *state_path; - perm_path = t_strconcat(PKG_STATEDIR"/"MOUNTPOINT_LIST_FNAME, NULL); + perm_path = t_strconcat(set->state_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); state_path = t_strconcat(set->base_dir, "/"MOUNTPOINT_LIST_FNAME, NULL); mountpoints = mountpoint_list_init(perm_path, state_path); @@ -340,9 +340,12 @@ instance_update_now, list); } -static void instance_update(void) +static void instance_update(const struct master_settings *set) { - instances = master_instance_list_init(MASTER_INSTANCE_PATH); + const char *path; + + path = t_strconcat(set->state_dir, "/instances", NULL); + instances = master_instance_list_init(path); instance_update_now(instances); } @@ -538,7 +541,7 @@ create_pid_file(pidfile_path); create_config_symlink(set); mountpoints_update(set); - instance_update(); + instance_update(set); services_monitor_start(services); } diff --git a/src/master/master-settings.c b/src/master/master-settings.c --- a/src/master/master-settings.c +++ b/src/master/master-settings.c @@ -171,6 +171,7 @@ static const struct setting_define master_setting_defines[] = { DEF(SET_STR, base_dir), + DEF(SET_STR, state_dir), DEF(SET_STR, libexec_dir), DEF(SET_STR, instance_name), DEF(SET_STR, import_environment), @@ -211,6 +212,7 @@ static const struct master_settings master_default_settings = { .base_dir = PKG_RUNDIR, + .state_dir = PKG_STATEDIR, .libexec_dir = PKG_LIBEXECDIR, .instance_name = PACKAGE, .import_environment = "TZ" ENV_SYSTEMD ENV_GDB, @@ -737,8 +739,8 @@ } /* Make sure our permanent state directory exists */ - if (mkdir_parents(PKG_STATEDIR, 0750) < 0 && errno != EEXIST) { - i_error("mkdir(%s) failed: %m", PKG_STATEDIR); + if (mkdir_parents(set->state_dir, 0750) < 0 && errno != EEXIST) { + i_error("mkdir(%s) failed: %m", set->state_dir); return FALSE; } diff --git a/src/master/master-settings.h b/src/master/master-settings.h --- a/src/master/master-settings.h +++ b/src/master/master-settings.h @@ -5,6 +5,7 @@ struct master_settings { const char *base_dir; + const char *state_dir; const char *libexec_dir; const char *instance_name; const char *import_environment; diff --git a/src/replication/replicator/replicator-settings.c b/src/replication/replicator/replicator-settings.c --- a/src/replication/replicator/replicator-settings.c +++ b/src/replication/replicator/replicator-settings.c @@ -49,6 +49,7 @@ { type, #name, offsetof(struct replicator_settings, name), NULL } static const struct setting_define replicator_setting_defines[] = { + DEF(SET_STR, state_dir), DEF(SET_STR, auth_socket_path), DEF(SET_STR, doveadm_socket_path), @@ -59,6 +60,7 @@ }; const struct replicator_settings replicator_default_settings = { + .state_dir = PKG_STATEDIR, .auth_socket_path = "auth-userdb", .doveadm_socket_path = "doveadm-server", diff --git a/src/replication/replicator/replicator-settings.h b/src/replication/replicator/replicator-settings.h --- a/src/replication/replicator/replicator-settings.h +++ b/src/replication/replicator/replicator-settings.h @@ -2,6 +2,7 @@ #define REPLICATOR_SETTINGS_H struct replicator_settings { + const char *state_dir; const char *auth_socket_path; const char *doveadm_socket_path; diff --git a/src/replication/replicator/replicator.c b/src/replication/replicator/replicator.c --- a/src/replication/replicator/replicator.c +++ b/src/replication/replicator/replicator.c @@ -13,7 +13,6 @@ #define REPLICATOR_AUTH_SERVICE_NAME "replicator" #define REPLICATOR_DB_DUMP_INTERVAL_MSECS (1000*60*15) -#define REPLICATOR_DB_PATH PKG_STATEDIR"/replicator.db" static struct replicator_queue *queue; static struct replicator_brain *brain; @@ -32,7 +31,7 @@ struct auth_master_user_list_ctx *ctx; struct auth_user_info user_info; struct replicator_user *user; - const char *username; + const char *db_path, *username; auth_conn = auth_master_init(set->auth_socket_path, AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT); @@ -53,12 +52,16 @@ auth_master_deinit(&auth_conn); /* add updates from replicator db, if it exists */ - (void)replicator_queue_import(queue, REPLICATOR_DB_PATH); + db_path = t_strconcat(set->state_dir, "replicator.db", NULL); + (void)replicator_queue_import(queue, db_path); } static void replicator_dump_timeout(void *context ATTR_UNUSED) { - (void)replicator_queue_export(queue, REPLICATOR_DB_PATH); + const char *db_path; + + db_path = t_strconcat(set->state_dir, "replicator.db", NULL); + (void)replicator_queue_export(queue, db_path); } static void main_init(void) @@ -77,10 +80,13 @@ static void main_deinit(void) { + const char *db_path; + notify_connections_destroy_all(); replicator_brain_deinit(&brain); timeout_remove(&to_dump); - (void)replicator_queue_export(queue, REPLICATOR_DB_PATH); + db_path = t_strconcat(set->state_dir, "replicator.db", NULL); + (void)replicator_queue_export(queue, db_path); replicator_queue_deinit(&queue); } diff --git a/src/ssl-params/main.c b/src/ssl-params/main.c --- a/src/ssl-params/main.c +++ b/src/ssl-params/main.c @@ -112,11 +112,12 @@ static void main_init(const struct ssl_params_settings *set) { + const char *filename; lib_signals_set_handler(SIGCHLD, LIBSIG_FLAGS_SAFE, sig_chld, NULL); ssl_params = buffer_create_dynamic(default_pool, 1024); - param = ssl_params_init(PKG_STATEDIR"/"SSL_BUILD_PARAM_FNAME, - ssl_params_callback, set); + filename = t_strconcat(set->state_dir, "/"SSL_BUILD_PARAM_FNAME, NULL); + param = ssl_params_init(filename, ssl_params_callback, set); } static void main_deinit(void) diff --git a/src/ssl-params/ssl-params-settings.c b/src/ssl-params/ssl-params-settings.c --- a/src/ssl-params/ssl-params-settings.c +++ b/src/ssl-params/ssl-params-settings.c @@ -58,12 +58,14 @@ { type, #name, offsetof(struct ssl_params_settings, name), NULL } static const struct setting_define ssl_params_setting_defines[] = { + DEF(SET_STR, state_dir), DEF(SET_TIME, ssl_parameters_regenerate), SETTING_DEFINE_LIST_END }; static const struct ssl_params_settings ssl_params_default_settings = { + .state_dir = PKG_STATEDIR, .ssl_parameters_regenerate = 3600*24*7 }; diff --git a/src/ssl-params/ssl-params-settings.h b/src/ssl-params/ssl-params-settings.h --- a/src/ssl-params/ssl-params-settings.h +++ b/src/ssl-params/ssl-params-settings.h @@ -4,6 +4,7 @@ struct master_service; struct ssl_params_settings { + const char *state_dir; unsigned int ssl_parameters_regenerate; };