summaryrefslogtreecommitdiff
path: root/source4/torture/raw/oplock.c
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-12-03 13:46:11 -0800
committerTim Prouty <tprouty@samba.org>2009-12-03 18:54:52 -0800
commit15e1c610273766a548a28b4d8731c6e9bad4496e (patch)
tree3a1fb3461555946e19b8a5b0f1af870acc3049c3 /source4/torture/raw/oplock.c
parent8f7e5732ef3accd833906276f4a13891bac26726 (diff)
downloadsamba-15e1c610273766a548a28b4d8731c6e9bad4496e.tar.gz
samba-15e1c610273766a548a28b4d8731c6e9bad4496e.tar.bz2
samba-15e1c610273766a548a28b4d8731c6e9bad4496e.zip
s4 torture: Add a new RAW-OPLOCK test: BATCH26
Try a rename with a wide-open share mode on an already open file and the there is still share mode contention. For the reason why see: http://social.msdn.microsoft.com/Forums/en-US/os_fileservices/thread/3ca14dc9-da1f-4786-a8f7-a86e9903db0c Msft's anser: After further review, The reason for server to fail with sharing violation is that the windows server that executes a path-based rename request opens the file for DELETE access, but only with FILE_SHARED_READ as ShareAccess . Therefore, the existing open(frame 76), which has shared read/write/delete , is compatible with the Windows servers access mode (DELETE), but Windows servers open is not compatible with access mode in existing open. Note that it is correct to state that the logic in Windows server could have been written to allow shared read/write/delete in which case it would succeed as you mention. The behavior here is historical based on the existing implementation.
Diffstat (limited to 'source4/torture/raw/oplock.c')
-rw-r--r--source4/torture/raw/oplock.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index d35445c7eb..78987e3121 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -2969,6 +2969,113 @@ done:
return ret;
}
+/**
+ * Similar to batch17/18, but test with open share mode rather than
+ * share_none.
+ */
+static bool test_raw_oplock_batch26(struct torture_context *tctx,
+ struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+ const char *fname1 = BASEDIR "\\test_batch26_1.dat";
+ const char *fname2 = BASEDIR "\\test_batch26_2.dat";
+ NTSTATUS status;
+ bool ret = true;
+ union smb_open io;
+ union smb_rename rn;
+ uint16_t fnum=0;
+
+ if (!torture_setup_dir(cli1, BASEDIR)) {
+ return false;
+ }
+
+ /* cleanup */
+ smbcli_unlink(cli1->tree, fname1);
+ smbcli_unlink(cli1->tree, fname2);
+
+ smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
+ cli1->tree);
+
+ /*
+ base ntcreatex parms
+ */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid.fnum = 0;
+ io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname1;
+
+ torture_comment(tctx, "BATCH26: open a file with an batch oplock "
+ "(share mode: none)\n");
+
+ ZERO_STRUCT(break_info);
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
+ NTCREATEX_FLAGS_REQUEST_OPLOCK |
+ NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
+
+
+ status = smb_raw_open(cli1->tree, tctx, &io);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+ CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
+
+ torture_comment(tctx, "rename should trigger a break\n");
+ ZERO_STRUCT(rn);
+ rn.generic.level = RAW_RENAME_RENAME;
+ rn.rename.in.pattern1 = fname1;
+ rn.rename.in.pattern2 = fname2;
+ rn.rename.in.attrib = 0;
+
+ torture_comment(tctx, "trying rename while first file open\n");
+ status = smb_raw_rename(cli2->tree, &rn);
+ CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+
+ torture_wait_for_oplock_break(tctx);
+ CHECK_VAL(break_info.count, 1);
+ CHECK_VAL(break_info.failures, 0);
+ CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
+
+ /* Close and reopen with batch again. */
+ smbcli_close(cli1->tree, fnum);
+ ZERO_STRUCT(break_info);
+
+ status = smb_raw_open(cli1->tree, tctx, &io);
+ CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+ CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
+
+ /* Now try ntrename. */
+ torture_comment(tctx, "ntrename should trigger a break\n");
+ ZERO_STRUCT(rn);
+ rn.generic.level = RAW_RENAME_NTRENAME;
+ rn.ntrename.in.attrib = 0;
+ rn.ntrename.in.flags = RENAME_FLAG_RENAME;
+ rn.ntrename.in.old_name = fname1;
+ rn.ntrename.in.new_name = fname2;
+ torture_comment(tctx, "trying rename while first file open\n");
+ status = smb_raw_rename(cli2->tree, &rn);
+ CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+
+ torture_wait_for_oplock_break(tctx);
+ CHECK_VAL(break_info.count, 1);
+ CHECK_VAL(break_info.failures, 0);
+ CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
+
+ smbcli_close(cli1->tree, fnum);
+
+done:
+ smb_raw_exit(cli1->session);
+ smb_raw_exit(cli2->session);
+ smbcli_deltree(cli1->tree, BASEDIR);
+ return ret;
+}
+
/* Test how oplocks work on streams. */
static bool test_raw_oplock_stream1(struct torture_context *tctx,
struct smbcli_state *cli1,
@@ -3557,6 +3664,7 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
torture_suite_add_2smb_test(suite, "BATCH25", test_raw_oplock_batch25);
+ torture_suite_add_2smb_test(suite, "BATCH26", test_raw_oplock_batch26);
torture_suite_add_2smb_test(suite, "STREAM1", test_raw_oplock_stream1);
torture_suite_add_1smb_test(suite, "DOC1", test_raw_oplock_doc);
torture_suite_add_2smb_test(suite, "BRL1", test_raw_oplock_brl1);