]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-doveadm, doveadm: Change log passthrough to be optional
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 30 Jul 2021 14:23:55 +0000 (17:23 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 17 Jan 2022 11:52:09 +0000 (13:52 +0200)
src/doveadm/client-connection-tcp.c
src/doveadm/doveadm-mail-server.c
src/lib-doveadm/doveadm-client.c
src/lib-doveadm/doveadm-client.h
src/lib-doveadm/doveadm-protocol.h

index 091ea89eefa42ef0652e147306b6faec7ff7097e..dc1bce049615286dcd630ddab210753dc6aaf551 100644 (file)
@@ -26,6 +26,7 @@
 struct client_connection_tcp {
        struct client_connection conn;
 
+       unsigned int minor_version;
        int fd;
        struct io *io;
        struct istream *input;
@@ -38,7 +39,6 @@ struct client_connection_tcp {
        bool preauthenticated:1;
        bool authenticated:1;
        bool io_setup:1;
-       bool use_multiplex:1;
 };
 
 static void
@@ -244,6 +244,20 @@ static void client_connection_log_passthrough(struct client_connection_tcp *conn
        doveadm_server_capture_logs();
 }
 
+static void
+client_handle_options(struct client_connection_tcp *conn,
+                     const char *const *options)
+{
+       for (unsigned int i = 0; options[i] != NULL; i++) {
+               if (strcmp(options[i], "log-passthrough") == 0) {
+                       if (conn->log_out == NULL)
+                               client_connection_log_passthrough(conn);
+               } else {
+                       /* unknown option - ignore */
+               }
+       }
+}
+
 static bool client_handle_command(struct client_connection_tcp *conn,
                                  const char *const *args)
 {
@@ -287,6 +301,11 @@ static bool client_handle_command(struct client_connection_tcp *conn,
                }
        }
 
+       if (strcmp(cmd_name, "OPTION") == 0) {
+               client_handle_options(conn, args+3);
+               return TRUE;
+       }
+
        if (!doveadm_client_is_allowed_command(conn->conn.set, cmd_name)) {
                i_error("doveadm client isn't allowed to use command: %s",
                        cmd_name);
@@ -387,7 +406,6 @@ client_connection_tcp_input(struct client_connection_tcp *conn)
        const char *line;
        bool ok = TRUE;
        int ret;
-       unsigned int minor;
 
        if (!conn->handshaked) {
                if ((line = i_stream_read_next_line(conn->input)) == NULL) {
@@ -398,17 +416,17 @@ client_connection_tcp_input(struct client_connection_tcp *conn)
                        return;
                }
                if (!version_string_verify_full(line, "doveadm-server",
-                               DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR, &minor)) {
+                               DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR,
+                               &conn->minor_version)) {
                        i_error("doveadm client not compatible with this server "
                                "(mixed old and new binaries?)");
                        client_connection_tcp_destroy(&conn);
                        return;
                }
-               if (minor >= DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX) {
+               if (conn->minor_version >= DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX) {
                        /* send version reply */
                        o_stream_nsend_str(conn->output,
                                           DOVEADM_CLIENT_PROTOCOL_VERSION_LINE"\n");
-                       conn->use_multiplex = TRUE;
                }
                client_connection_tcp_send_auth_handshake(conn);
                conn->handshaked = TRUE;
@@ -427,12 +445,17 @@ client_connection_tcp_input(struct client_connection_tcp *conn)
 
        if (!conn->io_setup) {
                conn->io_setup = TRUE;
-                if (conn->use_multiplex) {
+               if (conn->minor_version >= DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX) {
                         struct ostream *os = conn->output;
                         conn->output = o_stream_create_multiplex(os, SIZE_MAX);
                         o_stream_set_name(conn->output, o_stream_get_name(os));
                         o_stream_set_no_error_handling(conn->output, TRUE);
                         o_stream_unref(&os);
+               }
+               if (conn->minor_version >= DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX &&
+                   conn->minor_version < DOVEADM_PROTOCOL_MIN_VERSION_LOG_PASSTHROUGH) {
+                       /* Log passthrough supported by the client, but it's
+                          not explicitly requested. */
                        client_connection_log_passthrough(conn);
                 }
                doveadm_print_ostream = conn->output;
index 808faf2eaf398bbe48557e3d206488d518de8651..51a902f235915a02e9cbe658023e2f12dc7e4f41 100644 (file)
@@ -683,6 +683,7 @@ int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
                .username = ctx->set->doveadm_username,
                .password = ctx->set->doveadm_password,
                .ssl_flags = proxy_set.ssl_flags,
+               .log_passthrough = TRUE,
        };
 
        server_name = socket_path != NULL ? socket_path :
index 97400c08ca0a9224b2db817f2576e3a01dda94d2..24292c6b70819b7d737a893203c337ccd7c42063 100644 (file)
@@ -81,6 +81,8 @@ void doveadm_client_settings_dup(const struct doveadm_client_settings *src,
                dest_r->ssl_ctx = src->ssl_ctx;
                ssl_iostream_context_ref(dest_r->ssl_ctx);
        }
+
+       dest_r->log_passthrough = src->log_passthrough;
 }
 
 static void doveadm_client_set_print_pending(struct doveadm_client *conn)
@@ -339,6 +341,10 @@ static void doveadm_client_authenticated(struct doveadm_client *conn)
        if (conn->conn.minor_version >= DOVEADM_PROTOCOL_MIN_VERSION_MULTIPLEX)
                doveadm_client_start_multiplex(conn);
 
+       if (conn->set.log_passthrough &&
+           conn->conn.minor_version >= DOVEADM_PROTOCOL_MIN_VERSION_LOG_PASSTHROUGH)
+               o_stream_nsend_str(conn->conn.output, "\t\tOPTION\tlog-passthrough\n");
+
        if (conn->delayed_cmd != NULL) {
                o_stream_nsend_str(conn->conn.output, conn->delayed_cmd);
                conn->delayed_cmd = NULL;
index 7d21282ff3c2c4dace5ca8a6595ef21d8967fc0e..367a53ddbb42322c91c2009be1fa192896d6826f 100644 (file)
@@ -44,6 +44,9 @@ struct doveadm_client_settings {
        struct ssl_iostream_settings ssl_set;
        /* SSL context, or NULL to create a new one. */
        struct ssl_iostream_context *ssl_ctx;
+
+       /* Enable receiving logs from the server */
+       bool log_passthrough;
 };
 
 /* Duplicate doveadm client settings. Note that the ssl_ctx is referenced by
index d2b45790799a3119adae0bc954ed44342ac76a8a..207f68281bf470d1b86b44ccacf815d5248ee8b8 100644 (file)
@@ -10,6 +10,7 @@
 #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_EX_NOTFOUND EX_NOHOST
 #define DOVEADM_EX_NOTPOSSIBLE EX_DATAERR