From: Timo Sirainen Date: Wed, 15 Sep 2021 13:34:32 +0000 (+0300) Subject: lib-doveadm, doveadm: Send proxy-ttl differently in doveadm protocol X-Git-Tag: 2.4.0~4722 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1edb96b309e1d97794a4a540886e619a9b12e246;p=thirdparty%2Fdovecot%2Fcore.git lib-doveadm, doveadm: Send proxy-ttl differently in doveadm protocol The --proxy-ttl parameter works only for mail commands. This breaks using lib-doveadm with non-mail commands. Fix this by extending the doveadm command "flags" parameter with "x" that specifies that the next field is a tabescaped list of key=value pairs which can be used to specify any kind of future command-specific options. --- diff --git a/src/doveadm/client-connection-tcp.c b/src/doveadm/client-connection-tcp.c index dc1bce0496..97c9402455 100644 --- a/src/doveadm/client-connection-tcp.c +++ b/src/doveadm/client-connection-tcp.c @@ -279,9 +279,7 @@ static bool client_handle_command(struct client_connection_tcp *conn, cctx.remote_port = conn->conn.remote_port; doveadm_exit_code = 0; - flags = args[0]; - cctx.username = args[1]; - cmd_name = args[2]; + flags = args[0]; args++; argc--; doveadm_debug = FALSE; doveadm_verbose = FALSE; @@ -295,14 +293,20 @@ static bool client_handle_command(struct client_connection_tcp *conn, case 'v': doveadm_verbose = TRUE; break; + case 'x': + cctx.extra_fields = t_strsplit_tabescaped(args[0]); + args++; argc--; + break; default: i_error("doveadm client: Unknown flag: %c", *flags); return FALSE; } } + cctx.username = args[0]; args++; argc--; + cmd_name = args[0]; if (strcmp(cmd_name, "OPTION") == 0) { - client_handle_options(conn, args+3); + client_handle_options(conn, args+1); return TRUE; } @@ -317,7 +321,7 @@ static bool client_handle_command(struct client_connection_tcp *conn, /* Disable IO while running a command. This is required for commands that do IO themselves (e.g. dsync-server). */ io_remove(&conn->io); - if (doveadm_cmd_handle(conn, cmd_name, argc-2, args+2, &cctx) < 0) + if (doveadm_cmd_handle(conn, cmd_name, argc, args, &cctx) < 0) o_stream_nsend(conn->output, "\n-\n", 3); o_stream_uncork(conn->output); conn->io = io_add_istream(conn->input, client_connection_tcp_input, conn); diff --git a/src/doveadm/doveadm-cmd.h b/src/doveadm/doveadm-cmd.h index bd44693fcb..5f66ee65bd 100644 --- a/src/doveadm/doveadm-cmd.h +++ b/src/doveadm/doveadm-cmd.h @@ -77,6 +77,8 @@ struct doveadm_cmd_context { const char *username; struct ip_addr local_ip, remote_ip; in_port_t local_port, remote_port; + /* extra fields (e.g. forward_*) sent via doveadm protocol */ + const char *const *extra_fields; enum doveadm_client_type conn_type; struct istream *input; diff --git a/src/doveadm/doveadm-mail-server.c b/src/doveadm/doveadm-mail-server.c index d5462372f7..f3d07e83ec 100644 --- a/src/doveadm/doveadm-mail-server.c +++ b/src/doveadm/doveadm-mail-server.c @@ -636,6 +636,28 @@ doveadm_mail_server_user_get_host(struct doveadm_mail_cmd_context *ctx, return ret; } +static void +doveadm_mail_cmd_extra_fields_parse(struct doveadm_mail_cmd_context *ctx) +{ + const char *key, *value; + + if (ctx->cctx->extra_fields == NULL) + return; + for (unsigned int i = 0; ctx->cctx->extra_fields[i] != NULL; i++) { + key = ctx->cctx->extra_fields[i]; + value = strchr(key, '='); + if (value != NULL) + key = t_strdup_until(key, value++); + else + value = ""; + if (strcmp(key, "proxy-ttl") == 0) { + if (str_to_int(value, &ctx->proxy_ttl) < 0 || + ctx->proxy_ttl <= 0) + i_error("Invalid proxy-ttl value: %s", value); + } + } +} + int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx, const char **error_r) { @@ -649,6 +671,7 @@ int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx, i_assert(cmd_ctx == ctx || cmd_ctx == NULL); cmd_ctx = ctx; + doveadm_mail_cmd_extra_fields_parse(ctx); ret = doveadm_mail_server_user_get_host(ctx, &proxy_set, &socket_path, &referral, error_r); if (ret < 0) diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index a6bf9f2ae5..1d0aa1e349 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -952,9 +952,6 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx) /* This parameter allows to set additional * mailbox transaction flags. */ mctx->transaction_flags = arg->value.v_int64; - } else if (strcmp(arg->name, "proxy-ttl") == 0) { - /* if this becomes <= 1, stop attempting to proxy */ - mctx->proxy_ttl = arg->value.v_int64; /* Keep all named special parameters above this line */ diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h index 928494de08..a3bdd1809f 100644 --- a/src/doveadm/doveadm-mail.h +++ b/src/doveadm/doveadm-mail.h @@ -198,8 +198,7 @@ DOVEADM_CMD_PARAM('A', "all-users", CMD_PARAM_BOOL, 0) \ DOVEADM_CMD_PARAM('S', "socket-path", CMD_PARAM_STR, 0) \ DOVEADM_CMD_PARAM('u', "user", CMD_PARAM_STR, 0) \ DOVEADM_CMD_PARAM('\0', "trans-flags", CMD_PARAM_INT64, 0) \ -DOVEADM_CMD_PARAM('F', "user-file", CMD_PARAM_ISTREAM, 0) \ -DOVEADM_CMD_PARAM('\0', "proxy-ttl", CMD_PARAM_INT64, 0) +DOVEADM_CMD_PARAM('F', "user-file", CMD_PARAM_ISTREAM, 0) #define DOVEADM_CMD_MAIL_USAGE_PREFIX \ "[-u |-A] [-S ] " diff --git a/src/lib-doveadm/doveadm-client.c b/src/lib-doveadm/doveadm-client.c index eb61cbb39e..d3b27dae95 100644 --- a/src/lib-doveadm/doveadm-client.c +++ b/src/lib-doveadm/doveadm-client.c @@ -237,23 +237,18 @@ doveadm_client_send_cmd(struct doveadm_client *conn, i_assert(conn->authenticated); i_assert(proxy_ttl >= 1); - if (conn->conn.minor_version < DOVEADM_PROTOCOL_MIN_VERSION_PROXY_TTL) { + if (conn->conn.minor_version < DOVEADM_PROTOCOL_MIN_VERSION_EXTRA_FIELDS) { o_stream_nsend_str(conn->conn.output, cmdline); return; } - /* [] - - Insert --proxy-ttl as the first arg. */ + /* [] */ const char *p = strchr(cmdline, '\t'); i_assert(p != NULL); - p = strchr(p+1, '\t'); - i_assert(p != NULL); - p = strchr(p+1, '\t'); - i_assert(p != NULL); size_t prefix_len = p - cmdline; const char *proxy_ttl_str = t_strdup_printf( - "\t--proxy-ttl\t%d", proxy_ttl); + "x\tproxy-ttl=%d", proxy_ttl); struct const_iovec iov[] = { { cmdline, prefix_len }, { proxy_ttl_str, strlen(proxy_ttl_str) }, diff --git a/src/lib-doveadm/doveadm-protocol.h b/src/lib-doveadm/doveadm-protocol.h index 207f68281b..4f2760bd60 100644 --- a/src/lib-doveadm/doveadm-protocol.h +++ b/src/lib-doveadm/doveadm-protocol.h @@ -9,8 +9,8 @@ #define DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX 1 #define DOVEADM_PROTOCOL_MIN_VERSION_STARTTLS 2 -#define DOVEADM_PROTOCOL_MIN_VERSION_PROXY_TTL 3 #define DOVEADM_PROTOCOL_MIN_VERSION_LOG_PASSTHROUGH 3 +#define DOVEADM_PROTOCOL_MIN_VERSION_EXTRA_FIELDS 3 #define DOVEADM_EX_NOTFOUND EX_NOHOST #define DOVEADM_EX_NOTPOSSIBLE EX_DATAERR