From c50e7a15f9a7f2c5821b5ee468f9ade6eaa0ed55 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 May 2008 07:28:29 +1000 Subject: don't emulate broken SMB2 locking behaviour from windows --- source/ntvfs/posix/pvfs_lock.c | 14 ++------- source/torture/smb2/lock.c | 70 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/source/ntvfs/posix/pvfs_lock.c b/source/ntvfs/posix/pvfs_lock.c index baa92880f13..822b28246ad 100644 --- a/source/ntvfs/posix/pvfs_lock.c +++ b/source/ntvfs/posix/pvfs_lock.c @@ -68,13 +68,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, int i, NTSTATUS status) { - /* in SMB2 mode we also try to unlock failing lock */ - if (req->ctx->protocol != PROTOCOL_SMB2) { - i--; - } - /* undo the locks we just did */ - for (;i>=0;i--) { + for (i--;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, @@ -390,12 +385,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, DLIST_ADD(f->pending_list, pending); return NT_STATUS_OK; } - /* in SMB2 mode we also try to unlock failing lock */ - if (req->ctx->protocol != PROTOCOL_SMB2) { - i--; - } + /* undo the locks we just did */ - for (;i>=0;i--) { + for (i--;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, diff --git a/source/torture/smb2/lock.c b/source/torture/smb2/lock.c index 5a36ac3eaef..35ad8396107 100644 --- a/source/torture/smb2/lock.c +++ b/source/torture/smb2/lock.c @@ -106,7 +106,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree lck.in.reserved = 0x123ab3; status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_OK); + if (torture_setting_bool(torture, "windows", false)) { + CHECK_STATUS(status, NT_STATUS_OK); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } CHECK_VALUE(lck.out.reserved, 0); lck.in.reserved = 0x123ab4; @@ -115,7 +119,11 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree lck.in.reserved = 0x123ab5; status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_OK); + if (torture_setting_bool(torture, "windows", false)) { + CHECK_STATUS(status, NT_STATUS_OK); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } CHECK_VALUE(lck.out.reserved, 0); lck.in.lock_count = 0x0001; @@ -133,14 +141,22 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_OK); + if (torture_setting_bool(torture, "windows", false)) { + CHECK_STATUS(status, NT_STATUS_OK); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } CHECK_VALUE(lck.out.reserved, 0); status = smb2_lock(tree, &lck); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb2_lock(tree, &lck); - CHECK_STATUS(status, NT_STATUS_OK); + if (torture_setting_bool(torture, "windows", false)) { + CHECK_STATUS(status, NT_STATUS_OK); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } CHECK_VALUE(lck.out.reserved, 0); el[0].flags = 0x00000000; @@ -473,6 +489,51 @@ static bool test_lock_rw_exclusiv(struct torture_context *torture, struct smb2_t return test_lock_read_write(torture, tree, &s); } + +static bool test_lock_auto_unlock(struct torture_context *torture, struct smb2_tree *tree) +{ + bool ret = true; + NTSTATUS status; + struct smb2_handle h; + uint8_t buf[200]; + struct smb2_lock lck; + struct smb2_lock_element el[2]; + + ZERO_STRUCT(buf); + + status = torture_smb2_testfile(tree, "autounlock.txt", &h); + CHECK_STATUS(status, NT_STATUS_OK); + + status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf)); + CHECK_STATUS(status, NT_STATUS_OK); + + ZERO_STRUCT(lck); + lck.in.locks = el; + lck.in.lock_count = 0x0001; + lck.in.file.handle = h; + el[0].offset = 0; + el[0].length = 1; + el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY; + status = smb2_lock(tree, &lck); + CHECK_STATUS(status, NT_STATUS_OK); + + status = smb2_lock(tree, &lck); + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + + status = smb2_lock(tree, &lck); + if (torture_setting_bool(torture, "windows", false)) { + CHECK_STATUS(status, NT_STATUS_OK); + } else { + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + } + + + +done: + return ret; +} + + /* basic testing of SMB2 locking */ struct torture_suite *torture_smb2_lock_init(void) @@ -483,6 +544,7 @@ struct torture_suite *torture_smb2_lock_init(void) torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none); torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared); torture_suite_add_1smb2_test(suite, "RW-EXCLUSIV", test_lock_rw_exclusiv); + torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK", test_lock_auto_unlock); suite->description = talloc_strdup(suite, "SMB2-LOCK tests"); -- cgit v1.2.1