dovecot-2.0: doveadm: Added support for using local/remote {} se...

dovecot at dovecot.org dovecot at dovecot.org
Fri May 20 14:08:52 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.0/rev/b6568a36ecf9
changeset: 12815:b6568a36ecf9
user:      Timo Sirainen <tss at iki.fi>
date:      Fri May 20 14:08:43 2011 +0300
description:
doveadm: Added support for using local/remote {} settings.

diffstat:

 src/doveadm/client-connection.c   |  73 ++++++++++++++++++++++++++++++++------
 src/doveadm/doveadm-mail-server.c |  39 ++++++++++----------
 src/doveadm/doveadm-mail.c        |  32 +++++++++-------
 src/doveadm/doveadm-mail.h        |  11 +++--
 4 files changed, 105 insertions(+), 50 deletions(-)

diffs (truncated from 419 to 300 lines):

diff -r 6604f80abb02 -r b6568a36ecf9 src/doveadm/client-connection.c
--- 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);
diff -r 6604f80abb02 -r b6568a36ecf9 src/doveadm/doveadm-mail-server.c
--- 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);


More information about the dovecot-cvs mailing list