TODO(finish): start of a smb2 shadow-copy test suite master-shadow_copy2-wip
authorMichael Adam <obnox@samba.org>
Tue, 13 Aug 2013 15:46:36 +0000 (17:46 +0200)
committerMichael Adam <obnox@samba.org>
Thu, 31 Oct 2013 13:44:24 +0000 (14:44 +0100)
source4/torture/smb2/shadow_copy.c [new file with mode: 0644]
source4/torture/smb2/smb2.c
source4/torture/smb2/wscript_build

diff --git a/source4/torture/smb2/shadow_copy.c b/source4/torture/smb2/shadow_copy.c
new file mode 100644 (file)
index 0000000..5ccabba
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   test suite for SMB2 shadow copy operations
+
+   Copyright (C) Michael Adam 2013
+
+   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 "librpc/gen_ndr/security.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "torture/torture.h"
+#include "torture/smb2/proto.h"
+#include "librpc/gen_ndr/ndr_ioctl.h"
+
+#define FNAME  "testfsctl.dat"
+#define FNAME2 "testfsctl2.dat"
+
+/**
+ * Open the share's base directory and get the shadow copy data.
+ */
+static bool test_shadow_copy_1(struct torture_context *torture,
+                              struct smb2_tree *tree)
+{
+       struct smb2_handle h;
+       NTSTATUS status;
+       union smb_ioctl ioctl;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
+       uint32_t num_volumes;
+       uint32_t num_labels;
+       uint32_t count;
+       uint32_t delivered_count;
+
+       status = smb2_util_roothandle(tree, &h);
+       torture_assert_ntstatus_ok(torture, status, "open root");
+
+       ZERO_STRUCT(ioctl);
+       ioctl.smb2.level = RAW_IOCTL_SMB2;
+       ioctl.smb2.in.file.handle = h;
+       ioctl.smb2.in.function = FSCTL_SRV_ENUM_SNAPS;
+       ioctl.smb2.in.max_response_size = 16;
+       ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+       status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST))
+       {
+               torture_skip(torture, "FSCTL_GET_SHADOW_COPY_DATA not supported\n");
+       }
+       torture_assert_ntstatus_ok(torture, status, "FSCTL_GET_SHADOW_COPY_DATA");
+
+       torture_assert(torture,
+                      (ioctl.smb2.out.out.length >= 12),
+                       "FSCTL_GET_SHADOW_COPY_DATA response: out data too small (header)");
+
+       num_volumes = IVAL(ioctl.smb2.out.out.data, 0);
+       num_labels = IVAL(ioctl.smb2.out.out.data, 4);
+       count = IVAL(ioctl.smb2.out.out.data, 8);
+
+       torture_assert(torture,
+                      (count == num_volumes * 2 * 25 + 2),
+                      "FSCTL_GET_SHADOW_COPY_DATA response: wrong count");
+
+       delivered_count = num_labels * 2 * 25 + 2;
+
+       torture_assert(torture,
+                      (ioctl.smb2.out.out.length >= 12 + delivered_count),
+                       "FSCTL_GET_SHADOW_COPY_DATA response: out data too small (labels)");
+
+       /*
+        * request again, with enough space now.
+        *
+        * TODO: alloc buffer ??
+        */
+
+       ZERO_STRUCT(ioctl);
+       ioctl.smb2.level = RAW_IOCTL_SMB2;
+       ioctl.smb2.in.file.handle = h;
+       ioctl.smb2.in.function = FSCTL_SRV_ENUM_SNAPS;
+       ioctl.smb2.in.max_response_size = 16 + count;
+       //ioctl.smb2.in.max_response_size = 16 + num_volumes * 2 * 25 + 2;
+       ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+       status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST))
+       {
+               torture_skip(torture, "FSCTL_GET_SHADOW_COPY_DATA not supported\n");
+       }
+       torture_assert_ntstatus_ok(torture, status, "FSCTL_GET_SHADOW_COPY_DATA");
+
+       torture_assert(torture,
+                      (ioctl.smb2.out.out.length >= 12),
+                       "FSCTL_GET_SHADOW_COPY_DATA response: out data too small (header)");
+
+       num_volumes = IVAL(ioctl.smb2.out.out.data, 0);
+       num_labels = IVAL(ioctl.smb2.out.out.data, 4);
+       count = IVAL(ioctl.smb2.out.out.data, 8);
+
+       torture_assert(torture,
+                      (num_volumes == num_labels),
+                      "FSCTL_GET_SHADOW_COPY_DATA response: wrong number of labels");
+
+       torture_assert(torture,
+                      (count == num_volumes * 2 * 25 + 2),
+                      "FSCTL_GET_SHADOW_COPY_DATA response: wrong count");
+
+       delivered_count = num_labels * 2 * 25 + 2;
+
+       torture_assert(torture,
+                      (ioctl.smb2.out.out.length >= 12 + delivered_count),
+                       "FSCTL_GET_SHADOW_COPY_DATA response: out data too small (labels)");
+
+       return true;
+}
+
+#if 0
+/**
+ */
+static bool test_shadow_copy_1(struct torture_context *torture,
+                              struct smb2_tree *tree)
+{
+       struct smb2_handle h;
+       uint8_t buf[100];
+       NTSTATUS status;
+       union smb_ioctl ioctl;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
+
+       smb2_util_unlink(tree, FNAME);
+
+       status = torture_smb2_testfile(tree, FNAME, &h);
+       torture_assert_ntstatus_ok(torture, status, "create write");
+
+       ZERO_ARRAY(buf);
+       status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
+       torture_assert_ntstatus_ok(torture, status, "write");
+
+       ZERO_STRUCT(ioctl);
+       ioctl.smb2.level = RAW_IOCTL_SMB2;
+       ioctl.smb2.in.file.handle = h;
+       ioctl.smb2.in.function = FSCTL_SRV_ENUM_SNAPS;
+       ioctl.smb2.in.max_response_size = 16;
+       ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+       status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)
+        || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
+               torture_skip(torture, "FSCTL_SRV_ENUM_SNAPS not supported\n");
+       }
+       torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_ENUM_SNAPS");
+
+       return true;
+}
+#endif
+
+/**
+ *  basic testing of SMB2 shadow copies
+ */
+struct torture_suite *torture_smb2_shadow_copy_init(void)
+{
+       struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "shadow-copy");
+
+       torture_suite_add_1smb2_test(suite, "shadow_copy_1",
+                                    test_shadow_copy_1);
+
+       suite->description = talloc_strdup(suite, "SMB2-SHADOW-COPY tests");
+
+       return suite;
+}
+
index 19d7e4ae92a70c4bb566007c7965032ec872495a..023cc2a2db3edfff7a177a285ad761eb1f764135 100644 (file)
@@ -170,6 +170,7 @@ NTSTATUS torture_smb2_init(void)
        torture_suite_add_suite(suite, torture_smb2_session_init());
 
        torture_suite_add_suite(suite, torture_smb2_doc_init());
+       torture_suite_add_suite(suite, torture_smb2_shadow_copy_init());
 
        suite->description = talloc_strdup(suite, "SMB2-specific tests");
 
index 42393c433dd088cce2db640cbb33664a71ab37ed..38019e4789430dd40b3e9620baa14ecb3faf850f 100644 (file)
@@ -4,7 +4,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2',
        source='''connect.c scan.c util.c getinfo.c setinfo.c lock.c notify.c
        smb2.c durable_open.c durable_v2_open.c oplock.c dir.c lease.c create.c
        acls.c read.c compound.c streams.c ioctl.c rename.c
-       session.c delete-on-close.c''',
+       session.c delete-on-close.c shadow_copy.c''',
        subsystem='smbtorture',
        deps='LIBCLI_SMB2 POPT_CREDENTIALS torture NDR_IOCTL',
        internal_module=True,