Mercurial > dovecot > core-2.2
changeset 10130:d1384c2b08e5 HEAD
Merged single and multi mail_storage_service_*() functions.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 21 Oct 2009 19:54:00 -0400 |
parents | 3c87c0b18090 |
children | 9ef0821a2ce7 |
files | src/doveadm/doveadm-mail.c src/dsync/dsync.c src/imap/imap-client.c src/imap/imap-client.h src/imap/main.c src/lda/main.c src/lib-storage/mail-storage-service.c src/lib-storage/mail-storage-service.h src/lib-storage/mail-user.c src/lib-storage/mail-user.h src/lmtp/client.c src/lmtp/client.h src/lmtp/commands.c src/lmtp/main.c src/lmtp/main.h src/plugins/convert/convert-tool.c src/plugins/expire/expire-tool.c src/pop3/main.c src/pop3/pop3-client.c src/pop3/pop3-client.h |
diffstat | 20 files changed, 438 insertions(+), 474 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/doveadm-mail.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/doveadm/doveadm-mail.c Wed Oct 21 19:54:00 2009 -0400 @@ -79,35 +79,44 @@ enum mail_storage_service_flags service_flags, const char *args[]) { + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; struct mail_storage_service_input input; struct mail_user *mail_user; + const char *error; if (username == NULL) i_fatal("USER environment is missing and -u option not used"); memset(&input, 0, sizeof(input)); input.username = username; - mail_user = mail_storage_service_init_user(master_service, &input, NULL, - service_flags); + + storage_service = mail_storage_service_init(master_service, NULL, + service_flags); + if (mail_storage_service_lookup_next(storage_service, &input, + &service_user, &mail_user, + &error) <= 0) + i_fatal("%s", error); cmd(mail_user, args); mail_user_unref(&mail_user); - mail_storage_service_deinit_user(); + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); } static int doveadm_mail_next_user(doveadm_mail_command_t *cmd, - struct mail_storage_service_multi_ctx *multi, + struct mail_storage_service_ctx *storage_service, const struct mail_storage_service_input *input, - pool_t pool, const char *args[]) + const char *args[]) { - struct mail_storage_service_multi_user *multi_user; + struct mail_storage_service_user *service_user; struct mail_user *mail_user; const char *error; int ret; i_set_failure_prefix(t_strdup_printf("doveadm(%s): ", input->username)); - ret = mail_storage_service_multi_lookup(multi, input, pool, - &multi_user, &error); + ret = mail_storage_service_lookup(storage_service, input, + &service_user, &error); if (ret <= 0) { if (ret == 0) { i_info("User no longer exists, skipping"); @@ -117,14 +126,14 @@ return -1; } } - if (mail_storage_service_multi_next(multi, multi_user, - &mail_user, &error) < 0) { + if (mail_storage_service_next(storage_service, service_user, + &mail_user, &error) < 0) { i_error("User init failed: %s", error); - mail_storage_service_multi_user_free(multi_user); + mail_storage_service_user_free(&service_user); return -1; } - mail_storage_service_multi_user_free(multi_user); cmd(mail_user, args); + mail_storage_service_user_free(&service_user); mail_user_unref(&mail_user); return 0; } @@ -140,10 +149,9 @@ const char *args[]) { struct mail_storage_service_input input; - struct mail_storage_service_multi_ctx *multi; + struct mail_storage_service_ctx *storage_service; unsigned int user_idx, user_count, interval, n; const char *user; - pool_t pool; int ret; service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; @@ -151,25 +159,24 @@ memset(&input, 0, sizeof(input)); input.service = "doveadm"; - multi = mail_storage_service_multi_init(master_service, NULL, - service_flags); - pool = pool_alloconly_create("multi user", 8192); + storage_service = mail_storage_service_init(master_service, NULL, + service_flags); lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL); lib_signals_set_handler(SIGTERM, FALSE, sig_die, NULL); - user_count = mail_storage_service_multi_all_init(multi); + user_count = mail_storage_service_all_init(storage_service); n = user_count / 10000; for (interval = 10; n > 0 && interval < 1000; interval *= 10) n /= 10; user_idx = 0; - while ((ret = mail_storage_service_multi_all_next(multi, &user)) > 0) { - p_clear(pool); + while ((ret = mail_storage_service_all_next(storage_service, + &user)) > 0) { input.username = user; T_BEGIN { - ret = doveadm_mail_next_user(cmd, multi, &input, - pool, args); + ret = doveadm_mail_next_user(cmd, storage_service, + &input, args); } T_END; if (ret < 0) break; @@ -190,8 +197,7 @@ i_set_failure_prefix("doveadm: "); if (ret < 0) i_error("Failed to iterate through some users"); - mail_storage_service_multi_deinit(&multi); - pool_unref(&pool); + mail_storage_service_deinit(&storage_service); } static void
--- a/src/dsync/dsync.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/dsync/dsync.c Wed Oct 21 19:54:00 2009 -0400 @@ -69,10 +69,12 @@ enum mail_storage_service_flags ssflags = MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR; enum dsync_brain_flags brain_flags = 0; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; struct mail_storage_service_input input; struct mail_user *mail_user; struct dsync_worker *worker1, *worker2; - const char *username, *mailbox = NULL, *cmd = NULL; + const char *error, *username, *mailbox = NULL, *cmd = NULL; bool dest = TRUE; int c, ret, fd_in = STDIN_FILENO, fd_out = STDOUT_FILENO; @@ -112,8 +114,13 @@ memset(&input, 0, sizeof(input)); input.username = username; - mail_user = mail_storage_service_init_user(master_service, - &input, NULL, ssflags); + + storage_service = mail_storage_service_init(master_service, NULL, + ssflags); + if (mail_storage_service_lookup_next(storage_service, &input, + &service_user, &mail_user, + &error) <= 0) + i_fatal("%s", error); if (cmd != NULL) { /* user initialization may exec doveconf, so do our forking @@ -152,7 +159,8 @@ dsync_worker_deinit(&worker2); mail_user_unref(&mail_user); - mail_storage_service_deinit_user(); + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); return ret < 0 ? 1 : 0; }
--- a/src/imap/imap-client.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/imap/imap-client.c Wed Oct 21 19:54:00 2009 -0400 @@ -13,6 +13,7 @@ #include "imap-resp-code.h" #include "imap-util.h" #include "mail-namespace.h" +#include "mail-storage-service.h" #include "imap-commands.h" #include <stdlib.h> @@ -31,6 +32,7 @@ } struct client *client_create(int fd_in, int fd_out, struct mail_user *user, + struct mail_storage_service_user *service_user, const struct imap_settings *set) { struct client *client; @@ -42,6 +44,7 @@ client = i_new(struct client, 1); client->set = set; + client->service_user = service_user; client->fd_in = fd_in; client->fd_out = fd_out; client->input = i_stream_create_fd(fd_in, @@ -212,6 +215,7 @@ array_free(&client->search_updates); str_free(&client->capability_string); pool_unref(&client->command_pool); + mail_storage_service_user_free(&client->service_user); i_free(client); master_service_client_connection_destroyed(master_service);
--- a/src/imap/imap-client.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/imap/imap-client.h Wed Oct 21 19:54:00 2009 -0400 @@ -94,6 +94,7 @@ struct ostream *output; struct timeout *to_idle, *to_idle_output; + struct mail_storage_service_user *service_user; const struct imap_settings *set; string_t *capability_string; @@ -151,6 +152,7 @@ /* Create new client with specified input/output handles. socket specifies if the handle is a socket. */ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, + struct mail_storage_service_user *service_user, const struct imap_settings *set); void client_destroy(struct client *client, const char *reason);
--- a/src/imap/main.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/imap/main.c Wed Oct 21 19:54:00 2009 -0400 @@ -23,13 +23,8 @@ #define IS_STANDALONE() \ (getenv(MASTER_UID_ENV) == NULL) -static const struct setting_parser_info *set_roots[] = { - &imap_setting_parser_info, - NULL -}; +static struct mail_storage_service_ctx *storage_service; static struct master_login *master_login = NULL; -static enum mail_storage_service_flags storage_service_flags = 0; -static bool user_initialized = FALSE; void (*hook_client_created)(struct client **client) = NULL; @@ -87,7 +82,9 @@ } static void -main_stdio_init_user(const struct imap_settings *set, struct mail_user *user) +main_stdio_init_user(const struct imap_settings *set, + struct mail_user *mail_user, + struct mail_storage_service_user *user) { struct client *client; buffer_t *input_buf; @@ -97,7 +94,8 @@ input_buf = input_base64 == NULL ? NULL : t_base64_decode_str(input_base64); - client = client_create(STDIN_FILENO, STDOUT_FILENO, user, set); + client = client_create(STDIN_FILENO, STDOUT_FILENO, + mail_user, user, set); client_add_input(client, input_buf); } @@ -107,6 +105,10 @@ struct mail_user *mail_user; const struct imap_settings *set; const char *value; + struct mail_storage_service_user *user; + const char *error; + pool_t user_pool; + int ret; memset(&input, 0, sizeof(input)); input.module = input.service = "imap"; @@ -120,11 +122,17 @@ if ((value = getenv("LOCAL_IP")) != NULL) net_addr2ip(value, &input.local_ip); - user_initialized = TRUE; - mail_user = mail_storage_service_init_user(master_service, - &input, set_roots, - storage_service_flags); - set = mail_storage_service_get_settings(master_service); + user_pool = pool_alloconly_create("storage user pool", 512); + ret = mail_storage_service_lookup(storage_service, &input, + &user, &error); + if (ret <= 0) + i_fatal("User lookup failed: %s", error); + if (mail_storage_service_next(storage_service, + user, &mail_user, &error) < 0) + i_fatal("User init failed: %s", error); + + set = mail_storage_service_user_get_set(user)[1]; + restrict_access_allow_coredumps(TRUE); if (set->shutdown_clients) master_service_set_die_with_master(master_service, TRUE); @@ -132,7 +140,7 @@ /* fake that we're running, so we know if client was destroyed while handling its initial input */ io_loop_set_running(current_ioloop); - main_stdio_init_user(set, mail_user); + main_stdio_init_user(set, mail_user, user); } static void @@ -140,9 +148,11 @@ const char *username, const char *const *extra_fields) { struct mail_storage_service_input input; + struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *imap_client; const struct imap_settings *set; + const char *error; buffer_t input_buf; if (imap_clients != NULL) { @@ -150,7 +160,6 @@ (void)close(client->fd); return; } - i_assert(!user_initialized); memset(&input, 0, sizeof(input)); input.module = input.service = "imap"; @@ -164,13 +173,13 @@ (void)close(client->fd); return; } - user_initialized = TRUE; master_login_deinit(&master_login); - mail_user = mail_storage_service_init_user(master_service, - &input, set_roots, - storage_service_flags); - set = mail_storage_service_get_settings(master_service); + if (mail_storage_service_lookup_next(storage_service, &input, + &user, &mail_user, &error) <= 0) + i_fatal("%s", error); + set = mail_storage_service_user_get_set(user)[1]; + restrict_access_allow_coredumps(TRUE); if (set->shutdown_clients) master_service_set_die_with_master(master_service, TRUE); @@ -181,7 +190,8 @@ buffer_create_const_data(&input_buf, client->data, client->auth_req.data_size); - imap_client = client_create(client->fd, client->fd, mail_user, set); + imap_client = client_create(client->fd, client->fd, mail_user, + user, set); T_BEGIN { client_add_input(imap_client, &input_buf); } T_END; @@ -199,7 +209,12 @@ int main(int argc, char *argv[]) { + static const struct setting_parser_info *set_roots[] = { + &imap_setting_parser_info, + NULL + }; enum master_service_flags service_flags = 0; + enum mail_storage_service_flags storage_service_flags = 0; if (IS_STANDALONE() && getuid() == 0 && net_getpeername(1, NULL, NULL) == 0) { @@ -219,13 +234,17 @@ master_service = master_service_init("imap", service_flags, &argc, &argv, NULL); if (master_getopt(master_service) > 0) - exit(FATAL_DEFAULT); + return FATAL_DEFAULT; master_service_init_finish(master_service); /* plugins may want to add commands, so this needs to be called early */ commands_init(); imap_fetch_handlers_init(); + storage_service = + mail_storage_service_init(master_service, + set_roots, storage_service_flags); + if (IS_STANDALONE()) { T_BEGIN { main_stdio_run(); @@ -242,8 +261,8 @@ if (master_login != NULL) master_login_deinit(&master_login); - if (user_initialized) - mail_storage_service_deinit_user(); + mail_storage_service_deinit(&storage_service); + imap_fetch_handlers_deinit(); commands_deinit();
--- a/src/lda/main.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lda/main.c Wed Oct 21 19:54:00 2009 -0400 @@ -245,6 +245,8 @@ struct mail_deliver_context ctx; enum mail_storage_service_flags service_flags = 0; const char *user, *errstr, *path; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; struct mail_storage_service_input service_input; struct mail_user *raw_mail_user; struct mail_namespace *raw_ns; @@ -380,14 +382,17 @@ service_input.username = user; service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT; - ctx.dest_user = mail_storage_service_init_user(master_service, - &service_input, - set_roots, - service_flags); + storage_service = mail_storage_service_init(master_service, set_roots, + service_flags); + if (mail_storage_service_lookup_next(storage_service, &service_input, + &service_user, &ctx.dest_user, + &errstr) <= 0) + i_fatal("%s", errstr); + #ifdef SIGXFSZ lib_signals_ignore(SIGXFSZ, TRUE); #endif - ctx.set = mail_storage_service_get_settings(master_service); + ctx.set = mail_storage_service_user_get_set(service_user)[1]; duplicate_init(mail_user_set_get_storage_set(ctx.dest_user->set)); /* create a separate mail user for the internal namespace */ @@ -489,7 +494,8 @@ duplicate_deinit(); pool_unref(&ctx.pool); - mail_storage_service_deinit_user(); + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); return EX_OK; }
--- a/src/lib-storage/mail-storage-service.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lib-storage/mail-storage-service.c Wed Oct 21 19:54:00 2009 -0400 @@ -27,16 +27,18 @@ #define MAX_TIME_BACKWARDS_SLEEP 5 #define MAX_NOWARN_FORWARD_SECS 10 -struct mail_storage_service_multi_ctx { +struct mail_storage_service_ctx { struct master_service *service; struct auth_master_connection *conn; struct auth_master_user_list_ctx *auth_list; + const struct setting_parser_info **set_roots; enum mail_storage_service_flags flags; unsigned int modules_initialized:1; + unsigned int debug:1; }; -struct mail_storage_service_multi_user { +struct mail_storage_service_user { pool_t pool; struct mail_storage_service_input input; @@ -81,17 +83,15 @@ } static int -user_reply_handle(struct setting_parser_context *set_parser, - const struct mail_user_settings *user_set, +user_reply_handle(struct mail_storage_service_user *user, const struct auth_user_reply *reply, - const char **system_groups_user_r, const char **error_r) + const char **error_r) { + struct setting_parser_context *set_parser = user->set_parser; const char *const *str, *p, *line, *key; unsigned int i, count; int ret = 0; - *system_groups_user_r = NULL; - if (reply->uid != (uid_t)-1) { if (reply->uid == 0) { *error_r = "userdb returned 0 as uid"; @@ -106,7 +106,7 @@ set_keyval(set_parser, "mail_home", reply->home); if (reply->chroot != NULL) { - if (!validate_chroot(user_set, reply->chroot)) { + if (!validate_chroot(user->user_set, reply->chroot)) { *error_r = t_strdup_printf( "userdb returned invalid chroot directory: %s " "(see valid_chroot_dirs setting)", @@ -119,9 +119,10 @@ str = array_get(&reply->extra_fields, &count); for (i = 0; i < count && ret == 0; i++) { line = str[i]; - if (strncmp(line, "system_groups_user=", 19) == 0) - *system_groups_user_r = t_strdup(line + 19); - else T_BEGIN { + if (strncmp(line, "system_groups_user=", 19) == 0) { + user->system_groups_user = + p_strdup(user->pool, line + 19); + } else T_BEGIN { if (strncmp(line, "mail=", 5) == 0) { line = t_strconcat("mail_location=", line + 5, NULL); @@ -148,10 +149,8 @@ } static int -service_auth_userdb_lookup(struct auth_master_connection *conn, - const char *service_name, +service_auth_userdb_lookup(struct mail_storage_service_ctx *ctx, const struct mail_storage_service_input *input, - const struct mail_user_settings *user_set, pool_t pool, const char **user, const char *const **fields_r, const char **error_r) @@ -161,15 +160,15 @@ int ret; memset(&info, 0, sizeof(info)); - info.service = service_name; + info.service = ctx->service->name; info.local_ip = input->local_ip; info.remote_ip = input->remote_ip; - ret = auth_master_user_lookup(conn, *user, &info, pool, + ret = auth_master_user_lookup(ctx->conn, *user, &info, pool, &new_username, fields_r); if (ret > 0) { if (strcmp(*user, new_username) != 0) { - if (mail_user_set_get_storage_set(user_set)->mail_debug) + if (ctx->debug) i_debug("changed username to %s", new_username); *user = t_strdup(new_username); } @@ -290,56 +289,11 @@ } } -static void -mail_storage_service_init_settings(struct master_service *service, - const struct mail_storage_service_input *input, - const struct setting_parser_info *set_roots[], - bool preserve_home) -{ - ARRAY_DEFINE(all_set_roots, const struct setting_parser_info *); - const struct setting_parser_info *info = &mail_user_setting_parser_info; - struct master_service_settings_input set_input; - const char *error; - unsigned int i; - - (void)umask(0077); - - mail_storage_init(); - mail_storage_register_all(); - mailbox_list_register_all(); - - t_array_init(&all_set_roots, 5); - array_append(&all_set_roots, &info, 1); - if (set_roots != NULL) { - for (i = 0; set_roots[i] != NULL; i++) - array_append(&all_set_roots, &set_roots[i], 1); - } - (void)array_append_space(&all_set_roots); - - /* read settings after registering storages so they can have their - own setting definitions too */ - memset(&set_input, 0, sizeof(set_input)); - set_input.roots = array_idx_modifiable(&all_set_roots, 0); - set_input.dyn_parsers = mail_storage_get_dynamic_parsers(); - set_input.preserve_home = preserve_home; - if (input != NULL) { - set_input.module = input->module; - set_input.service = input->service; - set_input.username = input->username; - set_input.local_ip = input->local_ip; - set_input.remote_ip = input->remote_ip; - } - if (master_service_settings_read(service, &set_input, &error) < 0) - i_fatal("Error reading configuration: %s", error); -} - static int -mail_storage_service_init_post(struct master_service *service, +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, - bool setuid_root, - enum mail_storage_service_flags flags, struct mail_user **mail_user_r, const char **error_r) { @@ -350,16 +304,15 @@ if (mail_set->mail_debug) { i_debug("Effective uid=%s, gid=%s, home=%s", - dec2str(geteuid()), dec2str(getegid()), - home != NULL ? home : "(none)"); + dec2str(geteuid()), dec2str(getegid()), home); } - if (setuid_root) { + if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0) { /* we don't want to write core files to any users' home directories since they could contain information about other users' mails as well. so do no chdiring to home. */ } else if (*home != '\0' && - (flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) { + (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) { /* If possible chdir to home directory, so that core file could be written in case we crash. */ if (chdir(home) < 0) { @@ -372,7 +325,7 @@ 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(), service->name, + 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); @@ -436,7 +389,7 @@ static void mail_storage_service_init_log(struct master_service *service, - struct mail_storage_service_input *input) + struct mail_storage_service_user *user) { const struct mail_user_settings *user_set; void **sets; @@ -448,8 +401,8 @@ string_t *str; str = t_str_new(256); - var_expand(str, user_set->mail_log_prefix, - get_var_expand_table(service, input)); + var_expand(str, user->user_set->mail_log_prefix, + get_var_expand_table(service, &user->input)); master_service_init_log(service, str_c(str)); } T_END; } @@ -485,273 +438,181 @@ } } } -static struct mail_user * -init_user_real(struct master_service *service, - const struct mail_storage_service_input *_input, - const struct setting_parser_info *set_roots[], - enum mail_storage_service_flags flags) + +struct mail_storage_service_ctx * +mail_storage_service_init(struct master_service *service, + const struct setting_parser_info *set_roots[], + enum mail_storage_service_flags flags) { - struct mail_storage_service_input input = *_input; - const struct master_service_settings *set; - const struct mail_user_settings *user_set; - const struct mail_storage_settings *mail_set; - struct mail_user *mail_user; - struct auth_master_connection *conn; - void **sets; - const char *user, *orig_user, *home, *chroot, *error; - const char *system_groups_user = NULL, *const *userdb_fields = NULL; - unsigned int len; - bool userdb_lookup; - pool_t userdb_pool = NULL; + struct mail_storage_service_ctx *ctx; + unsigned int count; + (void)umask(0077); io_loop_set_time_moved_callback(current_ioloop, mail_storage_service_time_moved); - userdb_lookup = (flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0; - mail_storage_service_init_settings(service, &input, set_roots, - !userdb_lookup); - - /* the SET_VARS changes we do to set_parser are in their expanded form. - lib-master should have already called settings_parse_set_expanded() - to make this happen, but do it here again just in case. */ - settings_parse_set_expanded(service->set_parser, TRUE); - - if ((flags & MAIL_STORAGE_SERVICE_FLAG_DEBUG) != 0) - set_keyval(service->set_parser, "mail_debug", "yes"); - - mail_storage_service_init_log(service, &input); - set = master_service_settings_get(service); - sets = master_service_settings_get_others(service); - user_set = sets[0]; - mail_set = mail_user_set_get_storage_set(user_set); - - if (userdb_lookup) { - /* userdb lookup may change settings, do it as soon as - possible. */ - orig_user = user = input.username; - conn = auth_master_init(user_set->auth_socket_path, - mail_set->mail_debug); - userdb_pool = pool_alloconly_create("userdb lookup", 1024); - if (service_auth_userdb_lookup(conn, service->name, &input, - user_set, userdb_pool, &user, - &userdb_fields, &error) <= 0) - i_fatal("%s", error); - auth_master_deinit(&conn); - input.username = user; - - /* set up logging again in case username changed */ - mail_storage_service_init_log(service, &input); - } else if (input.userdb_fields != NULL) { - userdb_fields = input.userdb_fields; - userdb_pool = pool_alloconly_create("userdb fields", 1024); - } - if (userdb_fields != NULL) { - struct auth_user_reply reply; - - auth_user_fields_parse(userdb_fields, userdb_pool, &reply); - if (user_reply_handle(service->set_parser, user_set, &reply, - &system_groups_user, &error) < 0) - i_fatal("%s", error); - } - if (userdb_pool != NULL) - pool_unref(&userdb_pool); - - /* variable strings are expanded in mail_user_init(), - but we need the home and chroot sooner so do them separately here. */ - home = user_expand_varstr(service, &input, user_set->mail_home); - chroot = user_expand_varstr(service, &input, user_set->mail_chroot); - - if (!userdb_lookup) { - if (*home == '\0' && getenv("HOME") != NULL) { - home = getenv("HOME"); - set_keyval(service->set_parser, "mail_home", home); - } - } - - if (*home != '/') { - i_fatal("user %s: Relative home directory paths not supported: " - "%s", input.username, home); - - } + mail_storage_init(); + mail_storage_register_all(); + mailbox_list_register_all(); - len = strlen(chroot); - if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 && - strncmp(home, chroot, len - 2) == 0) { - /* If chroot ends with "/.", strip chroot dir from home dir */ - home += len - 2; - if (*home == '\0') - home = "/"; - - set_keyval(service->set_parser, "mail_home", home); - chroot = t_strndup(chroot, len - 2); - } - - modules = *user_set->mail_plugins == '\0' ? NULL : - module_dir_load(user_set->mail_plugin_dir, - user_set->mail_plugins, TRUE, - master_service_get_version_string(service)); - - if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) != 0) { - /* no changes */ - } else if ((flags & MAIL_STORAGE_SERVICE_FLAG_RESTRICT_BY_ENV) != 0) { - restrict_access_by_env(home, - (flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0); - } else { - service_drop_privileges(user_set, system_groups_user, - home, chroot, - (flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, - FALSE); - } - /* privileges are now dropped */ - restrict_access_allow_coredumps(TRUE); - - dict_drivers_register_builtin(); - module_dir_init(modules); - mail_users_init(user_set->auth_socket_path, mail_set->mail_debug); - if (mail_storage_service_init_post(service, &input, home, user_set, - FALSE, flags, - &mail_user, &error) < 0) - i_fatal("%s", error); - return mail_user; -} - -struct mail_user * -mail_storage_service_init_user(struct master_service *service, - const struct mail_storage_service_input *_input, - const struct setting_parser_info *set_roots[], - enum mail_storage_service_flags flags) -{ - struct mail_user *user; - - T_BEGIN { - user = init_user_real(service, _input, set_roots, flags); - } T_END; - return user; -} - -void mail_storage_service_deinit_user(void) -{ - module_dir_unload(&modules); - mail_storage_deinit(); - mail_users_deinit(); - dict_drivers_unregister_builtin(); -} - -struct mail_storage_service_multi_ctx * -mail_storage_service_multi_init(struct master_service *service, - const struct setting_parser_info *set_roots[], - enum mail_storage_service_flags flags) -{ - struct mail_storage_service_multi_ctx *ctx; - const struct master_service_settings *set; - const struct mail_user_settings *user_set; - const struct mail_storage_settings *mail_set; - void **sets; - - io_loop_set_time_moved_callback(current_ioloop, - mail_storage_service_time_moved); - - ctx = i_new(struct mail_storage_service_multi_ctx, 1); + ctx = i_new(struct mail_storage_service_ctx, 1); ctx->service = service; ctx->flags = flags; - mail_storage_service_init_settings(service, NULL, set_roots, FALSE); - - set = master_service_settings_get(service); - sets = master_service_settings_get_others(service); - user_set = sets[0]; - mail_set = mail_user_set_get_storage_set(user_set); + /* @UNSAFE */ + if (set_roots == NULL) + count = 0; + else + for (count = 0; set_roots[count] != NULL; count++) ; + ctx->set_roots = i_new(const struct setting_parser_info *, count + 2); + ctx->set_roots[0] = &mail_user_setting_parser_info; + memcpy(ctx->set_roots + 1, set_roots, sizeof(*ctx->set_roots) * count); /* do all the global initialization. delay initializing plugins until we drop privileges the first time. */ master_service_init_log(service, t_strconcat(service->name, ": ", NULL)); - modules = *user_set->mail_plugins == '\0' ? NULL : - module_dir_load(user_set->mail_plugin_dir, - user_set->mail_plugins, TRUE, - master_service_get_version_string(service)); - - if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) { - ctx->conn = auth_master_init(user_set->auth_socket_path, - mail_set->mail_debug); - } - dict_drivers_register_builtin(); - mail_users_init(user_set->auth_socket_path, mail_set->mail_debug); return ctx; } struct auth_master_connection * -mail_storage_service_multi_get_auth_conn(struct mail_storage_service_multi_ctx *ctx) +mail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx) { return ctx->conn; } -static int multi_userdb_lookup(struct mail_storage_service_multi_ctx *ctx, - struct mail_storage_service_multi_user *user, - pool_t userdb_pool, const char **error_r) +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) { - struct auth_user_reply reply; - const char *username, *system_groups_user, *const *userdb_fields; - int ret; + struct master_service_settings_input set_input; - username = user->input.username; - ret = service_auth_userdb_lookup(ctx->conn, ctx->service->name, - &user->input, user->user_set, - userdb_pool, &username, - &userdb_fields, error_r); - if (ret <= 0) - return ret; + /* read settings after registering storages so they can have their + own setting definitions too */ + 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; + if (input != NULL) { + set_input.module = input->module; + set_input.service = input->service; + set_input.username = input->username; + set_input.local_ip = input->local_ip; + set_input.remote_ip = input->remote_ip; + } + if (master_service_settings_read(ctx->service, &set_input, + error_r) < 0) { + *error_r = t_strdup_printf("Error reading configuration: %s", + *error_r); + return -1; + } + return 0; +} - auth_user_fields_parse(userdb_fields, userdb_pool, &reply); - ret = user_reply_handle(user->set_parser, user->user_set, - &reply, &system_groups_user, error_r); - if (ret <= 0) - return ret; +static void +mail_storage_service_first_init(struct mail_storage_service_ctx *ctx, + 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; - user->input.username = p_strdup(user->pool, username); - user->system_groups_user = p_strdup(user->pool, system_groups_user); - return 1; + modules = *user_set->mail_plugins == '\0' ? NULL : + module_dir_load(user_set->mail_plugin_dir, + user_set->mail_plugins, TRUE, + master_service_get_version_string(ctx->service)); + + ctx->conn = auth_master_init(user_set->auth_socket_path, + mail_set->mail_debug); + + i_assert(mail_user_auth_master_conn == NULL); + mail_user_auth_master_conn = ctx->conn; } -int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx, - const struct mail_storage_service_input *input, - pool_t pool, - struct mail_storage_service_multi_user **user_r, - const char **error_r) +int mail_storage_service_lookup(struct mail_storage_service_ctx *ctx, + const struct mail_storage_service_input *input, + struct mail_storage_service_user **user_r, + const char **error_r) { - struct mail_storage_service_multi_user *user; + struct mail_storage_service_user *user; + const char *username = input->username; + const struct mail_user_settings *user_set; + const char *const *userdb_fields; + struct auth_user_reply reply; void **sets; - pool_t userdb_pool; + pool_t user_pool, temp_pool; + bool keep_home; int ret = 1; - user = p_new(pool, struct mail_storage_service_multi_user, 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) + 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); + + temp_pool = pool_alloconly_create("userdb lookup", 1024); + if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) { + ret = service_auth_userdb_lookup(ctx, input, temp_pool, + &username, &userdb_fields, + error_r); + if (ret <= 0) { + pool_unref(&temp_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 = pool; + user->pool = user_pool; user->input = *input; - user->input.username = p_strdup(pool, input->username); + user->input.userdb_fields = NULL; + user->input.username = p_strdup(user_pool, username); - user->set_parser = settings_parser_dup(ctx->service->set_parser, pool); + user->set_parser = + settings_parser_dup(ctx->service->set_parser, user_pool); sets = settings_parser_get_list(user->set_parser); user->user_set = sets[1]; - if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) { - userdb_pool = pool_alloconly_create("userdb lookup", 1024); - ret = multi_userdb_lookup(ctx, user, userdb_pool, error_r); - pool_unref(&userdb_pool); + if (keep_home) { + const char *home = getenv("HOME"); + if (home != NULL) + set_keyval(user->set_parser, "mail_home", home); } + + if (userdb_fields != NULL) { + auth_user_fields_parse(userdb_fields, temp_pool, &reply); + if (user_reply_handle(user, &reply, error_r) < 0) + ret = -1; + } + pool_unref(&temp_pool); + *user_r = user; - return 1; + return ret; } -int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, - struct mail_storage_service_multi_user *user, - struct mail_user **mail_user_r, - const char **error_r) +int mail_storage_service_next(struct mail_storage_service_ctx *ctx, + struct mail_storage_service_user *user, + struct mail_user **mail_user_r, + const char **error_r) { const struct mail_user_settings *user_set = user->user_set; const char *home, *chroot; unsigned int len; + bool temp_priv_drop = + (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP); /* variable strings are expanded in mail_user_init(), but we need the home and chroot sooner so do them separately here. */ @@ -760,13 +621,21 @@ chroot = user_expand_varstr(ctx->service, &user->input, user_set->mail_chroot); - mail_storage_service_init_log(ctx->service, &user->input); + if (*home != '/' && *home != '\0') { + i_error("user %s: Relative home directory paths not supported: " + "%s", user->input.username, home); + return -1; + } + + mail_storage_service_init_log(ctx->service, user); if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) { service_drop_privileges(user_set, user->system_groups_user, home, chroot, (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0, - TRUE); + temp_priv_drop); + if (!temp_priv_drop) + restrict_access_allow_coredumps(TRUE); } if (!ctx->modules_initialized) { /* privileges dropped for the first time. initialize the @@ -781,24 +650,59 @@ if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 && strncmp(home, chroot, len - 2) == 0) { /* home dir already contains the chroot dir */ - } else if (len > 0) { + if (!temp_priv_drop) { + home += len - 2; + if (*home == '\0') + home = "/"; + + set_keyval(user->set_parser, "mail_home", home); + chroot = t_strndup(chroot, len - 2); + } + } else if (len > 0 && temp_priv_drop) { set_keyval(user->set_parser, "mail_home", t_strconcat(chroot, "/", home, NULL)); } - if (mail_storage_service_init_post(ctx->service, &user->input, - home, user_set, TRUE, ctx->flags, + if (mail_storage_service_init_post(ctx, &user->input, home, user_set, mail_user_r, error_r) < 0) return -1; return 0; } -void mail_storage_service_multi_user_free(struct mail_storage_service_multi_user *user) +int mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx, + const struct mail_storage_service_input *input, + struct mail_storage_service_user **user_r, + struct mail_user **mail_user_r, + const char **error_r) { + struct mail_storage_service_user *user; + const char *error; + int ret; + + ret = mail_storage_service_lookup(ctx, input, &user, &error); + if (ret <= 0) { + *error_r = t_strdup_printf("User lookup failed: %s", error); + return ret; + } + if (mail_storage_service_next(ctx, user, mail_user_r, &error) < 0) { + mail_storage_service_user_free(&user); + *error_r = t_strdup_printf("User init failed: %s", error); + return -1; + } + *user_r = user; + return 1; +} + +void mail_storage_service_user_free(struct mail_storage_service_user **_user) +{ + struct mail_storage_service_user *user = *_user; + + *_user = NULL; settings_parser_deinit(&user->set_parser); + pool_unref(&user->pool); } unsigned int -mail_storage_service_multi_all_init(struct mail_storage_service_multi_ctx *ctx) +mail_storage_service_all_init(struct mail_storage_service_ctx *ctx) { if (ctx->auth_list != NULL) (void)auth_master_user_list_deinit(&ctx->auth_list); @@ -806,8 +710,8 @@ return auth_master_user_list_count(ctx->auth_list); } -int mail_storage_service_multi_all_next(struct mail_storage_service_multi_ctx *ctx, - const char **username_r) +int mail_storage_service_all_next(struct mail_storage_service_ctx *ctx, + const char **username_r) { i_assert((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0); @@ -817,20 +721,26 @@ return auth_master_user_list_deinit(&ctx->auth_list); } -void mail_storage_service_multi_deinit(struct mail_storage_service_multi_ctx **_ctx) +void mail_storage_service_deinit(struct mail_storage_service_ctx **_ctx) { - struct mail_storage_service_multi_ctx *ctx = *_ctx; + struct mail_storage_service_ctx *ctx = *_ctx; *_ctx = NULL; if (ctx->auth_list != NULL) (void)auth_master_user_list_deinit(&ctx->auth_list); - if (ctx->conn != NULL) + if (ctx->conn != NULL) { + if (mail_user_auth_master_conn == ctx->conn) + mail_user_auth_master_conn = NULL; auth_master_deinit(&ctx->conn); + } i_free(ctx); - mail_storage_service_deinit_user(); + + module_dir_unload(&modules); + mail_storage_deinit(); + dict_drivers_unregister_builtin(); } -void *mail_storage_service_multi_user_get_set(struct mail_storage_service_multi_user *user) +void **mail_storage_service_user_get_set(struct mail_storage_service_user *user) { return settings_parser_get_list(user->set_parser) + 1; }
--- a/src/lib-storage/mail-storage-service.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lib-storage/mail-storage-service.h Wed Oct 21 19:54:00 2009 -0400 @@ -4,6 +4,7 @@ #include "network.h" struct master_service; +struct mail_user; enum mail_storage_service_flags { /* Fail if we don't drop root privileges */ @@ -14,10 +15,10 @@ MAIL_STORAGE_SERVICE_FLAG_DEBUG = 0x04, /* Keep the current process permissions */ MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS = 0x08, - /* Get the process permissions from environment */ - MAIL_STORAGE_SERVICE_FLAG_RESTRICT_BY_ENV = 0x10, /* Don't chdir() to user's home */ - MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR = 0x20 + MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR = 0x10, + /* Drop privileges only temporarily (keep running as setuid-root) */ + MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP = 0x20 }; struct mail_storage_service_input { @@ -30,44 +31,42 @@ }; struct setting_parser_info; -struct mail_storage_service_multi_user; - -struct mail_user * -mail_storage_service_init_user(struct master_service *service, - const struct mail_storage_service_input *input, - const struct setting_parser_info *set_roots[], - enum mail_storage_service_flags flags); -void mail_storage_service_deinit_user(void); +struct mail_storage_service_user; -struct mail_storage_service_multi_ctx * -mail_storage_service_multi_init(struct master_service *service, - const struct setting_parser_info *set_roots[], - enum mail_storage_service_flags flags); +struct mail_storage_service_ctx * +mail_storage_service_init(struct master_service *service, + const struct setting_parser_info *set_roots[], + enum mail_storage_service_flags flags); struct auth_master_connection * -mail_storage_service_multi_get_auth_conn(struct mail_storage_service_multi_ctx *ctx); +mail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx); /* Returns 1 if ok, 0 if user wasn't found, -1 if error. */ -int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx, - const struct mail_storage_service_input *input, - pool_t pool, - struct mail_storage_service_multi_user **user_r, - const char **error_r); -int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx, - struct mail_storage_service_multi_user *user, - struct mail_user **mail_user_r, - const char **error_r); -void mail_storage_service_multi_user_free(struct mail_storage_service_multi_user *user); +int mail_storage_service_lookup(struct mail_storage_service_ctx *ctx, + const struct mail_storage_service_input *input, + struct mail_storage_service_user **user_r, + const char **error_r); +int mail_storage_service_next(struct mail_storage_service_ctx *ctx, + struct mail_storage_service_user *user, + struct mail_user **mail_user_r, + const char **error_r); +/* Combine lookup() and next() into one call. */ +int mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx, + const struct mail_storage_service_input *input, + struct mail_storage_service_user **user_r, + struct mail_user **mail_user_r, + const char **error_r); +void mail_storage_service_user_free(struct mail_storage_service_user **user); /* Initialize iterating through all users. Return the number of users. */ unsigned int -mail_storage_service_multi_all_init(struct mail_storage_service_multi_ctx *ctx); +mail_storage_service_all_init(struct mail_storage_service_ctx *ctx); /* Iterate through all usernames. Returns 1 if username was returned, 0 if there are no more users, -1 if error. */ -int mail_storage_service_multi_all_next(struct mail_storage_service_multi_ctx *ctx, - const char **username_r); -void mail_storage_service_multi_deinit(struct mail_storage_service_multi_ctx **ctx); +int mail_storage_service_all_next(struct mail_storage_service_ctx *ctx, + const char **username_r); +void mail_storage_service_deinit(struct mail_storage_service_ctx **ctx); /* Return the settings pointed to by set_root parameter in _init(). The settings contain all the changes done by userdb lookups. */ -void *mail_storage_service_multi_user_get_set(struct mail_storage_service_multi_user *user); +void **mail_storage_service_user_get_set(struct mail_storage_service_user *user); /* Return the settings pointed to by set_root parameter in _init() */ void *mail_storage_service_get_settings(struct master_service *service);
--- a/src/lib-storage/mail-user.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lib-storage/mail-user.c Wed Oct 21 19:54:00 2009 -0400 @@ -19,9 +19,9 @@ #include <stdlib.h> struct mail_user_module_register mail_user_module_register = { 0 }; -void (*hook_mail_user_created)(struct mail_user *user) = NULL; +struct auth_master_connection *mail_user_auth_master_conn; -static struct auth_master_connection *auth_master_conn; +void (*hook_mail_user_created)(struct mail_user *user) = NULL; static void mail_user_deinit_base(struct mail_user *user) { @@ -259,12 +259,13 @@ return user->_home != NULL ? 1 : 0; } - if (auth_master_conn == NULL) + if (mail_user_auth_master_conn == NULL) return 0; userdb_pool = pool_alloconly_create("userdb lookup", 512); - ret = auth_master_user_lookup(auth_master_conn, user->username, - &info, userdb_pool, &username, &fields); + ret = auth_master_user_lookup(mail_user_auth_master_conn, + user->username, &info, userdb_pool, + &username, &fields); if (ret < 0) *home_r = NULL; else { @@ -347,15 +348,3 @@ return t_strconcat(net_ip2addr(user->remote_ip), "/", str_tabescape(user->username), NULL); } - -void mail_users_init(const char *auth_socket_path, bool debug) -{ - auth_master_conn = auth_socket_path == NULL ? NULL : - auth_master_init(auth_socket_path, debug); -} - -void mail_users_deinit(void) -{ - if (auth_master_conn != NULL) - auth_master_deinit(&auth_master_conn); -}
--- a/src/lib-storage/mail-user.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lib-storage/mail-user.h Wed Oct 21 19:54:00 2009 -0400 @@ -53,13 +53,11 @@ struct mail_user_module_register *reg; }; extern struct mail_user_module_register mail_user_module_register; +extern struct auth_master_connection *mail_user_auth_master_conn; /* Called after user has been created */ extern void (*hook_mail_user_created)(struct mail_user *user); -void mail_users_init(const char *auth_socket_path, bool debug); -void mail_users_deinit(void); - struct mail_user *mail_user_alloc(const char *username, const struct mail_user_settings *set); /* Returns -1 if settings were invalid. */
--- a/src/lmtp/client.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lmtp/client.c Wed Oct 21 19:54:00 2009 -0400 @@ -1,7 +1,7 @@ /* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "buffer.h" +#include "array.h" #include "str.h" #include "llist.h" #include "istream.h" @@ -11,6 +11,7 @@ #include "master-service-settings.h" #include "mail-namespace.h" #include "mail-storage.h" +#include "mail-storage-service.h" #include "main.h" #include "lmtp-proxy.h" #include "commands.h" @@ -228,6 +229,11 @@ void client_state_reset(struct client *client) { + struct mail_recipient *rcpt; + + array_foreach_modifiable(&client->state.rcpt_to, rcpt) + mail_storage_service_user_free(&rcpt->service_user); + if (client->state.raw_mail != NULL) mail_free(&client->state.raw_mail); if (client->state.raw_trans != NULL)
--- a/src/lmtp/client.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lmtp/client.h Wed Oct 21 19:54:00 2009 -0400 @@ -7,7 +7,7 @@ struct mail_recipient { const char *name; - struct mail_storage_service_multi_user *multi_user; + struct mail_storage_service_user *service_user; }; struct client_state {
--- a/src/lmtp/commands.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lmtp/commands.c Wed Oct 21 19:54:00 2009 -0400 @@ -175,7 +175,7 @@ info.remote_port = client->remote_port; pool = pool_alloconly_create("auth lookup", 1024); - auth_conn = mail_storage_service_multi_get_auth_conn(multi_service); + auth_conn = mail_storage_service_get_auth_conn(storage_service); ret = auth_master_pass_lookup(auth_conn, address, &info, pool, &fields); if (ret <= 0) { @@ -312,9 +312,8 @@ input.local_ip = client->local_ip; input.remote_ip = client->remote_ip; - ret = mail_storage_service_multi_lookup(multi_service, &input, - client->state_pool, - &rcpt.multi_user, &error); + ret = mail_storage_service_lookup(storage_service, &input, + &rcpt.service_user, &error); if (ret < 0) { i_error("User lookup failed: %s", error); @@ -371,14 +370,14 @@ int ret; i_set_failure_prefix(t_strdup_printf("lmtp(%s): ", rcpt->name)); - if (mail_storage_service_multi_next(multi_service, rcpt->multi_user, - &client->state.dest_user, - &error) < 0) { + if (mail_storage_service_next(storage_service, rcpt->service_user, + &client->state.dest_user, + &error) < 0) { i_error("%s", error); client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, rcpt->name); return -1; } - sets = mail_storage_service_multi_user_get_set(rcpt->multi_user); + sets = mail_storage_service_user_get_set(rcpt->service_user); memset(&dctx, 0, sizeof(dctx)); dctx.pool = pool_alloconly_create("mail delivery", 1024);
--- a/src/lmtp/main.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lmtp/main.c Wed Oct 21 19:54:00 2009 -0400 @@ -22,7 +22,7 @@ #define IS_STANDALONE() \ (getenv(MASTER_UID_ENV) == NULL) -struct mail_storage_service_multi_ctx *multi_service; +struct mail_storage_service_ctx *storage_service; static void client_connected(const struct master_service_connection *conn) { @@ -74,16 +74,15 @@ return FATAL_DEFAULT; master_service_init_finish(master_service); - multi_service = mail_storage_service_multi_init(master_service, - set_roots, - storage_service_flags); + storage_service = mail_storage_service_init(master_service, set_roots, + storage_service_flags); restrict_access_allow_coredumps(TRUE); main_init(); master_service_run(master_service, client_connected); main_deinit(); - mail_storage_service_multi_deinit(&multi_service); + mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); return 0; }
--- a/src/lmtp/main.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/lmtp/main.h Wed Oct 21 19:54:00 2009 -0400 @@ -1,7 +1,7 @@ #ifndef MAIN_H #define MAIN_H -extern struct mail_storage_service_multi_ctx *multi_service; +extern struct mail_storage_service_ctx *storage_service; void listener_client_destroyed(void);
--- a/src/plugins/convert/convert-tool.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/plugins/convert/convert-tool.c Wed Oct 21 19:54:00 2009 -0400 @@ -17,6 +17,8 @@ int main(int argc, char *argv[]) { + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; struct mail_storage_service_input input; struct mail_user *user; struct convert_plugin_settings set; @@ -53,7 +55,10 @@ master_service_init_log(master_service, t_strdup_printf("convert-tool(%s): ", input.username)); - user = mail_storage_service_init_user(master_service, &input, NULL, 0); + storage_service = mail_storage_service_init(master_service, NULL, 0); + if (mail_storage_service_lookup_next(storage_service, &input, + &service_user, &user, &error) <= 0) + i_fatal("%s", error); memset(&ns_set, 0, sizeof(ns_set)); ns_set.location = argv[4]; @@ -75,7 +80,8 @@ i_error("Internal failure"); mail_user_unref(&user); - mail_storage_service_deinit_user(); + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); return ret <= 0 ? 1 : 0; }
--- a/src/plugins/expire/expire-tool.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/plugins/expire/expire-tool.c Wed Oct 21 19:54:00 2009 -0400 @@ -18,8 +18,8 @@ #include <time.h> struct expire_context { - pool_t multi_user_pool; - struct mail_storage_service_multi_ctx *multi; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; struct mail_user *mail_user; struct expire_env *env; bool testrun; @@ -28,7 +28,6 @@ static int expire_init_user(struct expire_context *ctx, const char *user) { struct mail_storage_service_input input; - struct mail_storage_service_multi_user *multi_user; const char *expire, *expire_altmove, *errstr; int ret; @@ -38,19 +37,12 @@ input.service = "expire-tool"; input.username = user; - p_clear(ctx->multi_user_pool); - ret = mail_storage_service_multi_lookup(ctx->multi, &input, - ctx->multi_user_pool, - &multi_user, &errstr); + ret = mail_storage_service_lookup_next(ctx->storage_service, &input, + &ctx->service_user, + &ctx->mail_user, &errstr); if (ret <= 0) { if (ret < 0 || ctx->testrun) - i_error("User lookup failed: %s", errstr); - return ret; - } - ret = mail_storage_service_multi_next(ctx->multi, multi_user, - &ctx->mail_user, &errstr); - if (ret < 0) { - i_error("User init failed: %s", errstr); + i_error("%s", errstr); return ret; } @@ -68,6 +60,7 @@ static void expire_deinit_user(struct expire_context *ctx) { mail_user_unref(&ctx->mail_user); + mail_storage_service_user_free(&ctx->service_user); expire_env_deinit(&ctx->env); } @@ -214,8 +207,7 @@ int ret; memset(&ctx, 0, sizeof(ctx)); - ctx.multi_user_pool = pool_alloconly_create("multi user pool", 512); - ctx.multi = mail_storage_service_multi_init(service, NULL, + ctx.storage_service = mail_storage_service_init(service, NULL, MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP); sets = master_service_settings_get_others(service); @@ -306,8 +298,7 @@ if (ctx.mail_user != NULL) expire_deinit_user(&ctx); - mail_storage_service_multi_deinit(&ctx.multi); - pool_unref(&ctx.multi_user_pool); + mail_storage_service_deinit(&ctx.storage_service); } int main(int argc, char *argv[])
--- a/src/pop3/main.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/pop3/main.c Wed Oct 21 19:54:00 2009 -0400 @@ -20,13 +20,8 @@ #define IS_STANDALONE() \ (getenv(MASTER_UID_ENV) == NULL) -static const struct setting_parser_info *set_roots[] = { - &pop3_setting_parser_info, - NULL -}; +static struct mail_storage_service_ctx *storage_service; static struct master_login *master_login = NULL; -static enum mail_storage_service_flags storage_service_flags = 0; -static bool user_initialized = FALSE; void (*hook_client_created)(struct client **client) = NULL; @@ -50,7 +45,9 @@ } static void -main_stdio_init_user(const struct pop3_settings *set, struct mail_user *user) +main_stdio_init_user(const struct pop3_settings *set, + struct mail_user *mail_user, + struct mail_storage_service_user *user) { struct client *client; buffer_t *input_buf; @@ -60,7 +57,8 @@ input_buf = input_base64 == NULL ? NULL : t_base64_decode_str(input_base64); - client = client_create(STDIN_FILENO, STDOUT_FILENO, user, set); + client = client_create(STDIN_FILENO, STDOUT_FILENO, + mail_user, user, set); client_add_input(client, input_buf); } @@ -70,6 +68,10 @@ struct mail_user *mail_user; const struct pop3_settings *set; const char *value; + struct mail_storage_service_user *user; + const char *error; + pool_t user_pool; + int ret; memset(&input, 0, sizeof(input)); input.module = input.service = "pop3"; @@ -83,11 +85,16 @@ if ((value = getenv("LOCAL_IP")) != NULL) net_addr2ip(value, &input.local_ip); - user_initialized = TRUE; - mail_user = mail_storage_service_init_user(master_service, - &input, set_roots, - storage_service_flags); - set = mail_storage_service_get_settings(master_service); + user_pool = pool_alloconly_create("storage user pool", 512); + ret = mail_storage_service_lookup(storage_service, &input, + &user, &error); + if (ret <= 0) + i_fatal("User lookup failed: %s", error); + if (mail_storage_service_next(storage_service, + user, &mail_user, &error) < 0) + i_fatal("User init failed: %s", error); + set = mail_storage_service_user_get_set(user)[1]; + restrict_access_allow_coredumps(TRUE); if (set->shutdown_clients) master_service_set_die_with_master(master_service, TRUE); @@ -95,7 +102,7 @@ /* fake that we're running, so we know if client was destroyed while handling its initial input */ io_loop_set_running(current_ioloop); - main_stdio_init_user(set, mail_user); + main_stdio_init_user(set, mail_user, user); } static void @@ -103,9 +110,11 @@ const char *username, const char *const *extra_fields) { struct mail_storage_service_input input; + struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *pop3_client; const struct pop3_settings *set; + const char *error; buffer_t input_buf; if (pop3_clients != NULL) { @@ -113,7 +122,6 @@ (void)close(client->fd); return; } - i_assert(!user_initialized); memset(&input, 0, sizeof(input)); input.module = input.service = "pop3"; @@ -127,13 +135,13 @@ (void)close(client->fd); return; } - user_initialized = TRUE; master_login_deinit(&master_login); - mail_user = mail_storage_service_init_user(master_service, - &input, set_roots, - storage_service_flags); - set = mail_storage_service_get_settings(master_service); + if (mail_storage_service_lookup_next(storage_service, &input, + &user, &mail_user, &error) <= 0) + i_fatal("%s", error); + set = mail_storage_service_user_get_set(user)[1]; + restrict_access_allow_coredumps(TRUE); if (set->shutdown_clients) master_service_set_die_with_master(master_service, TRUE); @@ -144,7 +152,8 @@ buffer_create_const_data(&input_buf, client->data, client->auth_req.data_size); - pop3_client = client_create(client->fd, client->fd, mail_user, set); + pop3_client = client_create(client->fd, client->fd, mail_user, + user, set); T_BEGIN { client_add_input(pop3_client, &input_buf); } T_END; @@ -162,7 +171,12 @@ int main(int argc, char *argv[]) { + static const struct setting_parser_info *set_roots[] = { + &pop3_setting_parser_info, + NULL + }; enum master_service_flags service_flags = 0; + enum mail_storage_service_flags storage_service_flags = 0; if (IS_STANDALONE() && getuid() == 0 && net_getpeername(1, NULL, NULL) == 0) { @@ -185,6 +199,10 @@ return FATAL_DEFAULT; master_service_init_finish(master_service); + storage_service = + mail_storage_service_init(master_service, + set_roots, storage_service_flags); + if (IS_STANDALONE()) { T_BEGIN { main_stdio_run(); @@ -201,8 +219,7 @@ if (master_login != NULL) master_login_deinit(&master_login); - if (user_initialized) - mail_storage_service_deinit_user(); + mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); return 0; }
--- a/src/pop3/pop3-client.c Wed Oct 21 16:58:10 2009 -0400 +++ b/src/pop3/pop3-client.c Wed Oct 21 19:54:00 2009 -0400 @@ -12,6 +12,7 @@ #include "var-expand.h" #include "master-service.h" #include "mail-storage.h" +#include "mail-storage-service.h" #include "pop3-commands.h" #include "mail-search-build.h" #include "mail-namespace.h" @@ -182,6 +183,7 @@ } struct client *client_create(int fd_in, int fd_out, struct mail_user *user, + struct mail_storage_service_user *service_user, const struct pop3_settings *set) { struct mail_namespace *ns; @@ -197,6 +199,7 @@ net_set_nonblock(fd_out, TRUE); client = i_new(struct client, 1); + client->service_user = service_user; client->set = set; client->fd_in = fd_in; client->fd_out = fd_out; @@ -368,7 +371,7 @@ if (close(client->fd_out) < 0) i_error("close(client out) failed: %m"); } - + mail_storage_service_user_free(&client->service_user); i_free(client); master_service_client_connection_destroyed(master_service);
--- a/src/pop3/pop3-client.h Wed Oct 21 16:58:10 2009 -0400 +++ b/src/pop3/pop3-client.h Wed Oct 21 19:54:00 2009 -0400 @@ -21,6 +21,7 @@ command_func_t *cmd; void *cmd_context; + struct mail_storage_service_user *service_user; struct mail_user *user; struct mail_namespace *inbox_ns; struct mailbox *mailbox; @@ -65,6 +66,7 @@ /* Create new client with specified input/output handles. socket specifies if the handle is a socket. */ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, + struct mail_storage_service_user *service_user, const struct pop3_settings *set); void client_destroy(struct client *client, const char *reason);