torture/smb2: make SMB2 BRL tests pass against W2K8R2
[ira/wip.git] / source4 / torture / smb2 / lock.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 lock test suite
5
6    Copyright (C) Stefan Metzmacher 2006
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
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28
29
30 #define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
31     (torture_setting_bool(_tctx, "invalid_lock_range_support", true))
32 #define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
33
34 #define CHECK_STATUS(status, correct) do { \
35         if (!NT_STATUS_EQUAL(status, correct)) { \
36                 printf("(%s) Incorrect status %s - should be %s\n", \
37                        __location__, nt_errstr(status), nt_errstr(correct)); \
38                 ret = false; \
39                 goto done; \
40         }} while (0)
41
42 #define CHECK_VALUE(v, correct) do { \
43         if ((v) != (correct)) { \
44                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
45                        __location__, #v, v, correct); \
46                 ret = false; \
47                 goto done; \
48         }} while (0)
49
50 static bool test_valid_request(struct torture_context *torture, struct smb2_tree *tree)
51 {
52         bool ret = true;
53         NTSTATUS status;
54         struct smb2_handle h;
55         uint8_t buf[200];
56         struct smb2_lock lck;
57         struct smb2_lock_element el[2];
58
59         ZERO_STRUCT(buf);
60
61         status = torture_smb2_testfile(tree, "lock1.txt", &h);
62         CHECK_STATUS(status, NT_STATUS_OK);
63
64         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
65         CHECK_STATUS(status, NT_STATUS_OK);
66
67         lck.in.locks            = el;
68
69         torture_comment(torture, "Test request with 0 locks.\n");
70
71         lck.in.lock_count       = 0x0000;
72         lck.in.reserved         = 0x00000000;
73         lck.in.file.handle      = h;
74         el[0].offset            = 0x0000000000000000;
75         el[0].length            = 0x0000000000000000;
76         el[0].reserved          = 0x0000000000000000;
77         el[0].flags             = 0x00000000;
78         status = smb2_lock(tree, &lck);
79         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
80
81         lck.in.lock_count       = 0x0000;
82         lck.in.reserved         = 0x00000000;
83         lck.in.file.handle      = h;
84         el[0].offset            = 0;
85         el[0].length            = 0;
86         el[0].reserved          = 0x00000000;
87         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
88         status = smb2_lock(tree, &lck);
89         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
90
91         lck.in.lock_count       = 0x0001;
92         lck.in.reserved         = 0x00000000;
93         lck.in.file.handle      = h;
94         el[0].offset            = 0;
95         el[0].length            = 0;
96         el[0].reserved          = 0x00000000;
97         el[0].flags             = SMB2_LOCK_FLAG_NONE;
98         status = smb2_lock(tree, &lck);
99         if (TARGET_IS_W2K8(torture)) {
100                 CHECK_STATUS(status, NT_STATUS_OK);
101                 torture_warning(torture, "Target has bug validating lock flags "
102                                          "parameter.\n");
103         } else {
104                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
105         }
106
107         torture_comment(torture, "Test >63-bit lock requests.\n");
108
109         lck.in.file.handle.data[0] +=1;
110         status = smb2_lock(tree, &lck);
111         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
112         lck.in.file.handle.data[0] -=1;
113
114         lck.in.lock_count       = 0x0001;
115         lck.in.reserved         = 0x123ab1;
116         lck.in.file.handle      = h;
117         el[0].offset            = UINT64_MAX;
118         el[0].length            = UINT64_MAX;
119         el[0].reserved          = 0x00000000;
120         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
121                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
122         status = smb2_lock(tree, &lck);
123         if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
124                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
125         } else {
126                 CHECK_STATUS(status, NT_STATUS_OK);
127                 CHECK_VALUE(lck.out.reserved, 0);
128         }
129
130         lck.in.reserved         = 0x123ab2;
131         status = smb2_lock(tree, &lck);
132         if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
133                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
134         } else {
135                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
136         }
137
138         torture_comment(torture, "Test basic lock stacking.\n");
139
140         lck.in.lock_count       = 0x0001;
141         lck.in.reserved         = 0x12345678;
142         lck.in.file.handle      = h;
143         el[0].offset            = UINT32_MAX;
144         el[0].length            = UINT32_MAX;
145         el[0].reserved          = 0x87654321;
146         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
147                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
148         status = smb2_lock(tree, &lck);
149         CHECK_STATUS(status, NT_STATUS_OK);
150         CHECK_VALUE(lck.out.reserved, 0);
151
152         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
153         status = smb2_lock(tree, &lck);
154         CHECK_STATUS(status, NT_STATUS_OK);
155         CHECK_VALUE(lck.out.reserved, 0);
156
157         status = smb2_lock(tree, &lck);
158         CHECK_STATUS(status, NT_STATUS_OK);
159         CHECK_VALUE(lck.out.reserved, 0);
160
161         lck.in.lock_count       = 0x0001;
162         lck.in.reserved         = 0x87654321;
163         lck.in.file.handle      = h;
164         el[0].offset            = 0x00000000FFFFFFFF;
165         el[0].length            = 0x00000000FFFFFFFF;
166         el[0].reserved          = 0x1234567;
167         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
168         status = smb2_lock(tree, &lck);
169         CHECK_STATUS(status, NT_STATUS_OK);
170
171         lck.in.lock_count       = 0x0001;
172         lck.in.reserved         = 0x1234567;
173         lck.in.file.handle      = h;
174         el[0].offset            = 0x00000000FFFFFFFF;
175         el[0].length            = 0x00000000FFFFFFFF;
176         el[0].reserved          = 0x00000000;
177         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
178         status = smb2_lock(tree, &lck);
179         CHECK_STATUS(status, NT_STATUS_OK);
180
181         status = smb2_lock(tree, &lck);
182         CHECK_STATUS(status, NT_STATUS_OK);
183         status = smb2_lock(tree, &lck);
184         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
185
186         torture_comment(torture, "Test flags field permutations.\n");
187
188         lck.in.lock_count       = 0x0001;
189         lck.in.reserved         = 0;
190         lck.in.file.handle      = h;
191         el[0].offset            = 1;
192         el[0].length            = 1;
193         el[0].reserved          = 0x00000000;
194         el[0].flags             = ~SMB2_LOCK_FLAG_ALL_MASK;
195
196         status = smb2_lock(tree, &lck);
197         if (TARGET_IS_W2K8(torture)) {
198                 CHECK_STATUS(status, NT_STATUS_OK);
199                 torture_warning(torture, "Target has bug validating lock flags "
200                                          "parameter.\n");
201         } else {
202                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
203         }
204
205         if (TARGET_IS_W2K8(torture)) {
206                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
207                 status = smb2_lock(tree, &lck);
208                 CHECK_STATUS(status, NT_STATUS_OK);
209         }
210
211         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
212         status = smb2_lock(tree, &lck);
213         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
214
215         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
216                                   SMB2_LOCK_FLAG_EXCLUSIVE;
217         status = smb2_lock(tree, &lck);
218         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
219
220         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
221                                   SMB2_LOCK_FLAG_SHARED;
222         status = smb2_lock(tree, &lck);
223         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
224
225         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
226                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
227         status = smb2_lock(tree, &lck);
228         if (TARGET_IS_W2K8(torture)) {
229                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
230                 torture_warning(torture, "Target has bug validating lock flags "
231                                          "parameter.\n");
232         } else {
233                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
234         }
235
236         torture_comment(torture, "Test return error when 2 locks are "
237                                  "requested\n");
238
239         lck.in.lock_count       = 2;
240         lck.in.reserved         = 0;
241         lck.in.file.handle      = h;
242         el[0].offset            = 9999;
243         el[0].length            = 1;
244         el[0].reserved          = 0x00000000;
245         el[1].offset            = 9999;
246         el[1].length            = 1;
247         el[1].reserved          = 0x00000000;
248
249         lck.in.lock_count       = 2;
250         el[0].flags             = 0;
251         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
252         status = smb2_lock(tree, &lck);
253         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
254
255         lck.in.lock_count       = 2;
256         el[0].flags             = 0;
257         el[1].flags             = 0;
258         status = smb2_lock(tree, &lck);
259         if (TARGET_IS_W2K8(torture)) {
260                 CHECK_STATUS(status, NT_STATUS_OK);
261                 torture_warning(torture, "Target has bug validating lock flags "
262                                          "parameter.\n");
263         } else {
264                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
265         }
266
267         lck.in.lock_count       = 2;
268         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
269         el[1].flags             = 0;
270         status = smb2_lock(tree, &lck);
271         if (TARGET_IS_W2K8(torture)) {
272                 CHECK_STATUS(status, NT_STATUS_OK);
273                 torture_warning(torture, "Target has bug validating lock flags "
274                                          "parameter.\n");
275         } else {
276                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
277         }
278
279         lck.in.lock_count       = 1;
280         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
281         status = smb2_lock(tree, &lck);
282         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
283
284         lck.in.lock_count       = 1;
285         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
286         status = smb2_lock(tree, &lck);
287         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
288
289         lck.in.lock_count       = 1;
290         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
291         status = smb2_lock(tree, &lck);
292         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
293
294         lck.in.lock_count       = 1;
295         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
296         status = smb2_lock(tree, &lck);
297         CHECK_STATUS(status, NT_STATUS_OK);
298
299         status = smb2_lock(tree, &lck);
300         CHECK_STATUS(status, NT_STATUS_OK);
301
302         lck.in.lock_count       = 2;
303         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
304         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
305         status = smb2_lock(tree, &lck);
306         CHECK_STATUS(status, NT_STATUS_OK);
307
308         lck.in.lock_count       = 1;
309         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
310         status = smb2_lock(tree, &lck);
311         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
312
313 done:
314         return ret;
315 }
316
317 struct test_lock_read_write_state {
318         const char *fname;
319         uint32_t lock_flags;
320         NTSTATUS write_h1_status;
321         NTSTATUS read_h1_status;
322         NTSTATUS write_h2_status;
323         NTSTATUS read_h2_status;
324 };
325
326 static bool test_lock_read_write(struct torture_context *torture,
327                                  struct smb2_tree *tree,
328                                  struct test_lock_read_write_state *s)
329 {
330         bool ret = true;
331         NTSTATUS status;
332         struct smb2_handle h1, h2;
333         uint8_t buf[200];
334         struct smb2_lock lck;
335         struct smb2_create cr;
336         struct smb2_write wr;
337         struct smb2_read rd;
338         struct smb2_lock_element el[1];
339
340         lck.in.locks            = el;
341
342         ZERO_STRUCT(buf);
343
344         status = torture_smb2_testfile(tree, s->fname, &h1);
345         CHECK_STATUS(status, NT_STATUS_OK);
346
347         status = smb2_util_write(tree, h1, buf, 0, ARRAY_SIZE(buf));
348         CHECK_STATUS(status, NT_STATUS_OK);
349
350         lck.in.lock_count       = 0x0001;
351         lck.in.reserved         = 0x00000000;
352         lck.in.file.handle      = h1;
353         el[0].offset            = 0;
354         el[0].length            = ARRAY_SIZE(buf)/2;
355         el[0].reserved          = 0x00000000;
356         el[0].flags             = s->lock_flags;
357         status = smb2_lock(tree, &lck);
358         CHECK_STATUS(status, NT_STATUS_OK);
359         CHECK_VALUE(lck.out.reserved, 0);
360
361         lck.in.lock_count       = 0x0001;
362         lck.in.reserved         = 0x00000000;
363         lck.in.file.handle      = h1;
364         el[0].offset            = ARRAY_SIZE(buf)/2;
365         el[0].length            = ARRAY_SIZE(buf)/2;
366         el[0].reserved          = 0x00000000;
367         el[0].flags             = s->lock_flags;
368         status = smb2_lock(tree, &lck);
369         CHECK_STATUS(status, NT_STATUS_OK);
370         CHECK_VALUE(lck.out.reserved, 0);
371
372         ZERO_STRUCT(cr);
373         cr.in.oplock_level = 0;
374         cr.in.desired_access = SEC_RIGHTS_FILE_ALL;
375         cr.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
376         cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
377         cr.in.share_access = 
378                 NTCREATEX_SHARE_ACCESS_DELETE|
379                 NTCREATEX_SHARE_ACCESS_READ|
380                 NTCREATEX_SHARE_ACCESS_WRITE;
381         cr.in.create_options = 0;
382         cr.in.fname = s->fname;
383
384         status = smb2_create(tree, tree, &cr);
385         CHECK_STATUS(status, NT_STATUS_OK);
386
387         h2 = cr.out.file.handle;
388
389         ZERO_STRUCT(wr);
390         wr.in.file.handle = h1;
391         wr.in.offset      = ARRAY_SIZE(buf)/2;
392         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
393
394         status = smb2_write(tree, &wr);
395         CHECK_STATUS(status, s->write_h1_status);
396
397         ZERO_STRUCT(rd);
398         rd.in.file.handle = h1;
399         rd.in.offset      = ARRAY_SIZE(buf)/2;
400         rd.in.length      = ARRAY_SIZE(buf)/2;
401
402         status = smb2_read(tree, tree, &rd);
403         CHECK_STATUS(status, s->read_h1_status);
404
405         ZERO_STRUCT(wr);
406         wr.in.file.handle = h2;
407         wr.in.offset      = ARRAY_SIZE(buf)/2;
408         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
409
410         status = smb2_write(tree, &wr);
411         CHECK_STATUS(status, s->write_h2_status);
412
413         ZERO_STRUCT(rd);
414         rd.in.file.handle = h2;
415         rd.in.offset      = ARRAY_SIZE(buf)/2;
416         rd.in.length      = ARRAY_SIZE(buf)/2;
417
418         status = smb2_read(tree, tree, &rd);
419         CHECK_STATUS(status, s->read_h2_status);
420
421         lck.in.lock_count       = 0x0001;
422         lck.in.reserved         = 0x00000000;
423         lck.in.file.handle      = h1;
424         el[0].offset            = ARRAY_SIZE(buf)/2;
425         el[0].length            = ARRAY_SIZE(buf)/2;
426         el[0].reserved          = 0x00000000;
427         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
428         status = smb2_lock(tree, &lck);
429         CHECK_STATUS(status, NT_STATUS_OK);
430         CHECK_VALUE(lck.out.reserved, 0);
431
432         ZERO_STRUCT(wr);
433         wr.in.file.handle = h2;
434         wr.in.offset      = ARRAY_SIZE(buf)/2;
435         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
436
437         status = smb2_write(tree, &wr);
438         CHECK_STATUS(status, NT_STATUS_OK);
439
440         ZERO_STRUCT(rd);
441         rd.in.file.handle = h2;
442         rd.in.offset      = ARRAY_SIZE(buf)/2;
443         rd.in.length      = ARRAY_SIZE(buf)/2;
444
445         status = smb2_read(tree, tree, &rd);
446         CHECK_STATUS(status, NT_STATUS_OK);
447
448 done:
449         return ret;
450 }
451
452 static bool test_lock_rw_none(struct torture_context *torture,
453                               struct smb2_tree *tree)
454 {
455         struct test_lock_read_write_state s = {
456                 .fname                  = "lock_rw_none.dat",
457                 .lock_flags             = SMB2_LOCK_FLAG_NONE,
458                 .write_h1_status        = NT_STATUS_FILE_LOCK_CONFLICT,
459                 .read_h1_status         = NT_STATUS_OK,
460                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
461                 .read_h2_status         = NT_STATUS_OK,
462         };
463
464         if (!TARGET_IS_W2K8(torture)) {
465                 torture_skip(torture, "RW-NONE tests the behavior of a "
466                              "NONE-type lock, which is the same as a SHARED "
467                              "lock but is granted due to a bug in W2K8.  If "
468                              "target is not W2K8 we skip this test.\n");
469         }
470
471         return test_lock_read_write(torture, tree, &s);
472 }
473
474 static bool test_lock_rw_shared(struct torture_context *torture,
475                                 struct smb2_tree *tree)
476 {
477         struct test_lock_read_write_state s = {
478                 .fname                  = "lock_rw_shared.dat",
479                 .lock_flags             = SMB2_LOCK_FLAG_SHARED,
480                 .write_h1_status        = NT_STATUS_FILE_LOCK_CONFLICT,
481                 .read_h1_status         = NT_STATUS_OK,
482                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
483                 .read_h2_status         = NT_STATUS_OK,
484         };
485
486         return test_lock_read_write(torture, tree, &s);
487 }
488
489 static bool test_lock_rw_exclusive(struct torture_context *torture,
490                                    struct smb2_tree *tree)
491 {
492         struct test_lock_read_write_state s = {
493                 .fname                  = "lock_rw_exclusive.dat",
494                 .lock_flags             = SMB2_LOCK_FLAG_EXCLUSIVE,
495                 .write_h1_status        = NT_STATUS_OK,
496                 .read_h1_status         = NT_STATUS_OK,
497                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
498                 .read_h2_status         = NT_STATUS_FILE_LOCK_CONFLICT,
499         };
500
501         return test_lock_read_write(torture, tree, &s);
502 }
503
504 static bool test_lock_auto_unlock(struct torture_context *torture,
505                                   struct smb2_tree *tree)
506 {
507         bool ret = true;
508         NTSTATUS status;
509         struct smb2_handle h;
510         uint8_t buf[200];
511         struct smb2_lock lck;
512         struct smb2_lock_element el[2];
513
514         ZERO_STRUCT(buf);
515
516         status = torture_smb2_testfile(tree, "autounlock.txt", &h);
517         CHECK_STATUS(status, NT_STATUS_OK);
518
519         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
520         CHECK_STATUS(status, NT_STATUS_OK);
521
522         ZERO_STRUCT(lck);
523         lck.in.locks            = el;
524         lck.in.lock_count       = 0x0001;
525         lck.in.file.handle      = h;
526         el[0].offset            = 0;
527         el[0].length            = 1;
528         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
529                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
530         status = smb2_lock(tree, &lck);
531         CHECK_STATUS(status, NT_STATUS_OK);
532
533         status = smb2_lock(tree, &lck);
534         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
535
536         status = smb2_lock(tree, &lck);
537         if (TARGET_IS_W2K8(torture)) {
538                 CHECK_STATUS(status, NT_STATUS_OK);
539                 torture_warning(torture, "Target has \"pretty please\" bug. "
540                                 "Every other contending lock request "
541                                 "succeeds.");
542         } else {
543                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
544         }
545
546         status = smb2_lock(tree, &lck);
547         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
548
549 done:
550         return ret;
551 }
552
553
554 /* basic testing of SMB2 locking
555 */
556 struct torture_suite *torture_smb2_lock_init(void)
557 {
558         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LOCK");
559
560         torture_suite_add_1smb2_test(suite, "VALID-REQUEST", test_valid_request);
561         torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none);
562         torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared);
563         torture_suite_add_1smb2_test(suite, "RW-EXCLUSIVE", test_lock_rw_exclusive);
564         torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK", test_lock_auto_unlock);
565
566         suite->description = talloc_strdup(suite, "SMB2-LOCK tests");
567
568         return suite;
569 }
570