The branch, master has been updated via 7a6d240 smbd: Fix the extended *.oplock.doc1 tests via 672c228 torture: Extend the smb2.oplock.doc1 test via 6fbbf94 torture: Extend the raw.oplock.doc1 test from dba7804 ntdb: Make sure variables passed by value are initialized.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 7a6d240b7fa5ac365af3b615f154017ac83d0942 Author: Volker Lendecke <v...@samba.org> Date: Wed Sep 25 18:41:07 2013 -0700 smbd: Fix the extended *.oplock.doc1 tests We need to check for DELETE_PENDING before the first oplock break Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Sat Oct 12 01:56:18 CEST 2013 on sn-devel-104 commit 672c22831032b862a11259ddb1e0cc8ef9ba0d26 Author: Volker Lendecke <v...@samba.org> Date: Wed Sep 25 23:04:50 2013 -0700 torture: Extend the smb2.oplock.doc1 test If delete_on_close is set, there is no oplock break. Check that. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6fbbf94def82132b3c4fd9dcb24d8dae41fca950 Author: Volker Lendecke <v...@samba.org> Date: Wed Sep 25 19:00:57 2013 -0700 torture: Extend the raw.oplock.doc1 test If delete_on_close is set, there is no oplock break. Check that. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/knownfail | 2 + source3/smbd/open.c | 59 +++++++++++++++++++++++------------------ source4/torture/raw/oplock.c | 28 ++++++++++++++----- source4/torture/smb2/oplock.c | 34 +++++++++++++++++++---- 4 files changed, 84 insertions(+), 39 deletions(-) Changeset truncated at 500 lines: diff --git a/selftest/knownfail b/selftest/knownfail index 8b89f00..1653cea 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -122,6 +122,7 @@ ^samba4.smb2.rename.share_delete_no_delete_access\(.*\)$ ^samba4.smb2.rename.no_share_delete_no_delete_access\(.*\)$ ^samba4.smb2.rename.msword +^samba4.smb2.oplock.doc ^samba4.smb2.compound.related3 ^samba4.smb2.compound.compound-break ^samba4.winbind.struct.*.show_sequence # Not yet working in winbind @@ -138,6 +139,7 @@ ^samba4.smb2.lock.*.multiple-unlock # bug 6959 ^samba4.raw.sfileinfo.*.end-of-file\(.*\)$ # bug 6962 ^samba4.raw.oplock.*.batch22 # bug 6963 +^samba4.raw.oplock.*.doc1 ^samba4.raw.lock.*.zerobyteread # bug 6974 ^samba4.smb2.lock.*.zerobyteread # bug 6974 ^samba4.raw.streams.*.delete diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 5024c90..6255180 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1093,6 +1093,26 @@ bool is_stat_open(uint32 access_mask) ((access_mask & ~stat_open_bits) == 0)); } +static bool has_delete_on_close(struct share_mode_lock *lck, + uint32_t name_hash) +{ + struct share_mode_data *d = lck->data; + uint32_t i; + + if (d->num_share_modes == 0) { + return false; + } + if (!is_delete_on_close_set(lck, name_hash)) { + return false; + } + for (i=0; i<d->num_share_modes; i++) { + if (!share_mode_stale_pid(d, i)) { + return true; + } + } + return false; +} + /**************************************************************************** Deal with share modes Invarient: Share mode must be locked on entry and exit. @@ -1113,25 +1133,6 @@ static NTSTATUS open_mode_check(connection_struct *conn, return NT_STATUS_OK; } - /* A delete on close prohibits everything */ - - if (is_delete_on_close_set(lck, name_hash)) { - /* - * Check the delete on close token - * is valid. It could have been left - * after a server crash. - */ - for(i = 0; i < lck->data->num_share_modes; i++) { - if (!share_mode_stale_pid(lck->data, i)) { - - *file_existed = true; - - return NT_STATUS_DELETE_PENDING; - } - } - return NT_STATUS_OK; - } - if (is_stat_open(access_mask)) { /* Stat open that doesn't trigger oplock breaks or share mode * checks... ! JRA. */ @@ -2416,6 +2417,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, &got_level2_oplock, &got_a_none_oplock); + if (has_delete_on_close(lck, fsp->name_hash)) { + TALLOC_FREE(lck); + fd_close(fsp); + return NT_STATUS_DELETE_PENDING; + } + /* First pass - send break only on batch oplocks. */ if ((req != NULL) && delay_for_batch_oplocks(fsp, @@ -2450,13 +2457,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } } - if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { - /* DELETE_PENDING is not deferred for a second */ - TALLOC_FREE(lck); - fd_close(fsp); - return status; - } - if (!NT_STATUS_IS_OK(status)) { uint32 can_access_mask; bool can_access = True; @@ -3166,6 +3166,13 @@ static NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } + if (has_delete_on_close(lck, fsp->name_hash)) { + TALLOC_FREE(lck); + fd_close(fsp); + file_free(req, fsp); + return NT_STATUS_DELETE_PENDING; + } + status = open_mode_check(conn, lck, fsp->name_hash, access_mask, share_access, create_options, &dir_existed); diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index c2e086a..b4aac11 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -3576,7 +3576,8 @@ static bool test_raw_oplock_stream1(struct torture_context *tctx, } static bool test_raw_oplock_doc(struct torture_context *tctx, - struct smbcli_state *cli) + struct smbcli_state *cli, + struct smbcli_state *cli2) { const char *fname = BASEDIR "\\test_oplock_doc.dat"; NTSTATUS status; @@ -3600,16 +3601,15 @@ static bool test_raw_oplock_doc(struct torture_context *tctx, 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_NONE; + 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 = NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = fname; - torture_comment(tctx, "open a delete-on-close file with a batch " - "oplock\n"); - ZERO_STRUCT(break_info); + torture_comment(tctx, "open a file with a batch oplock\n"); io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; @@ -3619,6 +3619,20 @@ static bool test_raw_oplock_doc(struct torture_context *tctx, fnum = io.ntcreatex.out.file.fnum; CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN); + torture_comment(tctx, "Set delete-on-close\n"); + status = smbcli_nt_delete_on_close(cli->tree, fnum, true); + CHECK_STATUS(tctx, status, NT_STATUS_OK); + + torture_comment(tctx, "2nd open should not break and get " + "DELETE_PENDING\n"); + ZERO_STRUCT(break_info); + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA; + status = smb_raw_open(cli2->tree, tctx, &io); + CHECK_STATUS(tctx, status, NT_STATUS_DELETE_PENDING); + CHECK_VAL(break_info.count, 0); + smbcli_close(cli->tree, fnum); done: @@ -4075,7 +4089,7 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx) 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, "doc1", test_raw_oplock_doc); torture_suite_add_2smb_test(suite, "brl1", test_raw_oplock_brl1); torture_suite_add_1smb_test(suite, "brl2", test_raw_oplock_brl2); torture_suite_add_1smb_test(suite, "brl3", test_raw_oplock_brl3); diff --git a/source4/torture/smb2/oplock.c b/source4/torture/smb2/oplock.c index 4cf7c7d..5070d00 100644 --- a/source4/torture/smb2/oplock.c +++ b/source4/torture/smb2/oplock.c @@ -2896,16 +2896,19 @@ static bool test_raw_oplock_stream1(struct torture_context *tctx, return ret; } -static bool test_smb2_oplock_doc(struct torture_context *tctx, struct smb2_tree *tree) +static bool test_smb2_oplock_doc(struct torture_context *tctx, struct smb2_tree *tree, + struct smb2_tree *tree2) { const char *fname = BASEDIR "\\test_oplock_doc.dat"; NTSTATUS status; bool ret = true; union smb_open io; struct smb2_handle h, h1; + union smb_setfileinfo sfinfo; status = torture_smb2_testdir(tree, BASEDIR, &h); torture_assert_ntstatus_ok(tctx, status, "Error creating directory"); + smb2_util_close(tree, h); /* cleanup */ smb2_util_unlink(tree, fname); @@ -2920,15 +2923,15 @@ static bool test_smb2_oplock_doc(struct torture_context *tctx, struct smb2_tree io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL; io.smb2.in.alloc_size = 0; io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL; - io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE; io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF; - io.smb2.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + io.smb2.in.create_options = 0; io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; io.smb2.in.security_flags = 0; io.smb2.in.fname = fname; - torture_comment(tctx, "open a delete-on-close file with a batch " - "oplock\n"); + torture_comment(tctx, "open a file with a batch oplock\n"); ZERO_STRUCT(break_info); io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED; io.smb2.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; @@ -2938,6 +2941,25 @@ static bool test_smb2_oplock_doc(struct torture_context *tctx, struct smb2_tree h1 = io.smb2.out.file.handle; CHECK_VAL(io.smb2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + torture_comment(tctx, "Set delete on close\n"); + ZERO_STRUCT(sfinfo); + sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION; + sfinfo.generic.in.file.handle = h1; + sfinfo.disposition_info.in.delete_on_close = 1; + status = smb2_setinfo_file(tree, &sfinfo); + torture_assert_ntstatus_ok(tctx, status, "Incorrect status"); + + torture_comment(tctx, "2nd open should not break and get " + "DELETE_PENDING\n"); + ZERO_STRUCT(break_info); + io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN; + io.smb2.in.create_options = 0; + io.smb2.in.desired_access = SEC_FILE_READ_DATA; + status = smb2_create(tree2, tctx, &io.smb2); + torture_assert_ntstatus_equal(tctx, status, NT_STATUS_DELETE_PENDING, + "Incorrect status"); + CHECK_VAL(break_info.count, 0); + smb2_util_close(tree, h1); smb2_util_unlink(tree, fname); @@ -3412,7 +3434,7 @@ struct torture_suite *torture_smb2_oplocks_init(void) torture_suite_add_2smb2_test(suite, "batch24", test_smb2_oplock_batch24); torture_suite_add_1smb2_test(suite, "batch25", test_smb2_oplock_batch25); torture_suite_add_2smb2_test(suite, "stream1", test_raw_oplock_stream1); - torture_suite_add_1smb2_test(suite, "doc", test_smb2_oplock_doc); + torture_suite_add_2smb2_test(suite, "doc", test_smb2_oplock_doc); torture_suite_add_2smb2_test(suite, "brl1", test_smb2_oplock_brl1); torture_suite_add_1smb2_test(suite, "brl2", test_smb2_oplock_brl2); torture_suite_add_1smb2_test(suite, "brl3", test_smb2_oplock_brl3); -- Samba Shared Repository