The branch, master has been updated
       via  6140c3177a0 smbd: fix share access check for overwrite dispostions
       via  849afe05ade smbtorture: add subtests for overwrite dispositions vs 
sharemodes
       via  4591f27ca81 smbtorture: fix smb2.notify.mask test
       via  f88e52a6f48 smbtorture: prepare test_overwrite_read_only_file() for 
more subtests
      from  1428519372b tests: add test for cli_get_posix_fs_info

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 6140c3177a0330f42411618c3fca28930ea02a21
Author: Ralph Boehme <[email protected]>
Date:   Wed Oct 2 14:09:33 2024 +0200

    smbd: fix share access check for overwrite dispostions
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>
    
    Autobuild-User(master): Ralph Böhme <[email protected]>
    Autobuild-Date(master): Mon Oct 14 12:23:04 UTC 2024 on atb-devel-224

commit 849afe05ade140898b1eab9b28d46edc8357c844
Author: Ralph Boehme <[email protected]>
Date:   Wed Oct 2 14:08:36 2024 +0200

    smbtorture: add subtests for overwrite dispositions vs sharemodes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 4591f27ca81dff997ef7474565fc9c373abfa4a9
Author: Ralph Boehme <[email protected]>
Date:   Wed Oct 2 18:17:17 2024 +0200

    smbtorture: fix smb2.notify.mask test
    
    The strange function custom_smb2_create() was somehow causing
    NT_STATUS_DELETE_PENDING failures:
    
      failure: mask [
      (../../source4/torture/smb2/notify.c:490) Incorrect status 
NT_STATUS_DELETE_PENDING - should be NT_STATUS_OK
      ]
    
    I couldn't figure out what was causing this exactly, but after doing these
    cleanups the error went away.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit f88e52a6f487a216dbb805fabc08e862abb9b643
