From: Ralph Boehme Date: Thu, 8 Apr 2021 10:17:22 +0000 (+0200) Subject: smbd: SMB2 Compound related chain handling when generation of FileId has failed X-Git-Tag: tevent-0.11.0~1256 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fc6eba619eb91925513d0c62263db894faffd8d6;p=thirdparty%2Fsamba.git smbd: SMB2 Compound related chain handling when generation of FileId has failed 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 Reviewed-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Apr 8 17:30:50 UTC 2021 on sn-devel-184 --- diff --git a/selftest/knownfail.d/samba3.smb2.compound b/selftest/knownfail.d/samba3.smb2.compound deleted file mode 100644 index cf4f5fa401d..00000000000 --- a/selftest/knownfail.d/samba3.smb2.compound +++ /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 diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index f49096cba8a..a227fdd903a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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 diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index dc6bd72591e..ef844fb9346 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -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, diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index d5b0df33dde..9bd5bf79b30 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -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);