From: Timo Sirainen Date: Tue, 31 Oct 2017 22:49:53 +0000 (+0200) Subject: login-common: Split client_create() to client_alloc() and client_init() X-Git-Tag: 2.3.0.rc1~523 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66ea9eaaa2d7531b3be8f633937628c94d907031;p=thirdparty%2Fdovecot%2Fcore.git login-common: Split client_create() to client_alloc() and client_init() client_unref() can be used to free an allocated client that hasn't been fully created. --- diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index f46096db1e..7dbd24ef80 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -152,11 +152,10 @@ static bool client_is_trusted(struct client *client) } struct client * -client_create(int fd, bool ssl, pool_t pool, - const struct master_service_connection *conn, - const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set, - void **other_sets) +client_alloc(int fd, bool ssl, pool_t pool, + const struct master_service_connection *conn, + const struct login_settings *set, + const struct master_service_ssl_settings *ssl_set) { struct client *client; @@ -201,7 +200,11 @@ client_create(int fd, bool ssl, pool_t pool, net_ip_compare(&conn->real_remote_ip, &conn->real_local_ip); } client->proxy_ttl = LOGIN_PROXY_TTL; + return client; +} +void client_init(struct client *client, void **other_sets) +{ if (last_client == NULL) last_client = client; DLLIST_PREPEND(&clients, client); @@ -214,6 +217,7 @@ client_create(int fd, bool ssl, pool_t pool, hook_login_client_allocated(client); client->v.create(client, other_sets); + client->create_finished = TRUE; if (auth_client_is_connected(auth_client)) client_notify_auth_ready(client); @@ -221,11 +225,12 @@ client_create(int fd, bool ssl, pool_t pool, client_set_auth_waiting(client); login_refresh_proctitle(); - return client; } void client_destroy(struct client *client, const char *reason) { + i_assert(client->create_finished); + if (client->destroyed) return; client->destroyed = TRUE; @@ -324,6 +329,12 @@ bool client_unref(struct client **_client) if (--client->refcount > 0) return TRUE; + if (!client->create_finished) { + pool_unref(&client->preproxy_pool); + pool_unref(&client->pool); + return FALSE; + } + i_assert(client->destroyed); i_assert(client->login_proxy == NULL); diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 6a84c8f09b..1d7de7f0a6 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -196,6 +196,7 @@ struct client { /* director_username_hash cached, if non-zero */ unsigned int director_username_hash_cache; + bool create_finished:1; bool destroyed:1; bool input_blocked:1; bool login_success:1; @@ -237,11 +238,11 @@ void login_client_hooks_add(struct module *module, void login_client_hooks_remove(const struct login_client_hooks *hooks); struct client * -client_create(int fd, bool ssl, pool_t pool, - const struct master_service_connection *conn, - const struct login_settings *set, - const struct master_service_ssl_settings *ssl_set, - void **other_sets); +client_alloc(int fd, bool ssl, pool_t pool, + const struct master_service_connection *conn, + const struct login_settings *set, + const struct master_service_ssl_settings *ssl_set); +void client_init(struct client *client, void **other_sets); void client_destroy(struct client *client, const char *reason); void client_destroy_success(struct client *client, const char *reason); diff --git a/src/login-common/main.c b/src/login-common/main.c index 670e0dc852..e69f2608d2 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -128,8 +128,9 @@ client_connected_finish(const struct master_service_connection *conn) &conn->remote_ip, NULL, &ssl_set, &other_sets); if (!ssl_connections && !conn->ssl) { - (void)client_create(conn->fd, FALSE, pool, conn, - set, ssl_set, other_sets); + client = client_alloc(conn->fd, FALSE, pool, conn, + set, ssl_set); + client_init(client, other_sets); } else { fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, pool, set, ssl_set, &proxy); @@ -140,8 +141,9 @@ client_connected_finish(const struct master_service_connection *conn) return; } - client = client_create(fd_ssl, TRUE, pool, conn, - set, ssl_set, other_sets); + client = client_alloc(fd_ssl, TRUE, pool, conn, + set, ssl_set); + client_init(client, other_sets); client->ssl_proxy = proxy; ssl_proxy_set_client(proxy, client); ssl_proxy_start(proxy);