Mercurial > dovecot > core-2.2
changeset 15593:e0d4d8f9d097
replicator: Send only one sync command to doveadm-server per connection.
This fixes setuid()/setgid() problems when multiple UIDs are used.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 08 Jan 2013 07:42:38 +0200 |
parents | 0949ddc3a892 |
children | 5bb80a6491eb |
files | src/replication/replicator/doveadm-connection.c |
diffstat | 1 files changed, 16 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/replication/replicator/doveadm-connection.c Tue Jan 08 06:41:56 2013 +0200 +++ b/src/replication/replicator/doveadm-connection.c Tue Jan 08 07:42:38 2013 +0200 @@ -29,6 +29,7 @@ time_t last_connect_failure; unsigned int handshaked:1; unsigned int end_of_print:1; + unsigned int cmd_sent:1; }; struct doveadm_connection *doveadm_connection_init(const char *path) @@ -55,7 +56,7 @@ callback(reply, context); } -static void doveadm_disconnect(struct doveadm_connection *conn) +static void doveadm_close(struct doveadm_connection *conn) { if (conn->fd == -1) return; @@ -66,7 +67,13 @@ if (close(conn->fd) < 0) i_error("close(doveadm) failed: %m"); conn->fd = -1; + conn->end_of_print = FALSE; + conn->cmd_sent = FALSE; +} +static void doveadm_disconnect(struct doveadm_connection *conn) +{ + doveadm_close(conn); if (conn->callback != NULL) doveadm_callback(conn, DOVEADM_REPLY_FAIL); } @@ -102,6 +109,9 @@ conn->end_of_print = TRUE; return 0; } + line = t_strdup(line); + doveadm_close(conn); + if (line[0] == '+') doveadm_callback(conn, DOVEADM_REPLY_OK); else if (line[0] == '-') { @@ -113,9 +123,9 @@ i_error("%s: Invalid input: %s", conn->path, line); return -1; } - conn->end_of_print = FALSE; /* FIXME: disconnect after each request for now. - doveadm server's getopt() handling seems to break otherwise */ + doveadm server's getopt() handling seems to break otherwise. + also with multiple UIDs doveadm-server fails because setid() fails */ return -1; } @@ -158,7 +168,7 @@ static void doveadm_fail_timeout(struct doveadm_connection *conn) { - doveadm_callback(conn, DOVEADM_REPLY_FAIL); + doveadm_disconnect(conn); } void doveadm_connection_sync(struct doveadm_connection *conn, @@ -170,6 +180,7 @@ i_assert(callback != NULL); i_assert(!doveadm_connection_is_busy(conn)); + conn->cmd_sent = TRUE; conn->callback = callback; conn->context = context; @@ -192,5 +203,5 @@ bool doveadm_connection_is_busy(struct doveadm_connection *conn) { - return conn->callback != NULL; + return conn->cmd_sent; }