summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/files.c8
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/smb2_glue.c20
3 files changed, 31 insertions, 0 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 43956e3903..7ad5ce3ae6 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -503,6 +503,14 @@ void file_free(struct smb_request *req, files_struct *fsp)
req->chain_fsp = NULL;
}
+ /*
+ * Clear all possible chained fsp
+ * pointers in the SMB2 request queue.
+ */
+ if (req != NULL && req->smb2req) {
+ remove_smb2_chained_fsp(fsp);
+ }
+
/* Closing a file can invalidate the positive cache. */
if (fsp == fsp_fi_cache.fsp) {
ZERO_STRUCT(fsp_fi_cache);
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 9df255475e..3533d60e7a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -277,6 +277,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req);
NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req);
struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
+void remove_smb2_chained_fsp(files_struct *fsp);
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
@@ -353,6 +354,8 @@ struct smbd_smb2_request {
bool async;
bool cancelled;
+ /* fake smb1 request. */
+ struct smb_request *smb1req;
struct files_struct *compat_chain_fsp;
NTSTATUS next_status;
diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c
index d6252ef349..8b595affe0 100644
--- a/source3/smbd/smb2_glue.c
+++ b/source3/smbd/smb2_glue.c
@@ -49,6 +49,26 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
smbreq->mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
smbreq->chain_fsp = req->compat_chain_fsp;
smbreq->smb2req = req;
+ req->smb1req = smbreq;
return smbreq;
}
+
+/*********************************************************
+ Called from file_free() to remove any chained fsp pointers.
+*********************************************************/
+
+void remove_smb2_chained_fsp(files_struct *fsp)
+{
+ struct smbd_server_connection *sconn = smbd_server_conn;
+ struct smbd_smb2_request *smb2req;
+
+ for (smb2req = sconn->smb2.requests; smb2req; smb2req = smb2req->next) {
+ if (smb2req->compat_chain_fsp == fsp) {
+ smb2req->compat_chain_fsp = NULL;
+ }
+ if (smb2req->smb1req && smb2req->smb1req->chain_fsp == fsp) {
+ smb2req->smb1req->chain_fsp = NULL;
+ }
+ }
+}