pool_unref(&ctx.who.pool);
}
+#define DOVEADM_CMD_KICK_FIELDS \
+ .cmd = cmd_kick, \
+ .usage = "[-a <anvil socket path>] [-f <passdb field>] [-h <dest host>] <user mask>[|]<ip/bits>", \
+DOVEADM_CMD_PARAMS_START \
+DOVEADM_CMD_PARAM('a',"socket-path",CMD_PARAM_STR,0) \
+DOVEADM_CMD_PARAM('f',"passdb-field",CMD_PARAM_STR,0) \
+DOVEADM_CMD_PARAM('h',"dest-host",CMD_PARAM_STR,0) \
+DOVEADM_CMD_PARAM('\0',"mask",CMD_PARAM_ARRAY,CMD_PARAM_FLAG_POSITIONAL) \
+DOVEADM_CMD_PARAMS_END
+
struct doveadm_cmd_ver2 doveadm_cmd_kick_ver2 = {
.name = "kick",
- .cmd = cmd_kick,
- .usage = "[-a <anvil socket path>] [-f <passdb field>] [-h <dest host>] <user mask>[|]<ip/bits>",
-DOVEADM_CMD_PARAMS_START
-DOVEADM_CMD_PARAM('a',"socket-path",CMD_PARAM_STR,0)
-DOVEADM_CMD_PARAM('f',"passdb-field",CMD_PARAM_STR,0)
-DOVEADM_CMD_PARAM('h',"dest-host",CMD_PARAM_STR,0)
-DOVEADM_CMD_PARAM('\0',"mask",CMD_PARAM_ARRAY,CMD_PARAM_FLAG_POSITIONAL)
-DOVEADM_CMD_PARAMS_END
+ DOVEADM_CMD_KICK_FIELDS
+};
+struct doveadm_cmd_ver2 doveadm_cmd_proxy_kick_ver2 = {
+ .name = "proxy kick",
+ DOVEADM_CMD_KICK_FIELDS
};
+++ /dev/null
-/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "ioloop.h"
-#include "str.h"
-#include "strescape.h"
-#include "ipc-client.h"
-#include "doveadm.h"
-#include "doveadm-print.h"
-
-#include <stdio.h>
-#include <unistd.h>
-
-struct proxy_context {
- struct ipc_client *ipc;
- const char *username_field;
- const char *kick_hosts;
-};
-
-extern struct doveadm_cmd_ver2 doveadm_cmd_proxy[];
-
-static void proxy_cmd_help(struct doveadm_cmd_context *cctx) ATTR_NORETURN;
-
-static struct proxy_context *
-cmd_proxy_init(struct doveadm_cmd_context *cctx)
-{
- struct proxy_context *ctx;
- const char *socket_path;
-
- ctx = t_new(struct proxy_context, 1);
- if (!doveadm_cmd_param_str(cctx, "socket-path", &socket_path)) {
- socket_path = t_strconcat(doveadm_settings->base_dir,
- "/ipc", NULL);
- }
- (void)doveadm_cmd_param_str(cctx, "passdb-field", &ctx->username_field);
- (void)doveadm_cmd_param_str(cctx, "host", &ctx->kick_hosts);
- ctx->ipc = ipc_client_init(socket_path);
- 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 ||
- str_begins(arg, "user_")) {
- 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)
-{
- bool *seen_header = context;
-
- switch (state) {
- case IPC_CLIENT_CMD_STATE_REPLY: {
- const char *const *args = t_strsplit_tabescaped(data);
-
- if (!*seen_header) {
- cmd_proxy_list_header(args);
- *seen_header = TRUE;
- } else {
- for (; *args != NULL; args++)
- doveadm_print(*args);
- }
- return;
- }
- case IPC_CLIENT_CMD_STATE_OK:
- break;
- case IPC_CLIENT_CMD_STATE_ERROR:
- i_error("LIST-FULL failed: %s", data);
- break;
- }
- io_loop_stop(current_ioloop);
-}
-
-static void cmd_proxy_list(struct doveadm_cmd_context *cctx)
-{
- struct proxy_context *ctx;
- bool seen_header = FALSE;
-
- ctx = cmd_proxy_init(cctx);
-
- doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
-
- io_loop_set_running(current_ioloop);
- 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);
-}
-
-static void cmd_proxy_kick_callback(enum ipc_client_cmd_state state,
- const char *data, void *context ATTR_UNUSED)
-{
- switch (state) {
- case IPC_CLIENT_CMD_STATE_REPLY:
- return;
- case IPC_CLIENT_CMD_STATE_OK:
- if (data[0] == '\0')
- data = "0";
- doveadm_print(data);
- break;
- case IPC_CLIENT_CMD_STATE_ERROR:
- i_error("KICK failed: %s", data);
- doveadm_exit_code = EX_TEMPFAIL;
- break;
- }
- io_loop_stop(current_ioloop);
-}
-
-static void cmd_proxy_kick(struct doveadm_cmd_context *cctx)
-{
- struct proxy_context *ctx;
- const char *const *users = NULL;
- string_t *cmd;
-
- ctx = cmd_proxy_init(cctx);
- (void)doveadm_cmd_param_array(cctx, "user", &users);
- if (users == NULL && ctx->kick_hosts == NULL)
- proxy_cmd_help(cctx);
-
- doveadm_print_init(DOVEADM_PRINT_TYPE_FORMATTED);
- doveadm_print_formatted_set_format("%{count} connections kicked\n");
- doveadm_print_header_simple("count");
-
- cmd = t_str_new(128);
- str_append(cmd, "proxy\t*\t");
- if (ctx->kick_hosts != NULL) {
- str_append(cmd, "KICK-HOST\t");
- str_append(cmd, ctx->kick_hosts);
- }
- else if (ctx->username_field == NULL)
- str_append(cmd, "KICK");
- else {
- str_append(cmd, "KICK-ALT\t");
- str_append_tabescaped(cmd, ctx->username_field);
- }
- if (users != NULL) {
- for (unsigned int i = 0; users[i] != NULL; i++) {
- str_append_c(cmd, '\t');
- str_append_tabescaped(cmd, users[i]);
- }
- }
- ipc_client_cmd(ctx->ipc, str_c(cmd), cmd_proxy_kick_callback, NULL);
- io_loop_run(current_ioloop);
- ipc_client_deinit(&ctx->ipc);
-}
-
-struct doveadm_cmd_ver2 doveadm_cmd_proxy[] = {
-{
- .name = "proxy list",
- .usage = "[-a <ipc socket path>]",
- .cmd = cmd_proxy_list,
-DOVEADM_CMD_PARAMS_START
-DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAMS_END
-},
-{
- .name = "proxy kick",
- .usage = "[-a <ipc socket path>] [-f <passdb field>] [-h <host> [...] | <user> [...]]",
- .cmd = cmd_proxy_kick,
-DOVEADM_CMD_PARAMS_START
-DOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAM('f', "passdb-field", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAM('h', "host", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
-DOVEADM_CMD_PARAMS_END
-}
-};
-
-static void proxy_cmd_help(struct doveadm_cmd_context *cctx)
-{
- unsigned int i;
-
- for (i = 0; i < N_ELEMENTS(doveadm_cmd_proxy); i++) {
- if (doveadm_cmd_proxy[i].cmd == cctx->cmd->cmd)
- help_ver2(&doveadm_cmd_proxy[i]);
- }
- i_unreached();
-}
-
-void doveadm_register_proxy_commands(void)
-{
- unsigned int i;
-
- for (i = 0; i < N_ELEMENTS(doveadm_cmd_proxy); i++)
- doveadm_cmd_register_ver2(&doveadm_cmd_proxy[i]);
-}
pool_unref(&ctx.pool);
}
+#define DOVEADM_CMD_WHO_FIELDS \
+ .cmd = cmd_who, \
+ .usage = "[-a <anvil socket path>] [-1] [-f <passdb field>] [<user mask>] [<ip/bits>]", \
+DOVEADM_CMD_PARAMS_START \
+DOVEADM_CMD_PARAM('a',"socket-path", CMD_PARAM_STR, 0) \
+DOVEADM_CMD_PARAM('1',"separate-connections", CMD_PARAM_BOOL, 0) \
+DOVEADM_CMD_PARAM('f',"passdb-field", CMD_PARAM_STR, 0) \
+DOVEADM_CMD_PARAM('\0',"mask", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL) \
+DOVEADM_CMD_PARAMS_END
+
struct doveadm_cmd_ver2 doveadm_cmd_who_ver2 = {
.name = "who",
- .cmd = cmd_who,
- .usage = "[-a <anvil socket path>] [-1] [-f <passdb field>] [<user mask>] [<ip/bits>]",
-DOVEADM_CMD_PARAMS_START
-DOVEADM_CMD_PARAM('a',"socket-path", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAM('1',"separate-connections", CMD_PARAM_BOOL, 0)
-DOVEADM_CMD_PARAM('f',"passdb-field", CMD_PARAM_STR, 0)
-DOVEADM_CMD_PARAM('\0',"mask", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
-DOVEADM_CMD_PARAMS_END
+ DOVEADM_CMD_WHO_FIELDS
+};
+
+struct doveadm_cmd_ver2 doveadm_cmd_proxy_list_ver2 = {
+ .name = "proxy list",
+ DOVEADM_CMD_WHO_FIELDS
};