Mercurial > dovecot > core-2.2
changeset 13037:b6568a36ecf9
doveadm: Added support for using local/remote {} settings.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 20 May 2011 14:08:43 +0300 |
parents | 6604f80abb02 |
children | c46b1ce45cd1 |
files | src/doveadm/client-connection.c src/doveadm/doveadm-mail-server.c src/doveadm/doveadm-mail.c src/doveadm/doveadm-mail.h |
diffstat | 4 files changed, 105 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/client-connection.c Fri May 20 13:30:40 2011 +0300 +++ b/src/doveadm/client-connection.c Fri May 20 14:08:43 2011 +0300 @@ -6,7 +6,9 @@ #include "istream.h" #include "ostream.h" #include "strescape.h" +#include "settings-parser.h" #include "master-service.h" +#include "master-service-settings.h" #include "mail-storage-service.h" #include "doveadm-util.h" #include "doveadm-server.h" @@ -20,17 +22,24 @@ #define MAX_INBUF_SIZE 1024 struct client_connection { + pool_t pool; + int fd; struct io *io; struct istream *input; struct ostream *output; + struct ip_addr local_ip, remote_ip; + const struct doveadm_settings *set; unsigned int handshaked:1; unsigned int authenticated:1; }; -static bool doveadm_mail_cmd_server(const char *cmd_name, const char *username, - int argc, char *argv[]) +static bool +doveadm_mail_cmd_server(const char *cmd_name, + const struct doveadm_settings *set, + const struct mail_storage_service_input *input, + int argc, char *argv[]) { enum mail_storage_service_flags service_flags = MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT | @@ -50,7 +59,7 @@ if (doveadm_debug) service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; - ctx = doveadm_mail_cmd_init(cmd); + ctx = doveadm_mail_cmd_init(cmd, set); getopt_args = t_strconcat("Au:", ctx->getopt_args, NULL); while ((c = getopt(argc, argv, getopt_args)) > 0) { switch (c) { @@ -88,10 +97,10 @@ doveadm_print_header("username", "Username", DOVEADM_PRINT_HEADER_FLAG_STICKY | DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); - doveadm_print_sticky("username", username); + doveadm_print_sticky("username", input->username); } - doveadm_mail_single_user(ctx, argv, username, service_flags); + doveadm_mail_single_user(ctx, argv, input, service_flags); ctx->v.deinit(ctx); doveadm_print_flush(); return !ctx->failed; @@ -99,10 +108,14 @@ static bool client_handle_command(struct client_connection *conn, char **args) { - const char *flags, *username, *cmd_name; + struct mail_storage_service_input input; + const char *flags, *cmd_name; unsigned int argc; bool ret; + memset(&input, 0, sizeof(input)); + input.service = "doveadm"; + for (argc = 0; args[argc] != NULL; argc++) args[argc] = str_tabunescape(args[argc]); @@ -111,7 +124,7 @@ return FALSE; } flags = args[0]; - username = args[1]; + input.username = args[1]; cmd_name = args[2]; args += 3; argc -= 3; @@ -135,7 +148,7 @@ } o_stream_cork(conn->output); - ret = doveadm_mail_cmd_server(cmd_name, username, argc, args); + ret = doveadm_mail_cmd_server(cmd_name, conn->set, &input, argc, args); if (ret) o_stream_send(conn->output, "\n+\n", 3); else @@ -160,7 +173,7 @@ if ((line = i_stream_read_next_line(conn->input)) == NULL) return 0; - if (*doveadm_settings->doveadm_password == '\0') { + if (*conn->set->doveadm_password == '\0') { i_error("doveadm_password not set, " "remote authentication disabled"); return -1; @@ -187,7 +200,7 @@ return -1; } pass = t_strndup(data + 9, size - 9); - if (strcmp(pass, doveadm_settings->doveadm_password) != 0) { + if (strcmp(pass, conn->set->doveadm_password) != 0) { i_error("doveadm client authenticated with wrong password"); return -1; } @@ -237,18 +250,52 @@ client_connection_destroy(&conn); } +static int client_connection_read_settings(struct client_connection *conn) +{ + const struct setting_parser_info *set_roots[] = { + &doveadm_setting_parser_info, + NULL + }; + struct master_service_settings_input input; + struct master_service_settings_output output; + const char *error; + void *set; + + memset(&input, 0, sizeof(input)); + input.roots = set_roots; + input.service = "doveadm"; + input.local_ip = conn->local_ip; + input.remote_ip = conn->remote_ip; + + if (master_service_settings_read(master_service, &input, + &output, &error) < 0) { + i_error("Error reading configuration: %s", error); + return -1; + } + set = master_service_settings_get_others(master_service)[0]; + conn->set = settings_dup(&doveadm_setting_parser_info, set, conn->pool); + return 0; +} + struct client_connection *client_connection_create(int fd, int listen_fd) { struct client_connection *conn; struct stat st; const char *listen_path; + unsigned int port; + pool_t pool; - conn = i_new(struct client_connection, 1); + pool = pool_alloconly_create("doveadm client", 1024*16); + conn = p_new(pool, struct client_connection, 1); + conn->pool = pool; conn->fd = fd; conn->io = io_add(fd, IO_READ, client_connection_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + (void)net_getsockname(fd, &conn->local_ip, &port); + (void)net_getpeername(fd, &conn->remote_ip, &port); + /* we'll have to do this with stat(), because at least in Linux fstat() always returns mode as 0777 */ if (net_getunixname(listen_fd, &listen_path) == 0 && @@ -260,6 +307,8 @@ } else { o_stream_send(conn->output, "-\n", 2); } + if (client_connection_read_settings(conn) < 0) + client_connection_destroy(&conn); return conn; } @@ -274,7 +323,7 @@ io_remove(&conn->io); if (close(conn->fd) < 0) i_error("close(client) failed: %m"); - i_free(conn); + pool_unref(&conn->pool); doveadm_client = NULL; master_service_client_connection_destroyed(master_service);
--- a/src/doveadm/doveadm-mail-server.c Fri May 20 13:30:40 2011 +0300 +++ b/src/doveadm/doveadm-mail-server.c Fri May 20 14:08:43 2011 +0300 @@ -30,7 +30,8 @@ static void doveadm_mail_server_handle(struct server_connection *conn, const char *username); -static struct doveadm_server *doveadm_server_get(const char *name) +static struct doveadm_server * +doveadm_server_get(struct doveadm_mail_cmd_context *ctx, const char *name) { struct doveadm_server *server; char *dup_name; @@ -46,7 +47,7 @@ server = p_new(server_pool, struct doveadm_server, 1); server->name = dup_name = p_strdup(server_pool, name); p_array_init(&server->connections, server_pool, - doveadm_settings->doveadm_worker_count); + ctx->set->doveadm_worker_count); p_array_init(&server->queue, server_pool, DOVEADM_SERVER_QUEUE_MAX); hash_table_insert(servers, dup_name, server); @@ -145,10 +146,9 @@ static int doveadm_mail_server_user_get_host(struct doveadm_mail_cmd_context *ctx, - const char *username, const char **host_r, - const char **error_r) + const struct mail_storage_service_input *input, + const char **host_r, const char **error_r) { - struct mail_storage_service_input input; struct auth_master_connection *auth_conn; struct auth_user_info info; pool_t pool; @@ -157,22 +157,20 @@ bool proxying; int ret; - *host_r = doveadm_settings->doveadm_socket_path; + *host_r = ctx->set->doveadm_socket_path; - if (doveadm_settings->doveadm_proxy_port == 0) + if (ctx->set->doveadm_proxy_port == 0) return 0; /* make sure we have an auth connection */ - memset(&input, 0, sizeof(input)); - input.service = "doveadm"; - mail_storage_service_init_settings(ctx->storage_service, &input); + mail_storage_service_init_settings(ctx->storage_service, input); memset(&info, 0, sizeof(info)); info.service = master_service_get_name(master_service); pool = pool_alloconly_create("auth lookup", 1024); auth_conn = mail_storage_service_get_auth_conn(ctx->storage_service); - ret = auth_master_pass_lookup(auth_conn, username, &info, + ret = auth_master_pass_lookup(auth_conn, input->username, &info, pool, &fields); if (ret < 0) { *error_r = fields[0] != NULL ? @@ -196,7 +194,7 @@ ret = -1; } else { *host_r = t_strdup_printf("%s:%u", proxy_host, - doveadm_settings->doveadm_proxy_port); + ctx->set->doveadm_proxy_port); } } pool_unref(&pool); @@ -204,7 +202,8 @@ } int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx, - const char *username, const char **error_r) + const struct mail_storage_service_input *input, + const char **error_r) { struct doveadm_server *server; struct server_connection *conn; @@ -219,28 +218,28 @@ so undo any sticks we might have added already */ doveadm_print_unstick_headers(); - ret = doveadm_mail_server_user_get_host(ctx, username, &host, error_r); + ret = doveadm_mail_server_user_get_host(ctx, input, &host, error_r); if (ret < 0) return -1; if (ret == 0 && - (doveadm_settings->doveadm_worker_count == 0 || doveadm_server)) { + (ctx->set->doveadm_worker_count == 0 || doveadm_server)) { /* run it ourself */ return 0; } - server = doveadm_server_get(host); + server = doveadm_server_get(ctx, host); conn = doveadm_server_find_unused_conn(server); if (conn != NULL) - doveadm_mail_server_handle(conn, username); + doveadm_mail_server_handle(conn, input->username); else if (array_count(&server->connections) < - I_MAX(doveadm_settings->doveadm_worker_count, 1)) { + I_MAX(ctx->set->doveadm_worker_count, 1)) { conn = server_connection_create(server); - doveadm_mail_server_handle(conn, username); + doveadm_mail_server_handle(conn, input->username); } else { if (array_count(&server->queue) >= DOVEADM_SERVER_QUEUE_MAX) doveadm_server_flush_one(server); - username_dup = i_strdup(username); + username_dup = i_strdup(input->username); array_append(&server->queue, &username_dup, 1); } *error_r = "doveadm server failure";
--- a/src/doveadm/doveadm-mail.c Fri May 20 13:30:40 2011 +0300 +++ b/src/doveadm/doveadm-mail.c Fri May 20 14:08:43 2011 +0300 @@ -195,7 +195,7 @@ /* see if we want to execute this command via (another) doveadm server */ - ret = doveadm_mail_server_user(ctx, input->username, error_r); + ret = doveadm_mail_server_user(ctx, input, error_r); if (ret != 0) return ret; @@ -223,20 +223,14 @@ return 1; } -void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, - char *argv[], const char *username, +void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, char *argv[], + const struct mail_storage_service_input *input, enum mail_storage_service_flags service_flags) { - struct mail_storage_service_input input; const char *error; int ret; - if (username == NULL) - i_fatal("USER environment is missing and -u option not used"); - - memset(&input, 0, sizeof(input)); - input.service = "doveadm"; - input.username = username; + i_assert(input->username != NULL); ctx->storage_service = mail_storage_service_init(master_service, NULL, service_flags); @@ -244,7 +238,7 @@ if (hook_doveadm_mail_init != NULL) hook_doveadm_mail_init(ctx); - ret = doveadm_mail_next_user(ctx, &input, &error); + ret = doveadm_mail_next_user(ctx, input, &error); if (ret < 0) i_fatal("%s", error); else if (ret == 0) @@ -340,11 +334,13 @@ } struct doveadm_mail_cmd_context * -doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd) +doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd, + const struct doveadm_settings *set) { struct doveadm_mail_cmd_context *ctx; ctx = cmd->alloc(); + ctx->set = set; ctx->cmd = cmd; if (ctx->v.init == NULL) ctx->v.init = doveadm_mail_cmd_init_noop; @@ -369,7 +365,7 @@ if (doveadm_debug) service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; - ctx = doveadm_mail_cmd_init(cmd); + ctx = doveadm_mail_cmd_init(cmd, doveadm_settings); getopt_args = t_strconcat("AS:u:", ctx->getopt_args, NULL); username = getenv("USER"); @@ -414,7 +410,15 @@ } if (ctx->iterate_single_user) { - doveadm_mail_single_user(ctx, argv, username, service_flags); + struct mail_storage_service_input input; + + if (username == NULL) + i_fatal("USER environment is missing and -u option not used"); + + memset(&input, 0, sizeof(input)); + input.service = "doveadm"; + input.username = username; + doveadm_mail_single_user(ctx, argv, &input, service_flags); } else { service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; doveadm_mail_all_users(ctx, argv, wildcard_user, service_flags);
--- a/src/doveadm/doveadm-mail.h Fri May 20 13:30:40 2011 +0300 +++ b/src/doveadm/doveadm-mail.h Fri May 20 14:08:43 2011 +0300 @@ -39,6 +39,7 @@ const char *const *args; const char *getopt_args; + const struct doveadm_settings *set; struct mail_storage_service_ctx *storage_service; /* search args aren't set for all mail commands */ struct mail_search_args *search_args; @@ -80,12 +81,14 @@ void doveadm_mail_deinit(void); struct doveadm_mail_cmd_context * -doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd); -void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, - char *argv[], const char *username, +doveadm_mail_cmd_init(const struct doveadm_mail_cmd *cmd, + const struct doveadm_settings *set); +void doveadm_mail_single_user(struct doveadm_mail_cmd_context *ctx, char *argv[], + const struct mail_storage_service_input *input, enum mail_storage_service_flags service_flags); int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx, - const char *username, const char **error_r); + const struct mail_storage_service_input *input, + const char **error_r); void doveadm_mail_server_flush(void); int doveadm_mailbox_find_and_sync(struct mail_user *user, const char *mailbox,