changeset 20841:c3cc30b7eda6

doveadm proxy list: Show all user_* fields in output.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 06 Oct 2016 14:38:04 +0300
parents 1b4a57403aef
children 8c389aa81c15
files src/doveadm/doveadm-proxy.c src/login-common/login-proxy.c
diffstat 2 files changed, 83 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/doveadm-proxy.c	Wed Oct 05 23:22:56 2016 +0300
+++ b/src/doveadm/doveadm-proxy.c	Thu Oct 06 14:38:04 2016 +0300
@@ -41,21 +41,59 @@
 	return ctx;
 }
 
+static void cmd_proxy_list_header(const char *const *args)
+{
+	struct {
+		const char *key;
+		const char *title;
+	} header_map[] = {
+		{ "service", "proto" },
+		{ "src-ip", "src ip" },
+		{ "dest-ip", "dest ip" },
+		{ "dest-port", "port" },
+	};
+	for (unsigned int i = 0; args[i] != NULL; i++) {
+		const char *arg = args[i];
+
+		if (strcmp(arg, "username") == 0 ||
+		    strncmp(arg, "user_", 5) == 0) {
+			doveadm_print_header(arg, arg,
+					     DOVEADM_PRINT_HEADER_FLAG_EXPAND);
+			continue;
+		}
+		const char *title = arg;
+		for (unsigned int j = 0; j < N_ELEMENTS(header_map); j++) {
+			if (strcmp(header_map[j].key, arg) == 0) {
+				title = header_map[j].title;
+				break;
+			}
+		}
+		doveadm_print_header(arg, title, 0);
+	}
+}
+
 static void cmd_proxy_list_callback(enum ipc_client_cmd_state state,
-				    const char *data, void *context ATTR_UNUSED)
+				    const char *data, void *context)
 {
+	bool *seen_header = context;
+
 	switch (state) {
-	case IPC_CLIENT_CMD_STATE_REPLY:
-		T_BEGIN {
-			const char *const *args = t_strsplit_tab(data);
+	case IPC_CLIENT_CMD_STATE_REPLY: {
+		const char *const *args = t_strsplit_tab(data);
+
+		if (!*seen_header) {
+			cmd_proxy_list_header(args);
+			*seen_header = TRUE;
+		} else {
 			for (; *args != NULL; args++)
 				doveadm_print(*args);
-		} T_END;
+		}
 		return;
+	}
 	case IPC_CLIENT_CMD_STATE_OK:
 		break;
 	case IPC_CLIENT_CMD_STATE_ERROR:
-		i_error("LIST failed: %s", data);
+		i_error("LIST-FULL failed: %s", data);
 		break;
 	}
 	io_loop_stop(current_ioloop);
@@ -64,19 +102,15 @@
 static void cmd_proxy_list(int argc, char *argv[])
 {
 	struct proxy_context *ctx;
+	bool seen_header = FALSE;
 
 	ctx = cmd_proxy_init(argc, argv, "a:", cmd_proxy_list);
 
 	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
-	doveadm_print_header("username", "username", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
-	doveadm_print_header("service", "proto", 0);
-	doveadm_print_header("src-ip", "src ip", 0);
-	doveadm_print_header("dest-ip", "dest ip", 0);
-	doveadm_print_header("dest-port", "port", 0);
 
 	io_loop_set_running(current_ioloop);
-	ipc_client_cmd(ctx->ipc, "proxy\t*\tLIST",
-		       cmd_proxy_list_callback, NULL);
+	ipc_client_cmd(ctx->ipc, "proxy\t*\tLIST-FULL",
+		       cmd_proxy_list_callback, &seen_header);
 	if (io_loop_is_running(current_ioloop))
 		io_loop_run(current_ioloop);
 	ipc_client_deinit(&ctx->ipc);
--- a/src/login-common/login-proxy.c	Wed Oct 05 23:22:56 2016 +0300
+++ b/src/login-common/login-proxy.c	Thu Oct 06 14:38:04 2016 +0300
@@ -5,7 +5,9 @@
 #include "istream.h"
 #include "ostream.h"
 #include "llist.h"
+#include "array.h"
 #include "str.h"
+#include "strescape.h"
 #include "str-sanitize.h"
 #include "time-util.h"
 #include "master-service.h"
@@ -915,30 +917,51 @@
 }
 
 static void
-login_proxy_cmd_list_reply(struct ipc_cmd *cmd,
+login_proxy_cmd_list_reply(struct ipc_cmd *cmd, string_t *str,
 			   struct login_proxy *proxy)
 {
-	T_BEGIN {
-		const char *reply;
+	unsigned int i, alt_count = array_count(&global_alt_usernames);
 
-		reply = t_strdup_printf("%s\t%s\t%s\t%s\t%u",
-					proxy->client->virtual_user,
-					login_binary->protocol,
-					net_ip2addr(&proxy->client->ip),
-					net_ip2addr(&proxy->ip), proxy->port);
-		ipc_cmd_send(cmd, reply);
-	} T_END;
+	str_truncate(str, 0);
+	str_append_tabescaped(str, proxy->client->virtual_user);
+	str_append_c(str, '\t');
+	i = 0;
+	if (proxy->client->alt_usernames != NULL) {
+		for (; proxy->client->alt_usernames[i] != NULL; i++) {
+			str_append_tabescaped(str, proxy->client->alt_usernames[i]);
+			str_append_c(str, '\t');
+		}
+		i_assert(i <= alt_count);
+	}
+	for (; i < alt_count; i++)
+		str_append_c(str, '\t');
+
+	str_printfa(str, "%s\t%s\t%s\t%u", login_binary->protocol,
+		    net_ip2addr(&proxy->client->ip),
+		    net_ip2addr(&proxy->ip), proxy->port);
+	ipc_cmd_send(cmd, str_c(str));
 }
 
 static void
 login_proxy_cmd_list(struct ipc_cmd *cmd, const char *const *args ATTR_UNUSED)
 {
 	struct login_proxy *proxy;
+	char *const *fieldp;
+	string_t *str = t_str_new(64);
+
+	str_append(str, "username\t");
+	array_foreach(&global_alt_usernames, fieldp) {
+		str_append_tabescaped(str, *fieldp);
+		str_append_c(str, '\t');
+	}
+	str_append(str, "service\tsrc-ip\tdest-ip\tdest-port");
+
+	ipc_cmd_send(cmd, str_c(str));
 
 	for (proxy = login_proxies; proxy != NULL; proxy = proxy->next)
-		login_proxy_cmd_list_reply(cmd, proxy);
+		login_proxy_cmd_list_reply(cmd, str, proxy);
 	for (proxy = login_proxies_pending; proxy != NULL; proxy = proxy->next)
-		login_proxy_cmd_list_reply(cmd, proxy);
+		login_proxy_cmd_list_reply(cmd, str, proxy);
 	ipc_cmd_success(&cmd);
 }
 
@@ -952,7 +975,7 @@
 		login_proxy_cmd_kick(cmd, args);
 	else if (strcmp(name, "KICK-DIRECTOR-HASH") == 0)
 		login_proxy_cmd_kick_director_hash(cmd, args);
-	else if (strcmp(name, "LIST") == 0)
+	else if (strcmp(name, "LIST-FULL") == 0)
 		login_proxy_cmd_list(cmd, args);
 	else
 		ipc_cmd_fail(&cmd, "Unknown command");