From: Ralph Boehme Date: Wed, 1 Apr 2026 10:26:28 +0000 (+0200) Subject: smbtorture: add additional checks to smb2.maximum_allowed.read_only_file X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=878e7975de17b5c8218cb2c44b44d8a8fac4f073;p=thirdparty%2Fsamba.git smbtorture: add additional checks to smb2.maximum_allowed.read_only_file Prooves that: - the "MxAC" context response actually ignores FILE_ATTRIBUTE_READONLY, - actuall effective access rights honor FILE_ATTRIBUTE_READONLY (using RAW_FILEINFO_ACCESS_INFORMATION getinfo level), - attempting to write to a file with FILE_ATTRIBUTE_READONLY fails. Test passed against Windows, fails against both s3 and s4 servers. Skipping the ad_dc_ntvfs test in the future, I'm not going to fix that. BUG: https://bugzilla.samba.org/show_bug.cgi?id=16030 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- diff --git a/selftest/knownfail.d/smb2.maximum_allowed b/selftest/knownfail.d/smb2.maximum_allowed new file mode 100644 index 00000000000..7e29a84ab4f --- /dev/null +++ b/selftest/knownfail.d/smb2.maximum_allowed @@ -0,0 +1 @@ +^samba3.smb2.maximum_allowed.read_only_file\(.*\) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index d98a42d3b61..d82da700e6f 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -429,6 +429,7 @@ smb2_s3only = [ "smb2.ea", "smb2.create_no_streams", "smb2.streams", + "smb2.maximum_allowed", ] smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only] diff --git a/source4/torture/smb2/max_allowed.c b/source4/torture/smb2/max_allowed.c index bc4b75527fc..4f1a1ca3a40 100644 --- a/source4/torture/smb2/max_allowed.c +++ b/source4/torture/smb2/max_allowed.c @@ -228,6 +228,7 @@ static bool torture_smb2_read_only_file(struct torture_context *tctx, { struct smb2_create c; struct smb2_handle h = {{0}}; + union smb_fileinfo getinfo; bool ret = true; NTSTATUS status; @@ -252,6 +253,7 @@ static bool torture_smb2_read_only_file(struct torture_context *tctx, .in.file_attributes = FILE_ATTRIBUTE_READONLY, .in.create_disposition = NTCREATEX_DISP_OPEN, .in.fname = MAXIMUM_ALLOWED_FILE, + .in.query_maximal_access = true, }; status = smb2_create(tree, tctx, &c); @@ -259,6 +261,53 @@ static bool torture_smb2_read_only_file(struct torture_context *tctx, tctx, status, ret, done, "Failed to open READ-ONLY file with SEC_FLAG_MAXIMUM_ALLOWED\n"); h = c.out.file.handle; + + /* + * Verify maximum access from create context + */ + + torture_assert_u32_equal_goto(tctx, + c.out.maximal_access, + SEC_RIGHTS_FILE_ALL, + ret, done, + "Wrong maxaccess\n"); + + /* + * Verify actual access mask from infolevel + */ + + ZERO_STRUCT(getinfo); + getinfo.generic.level = RAW_FILEINFO_ACCESS_INFORMATION; + getinfo.generic.in.file.handle = h; + + status = smb2_getinfo_file(tree, tree, &getinfo); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, + "smb2_getinfo_file\n"); + + torture_assert_u32_equal_goto( + tctx, + getinfo.access_information.out.access_flags, + /* + * Use exactly the bits from MS-FSA 2.1.5.1.2.1 "Algorithm to + * Check Access to an Existing File" and note that + * SEC_FILE_APPEND_DATA = SEC_DIR_ADD_SUBDIR + */ + SEC_RIGHTS_FILE_ALL & ~( + SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_DIR_ADD_SUBDIR | + SEC_DIR_DELETE_CHILD + ), + ret, done, + "Bad access mask\n"); + + status = smb2_util_write(tree, h, "foo", 0, 3); + torture_assert_ntstatus_equal_goto(tctx, + status, + NT_STATUS_ACCESS_DENIED, + ret, done, + "smb2_getinfo_file\n"); + smb2_util_close(tree, h); ZERO_STRUCT(h);