From: Timo Sirainen Date: Fri, 30 Jul 2021 14:23:55 +0000 (+0300) Subject: lib-doveadm, doveadm: Change log passthrough to be optional X-Git-Tag: 2.4.0~4750 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cc4dfb06d4f15a68271602635bf5948267ac8f03;p=thirdparty%2Fdovecot%2Fcore.git lib-doveadm, doveadm: Change log passthrough to be optional --- diff --git a/src/doveadm/client-connection-tcp.c b/src/doveadm/client-connection-tcp.c index 091ea89eef..dc1bce0496 100644 --- a/src/doveadm/client-connection-tcp.c +++ b/src/doveadm/client-connection-tcp.c @@ -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; diff --git a/src/doveadm/doveadm-mail-server.c b/src/doveadm/doveadm-mail-server.c index 808faf2eaf..51a902f235 100644 --- a/src/doveadm/doveadm-mail-server.c +++ b/src/doveadm/doveadm-mail-server.c @@ -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 : diff --git a/src/lib-doveadm/doveadm-client.c b/src/lib-doveadm/doveadm-client.c index 97400c08ca..24292c6b70 100644 --- a/src/lib-doveadm/doveadm-client.c +++ b/src/lib-doveadm/doveadm-client.c @@ -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; diff --git a/src/lib-doveadm/doveadm-client.h b/src/lib-doveadm/doveadm-client.h index 7d21282ff3..367a53ddbb 100644 --- a/src/lib-doveadm/doveadm-client.h +++ b/src/lib-doveadm/doveadm-client.h @@ -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 diff --git a/src/lib-doveadm/doveadm-protocol.h b/src/lib-doveadm/doveadm-protocol.h index d2b4579079..207f68281b 100644 --- a/src/lib-doveadm/doveadm-protocol.h +++ b/src/lib-doveadm/doveadm-protocol.h @@ -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