don't emulate broken SMB2 locking behaviour from windows
authorAndrew Tridgell <tridge@samba.org>
Thu, 29 May 2008 21:28:29 +0000 (07:28 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 29 May 2008 21:28:29 +0000 (07:28 +1000)
(This used to be commit c50e7a15f9a7f2c5821b5ee468f9ade6eaa0ed55)

source4/ntvfs/posix/pvfs_lock.c
source4/torture/smb2/lock.c

index baa92880f13d570e8c6cb6b33082a67e05a070fc..822b28246ad6f5a7a36cb8c490b78db7f0ccd26a 100644 (file)
@@ -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,
index 5a36ac3eaef2ca8a631842e08a2485e87a39b4c3..35ad8396107bffde8a263c076713576650c57b3a 100644 (file)
@@ -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");