From: Tim Prouty Date: Mon, 30 Nov 2009 19:59:19 +0000 (-0800) Subject: s4 torture: Update RAW-SFILEINFO-END-OF-FILE to test some additional corner cases X-Git-Tag: samba-4.0.0alpha10~148 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=5035a900051c7946346d4e8b32e8f13f802ce5be s4 torture: Update RAW-SFILEINFO-END-OF-FILE to test some additional corner cases It turns out setting the end-of-file with Trans2SetPathInfo using the snia spec's info level will attempt to open the file, enforcing share modes, but then subsequentlys fail the setpathinfo with a dos error of INVALID_LEVEL. Doing a Trans2SetFileInfo with either end-of-file info level succeeds as expected. --- diff --git a/source4/torture/raw/setfileinfo.c b/source4/torture/raw/setfileinfo.c index 95fb9d7e060..42f4f320c2b 100644 --- a/source4/torture/raw/setfileinfo.c +++ b/source4/torture/raw/setfileinfo.c @@ -700,9 +700,14 @@ static bool torture_raw_sfileinfo_bug(struct torture_context *torture, return true; } +/** + * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented + * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of + * trans2setpathinfo. + */ static bool -torture_raw_sfileinfo_eof(struct torture_context *tctx, struct smbcli_state *cli1, - struct smbcli_state *cli2) +torture_raw_sfileinfo_eof(struct torture_context *tctx, + struct smbcli_state *cli1, struct smbcli_state *cli2) { const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat"; NTSTATUS status; @@ -774,39 +779,119 @@ torture_raw_sfileinfo_eof(struct torture_context *tctx, struct smbcli_state *cli */ if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) { /* It succeeds! This is just weird! */ - torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, - done, "Status should be OK"); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, + ret, done, "Status should be OK"); + + /* Verify that the file was actually extended to 100. */ + ZERO_STRUCT(qfi); + qfi.generic.level = RAW_FILEINFO_STANDARD_INFO; + qfi.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli2->tree, tctx, &qfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, + ret, done, "Status should be OK"); + + torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100, + "alloc_size should be 100 since the setpathinfo " + "succeeded."); } else { torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be " "SHARING_VIOLATION"); - goto done; } - /* Verify that the file was actually extended to 100. */ + /* close the first file. */ + smbcli_close(cli1->tree, fnum); + fnum = 0; + + /* Try to sfileinfo to extend the file again (non-pass-through). */ + ZERO_STRUCT(sfi); + sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO; + sfi.generic.in.file.path = fname; + sfi.end_of_file_info.in.size = 200; + status = smb_raw_setpathinfo(cli2->tree, &sfi); + + /* This should cause the client to retun invalid level. */ + if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) { + /* + * Windows sends back an invalid packet that smbclient sees + * and returns INTERNAL_ERROR. + */ + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be " + "INTERNAL_ERROR"); + } else { + torture_assert_ntstatus_equal_goto(tctx, status, + NT_STATUS_INVALID_LEVEL, ret, done, "Status should be " + "INVALID_LEVEL"); + } + + /* Try to extend the file now with the passthrough level. */ + sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + status = smb_raw_setpathinfo(cli2->tree, &sfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); + + /* Verify that the file was actually extended to 200. */ ZERO_STRUCT(qfi); qfi.generic.level = RAW_FILEINFO_STANDARD_INFO; qfi.generic.in.file.path = fname; status = smb_raw_pathinfo(cli2->tree, tctx, &qfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, done, "Status should be OK"); + torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200, + "alloc_size should be 200 since the setpathinfo succeeded."); - torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100, - "alloc_size should be 100 since the setpathinfo succeeded."); + /* Open the file so end of file can be set by handle. */ + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE; + status = smb_raw_open(cli1->tree, tctx, &io); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); + fnum = io.ntcreatex.out.file.fnum; - /* - * Try another open with just write to mimic what setpathinfo should - * be doing under the covers. - */ - io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; - status = smb_raw_open(cli2->tree, tctx, &io); - torture_assert_ntstatus_equal_goto(tctx, status, - NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be " - "SHARING_VIOLATION"); + /* Try sfileinfo to extend the file by handle (non-pass-through). */ + ZERO_STRUCT(sfi); + sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO; + sfi.generic.in.file.fnum = fnum; + sfi.end_of_file_info.in.size = 300; + status = smb_raw_setfileinfo(cli1->tree, &sfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); - smbcli_close(cli1->tree, fnum); + /* Verify that the file was actually extended to 300. */ + ZERO_STRUCT(qfi); + qfi.generic.level = RAW_FILEINFO_STANDARD_INFO; + qfi.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli1->tree, tctx, &qfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); + torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300, + "alloc_size should be 300 since the setpathinfo succeeded."); + + /* Try sfileinfo to extend the file by handle (pass-through). */ + ZERO_STRUCT(sfi); + sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sfi.generic.in.file.fnum = fnum; + sfi.end_of_file_info.in.size = 400; + status = smb_raw_setfileinfo(cli1->tree, &sfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); + + /* Verify that the file was actually extended to 300. */ + ZERO_STRUCT(qfi); + qfi.generic.level = RAW_FILEINFO_STANDARD_INFO; + qfi.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli1->tree, tctx, &qfi); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret, + done, "Status should be OK"); + torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400, + "alloc_size should be 400 since the setpathinfo succeeded."); + done: + if (fnum > 0) { + smbcli_close(cli1->tree, fnum); + fnum = 0; + } -done: smb_raw_exit(cli1->session); smb_raw_exit(cli2->session); smbcli_deltree(cli1->tree, BASEDIR);