dovecot-2.0-sslstream: lib-storage: Changed APIs to fix reading ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 02:55:24 EET 2010
details: http://hg.dovecot.org/dovecot-2.0-sslstream/rev/545bdb7670d2
changeset: 10135:545bdb7670d2
user: Timo Sirainen <tss at iki.fi>
date: Thu Oct 22 18:31:18 2009 -0400
description:
lib-storage: Changed APIs to fix reading settings for multiple users.
diffstat:
14 files changed, 220 insertions(+), 81 deletions(-)
src/lda/main.c | 4
src/lib-storage/index/shared/shared-storage.c | 3
src/lib-storage/mail-namespace.c | 4
src/lib-storage/mail-storage-service.c | 150 +++++++++++++++++++------
src/lib-storage/mail-storage-service.h | 5
src/lib-storage/mail-storage-settings.c | 17 +-
src/lib-storage/mail-storage-settings.h | 7 -
src/lib-storage/mail-user.c | 13 +-
src/lib-storage/mail-user.h | 2
src/lmtp/client.c | 51 +++++++-
src/lmtp/client.h | 5
src/lmtp/commands.c | 4
src/lmtp/lmtp-settings.c | 12 +-
src/lmtp/main.c | 24 +---
diffs (truncated from 709 to 300 lines):
diff -r 1eedcee69ce7 -r 545bdb7670d2 src/lda/main.c
--- a/src/lda/main.c Thu Oct 22 18:27:57 2009 -0400
+++ b/src/lda/main.c Thu Oct 22 18:31:18 2009 -0400
@@ -393,14 +393,14 @@ int main(int argc, char *argv[])
lib_signals_ignore(SIGXFSZ, TRUE);
#endif
ctx.set = mail_storage_service_user_get_set(service_user)[1];
- duplicate_init(mail_user_set_get_storage_set(ctx.dest_user->set));
+ duplicate_init(mail_user_set_get_storage_set(ctx.dest_user));
/* create a separate mail user for the internal namespace */
if (master_service_set(master_service,
"mail_full_filesystem_access=yes") < 0)
i_unreached();
sets = master_service_settings_get_others(master_service);
- raw_mail_user = mail_user_alloc(user, sets[0]);
+ raw_mail_user = mail_user_alloc(user, ctx.dest_user->set_info, sets[0]);
mail_user_set_home(raw_mail_user, "/");
if (mail_user_init(raw_mail_user, &errstr) < 0)
i_fatal("Raw user initialization failed: %s", errstr);
diff -r 1eedcee69ce7 -r 545bdb7670d2 src/lib-storage/index/shared/shared-storage.c
--- a/src/lib-storage/index/shared/shared-storage.c Thu Oct 22 18:27:57 2009 -0400
+++ b/src/lib-storage/index/shared/shared-storage.c Thu Oct 22 18:31:18 2009 -0400
@@ -223,7 +223,8 @@ int shared_storage_get_namespace(struct
return 0;
}
- owner = mail_user_alloc(userdomain, user->unexpanded_set);
+ owner = mail_user_alloc(userdomain, user->set_info,
+ user->unexpanded_set);
if (!var_has_key(storage->location, 'h', "home"))
ret = 1;
else {
diff -r 1eedcee69ce7 -r 545bdb7670d2 src/lib-storage/mail-namespace.c
--- a/src/lib-storage/mail-namespace.c Thu Oct 22 18:27:57 2009 -0400
+++ b/src/lib-storage/mail-namespace.c Thu Oct 22 18:31:18 2009 -0400
@@ -236,7 +236,7 @@ int mail_namespaces_init(struct mail_use
namespaces = NULL; ns_p = &namespaces;
- mail_set = mail_user_set_get_storage_set(user->set);
+ mail_set = mail_user_set_get_storage_set(user);
if (array_is_created(&user->set->namespaces))
ns_set = array_get(&user->set->namespaces, &count);
else {
@@ -335,7 +335,7 @@ struct mail_namespace *mail_namespaces_i
ns->prefix = i_strdup("");
ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST_PREFIX |
NAMESPACE_FLAG_SUBSCRIPTIONS;
- ns->mail_set = mail_user_set_get_storage_set(user->set);
+ ns->mail_set = mail_user_set_get_storage_set(user);
user->namespaces = ns;
return ns;
}
diff -r 1eedcee69ce7 -r 545bdb7670d2 src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c Thu Oct 22 18:27:57 2009 -0400
+++ b/src/lib-storage/mail-storage-service.c Thu Oct 22 18:31:18 2009 -0400
@@ -44,6 +44,7 @@ struct mail_storage_service_user {
const char *system_groups_user;
const struct mail_user_settings *user_set;
+ const struct setting_parser_info *user_info;
struct setting_parser_context *set_parser;
};
@@ -291,16 +292,20 @@ service_drop_privileges(const struct mai
static int
mail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
- const struct mail_storage_service_input *input,
- const char *home,
- const struct mail_user_settings *user_set,
- struct mail_user **mail_user_r,
+ struct mail_storage_service_user *user,
+ const char *home, struct mail_user **mail_user_r,
const char **error_r)
{
const struct mail_storage_settings *mail_set;
struct mail_user *mail_user;
- mail_set = mail_user_set_get_storage_set(user_set);
+ mail_user = mail_user_alloc(user->input.username, user->user_info,
+ user->user_set);
+ mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
+ mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
+ &user->input.local_ip, &user->input.remote_ip);
+
+ mail_set = mail_user_set_get_storage_set(mail_user);
if (mail_set->mail_debug) {
i_debug("Effective uid=%s, gid=%s, home=%s",
@@ -323,10 +328,6 @@ mail_storage_service_init_post(struct ma
}
}
- mail_user = mail_user_alloc(input->username, user_set);
- mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
- mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
- &input->local_ip, &input->remote_ip);
if (mail_user_init(mail_user, error_r) < 0) {
mail_user_unref(&mail_user);
return -1;
@@ -482,19 +483,93 @@ mail_storage_service_get_auth_conn(struc
return ctx->conn;
}
-static int
-mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
- const struct mail_storage_service_input *input,
- bool preserve_home, const char **error_r)
+static void
+settings_parser_update_children_parent(struct setting_parser_info *parent,
+ pool_t pool)
+{
+ struct setting_define *new_defs;
+ struct setting_parser_info *new_info;
+ unsigned int i, count;
+
+ for (count = 0; parent->defines[count].key != NULL; count++) ;
+
+ new_defs = p_new(pool, struct setting_define, count + 1);
+ memcpy(new_defs, parent->defines, sizeof(*new_defs) * count);
+ parent->defines = new_defs;
+
+ for (i = 0; i < count; i++) {
+ if (new_defs[i].list_info == NULL ||
+ new_defs[i].list_info->parent == NULL)
+ continue;
+
+ new_info = p_new(pool, struct setting_parser_info, 1);
+ *new_info = *new_defs[i].list_info;
+ new_info->parent = parent;
+ new_defs[i].list_info = new_info;
+ }
+}
+
+static void
+dyn_parsers_update_parent(pool_t pool,
+ struct master_service_settings_input *input)
+{
+ const struct setting_parser_info *old_parent, **new_roots;
+ struct setting_parser_info *new_parent, *new_info;
+ struct dynamic_settings_parser *new_dyn_parsers;
+ unsigned int i, count;
+
+ /* settings_parser_info_update() modifies the parent structure.
+ since we may be using the same structure later, we want it to be
+ in its original state, so we'll have to copy all structures. */
+ old_parent = input->dyn_parsers[0].info->parent;
+ new_parent = p_new(pool, struct setting_parser_info, 1);
+ *new_parent = *old_parent;
+ settings_parser_update_children_parent(new_parent, pool);
+
+ /* update root */
+ for (count = 0; input->roots[count] != NULL; count++) ;
+ new_roots = p_new(pool, const struct setting_parser_info *, count + 1);
+ for (i = 0; i < count; i++) {
+ if (input->roots[i] == old_parent)
+ new_roots[i] = new_parent;
+ else
+ new_roots[i] = input->roots[i];
+ }
+ input->roots = new_roots;
+
+ /* update parent in dyn_parsers */
+ for (count = 0; input->dyn_parsers[count].name != NULL; count++) ;
+ new_dyn_parsers = p_new(pool, struct dynamic_settings_parser, count + 1);
+ for (i = 0; i < count; i++) {
+ new_dyn_parsers[i] = input->dyn_parsers[i];
+
+ new_info = p_new(pool, struct setting_parser_info, 1);
+ *new_info = *input->dyn_parsers[i].info;
+ new_info->parent = new_parent;
+ new_dyn_parsers[i].info = new_info;
+ }
+ input->dyn_parsers = new_dyn_parsers;
+}
+
+int mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
+ const struct mail_storage_service_input *input,
+ pool_t pool,
+ const struct setting_parser_info **user_info_r,
+ const char **error_r)
{
struct master_service_settings_input set_input;
-
- /* read settings after registering storages so they can have their
- own setting definitions too */
+ unsigned int i;
+
memset(&set_input, 0, sizeof(set_input));
set_input.roots = ctx->set_roots;
set_input.dyn_parsers = mail_storage_get_dynamic_parsers();
- set_input.preserve_home = preserve_home;
+ /* settings reader may exec doveconf, which is going to clear
+ environment, and if we're not doing a userdb lookup we want to
+ use $HOME */
+ set_input.preserve_home =
+ (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
+ dyn_parsers_update_parent(pool, &set_input);
+
if (input != NULL) {
set_input.module = input->module;
set_input.service = input->service;
@@ -508,17 +583,27 @@ mail_storage_service_read_settings(struc
*error_r);
return -1;
}
- return 0;
+
+ for (i = 0; ctx->set_roots[i] != NULL; i++) {
+ if (ctx->set_roots[i] == &mail_user_setting_parser_info) {
+ *user_info_r = set_input.roots[i];
+ return 0;
+ }
+ }
+ i_unreached();
+ return -1;
}
static void
mail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
+ const struct setting_parser_info *user_info,
const struct mail_user_settings *user_set)
{
const struct mail_storage_settings *mail_set;
- mail_set = mail_user_set_get_storage_set(user_set);
- ctx->debug = mail_user_set_get_storage_set(user_set)->mail_debug;
+ mail_set = mail_user_set_get_driver_settings(user_info, user_set,
+ MAIL_STORAGE_SET_DRIVER_NAME);
+ ctx->debug = mail_set->mail_debug;
modules = *user_set->mail_plugins == '\0' ? NULL :
module_dir_load(user_set->mail_plugin_dir,
@@ -526,7 +611,7 @@ mail_storage_service_first_init(struct m
master_service_get_version_string(ctx->service));
ctx->conn = auth_master_init(user_set->auth_socket_path,
- mail_set->mail_debug);
+ ctx->debug);
i_assert(mail_user_auth_master_conn == NULL);
mail_user_auth_master_conn = ctx->conn;
@@ -539,26 +624,26 @@ int mail_storage_service_lookup(struct m
{
struct mail_storage_service_user *user;
const char *username = input->username;
+ const struct setting_parser_info *user_info;
const struct mail_user_settings *user_set;
const char *const *userdb_fields;
struct auth_user_reply reply;
void **sets;
pool_t user_pool, temp_pool;
- bool keep_home;
int ret = 1;
- /* settings reader may exec doveconf, which is going to clear
- environment, and if we're not doing a userdb lookup we want to
- use $HOME */
- keep_home = (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
- if (mail_storage_service_read_settings(ctx, input, keep_home,
- error_r) < 0)
+ user_pool = pool_alloconly_create("mail storage service user", 1024*4);
+
+ if (mail_storage_service_read_settings(ctx, input, user_pool,
+ &user_info, error_r) < 0) {
+ pool_unref(&user_pool);
return -1;
+ }
sets = settings_parser_get_list(ctx->service->set_parser);
user_set = sets[1];
if (ctx->conn == NULL)
- mail_storage_service_first_init(ctx, user_set);
+ mail_storage_service_first_init(ctx, user_info, user_set);
temp_pool = pool_alloconly_create("userdb lookup", 1024);
if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
@@ -567,26 +652,27 @@ int mail_storage_service_lookup(struct m
error_r);
if (ret <= 0) {
pool_unref(&temp_pool);
+ pool_unref(&user_pool);
return ret;
}
} else {
userdb_fields = input->userdb_fields;
}
- user_pool = pool_alloconly_create("mail storage service user", 1024*3);
user = p_new(user_pool, struct mail_storage_service_user, 1);
memset(user_r, 0, sizeof(user_r));
user->pool = user_pool;
user->input = *input;
user->input.userdb_fields = NULL;
user->input.username = p_strdup(user_pool, username);
+ user->user_info = user_info;
user->set_parser =
More information about the dovecot-cvs
mailing list