s4: fix various warnings (not "const" related ones)
[sfrench/samba-autobuild/.git] / source4 / torture / smb2 / compound.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for SMB2 compounded requests
5
6    Copyright (C) Stefan Metzmacher 2009
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 "librpc/gen_ndr/security.h"
24 #include "libcli/smb2/smb2.h"
25 #include "libcli/smb2/smb2_calls.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28
29 #define CHECK_STATUS(status, correct) do { \
30         if (!NT_STATUS_EQUAL(status, correct)) { \
31                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
32                        nt_errstr(status), nt_errstr(correct)); \
33                 ret = false; \
34                 goto done; \
35         }} while (0)
36
37 static bool test_compound_related1(struct torture_context *tctx,
38                                    struct smb2_tree *tree)
39 {
40         struct smb2_handle hd;
41         struct smb2_create cr;
42         NTSTATUS status;
43         const char *fname = "compound_related1.dat";
44         struct smb2_close cl;
45         bool ret = true;
46         struct smb2_request *req[2];
47
48         smb2_transport_credits_ask_num(tree->session->transport, 2);
49
50         smb2_util_unlink(tree, fname);
51
52         smb2_transport_credits_ask_num(tree->session->transport, 1);
53
54         ZERO_STRUCT(cr);
55         cr.in.security_flags            = 0x00;
56         cr.in.oplock_level              = 0;
57         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
58         cr.in.create_flags              = 0x00000000;
59         cr.in.reserved                  = 0x00000000;
60         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
61         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
62         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
63                                           NTCREATEX_SHARE_ACCESS_WRITE |
64                                           NTCREATEX_SHARE_ACCESS_DELETE;
65         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
66         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
67                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
68                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
69                                           0x00200000;
70         cr.in.fname                     = fname;
71
72         smb2_transport_compound_start(tree->session->transport, 2);
73
74         req[0] = smb2_create_send(tree, &cr);
75
76         smb2_transport_compound_set_related(tree->session->transport, true);
77
78         hd.data[0] = UINT64_MAX;
79         hd.data[1] = UINT64_MAX;
80
81         ZERO_STRUCT(cl);
82         cl.in.file.handle = hd;
83         req[1] = smb2_close_send(tree, &cl);
84
85         status = smb2_create_recv(req[0], tree, &cr);
86         CHECK_STATUS(status, NT_STATUS_OK);
87         status = smb2_close_recv(req[1], &cl);
88         CHECK_STATUS(status, NT_STATUS_OK);
89
90         smb2_util_unlink(tree, fname);
91 done:
92         return ret;
93 }
94
95 static bool test_compound_related2(struct torture_context *tctx,
96                                    struct smb2_tree *tree)
97 {
98         struct smb2_handle hd;
99         struct smb2_create cr;
100         NTSTATUS status;
101         const char *fname = "compound_related2.dat";
102         struct smb2_close cl;
103         bool ret = true;
104         struct smb2_request *req[5];
105
106         smb2_transport_credits_ask_num(tree->session->transport, 5);
107
108         smb2_util_unlink(tree, fname);
109
110         smb2_transport_credits_ask_num(tree->session->transport, 1);
111
112         ZERO_STRUCT(cr);
113         cr.in.security_flags            = 0x00;
114         cr.in.oplock_level              = 0;
115         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
116         cr.in.create_flags              = 0x00000000;
117         cr.in.reserved                  = 0x00000000;
118         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
119         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
120         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
121                                           NTCREATEX_SHARE_ACCESS_WRITE |
122                                           NTCREATEX_SHARE_ACCESS_DELETE;
123         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
124         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
125                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
126                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
127                                           0x00200000;
128         cr.in.fname                     = fname;
129
130         smb2_transport_compound_start(tree->session->transport, 5);
131
132         req[0] = smb2_create_send(tree, &cr);
133
134         hd.data[0] = UINT64_MAX;
135         hd.data[1] = UINT64_MAX;
136
137         smb2_transport_compound_set_related(tree->session->transport, true);
138
139         ZERO_STRUCT(cl);
140         cl.in.file.handle = hd;
141         req[1] = smb2_close_send(tree, &cl);
142         req[2] = smb2_close_send(tree, &cl);
143         req[3] = smb2_close_send(tree, &cl);
144         req[4] = smb2_close_send(tree, &cl);
145
146         status = smb2_create_recv(req[0], tree, &cr);
147         CHECK_STATUS(status, NT_STATUS_OK);
148         status = smb2_close_recv(req[1], &cl);
149         CHECK_STATUS(status, NT_STATUS_OK);
150         status = smb2_close_recv(req[2], &cl);
151         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
152         status = smb2_close_recv(req[3], &cl);
153         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
154         status = smb2_close_recv(req[4], &cl);
155         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
156
157         smb2_util_unlink(tree, fname);
158 done:
159         return ret;
160 }
161
162 static bool test_compound_unrelated1(struct torture_context *tctx,
163                                      struct smb2_tree *tree)
164 {
165         struct smb2_handle hd;
166         struct smb2_create cr;
167         NTSTATUS status;
168         const char *fname = "compound_unrelated1.dat";
169         struct smb2_close cl;
170         bool ret = true;
171         struct smb2_request *req[5];
172
173         smb2_transport_credits_ask_num(tree->session->transport, 5);
174
175         smb2_util_unlink(tree, fname);
176
177         smb2_transport_credits_ask_num(tree->session->transport, 1);
178
179         ZERO_STRUCT(cr);
180         cr.in.security_flags            = 0x00;
181         cr.in.oplock_level              = 0;
182         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
183         cr.in.create_flags              = 0x00000000;
184         cr.in.reserved                  = 0x00000000;
185         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
186         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
187         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
188                                           NTCREATEX_SHARE_ACCESS_WRITE |
189                                           NTCREATEX_SHARE_ACCESS_DELETE;
190         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
191         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
192                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
193                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
194                                           0x00200000;
195         cr.in.fname                     = fname;
196
197         smb2_transport_compound_start(tree->session->transport, 5);
198
199         req[0] = smb2_create_send(tree, &cr);
200
201         hd.data[0] = UINT64_MAX;
202         hd.data[1] = UINT64_MAX;
203
204         ZERO_STRUCT(cl);
205         cl.in.file.handle = hd;
206         req[1] = smb2_close_send(tree, &cl);
207         req[2] = smb2_close_send(tree, &cl);
208         req[3] = smb2_close_send(tree, &cl);
209         req[4] = smb2_close_send(tree, &cl);
210
211         status = smb2_create_recv(req[0], tree, &cr);
212         CHECK_STATUS(status, NT_STATUS_OK);
213         status = smb2_close_recv(req[1], &cl);
214         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
215         status = smb2_close_recv(req[2], &cl);
216         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
217         status = smb2_close_recv(req[3], &cl);
218         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
219         status = smb2_close_recv(req[4], &cl);
220         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
221
222         smb2_util_unlink(tree, fname);
223 done:
224         return ret;
225 }
226
227 static bool test_compound_invalid1(struct torture_context *tctx,
228                                    struct smb2_tree *tree)
229 {
230         struct smb2_handle hd;
231         struct smb2_create cr;
232         NTSTATUS status;
233         const char *fname = "compound_invalid1.dat";
234         struct smb2_close cl;
235         bool ret = true;
236         struct smb2_request *req[2];
237
238         smb2_transport_credits_ask_num(tree->session->transport, 2);
239
240         smb2_util_unlink(tree, fname);
241
242         smb2_transport_credits_ask_num(tree->session->transport, 1);
243
244         ZERO_STRUCT(cr);
245         cr.in.security_flags            = 0x00;
246         cr.in.oplock_level              = 0;
247         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
248         cr.in.create_flags              = 0x00000000;
249         cr.in.reserved                  = 0x00000000;
250         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
251         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
252         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
253                                           NTCREATEX_SHARE_ACCESS_WRITE |
254                                           NTCREATEX_SHARE_ACCESS_DELETE;
255         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
256         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
257                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
258                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
259                                           0x00200000;
260         cr.in.fname                     = fname;
261
262         smb2_transport_compound_start(tree->session->transport, 2);
263
264         /* passing the first request with the related flag is invalid */
265         smb2_transport_compound_set_related(tree->session->transport, true);
266
267         req[0] = smb2_create_send(tree, &cr);
268
269         hd.data[0] = UINT64_MAX;
270         hd.data[1] = UINT64_MAX;
271
272         ZERO_STRUCT(cl);
273         cl.in.file.handle = hd;
274         req[1] = smb2_close_send(tree, &cl);
275
276         status = smb2_create_recv(req[0], tree, &cr);
277         /* TODO: check why this fails with --signing=required */
278         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
279         status = smb2_close_recv(req[1], &cl);
280         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
281
282         smb2_util_unlink(tree, fname);
283 done:
284         return ret;
285 }
286
287 static bool test_compound_invalid2(struct torture_context *tctx,
288                                    struct smb2_tree *tree)
289 {
290         struct smb2_handle hd;
291         struct smb2_create cr;
292         NTSTATUS status;
293         const char *fname = "compound_invalid2.dat";
294         struct smb2_close cl;
295         bool ret = true;
296         struct smb2_request *req[5];
297
298         smb2_transport_credits_ask_num(tree->session->transport, 5);
299
300         smb2_util_unlink(tree, fname);
301
302         smb2_transport_credits_ask_num(tree->session->transport, 1);
303
304         ZERO_STRUCT(cr);
305         cr.in.security_flags            = 0x00;
306         cr.in.oplock_level              = 0;
307         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
308         cr.in.create_flags              = 0x00000000;
309         cr.in.reserved                  = 0x00000000;
310         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
311         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
312         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
313                                           NTCREATEX_SHARE_ACCESS_WRITE |
314                                           NTCREATEX_SHARE_ACCESS_DELETE;
315         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
316         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
317                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
318                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
319                                           0x00200000;
320         cr.in.fname                     = fname;
321
322         smb2_transport_compound_start(tree->session->transport, 5);
323
324         req[0] = smb2_create_send(tree, &cr);
325
326         hd.data[0] = UINT64_MAX;
327         hd.data[1] = UINT64_MAX;
328
329         smb2_transport_compound_set_related(tree->session->transport, true);
330
331         ZERO_STRUCT(cl);
332         cl.in.file.handle = hd;
333         req[1] = smb2_close_send(tree, &cl);
334         /* strange that this is not generating invalid parameter */
335         smb2_transport_compound_set_related(tree->session->transport, false);
336         req[2] = smb2_close_send(tree, &cl);
337         req[3] = smb2_close_send(tree, &cl);
338         smb2_transport_compound_set_related(tree->session->transport, true);
339         req[4] = smb2_close_send(tree, &cl);
340
341         status = smb2_create_recv(req[0], tree, &cr);
342         CHECK_STATUS(status, NT_STATUS_OK);
343         status = smb2_close_recv(req[1], &cl);
344         CHECK_STATUS(status, NT_STATUS_OK);
345         status = smb2_close_recv(req[2], &cl);
346         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
347         status = smb2_close_recv(req[3], &cl);
348         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
349         status = smb2_close_recv(req[4], &cl);
350         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
351
352         smb2_util_unlink(tree, fname);
353 done:
354         return ret;
355 }
356
357 static bool test_compound_invalid3(struct torture_context *tctx,
358                                    struct smb2_tree *tree)
359 {
360         struct smb2_handle hd;
361         struct smb2_create cr;
362         NTSTATUS status;
363         const char *fname = "compound_invalid3.dat";
364         struct smb2_close cl;
365         bool ret = true;
366         struct smb2_request *req[5];
367
368         smb2_transport_credits_ask_num(tree->session->transport, 5);
369
370         smb2_util_unlink(tree, fname);
371
372         smb2_transport_credits_ask_num(tree->session->transport, 1);
373
374         ZERO_STRUCT(cr);
375         cr.in.security_flags            = 0x00;
376         cr.in.oplock_level              = 0;
377         cr.in.impersonation_level       = NTCREATEX_IMPERSONATION_IMPERSONATION;
378         cr.in.create_flags              = 0x00000000;
379         cr.in.reserved                  = 0x00000000;
380         cr.in.desired_access            = SEC_RIGHTS_FILE_ALL;
381         cr.in.file_attributes           = FILE_ATTRIBUTE_NORMAL;
382         cr.in.share_access              = NTCREATEX_SHARE_ACCESS_READ |
383                                           NTCREATEX_SHARE_ACCESS_WRITE |
384                                           NTCREATEX_SHARE_ACCESS_DELETE;
385         cr.in.create_disposition        = NTCREATEX_DISP_OPEN_IF;
386         cr.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
387                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
388                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
389                                           0x00200000;
390         cr.in.fname                     = fname;
391
392         smb2_transport_compound_start(tree->session->transport, 5);
393
394         req[0] = smb2_create_send(tree, &cr);
395
396         hd.data[0] = UINT64_MAX;
397         hd.data[1] = UINT64_MAX;
398
399         ZERO_STRUCT(cl);
400         cl.in.file.handle = hd;
401         req[1] = smb2_close_send(tree, &cl);
402         req[2] = smb2_close_send(tree, &cl);
403         /* flipping the related flag is invalid */
404         smb2_transport_compound_set_related(tree->session->transport, true);
405         req[3] = smb2_close_send(tree, &cl);
406         req[4] = smb2_close_send(tree, &cl);
407
408         status = smb2_create_recv(req[0], tree, &cr);
409         CHECK_STATUS(status, NT_STATUS_OK);
410         status = smb2_close_recv(req[1], &cl);
411         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
412         status = smb2_close_recv(req[2], &cl);
413         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
414         status = smb2_close_recv(req[3], &cl);
415         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
416         status = smb2_close_recv(req[4], &cl);
417         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
418
419         smb2_util_unlink(tree, fname);
420 done:
421         return ret;
422 }
423
424 struct torture_suite *torture_smb2_compound_init(void)
425 {
426         struct torture_suite *suite =
427             torture_suite_create(talloc_autofree_context(), "COMPOUND");
428
429         torture_suite_add_1smb2_test(suite, "RELATED1", test_compound_related1);
430         torture_suite_add_1smb2_test(suite, "RELATED2", test_compound_related2);
431         torture_suite_add_1smb2_test(suite, "UNRELATED1", test_compound_unrelated1);
432         torture_suite_add_1smb2_test(suite, "INVALID1", test_compound_invalid1);
433         torture_suite_add_1smb2_test(suite, "INVALID2", test_compound_invalid2);
434         torture_suite_add_1smb2_test(suite, "INVALID3", test_compound_invalid3);
435
436         suite->description = talloc_strdup(suite, "SMB2-COMPOUND tests");
437
438         return suite;
439 }