Author: Ralph Boehme <[email protected]>
Date:   Wed Oct 2 14:07:49 2024 +0200

    smbtorture: prepare test_overwrite_read_only_file() for more subtests
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/open.c           |   6 +-
 source4/torture/smb2/acls.c   | 124 +++++++++++++++++++++++++++++++++++++++---
 source4/torture/smb2/notify.c |  34 +++++-------
 3 files changed, 135 insertions(+), 29 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 33554fcee13..f132587fb8c 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3389,6 +3389,7 @@ static NTSTATUS check_and_store_share_mode(
        struct share_mode_lock *lck,
        uint32_t create_disposition,
        uint32_t access_mask,
+       uint32_t open_access_mask,
        uint32_t share_access,
        int oplock_request,
        const struct smb2_lease *lease,
@@ -3415,7 +3416,7 @@ static NTSTATUS check_and_store_share_mode(
        status = handle_share_mode_lease(fsp,
                                         lck,
                                         create_disposition,
-                                        access_mask,
+                                        open_access_mask,
                                         share_access,
                                         oplock_request,
                                         lease,
@@ -3745,6 +3746,7 @@ struct open_ntcreate_lock_state {
        struct smb_request *req;
        uint32_t create_disposition;
        uint32_t access_mask;
+       uint32_t open_access_mask;
        uint32_t share_access;
        int oplock_request;
        const struct smb2_lease *lease;
@@ -3773,6 +3775,7 @@ static void open_ntcreate_lock_add_entry(struct 
share_mode_lock *lck,
                                                   lck,
                                                   state->create_disposition,
                                                   state->access_mask,
+                                                  state->open_access_mask,
                                                   state->share_access,
                                                   state->oplock_request,
                                                   state->lease,
@@ -4407,6 +4410,7 @@ static NTSTATUS open_file_ntcreate(connection_struct 
*conn,
                .req                    = req,
                .create_disposition     = create_disposition,
                .access_mask            = access_mask,
+               .open_access_mask       = open_access_mask,
                .share_access           = share_access,
                .oplock_request         = oplock_request,
                .lease                  = lease,
diff --git a/source4/torture/smb2/acls.c b/source4/torture/smb2/acls.c
index 019886ebcd2..0459d6547dc 100644
--- a/source4/torture/smb2/acls.c
+++ b/source4/torture/smb2/acls.c
@@ -2993,9 +2993,11 @@ static bool test_overwrite_read_only_file(struct 
torture_context *tctx,
                                          struct smb2_tree *tree)
 {
        NTSTATUS status;
-       struct smb2_create c;
+       struct smb2_create c = {};
+       struct smb2_create c2 = {};
        const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt";
        struct smb2_handle handle = {{0}};
+       struct smb2_handle h2 = {};
        union smb_fileinfo q;
        union smb_setfileinfo set;
        struct security_descriptor *sd = NULL, *sd_orig = NULL;
@@ -3007,17 +3009,26 @@ static bool test_overwrite_read_only_file(struct 
torture_context *tctx,
                int disposition;
                const char *disposition_string;
                NTSTATUS expected_status;
-       } tcases[] = {
+       };
+
 #define TCASE(d, s) {                          \
                .disposition = d,               \
                .disposition_string = #d,       \
                .expected_status = s,           \
        }
+
+       struct tcase fs_tcases[] = {
                TCASE(NTCREATEX_DISP_OPEN, NT_STATUS_OK),
                TCASE(NTCREATEX_DISP_SUPERSEDE, NT_STATUS_ACCESS_DENIED),
                TCASE(NTCREATEX_DISP_OVERWRITE, 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
 
        ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
@@ -3075,12 +3086,12 @@ static bool test_overwrite_read_only_file(struct 
torture_context *tctx,
        smb2_util_close(tree, handle);
        ZERO_STRUCT(handle);
 
-       for (i = 0; i < ARRAY_SIZE(tcases); i++) {
+       for (i = 0; i < ARRAY_SIZE(fs_tcases); i++) {
                torture_comment(tctx, "Verify open with %s disposition\n",
-                               tcases[i].disposition_string);
+                               fs_tcases[i].disposition_string);
 
                c = (struct smb2_create) {
-                       .in.create_disposition = tcases[i].disposition,
+                       .in.create_disposition = fs_tcases[i].disposition,
                        .in.desired_access = SEC_FILE_READ_DATA,
                        .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
                        .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
@@ -3091,7 +3102,7 @@ static bool test_overwrite_read_only_file(struct 
torture_context *tctx,
                status = smb2_create(tree, tctx, &c);
                smb2_util_close(tree, c.out.file.handle);
                torture_assert_ntstatus_equal_goto(
-                       tctx, status, tcases[i].expected_status, ret, done,
+                       tctx, status, fs_tcases[i].expected_status, ret, done,
                        "smb2_create failed\n");
        };
 
@@ -3121,11 +3132,108 @@ static bool test_overwrite_read_only_file(struct 
torture_context *tctx,
        torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                        "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);
 
+       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:
-       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_deltree(tree, BASEDIR);
        return ret;
diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c
index 0aadc50c607..b76cb7967aa 100644
--- a/source4/torture/smb2/notify.c
+++ b/source4/torture/smb2/notify.c
@@ -944,6 +944,7 @@ static bool torture_smb2_notify_mask(struct torture_context 
*torture,
                               notify.smb2.out.changes[0].action, \
                               notify.smb2.in.completion_filter); \
                        ret = false; \
+                       goto done; \
                } else if (notify.smb2.out.changes[0].action != Action) { \
                        torture_result(torture, TORTURE_FAIL, \
                               "ERROR: nchanges=%d action=%d " \
@@ -953,6 +954,7 @@ static bool torture_smb2_notify_mask(struct torture_context 
*torture,
                               Action, \
                               notify.smb2.in.completion_filter); \
                        ret = false; \
+                       goto done; \
                } else if (strcmp(notify.smb2.out.changes[0].name.s, \
                           "tname1") != 0) { \
                        torture_result(torture, TORTURE_FAIL, \
@@ -963,6 +965,7 @@ static bool torture_smb2_notify_mask(struct torture_context 
*torture,
                               notify.smb2.in.completion_filter, \
                               notify.smb2.out.changes[0].name.s);      \
                        ret = false; \
+                       goto done; \
                } \
        } \
        } while (0); \
@@ -1016,14 +1019,12 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
        torture_comment(torture, "Testing rename file\n");
        ZERO_STRUCT(sinfo);
        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
-       sinfo.rename_information.in.file.handle = h1;
        sinfo.rename_information.in.overwrite = true;
        sinfo.rename_information.in.root_fid = 0;
        sinfo.rename_information.in.new_name = BASEDIR_MSK "\\tname2";
        NOTIFY_MASK_TEST("Testing rename file",
-                        smb2_util_close(tree2, custom_smb2_create(tree2,
-                                               torture, &(io1.smb2)));,
-                        smb2_setinfo_file(tree2, &sinfo);,
+                        torture_smb2_testfile(tree2, BASEDIR_MSK "\\tname1", 
&h2);,
+                        (sinfo.rename_information.in.file.handle = h2, 
smb2_setinfo_file(tree2, &sinfo));,
                         smb2_util_unlink(tree2, BASEDIR_MSK "\\tname2");,
                         NOTIFY_ACTION_OLD_NAME,
                         FILE_NOTIFY_CHANGE_FILE_NAME, 2);
@@ -1031,21 +1032,19 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
        torture_comment(torture, "Testing rename dir\n");
        ZERO_STRUCT(sinfo);
        sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
-       sinfo.rename_information.in.file.handle = h1;
        sinfo.rename_information.in.overwrite = true;
        sinfo.rename_information.in.root_fid = 0;
        sinfo.rename_information.in.new_name = BASEDIR_MSK "\\tname2";
        NOTIFY_MASK_TEST("Testing rename dir",
-               smb2_util_mkdir(tree2, BASEDIR_MSK "\\tname1");,
-               smb2_setinfo_file(tree2, &sinfo);,
-               smb2_util_rmdir(tree2, BASEDIR_MSK "\\tname2");,
+               torture_smb2_testdir(tree2, BASEDIR_MSK "\\tname1", &h2);,
+               (sinfo.rename_information.in.file.handle = h2, 
smb2_setinfo_file(tree2, &sinfo));,
+               (smb2_util_close(tree2, h2), smb2_util_rmdir(tree2, BASEDIR_MSK 
"\\tname2"));,
                NOTIFY_ACTION_OLD_NAME,
                FILE_NOTIFY_CHANGE_DIR_NAME, 2);
 
        torture_comment(torture, "Testing set path attribute\n");
        NOTIFY_MASK_TEST("Testing set path attribute",
-               smb2_util_close(tree2, custom_smb2_create(tree2,
-                                      torture, &(io.smb2)));,
+               torture_setup_simple_file(torture, tree2, BASEDIR_MSK 
"\\tname1");,
                smb2_util_setatr(tree2, BASEDIR_MSK "\\tname1",
                                 FILE_ATTRIBUTE_HIDDEN);,
                smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1");,
@@ -1055,12 +1054,10 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
        torture_comment(torture, "Testing set path write time\n");
        ZERO_STRUCT(sinfo);
        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
-       sinfo.generic.in.file.handle = h1;
        sinfo.basic_info.in.write_time = 1000;
        NOTIFY_MASK_TEST("Testing set path write time",
-               smb2_util_close(tree2, custom_smb2_create(tree2,
-                                      torture, &(io1.smb2)));,
-               smb2_setinfo_file(tree2, &sinfo);,
+               torture_setup_simple_file(torture, tree2, BASEDIR_MSK 
"\\tname1");,
+               (sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, 
&sinfo));,
                smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1");,
                NOTIFY_ACTION_MODIFIED,
                FILE_NOTIFY_CHANGE_LAST_WRITE, 1);
@@ -1073,13 +1070,12 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
        else {
                ZERO_STRUCT(sinfo);
                sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
-               sinfo.generic.in.file.handle = h1;
                sinfo.basic_info.in.create_time = 0;
                torture_comment(torture, "Testing set file create time\n");
                NOTIFY_MASK_TEST("Testing set file create time",
                        smb2_create_complex_file(torture, tree2,
                        BASEDIR_MSK "\\tname1", &h2);,
-                       smb2_setinfo_file(tree2, &sinfo);,
+                       (sinfo.generic.in.file.handle = h2, 
smb2_setinfo_file(tree2, &sinfo));,
                        (smb2_util_close(tree2, h2),
                         smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
                        NOTIFY_ACTION_MODIFIED,
@@ -1088,7 +1084,6 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
 
        ZERO_STRUCT(sinfo);
        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
-       sinfo.generic.in.file.handle = h1;
        sinfo.basic_info.in.access_time = 0;
        torture_comment(torture, "Testing set file access time\n");
        NOTIFY_MASK_TEST("Testing set file access time",
@@ -1096,7 +1091,7 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
                        tree2,
                        BASEDIR_MSK "\\tname1",
                        &h2);,
-               smb2_setinfo_file(tree2, &sinfo);,
+               (sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, 
&sinfo));,
                (smb2_util_close(tree2, h2),
                smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
                NOTIFY_ACTION_MODIFIED,
@@ -1104,7 +1099,6 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
 
        ZERO_STRUCT(sinfo);
        sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
-       sinfo.generic.in.file.handle = h1;
        sinfo.basic_info.in.change_time = 0;
        torture_comment(torture, "Testing set file change time\n");
        NOTIFY_MASK_TEST("Testing set file change time",
@@ -1112,7 +1106,7 @@ static bool torture_smb2_notify_mask(struct 
torture_context *torture,
                        tree2,
                        BASEDIR_MSK "\\tname1",
                        &h2);,
-               smb2_setinfo_file(tree2, &sinfo);,
+               (sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, 
&sinfo));,
                (smb2_util_close(tree2, h2),
                smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
                NOTIFY_ACTION_MODIFIED,


-- 
Samba Shared Repository

Reply via email to