mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
tests: Add 2 tests for unique fileid's with top bit set (generated from itime) for files and directories.
smb2.fileid_unique.fileid_unique
smb2.fileid_unique.fileid_unique-dir
Create 100 files or directories as fast as we can
against a "normal" share, then read info on them
and ensure (a) top bit is set (generated from itime)
and (b) uniqueness across all generated objects
(checks poor timestamp resolution doesn't create
duplicate fileids).
This shows that even on ext4, this is enough to
cause duplicate fileids to be returned.
Add knownfail.d/fileid-unique
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14928
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
(back-ported picked from commit 30fea0d311
)
This commit is contained in:
parent
1d27e85826
commit
9f0353b2f4
2
selftest/knownfail.d/fileid-unique
Normal file
2
selftest/knownfail.d/fileid-unique
Normal file
@ -0,0 +1,2 @@
|
||||
^samba3.smb2.fileid_unique.fileid_unique\(fileserver\)
|
||||
^samba3.smb2.fileid_unique.fileid_unique-dir\(fileserver\)
|
@ -878,6 +878,8 @@ for t in tests:
|
||||
plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
|
||||
elif t == "smb2.fileid":
|
||||
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_xattr -U$USERNAME%$PASSWORD')
|
||||
elif t == "smb2.fileid_unique":
|
||||
plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
|
||||
elif t == "rpc.wkssvc":
|
||||
plansmbtorture4testsuite(t, "ad_member", '//$SERVER/tmp -U$DC_USERNAME%$DC_PASSWORD')
|
||||
elif t == "rpc.srvsvc":
|
||||
|
@ -370,6 +370,7 @@ smb2_s3only = [
|
||||
"smb2.durable-v2-delay",
|
||||
"smb2.aio_delay",
|
||||
"smb2.fileid",
|
||||
"smb2.fileid_unique",
|
||||
"smb2.timestamps",
|
||||
]
|
||||
smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only]
|
||||
|
@ -2707,6 +2707,191 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_fileid_unique_object(
|
||||
struct torture_context *tctx,
|
||||
struct smb2_tree *tree,
|
||||
unsigned int num_objs,
|
||||
bool create_dirs)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(tctx);
|
||||
char *fname = NULL;
|
||||
struct smb2_handle testdirh;
|
||||
struct smb2_handle h1;
|
||||
struct smb2_create create;
|
||||
unsigned int i;
|
||||
uint64_t fileid_array[num_objs];
|
||||
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,
|
||||
"test_fileid_unique failed\n");
|
||||
smb2_util_close(tree, testdirh);
|
||||
|
||||
/* Create num_obj files as rapidly as we can. */
|
||||
for (i = 0; i < num_objs; i++) {
|
||||
fname = talloc_asprintf(mem_ctx,
|
||||
"%s\\testfile.%u",
|
||||
DNAME,
|
||||
i);
|
||||
torture_assert_goto(tctx,
|
||||
fname != NULL,
|
||||
ret,
|
||||
done,
|
||||
"talloc failed\n");
|
||||
|
||||
create = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_ATTRIBUTE,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.create_disposition = NTCREATEX_DISP_CREATE,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
if (create_dirs) {
|
||||
create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
create.in.create_options = FILE_DIRECTORY_FILE;
|
||||
}
|
||||
|
||||
status = smb2_create(tree, tctx, &create);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
torture_fail(tctx,
|
||||
talloc_asprintf(tctx,
|
||||
"test file %s could not be created\n",
|
||||
fname));
|
||||
TALLOC_FREE(fname);
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
h1 = create.out.file.handle;
|
||||
smb2_util_close(tree, h1);
|
||||
TALLOC_FREE(fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the file ids.
|
||||
*/
|
||||
for (i = 0; i < num_objs; i++) {
|
||||
union smb_fileinfo finfo;
|
||||
|
||||
fname = talloc_asprintf(mem_ctx,
|
||||
"%s\\testfile.%u",
|
||||
DNAME,
|
||||
i);
|
||||
torture_assert_goto(tctx,
|
||||
fname != NULL,
|
||||
ret,
|
||||
done,
|
||||
"talloc failed\n");
|
||||
|
||||
create = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_ATTRIBUTE,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.create_disposition = NTCREATEX_DISP_OPEN,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
if (create_dirs) {
|
||||
create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
create.in.create_options = FILE_DIRECTORY_FILE;
|
||||
}
|
||||
|
||||
status = smb2_create(tree, tctx, &create);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
torture_fail(tctx,
|
||||
talloc_asprintf(tctx,
|
||||
"test file %s could not "
|
||||
"be opened: %s\n",
|
||||
fname,
|
||||
nt_errstr(status)));
|
||||
TALLOC_FREE(fname);
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
h1 = create.out.file.handle;
|
||||
|
||||
finfo = (union smb_fileinfo) {
|
||||
.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
|
||||
.generic.in.file.handle = h1,
|
||||
};
|
||||
|
||||
status = smb2_getinfo_file(tree, tctx, &finfo);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
torture_fail(tctx,
|
||||
talloc_asprintf(tctx,
|
||||
"failed to get fileid for "
|
||||
"test file %s: %s\n",
|
||||
fname,
|
||||
nt_errstr(status)));
|
||||
TALLOC_FREE(fname);
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
smb2_util_close(tree, h1);
|
||||
/*
|
||||
* Samba created files on a "normal" share
|
||||
* using itime should have the top bit of the fileid set.
|
||||
*/
|
||||
fileid_array[i] = finfo.all_info2.out.file_id;
|
||||
|
||||
if ((fileid_array[i] & 0x8000000000000000) == 0) {
|
||||
torture_fail(tctx,
|
||||
talloc_asprintf(tctx,
|
||||
"test file %s fileid 0x%lx top "
|
||||
"bit not set\n",
|
||||
fname,
|
||||
fileid_array[i]));
|
||||
TALLOC_FREE(fname);
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
TALLOC_FREE(fname);
|
||||
}
|
||||
|
||||
/* All returned fileids must be unique. 100 is small so brute force. */
|
||||
for (i = 0; i < num_objs - 1; i++) {
|
||||
unsigned int j;
|
||||
for (j = i + 1; j < num_objs; j++) {
|
||||
if (fileid_array[i] == fileid_array[j]) {
|
||||
torture_fail(tctx,
|
||||
talloc_asprintf(tctx,
|
||||
"fileid %u == fileid %u (0x%lu)\n",
|
||||
i,
|
||||
j,
|
||||
fileid_array[i]));
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
smb2_util_close(tree, testdirh);
|
||||
smb2_deltree(tree, DNAME);
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_fileid_unique(
|
||||
struct torture_context *tctx,
|
||||
struct smb2_tree *tree)
|
||||
{
|
||||
return test_fileid_unique_object(tctx, tree, 100, false);
|
||||
}
|
||||
|
||||
static bool test_fileid_unique_dir(
|
||||
struct torture_context *tctx,
|
||||
struct smb2_tree *tree)
|
||||
{
|
||||
return test_fileid_unique_object(tctx, tree, 100, true);
|
||||
}
|
||||
|
||||
/*
|
||||
test opening quota fakefile handle and returned attributes
|
||||
*/
|
||||
@ -2823,3 +3008,23 @@ struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx)
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
/*
|
||||
Testing for uniqueness of SMB2 File-IDs
|
||||
*/
|
||||
struct torture_suite *torture_smb2_fileid_unique_init(TALLOC_CTX *ctx)
|
||||
{
|
||||
struct torture_suite *suite = torture_suite_create(ctx,
|
||||
"fileid_unique");
|
||||
|
||||
torture_suite_add_1smb2_test(suite,
|
||||
"fileid_unique",
|
||||
test_fileid_unique);
|
||||
torture_suite_add_1smb2_test(suite,
|
||||
"fileid_unique-dir",
|
||||
test_fileid_unique_dir);
|
||||
|
||||
suite->description = talloc_strdup(suite, "SMB2-FILEID-UNIQUE tests");
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
@ -212,6 +212,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
|
||||
torture_suite_add_1smb2_test(suite, "secleak", torture_smb2_sec_leak);
|
||||
torture_suite_add_1smb2_test(suite, "session-id", run_sessidtest);
|
||||
torture_suite_add_suite(suite, torture_smb2_deny_init(suite));
|
||||
torture_suite_add_suite(suite, torture_smb2_fileid_unique_init(suite));
|
||||
|
||||
suite->description = talloc_strdup(suite, "SMB2-specific tests");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user