diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c index 2378c0c15ca..540746f9f87 100644 --- a/source3/smbd/server_exit.c +++ b/source3/smbd/server_exit.c @@ -110,13 +110,11 @@ static void exit_server_common(enum server_exit_reason how, /* * Here we typically have just one connection */ - for (; xconn != NULL; xconn = xconn_next) { - xconn_next = xconn->next; - DLIST_REMOVE(client->connections, xconn); - + for (; xconn != NULL; xconn = xconn->next) { /* * This is typically the disconnect for the only * (or with multi-channel last) connection of the client + * First mark the connections closed. */ if (NT_STATUS_IS_OK(xconn->transport.status)) { switch (how) { @@ -128,8 +126,6 @@ static void exit_server_common(enum server_exit_reason how, break; } } - - TALLOC_FREE(xconn); DO_PROFILE_INC(disconnect); } @@ -168,6 +164,18 @@ static void exit_server_common(enum server_exit_reason how, "smbXsrv_session_logoff_all() failed (%s) - " "triggering cleanup\n", nt_errstr(status))); } + + /* + * Now actually free the connections, we've finished + * sending any pending replies. + */ + for (xconn = client->connections; + xconn != NULL; + xconn = xconn_next) { + xconn_next = xconn->next; + DLIST_REMOVE(client->connections, xconn); + TALLOC_FREE(xconn); + } } change_to_root_user();