1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-07 01:58:28 +03:00

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)
This commit is contained in:
Ralph Boehme 2018-08-29 17:19:29 +02:00 committed by Stefan Metzmacher
parent d36fbe95e5
commit 9fe8691cda
2 changed files with 23 additions and 24 deletions

View File

@ -1 +0,0 @@
^samba3.blackbox.durable_v2_delay.durable_v2_delay\(simpleserver:local\)

View File

@ -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;
}