summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Ross <gwr@nexenta.com>2020-04-26 13:32:04 -0400
committerGordon Ross <gordon.ross@tintri.com>2020-07-24 18:01:05 -0400
commitdde7ba523f4198e0f5b40039179233749a87f105 (patch)
treecb2b9862be56be912d0b65e04f48ccd0900eb70a
parent9e2a4eaf6fee551c027291466c695e4414145b39 (diff)
downloadillumos-joyent-dde7ba523f4198e0f5b40039179233749a87f105.tar.gz
12932 Some SMB2 oplock break cases fail in the Windows Protocol Test Suite
Portions contributed by: Andrew Stormont <astormont@racktopsystems.com> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_oplock.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_oplock.c b/usr/src/uts/common/fs/smbsrv/smb2_oplock.c
index 84bd8ccafb..f3f96c2b21 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_oplock.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_oplock.c
@@ -10,7 +10,8 @@
*/
/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
+ * Copyright 2019 RackTop Systems.
*/
/*
@@ -96,13 +97,35 @@ smb2_oplock_break_ack(smb_request_t *sr)
NewLevel = OPLOCK_LEVEL_BATCH;
break;
case SMB2_OPLOCK_LEVEL_LEASE: /* 0xFF */
- default:
NewLevel = OPLOCK_LEVEL_NONE;
break;
+ default:
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto errout;
}
ofile = sr->fid_ofile;
+ if (ofile->f_oplock.og_breaking == 0) {
+ /*
+ * This is an unsolicited Ack. (There is no
+ * outstanding oplock break in progress now.)
+ * There are WPTS tests that care which error
+ * is returned. See [MS-SMB2] 3.3.5.22.1
+ */
+ if (smbOplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto errout;
+ }
+ if (NewLevel >= (ofile->f_oplock.og_state &
+ OPLOCK_LEVEL_TYPE_MASK)) {
+ status = NT_STATUS_INVALID_OPLOCK_PROTOCOL;
+ goto errout;
+ }
+ status = NT_STATUS_INVALID_DEVICE_STATE;
+ goto errout;
+ }
ofile->f_oplock.og_breaking = 0;
+
status = smb_oplock_ack_break(sr, ofile, &NewLevel);
if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
status = smb2sr_go_async(sr);