summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2018-08-29 17:19:29 +0200
committerStefan Metzmacher <metze@samba.org>2018-09-05 13:31:44 +0200
commit9fe8691cdae495a6b08bd5e525bd6b58e0ac93bc (patch)
tree7e0d4b435b2b634111947ef0ed3cad5a4fbd3ece /source3
parentd36fbe95e57fe8a044703e7eee1d7401d1baa6e0 (diff)
downloadsamba-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.c46
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;
}