smbd: SMB2 Compound related chain handling when generation of FileId has failed
authorRalph Boehme <slow@samba.org>
Thu, 8 Apr 2021 10:17:22 +0000 (12:17 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 8 Apr 2021 17:30:50 +0000 (17:30 +0000)
Issue:
We have a scenario where an application sends a Compound Related chain
consisting of:
SMB2_CREATE
SMB2_IOCTL
SMB2_SET_INFO
SMB2_CLOSE

SMB2_CREATE failed with NT_STATUS_ACCESS_DENIED and subsequent
requests all fail. In Samba they return NT_STATUS_FILE_CLOSED.

When I tried the same against a Win2k12 server, I noticed that all the
failed requests of the chain would return NT_STATUS_ACCESS_DENIED.

I believe this behaviour is also mentioned in the [MS-SMB2] Specs
3.3.5.2.7.2: Handling Compounded Related Requests

"When the current operation requires a FileId and the previous
operation either contains or generates a FileId, if the previous
operation fails with an error, the server SHOULD<223> fail the current
operation with the same error code returned by the previous
operation."

Fix:
Save NTATUS of a failed Create request. When we process subsequent
requests of the chain we check if the previous Create has failed. In
case of a Create failure we returned the saved NTSTATUS.

Signed-off-by: Anubhav Rakshit <anubhav.rakshit@gmail.com>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Apr  8 17:30:50 UTC 2021 on sn-devel-184

selftest/knownfail.d/samba3.smb2.compound [deleted file]
source3/smbd/globals.h
source3/smbd/smb2_create.c
source3/smbd/smb2_server.c

diff --git a/selftest/knownfail.d/samba3.smb2.compound b/selftest/knownfail.d/samba3.smb2.compound
deleted file mode 100644 (file)
index cf4f5fa..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-^samba3.smb2.compound.related4
-^samba3.smb2.compound aio.related4
-^samba3.smb2.compound.related7
-^samba3.smb2.compound aio.related7
-^samba3.smb2.compound.related8
-^samba3.smb2.compound aio.related8
index f49096cba8a31acfbb8bd8fbc4fe17f1fa510195..a227fdd903a4f56bb79faa76a8f74e161537a7c4 100644 (file)
@@ -741,6 +741,7 @@ struct smbd_smb2_request {
        bool do_encryption;
        struct tevent_timer *async_te;
        bool compound_related;
+       NTSTATUS compound_create_err;
 
        /*
         * Give the implementation of an SMB2 req a way to tell the SMB2 request
index dc6bd72591e3a12991b38e5ac218c5bcbf665314..ef844fb93465009860a47b36355d063964e44312 100644 (file)
@@ -331,6 +331,9 @@ static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
                                       &out_file_id_volatile,
                                       &out_context_blobs);
        if (!NT_STATUS_IS_OK(status)) {
+               if (smbd_smb2_is_compound(smb2req)) {
+                       smb2req->compound_create_err = status;
+               }
                error = smbd_smb2_request_error(smb2req, status);
                if (!NT_STATUS_IS_OK(error)) {
                        smbd_server_connection_terminate(smb2req->xconn,
index d5b0df33dde71ac78127148541041e5b4049ebb7..9bd5bf79b30b603a8beb3c0679a4221fa5e7183c 100644 (file)
@@ -3262,6 +3262,12 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 
                fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
                if (fsp == NULL) {
+                       if (req->compound_related &&
+                           !NT_STATUS_IS_OK(req->compound_create_err))
+                       {
+                               return smbd_smb2_request_error(req,
+                                               req->compound_create_err);
+                       }
                        if (!call->allow_invalid_fileid) {
                                return smbd_smb2_request_error(req,
                                                NT_STATUS_FILE_CLOSED);