s4-torture: Add #defines required by the new tests
[metze/samba/wip.git] / source4 / torture / smb2 / multichannel.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * test SMB2 multichannel operations
5  *
6  * Copyright (C) Guenther Deschner, 2016
7  *
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.
12  *
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.
17  *
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/>.
20  */
21
22 #include "includes.h"
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"
32
33 #define BASEDIR "multichanneltestdir"
34
35 #define CHECK_STATUS(status, correct) \
36         torture_assert_ntstatus_equal_goto(tctx, status, correct,\
37                                            ret, done, "")
38
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); \
44                 ret = false; \
45                 goto done; \
46         } } while (0)
47
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); \
54                 ret = false; \
55                 goto done; \
56         } } while (0)
57
58 #define CHECK_CREATED(__io, __created, __attribute)                     \
59         do {                                                            \
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);                    \
66         } while (0)
67
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); \
73                 ret = false; \
74                 goto done; \
75         } } while (0)
76
77 #define CHECK_LEASE(__io, __state, __oplevel, __key, __flags)           \
78         do {                                                            \
79                 CHECK_VAL((__io)->out.lease_response.lease_version, 1); \
80                 if (__oplevel) {                                        \
81                         CHECK_VAL((__io)->out.oplock_level, \
82                                         SMB2_OPLOCK_LEVEL_LEASE); \
83                         CHECK_VAL((__io)->out.lease_response.lease_key.data[0],\
84                                   (__key)); \
85                         CHECK_VAL((__io)->out.lease_response.lease_key.data[1],\
86                                   ~(__key)); \
87                         CHECK_VAL((__io)->out.lease_response.lease_state,\
88                                   smb2_util_lease_state(__state)); \
89                 } else {                                                \
90                         CHECK_VAL((__io)->out.oplock_level,\
91                                   SMB2_OPLOCK_LEVEL_NONE); \
92                         CHECK_VAL((__io)->out.lease_response.lease_key.data[0],\
93                                   0); \
94                         CHECK_VAL((__io)->out.lease_response.lease_key.data[1],\
95                                   0); \
96                         CHECK_VAL((__io)->out.lease_response.lease_state, 0); \
97                 }                                                       \
98                                                                         \
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); \
102         } while (0)
103
104 static bool test_ioctl_network_interface_info(struct torture_context *tctx,
105                                               struct smb2_tree *tree,
106                                               struct fsctl_net_iface_info *info)
107 {
108         union smb_ioctl ioctl;
109         struct smb2_handle fh;
110         uint32_t caps;
111
112         caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
113         if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
114                 torture_skip(tctx,
115                             "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
116         }
117
118         ZERO_STRUCT(ioctl);
119
120         ioctl.smb2.level = RAW_IOCTL_SMB2;
121
122         fh.data[0] = UINT64_MAX;
123         fh.data[1] = UINT64_MAX;
124
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;
130
131         torture_assert_ntstatus_ok(tctx,
132                 smb2_ioctl(tree, tctx, &ioctl.smb2),
133                 "FSCTL_QUERY_NETWORK_INTERFACE_INFO failed");
134
135         torture_assert(tctx,
136                 (ioctl.smb2.out.out.length != 0),
137                 "no interface info returned???");
138
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");
143
144         if (DEBUGLVL(1)) {
145                 NDR_PRINT_DEBUG(fsctl_net_iface_info, info);
146         }
147
148         return true;
149 }
150
151 static bool test_multichannel_interface_info(struct torture_context *tctx,
152                                              struct smb2_tree *tree)
153 {
154         struct fsctl_net_iface_info info;
155
156         return test_ioctl_network_interface_info(tctx, tree, &info);
157 }
158
159 struct torture_suite *torture_smb2_multichannel_init(TALLOC_CTX *ctx)
160 {
161         struct torture_suite *suite = torture_suite_create(ctx, "multichannel");
162
163         torture_suite_add_1smb2_test(suite, "interface_info",
164                                      test_multichannel_interface_info);
165
166         suite->description = talloc_strdup(suite, "SMB2 Multichannel tests");
167
168         return suite;
169 }