s4/torture: additional tests for kernel-oplocks
authorRalph Boehme <slow@samba.org>
Thu, 18 May 2017 11:17:38 +0000 (13:17 +0200)
committerVolker Lendecke <vl@samba.org>
Wed, 9 Aug 2017 16:41:06 +0000 (18:41 +0200)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
source4/torture/smb2/oplock.c

index 7c59780dbd2b1ccbe80c40460db33ecb6c420ae9..e0db5ecb50d28b2f14d71a7c7123868f1250a4da 100644 (file)
@@ -4491,6 +4491,189 @@ done:
        return ret;
 }
 
+/**
+ * 1) create testfile with stream
+ * 2) open stream r/w with batch oplock -> batch oplock granted
+ * 3) open stream r/o with batch oplock
+ *
+ * Verify 3) does trigger an oplock break
+ **/
+static bool test_smb2_kernel_oplocks5(struct torture_context *tctx,
+                                     struct smb2_tree *tree)
+{
+       const char *fname = "test_kernel_oplock4.dat";
+       const char *sname = "test_kernel_oplock4.dat:foo";
+       NTSTATUS status;
+       bool ret = true;
+       struct smb2_create create;
+       struct smb2_handle h1 = {{0}}, h2 = {{0}};
+
+       tree->session->transport->oplock.handler = torture_oplock_handler;
+       tree->session->transport->oplock.private_data = tree;
+       ZERO_STRUCT(break_info);
+       smb2_util_unlink(tree, fname);
+
+       /* 1 */
+       status = torture_smb2_testfile(tree, fname, &h1);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "Error creating testfile\n");
+       smb2_util_close(tree, h1);
+       ZERO_STRUCT(h1);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_READ;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = sname;
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h1 = create.out.file.handle;
+       smb2_util_close(tree, h1);
+       ZERO_STRUCT(h1);
+
+       /* 2 */
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = sname;
+       create.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h1 = create.out.file.handle;
+
+       torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_BATCH, ret, done,
+                           "Oplock level is not SMB2_OPLOCK_LEVEL_BATCH\n");
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_READ;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = sname;
+       create.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h2 = create.out.file.handle;
+
+       torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_NONE, ret, done,
+                           "Oplock level is not SMB2_OPLOCK_LEVEL_NONE\n");
+
+       torture_wait_for_oplock_break(tctx);
+       if (break_info.count != 1) {
+               torture_warning(tctx, "Stream open didn't cause oplock break\n");
+       }
+
+done:
+       if (!smb2_util_handle_empty(h1)) {
+               smb2_util_close(tree, h1);
+       }
+       if (!smb2_util_handle_empty(h2)) {
+               smb2_util_close(tree, h2);
+       }
+       smb2_util_unlink(tree, fname);
+       return ret;
+}
+
+/**
+ * 1) create testfile with stream
+ * 2) 1st client opens stream r/w with batch oplock -> batch oplock granted
+ * 3) 2nd client opens stream r/o with batch oplock
+ *
+ * Verify 3) does trigger an oplock break
+ **/
+static bool test_smb2_kernel_oplocks6(struct torture_context *tctx,
+                                     struct smb2_tree *tree,
+                                     struct smb2_tree *tree2)
+{
+       const char *fname = "test_kernel_oplock6.dat";
+       const char *sname = "test_kernel_oplock6.dat:foo";
+       NTSTATUS status;
+       bool ret = true;
+       struct smb2_create create;
+       struct smb2_handle h1 = {{0}}, h2 = {{0}};
+
+       smb2_util_unlink(tree, fname);
+       status = torture_smb2_testfile(tree, fname, &h1);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "Error creating testfile\n");
+       smb2_util_close(tree, h1);
+       ZERO_STRUCT(h1);
+
+       tree->session->transport->oplock.handler = torture_oplock_handler;
+       tree->session->transport->oplock.private_data = tree;
+       ZERO_STRUCT(break_info);
+
+       /* 1 */
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_READ;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = sname;
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h1 = create.out.file.handle;
+       smb2_util_close(tree, h1);
+       ZERO_STRUCT(h1);
+
+       /* 2 */
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = fname;
+       create.in.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h1 = create.out.file.handle;
+
+       torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE, ret, done,
+                           "Oplock level is not SMB2_OPLOCK_LEVEL_EXCLUSIVE\n");
+
+       /* 3 */
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_READ;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = fname;
+
+       status = smb2_create(tree2, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
+       h2 = create.out.file.handle;
+
+       torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_NONE, ret, done,
+                           "Oplock level is not SMB2_OPLOCK_LEVEL_NONE\n");
+
+       torture_wait_for_oplock_break(tctx);
+       torture_assert_goto(tctx, break_info.count == 1, ret, done, "Expected 1 oplock break\n");
+
+done:
+       if (!smb2_util_handle_empty(h1)) {
+               smb2_util_close(tree, h1);
+       }
+       if (!smb2_util_handle_empty(h2)) {
+               smb2_util_close(tree, h2);
+       }
+       smb2_util_unlink(tree, fname);
+       return ret;
+}
+
 struct torture_suite *torture_smb2_kernel_oplocks_init(TALLOC_CTX *ctx)
 {
        struct torture_suite *suite =
@@ -4500,6 +4683,8 @@ struct torture_suite *torture_smb2_kernel_oplocks_init(TALLOC_CTX *ctx)
        torture_suite_add_1smb2_test(suite, "kernel_oplocks2", test_smb2_kernel_oplocks2);
        torture_suite_add_2smb2_test(suite, "kernel_oplocks3", test_smb2_kernel_oplocks3);
        torture_suite_add_1smb2_test(suite, "kernel_oplocks4", test_smb2_kernel_oplocks4);
+       torture_suite_add_1smb2_test(suite, "kernel_oplocks5", test_smb2_kernel_oplocks5);
+       torture_suite_add_2smb2_test(suite, "kernel_oplocks6", test_smb2_kernel_oplocks6);
 
        suite->description = talloc_strdup(suite, "SMB2-KERNEL-OPLOCK tests");