From: Stephan Bosch Date: Sat, 7 Oct 2017 19:30:27 +0000 (+0200) Subject: doveadm: Changed command contexts to contain the input, output, and connection type... X-Git-Tag: 2.3.0.rc1~772 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b58508a918279d773ef32518f5d5d933023c252;p=thirdparty%2Fdovecot%2Fcore.git doveadm: Changed command contexts to contain the input, output, and connection type values directly. Before, it used a direct pointer to the connection. It used also flags to indicate the connection type, which is now consolidated in the connection type enum. --- diff --git a/src/doveadm/client-connection-http.c b/src/doveadm/client-connection-http.c index 52089a8970..5d6daa6223 100644 --- a/src/doveadm/client-connection-http.c +++ b/src/doveadm/client-connection-http.c @@ -107,7 +107,8 @@ client_connection_create_http(int fd, bool ssl) conn->client.pool = pool; conn->client.http = TRUE; - if (client_connection_init(&conn->client, fd) < 0) + if (client_connection_init(&conn->client, + CLIENT_CONNECTION_TYPE_HTTP, fd) < 0) return NULL; conn->http_client = http_server_connection_create(doveadm_http_server, @@ -346,7 +347,11 @@ doveadm_http_server_command_execute(struct client_connection_http *conn) struct istream *is; const char *user; struct ioloop *ioloop,*prev_ioloop = current_ioloop; + i_zero(&cctx); + cctx.conn_type = conn->client.type; + cctx.input = conn->client.input; + cctx.output = conn->client.output; // create iostream doveadm_print_ostream = iostream_temp_create("/tmp/doveadm.", 0); @@ -361,7 +366,6 @@ doveadm_http_server_command_execute(struct client_connection_http *conn) ioloop = io_loop_create(); doveadm_exit_code = 0; - cctx.cli = FALSE; cctx.local_ip = conn->client.local_ip; cctx.local_port = conn->client.local_port; cctx.remote_ip = conn->client.remote_ip; diff --git a/src/doveadm/client-connection-private.h b/src/doveadm/client-connection-private.h index fefadfc6b3..e90b1e586a 100644 --- a/src/doveadm/client-connection-private.h +++ b/src/doveadm/client-connection-private.h @@ -6,7 +6,8 @@ bool doveadm_client_is_allowed_command(const struct doveadm_settings *set, const char *cmd_name); -int client_connection_init(struct client_connection *conn, int fd); +int client_connection_init(struct client_connection *conn, + enum client_connection_type type, int fd); void client_connection_set_proctitle(struct client_connection *conn, const char *text); diff --git a/src/doveadm/client-connection.c b/src/doveadm/client-connection.c index 886ceb9bd8..0641a6d5e8 100644 --- a/src/doveadm/client-connection.c +++ b/src/doveadm/client-connection.c @@ -165,6 +165,7 @@ doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd, int c; mctx = doveadm_mail_cmd_init(cmd, set); + mctx->cctx = cctx; mctx->full_args = argv+1; mctx->proxying = TRUE; mctx->cur_username = cctx->username; @@ -237,7 +238,6 @@ doveadm_mail_cmd_server_run(struct client_connection *conn, const char *error; int ret; - mctx->conn = conn; o_stream_cork(conn->output); if (mctx->v.preinit != NULL) @@ -352,14 +352,13 @@ static bool client_handle_command(struct client_connection *conn, return FALSE; } i_zero(&cctx); - cctx.cli = FALSE; - cctx.tcp_server = TRUE; - + cctx.conn_type = conn->type; + cctx.input = conn->input; + cctx.output = conn->output; cctx.local_ip = conn->local_ip; cctx.remote_ip = conn->remote_ip; cctx.local_port = conn->local_port; cctx.remote_port = conn->remote_port; - cctx.conn = conn; doveadm_exit_code = 0; flags = args[0]; @@ -606,11 +605,15 @@ client_connection_send_auth_handshake(struct client_connection * } } -int client_connection_init(struct client_connection *conn, int fd) +int client_connection_init(struct client_connection *conn, + enum client_connection_type type, int fd) { const char *ip; + i_assert(type != CLIENT_CONNECTION_TYPE_CLI); + conn->fd = fd; + conn->type = type; (void)net_getsockname(fd, &conn->local_ip, &conn->local_port); (void)net_getpeername(fd, &conn->remote_ip, &conn->remote_port); @@ -636,7 +639,8 @@ client_connection_create(int fd, int listen_fd, bool ssl) conn = p_new(pool, struct client_connection, 1); conn->pool = pool; - if (client_connection_init(conn, fd) < 0) + if (client_connection_init(conn, + CLIENT_CONNECTION_TYPE_TCP, fd) < 0) return NULL; doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER); diff --git a/src/doveadm/client-connection.h b/src/doveadm/client-connection.h index 4b18664a2b..00e92fb2b1 100644 --- a/src/doveadm/client-connection.h +++ b/src/doveadm/client-connection.h @@ -5,8 +5,15 @@ #define DOVEADM_LOG_CHANNEL_ID 'L' +enum client_connection_type { + CLIENT_CONNECTION_TYPE_CLI = 0, + CLIENT_CONNECTION_TYPE_TCP, + CLIENT_CONNECTION_TYPE_HTTP, +}; + struct client_connection { pool_t pool; + enum client_connection_type type; int fd; const char *name; diff --git a/src/doveadm/doveadm-cmd.h b/src/doveadm/doveadm-cmd.h index 9f226ef8c3..743f4be263 100644 --- a/src/doveadm/doveadm-cmd.h +++ b/src/doveadm/doveadm-cmd.h @@ -2,6 +2,7 @@ #define DOVEADM_CMD_H #include "net.h" +#include "client-connection.h" #define DOVEADM_CMD_PARAMS_START .parameters = (const struct doveadm_cmd_param[]){ #define DOVEADM_CMD_PARAM(optP, nameP, typeP, flagP ) { .short_opt = optP, .name = nameP, .type = typeP, .flags = flagP }, @@ -76,11 +77,12 @@ struct doveadm_cmd_context { const struct doveadm_cmd_param *argv; const char *username; - bool cli; - bool tcp_server; struct ip_addr local_ip, remote_ip; in_port_t local_port, remote_port; - struct client_connection *conn; + + enum client_connection_type conn_type; + struct istream *input; + struct ostream *output; }; ARRAY_DEFINE_TYPE(doveadm_cmd, struct doveadm_cmd); diff --git a/src/doveadm/doveadm-dsync.c b/src/doveadm/doveadm-dsync.c index 091be87439..7f82e15935 100644 --- a/src/doveadm/doveadm-dsync.c +++ b/src/doveadm/doveadm-dsync.c @@ -559,6 +559,7 @@ static int cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; + struct doveadm_cmd_context *cctx = _ctx->cctx; struct dsync_ibc *ibc, *ibc2 = NULL; struct dsync_brain *brain; struct dsync_brain_settings set; @@ -684,7 +685,7 @@ cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) if (changes_during_sync != NULL || changes_during_sync2 != NULL) { /* don't log a warning when running via doveadm server (e.g. called by replicator) */ - if (ctx->ctx.conn == NULL) { + if (cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI) { i_warning("Mailbox changes caused a desync. " "You may want to run dsync again: %s", changes_during_sync == NULL || @@ -1135,6 +1136,8 @@ cmd_dsync_server_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user) { struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; + struct doveadm_cmd_context *cctx = _ctx->cctx; + bool cli = (cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); struct dsync_ibc *ibc; struct dsync_brain *brain; string_t *temp_prefix, *state_str = NULL; @@ -1142,12 +1145,12 @@ cmd_dsync_server_run(struct doveadm_mail_cmd_context *_ctx, const char *name, *process_title_prefix = ""; enum mail_error mail_error; - if (_ctx->conn != NULL) { + if (!cli) { /* doveadm-server connection. start with a success reply. after that follows the regular dsync protocol. */ ctx->fd_in = ctx->fd_out = -1; - ctx->input = _ctx->conn->input; - ctx->output = _ctx->conn->output; + ctx->input = cctx->input; + ctx->output = cctx->output; o_stream_nsend(ctx->output, "\n+\n", 3); i_set_failure_prefix("dsync-server(%s): ", user->username); name = i_stream_get_name(ctx->input); @@ -1184,10 +1187,10 @@ cmd_dsync_server_run(struct doveadm_mail_cmd_context *_ctx, doveadm_mail_failed_error(_ctx, mail_error); dsync_ibc_deinit(&ibc); - if (_ctx->conn != NULL) { + if (!cli) { /* make sure nothing more is written by the generic doveadm connection code */ - o_stream_close(_ctx->conn->output); + o_stream_close(cctx->output); } if (ctx->replicator_notify && _ctx->exit_code == 0) diff --git a/src/doveadm/doveadm-kick.c b/src/doveadm/doveadm-kick.c index ad95fd890a..1805d86b1a 100644 --- a/src/doveadm/doveadm-kick.c +++ b/src/doveadm/doveadm-kick.c @@ -28,7 +28,7 @@ struct kick_pid { struct kick_context { struct who_context who; HASH_TABLE(void *, struct kick_pid *) pids; - bool cli; + enum client_connection_type conn_type; bool force_kick; ARRAY(const char *) kicked_users; }; @@ -101,15 +101,16 @@ kick_print_kicked(struct kick_context *ctx, const bool show_warning) { unsigned int i, count; const char *const *users; + bool cli = (ctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); if (array_count(&ctx->kicked_users) == 0) { - if (ctx->cli) + if (cli) printf("no users kicked\n"); doveadm_exit_code = DOVEADM_EX_NOTFOUND; return; } - if (ctx->cli) { + if (cli) { if (show_warning) { printf("warning: other connections would also be " "kicked from following users:\n"); @@ -125,7 +126,7 @@ kick_print_kicked(struct kick_context *ctx, const bool show_warning) if (strcmp(users[i-1], users[i]) != 0) doveadm_print(users[i]); } - if (ctx->cli) + if (cli) printf("\n"); if (show_warning) @@ -188,8 +189,8 @@ static void cmd_kick(struct doveadm_cmd_context *cctx) i_error("user and/or ip[/bits] must be specified."); return; } - ctx.cli = cctx->cli; - if (!ctx.cli) { + ctx.conn_type = cctx->conn_type; + if (ctx.conn_type != CLIENT_CONNECTION_TYPE_CLI) { /* force-kick is a pretty ugly option. its output can't be nicely translated to an API reply. it also wouldn't be very useful in scripts, only for preventing a new admin from diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index a611ee7e33..3551a32db6 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -222,18 +222,20 @@ static void doveadm_mail_cmd_input_read(struct doveadm_mail_cmd_context *ctx) void doveadm_mail_get_input(struct doveadm_mail_cmd_context *ctx) { + const struct doveadm_cmd_context *cctx = ctx->cctx; + bool cli = (cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); struct istream *inputs[2]; if (ctx->cmd_input != NULL) return; - if (!ctx->cli && ctx->conn == NULL) { + if (!cli && cctx->input == NULL) { ctx->cmd_input = i_stream_create_error_str(EINVAL, "Input stream missing (provide with file parameter)"); return; } - if (ctx->conn != NULL) - inputs[0] = i_stream_create_dot(ctx->conn->input, FALSE); + if (!cli) + inputs[0] = i_stream_create_dot(cctx->input, FALSE); else { inputs[0] = i_stream_create_fd(STDIN_FILENO, 1024*1024); i_stream_set_name(inputs[0], "stdin"); @@ -592,6 +594,7 @@ doveadm_mail_cmd_exec(struct doveadm_mail_cmd_context *ctx, struct doveadm_cmd_context *cctx, const char *wildcard_user) { + bool cli = (cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); int ret; const char *error; @@ -610,7 +613,7 @@ doveadm_mail_cmd_exec(struct doveadm_mail_cmd_context *ctx, if (ctx->iterate_single_user) { if (ctx->cur_username == NULL) i_fatal_status(EX_USAGE, "USER environment is missing and -u option not used"); - if (!ctx->cli) { + if (!cli) { /* we may access multiple users */ ctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP; } @@ -658,13 +661,14 @@ doveadm_mail_cmd(const struct doveadm_mail_cmd *cmd, int argc, char *argv[]) const char *getopt_args, *wildcard_user; int c; + i_zero(&cctx); + cctx.conn_type = CLIENT_CONNECTION_TYPE_CLI; + ctx = doveadm_mail_cmdline_init(cmd); + ctx->cctx = &cctx; ctx->full_args = (const void *)(argv + 1); - ctx->cli = TRUE; ctx->cur_username = getenv("USER"); - i_zero(&cctx); - getopt_args = "AF:S:u:"; /* keep context's getopt_args first in case it contains '+' */ if (ctx->getopt_args != NULL) @@ -961,17 +965,20 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) const char *fieldstr; ARRAY_TYPE(const_string) pargv, full_args; int i; + bool cli = (cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); + bool tcp_server = (cctx->conn_type == CLIENT_CONNECTION_TYPE_TCP); struct doveadm_mail_cmd mail_cmd = { cctx->cmd->mail_cmd, cctx->cmd->name, cctx->cmd->usage }; - if (!cctx->cli) { + if (!cli) { mctx = doveadm_mail_cmd_init(&mail_cmd, doveadm_settings); /* doveadm-server always does userdb lookups */ mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; } else { mctx = doveadm_mail_cmdline_init(&mail_cmd); } + mctx->cctx = cctx; mctx->cur_username = cctx->username; mctx->iterate_all_users = FALSE; wildcard_user = NULL; @@ -985,7 +992,7 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) continue; if (strcmp(arg->name, "all-users") == 0) { - if (cctx->tcp_server) + if (tcp_server) mctx->add_username_header = TRUE; else mctx->iterate_all_users = arg->value.v_bool; @@ -997,7 +1004,7 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) doveadm_settings->doveadm_worker_count = 1; } else if (strcmp(arg->name, "user") == 0) { mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; - if (!cctx->tcp_server) + if (!tcp_server) mctx->cur_username = arg->value.v_string; fieldstr = "-u"; @@ -1005,13 +1012,13 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) array_append(&full_args, &arg->value.v_string, 1); if (strchr(arg->value.v_string, '*') != NULL || strchr(arg->value.v_string, '?') != NULL) { - if (cctx->tcp_server) + if (tcp_server) mctx->add_username_header = TRUE; else { wildcard_user = arg->value.v_string; mctx->cur_username = NULL; } - } else if (!cctx->tcp_server) { + } else if (!tcp_server) { cctx->username = mctx->cur_username; } } else if (strcmp(arg->name, "user-file") == 0) { @@ -1085,8 +1092,6 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) mctx->args = array_idx(&full_args, args_pos); mctx->full_args = array_idx(&full_args, 0); - mctx->cli = cctx->cli; - mctx->conn = cctx->conn; doveadm_mail_cmd_exec(mctx, cctx, wildcard_user); doveadm_mail_cmd_free(mctx); diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index b1e935fef0..f28bdaa91a 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -61,12 +61,11 @@ union doveadm_mail_cmd_module_context { struct doveadm_mail_cmd_context { pool_t pool; + struct doveadm_cmd_context *cctx; const struct doveadm_mail_cmd *cmd; const char *const *args; /* args including -options */ const char *const *full_args; - /* connection via doveadm-server */ - struct client_connection *conn; const char *getopt_args; const struct doveadm_settings *set; @@ -99,8 +98,6 @@ struct doveadm_mail_cmd_context { bool iterate_all_users:1; /* Add username header to all replies */ bool add_username_header:1; - /* Running from CLI doveadm (not doveadm-server) */ - bool cli:1; }; struct doveadm_mail_cmd { diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index a03c466030..0d8aeaed29 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -299,7 +299,7 @@ int main(int argc, char *argv[]) int c; i_zero(&cctx); - cctx.cli = TRUE; + cctx.conn_type = CLIENT_CONNECTION_TYPE_CLI; i_set_failure_exit_callback(failure_exit_callback); doveadm_dsync_main(&argc, &argv); diff --git a/src/plugins/mail-crypt/doveadm-mail-crypt.c b/src/plugins/mail-crypt/doveadm-mail-crypt.c index 0655236657..10c3e7b5a9 100644 --- a/src/plugins/mail-crypt/doveadm-mail-crypt.c +++ b/src/plugins/mail-crypt/doveadm-mail-crypt.c @@ -692,6 +692,7 @@ static int cmd_mcp_key_password_run(struct doveadm_mail_cmd_context *_ctx, { struct mcp_cmd_context *ctx = (struct mcp_cmd_context *)_ctx; + bool cli = (_ctx->cctx->conn_type == CLIENT_CONNECTION_TYPE_CLI); struct raw_key { const char *attr; @@ -711,7 +712,7 @@ static int cmd_mcp_key_password_run(struct doveadm_mail_cmd_context *_ctx, _ctx->exit_code = EX_USAGE; return -1; } - if (!_ctx->cli) { + if (!cli) { doveadm_print("No cli - cannot ask for password"); _ctx->exit_code = EX_USAGE; return -1; @@ -726,7 +727,7 @@ static int cmd_mcp_key_password_run(struct doveadm_mail_cmd_context *_ctx, _ctx->exit_code = EX_USAGE; return -1; } - if (!_ctx->cli) { + if (!cli) { doveadm_print("No cli - cannot ask for password"); _ctx->exit_code = EX_USAGE; return -1;