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