]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbtorture: DH reconnect with different user must fail with NT_STATUS_ACCESS_DENIED
authorRalph Boehme <slow@samba.org>
Fri, 8 Nov 2024 10:25:21 +0000 (11:25 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 6 Jun 2025 16:16:34 +0000 (16:16 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11122

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail.d/samba3.smb2.durable-open [new file with mode: 0644]
source3/selftest/tests.py
source4/torture/smb2/durable_open.c

diff --git a/selftest/knownfail.d/samba3.smb2.durable-open b/selftest/knownfail.d/samba3.smb2.durable-open
new file mode 100644 (file)
index 0000000..b6536e2
--- /dev/null
@@ -0,0 +1 @@
+^samba3.smb2.durable-open.reopen6\(nt4_dc\)
index cedcf97e994fdbee3c7564fa5a2255d2495300cd..008c444681c64d214deed8c9a2447d70bc686738 100755 (executable)
@@ -1239,7 +1239,8 @@ for t in tests:
     elif t == "rpc.mdssvc":
         plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
     elif t == "smb2.durable-open" or t == "smb2.durable-v2-open" or t == "smb2.replay" or t == "smb2.durable-v2-delay":
-        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
+        creds = " --option=torture:user2name=user1 --option=torture:user2password=$PASSWORD"
+        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD' + creds)
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
     elif t == "base.rw1":
         plansmbtorture4testsuite(t, "nt4_dc_smb1", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
index 4b6ca0570d2438d432242a29656a56b2b462a59e..2c5bc2224e6d4836c0dd546dcffde6d835f2d909 100644 (file)
 #include "../libcli/smb/smbXcli_base.h"
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
+#include "torture/util.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "lib/param/param.h"
+#include "libcli/resolve/resolve.h"
+#include "auth/credentials/credentials.h"
 
 #define CHECK_VAL(v, correct) \
        torture_assert_u64_equal_goto(tctx, v, correct, ret, done, __location__)
@@ -1694,6 +1698,100 @@ done:
        return ret;
 }
 
+/**
+ * basic test for doing a durable open:
+ * logoff, create a new session, do a durable reopen (fails with EACCESS)
+ */
+static bool test_durable_open_reopen6(struct torture_context *tctx,
+                                     struct smb2_tree *tree)
+{
+       const char *host = torture_setting_string(tctx, "host", NULL);
+       const char *share = torture_setting_string(tctx, "share", NULL);
+       struct cli_credentials *creds2 = torture_user2_credentials(tctx, tctx);
+       struct smbcli_options options = tree->session->transport->options;
+       struct smb2_tree *tree2 = NULL;
+       char fname[256];
+       struct smb2_handle h, d;
+       struct smb2_create c;
+       NTSTATUS status;
+       bool anon;
+       bool ret = true;
+
+       torture_assert(tctx, (creds2 != NULL), "talloc error");
+       anon = cli_credentials_is_anonymous(creds2);
+       if (anon) {
+               torture_skip(tctx, "valid user2 credentials are required");
+       }
+
+       /* Choose a random name in case the state is left a little funky. */
+       snprintf(fname, 256, "durable_open_reopen4_%s.dat",
+                generate_random_str(tctx, 8));
+
+       smb2_util_unlink(tree, fname);
+
+       smb2_oplock_create_share(&c, fname,
+                                smb2_util_share_access(""),
+                                smb2_util_oplock_level("b"));
+       c.in.durable_open = true;
+
+       status = smb2_create(tree, tree, &c);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       h = d = c.out.file.handle;
+
+       CHECK_CREATED(&c, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+       CHECK_VAL(c.out.durable_open, true);
+       CHECK_VAL(c.out.oplock_level, smb2_util_oplock_level("b"));
+
+       /* Disconnect */
+       TALLOC_FREE(tree);
+       ZERO_STRUCT(h);
+
+       /* Reconnect with a different user */
+       status = smb2_connect(tctx,
+                             host,
+                             share,
+                             tctx->lp_ctx,
+                             lpcfg_resolve_context(tctx->lp_ctx),
+                             creds2,
+                             &tree2,
+                             tctx->ev,
+                             &options,
+                             lpcfg_socket_options(tctx->lp_ctx),
+                             lpcfg_gensec_settings(tctx, tctx->lp_ctx)
+                             );
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_connect failed");
+
+       ZERO_STRUCT(c);
+       c.in.fname = fname;
+       c.in.durable_handle = &d;
+
+       status = smb2_create(tree2, tree2, &c);
+       torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED,
+                                          ret, done, "failed\n");
+
+       ret = torture_smb2_connection_ext(tctx, 0, &options, &tree);
+       torture_assert_goto(tctx, ret, ret, done,
+                           "torture_smb2_connection_ext failed\n");
+
+       status = smb2_create(tree, tree, &c);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_create failed\n");
+       h = c.out.file.handle;
+
+done:
+       if (tree != NULL) {
+               if (!smb2_util_handle_empty(h)) {
+                       smb2_util_close(tree, h);
+               }
+               smb2_util_unlink(tree, fname);
+               talloc_free(tree);
+       }
+
+       talloc_free(tree2);
+       return ret;
+}
+
 static bool test_durable_open_delete_on_close1(struct torture_context *tctx,
                                               struct smb2_tree *tree)
 {
@@ -3025,6 +3123,7 @@ struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx)
        torture_suite_add_1smb2_test(suite, "reopen3", test_durable_open_reopen3);
        torture_suite_add_1smb2_test(suite, "reopen4", test_durable_open_reopen4);
        torture_suite_add_1smb2_test(suite, "reopen5", test_durable_open_reopen5);
+       torture_suite_add_1smb2_test(suite, "reopen6", test_durable_open_reopen6);
        torture_suite_add_1smb2_test(suite, "delete_on_close1",
                                     test_durable_open_delete_on_close1);
        torture_suite_add_1smb2_test(suite, "delete_on_close2",