dovecot-2.0: lib-master API changed to avoid accidentally leakin...

dovecot at dovecot.org dovecot at dovecot.org
Thu May 27 14:16:40 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/b8d3c96e61a7
changeset: 11388:b8d3c96e61a7
user:      Timo Sirainen <tss at iki.fi>
date:      Thu May 27 12:16:36 2010 +0100
description:
lib-master API changed to avoid accidentally leaking client connections.
This change also fixes many such leaks.

diffstat:

 src/anvil/main.c                |   3 ++-
 src/auth/main.c                 |   7 ++++---
 src/config/main.c               |   3 ++-
 src/dict/main.c                 |   3 ++-
 src/director/main.c             |  15 ++++++++-------
 src/dns/dns-client.c            |   5 +++--
 src/dsync/dsync.c               |   2 +-
 src/imap/main.c                 |   4 ++--
 src/lib-master/master-service.c |  11 +++++++++++
 src/lib-master/master-service.h |   6 +++++-
 src/lmtp/main.c                 |   3 ++-
 src/log/main.c                  |   3 ++-
 src/login-common/main.c         |   4 +++-
 src/pop3/main.c                 |   4 ++--
 src/ssl-params/main.c           |   3 ++-
 src/util/script.c               |   4 +---
 src/util/tcpwrap.c              |   3 ++-
 17 files changed, 54 insertions(+), 29 deletions(-)

diffs (truncated from 349 to 300 lines):

diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/anvil/main.c
--- a/src/anvil/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/anvil/main.c	Thu May 27 12:16:36 2010 +0100
@@ -18,10 +18,11 @@
 struct penalty *penalty;
 static struct io *log_fdpass_io;
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	bool master = conn->listen_fd == MASTER_LISTEN_FD_FIRST;
 
+	master_service_client_connection_accept(conn);
 	anvil_connection_create(conn->fd, master, conn->fifo);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/auth/main.c
--- a/src/auth/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/auth/main.c	Thu May 27 12:16:36 2010 +0100
@@ -182,18 +182,18 @@
 	pool_unref(&auth_set_pool);
 }
 
-static void worker_connected(const struct master_service_connection *conn)
+static void worker_connected(struct master_service_connection *conn)
 {
 	if (auth_worker_client != NULL) {
 		i_error("Auth workers can handle only a single client");
-		(void)close(conn->fd);
 		return;
 	}
 
+	master_service_client_connection_accept(conn);
 	(void)auth_worker_client_create(auth_find_service(NULL), conn->fd);
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	enum auth_socket_type *type;
 	const char *path, *name, *suffix;
@@ -245,6 +245,7 @@
 	default:
 		i_unreached();
 	}
+	master_service_client_connection_accept(conn);
 }
 
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/config/main.c
--- a/src/config/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/config/main.c	Thu May 27 12:16:36 2010 +0100
@@ -8,8 +8,9 @@
 #include "config-parser.h"
 #include "config-request.h"
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
+	master_service_client_connection_accept(conn);
 	config_connection_create(conn->fd);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/dict/main.c
--- a/src/dict/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/dict/main.c	Thu May 27 12:16:36 2010 +0100
@@ -20,8 +20,9 @@
 	/* hope that other processes relying on us will die first. */
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
+	master_service_client_connection_accept(conn);
 	dict_connection_create(conn->fd);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/director/main.c
--- a/src/director/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/director/main.c	Thu May 27 12:16:36 2010 +0100
@@ -37,7 +37,7 @@
 	return 0;
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	struct auth_connection *auth;
 	const char *path, *name;
@@ -47,9 +47,9 @@
 	if (conn->fifo) {
 		if (notify_conn != NULL) {
 			i_error("Received another proxy-notify connection");
-			(void)close(conn->fd);
 			return;
 		}
+		master_service_client_connection_accept(conn);
 		notify_conn = notify_connection_init(director, conn->fd);
 		return;
 	}
@@ -57,8 +57,8 @@
 	if (net_getpeername(conn->fd, &ip, &port) == 0 &&
 	    (IPADDR_IS_V4(&ip) || IPADDR_IS_V6(&ip))) {
 		/* TCP/IP connection - this is another director */
-		if (director_client_connected(conn->fd, &ip) < 0)
-			(void)close(conn->fd);
+		if (director_client_connected(conn->fd, &ip) == 0)
+			master_service_client_connection_accept(conn);
 		return;
 	}
 
