]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-login: Keep connection in server's linked list until it's fully freed
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 24 Mar 2023 02:02:28 +0000 (04:02 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Sun, 14 May 2023 17:52:36 +0000 (17:52 +0000)
Otherwise the connection isn't accessible from any global variables.

src/lib-master/master-login.c

index e25ce35a79a7704866a8823680a77d3e652fcafa..b5d76ff210215341e24114131681f7890c9cdaa6 100644 (file)
@@ -87,6 +87,7 @@ master_login_init(struct master_service *service,
 void master_login_deinit(struct master_login **_login)
 {
        struct master_login *login = *_login;
+       struct master_login_connection *conn, *next;
 
        *_login = NULL;
 
@@ -94,11 +95,16 @@ void master_login_deinit(struct master_login **_login)
        login->service->login = NULL;
 
        master_login_auth_deinit(&login->auth);
-       while (login->conns != NULL) {
-               struct master_login_connection *conn = login->conns;
-
-               master_login_conn_close(conn);
-               master_login_conn_unref(&conn);
+       for (conn = login->conns; conn != NULL; conn = next) {
+               next = conn->next;
+               if (!master_login_conn_is_closed(conn)) {
+                       master_login_conn_close(conn);
+                       master_login_conn_unref(&conn);
+               } else {
+                       /* FIXME: auth request or post-login script is still
+                          running - we don't currently support aborting them */
+                       i_assert(conn->clients != NULL);
+               }
        }
        i_free(login->postlogin_socket_path);
        i_free(login);
@@ -526,8 +532,6 @@ static void master_login_conn_close(struct master_login_connection *conn)
        if (master_login_conn_is_closed(conn))
                return;
 
-       DLLIST_REMOVE(&conn->login->conns, conn);
-
        io_remove(&conn->io);
        o_stream_close(conn->output);
        if (close(conn->fd) < 0)
@@ -549,6 +553,8 @@ static void master_login_conn_unref(struct master_login_connection **_conn)
        master_login_conn_close(conn);
        o_stream_unref(&conn->output);
 
+       DLLIST_REMOVE(&conn->login->conns, conn);
+
        if (!conn->login_success)
                master_service_client_connection_destroyed(conn->login->service);
        i_free(conn);