]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-doveadm, doveadm: Send proxy-ttl differently in doveadm protocol
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Sep 2021 13:34:32 +0000 (16:34 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 17 Jan 2022 11:52:09 +0000 (13:52 +0200)
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.

src/doveadm/client-connection-tcp.c
src/doveadm/doveadm-cmd.h
src/doveadm/doveadm-mail-server.c
src/doveadm/doveadm-mail.c
src/doveadm/doveadm-mail.h
src/lib-doveadm/doveadm-client.c
src/lib-doveadm/doveadm-protocol.h

index dc1bce049615286dcd630ddab210753dc6aaf551..97c9402455e58200211cc6226e4d9c7bf5926975 100644 (file)
@@ -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);
index bd44693fcbb56df4ad85e4ff9da1803400ef367b..5f66ee65bd1692b2f07f26e215d97e445ba59161 100644 (file)
@@ -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;
index d5462372f75f304e4fc20a76043faca3d543a3f0..f3d07e83ecb9c4ae5b7f5c97097d32ece76ddac8 100644 (file)
@@ -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)
index a6bf9f2ae5538d6d785d912a1155405ffd5fb863..1d0aa1e3498eb717e267e8ba4c14953d28b2ba37 100644 (file)
@@ -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 */
 
index 928494de0853f491e6edbdf19a3050f904ab5b1b..a3bdd1809f2b6a61cf711535f5131505cde2d68e 100644 (file)
@@ -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 <user>|-A] [-S <socket_path>] "
index eb61cbb39ec20bcf51020339dbbbea6fb5771450..d3b27dae955ebc0ff8b27052aad6f84f18579b42 100644 (file)
@@ -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;
        }
 
-       /* <flags> <username> <command> [<args>] -
-          Insert --proxy-ttl as the first arg. */
+       /* <flags + x> <extra fields> <username> <command> [<args>] */
        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) },
index 207f68281bf470d1b86b44ccacf815d5248ee8b8..4f2760bd6031cc46602399932aefa1716a7e10d3 100644 (file)
@@ -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