diff options
author | Ralph Boehme <slow@samba.org> | 2018-08-29 17:19:29 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2018-09-05 13:31:44 +0200 |
commit | 9fe8691cdae495a6b08bd5e525bd6b58e0ac93bc (patch) | |
tree | 7e0d4b435b2b634111947ef0ed3cad5a4fbd3ece /source3 | |
parent | d36fbe95e57fe8a044703e7eee1d7401d1baa6e0 (diff) | |
download | samba-9fe8691cdae495a6b08bd5e525bd6b58e0ac93bc.tar.gz |
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
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 8f6edcc1645e0ed35eaec914bd0b672500ce986c)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/smbXsrv_session.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c index 9e1fb6977b4..d0622f3919a 100644 --- a/source3/smbd/smbXsrv_session.c +++ b/source3/smbd/smbXsrv_session.c @@ -1659,6 +1659,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) { @@ -1718,29 +1741,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; } |