@@ -74,14 +74,15 @@
 	len = strlen(name);
 	if (len > 6 && strcmp(name + len - 6, "-admin") == 0) {
 		/* doveadm connection */
+		master_service_client_connection_accept(conn);
 		(void)doveadm_connection_init(director, conn->fd);
 	} else {
 		/* login connection */
 		auth = auth_connection_init(auth_socket_path);
-		if (auth_connection_connect(auth) == 0)
+		if (auth_connection_connect(auth) == 0) {
+			master_service_client_connection_accept(conn);
 			login_connection_init(director, conn->fd, auth);
-		else {
-			(void)close(conn->fd);
+		} else {
 			auth_connection_deinit(&auth);
 		}
 	}
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/dns/dns-client.c
--- a/src/dns/dns-client.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/dns/dns-client.c	Thu May 27 12:16:36 2010 +0100
@@ -115,13 +115,14 @@
 	master_service_client_connection_destroyed(master_service);
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	if (dns_client != NULL) {
 		i_error("dns-client must be configured with client_limit=1");
-		(void)close(conn->fd);
 		return;
 	}
+
+	master_service_client_connection_accept(conn);
 	dns_client = dns_client_create(conn->fd);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/dsync/dsync.c
--- a/src/dsync/dsync.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/dsync/dsync.c	Thu May 27 12:16:36 2010 +0100
@@ -67,7 +67,7 @@
 }
 
 static void
-dsync_connected(const struct master_service_connection *conn ATTR_UNUSED)
+dsync_connected(struct master_service_connection *conn ATTR_UNUSED)
 {
 	i_fatal("Running as service not supported currently");
 }
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/imap/main.c
--- a/src/imap/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/imap/main.c	Thu May 27 12:16:36 2010 +0100
@@ -276,12 +276,12 @@
 	}
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	if (master_login == NULL) {
 		/* running standalone, we shouldn't even get here */
-		(void)close(conn->fd);
 	} else {
+		master_service_client_connection_accept(conn);
 		master_login_add(master_login, conn->fd);
 	}
 }
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/lib-master/master-service.c	Thu May 27 12:16:36 2010 +0100
@@ -537,6 +537,11 @@
 	}
 }
 
+void master_service_client_connection_accept(struct master_service_connection *conn)
+{
+	conn->accepted = TRUE;
+}
+
 void master_service_client_connection_destroyed(struct master_service *service)
 {
 	/* we can listen again */
@@ -711,6 +716,12 @@
 	master_status_update(service);
 
 	service->callback(&conn);
+
+	if (!conn.accepted) {
+		if (close(conn.fd) < 0)
+			i_error("close(service connection) failed: %m");
+		master_service_client_connection_destroyed(service);
+	}
 }
 
 static void io_listeners_init(struct master_service *service)
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/lib-master/master-service.h
--- a/src/lib-master/master-service.h	Thu May 27 11:36:07 2010 +0100
+++ b/src/lib-master/master-service.h	Thu May 27 12:16:36 2010 +0100
@@ -29,10 +29,12 @@
 
 	unsigned int fifo:1;
 	unsigned int ssl:1;
+
+	unsigned int accepted:1;
 };
 
 typedef void
-master_service_connection_callback_t(const struct master_service_connection *conn);
+master_service_connection_callback_t(struct master_service_connection *conn);
 
 extern struct master_service *master_service;
 
@@ -109,6 +111,8 @@
 
 /* Send command to anvil process, if we have fd to it. */
 void master_service_anvil_send(struct master_service *service, const char *cmd);
+/* Call to accept the client connection. Otherwise the connection is closed. */
+void master_service_client_connection_accept(struct master_service_connection *conn);
 /* Call whenever a client connection is destroyed. */
 void master_service_client_connection_destroyed(struct master_service *service);
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/lmtp/main.c
--- a/src/lmtp/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/lmtp/main.c	Thu May 27 12:16:36 2010 +0100
@@ -28,8 +28,9 @@
 const char *dns_client_socket_path;
 struct mail_storage_service_ctx *storage_service;
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
+	master_service_client_connection_accept(conn);
 	(void)client_create(conn->fd, conn->fd, conn);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/log/main.c
--- a/src/log/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/log/main.c	Thu May 27 12:16:36 2010 +0100
@@ -28,8 +28,9 @@
 	log_connections_deinit();
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
+	master_service_client_connection_accept(conn);
 	log_connection_create(conn->fd, conn->listen_fd);
 }
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/login-common/main.c
--- a/src/login-common/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/login-common/main.c	Thu May 27 12:16:36 2010 +0100
@@ -206,12 +206,14 @@
 	}
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	const char *access_sockets =
 		global_login_settings->login_access_sockets;
 	struct login_access_lookup *lookup;
 
+	master_service_client_connection_accept(conn);
+
 	/* make sure we're connected (or attempting to connect) to auth */
 	auth_client_connect(auth_client);
 
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/pop3/main.c
--- a/src/pop3/main.c	Thu May 27 11:36:07 2010 +0100
+++ b/src/pop3/main.c	Thu May 27 12:16:36 2010 +0100
@@ -172,12 +172,12 @@
 	}
 }
 
-static void client_connected(const struct master_service_connection *conn)
+static void client_connected(struct master_service_connection *conn)
 {
 	if (master_login == NULL) {
 		/* running standalone, we shouldn't even get here */
-		(void)close(conn->fd);
 	} else {
+		master_service_client_connection_accept(conn);
 		master_login_add(master_login, conn->fd);
 	}
 }
diff -r 7b8bd33c96f9 -r b8d3c96e61a7 src/ssl-params/main.c


More information about the dovecot-cvs mailing list