summaryrefslogtreecommitdiff
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:35:27 +0200
commitb7c659a4499dc7b62423ce930f7ce2128eded90e (patch)
tree29e2cfe15c0269c52651ca81510d2f36adc45d03
parent51253045e827c14b14d527d1c48d037d8002588f (diff)
downloadsamba-b7c659a4499dc7b62423ce930f7ce2128eded90e.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)
-rw-r--r--selftest/knownfail.d/samba3.blackbox1
-rw-r--r--source3/smbd/smbXsrv_session.c46
2 files changed, 23 insertions, 24 deletions
diff --git a/selftest/knownfail.d/samba3.blackbox b/selftest/knownfail.d/samba3.blackbox
deleted file mode 100644
index b03a1ac09e2..00000000000
--- a/selftest/knownfail.d/samba3.blackbox
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.blackbox.durable_v2_delay.durable_v2_delay\(simpleserver:local\)
diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c
index f84d2a94ce1..7fe385c2047 100644
--- a/source3/smbd/smbXsrv_session.c
+++ b/source3/smbd/smbXsrv_session.c
@@ -1651,6 +1651,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) {
@@ -1710,29 +1733,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;
}