From 466815854d07bb43749b0290b9b1853ce606c8f1 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 29 Aug 2018 17:19:29 +0200 Subject: [PATCH] s3:smbd: let session logoff close files and tcons before deleting the session This avoids a race in durable handle reconnects if the reconnect comes in while the old session is still in the tear-down phase. The new session is supposed to rendezvous with and wait for destruction of the old session, which is internally implemented with dbwrap_watch_send() on the old session record. If the old session deletes the session record before calling file_close_user() which marks all file handles as disconnected, the durable handle reconnect in the new session will fail as the records are not yet marked as disconnected which is a prerequisite. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13549 --- source3/smbd/smbXsrv_session.c | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c index 548d3b15006..5451dddb85b 100644 --- a/source3/smbd/smbXsrv_session.c +++ b/source3/smbd/smbXsrv_session.c @@ -1670,6 +1670,29 @@ NTSTATUS smbXsrv_session_logoff(struct smbXsrv_session *session) session->client = NULL; session->status = NT_STATUS_USER_SESSION_DELETED; + if (session->compat) { + file_close_user(sconn, session->compat->vuid); + } + + if (session->tcon_table != NULL) { + /* + * Note: We only have a tcon_table for SMB2. + */ + status = smb2srv_tcon_disconnect_all(session); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("smbXsrv_session_logoff(0x%08x): " + "smb2srv_tcon_disconnect_all() failed: %s\n", + session->global->session_global_id, + nt_errstr(status))); + error = status; + } + } + + if (session->compat) { + invalidate_vuid(sconn, session->compat->vuid); + session->compat = NULL; + } + global_rec = session->global->db_rec; session->global->db_rec = NULL; if (global_rec == NULL) { @@ -1729,29 +1752,6 @@ NTSTATUS smbXsrv_session_logoff(struct smbXsrv_session *session) } session->db_rec = NULL; - if (session->compat) { - file_close_user(sconn, session->compat->vuid); - } - - if (session->tcon_table != NULL) { - /* - * Note: We only have a tcon_table for SMB2. - */ - status = smb2srv_tcon_disconnect_all(session); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("smbXsrv_session_logoff(0x%08x): " - "smb2srv_tcon_disconnect_all() failed: %s\n", - session->global->session_global_id, - nt_errstr(status))); - error = status; - } - } - - if (session->compat) { - invalidate_vuid(sconn, session->compat->vuid); - session->compat = NULL; - } - return error; } -- 2.13.6