The Samba-Bugzilla – Attachment 15505 Details for
Bug 14137
Stale file handle error when using mkstemp on a share
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for 4.11 cherry-picked from master
bug14137-v411.patch (text/plain), 43.07 KB, created by
Ralph Böhme
on 2019-10-02 09:49:02 UTC
(
hide
)
Description:
Patch for 4.11 cherry-picked from master
Filename:
MIME Type:
Creator:
Ralph Böhme
Created:
2019-10-02 09:49:02 UTC
Size:
43.07 KB
patch
obsolete
>From b6ed1070280ffe6587310880552e267b2ba1607a Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 23 Sep 2019 15:15:01 -0700 >Subject: [PATCH 01/13] torture:smb2: extend test for File-IDs > >This now hopefully covers most possible combinations of creating and opening >files plus, checking the file's File-ID after every operation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 432202413f4d11d761c62f46a50747fcb9b6f0cf) >--- > selftest/knownfail.d/samba3.smb2.fileid | 1 + > source4/torture/smb2/create.c | 299 ++++++++++++++++++++---- > 2 files changed, 259 insertions(+), 41 deletions(-) > create mode 100644 selftest/knownfail.d/samba3.smb2.fileid > >diff --git a/selftest/knownfail.d/samba3.smb2.fileid b/selftest/knownfail.d/samba3.smb2.fileid >new file mode 100644 >index 00000000000..89455dacdf0 >--- /dev/null >+++ b/selftest/knownfail.d/samba3.smb2.fileid >@@ -0,0 +1 @@ >+^samba3.smb2.fileid.fileid\(nt4_dc\) >diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c >index beddefc4c8d..ea83b483491 100644 >--- a/source4/torture/smb2/create.c >+++ b/source4/torture/smb2/create.c >@@ -1919,8 +1919,8 @@ static bool test_fileid(struct torture_context *tctx, > struct smb2_find f; > unsigned int count; > union smb_search_data *d; >- uint64_t fileid; >- uint64_t stream_fileid; >+ uint64_t expected_fileid; >+ uint64_t returned_fileid; > NTSTATUS status; > bool ret = true; > >@@ -1930,6 +1930,9 @@ static bool test_fileid(struct torture_context *tctx, > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "torture_smb2_testdir failed\n"); > >+ /* >+ * Initial create with QFID >+ */ > create = (struct smb2_create) { > .in.desired_access = SEC_FILE_ALL, > .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >@@ -1943,9 +1946,47 @@ static bool test_fileid(struct torture_context *tctx, > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "test file could not be created\n"); > h1 = create.out.file.handle; >+ expected_fileid = BVAL(&create.out.on_disk_id, 0); >+ >+ /* >+ * Getinfo the File-ID on the just opened handle >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Open existing with QFID >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = fname, >+ .in.query_on_disk_id = true, >+ }; > >- fileid = BVAL(&create.out.on_disk_id, 0); >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); > >+ /* >+ * Getinfo the File-ID on the just opened handle >+ */ > finfo = (union smb_fileinfo) { > .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, > .generic.in.file.handle = h1, >@@ -1954,33 +1995,111 @@ static bool test_fileid(struct torture_context *tctx, > status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Overwrite with QFID >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OVERWRITE, >+ .in.fname = fname, >+ .in.query_on_disk_id = true, >+ }; > >- torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, > ret, done, "bad fileid\n"); > >- f = (struct smb2_find) { >- .in.file.handle = testdirh, >- .in.pattern = "foo", >- .in.max_response_size = 0x1000, >- .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >+ /* >+ * Getinfo the File-ID on the open with overwrite handle >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, > }; > >- status = smb2_find_level(tree, tree, &f, &count, &d); >+ status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >- "smb2_find_level failed\n"); >+ "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); > >- torture_assert_u64_equal_goto(tctx, >- d->id_both_directory_info.file_id, >- fileid, >+ /* >+ * Do some modifications on the basefile (IO, setinfo), verifying >+ * File-ID after each step. >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = fname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ >+ status = smb2_util_write(tree, h1, "foo", 0, strlen("foo")); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_util_write failed\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, > ret, done, "bad fileid\n"); > >+ sinfo = (union smb_setfileinfo) { >+ .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION, >+ .basic_info.in.file.handle = h1, >+ }; >+ unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL)); >+ >+ status = smb2_setinfo_file(tree, &sinfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_setinfo_file failed\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); > smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); > >+ /* >+ * Create stream, check the stream's File-ID, should be the same as the >+ * base file (sic!, tested against Windows). >+ */ > create = (struct smb2_create) { > .in.desired_access = SEC_FILE_ALL, > .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, > .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >- .in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF, >+ .in.create_disposition = NTCREATEX_DISP_CREATE, > .in.fname = sname, > .in.query_on_disk_id = true, > }; >@@ -1989,11 +2108,13 @@ static bool test_fileid(struct torture_context *tctx, > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "test file could not be created\n"); > h1 = create.out.file.handle; >- >- stream_fileid = BVAL(&create.out.on_disk_id, 0); >- torture_assert_u64_equal_goto(tctx, stream_fileid, fileid, >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, > ret, done, "bad fileid\n"); > >+ /* >+ * Getinfo the File-ID on the created stream >+ */ > finfo = (union smb_fileinfo) { > .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, > .generic.in.file.handle = h1, >@@ -2002,31 +2123,118 @@ static bool test_fileid(struct torture_context *tctx, > status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Open stream, check the stream's File-ID, should be the same as the >+ * base file (sic!, tested against Windows). >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; > >- torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, > ret, done, "bad fileid\n"); > >- f = (struct smb2_find) { >- .in.file.handle = testdirh, >- .in.pattern = "foo", >- .in.max_response_size = 0x1000, >- .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >- .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART, >+ /* >+ * Getinfo the File-ID on the opened stream >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, > }; > >- status = smb2_find_level(tree, tree, &f, &count, &d); >+ status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >- "smb2_find_level failed\n"); >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); > >- torture_assert_u64_equal_goto(tctx, >- d->id_both_directory_info.file_id, >- fileid, >+ /* >+ * Overwrite stream, check the stream's File-ID, should be the same as >+ * the base file (sic!, tested against Windows). >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OVERWRITE, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, > ret, done, "bad fileid\n"); > >+ /* >+ * Getinfo the File-ID on the overwritten stream >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Do some modifications on the stream (IO, setinfo), verifying File-ID >+ * after earch step. >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ > status = smb2_util_write(tree, h1, "foo", 0, strlen("foo")); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "smb2_util_write failed\n"); > >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ > sinfo = (union smb_setfileinfo) { > .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION, > .basic_info.in.file.handle = h1, >@@ -2041,16 +2249,17 @@ static bool test_fileid(struct torture_context *tctx, > .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, > .generic.in.file.handle = h1, > }; >- > status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "smb2_getinfo_file failed\n"); >- >- torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >- ret, done, "bad fileid\n"); >- > smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); > >+ /* >+ * Final open of the basefile with QFID >+ */ > create = (struct smb2_create) { > .in.desired_access = SEC_FILE_ALL, > .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >@@ -2064,7 +2273,13 @@ static bool test_fileid(struct torture_context *tctx, > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "test file could not be created\n"); > h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); > >+ /* >+ * Final Getinfo checking File-ID >+ */ > finfo = (union smb_fileinfo) { > .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, > .generic.in.file.handle = h1, >@@ -2073,10 +2288,15 @@ static bool test_fileid(struct torture_context *tctx, > status = smb2_getinfo_file(tree, tctx, &finfo); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "torture_smb2_testdir\n"); >- >- torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, > ret, done, "bad fileid\n"); > >+ /* >+ * Final list directory, verifying the operations on basefile and stream >+ * didn't modify the base file metadata. >+ */ > f = (struct smb2_find) { > .in.file.handle = testdirh, > .in.pattern = "foo", >@@ -2088,14 +2308,11 @@ static bool test_fileid(struct torture_context *tctx, > status = smb2_find_level(tree, tree, &f, &count, &d); > torture_assert_ntstatus_ok_goto(tctx, status, ret, done, > "smb2_find_level failed\n"); >- > torture_assert_u64_equal_goto(tctx, > d->id_both_directory_info.file_id, >- fileid, >+ expected_fileid, > ret, done, "bad fileid\n"); > >- smb2_util_close(tree, h1); >- > done: > smb2_util_close(tree, testdirh); > smb2_deltree(tree, DNAME); >-- >2.21.0 > > >From 890cf736427b400638fa67a7d3c9c026d16715b5 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Tue, 24 Sep 2019 13:09:03 -0700 >Subject: [PATCH 02/13] torture:smb2: add a File-ID test on directories > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 300b47442b023532bd65417fcec04d811f40ef76) >--- > selftest/knownfail.d/samba3.smb2.fileid | 1 + > source4/torture/smb2/create.c | 328 ++++++++++++++++++++++++ > 2 files changed, 329 insertions(+) > >diff --git a/selftest/knownfail.d/samba3.smb2.fileid b/selftest/knownfail.d/samba3.smb2.fileid >index 89455dacdf0..bdf86ac61b1 100644 >--- a/selftest/knownfail.d/samba3.smb2.fileid >+++ b/selftest/knownfail.d/samba3.smb2.fileid >@@ -1 +1,2 @@ > ^samba3.smb2.fileid.fileid\(nt4_dc\) >+^samba3.smb2.fileid.fileid-dir\(nt4_dc\) >diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c >index ea83b483491..aab74f5569a 100644 >--- a/source4/torture/smb2/create.c >+++ b/source4/torture/smb2/create.c >@@ -2320,6 +2320,333 @@ static bool test_fileid(struct torture_context *tctx, > return ret; > } > >+static bool test_fileid_dir(struct torture_context *tctx, >+ struct smb2_tree *tree) >+{ >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ const char *dname = DNAME "\\foo"; >+ const char *sname = DNAME "\\foo:bar"; >+ struct smb2_handle testdirh; >+ struct smb2_handle h1; >+ struct smb2_create create; >+ union smb_fileinfo finfo; >+ union smb_setfileinfo sinfo; >+ struct smb2_find f; >+ unsigned int count; >+ union smb_search_data *d; >+ uint64_t expected_fileid; >+ uint64_t returned_fileid; >+ NTSTATUS status; >+ bool ret = true; >+ >+ smb2_deltree(tree, DNAME); >+ >+ status = torture_smb2_testdir(tree, DNAME, &testdirh); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir failed\n"); >+ >+ /* >+ * Initial directory create with QFID >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.create_disposition = NTCREATEX_DISP_OPEN_IF, >+ .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY, >+ .in.create_options = NTCREATEX_OPTIONS_DIRECTORY, >+ .in.fname = dname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ expected_fileid = BVAL(&create.out.on_disk_id, 0); >+ >+ /* >+ * Getinfo the File-ID on the just opened handle >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Open existing directory with QFID >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY, >+ .in.create_options = NTCREATEX_OPTIONS_DIRECTORY, >+ .in.fname = dname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Getinfo the File-ID on the just opened handle >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Create stream, check the stream's File-ID, should be the same as the >+ * base file (sic!, tested against Windows). >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_CREATE, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Getinfo the File-ID on the created stream >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Open stream, check the stream's File-ID, should be the same as the >+ * base file (sic!, tested against Windows). >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Getinfo the File-ID on the opened stream >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Overwrite stream, check the stream's File-ID, should be the same as >+ * the base file (sic!, tested against Windows). >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OVERWRITE, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Getinfo the File-ID on the overwritten stream >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Do some modifications on the stream (IO, setinfo), verifying File-ID >+ * after earch step. >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ >+ status = smb2_util_write(tree, h1, "foo", 0, strlen("foo")); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_util_write failed\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ sinfo = (union smb_setfileinfo) { >+ .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION, >+ .basic_info.in.file.handle = h1, >+ }; >+ unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL)); >+ >+ status = smb2_setinfo_file(tree, &sinfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_setinfo_file failed\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Final open of the directory with QFID >+ */ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY, >+ .in.create_options = NTCREATEX_OPTIONS_DIRECTORY, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = dname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ returned_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Final Getinfo checking File-ID >+ */ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ smb2_util_close(tree, h1); >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+ /* >+ * Final list directory, verifying the operations on basefile and stream >+ * didn't modify the base file metadata. >+ */ >+ f = (struct smb2_find) { >+ .in.file.handle = testdirh, >+ .in.pattern = "foo", >+ .in.max_response_size = 0x1000, >+ .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >+ .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART, >+ }; >+ >+ status = smb2_find_level(tree, tree, &f, &count, &d); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_find_level failed\n"); >+ torture_assert_u64_equal_goto(tctx, >+ d->id_both_directory_info.file_id, >+ expected_fileid, >+ ret, done, "bad fileid\n"); >+ >+done: >+ smb2_util_close(tree, testdirh); >+ smb2_deltree(tree, DNAME); >+ talloc_free(mem_ctx); >+ return ret; >+} >+ > /* > basic testing of SMB2 read > */ >@@ -2366,6 +2693,7 @@ struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx) > struct torture_suite *suite = torture_suite_create(ctx, "fileid"); > > torture_suite_add_1smb2_test(suite, "fileid", test_fileid); >+ torture_suite_add_1smb2_test(suite, "fileid-dir", test_fileid_dir); > > suite->description = talloc_strdup(suite, "SMB2-CREATE tests"); > >-- >2.21.0 > > >From 54a2c7fd7a86fb008826d7f029bf8fdd16ad7de8 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 23 Sep 2019 15:15:31 -0700 >Subject: [PATCH 03/13] s3:smbd: change the place where we call dos_mode() when > processing SMB2_CREATE > >This is needed for ordinary file or directory opens so the QFID create context >response gets the correct File-ID value via dos_mode() from the DOS attributes >xattr. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit e1dfaa2b038d91e43d8d34bf1526b7728dba58a5) >--- > source3/smbd/smb2_create.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c >index 61ed72169fb..66f4aad8c9e 100644 >--- a/source3/smbd/smb2_create.c >+++ b/source3/smbd/smb2_create.c >@@ -1274,6 +1274,9 @@ static void smbd_smb2_create_after_exec(struct tevent_req *req) > DEBUG(10, ("smbd_smb2_create_send: " > "response construction phase\n")); > >+ state->out_file_attributes = dos_mode(state->result->conn, >+ state->result->fsp_name); >+ > if (state->mxac != NULL) { > NTTIME last_write_time; > >@@ -1472,8 +1475,6 @@ static void smbd_smb2_create_finish(struct tevent_req *req) > state->out_create_action = state->info; > } > result->op->create_action = state->out_create_action; >- state->out_file_attributes = dos_mode(result->conn, >- result->fsp_name); > > state->out_creation_ts = get_create_timespec(smb1req->conn, > result, result->fsp_name); >-- >2.21.0 > > >From 388af52158096f7c9c4cdd72a1708391a39633f0 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 23 Sep 2019 15:16:58 -0700 >Subject: [PATCH 04/13] s3:smbd: when storing DOS attribute call dos_mode() > beforehand > >This is required to ensure File-ID info is populated with the correct on-disk >value, before calling file_set_dosmode() which will update the on-disk value. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 49a754b82d33fb523cda4151a865584ae52a2e2f) >--- > selftest/knownfail.d/samba3.smb2.fileid | 1 - > source3/smbd/open.c | 1 + > 2 files changed, 1 insertion(+), 1 deletion(-) > >diff --git a/selftest/knownfail.d/samba3.smb2.fileid b/selftest/knownfail.d/samba3.smb2.fileid >index bdf86ac61b1..89455dacdf0 100644 >--- a/selftest/knownfail.d/samba3.smb2.fileid >+++ b/selftest/knownfail.d/samba3.smb2.fileid >@@ -1,2 +1 @@ > ^samba3.smb2.fileid.fileid\(nt4_dc\) >-^samba3.smb2.fileid.fileid-dir\(nt4_dc\) >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index a5650ac9c2d..7f1f8eae593 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -3725,6 +3725,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, > /* Overwritten files should be initially set as archive */ > if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) || > lp_store_dos_attributes(SNUM(conn))) { >+ (void)dos_mode(conn, smb_fname); > if (!posix_open) { > if (file_set_dosmode(conn, smb_fname, > new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE, >-- >2.21.0 > > >From d808e4169fa8b4b39cc3758dd0bbe2b6727dbde3 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 25 Sep 2019 08:53:29 -0700 >Subject: [PATCH 05/13] s3:lib: rework a return expression into an if block > >Needed to add additional stuff after the if block in the next commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit d7dc85990a177954925644f9ff332b3481a03cc7) >--- > source3/lib/filename_util.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 8a16bacddbe..6bf29c2b0c9 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -253,7 +253,11 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) > return false; > } > >- return smb_fname->stream_name != NULL; >+ if (smb_fname->stream_name == NULL) { >+ return false; >+ } >+ >+ return true; > } > > /**************************************************************************** >-- >2.21.0 > > >From 7cc039e74547334bf4f34f1986dcf8ce6ecb4010 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 25 Sep 2019 10:15:27 -0700 >Subject: [PATCH 06/13] s3:lib: assert stream_name is NULL for POSIX paths > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 6c1647ca7a2f68825c34e9ccc18b86ef911e14ac) >--- > source3/lib/filename_util.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 6bf29c2b0c9..165adb116b5 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -250,7 +250,7 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) > } > > if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) { >- return false; >+ SMB_ASSERT(smb_fname->stream_name == NULL); > } > > if (smb_fname->stream_name == NULL) { >-- >2.21.0 > > >From f97d242bc1caaa566e0fa602d2b42672cb7dbdea Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 25 Sep 2019 10:18:03 -0700 >Subject: [PATCH 07/13] s3:lib: factor out stream name asserts to helper > function > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit f9fdb8a2a6b9ad0fbb89a9734e81a8b1f527966f) >--- > source3/lib/filename_util.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 165adb116b5..7b3fab90c46 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -239,10 +239,7 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx, > return out; > } > >-/**************************************************************************** >- Simple check to determine if the filename is a stream. >- ***************************************************************************/ >-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) >+static void assert_valid_stream_smb_fname(const struct smb_filename *smb_fname) > { > /* stream_name must always be NULL if there is no stream. */ > if (smb_fname->stream_name) { >@@ -252,6 +249,15 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) > if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) { > SMB_ASSERT(smb_fname->stream_name == NULL); > } >+} >+ >+/**************************************************************************** >+ Simple check to determine if the filename is a stream. >+ ***************************************************************************/ >+ >+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) >+{ >+ assert_valid_stream_smb_fname(smb_fname); > > if (smb_fname->stream_name == NULL) { > return false; >-- >2.21.0 > > >From 686785c97ffa53e30a9969bdd3a71c488791ec9c Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Thu, 26 Sep 2019 10:38:06 -0700 >Subject: [PATCH 08/13] s3:lib: expand a comment with the function doc for > is_ntfs_stream_smb_fname > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 2584b4cdeae3f83962cd11538cd4e441104c8274) >--- > source3/lib/filename_util.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 7b3fab90c46..750c0bb8312 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -252,7 +252,8 @@ static void assert_valid_stream_smb_fname(const struct smb_filename *smb_fname) > } > > /**************************************************************************** >- Simple check to determine if the filename is a stream. >+ Simple check to determine if a smb_fname is a real named stream or the >+ default stream. > ***************************************************************************/ > > bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) >-- >2.21.0 > > >From 4ee26a9053afd0e51fb25126a7637b80b586811e Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 25 Sep 2019 11:19:26 -0700 >Subject: [PATCH 09/13] s3:lib: implement logic directly in > is_ntfs_default_stream_smb_fname() > >This allows changing the semantics of is_ntfs_stream_smb_fname() in the next >commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 3f8bc1ce3e094f943363921c46803fd5ec9f73bb) >--- > source3/lib/filename_util.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 750c0bb8312..ee49ae5ff8c 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -272,7 +272,9 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) > ***************************************************************************/ > bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) > { >- if (!is_ntfs_stream_smb_fname(smb_fname)) { >+ assert_valid_stream_smb_fname(smb_fname); >+ >+ if (smb_fname->stream_name == NULL) { > return false; > } > >-- >2.21.0 > > >From 658b9b8a4853e0954c9a66126e18bc1fde31c717 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 25 Sep 2019 11:29:04 -0700 >Subject: [PATCH 10/13] s3:lib: use strequal_m() in > is_ntfs_default_stream_smb_fname() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 780a8dcba998471bb154e8bae4391786b793e332) >--- > source3/lib/filename_util.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index ee49ae5ff8c..2917481c8bf 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -278,7 +278,7 @@ bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname) > return false; > } > >- return strcasecmp_m(smb_fname->stream_name, "::$DATA") == 0; >+ return strequal_m(smb_fname->stream_name, "::$DATA"); > } > > /**************************************************************************** >-- >2.21.0 > > >From eead2afb781c6b7dd28ea14cf4830b99f43973d6 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Thu, 26 Sep 2019 10:05:40 -0700 >Subject: [PATCH 11/13] s3:lib: add is_named_stream() > >Add a new utility functions that checks whether a struct smb_filename points to >a real named stream, excluding the default stream "::$DATA". > > foo -> false > foo::$DATA -> false > foo:bar -> true > foo:bar:$DATA -> true > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 091e3fdab61217251de1cf5111f070ff295d1649) >--- > source3/include/proto.h | 1 + > source3/lib/filename_util.c | 26 ++++++++++++++++++++++++++ > 2 files changed, 27 insertions(+) > >diff --git a/source3/include/proto.h b/source3/include/proto.h >index ad6f3bbf9c3..cb8890d340b 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -985,6 +985,7 @@ struct smb_filename *cp_smb_filename_nostream(TALLOC_CTX *mem_ctx, > const struct smb_filename *in); > bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); > bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); >+bool is_named_stream(const struct smb_filename *smb_fname); > bool is_invalid_windows_ea_name(const char *name); > bool ea_list_has_invalid_name(struct ea_list *ea_list); > bool split_stream_filename(TALLOC_CTX *ctx, >diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c >index 2917481c8bf..66c07001eba 100644 >--- a/source3/lib/filename_util.c >+++ b/source3/lib/filename_util.c >@@ -267,6 +267,32 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname) > return true; > } > >+/**************************************************************************** >+ Simple check to determine if a smb_fname is pointing to a normal file or >+ a named stream that is not the default stream "::$DATA". >+ >+ foo -> false >+ foo::$DATA -> false >+ foo:bar -> true >+ foo:bar:$DATA -> true >+ >+ ***************************************************************************/ >+ >+bool is_named_stream(const struct smb_filename *smb_fname) >+{ >+ assert_valid_stream_smb_fname(smb_fname); >+ >+ if (smb_fname->stream_name == NULL) { >+ return false; >+ } >+ >+ if (strequal_m(smb_fname->stream_name, "::$DATA")) { >+ return false; >+ } >+ >+ return true; >+} >+ > /**************************************************************************** > Returns true if the filename's stream == "::$DATA" > ***************************************************************************/ >-- >2.21.0 > > >From e1049400dd109d3d9080cf5bf45da78ae6f54839 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Tue, 24 Sep 2019 12:49:38 -0700 >Subject: [PATCH 12/13] s3:smbd: ensure a created stream picks up the File-ID > from the basefile > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 90a14c90c4bcede1ef5414e0800aa4c84cbcf1c9) >--- > selftest/knownfail.d/samba3.smb2.fileid | 1 - > source3/smbd/open.c | 2 +- > 2 files changed, 1 insertion(+), 2 deletions(-) > delete mode 100644 selftest/knownfail.d/samba3.smb2.fileid > >diff --git a/selftest/knownfail.d/samba3.smb2.fileid b/selftest/knownfail.d/samba3.smb2.fileid >deleted file mode 100644 >index 89455dacdf0..00000000000 >--- a/selftest/knownfail.d/samba3.smb2.fileid >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smb2.fileid.fileid\(nt4_dc\) >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 7f1f8eae593..8586b467d2e 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -3708,7 +3708,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, > fsp->initial_delete_on_close = True; > } > >- if (info == FILE_WAS_CREATED) { >+ if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) { > smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME; > > if (lp_store_dos_attributes(SNUM(conn)) && >-- >2.21.0 > > >From d47c38315bd565465edfacbe81a64aa4837a00a8 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Thu, 26 Sep 2019 10:41:37 -0700 >Subject: [PATCH 13/13] s3:smbd: add a comment explaining the File-ID semantics > when a file is created > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14137 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit c190f3efa9eb4f633df28074b481ff884b67e65f) >--- > source3/smbd/open.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 8586b467d2e..5524f80af20 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -3708,6 +3708,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, > fsp->initial_delete_on_close = True; > } > >+ /* >+ * If we created a file and it's not a stream, this is the point where >+ * we set the itime (aka invented time) that get's stored in the DOS >+ * attribute xattr. The value is going to be either what the filesystem >+ * provided or a copy of the creation date. >+ * >+ * Either way, we turn the itime into a File-ID, unless the filesystem >+ * provided one (unlikely). >+ */ > if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) { > smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME; > >-- >2.21.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 14137
:
15481
|
15482
|
15486
| 15505