Convert samba4.base.rw1 test to smb2
authorDavid Mulder <dmulder@suse.com>
Tue, 10 Dec 2019 20:49:28 +0000 (13:49 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 20 Dec 2019 22:01:28 +0000 (22:01 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Ralph Böhme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source4/torture/smb2/read_write.c [new file with mode: 0644]
source4/torture/smb2/smb2.c
source4/torture/smb2/wscript_build

diff --git a/source4/torture/smb2/read_write.c b/source4/torture/smb2/read_write.c
new file mode 100644 (file)
index 0000000..bc8898c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+   Unix SMB/CIFS implementation.
+   SMB read/write torture tester
+   Copyright (C) Andrew Tridgell 1997-2003
+   Copyright (C) Jelmer Vernooij 2006
+   Copyright (C) David Mulder 2019
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "includes.h"
+#include "torture/smbtorture.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "torture/torture.h"
+#include "torture/smb2/proto.h"
+
+static bool run_smb2_readwritetest(struct torture_context *tctx,
+                                  struct smb2_tree *t1, struct smb2_tree *t2)
+{
+       const char *lockfname = "torture2.lck";
+       struct smb2_create f1 = {0};
+       struct smb2_create f2 = {0};
+       struct smb2_handle h1 = {{0}};
+       struct smb2_handle h2 = {{0}};
+       int i;
+       uint8_t buf[131072];
+       bool correct = true;
+       NTSTATUS status;
+       int ret = 0;
+
+       ret = smb2_deltree(t1, lockfname);
+       torture_assert(tctx, ret != -1, "unlink failed");
+
+       f1.in.desired_access = SEC_FILE_ALL;
+       f1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+                            NTCREATEX_SHARE_ACCESS_WRITE;
+       f1.in.create_disposition = FILE_CREATE;
+       f1.in.fname = lockfname;
+
+       status = smb2_create(t1, tctx, &f1);
+       torture_assert_ntstatus_ok_goto(tctx, status, correct, done,
+               talloc_asprintf(tctx, "first open read/write of %s failed (%s)",
+               lockfname, nt_errstr(status)));
+       h1 = f1.out.file.handle;
+
+       f2.in.desired_access = SEC_FILE_READ_DATA;
+       f2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+                            NTCREATEX_SHARE_ACCESS_WRITE;
+       f2.in.create_disposition = FILE_OPEN;
+       f2.in.fname = lockfname;
+
+       status = smb2_create(t2, tctx, &f2);
+       torture_assert_ntstatus_ok_goto(tctx, status, correct, done,
+               talloc_asprintf(tctx, "second open read-only of %s failed (%s)",
+               lockfname, nt_errstr(status)));
+       h2 = f2.out.file.handle;
+
+       torture_comment(tctx, "Checking data integrity over %d ops\n",
+                       torture_numops);
+
+       for (i = 0; i < torture_numops; i++) {
+               struct smb2_write w = {0};
+               struct smb2_read r = {0};
+               size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
+
+               if (i % 10 == 0) {
+                       if (torture_setting_bool(tctx, "progress", true)) {
+                               torture_comment(tctx, "%d\r", i); fflush(stdout);
+                       }
+               }
+
+               generate_random_buffer(buf, buf_size);
+
+               w.in.file.handle = h1;
+               w.in.offset = 0;
+               w.in.data.data = buf;
+               w.in.data.length = buf_size;
+
+               status = smb2_write(t1, &w);
+               if (!NT_STATUS_IS_OK(status) || w.out.nwritten != buf_size) {
+                       torture_comment(tctx, "write failed (%s)\n",
+                                       nt_errstr(status));
+                       torture_result(tctx, TORTURE_FAIL,
+                                      "wrote %d, expected %d\n",
+                                      (int)w.out.nwritten, (int)buf_size);
+                       correct = false;
+                       goto done;
+               }
+
+               r.in.file.handle = h2;
+               r.in.offset = 0;
+               r.in.length = buf_size;
+               status = smb2_read(t2, tctx, &r);
+               if (!NT_STATUS_IS_OK(status) || r.out.data.length != buf_size) {
+                       torture_comment(tctx, "read failed (%s)\n",
+                                       nt_errstr(status));
+                       torture_result(tctx, TORTURE_FAIL,
+                                      "read %d, expected %d\n",
+                                      (int)r.out.data.length, (int)buf_size);
+                       correct = false;
+                       goto done;
+               }
+
+               torture_assert_mem_equal_goto(tctx, r.out.data.data, buf,
+                       buf_size, correct, done, "read/write compare failed\n");
+       }
+
+       status = smb2_util_close(t2, h2);
+       torture_assert_ntstatus_ok_goto(tctx, status, correct, done,
+               talloc_asprintf(tctx, "close failed (%s)", nt_errstr(status)));
+       ZERO_STRUCT(h2);
+
+       status = smb2_util_close(t1, h1);
+       torture_assert_ntstatus_ok_goto(tctx, status, correct, done,
+               talloc_asprintf(tctx, "close failed (%s)", nt_errstr(status)));
+       ZERO_STRUCT(h1);
+
+done:
+       if (!smb2_util_handle_empty(h2)) {
+               smb2_util_close(t2, h2);
+       }
+       if (!smb2_util_handle_empty(h1)) {
+               smb2_util_close(t1, h1);
+       }
+
+       status = smb2_util_unlink(t1, lockfname);
+       if (!NT_STATUS_IS_OK(status)) {
+               torture_comment(tctx, "unlink failed (%s)", nt_errstr(status));
+       }
+
+       return correct;
+}
+
+
+static bool run_smb2_wrap_readwritetest(struct torture_context *tctx,
+                                       struct smb2_tree *tree1,
+                                       struct smb2_tree *tree2)
+{
+       return run_smb2_readwritetest(tctx, tree1, tree1);
+}
+
+struct torture_suite *torture_smb2_readwrite_init(TALLOC_CTX *ctx)
+{
+       struct torture_suite *suite = torture_suite_create(ctx, "rw");
+
+       torture_suite_add_2smb2_test(suite, "rw1", run_smb2_readwritetest);
+       torture_suite_add_2smb2_test(suite, "rw2", run_smb2_wrap_readwritetest);
+
+       suite->description = talloc_strdup(suite, "SMB2 Samba4 Read/Write");
+
+       return suite;
+}
index 4f42ffacf87635f97d75680ba2cc772f69036819..c258c15ff91c6a82435148996d5d645de5d655d9 100644 (file)
@@ -200,6 +200,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
        torture_suite_add_suite(suite, torture_smb2_timestamps_init(suite));
        torture_suite_add_1smb2_test(suite, "openattr", torture_smb2_openattrtest);
        torture_suite_add_1smb2_test(suite, "winattr", torture_smb2_winattrtest);
+       torture_suite_add_suite(suite, torture_smb2_readwrite_init(suite));
 
        suite->description = talloc_strdup(suite, "SMB2-specific tests");
 
index d1c2e04af7105090b9e21c81ca64d59f414ebfbe..873fcd603641bd067f27fccbf619e8c67142ca98 100644 (file)
@@ -27,6 +27,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2',
         notify_disabled.c
         oplock.c
         read.c
+        read_write.c
         rename.c
         replay.c
         scan.c