]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm proxy list: Show all user_* fields in output.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Oct 2016 11:38:04 +0000 (14:38 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 13 Oct 2016 08:26:56 +0000 (10:26 +0200)
src/doveadm/doveadm-proxy.c
src/login-common/login-proxy.c

index 244f06555536355d90c1d08587c2381dd0a64a70..aba622240ea94f948c3dcd2fcda8b3993255dd01 100644 (file)
@@ -41,21 +41,59 @@ cmd_proxy_init(int argc, char *argv[], const char *getopt_args,
        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_callback(enum ipc_client_cmd_state state,
 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);
index 7ccf1558e94c0e5ddd01d531521e735b64df01a9..8f587c26d08ee2983990baa4ab519144867a787d 100644 (file)
@@ -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 @@ login_proxy_cmd_kick_director_hash(struct ipc_cmd *cmd, const char *const *args)
 }
 
 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 @@ static void login_proxy_ipc_cmd(struct ipc_cmd *cmd, const char *line)
                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");