1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

smbtorture: add subtests for overwrite dispositions vs sharemodes

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 849afe05ad)
This commit is contained in:
Ralph Boehme 2024-10-02 14:08:36 +02:00 committed by Jule Anger
parent 88caf2c091
commit 66c09de1f3
2 changed files with 108 additions and 2 deletions

View File

@ -0,0 +1 @@
^samba3.smb2.acls.OVERWRITE_READ_ONLY_FILE

View File

@ -2994,8 +2994,10 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
{ {
NTSTATUS status; NTSTATUS status;
struct smb2_create c = {}; struct smb2_create c = {};
struct smb2_create c2 = {};
const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt"; const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt";
struct smb2_handle handle = {{0}}; struct smb2_handle handle = {{0}};
struct smb2_handle h2 = {};
union smb_fileinfo q; union smb_fileinfo q;
union smb_setfileinfo set; union smb_setfileinfo set;
struct security_descriptor *sd = NULL, *sd_orig = NULL; struct security_descriptor *sd = NULL, *sd_orig = NULL;
@ -3021,6 +3023,12 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_ACCESS_DENIED), TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_ACCESS_DENIED),
TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_ACCESS_DENIED), TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_ACCESS_DENIED),
}; };
struct tcase sharing_tcases[] = {
TCASE(NTCREATEX_DISP_SUPERSEDE, NT_STATUS_SHARING_VIOLATION),
TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_SHARING_VIOLATION),
TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_SHARING_VIOLATION),
};
#undef TCASE #undef TCASE
ret = smb2_util_setup_dir(tctx, tree, BASEDIR); ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
@ -3124,11 +3132,108 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_setinfo_file failed\n"); "smb2_setinfo_file failed\n");
smb2_util_close(tree, handle); status = smb2_util_close(tree, handle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_util_close failed\n");
ZERO_STRUCT(handle); ZERO_STRUCT(handle);
for (i = 0; i < ARRAY_SIZE(sharing_tcases); i++) {
struct tcase *tcase = &sharing_tcases[i];
torture_comment(tctx, "Verify %s disposition\n",
tcase->disposition_string);
torture_comment(tctx, "Read-nonly open file with SHARE_READ\n");
c = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_DATA,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
.in.create_disposition = NTCREATEX_DISP_OPEN_IF,
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
.in.fname = fname,
};
status = smb2_create(tree, tctx, &c);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_create failed\n");
handle = c.out.file.handle;
torture_comment(tctx, "A second open with %s must return %s\n",
tcase->disposition_string, nt_errstr(tcase->expected_status));
c2 = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_DATA,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
.in.create_disposition = tcase->disposition,
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
.in.fname = fname,
};
status = smb2_create(tree, tctx, &c2);
torture_assert_ntstatus_equal_goto(tctx, status,
tcase->expected_status,
ret, done,
"Wrong status code\n");
status = smb2_util_close(tree, handle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_util_close failed\n");
ZERO_STRUCT(handle);
torture_comment(tctx, "First open with %s\n",
tcase->disposition_string);
c = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_DATA,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
.in.create_disposition = tcase->disposition,
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
.in.fname = fname,
};
status = smb2_create(tree, tctx, &c);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_create failed\n");
handle = c.out.file.handle;
torture_comment(tctx, "A second read-only open with SHARE_READ "
"must work\n");
c = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_DATA,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
.in.create_disposition = NTCREATEX_DISP_OPEN,
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
.in.fname = fname,
};
status = smb2_create(tree, tctx, &c);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_create failed\n");
h2 = c.out.file.handle;
status = smb2_util_close(tree, handle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_util_close failed\n");
ZERO_STRUCT(handle);
status = smb2_util_close(tree, h2);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_util_close failed\n");
ZERO_STRUCT(h2);
}
done: done:
smb2_util_close(tree, handle); if (!smb2_util_handle_empty(handle)) {
smb2_util_close(tree, handle);
}
if (!smb2_util_handle_empty(h2)) {
smb2_util_close(tree, h2);
}
smb2_util_unlink(tree, fname); smb2_util_unlink(tree, fname);
smb2_deltree(tree, BASEDIR); smb2_deltree(tree, BASEDIR);
return ret; return ret;