2 * Unix SMB/CIFS implementation.
4 * test SMB2 multichannel operations
6 * Copyright (C) Guenther Deschner, 2016
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/util.h"
27 #include "torture/smb2/proto.h"
28 #include "libcli/security/security.h"
29 #include "librpc/gen_ndr/ndr_security.h"
30 #include "librpc/gen_ndr/ndr_ioctl.h"
31 #include "../libcli/smb/smbXcli_base.h"
33 #define BASEDIR "multichanneltestdir"
35 #define CHECK_STATUS(status, correct) \
36 torture_assert_ntstatus_equal_goto(tctx, status, correct,\
39 #define CHECK_VAL(v, correct) do { \
40 if ((v) != (correct)) { \
41 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s" \
42 " got 0x%x - should be 0x%x\n", \
43 __location__, #v, (int)v, (int)correct); \
48 #define CHECK_VAL_GREATER_THAN(v, gt_val) do { \
49 if ((v) <= (gt_val)) { \
50 torture_result(tctx, TORTURE_FAIL, \
51 "(%s): wrong value for %s got 0x%x - " \
52 "should be greater than 0x%x\n", \
53 __location__, #v, (int)v, (int)gt_val); \
58 #define CHECK_CREATED(__io, __created, __attribute) \
60 CHECK_VAL((__io)->out.create_action, \
61 NTCREATEX_ACTION_ ## __created); \
62 CHECK_VAL((__io)->out.alloc_size, 0); \
63 CHECK_VAL((__io)->out.size, 0); \
64 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
65 CHECK_VAL((__io)->out.reserved2, 0); \
68 #define CHECK_PTR(ptr, correct) do { \
69 if ((ptr) != (correct)) { \
70 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s " \
71 "got 0x%p - should be 0x%p\n", \
72 __location__, #ptr, ptr, correct); \
77 #define CHECK_LEASE(__io, __state, __oplevel, __key, __flags) \
79 CHECK_VAL((__io)->out.lease_response.lease_version, 1); \
81 CHECK_VAL((__io)->out.oplock_level, \
82 SMB2_OPLOCK_LEVEL_LEASE); \
83 CHECK_VAL((__io)->out.lease_response.lease_key.data[0],\
85 CHECK_VAL((__io)->out.lease_response.lease_key.data[1],\
87 CHECK_VAL((__io)->out.lease_response.lease_state,\
88 smb2_util_lease_state(__state)); \
90 CHECK_VAL((__io)->out.oplock_level,\
91 SMB2_OPLOCK_LEVEL_NONE); \
92 CHECK_VAL((__io)->out.lease_response.lease_key.data[0],\
94 CHECK_VAL((__io)->out.lease_response.lease_key.data[1],\
96 CHECK_VAL((__io)->out.lease_response.lease_state, 0); \
99 CHECK_VAL((__io)->out.lease_response.lease_flags, (__flags)); \
100 CHECK_VAL((__io)->out.lease_response.lease_duration, 0); \
101 CHECK_VAL((__io)->out.lease_response.lease_epoch, 0); \
104 static bool test_ioctl_network_interface_info(struct torture_context *tctx,
105 struct smb2_tree *tree,
106 struct fsctl_net_iface_info *info)
108 union smb_ioctl ioctl;
109 struct smb2_handle fh;
112 caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
113 if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
115 "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
120 ioctl.smb2.level = RAW_IOCTL_SMB2;
122 fh.data[0] = UINT64_MAX;
123 fh.data[1] = UINT64_MAX;
125 ioctl.smb2.in.file.handle = fh;
126 ioctl.smb2.in.function = FSCTL_QUERY_NETWORK_INTERFACE_INFO;
127 /* Windows client sets this to 64KiB */
128 ioctl.smb2.in.max_output_response = 0x10000;
129 ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
131 torture_assert_ntstatus_ok(tctx,
132 smb2_ioctl(tree, tctx, &ioctl.smb2),
133 "FSCTL_QUERY_NETWORK_INTERFACE_INFO failed");
136 (ioctl.smb2.out.out.length != 0),
137 "no interface info returned???");
139 torture_assert_ndr_success(tctx,
140 ndr_pull_struct_blob(&ioctl.smb2.out.out, tctx, info,
141 (ndr_pull_flags_fn_t)ndr_pull_fsctl_net_iface_info),
142 "failed to ndr pull");
145 NDR_PRINT_DEBUG(fsctl_net_iface_info, info);
151 static bool test_multichannel_interface_info(struct torture_context *tctx,
152 struct smb2_tree *tree)
154 struct fsctl_net_iface_info info;
156 return test_ioctl_network_interface_info(tctx, tree, &info);
159 struct torture_suite *torture_smb2_multichannel_init(TALLOC_CTX *ctx)
161 struct torture_suite *suite = torture_suite_create(ctx, "multichannel");
163 torture_suite_add_1smb2_test(suite, "interface_info",
164 test_multichannel_interface_info);
166 suite->description = talloc_strdup(suite, "SMB2 Multichannel tests");