torture: skip FSCTL_SRV_ENUM_SNAPS test when not supported
[Samba/gbeck.git] / source4 / torture / smb2 / ioctl.c
blob8c949ef3009e763fdd10930a18d458bbf972cd30
1 /*
2 Unix SMB/CIFS implementation.
4 test suite for SMB2 ioctl operations
6 Copyright (C) David Disseldorp 2011
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 "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 #include "librpc/gen_ndr/ndr_ioctl.h"
30 #define FNAME "testfsctl.dat"
31 #define FNAME2 "testfsctl2.dat"
34 basic testing of SMB2 shadow copy calls
36 static bool test_ioctl_get_shadow_copy(struct torture_context *torture,
37 struct smb2_tree *tree)
39 struct smb2_handle h;
40 uint8_t buf[100];
41 NTSTATUS status;
42 union smb_ioctl ioctl;
43 TALLOC_CTX *tmp_ctx = talloc_new(tree);
45 smb2_util_unlink(tree, FNAME);
47 status = torture_smb2_testfile(tree, FNAME, &h);
48 torture_assert_ntstatus_ok(torture, status, "create write");
50 ZERO_ARRAY(buf);
51 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
52 torture_assert_ntstatus_ok(torture, status, "write");
54 ZERO_STRUCT(ioctl);
55 ioctl.smb2.level = RAW_IOCTL_SMB2;
56 ioctl.smb2.in.file.handle = h;
57 ioctl.smb2.in.function = FSCTL_SRV_ENUM_SNAPS;
58 ioctl.smb2.in.max_response_size = 16;
59 ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
61 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
62 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)
63 || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
64 torture_comment(torture,
65 "FSCTL_SRV_ENUM_SNAPS not supported, skipping\n");
66 return true;
68 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_ENUM_SNAPS");
70 return true;
74 basic testing of the SMB2 server side copy ioctls
76 static bool test_ioctl_req_resume_key(struct torture_context *torture,
77 struct smb2_tree *tree)
79 struct smb2_handle h;
80 uint8_t buf[100];
81 NTSTATUS status;
82 union smb_ioctl ioctl;
83 TALLOC_CTX *tmp_ctx = talloc_new(tree);
84 struct req_resume_key_rsp res_key;
85 enum ndr_err_code ndr_ret;
87 smb2_util_unlink(tree, FNAME);
89 status = torture_smb2_testfile(tree, FNAME, &h);
90 torture_assert_ntstatus_ok(torture, status, "create write");
92 ZERO_ARRAY(buf);
93 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
94 torture_assert_ntstatus_ok(torture, status, "write");
96 ZERO_STRUCT(ioctl);
97 ioctl.smb2.level = RAW_IOCTL_SMB2;
98 ioctl.smb2.in.file.handle = h;
99 ioctl.smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
100 ioctl.smb2.in.max_response_size = 32;
101 ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
103 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
104 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_REQUEST_RESUME_KEY");
106 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx, &res_key,
107 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
108 torture_assert_ndr_success(torture, ndr_ret,
109 "ndr_pull_req_resume_key_rsp");
111 ndr_print_debug((ndr_print_fn_t)ndr_print_req_resume_key_rsp, "yo", &res_key);
113 talloc_free(tmp_ctx);
114 return true;
117 static uint64_t patt_hash(uint64_t off)
119 return off;
122 static bool check_pattern(struct torture_context *torture,
123 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
124 struct smb2_handle h, uint64_t off, uint64_t len,
125 uint64_t patt_off)
127 uint64_t i;
128 struct smb2_read r;
129 NTSTATUS status;
131 ZERO_STRUCT(r);
132 r.in.file.handle = h;
133 r.in.length = len;
134 r.in.offset = off;
135 status = smb2_read(tree, mem_ctx, &r);
136 torture_assert_ntstatus_ok(torture, status, "read");
138 torture_assert_u64_equal(torture, r.out.data.length, len,
139 "read data len mismatch");
141 for (i = 0; i <= len - 8; i += 8, patt_off += 8) {
142 uint64_t data = BVAL(r.out.data.data, i);
143 torture_assert_u64_equal(torture, data, patt_hash(patt_off),
144 talloc_asprintf(torture, "read data "
145 "pattern bad at %llu\n",
146 (unsigned long long)i));
149 talloc_free(r.out.data.data);
150 return true;
153 static bool test_setup_copy_chunk(struct torture_context *torture,
154 struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
155 uint32_t nchunks,
156 struct smb2_handle *src_h,
157 uint64_t src_size,
158 struct smb2_handle *dest_h,
159 uint64_t dest_size,
160 struct srv_copychunk_copy *cc_copy,
161 union smb_ioctl *ioctl)
163 struct req_resume_key_rsp res_key;
164 NTSTATUS status;
165 enum ndr_err_code ndr_ret;
166 uint64_t i;
167 uint8_t *buf = talloc_zero_size(mem_ctx, MAX(src_size, dest_size));
168 if (buf == NULL) {
169 printf("no mem for file data buffer\n");
170 return false;
173 smb2_util_unlink(tree, FNAME);
174 smb2_util_unlink(tree, FNAME2);
176 status = torture_smb2_testfile(tree, FNAME, src_h);
177 torture_assert_ntstatus_ok(torture, status, "create write");
179 if (src_size > 0) {
180 for (i = 0; i <= src_size - 8; i += 8) {
181 SBVAL(buf, i, patt_hash(i));
183 status = smb2_util_write(tree, *src_h, buf, 0, src_size);
184 torture_assert_ntstatus_ok(torture, status, "src write");
187 status = torture_smb2_testfile(tree, FNAME2, dest_h);
188 torture_assert_ntstatus_ok(torture, status, "create write");
190 if (dest_size > 0) {
191 for (i = 0; i <= dest_size - 8; i += 8) {
192 SBVAL(buf, i, patt_hash(i));
194 status = smb2_util_write(tree, *dest_h, buf, 0, dest_size);
195 torture_assert_ntstatus_ok(torture, status, "dest write");
198 ZERO_STRUCTPN(ioctl);
199 ioctl->smb2.level = RAW_IOCTL_SMB2;
200 ioctl->smb2.in.file.handle = *src_h;
201 ioctl->smb2.in.function = FSCTL_SRV_REQUEST_RESUME_KEY;
202 /* Allow for Key + ContextLength + Context */
203 ioctl->smb2.in.max_response_size = 32;
204 ioctl->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
206 status = smb2_ioctl(tree, mem_ctx, &ioctl->smb2);
207 torture_assert_ntstatus_ok(torture, status,
208 "FSCTL_SRV_REQUEST_RESUME_KEY");
211 ndr_ret = ndr_pull_struct_blob(&ioctl->smb2.out.out, mem_ctx, &res_key,
212 (ndr_pull_flags_fn_t)ndr_pull_req_resume_key_rsp);
214 torture_assert_ndr_success(torture, ndr_ret,
215 "ndr_pull_req_resume_key_rsp");
217 ZERO_STRUCTPN(ioctl);
218 ioctl->smb2.level = RAW_IOCTL_SMB2;
219 ioctl->smb2.in.file.handle = *dest_h;
220 ioctl->smb2.in.function = FSCTL_SRV_COPYCHUNK;
221 ioctl->smb2.in.max_response_size = sizeof(struct srv_copychunk_rsp);
222 ioctl->smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
224 ZERO_STRUCTPN(cc_copy);
225 memcpy(cc_copy->source_key, res_key.resume_key, ARRAY_SIZE(cc_copy->source_key));
226 cc_copy->chunk_count = nchunks;
227 cc_copy->chunks = talloc_zero_array(mem_ctx, struct srv_copychunk, nchunks);
228 if (cc_copy->chunks == NULL) {
229 printf("not enough memory to allocate %u chunks\n", nchunks);
230 return false;
233 return true;
237 static bool check_copy_chunk_rsp(struct torture_context *torture,
238 struct srv_copychunk_rsp *cc_rsp,
239 uint32_t ex_chunks_written,
240 uint32_t ex_chunk_bytes_written,
241 uint32_t ex_total_bytes_written)
243 torture_assert_int_equal(torture, cc_rsp->chunks_written,
244 ex_chunks_written, "num chunks");
245 torture_assert_int_equal(torture, cc_rsp->chunk_bytes_written,
246 ex_chunk_bytes_written, "chunk bytes written");
247 torture_assert_int_equal(torture, cc_rsp->total_bytes_written,
248 ex_total_bytes_written, "chunk total bytes");
249 return true;
252 static bool test_ioctl_copy_chunk_simple(struct torture_context *torture,
253 struct smb2_tree *tree)
255 struct smb2_handle src_h;
256 struct smb2_handle dest_h;
257 NTSTATUS status;
258 union smb_ioctl ioctl;
259 TALLOC_CTX *tmp_ctx = talloc_new(tree);
260 struct srv_copychunk_copy cc_copy;
261 struct srv_copychunk_rsp cc_rsp;
262 enum ndr_err_code ndr_ret;
263 bool ok;
265 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
266 1, /* 1 chunk */
267 &src_h, 4096, /* fill 4096 byte src file */
268 &dest_h, 0, /* 0 byte dest file */
269 &cc_copy,
270 &ioctl);
271 if (!ok) {
272 return false;
275 /* copy all src file data (via a single chunk desc) */
276 cc_copy.chunks[0].source_off = 0;
277 cc_copy.chunks[0].target_off = 0;
278 cc_copy.chunks[0].length = 4096;
280 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
281 &cc_copy,
282 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
283 torture_assert_ndr_success(torture, ndr_ret,
284 "ndr_push_srv_copychunk_copy");
286 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
287 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_COPYCHUNK");
289 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
290 &cc_rsp,
291 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
292 torture_assert_ndr_success(torture, ndr_ret,
293 "ndr_pull_srv_copychunk_rsp");
295 ok = check_copy_chunk_rsp(torture, &cc_rsp,
296 1, /* chunks written */
297 0, /* chunk bytes unsuccessfully written */
298 4096); /* total bytes written */
299 if (!ok) {
300 return false;
303 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
304 if (!ok) {
305 return false;
308 smb2_util_close(tree, src_h);
309 smb2_util_close(tree, dest_h);
310 talloc_free(tmp_ctx);
311 return true;
314 static bool test_ioctl_copy_chunk_multi(struct torture_context *torture,
315 struct smb2_tree *tree)
317 struct smb2_handle src_h;
318 struct smb2_handle dest_h;
319 NTSTATUS status;
320 union smb_ioctl ioctl;
321 TALLOC_CTX *tmp_ctx = talloc_new(tree);
322 struct srv_copychunk_copy cc_copy;
323 struct srv_copychunk_rsp cc_rsp;
324 enum ndr_err_code ndr_ret;
325 bool ok;
327 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
328 2, /* chunks */
329 &src_h, 8192, /* src file */
330 &dest_h, 0, /* dest file */
331 &cc_copy,
332 &ioctl);
333 if (!ok) {
334 return false;
337 /* copy all src file data via two chunks */
338 cc_copy.chunks[0].source_off = 0;
339 cc_copy.chunks[0].target_off = 0;
340 cc_copy.chunks[0].length = 4096;
342 cc_copy.chunks[1].source_off = 4096;
343 cc_copy.chunks[1].target_off = 4096;
344 cc_copy.chunks[1].length = 4096;
346 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
347 &cc_copy,
348 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
349 torture_assert_ndr_success(torture, ndr_ret,
350 "ndr_push_srv_copychunk_copy");
352 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
353 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_COPYCHUNK");
355 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
356 &cc_rsp,
357 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
358 torture_assert_ndr_success(torture, ndr_ret,
359 "ndr_pull_srv_copychunk_rsp");
361 ok = check_copy_chunk_rsp(torture, &cc_rsp,
362 2, /* chunks written */
363 0, /* chunk bytes unsuccessfully written */
364 8192); /* total bytes written */
365 if (!ok) {
366 return false;
369 smb2_util_close(tree, src_h);
370 smb2_util_close(tree, dest_h);
371 talloc_free(tmp_ctx);
372 return true;
375 static bool test_ioctl_copy_chunk_tiny(struct torture_context *torture,
376 struct smb2_tree *tree)
378 struct smb2_handle src_h;
379 struct smb2_handle dest_h;
380 NTSTATUS status;
381 union smb_ioctl ioctl;
382 TALLOC_CTX *tmp_ctx = talloc_new(tree);
383 struct srv_copychunk_copy cc_copy;
384 struct srv_copychunk_rsp cc_rsp;
385 enum ndr_err_code ndr_ret;
386 bool ok;
388 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
389 2, /* chunks */
390 &src_h, 100, /* src file */
391 &dest_h, 0, /* dest file */
392 &cc_copy,
393 &ioctl);
394 if (!ok) {
395 return false;
398 /* copy all src file data via two chunks, sub block size chunks */
399 cc_copy.chunks[0].source_off = 0;
400 cc_copy.chunks[0].target_off = 0;
401 cc_copy.chunks[0].length = 50;
403 cc_copy.chunks[1].source_off = 50;
404 cc_copy.chunks[1].target_off = 50;
405 cc_copy.chunks[1].length = 50;
407 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
408 &cc_copy,
409 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
410 torture_assert_ndr_success(torture, ndr_ret,
411 "ndr_push_srv_copychunk_copy");
413 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
414 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_COPYCHUNK");
416 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
417 &cc_rsp,
418 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
419 torture_assert_ndr_success(torture, ndr_ret,
420 "ndr_pull_srv_copychunk_rsp");
422 ok = check_copy_chunk_rsp(torture, &cc_rsp,
423 2, /* chunks written */
424 0, /* chunk bytes unsuccessfully written */
425 100); /* total bytes written */
426 if (!ok) {
427 return false;
430 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 100, 0);
431 if (!ok) {
432 return false;
435 smb2_util_close(tree, src_h);
436 smb2_util_close(tree, dest_h);
437 talloc_free(tmp_ctx);
438 return true;
441 static bool test_ioctl_copy_chunk_over(struct torture_context *torture,
442 struct smb2_tree *tree)
444 struct smb2_handle src_h;
445 struct smb2_handle dest_h;
446 NTSTATUS status;
447 union smb_ioctl ioctl;
448 TALLOC_CTX *tmp_ctx = talloc_new(tree);
449 struct srv_copychunk_copy cc_copy;
450 struct srv_copychunk_rsp cc_rsp;
451 enum ndr_err_code ndr_ret;
452 bool ok;
454 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
455 2, /* chunks */
456 &src_h, 8192, /* src file */
457 &dest_h, 4096, /* dest file */
458 &cc_copy,
459 &ioctl);
460 if (!ok) {
461 return false;
464 /* first chunk overwrites existing dest data */
465 cc_copy.chunks[0].source_off = 0;
466 cc_copy.chunks[0].target_off = 0;
467 cc_copy.chunks[0].length = 4096;
469 /* second chunk overwrites the first */
470 cc_copy.chunks[1].source_off = 4096;
471 cc_copy.chunks[1].target_off = 0;
472 cc_copy.chunks[1].length = 4096;
474 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
475 &cc_copy,
476 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
477 torture_assert_ndr_success(torture, ndr_ret,
478 "ndr_push_srv_copychunk_copy");
480 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
481 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_COPYCHUNK");
483 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
484 &cc_rsp,
485 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
486 torture_assert_ndr_success(torture, ndr_ret,
487 "ndr_pull_srv_copychunk_rsp");
489 ok = check_copy_chunk_rsp(torture, &cc_rsp,
490 2, /* chunks written */
491 0, /* chunk bytes unsuccessfully written */
492 8192); /* total bytes written */
493 if (!ok) {
494 return false;
497 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 4096);
498 if (!ok) {
499 return false;
502 smb2_util_close(tree, src_h);
503 smb2_util_close(tree, dest_h);
504 talloc_free(tmp_ctx);
505 return true;
508 static bool test_ioctl_copy_chunk_append(struct torture_context *torture,
509 struct smb2_tree *tree)
511 struct smb2_handle src_h;
512 struct smb2_handle dest_h;
513 NTSTATUS status;
514 union smb_ioctl ioctl;
515 TALLOC_CTX *tmp_ctx = talloc_new(tree);
516 struct srv_copychunk_copy cc_copy;
517 struct srv_copychunk_rsp cc_rsp;
518 enum ndr_err_code ndr_ret;
519 bool ok;
521 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
522 2, /* chunks */
523 &src_h, 4096, /* src file */
524 &dest_h, 0, /* dest file */
525 &cc_copy,
526 &ioctl);
527 if (!ok) {
528 return false;
531 cc_copy.chunks[0].source_off = 0;
532 cc_copy.chunks[0].target_off = 0;
533 cc_copy.chunks[0].length = 4096;
535 /* second chunk appends the same data to the first */
536 cc_copy.chunks[1].source_off = 0;
537 cc_copy.chunks[1].target_off = 4096;
538 cc_copy.chunks[1].length = 4096;
540 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
541 &cc_copy,
542 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
543 torture_assert_ndr_success(torture, ndr_ret,
544 "ndr_push_srv_copychunk_copy");
546 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
547 torture_assert_ntstatus_ok(torture, status, "FSCTL_SRV_COPYCHUNK");
549 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
550 &cc_rsp,
551 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
552 torture_assert_ndr_success(torture, ndr_ret,
553 "ndr_pull_srv_copychunk_rsp");
555 ok = check_copy_chunk_rsp(torture, &cc_rsp,
556 2, /* chunks written */
557 0, /* chunk bytes unsuccessfully written */
558 8192); /* total bytes written */
559 if (!ok) {
560 return false;
563 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 4096, 0);
564 if (!ok) {
565 return false;
568 ok = check_pattern(torture, tree, tmp_ctx, dest_h, 4096, 4096, 0);
569 if (!ok) {
570 return false;
573 smb2_util_close(tree, src_h);
574 smb2_util_close(tree, dest_h);
575 talloc_free(tmp_ctx);
576 return true;
579 static bool test_ioctl_copy_chunk_limits(struct torture_context *torture,
580 struct smb2_tree *tree)
582 struct smb2_handle src_h;
583 struct smb2_handle dest_h;
584 NTSTATUS status;
585 union smb_ioctl ioctl;
586 TALLOC_CTX *tmp_ctx = talloc_new(tree);
587 struct srv_copychunk_copy cc_copy;
588 struct srv_copychunk_rsp cc_rsp;
589 enum ndr_err_code ndr_ret;
590 bool ok;
592 ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
593 1, /* chunks */
594 &src_h, 4096, /* src file */
595 &dest_h, 0, /* dest file */
596 &cc_copy,
597 &ioctl);
598 if (!ok) {
599 return false;
602 /* send huge chunk length request */
603 cc_copy.chunks[0].source_off = 0;
604 cc_copy.chunks[0].target_off = 0;
605 cc_copy.chunks[0].length = UINT_MAX;
607 ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
608 &cc_copy,
609 (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
610 torture_assert_ndr_success(torture, ndr_ret, "marshalling request");
612 status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
613 torture_assert_ntstatus_equal(torture, status,
614 NT_STATUS_INVALID_PARAMETER,
615 "bad oversize chunk response");
617 ndr_ret = ndr_pull_struct_blob(&ioctl.smb2.out.out, tmp_ctx,
618 &cc_rsp,
619 (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
620 torture_assert_ndr_success(torture, ndr_ret, "unmarshalling response");
622 torture_comment(torture, "limit max chunks, got %u\n",
623 cc_rsp.chunks_written);
624 torture_comment(torture, "limit max chunk len, got %u\n",
625 cc_rsp.chunk_bytes_written);
626 torture_comment(torture, "limit max total bytes, got %u\n",
627 cc_rsp.total_bytes_written);
629 smb2_util_close(tree, src_h);
630 smb2_util_close(tree, dest_h);
631 talloc_free(tmp_ctx);
632 return true;
636 basic testing of SMB2 ioctls
638 struct torture_suite *torture_smb2_ioctl_init(void)
640 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "ioctl");
642 torture_suite_add_1smb2_test(suite, "shadow_copy",
643 test_ioctl_get_shadow_copy);
644 torture_suite_add_1smb2_test(suite, "req_resume_key",
645 test_ioctl_req_resume_key);
646 torture_suite_add_1smb2_test(suite, "copy_chunk_simple",
647 test_ioctl_copy_chunk_simple);
648 torture_suite_add_1smb2_test(suite, "copy_chunk_multi",
649 test_ioctl_copy_chunk_multi);
650 torture_suite_add_1smb2_test(suite, "copy_chunk_tiny",
651 test_ioctl_copy_chunk_tiny);
652 torture_suite_add_1smb2_test(suite, "copy_chunk_overwrite",
653 test_ioctl_copy_chunk_over);
654 torture_suite_add_1smb2_test(suite, "copy_chunk_append",
655 test_ioctl_copy_chunk_append);
656 torture_suite_add_1smb2_test(suite, "copy_chunk_limits",
657 test_ioctl_copy_chunk_limits);
659 suite->description = talloc_strdup(suite, "SMB2-IOCTL tests");
661 return suite;