s4:torture/smb2: add smb2.durable-v2-open.reopen{1,2} tests
[Samba/gebeck_regimport.git] / source4 / torture / smb2 / durable_v2_open.c
blob3b5f7b632c1c3e6ddaf6588d919fcf8fdf96d258
1 /*
2 Unix SMB/CIFS implementation.
4 test suite for SMB2 version two of durable opens
6 Copyright (C) Michael Adam 2012
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 "../libcli/smb/smbXcli_base.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28 #include "librpc/ndr/libndr.h"
30 #define CHECK_VAL(v, correct) do { \
31 if ((v) != (correct)) { \
32 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
33 __location__, #v, (int)v, (int)correct); \
34 ret = false; \
35 }} while (0)
37 #define CHECK_STATUS(status, correct) do { \
38 if (!NT_STATUS_EQUAL(status, correct)) { \
39 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
40 nt_errstr(status), nt_errstr(correct)); \
41 ret = false; \
42 goto done; \
43 }} while (0)
45 #define CHECK_CREATED(__io, __created, __attribute) \
46 do { \
47 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
48 CHECK_VAL((__io)->out.alloc_size, 0); \
49 CHECK_VAL((__io)->out.size, 0); \
50 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
51 CHECK_VAL((__io)->out.reserved2, 0); \
52 } while(0)
54 /**
55 * basic durable_open test.
56 * durable state should only be granted when requested
57 * along with a batch oplock or a handle lease.
59 * This test tests durable open with all possible oplock types.
62 struct durable_open_vs_oplock {
63 const char *level;
64 const char *share_mode;
65 bool durable;
66 bool persistent;
69 #define NUM_OPLOCK_TYPES 4
70 #define NUM_SHARE_MODES 8
71 #define NUM_OPLOCK_OPEN_TESTS ( NUM_OPLOCK_TYPES * NUM_SHARE_MODES )
72 static struct durable_open_vs_oplock durable_open_vs_oplock_table[NUM_OPLOCK_OPEN_TESTS] =
74 { "", "", false, false },
75 { "", "R", false, false },
76 { "", "W", false, false },
77 { "", "D", false, false },
78 { "", "RD", false, false },
79 { "", "RW", false, false },
80 { "", "WD", false, false },
81 { "", "RWD", false, false },
83 { "s", "", false, false },
84 { "s", "R", false, false },
85 { "s", "W", false, false },
86 { "s", "D", false, false },
87 { "s", "RD", false, false },
88 { "s", "RW", false, false },
89 { "s", "WD", false, false },
90 { "s", "RWD", false, false },
92 { "x", "", false, false },
93 { "x", "R", false, false },
94 { "x", "W", false, false },
95 { "x", "D", false, false },
96 { "x", "RD", false, false },
97 { "x", "RW", false, false },
98 { "x", "WD", false, false },
99 { "x", "RWD", false, false },
101 { "b", "", true, false },
102 { "b", "R", true, false },
103 { "b", "W", true, false },
104 { "b", "D", true, false },
105 { "b", "RD", true, false },
106 { "b", "RW", true, false },
107 { "b", "WD", true, false },
108 { "b", "RWD", true, false },
111 static bool test_one_durable_v2_open_oplock(struct torture_context *tctx,
112 struct smb2_tree *tree,
113 const char *fname,
114 bool request_persistent,
115 struct durable_open_vs_oplock test)
117 NTSTATUS status;
118 TALLOC_CTX *mem_ctx = talloc_new(tctx);
119 struct smb2_handle _h;
120 struct smb2_handle *h = NULL;
121 bool ret = true;
122 struct smb2_create io;
124 smb2_util_unlink(tree, fname);
126 smb2_oplock_create_share(&io, fname,
127 smb2_util_share_access(test.share_mode),
128 smb2_util_oplock_level(test.level));
129 io.in.durable_open = false;
130 io.in.durable_open_v2 = true;
131 io.in.persistent_open = request_persistent;
132 io.in.create_guid = GUID_random();
134 status = smb2_create(tree, mem_ctx, &io);
135 CHECK_STATUS(status, NT_STATUS_OK);
136 _h = io.out.file.handle;
137 h = &_h;
138 CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
139 CHECK_VAL(io.out.durable_open, false);
140 CHECK_VAL(io.out.durable_open_v2, test.durable);
141 CHECK_VAL(io.out.persistent_open, test.persistent);
142 CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level(test.level));
144 done:
145 if (h != NULL) {
146 smb2_util_close(tree, *h);
148 smb2_util_unlink(tree, fname);
149 talloc_free(mem_ctx);
151 return ret;
154 static bool test_durable_v2_open_oplock_table(struct torture_context *tctx,
155 struct smb2_tree *tree,
156 const char *fname,
157 bool request_persistent,
158 struct durable_open_vs_oplock *table,
159 uint8_t num_tests)
161 bool ret = true;
162 uint8_t i;
164 smb2_util_unlink(tree, fname);
166 for (i = 0; i < num_tests; i++) {
167 ret = test_one_durable_v2_open_oplock(tctx,
168 tree,
169 fname,
170 request_persistent,
171 table[i]);
172 if (ret == false) {
173 goto done;
177 done:
178 smb2_util_unlink(tree, fname);
180 return ret;
183 bool test_durable_v2_open_oplock(struct torture_context *tctx,
184 struct smb2_tree *tree)
186 bool ret;
187 char fname[256];
189 /* Choose a random name in case the state is left a little funky. */
190 snprintf(fname, 256, "durable_open_oplock_%s.dat",
191 generate_random_str(tctx, 8));
193 ret = test_durable_v2_open_oplock_table(tctx, tree, fname,
194 false, /* request_persistent */
195 durable_open_vs_oplock_table,
196 NUM_OPLOCK_OPEN_TESTS);
198 talloc_free(tree);
200 return ret;
204 * basic durable handle open test.
205 * persistent state should only be granted when requested
206 * along with a batch oplock or a handle lease.
208 * This test tests persistent open with all valid lease types.
211 struct durable_open_vs_lease {
212 const char *type;
213 const char *share_mode;
214 bool durable;
215 bool persistent;
218 #define NUM_LEASE_TYPES 5
219 #define NUM_LEASE_OPEN_TESTS ( NUM_LEASE_TYPES * NUM_SHARE_MODES )
220 static struct durable_open_vs_lease durable_open_vs_lease_table[NUM_LEASE_OPEN_TESTS] =
222 { "", "", false, false },
223 { "", "R", false, false },
224 { "", "W", false, false },
225 { "", "D", false, false },
226 { "", "RW", false, false },
227 { "", "RD", false, false },
228 { "", "WD", false, false },
229 { "", "RWD", false, false },
231 { "R", "", false, false },
232 { "R", "R", false, false },
233 { "R", "W", false, false },
234 { "R", "D", false, false },
235 { "R", "RW", false, false },
236 { "R", "RD", false, false },
237 { "R", "DW", false, false },
238 { "R", "RWD", false, false },
240 { "RW", "", false, false },
241 { "RW", "R", false, false },
242 { "RW", "W", false, false },
243 { "RW", "D", false, false },
244 { "RW", "RW", false, false },
245 { "RW", "RD", false, false },
246 { "RW", "WD", false, false },
247 { "RW", "RWD", false, false },
249 { "RH", "", true, false },
250 { "RH", "R", true, false },
251 { "RH", "W", true, false },
252 { "RH", "D", true, false },
253 { "RH", "RW", true, false },
254 { "RH", "RD", true, false },
255 { "RH", "WD", true, false },
256 { "RH", "RWD", true, false },
258 { "RHW", "", true, false },
259 { "RHW", "R", true, false },
260 { "RHW", "W", true, false },
261 { "RHW", "D", true, false },
262 { "RHW", "RW", true, false },
263 { "RHW", "RD", true, false },
264 { "RHW", "WD", true, false },
265 { "RHW", "RWD", true, false },
268 static bool test_one_durable_v2_open_lease(struct torture_context *tctx,
269 struct smb2_tree *tree,
270 const char *fname,
271 bool request_persistent,
272 struct durable_open_vs_lease test)
274 NTSTATUS status;
275 TALLOC_CTX *mem_ctx = talloc_new(tctx);
276 struct smb2_handle _h;
277 struct smb2_handle *h = NULL;
278 bool ret = true;
279 struct smb2_create io;
280 struct smb2_lease ls;
281 uint64_t lease;
283 smb2_util_unlink(tree, fname);
285 lease = random();
287 smb2_lease_create_share(&io, &ls, false /* dir */, fname,
288 smb2_util_share_access(test.share_mode),
289 lease,
290 smb2_util_lease_state(test.type));
291 io.in.durable_open = false;
292 io.in.durable_open_v2 = true;
293 io.in.persistent_open = request_persistent;
294 io.in.create_guid = GUID_random();
296 status = smb2_create(tree, mem_ctx, &io);
297 CHECK_STATUS(status, NT_STATUS_OK);
298 _h = io.out.file.handle;
299 h = &_h;
300 CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
301 CHECK_VAL(io.out.durable_open, false);
302 CHECK_VAL(io.out.durable_open_v2, test.durable);
303 CHECK_VAL(io.out.persistent_open, test.persistent);
304 CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
305 CHECK_VAL(io.out.lease_response.lease_key.data[0], lease);
306 CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease);
307 CHECK_VAL(io.out.lease_response.lease_state,
308 smb2_util_lease_state(test.type));
309 done:
310 if (h != NULL) {
311 smb2_util_close(tree, *h);
313 smb2_util_unlink(tree, fname);
314 talloc_free(mem_ctx);
316 return ret;
319 static bool test_durable_v2_open_lease_table(struct torture_context *tctx,
320 struct smb2_tree *tree,
321 const char *fname,
322 bool request_persistent,
323 struct durable_open_vs_lease *table,
324 uint8_t num_tests)
326 bool ret = true;
327 uint8_t i;
329 smb2_util_unlink(tree, fname);
331 for (i = 0; i < num_tests; i++) {
332 ret = test_one_durable_v2_open_lease(tctx,
333 tree,
334 fname,
335 request_persistent,
336 table[i]);
337 if (ret == false) {
338 goto done;
342 done:
343 smb2_util_unlink(tree, fname);
345 return ret;
348 bool test_durable_v2_open_lease(struct torture_context *tctx,
349 struct smb2_tree *tree)
351 char fname[256];
352 bool ret = true;
353 uint32_t caps;
355 caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
356 if (!(caps & SMB2_CAP_LEASING)) {
357 torture_skip(tctx, "leases are not supported");
360 /* Choose a random name in case the state is left a little funky. */
361 snprintf(fname, 256, "durable_open_lease_%s.dat", generate_random_str(tctx, 8));
363 ret = test_durable_v2_open_lease_table(tctx, tree, fname,
364 false, /* request_persistent */
365 durable_open_vs_lease_table,
366 NUM_LEASE_OPEN_TESTS);
368 talloc_free(tree);
369 return ret;
373 * basic test for doing a durable open
374 * and do a durable reopen on the same connection
375 * while the first open is still active (fails)
377 bool test_durable_v2_open_reopen1(struct torture_context *tctx,
378 struct smb2_tree *tree)
380 NTSTATUS status;
381 TALLOC_CTX *mem_ctx = talloc_new(tctx);
382 char fname[256];
383 struct smb2_handle _h;
384 struct smb2_handle *h = NULL;
385 struct smb2_create io1, io2;
386 bool ret = true;
388 /* Choose a random name in case the state is left a little funky. */
389 snprintf(fname, 256, "durable_v2_open_reopen1_%s.dat",
390 generate_random_str(tctx, 8));
392 smb2_util_unlink(tree, fname);
394 smb2_oplock_create_share(&io1, fname,
395 smb2_util_share_access(""),
396 smb2_util_oplock_level("b"));
397 io1.in.durable_open = false;
398 io1.in.durable_open_v2 = true;
399 io1.in.persistent_open = false;
400 io1.in.create_guid = GUID_random();
401 io1.in.timeout = UINT32_MAX;
403 status = smb2_create(tree, mem_ctx, &io1);
404 CHECK_STATUS(status, NT_STATUS_OK);
405 _h = io1.out.file.handle;
406 h = &_h;
407 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
408 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
409 CHECK_VAL(io1.out.durable_open, false);
410 CHECK_VAL(io1.out.durable_open_v2, true);
411 CHECK_VAL(io1.out.persistent_open, false);
412 CHECK_VAL(io1.out.timeout, io1.in.timeout);
414 /* try a durable reconnect while the file is still open */
415 ZERO_STRUCT(io2);
416 io2.in = io1.in;
417 io2.in.durable_open_v2 = false;
418 io2.in.durable_handle_v2 = h;
419 io2.in.create_guid = io1.in.create_guid;
420 status = smb2_create(tree, mem_ctx, &io2);
421 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
423 done:
424 if (h != NULL) {
425 smb2_util_close(tree, *h);
428 smb2_util_unlink(tree, fname);
430 talloc_free(tree);
432 talloc_free(mem_ctx);
434 return ret;
438 * basic test for doing a durable open
439 * tcp disconnect, reconnect, do a durable reopen (succeeds)
441 bool test_durable_v2_open_reopen2(struct torture_context *tctx,
442 struct smb2_tree *tree)
444 NTSTATUS status;
445 TALLOC_CTX *mem_ctx = talloc_new(tctx);
446 char fname[256];
447 struct smb2_handle _h;
448 struct smb2_handle *h = NULL;
449 struct smb2_create io1, io2;
450 bool ret = true;
452 /* Choose a random name in case the state is left a little funky. */
453 snprintf(fname, 256, "durable_v2_open_reopen2_%s.dat",
454 generate_random_str(tctx, 8));
456 smb2_util_unlink(tree, fname);
458 smb2_oplock_create_share(&io1, fname,
459 smb2_util_share_access(""),
460 smb2_util_oplock_level("b"));
461 io1.in.durable_open = false;
462 io1.in.durable_open_v2 = true;
463 io1.in.persistent_open = false;
464 io1.in.create_guid = GUID_random();
465 io1.in.timeout = UINT32_MAX;
467 status = smb2_create(tree, mem_ctx, &io1);
468 CHECK_STATUS(status, NT_STATUS_OK);
469 _h = io1.out.file.handle;
470 h = &_h;
471 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
472 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
473 CHECK_VAL(io1.out.durable_open, false);
474 CHECK_VAL(io1.out.durable_open_v2, true);
475 CHECK_VAL(io1.out.persistent_open, false);
476 CHECK_VAL(io1.out.timeout, io1.in.timeout);
478 /* disconnect, reconnect and then do durable reopen */
479 talloc_free(tree);
480 tree = NULL;
482 if (!torture_smb2_connection(tctx, &tree)) {
483 torture_warning(tctx, "couldn't reconnect, bailing\n");
484 ret = false;
485 goto done;
488 ZERO_STRUCT(io2);
489 io2.in.fname = "";
490 io2.in.durable_handle_v2 = h;
491 status = smb2_create(tree, mem_ctx, &io2);
492 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
494 ZERO_STRUCT(io2);
495 io2.in.fname = "__non_existing_fname__";
496 io2.in.durable_handle_v2 = h;
497 status = smb2_create(tree, mem_ctx, &io2);
498 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
500 ZERO_STRUCT(io2);
501 io2.in.fname = fname;
502 io2.in.durable_handle_v2 = h;
503 status = smb2_create(tree, mem_ctx, &io2);
504 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
506 ZERO_STRUCT(io2);
508 * These are completely ignored by the server
510 io2.in.security_flags = 0x78;
511 io2.in.oplock_level = 0x78;
512 io2.in.impersonation_level = 0x12345678;
513 io2.in.create_flags = 0x12345678;
514 io2.in.reserved = 0x12345678;
515 io2.in.desired_access = 0x12345678;
516 io2.in.file_attributes = 0x12345678;
517 io2.in.share_access = 0x12345678;
518 io2.in.create_disposition = 0x12345678;
519 io2.in.create_options = 0x12345678;
520 io2.in.fname = "__non_existing_fname__";
523 * only io2.in.durable_handle_v2 and
524 * io2.in.create_guid are checked
526 io2.in.durable_open_v2 = false;
527 io2.in.durable_handle_v2 = h;
528 io2.in.create_guid = io1.in.create_guid;
529 h = NULL;
531 status = smb2_create(tree, mem_ctx, &io2);
532 CHECK_STATUS(status, NT_STATUS_OK);
533 CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
534 CHECK_VAL(io1.out.durable_open, false);
535 CHECK_VAL(io1.out.durable_open_v2, true);
536 CHECK_VAL(io1.out.persistent_open, false);
537 CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
538 _h = io2.out.file.handle;
539 h = &_h;
541 done:
542 if (h != NULL) {
543 smb2_util_close(tree, *h);
546 smb2_util_unlink(tree, fname);
548 talloc_free(tree);
550 talloc_free(mem_ctx);
552 return ret;
556 * basic persistent open test.
558 * This test tests durable open with all possible oplock types.
561 struct durable_open_vs_oplock persistent_open_oplock_ca_table[NUM_OPLOCK_OPEN_TESTS] =
563 { "", "", true, true },
564 { "", "R", true, true },
565 { "", "W", true, true },
566 { "", "D", true, true },
567 { "", "RD", true, true },
568 { "", "RW", true, true },
569 { "", "WD", true, true },
570 { "", "RWD", true, true },
572 { "s", "", true, true },
573 { "s", "R", true, true },
574 { "s", "W", true, true },
575 { "s", "D", true, true },
576 { "s", "RD", true, true },
577 { "s", "RW", true, true },
578 { "s", "WD", true, true },
579 { "s", "RWD", true, true },
581 { "x", "", true, true },
582 { "x", "R", true, true },
583 { "x", "W", true, true },
584 { "x", "D", true, true },
585 { "x", "RD", true, true },
586 { "x", "RW", true, true },
587 { "x", "WD", true, true },
588 { "x", "RWD", true, true },
590 { "b", "", true, true },
591 { "b", "R", true, true },
592 { "b", "W", true, true },
593 { "b", "D", true, true },
594 { "b", "RD", true, true },
595 { "b", "RW", true, true },
596 { "b", "WD", true, true },
597 { "b", "RWD", true, true },
600 bool test_persistent_open_oplock(struct torture_context *tctx,
601 struct smb2_tree *tree)
603 char fname[256];
604 bool ret = true;
605 uint32_t share_capabilities;
606 bool share_is_ca = false;
607 struct durable_open_vs_oplock *table;
609 /* Choose a random name in case the state is left a little funky. */
610 snprintf(fname, 256, "persistent_open_oplock_%s.dat", generate_random_str(tctx, 8));
612 share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
613 share_is_ca = share_capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
615 if (share_is_ca) {
616 table = persistent_open_oplock_ca_table;
617 } else {
618 table = durable_open_vs_oplock_table;
621 ret = test_durable_v2_open_oplock_table(tctx, tree, fname,
622 true, /* request_persistent */
623 table,
624 NUM_OPLOCK_OPEN_TESTS);
626 talloc_free(tree);
628 return ret;
632 * basic persistent handle open test.
633 * persistent state should only be granted when requested
634 * along with a batch oplock or a handle lease.
636 * This test tests persistent open with all valid lease types.
639 struct durable_open_vs_lease persistent_open_lease_ca_table[NUM_LEASE_OPEN_TESTS] =
641 { "", "", true, true },
642 { "", "R", true, true },
643 { "", "W", true, true },
644 { "", "D", true, true },
645 { "", "RW", true, true },
646 { "", "RD", true, true },
647 { "", "WD", true, true },
648 { "", "RWD", true, true },
650 { "R", "", true, true },
651 { "R", "R", true, true },
652 { "R", "W", true, true },
653 { "R", "D", true, true },
654 { "R", "RW", true, true },
655 { "R", "RD", true, true },
656 { "R", "DW", true, true },
657 { "R", "RWD", true, true },
659 { "RW", "", true, true },
660 { "RW", "R", true, true },
661 { "RW", "W", true, true },
662 { "RW", "D", true, true },
663 { "RW", "RW", true, true },
664 { "RW", "RD", true, true },
665 { "RW", "WD", true, true },
666 { "RW", "RWD", true, true },
668 { "RH", "", true, true },
669 { "RH", "R", true, true },
670 { "RH", "W", true, true },
671 { "RH", "D", true, true },
672 { "RH", "RW", true, true },
673 { "RH", "RD", true, true },
674 { "RH", "WD", true, true },
675 { "RH", "RWD", true, true },
677 { "RHW", "", true, true },
678 { "RHW", "R", true, true },
679 { "RHW", "W", true, true },
680 { "RHW", "D", true, true },
681 { "RHW", "RW", true, true },
682 { "RHW", "RD", true, true },
683 { "RHW", "WD", true, true },
684 { "RHW", "RWD", true, true },
687 bool test_persistent_open_lease(struct torture_context *tctx,
688 struct smb2_tree *tree)
690 char fname[256];
691 bool ret = true;
692 uint32_t caps;
693 uint32_t share_capabilities;
694 bool share_is_ca;
695 struct durable_open_vs_lease *table;
697 caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
698 if (!(caps & SMB2_CAP_LEASING)) {
699 torture_skip(tctx, "leases are not supported");
702 /* Choose a random name in case the state is left a little funky. */
703 snprintf(fname, 256, "persistent_open_lease_%s.dat", generate_random_str(tctx, 8));
705 share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
706 share_is_ca = share_capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
708 if (share_is_ca) {
709 table = persistent_open_lease_ca_table;
710 } else {
711 table = durable_open_vs_lease_table;
714 ret = test_durable_v2_open_lease_table(tctx, tree, fname,
715 true, /* request_persistent */
716 table,
717 NUM_LEASE_OPEN_TESTS);
719 talloc_free(tree);
721 return ret;
724 struct torture_suite *torture_smb2_durable_v2_open_init(void)
726 struct torture_suite *suite =
727 torture_suite_create(talloc_autofree_context(), "durable-v2-open");
729 torture_suite_add_1smb2_test(suite, "open-oplock", test_durable_v2_open_oplock);
730 torture_suite_add_1smb2_test(suite, "open-lease", test_durable_v2_open_lease);
731 torture_suite_add_1smb2_test(suite, "reopen1", test_durable_v2_open_reopen1);
732 torture_suite_add_1smb2_test(suite, "reopen2", test_durable_v2_open_reopen2);
733 torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock);
734 torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease);
736 suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests");
738 return suite;