s4:torture/smb2: fix and improve the smb2.lock.replay test
[bbaumbach/samba-autobuild/.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 #include "../libcli/smb/smbXcli_base.h"
26
27 #include "torture/torture.h"
28 #include "torture/smb2/proto.h"
29 #include "torture/util.h"
30
31 #include "lib/events/events.h"
32 #include "param/param.h"
33
34 #define CHECK_STATUS(status, correct) do { \
35         const char *_cmt = "(" __location__ ")"; \
36         torture_assert_ntstatus_equal_goto(torture,status,correct, \
37                                            ret,done,_cmt); \
38         } while (0)
39
40 #define CHECK_STATUS_CMT(status, correct, cmt) do { \
41         torture_assert_ntstatus_equal_goto(torture,status,correct, \
42                                            ret,done,cmt); \
43         } while (0)
44
45 #define CHECK_STATUS_CONT(status, correct) do { \
46         if (!NT_STATUS_EQUAL(status, correct)) { \
47                 torture_result(torture, TORTURE_FAIL, \
48                         "(%s) Incorrect status %s - should be %s\n", \
49                         __location__, nt_errstr(status), nt_errstr(correct)); \
50                 ret = false; \
51         }} while (0)
52
53 #define CHECK_VALUE(v, correct) do { \
54         const char *_cmt = "(" __location__ ")"; \
55         torture_assert_int_equal_goto(torture,v,correct,ret,done,_cmt); \
56         } while (0)
57
58 #define BASEDIR "testlock"
59
60 #define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
61     (torture_setting_bool(_tctx, "invalid_lock_range_support", true))
62 #define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
63
64 #define WAIT_FOR_ASYNC_RESPONSE(req) \
65         while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
66                 if (tevent_loop_once(torture->ev) != 0) { \
67                         break; \
68                 } \
69         }
70
71 static bool test_valid_request(struct torture_context *torture,
72                                struct smb2_tree *tree)
73 {
74         bool ret = true;
75         NTSTATUS status;
76         struct smb2_handle h;
77         uint8_t buf[200];
78         struct smb2_lock lck;
79         struct smb2_lock_element el[2];
80
81         ZERO_STRUCT(buf);
82
83         status = torture_smb2_testfile(tree, "lock1.txt", &h);
84         CHECK_STATUS(status, NT_STATUS_OK);
85
86         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
87         CHECK_STATUS(status, NT_STATUS_OK);
88
89         lck.in.locks            = el;
90
91         torture_comment(torture, "Test request with 0 locks.\n");
92
93         lck.in.lock_count       = 0x0000;
94         lck.in.lock_sequence    = 0x00000000;
95         lck.in.file.handle      = h;
96         el[0].offset            = 0x0000000000000000;
97         el[0].length            = 0x0000000000000000;
98         el[0].reserved          = 0x0000000000000000;
99         el[0].flags             = 0x00000000;
100         status = smb2_lock(tree, &lck);
101         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
102
103         lck.in.lock_count       = 0x0000;
104         lck.in.lock_sequence    = 0x00000000;
105         lck.in.file.handle      = h;
106         el[0].offset            = 0;
107         el[0].length            = 0;
108         el[0].reserved          = 0x00000000;
109         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
110         status = smb2_lock(tree, &lck);
111         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
112
113         lck.in.lock_count       = 0x0001;
114         lck.in.lock_sequence    = 0x00000000;
115         lck.in.file.handle      = h;
116         el[0].offset            = 0;
117         el[0].length            = 0;
118         el[0].reserved          = 0x00000000;
119         el[0].flags             = SMB2_LOCK_FLAG_NONE;
120         status = smb2_lock(tree, &lck);
121         if (TARGET_IS_W2K8(torture)) {
122                 CHECK_STATUS(status, NT_STATUS_OK);
123                 torture_warning(torture, "Target has bug validating lock flags "
124                                          "parameter.\n");
125         } else {
126                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
127         }
128
129         torture_comment(torture, "Test >63-bit lock requests.\n");
130
131         lck.in.file.handle.data[0] +=1;
132         status = smb2_lock(tree, &lck);
133         CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
134         lck.in.file.handle.data[0] -=1;
135
136         lck.in.lock_count       = 0x0001;
137         lck.in.lock_sequence    = 0x123ab1;
138         lck.in.file.handle      = h;
139         el[0].offset            = UINT64_MAX;
140         el[0].length            = UINT64_MAX;
141         el[0].reserved          = 0x00000000;
142         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
143                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
144         status = smb2_lock(tree, &lck);
145         if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
146                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
147         } else {
148                 CHECK_STATUS(status, NT_STATUS_OK);
149                 CHECK_VALUE(lck.out.reserved, 0);
150         }
151
152         lck.in.lock_sequence    = 0x123ab2;
153         status = smb2_lock(tree, &lck);
154         if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
155                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
156         } else {
157                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
158         }
159
160         torture_comment(torture, "Test basic lock stacking.\n");
161
162         lck.in.lock_count       = 0x0001;
163         lck.in.lock_sequence    = 0x12345678;
164         lck.in.file.handle      = h;
165         el[0].offset            = UINT32_MAX;
166         el[0].length            = UINT32_MAX;
167         el[0].reserved          = 0x87654321;
168         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
169                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
170         status = smb2_lock(tree, &lck);
171         CHECK_STATUS(status, NT_STATUS_OK);
172         CHECK_VALUE(lck.out.reserved, 0);
173
174         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
175         status = smb2_lock(tree, &lck);
176         CHECK_STATUS(status, NT_STATUS_OK);
177         CHECK_VALUE(lck.out.reserved, 0);
178
179         status = smb2_lock(tree, &lck);
180         CHECK_STATUS(status, NT_STATUS_OK);
181         CHECK_VALUE(lck.out.reserved, 0);
182
183         lck.in.lock_count       = 0x0001;
184         lck.in.lock_sequence    = 0x87654321;
185         lck.in.file.handle      = h;
186         el[0].offset            = 0x00000000FFFFFFFF;
187         el[0].length            = 0x00000000FFFFFFFF;
188         el[0].reserved          = 0x1234567;
189         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
190         status = smb2_lock(tree, &lck);
191         CHECK_STATUS(status, NT_STATUS_OK);
192
193         lck.in.lock_count       = 0x0001;
194         lck.in.lock_sequence    = 0x1234567;
195         lck.in.file.handle      = h;
196         el[0].offset            = 0x00000000FFFFFFFF;
197         el[0].length            = 0x00000000FFFFFFFF;
198         el[0].reserved          = 0x00000000;
199         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
200         status = smb2_lock(tree, &lck);
201         CHECK_STATUS(status, NT_STATUS_OK);
202
203         status = smb2_lock(tree, &lck);
204         CHECK_STATUS(status, NT_STATUS_OK);
205         status = smb2_lock(tree, &lck);
206         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
207
208         torture_comment(torture, "Test flags field permutations.\n");
209
210         lck.in.lock_count       = 0x0001;
211         lck.in.lock_sequence    = 0;
212         lck.in.file.handle      = h;
213         el[0].offset            = 1;
214         el[0].length            = 1;
215         el[0].reserved          = 0x00000000;
216         el[0].flags             = ~SMB2_LOCK_FLAG_ALL_MASK;
217
218         status = smb2_lock(tree, &lck);
219         if (TARGET_IS_W2K8(torture)) {
220                 CHECK_STATUS(status, NT_STATUS_OK);
221                 torture_warning(torture, "Target has bug validating lock flags "
222                                          "parameter.\n");
223         } else {
224                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
225         }
226
227         if (TARGET_IS_W2K8(torture)) {
228                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
229                 status = smb2_lock(tree, &lck);
230                 CHECK_STATUS(status, NT_STATUS_OK);
231         }
232
233         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
234         status = smb2_lock(tree, &lck);
235         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
236
237         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
238                                   SMB2_LOCK_FLAG_EXCLUSIVE;
239         status = smb2_lock(tree, &lck);
240         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
241
242         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
243                                   SMB2_LOCK_FLAG_SHARED;
244         status = smb2_lock(tree, &lck);
245         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
246
247         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK |
248                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
249         status = smb2_lock(tree, &lck);
250         if (TARGET_IS_W2K8(torture)) {
251                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
252                 torture_warning(torture, "Target has bug validating lock flags "
253                                          "parameter.\n");
254         } else {
255                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
256         }
257
258         torture_comment(torture, "Test return error when 2 locks are "
259                                  "requested\n");
260
261         lck.in.lock_count       = 2;
262         lck.in.lock_sequence    = 0;
263         lck.in.file.handle      = h;
264         el[0].offset            = 9999;
265         el[0].length            = 1;
266         el[0].reserved          = 0x00000000;
267         el[1].offset            = 9999;
268         el[1].length            = 1;
269         el[1].reserved          = 0x00000000;
270
271         lck.in.lock_count       = 2;
272         el[0].flags             = 0;
273         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
274         status = smb2_lock(tree, &lck);
275         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
276
277         lck.in.lock_count       = 2;
278         el[0].flags = SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
279         el[1].flags = SMB2_LOCK_FLAG_SHARED;
280         status = smb2_lock(tree, &lck);
281         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
282
283         lck.in.lock_count       = 2;
284         el[0].flags             = 0;
285         el[1].flags             = 0;
286         status = smb2_lock(tree, &lck);
287         if (TARGET_IS_W2K8(torture)) {
288                 CHECK_STATUS(status, NT_STATUS_OK);
289                 torture_warning(torture, "Target has bug validating lock flags "
290                                          "parameter.\n");
291         } else {
292                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
293         }
294
295         lck.in.lock_count       = 2;
296         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
297         el[1].flags             = 0;
298         status = smb2_lock(tree, &lck);
299         if (TARGET_IS_W2K8(torture)) {
300                 CHECK_STATUS(status, NT_STATUS_OK);
301                 torture_warning(torture, "Target has bug validating lock flags "
302                                          "parameter.\n");
303         } else {
304                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
305         }
306
307         lck.in.lock_count       = 1;
308         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
309         status = smb2_lock(tree, &lck);
310         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
311
312         lck.in.lock_count       = 1;
313         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
314         status = smb2_lock(tree, &lck);
315         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
316
317         lck.in.lock_count       = 1;
318         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
319         status = smb2_lock(tree, &lck);
320         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
321
322         lck.in.lock_count       = 1;
323         el[0].flags             = SMB2_LOCK_FLAG_SHARED;
324         status = smb2_lock(tree, &lck);
325         CHECK_STATUS(status, NT_STATUS_OK);
326
327         status = smb2_lock(tree, &lck);
328         CHECK_STATUS(status, NT_STATUS_OK);
329
330         lck.in.lock_count       = 2;
331         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
332         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
333         status = smb2_lock(tree, &lck);
334         CHECK_STATUS(status, NT_STATUS_OK);
335
336         lck.in.lock_count       = 1;
337         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
338         status = smb2_lock(tree, &lck);
339         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
340
341 done:
342         return ret;
343 }
344
345 struct test_lock_read_write_state {
346         const char *fname;
347         uint32_t lock_flags;
348         NTSTATUS write_h1_status;
349         NTSTATUS read_h1_status;
350         NTSTATUS write_h2_status;
351         NTSTATUS read_h2_status;
352 };
353
354 static bool test_lock_read_write(struct torture_context *torture,
355                                  struct smb2_tree *tree,
356                                  struct test_lock_read_write_state *s)
357 {
358         bool ret = true;
359         NTSTATUS status;
360         struct smb2_handle h1, h2;
361         uint8_t buf[200];
362         struct smb2_lock lck;
363         struct smb2_create cr;
364         struct smb2_write wr;
365         struct smb2_read rd;
366         struct smb2_lock_element el[1];
367
368         lck.in.locks            = el;
369
370         ZERO_STRUCT(buf);
371
372         status = torture_smb2_testfile(tree, s->fname, &h1);
373         CHECK_STATUS(status, NT_STATUS_OK);
374
375         status = smb2_util_write(tree, h1, buf, 0, ARRAY_SIZE(buf));
376         CHECK_STATUS(status, NT_STATUS_OK);
377
378         lck.in.lock_count       = 0x0001;
379         lck.in.lock_sequence    = 0x00000000;
380         lck.in.file.handle      = h1;
381         el[0].offset            = 0;
382         el[0].length            = ARRAY_SIZE(buf)/2;
383         el[0].reserved          = 0x00000000;
384         el[0].flags             = s->lock_flags;
385         status = smb2_lock(tree, &lck);
386         CHECK_STATUS(status, NT_STATUS_OK);
387         CHECK_VALUE(lck.out.reserved, 0);
388
389         lck.in.lock_count       = 0x0001;
390         lck.in.lock_sequence    = 0x00000000;
391         lck.in.file.handle      = h1;
392         el[0].offset            = ARRAY_SIZE(buf)/2;
393         el[0].length            = ARRAY_SIZE(buf)/2;
394         el[0].reserved          = 0x00000000;
395         el[0].flags             = s->lock_flags;
396         status = smb2_lock(tree, &lck);
397         CHECK_STATUS(status, NT_STATUS_OK);
398         CHECK_VALUE(lck.out.reserved, 0);
399
400         ZERO_STRUCT(cr);
401         cr.in.oplock_level = 0;
402         cr.in.desired_access = SEC_RIGHTS_FILE_ALL;
403         cr.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
404         cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
405         cr.in.share_access =
406                 NTCREATEX_SHARE_ACCESS_DELETE|
407                 NTCREATEX_SHARE_ACCESS_READ|
408                 NTCREATEX_SHARE_ACCESS_WRITE;
409         cr.in.create_options = 0;
410         cr.in.fname = s->fname;
411
412         status = smb2_create(tree, tree, &cr);
413         CHECK_STATUS(status, NT_STATUS_OK);
414
415         h2 = cr.out.file.handle;
416
417         ZERO_STRUCT(wr);
418         wr.in.file.handle = h1;
419         wr.in.offset      = ARRAY_SIZE(buf)/2;
420         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
421
422         status = smb2_write(tree, &wr);
423         CHECK_STATUS(status, s->write_h1_status);
424
425         ZERO_STRUCT(rd);
426         rd.in.file.handle = h1;
427         rd.in.offset      = ARRAY_SIZE(buf)/2;
428         rd.in.length      = ARRAY_SIZE(buf)/2;
429
430         status = smb2_read(tree, tree, &rd);
431         CHECK_STATUS(status, s->read_h1_status);
432
433         ZERO_STRUCT(wr);
434         wr.in.file.handle = h2;
435         wr.in.offset      = ARRAY_SIZE(buf)/2;
436         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
437
438         status = smb2_write(tree, &wr);
439         CHECK_STATUS(status, s->write_h2_status);
440
441         ZERO_STRUCT(rd);
442         rd.in.file.handle = h2;
443         rd.in.offset      = ARRAY_SIZE(buf)/2;
444         rd.in.length      = ARRAY_SIZE(buf)/2;
445
446         status = smb2_read(tree, tree, &rd);
447         CHECK_STATUS(status, s->read_h2_status);
448
449         lck.in.lock_count       = 0x0001;
450         lck.in.lock_sequence    = 0x00000000;
451         lck.in.file.handle      = h1;
452         el[0].offset            = ARRAY_SIZE(buf)/2;
453         el[0].length            = ARRAY_SIZE(buf)/2;
454         el[0].reserved          = 0x00000000;
455         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
456         status = smb2_lock(tree, &lck);
457         CHECK_STATUS(status, NT_STATUS_OK);
458         CHECK_VALUE(lck.out.reserved, 0);
459
460         ZERO_STRUCT(wr);
461         wr.in.file.handle = h2;
462         wr.in.offset      = ARRAY_SIZE(buf)/2;
463         wr.in.data        = data_blob_const(buf, ARRAY_SIZE(buf)/2);
464
465         status = smb2_write(tree, &wr);
466         CHECK_STATUS(status, NT_STATUS_OK);
467
468         ZERO_STRUCT(rd);
469         rd.in.file.handle = h2;
470         rd.in.offset      = ARRAY_SIZE(buf)/2;
471         rd.in.length      = ARRAY_SIZE(buf)/2;
472
473         status = smb2_read(tree, tree, &rd);
474         CHECK_STATUS(status, NT_STATUS_OK);
475
476 done:
477         return ret;
478 }
479
480 static bool test_lock_rw_none(struct torture_context *torture,
481                               struct smb2_tree *tree)
482 {
483         struct test_lock_read_write_state s = {
484                 .fname                  = "lock_rw_none.dat",
485                 .lock_flags             = SMB2_LOCK_FLAG_NONE,
486                 .write_h1_status        = NT_STATUS_FILE_LOCK_CONFLICT,
487                 .read_h1_status         = NT_STATUS_OK,
488                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
489                 .read_h2_status         = NT_STATUS_OK,
490         };
491
492         if (!TARGET_IS_W2K8(torture)) {
493                 torture_skip(torture, "RW-NONE tests the behavior of a "
494                              "NONE-type lock, which is the same as a SHARED "
495                              "lock but is granted due to a bug in W2K8.  If "
496                              "target is not W2K8 we skip this test.\n");
497         }
498
499         return test_lock_read_write(torture, tree, &s);
500 }
501
502 static bool test_lock_rw_shared(struct torture_context *torture,
503                                 struct smb2_tree *tree)
504 {
505         struct test_lock_read_write_state s = {
506                 .fname                  = "lock_rw_shared.dat",
507                 .lock_flags             = SMB2_LOCK_FLAG_SHARED,
508                 .write_h1_status        = NT_STATUS_FILE_LOCK_CONFLICT,
509                 .read_h1_status         = NT_STATUS_OK,
510                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
511                 .read_h2_status         = NT_STATUS_OK,
512         };
513
514         return test_lock_read_write(torture, tree, &s);
515 }
516
517 static bool test_lock_rw_exclusive(struct torture_context *torture,
518                                    struct smb2_tree *tree)
519 {
520         struct test_lock_read_write_state s = {
521                 .fname                  = "lock_rw_exclusive.dat",
522                 .lock_flags             = SMB2_LOCK_FLAG_EXCLUSIVE,
523                 .write_h1_status        = NT_STATUS_OK,
524                 .read_h1_status         = NT_STATUS_OK,
525                 .write_h2_status        = NT_STATUS_FILE_LOCK_CONFLICT,
526                 .read_h2_status         = NT_STATUS_FILE_LOCK_CONFLICT,
527         };
528
529         return test_lock_read_write(torture, tree, &s);
530 }
531
532 static bool test_lock_auto_unlock(struct torture_context *torture,
533                                   struct smb2_tree *tree)
534 {
535         bool ret = true;
536         NTSTATUS status;
537         struct smb2_handle h;
538         uint8_t buf[200];
539         struct smb2_lock lck;
540         struct smb2_lock_element el[1];
541
542         ZERO_STRUCT(buf);
543
544         status = torture_smb2_testfile(tree, "autounlock.txt", &h);
545         CHECK_STATUS(status, NT_STATUS_OK);
546
547         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
548         CHECK_STATUS(status, NT_STATUS_OK);
549
550         ZERO_STRUCT(lck);
551         ZERO_STRUCT(el[0]);
552         lck.in.locks            = el;
553         lck.in.lock_count       = 0x0001;
554         lck.in.file.handle      = h;
555         el[0].offset            = 0;
556         el[0].length            = 1;
557         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
558                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
559         status = smb2_lock(tree, &lck);
560         CHECK_STATUS(status, NT_STATUS_OK);
561
562         status = smb2_lock(tree, &lck);
563         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
564
565         status = smb2_lock(tree, &lck);
566         if (TARGET_IS_W2K8(torture)) {
567                 CHECK_STATUS(status, NT_STATUS_OK);
568                 torture_warning(torture, "Target has \"pretty please\" bug. "
569                                 "A contending lock request on the same handle "
570                                 "unlocks the lock.\n");
571         } else {
572                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
573         }
574
575         status = smb2_lock(tree, &lck);
576         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
577
578 done:
579         return ret;
580 }
581
582 /*
583   test different lock ranges and see if different handles conflict
584 */
585 static bool test_lock(struct torture_context *torture,
586                       struct smb2_tree *tree)
587 {
588         NTSTATUS status;
589         bool ret = true;
590         struct smb2_handle h = {{0}};
591         struct smb2_handle h2 = {{0}};
592         uint8_t buf[200];
593         struct smb2_lock lck;
594         struct smb2_lock_element el[2];
595
596         const char *fname = BASEDIR "\\async.txt";
597
598         status = torture_smb2_testdir(tree, BASEDIR, &h);
599         CHECK_STATUS(status, NT_STATUS_OK);
600         smb2_util_close(tree, h);
601
602         status = torture_smb2_testfile(tree, fname, &h);
603         CHECK_STATUS(status, NT_STATUS_OK);
604
605         ZERO_STRUCT(buf);
606         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
607         CHECK_STATUS(status, NT_STATUS_OK);
608
609         status = torture_smb2_testfile(tree, fname, &h2);
610         CHECK_STATUS(status, NT_STATUS_OK);
611
612         lck.in.locks            = el;
613
614         lck.in.lock_count       = 0x0001;
615         lck.in.lock_sequence    = 0x00000000;
616         lck.in.file.handle      = h;
617         el[0].reserved          = 0x00000000;
618         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
619                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
620
621         torture_comment(torture, "Trying 0/0 lock\n");
622         el[0].offset            = 0x0000000000000000;
623         el[0].length            = 0x0000000000000000;
624         status = smb2_lock(tree, &lck);
625         CHECK_STATUS(status, NT_STATUS_OK);
626         lck.in.file.handle      = h2;
627         status = smb2_lock(tree, &lck);
628         CHECK_STATUS(status, NT_STATUS_OK);
629         lck.in.file.handle      = h;
630         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
631         status = smb2_lock(tree, &lck);
632         CHECK_STATUS(status, NT_STATUS_OK);
633
634         torture_comment(torture, "Trying 0/1 lock\n");
635         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
636                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
637         el[0].offset            = 0x0000000000000000;
638         el[0].length            = 0x0000000000000001;
639         status = smb2_lock(tree, &lck);
640         CHECK_STATUS(status, NT_STATUS_OK);
641         lck.in.file.handle      = h2;
642         status = smb2_lock(tree, &lck);
643         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
644         lck.in.file.handle      = h;
645         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
646         status = smb2_lock(tree, &lck);
647         CHECK_STATUS(status, NT_STATUS_OK);
648         status = smb2_lock(tree, &lck);
649         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
650
651         torture_comment(torture, "Trying 0xEEFFFFF lock\n");
652         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
653                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
654         el[0].offset            = 0xEEFFFFFF;
655         el[0].length            = 4000;
656         status = smb2_lock(tree, &lck);
657         CHECK_STATUS(status, NT_STATUS_OK);
658         lck.in.file.handle      = h2;
659         status = smb2_lock(tree, &lck);
660         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
661         lck.in.file.handle      = h;
662         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
663         status = smb2_lock(tree, &lck);
664         CHECK_STATUS(status, NT_STATUS_OK);
665         status = smb2_lock(tree, &lck);
666         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
667
668         torture_comment(torture, "Trying 0xEF00000 lock\n");
669         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
670                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
671         el[0].offset            = 0xEF000000;
672         el[0].length            = 4000;
673         status = smb2_lock(tree, &lck);
674         CHECK_STATUS(status, NT_STATUS_OK);
675         lck.in.file.handle      = h2;
676         status = smb2_lock(tree, &lck);
677         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
678         lck.in.file.handle      = h;
679         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
680         status = smb2_lock(tree, &lck);
681         CHECK_STATUS(status, NT_STATUS_OK);
682         status = smb2_lock(tree, &lck);
683         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
684
685         torture_comment(torture, "Trying (2^63 - 1)/1\n");
686         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
687                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
688         el[0].offset            = 1;
689         el[0].offset          <<= 63;
690         el[0].offset--;
691         el[0].length            = 1;
692         status = smb2_lock(tree, &lck);
693         CHECK_STATUS(status, NT_STATUS_OK);
694         lck.in.file.handle      = h2;
695         status = smb2_lock(tree, &lck);
696         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
697         lck.in.file.handle      = h;
698         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
699         status = smb2_lock(tree, &lck);
700         CHECK_STATUS(status, NT_STATUS_OK);
701         status = smb2_lock(tree, &lck);
702         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
703
704         torture_comment(torture, "Trying 2^63/1\n");
705         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
706                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
707         el[0].offset            = 1;
708         el[0].offset          <<= 63;
709         el[0].length            = 1;
710         status = smb2_lock(tree, &lck);
711         CHECK_STATUS(status, NT_STATUS_OK);
712         lck.in.file.handle      = h2;
713         status = smb2_lock(tree, &lck);
714         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
715         lck.in.file.handle      = h;
716         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
717         status = smb2_lock(tree, &lck);
718         CHECK_STATUS(status, NT_STATUS_OK);
719         status = smb2_lock(tree, &lck);
720         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
721
722         torture_comment(torture, "Trying max/0 lock\n");
723         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
724                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
725         el[0].offset            = ~0;
726         el[0].length            = 0;
727         status = smb2_lock(tree, &lck);
728         CHECK_STATUS(status, NT_STATUS_OK);
729         lck.in.file.handle      = h2;
730         status = smb2_lock(tree, &lck);
731         CHECK_STATUS(status, NT_STATUS_OK);
732         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
733         status = smb2_lock(tree, &lck);
734         CHECK_STATUS(status, NT_STATUS_OK);
735         lck.in.file.handle      = h;
736         status = smb2_lock(tree, &lck);
737         CHECK_STATUS(status, NT_STATUS_OK);
738         status = smb2_lock(tree, &lck);
739         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
740
741         torture_comment(torture, "Trying max/1 lock\n");
742         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
743                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
744         el[0].offset            = ~0;
745         el[0].length            = 1;
746         status = smb2_lock(tree, &lck);
747         CHECK_STATUS(status, NT_STATUS_OK);
748         lck.in.file.handle      = h2;
749         status = smb2_lock(tree, &lck);
750         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
751         lck.in.file.handle      = h;
752         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
753         status = smb2_lock(tree, &lck);
754         CHECK_STATUS(status, NT_STATUS_OK);
755         status = smb2_lock(tree, &lck);
756         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
757
758         torture_comment(torture, "Trying max/2 lock\n");
759         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
760                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
761         el[0].offset            = ~0;
762         el[0].length            = 2;
763         status = smb2_lock(tree, &lck);
764         if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
765                 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
766         } else {
767                 CHECK_STATUS(status, NT_STATUS_OK);
768                 el[0].flags     = SMB2_LOCK_FLAG_UNLOCK;
769                 status = smb2_lock(tree, &lck);
770                 CHECK_STATUS(status, NT_STATUS_OK);
771         }
772
773         torture_comment(torture, "Trying wrong handle unlock\n");
774         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
775                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
776         el[0].offset            = 10001;
777         el[0].length            = 40002;
778         status = smb2_lock(tree, &lck);
779         CHECK_STATUS(status, NT_STATUS_OK);
780         lck.in.file.handle      = h2;
781         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
782         status = smb2_lock(tree, &lck);
783         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
784         lck.in.file.handle      = h;
785         status = smb2_lock(tree, &lck);
786         CHECK_STATUS(status, NT_STATUS_OK);
787
788 done:
789         smb2_util_close(tree, h2);
790         smb2_util_close(tree, h);
791         smb2_deltree(tree, BASEDIR);
792         return ret;
793 }
794
795 /*
796   test SMB2 LOCK async operation
797 */
798 static bool test_async(struct torture_context *torture,
799                        struct smb2_tree *tree)
800 {
801         NTSTATUS status;
802         bool ret = true;
803         struct smb2_handle h = {{0}};
804         struct smb2_handle h2 = {{0}};
805         uint8_t buf[200];
806         struct smb2_lock lck;
807         struct smb2_lock_element el[2];
808         struct smb2_request *req = NULL;
809
810         const char *fname = BASEDIR "\\async.txt";
811
812         status = torture_smb2_testdir(tree, BASEDIR, &h);
813         CHECK_STATUS(status, NT_STATUS_OK);
814         smb2_util_close(tree, h);
815
816         status = torture_smb2_testfile(tree, fname, &h);
817         CHECK_STATUS(status, NT_STATUS_OK);
818
819         ZERO_STRUCT(buf);
820         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
821         CHECK_STATUS(status, NT_STATUS_OK);
822
823         status = torture_smb2_testfile(tree, fname, &h2);
824         CHECK_STATUS(status, NT_STATUS_OK);
825
826         lck.in.locks            = el;
827
828         lck.in.lock_count       = 0x0001;
829         lck.in.lock_sequence    = 0x00000000;
830         lck.in.file.handle      = h;
831         el[0].offset            = 100;
832         el[0].length            = 50;
833         el[0].reserved          = 0x00000000;
834         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
835
836         torture_comment(torture, "  Acquire first lock\n");
837         status = smb2_lock(tree, &lck);
838         CHECK_STATUS(status, NT_STATUS_OK);
839
840         torture_comment(torture, "  Second lock should pend on first\n");
841         lck.in.file.handle      = h2;
842         req = smb2_lock_send(tree, &lck);
843         WAIT_FOR_ASYNC_RESPONSE(req);
844
845         torture_comment(torture, "  Unlock first lock\n");
846         lck.in.file.handle      = h;
847         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
848         status = smb2_lock(tree, &lck);
849         CHECK_STATUS(status, NT_STATUS_OK);
850
851         torture_comment(torture, "  Second lock should now succeed\n");
852         lck.in.file.handle      = h2;
853         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
854         status = smb2_lock_recv(req, &lck);
855         CHECK_STATUS(status, NT_STATUS_OK);
856
857 done:
858         smb2_util_close(tree, h2);
859         smb2_util_close(tree, h);
860         smb2_deltree(tree, BASEDIR);
861         return ret;
862 }
863
864 /*
865   test SMB2 LOCK Cancel operation
866 */
867 static bool test_cancel(struct torture_context *torture,
868                         struct smb2_tree *tree)
869 {
870         NTSTATUS status;
871         bool ret = true;
872         struct smb2_handle h = {{0}};
873         struct smb2_handle h2 = {{0}};
874         uint8_t buf[200];
875         struct smb2_lock lck;
876         struct smb2_lock_element el[2];
877         struct smb2_request *req = NULL;
878
879         const char *fname = BASEDIR "\\cancel.txt";
880
881         status = torture_smb2_testdir(tree, BASEDIR, &h);
882         CHECK_STATUS(status, NT_STATUS_OK);
883         smb2_util_close(tree, h);
884
885         status = torture_smb2_testfile(tree, fname, &h);
886         CHECK_STATUS(status, NT_STATUS_OK);
887
888         ZERO_STRUCT(buf);
889         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
890         CHECK_STATUS(status, NT_STATUS_OK);
891
892         status = torture_smb2_testfile(tree, fname, &h2);
893         CHECK_STATUS(status, NT_STATUS_OK);
894
895         lck.in.locks            = el;
896
897         lck.in.lock_count       = 0x0001;
898         lck.in.lock_sequence    = 0x00000000;
899         lck.in.file.handle      = h;
900         el[0].offset            = 100;
901         el[0].length            = 10;
902         el[0].reserved          = 0x00000000;
903         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
904
905         torture_comment(torture, "Testing basic cancel\n");
906
907         torture_comment(torture, "  Acquire first lock\n");
908         status = smb2_lock(tree, &lck);
909         CHECK_STATUS(status, NT_STATUS_OK);
910
911         torture_comment(torture, "  Second lock should pend on first\n");
912         lck.in.file.handle      = h2;
913         req = smb2_lock_send(tree, &lck);
914         WAIT_FOR_ASYNC_RESPONSE(req);
915
916         torture_comment(torture, "  Cancel the second lock\n");
917         smb2_cancel(req);
918         lck.in.file.handle      = h2;
919         status = smb2_lock_recv(req, &lck);
920         CHECK_STATUS(status, NT_STATUS_CANCELLED);
921
922         torture_comment(torture, "  Unlock first lock\n");
923         lck.in.file.handle      = h;
924         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
925         status = smb2_lock(tree, &lck);
926         CHECK_STATUS(status, NT_STATUS_OK);
927
928
929         torture_comment(torture, "Testing cancel by unlock\n");
930
931         torture_comment(torture, "  Acquire first lock\n");
932         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
933         status = smb2_lock(tree, &lck);
934         CHECK_STATUS(status, NT_STATUS_OK);
935
936         torture_comment(torture, "  Second lock should pend on first\n");
937         lck.in.file.handle      = h2;
938         req = smb2_lock_send(tree, &lck);
939         WAIT_FOR_ASYNC_RESPONSE(req);
940
941         torture_comment(torture, "  Attempt to unlock pending second lock\n");
942         lck.in.file.handle      = h2;
943         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
944         status = smb2_lock(tree, &lck);
945         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
946
947         torture_comment(torture, "  Now cancel the second lock\n");
948         smb2_cancel(req);
949         lck.in.file.handle      = h2;
950         status = smb2_lock_recv(req, &lck);
951         CHECK_STATUS(status, NT_STATUS_CANCELLED);
952
953         torture_comment(torture, "  Unlock first lock\n");
954         lck.in.file.handle      = h;
955         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
956         status = smb2_lock(tree, &lck);
957         CHECK_STATUS(status, NT_STATUS_OK);
958
959
960         torture_comment(torture, "Testing cancel by close\n");
961
962         torture_comment(torture, "  Acquire first lock\n");
963         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
964         status = smb2_lock(tree, &lck);
965         CHECK_STATUS(status, NT_STATUS_OK);
966
967         torture_comment(torture, "  Second lock should pend on first\n");
968         lck.in.file.handle      = h2;
969         req = smb2_lock_send(tree, &lck);
970         WAIT_FOR_ASYNC_RESPONSE(req);
971
972         torture_comment(torture, "  Close the second lock handle\n");
973         smb2_util_close(tree, h2);
974         CHECK_STATUS(status, NT_STATUS_OK);
975
976         torture_comment(torture, "  Check pending lock reply\n");
977         status = smb2_lock_recv(req, &lck);
978         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
979
980         torture_comment(torture, "  Unlock first lock\n");
981         lck.in.file.handle      = h;
982         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
983         status = smb2_lock(tree, &lck);
984         CHECK_STATUS(status, NT_STATUS_OK);
985
986 done:
987         smb2_util_close(tree, h2);
988         smb2_util_close(tree, h);
989         smb2_deltree(tree, BASEDIR);
990         return ret;
991 }
992
993 /*
994   test SMB2 LOCK Cancel by tree disconnect
995 */
996 static bool test_cancel_tdis(struct torture_context *torture,
997                              struct smb2_tree *tree)
998 {
999         NTSTATUS status;
1000         bool ret = true;
1001         struct smb2_handle h = {{0}};
1002         struct smb2_handle h2 = {{0}};
1003         uint8_t buf[200];
1004         struct smb2_lock lck;
1005         struct smb2_lock_element el[2];
1006         struct smb2_request *req = NULL;
1007
1008         const char *fname = BASEDIR "\\cancel_tdis.txt";
1009
1010         status = torture_smb2_testdir(tree, BASEDIR, &h);
1011         CHECK_STATUS(status, NT_STATUS_OK);
1012         smb2_util_close(tree, h);
1013
1014         status = torture_smb2_testfile(tree, fname, &h);
1015         CHECK_STATUS(status, NT_STATUS_OK);
1016
1017         ZERO_STRUCT(buf);
1018         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1019         CHECK_STATUS(status, NT_STATUS_OK);
1020
1021         status = torture_smb2_testfile(tree, fname, &h2);
1022         CHECK_STATUS(status, NT_STATUS_OK);
1023
1024         lck.in.locks            = el;
1025
1026         lck.in.lock_count       = 0x0001;
1027         lck.in.lock_sequence    = 0x00000000;
1028         lck.in.file.handle      = h;
1029         el[0].offset            = 100;
1030         el[0].length            = 10;
1031         el[0].reserved          = 0x00000000;
1032         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
1033
1034         torture_comment(torture, "Testing cancel by tree disconnect\n");
1035
1036         status = torture_smb2_testfile(tree, fname, &h);
1037         CHECK_STATUS(status, NT_STATUS_OK);
1038
1039         status = torture_smb2_testfile(tree, fname, &h2);
1040         CHECK_STATUS(status, NT_STATUS_OK);
1041
1042         torture_comment(torture, "  Acquire first lock\n");
1043         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
1044         status = smb2_lock(tree, &lck);
1045         CHECK_STATUS(status, NT_STATUS_OK);
1046
1047         torture_comment(torture, "  Second lock should pend on first\n");
1048         lck.in.file.handle      = h2;
1049         req = smb2_lock_send(tree, &lck);
1050         WAIT_FOR_ASYNC_RESPONSE(req);
1051
1052         torture_comment(torture, "  Disconnect the tree\n");
1053         smb2_tdis(tree);
1054         CHECK_STATUS(status, NT_STATUS_OK);
1055
1056         torture_comment(torture, "  Check pending lock reply\n");
1057         status = smb2_lock_recv(req, &lck);
1058         if (!NT_STATUS_EQUAL(status, NT_STATUS_RANGE_NOT_LOCKED)) {
1059                 /*
1060                  * The status depends on the server internals
1061                  * the order in which the files are closed
1062                  * by smb2_tdis().
1063                  */
1064                 CHECK_STATUS(status, NT_STATUS_OK);
1065         }
1066
1067         torture_comment(torture, "  Attempt to unlock first lock\n");
1068         lck.in.file.handle      = h;
1069         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1070         status = smb2_lock(tree, &lck);
1071         /*
1072          * Most Windows versions have a strange order to
1073          * verify the session id, tree id and file id.
1074          * (They should be checked in that order, but windows
1075          *  seems to check the file id before the others).
1076          */
1077         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
1078                 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1079         }
1080
1081 done:
1082         smb2_util_close(tree, h2);
1083         smb2_util_close(tree, h);
1084         smb2_deltree(tree, BASEDIR);
1085         return ret;
1086 }
1087
1088 /*
1089   test SMB2 LOCK Cancel by user logoff
1090 */
1091 static bool test_cancel_logoff(struct torture_context *torture,
1092                                struct smb2_tree *tree)
1093 {
1094         NTSTATUS status;
1095         bool ret = true;
1096         struct smb2_handle h = {{0}};
1097         struct smb2_handle h2 = {{0}};
1098         uint8_t buf[200];
1099         struct smb2_lock lck;
1100         struct smb2_lock_element el[2];
1101         struct smb2_request *req = NULL;
1102
1103         const char *fname = BASEDIR "\\cancel_logoff.txt";
1104
1105         status = torture_smb2_testdir(tree, BASEDIR, &h);
1106         CHECK_STATUS(status, NT_STATUS_OK);
1107         smb2_util_close(tree, h);
1108
1109         status = torture_smb2_testfile(tree, fname, &h);
1110         CHECK_STATUS(status, NT_STATUS_OK);
1111
1112         ZERO_STRUCT(buf);
1113         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1114         CHECK_STATUS(status, NT_STATUS_OK);
1115
1116         status = torture_smb2_testfile(tree, fname, &h2);
1117         CHECK_STATUS(status, NT_STATUS_OK);
1118
1119         lck.in.locks            = el;
1120
1121         lck.in.lock_count       = 0x0001;
1122         lck.in.lock_sequence    = 0x00000000;
1123         lck.in.file.handle      = h;
1124         el[0].offset            = 100;
1125         el[0].length            = 10;
1126         el[0].reserved          = 0x00000000;
1127         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
1128
1129         torture_comment(torture, "Testing cancel by ulogoff\n");
1130
1131         torture_comment(torture, "  Acquire first lock\n");
1132         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE;
1133         status = smb2_lock(tree, &lck);
1134         CHECK_STATUS(status, NT_STATUS_OK);
1135
1136         torture_comment(torture, "  Second lock should pend on first\n");
1137         lck.in.file.handle      = h2;
1138         req = smb2_lock_send(tree, &lck);
1139         WAIT_FOR_ASYNC_RESPONSE(req);
1140
1141         torture_comment(torture, "  Logoff user\n");
1142         smb2_logoff(tree->session);
1143
1144         torture_comment(torture, "  Check pending lock reply\n");
1145         status = smb2_lock_recv(req, &lck);
1146         if (!NT_STATUS_EQUAL(status, NT_STATUS_RANGE_NOT_LOCKED)) {
1147                 /*
1148                  * The status depends on the server internals
1149                  * the order in which the files are closed
1150                  * by smb2_logoff().
1151                  */
1152                 CHECK_STATUS(status, NT_STATUS_OK);
1153         }
1154
1155         torture_comment(torture, "  Attempt to unlock first lock\n");
1156         lck.in.file.handle      = h;
1157         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1158         status = smb2_lock(tree, &lck);
1159         /*
1160          * Most Windows versions have a strange order to
1161          * verify the session id, tree id and file id.
1162          * (They should be checked in that order, but windows
1163          *  seems to check the file id before the others).
1164          */
1165         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
1166                 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1167         }
1168
1169 done:
1170         smb2_util_close(tree, h2);
1171         smb2_util_close(tree, h);
1172         smb2_deltree(tree, BASEDIR);
1173         return ret;
1174 }
1175
1176 /*
1177  * Test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
1178  *
1179  * The SMBv1 protocol returns a different error code on lock acquisition
1180  * failure depending on a number of parameters, including what error code
1181  * was returned to the previous failure.
1182  *
1183  * SMBv2 has cleaned up these semantics and should always return
1184  * NT_STATUS_LOCK_NOT_GRANTED to failed lock requests, and
1185  * NT_STATUS_FILE_LOCK_CONFLICT to failed read/write requests due to a lock
1186  * being held on that range.
1187 */
1188 static bool test_errorcode(struct torture_context *torture,
1189                            struct smb2_tree *tree)
1190 {
1191         NTSTATUS status;
1192         bool ret = true;
1193         struct smb2_handle h = {{0}};
1194         struct smb2_handle h2 = {{0}};
1195         uint8_t buf[200];
1196         struct smb2_lock lck;
1197         struct smb2_lock_element el[2];
1198
1199         const char *fname = BASEDIR "\\errorcode.txt";
1200
1201         status = torture_smb2_testdir(tree, BASEDIR, &h);
1202         CHECK_STATUS(status, NT_STATUS_OK);
1203         smb2_util_close(tree, h);
1204
1205         status = torture_smb2_testfile(tree, fname, &h);
1206         CHECK_STATUS(status, NT_STATUS_OK);
1207
1208         ZERO_STRUCT(buf);
1209         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1210         CHECK_STATUS(status, NT_STATUS_OK);
1211
1212         status = torture_smb2_testfile(tree, fname, &h2);
1213         CHECK_STATUS(status, NT_STATUS_OK);
1214
1215         lck.in.locks            = el;
1216
1217         lck.in.lock_count       = 0x0001;
1218         lck.in.lock_sequence    = 0x00000000;
1219         lck.in.file.handle      = h;
1220         el[0].offset            = 100;
1221         el[0].length            = 10;
1222         el[0].reserved          = 0x00000000;
1223         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1224                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1225
1226         torture_comment(torture, "Testing LOCK_NOT_GRANTED vs. "
1227                                  "FILE_LOCK_CONFLICT\n");
1228
1229         if (TARGET_IS_W2K8(torture)) {
1230                 torture_result(torture, TORTURE_SKIP,
1231                     "Target has \"pretty please\" bug. A contending lock "
1232                     "request on the same handle unlocks the lock.");
1233                 goto done;
1234         }
1235
1236         status = smb2_lock(tree, &lck);
1237         CHECK_STATUS(status, NT_STATUS_OK);
1238
1239         /* Demonstrate that the first conflicting lock on each handle gives
1240          * LOCK_NOT_GRANTED. */
1241         lck.in.file.handle      = h;
1242         status = smb2_lock(tree, &lck);
1243         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1244
1245         lck.in.file.handle      = h2;
1246         status = smb2_lock(tree, &lck);
1247         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1248
1249         /* Demonstrate that each following conflict also gives
1250          * LOCK_NOT_GRANTED */
1251         lck.in.file.handle      = h;
1252         status = smb2_lock(tree, &lck);
1253         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1254
1255         lck.in.file.handle      = h2;
1256         status = smb2_lock(tree, &lck);
1257         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1258
1259         lck.in.file.handle      = h;
1260         status = smb2_lock(tree, &lck);
1261         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1262
1263         lck.in.file.handle      = h2;
1264         status = smb2_lock(tree, &lck);
1265         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1266
1267         /* Demonstrate that the smbpid doesn't matter */
1268         lck.in.file.handle      = h;
1269         status = smb2_lock(tree, &lck);
1270         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1271
1272         lck.in.file.handle      = h2;
1273         status = smb2_lock(tree, &lck);
1274         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1275
1276         /* Demonstrate that a 0-byte lock inside the locked range still
1277          * gives the same error. */
1278
1279         el[0].offset            = 102;
1280         el[0].length            = 0;
1281         lck.in.file.handle      = h;
1282         status = smb2_lock(tree, &lck);
1283         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1284
1285         lck.in.file.handle      = h2;
1286         status = smb2_lock(tree, &lck);
1287         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1288
1289         /* Demonstrate that a lock inside the locked range still gives the
1290          * same error. */
1291
1292         el[0].offset            = 102;
1293         el[0].length            = 5;
1294         lck.in.file.handle      = h;
1295         status = smb2_lock(tree, &lck);
1296         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1297
1298         lck.in.file.handle      = h2;
1299         status = smb2_lock(tree, &lck);
1300         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1301
1302 done:
1303         smb2_util_close(tree, h2);
1304         smb2_util_close(tree, h);
1305         smb2_deltree(tree, BASEDIR);
1306         return ret;
1307 }
1308
1309 /**
1310  * Tests zero byte locks.
1311  */
1312
1313 struct double_lock_test {
1314         struct smb2_lock_element lock1;
1315         struct smb2_lock_element lock2;
1316         NTSTATUS status;
1317 };
1318
1319 static struct double_lock_test zero_byte_tests[] = {
1320         /* {offset, count, reserved, flags},
1321          * {offset, count, reserved, flags},
1322          * status */
1323
1324         /** First, takes a zero byte lock at offset 10. Then:
1325         *   - Taking 0 byte lock at 10 should succeed.
1326         *   - Taking 1 byte locks at 9,10,11 should succeed.
1327         *   - Taking 2 byte lock at 9 should fail.
1328         *   - Taking 2 byte lock at 10 should succeed.
1329         *   - Taking 3 byte lock at 9 should fail.
1330         */
1331         {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1332         {{10, 0, 0, 0}, {9, 1, 0, 0},  NT_STATUS_OK},
1333         {{10, 0, 0, 0}, {10, 1, 0, 0}, NT_STATUS_OK},
1334         {{10, 0, 0, 0}, {11, 1, 0, 0}, NT_STATUS_OK},
1335         {{10, 0, 0, 0}, {9, 2, 0, 0},  NT_STATUS_LOCK_NOT_GRANTED},
1336         {{10, 0, 0, 0}, {10, 2, 0, 0}, NT_STATUS_OK},
1337         {{10, 0, 0, 0}, {9, 3, 0, 0},  NT_STATUS_LOCK_NOT_GRANTED},
1338
1339         /** Same, but opposite order. */
1340         {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1341         {{9, 1, 0, 0},  {10, 0, 0, 0}, NT_STATUS_OK},
1342         {{10, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1343         {{11, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1344         {{9, 2, 0, 0},  {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1345         {{10, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1346         {{9, 3, 0, 0},  {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1347
1348         /** Zero zero case. */
1349         {{0, 0, 0, 0},  {0, 0, 0, 0},  NT_STATUS_OK},
1350 };
1351
1352 static bool test_zerobytelength(struct torture_context *torture,
1353                                 struct smb2_tree *tree)
1354 {
1355         NTSTATUS status;
1356         bool ret = true;
1357         struct smb2_handle h = {{0}};
1358         struct smb2_handle h2 = {{0}};
1359         uint8_t buf[200];
1360         struct smb2_lock lck;
1361         int i;
1362
1363         const char *fname = BASEDIR "\\zero.txt";
1364
1365         torture_comment(torture, "Testing zero length byte range locks:\n");
1366
1367         status = torture_smb2_testdir(tree, BASEDIR, &h);
1368         CHECK_STATUS(status, NT_STATUS_OK);
1369         smb2_util_close(tree, h);
1370
1371         status = torture_smb2_testfile(tree, fname, &h);
1372         CHECK_STATUS(status, NT_STATUS_OK);
1373
1374         ZERO_STRUCT(buf);
1375         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1376         CHECK_STATUS(status, NT_STATUS_OK);
1377
1378         status = torture_smb2_testfile(tree, fname, &h2);
1379         CHECK_STATUS(status, NT_STATUS_OK);
1380
1381         /* Setup initial parameters */
1382         lck.in.lock_count       = 0x0001;
1383         lck.in.lock_sequence    = 0x00000000;
1384         lck.in.file.handle      = h;
1385
1386         /* Try every combination of locks in zero_byte_tests, using the same
1387          * handle for both locks. The first lock is assumed to succeed. The
1388          * second lock may contend, depending on the expected status. */
1389         for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1390                 torture_comment(torture,
1391                     "  ... {%llu, %llu} + {%llu, %llu} = %s\n",
1392                     (unsigned long long) zero_byte_tests[i].lock1.offset,
1393                     (unsigned long long) zero_byte_tests[i].lock1.length,
1394                     (unsigned long long) zero_byte_tests[i].lock2.offset,
1395                     (unsigned long long) zero_byte_tests[i].lock2.length,
1396                     nt_errstr(zero_byte_tests[i].status));
1397
1398                 /* Lock both locks. */
1399                 lck.in.locks            = &zero_byte_tests[i].lock1;
1400                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
1401                                           SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1402                 status = smb2_lock(tree, &lck);
1403                 CHECK_STATUS(status, NT_STATUS_OK);
1404
1405                 lck.in.locks            = &zero_byte_tests[i].lock2;
1406                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
1407                                           SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1408                 status = smb2_lock(tree, &lck);
1409                 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1410
1411                 /* Unlock both locks in reverse order. */
1412                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
1413                 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1414                         status = smb2_lock(tree, &lck);
1415                         CHECK_STATUS(status, NT_STATUS_OK);
1416                 }
1417
1418                 lck.in.locks            = &zero_byte_tests[i].lock1;
1419                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
1420                 status = smb2_lock(tree, &lck);
1421                 CHECK_STATUS(status, NT_STATUS_OK);
1422         }
1423
1424         /* Try every combination of locks in zero_byte_tests, using two
1425          * different handles. */
1426         for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1427                 torture_comment(torture,
1428                     "  ... {%llu, %llu} + {%llu, %llu} = %s\n",
1429                     (unsigned long long) zero_byte_tests[i].lock1.offset,
1430                     (unsigned long long) zero_byte_tests[i].lock1.length,
1431                     (unsigned long long) zero_byte_tests[i].lock2.offset,
1432                     (unsigned long long) zero_byte_tests[i].lock2.length,
1433                     nt_errstr(zero_byte_tests[i].status));
1434
1435                 /* Lock both locks. */
1436                 lck.in.file.handle      = h;
1437                 lck.in.locks            = &zero_byte_tests[i].lock1;
1438                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
1439                                           SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1440                 status = smb2_lock(tree, &lck);
1441                 CHECK_STATUS(status, NT_STATUS_OK);
1442
1443                 lck.in.file.handle      = h2;
1444                 lck.in.locks            = &zero_byte_tests[i].lock2;
1445                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_EXCLUSIVE |
1446                                           SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1447                 status = smb2_lock(tree, &lck);
1448                 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1449
1450                 /* Unlock both locks in reverse order. */
1451                 lck.in.file.handle      = h2;
1452                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
1453                 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1454                         status = smb2_lock(tree, &lck);
1455                         CHECK_STATUS(status, NT_STATUS_OK);
1456                 }
1457
1458                 lck.in.file.handle      = h;
1459                 lck.in.locks            = &zero_byte_tests[i].lock1;
1460                 lck.in.locks[0].flags   = SMB2_LOCK_FLAG_UNLOCK;
1461                 status = smb2_lock(tree, &lck);
1462                 CHECK_STATUS(status, NT_STATUS_OK);
1463         }
1464
1465 done:
1466         smb2_util_close(tree, h2);
1467         smb2_util_close(tree, h);
1468         smb2_deltree(tree, BASEDIR);
1469         return ret;
1470 }
1471
1472 static bool test_zerobyteread(struct torture_context *torture,
1473                               struct smb2_tree *tree)
1474 {
1475         NTSTATUS status;
1476         bool ret = true;
1477         struct smb2_handle h = {{0}};
1478         struct smb2_handle h2 = {{0}};
1479         uint8_t buf[200];
1480         struct smb2_lock lck;
1481         struct smb2_lock_element el[1];
1482         struct smb2_read rd;
1483
1484         const char *fname = BASEDIR "\\zerobyteread.txt";
1485
1486         status = torture_smb2_testdir(tree, BASEDIR, &h);
1487         CHECK_STATUS(status, NT_STATUS_OK);
1488         smb2_util_close(tree, h);
1489
1490         status = torture_smb2_testfile(tree, fname, &h);
1491         CHECK_STATUS(status, NT_STATUS_OK);
1492
1493         ZERO_STRUCT(buf);
1494         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1495         CHECK_STATUS(status, NT_STATUS_OK);
1496
1497         status = torture_smb2_testfile(tree, fname, &h2);
1498         CHECK_STATUS(status, NT_STATUS_OK);
1499
1500         /* Setup initial parameters */
1501         lck.in.locks            = el;
1502         lck.in.lock_count       = 0x0001;
1503         lck.in.lock_sequence    = 0x00000000;
1504         lck.in.file.handle      = h;
1505
1506         ZERO_STRUCT(rd);
1507         rd.in.file.handle = h2;
1508
1509         torture_comment(torture, "Testing zero byte read on lock range:\n");
1510
1511         /* Take an exclusive lock */
1512         torture_comment(torture, "  taking exclusive lock.\n");
1513         el[0].offset            = 0;
1514         el[0].length            = 10;
1515         el[0].reserved          = 0x00000000;
1516         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1517                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1518         status = smb2_lock(tree, &lck);
1519         CHECK_STATUS(status, NT_STATUS_OK);
1520         CHECK_VALUE(lck.out.reserved, 0);
1521
1522         /* Try a zero byte read */
1523         torture_comment(torture, "  reading 0 bytes.\n");
1524         rd.in.offset      = 5;
1525         rd.in.length      = 0;
1526         status = smb2_read(tree, tree, &rd);
1527         torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1528                                       "zero byte read did not return 0 bytes");
1529         CHECK_STATUS(status, NT_STATUS_OK);
1530
1531         /* Unlock lock */
1532         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1533         status = smb2_lock(tree, &lck);
1534         CHECK_STATUS(status, NT_STATUS_OK);
1535         CHECK_VALUE(lck.out.reserved, 0);
1536
1537         torture_comment(torture, "Testing zero byte read on zero byte lock "
1538                                  "range:\n");
1539
1540         /* Take an exclusive lock */
1541         torture_comment(torture, "  taking exclusive 0-byte lock.\n");
1542         el[0].offset            = 5;
1543         el[0].length            = 0;
1544         el[0].reserved          = 0x00000000;
1545         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1546                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1547         status = smb2_lock(tree, &lck);
1548         CHECK_STATUS(status, NT_STATUS_OK);
1549         CHECK_VALUE(lck.out.reserved, 0);
1550
1551         /* Try a zero byte read before the lock */
1552         torture_comment(torture, "  reading 0 bytes before the lock.\n");
1553         rd.in.offset      = 4;
1554         rd.in.length      = 0;
1555         status = smb2_read(tree, tree, &rd);
1556         torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1557                                       "zero byte read did not return 0 bytes");
1558         CHECK_STATUS(status, NT_STATUS_OK);
1559
1560         /* Try a zero byte read on the lock */
1561         torture_comment(torture, "  reading 0 bytes on the lock.\n");
1562         rd.in.offset      = 5;
1563         rd.in.length      = 0;
1564         status = smb2_read(tree, tree, &rd);
1565         torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1566                                       "zero byte read did not return 0 bytes");
1567         CHECK_STATUS(status, NT_STATUS_OK);
1568
1569         /* Try a zero byte read after the lock */
1570         torture_comment(torture, "  reading 0 bytes after the lock.\n");
1571         rd.in.offset      = 6;
1572         rd.in.length      = 0;
1573         status = smb2_read(tree, tree, &rd);
1574         torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1575                                       "zero byte read did not return 0 bytes");
1576         CHECK_STATUS(status, NT_STATUS_OK);
1577
1578         /* Unlock lock */
1579         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1580         status = smb2_lock(tree, &lck);
1581         CHECK_STATUS(status, NT_STATUS_OK);
1582         CHECK_VALUE(lck.out.reserved, 0);
1583
1584 done:
1585         smb2_util_close(tree, h2);
1586         smb2_util_close(tree, h);
1587         smb2_deltree(tree, BASEDIR);
1588         return ret;
1589 }
1590
1591 static bool test_unlock(struct torture_context *torture,
1592                         struct smb2_tree *tree)
1593 {
1594         NTSTATUS status;
1595         bool ret = true;
1596         struct smb2_handle h = {{0}};
1597         struct smb2_handle h2 = {{0}};
1598         uint8_t buf[200];
1599         struct smb2_lock lck;
1600         struct smb2_lock_element el1[1];
1601         struct smb2_lock_element el2[1];
1602
1603         const char *fname = BASEDIR "\\unlock.txt";
1604
1605         status = torture_smb2_testdir(tree, BASEDIR, &h);
1606         CHECK_STATUS(status, NT_STATUS_OK);
1607         smb2_util_close(tree, h);
1608
1609         status = torture_smb2_testfile(tree, fname, &h);
1610         CHECK_STATUS(status, NT_STATUS_OK);
1611
1612         ZERO_STRUCT(buf);
1613         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1614         CHECK_STATUS(status, NT_STATUS_OK);
1615
1616         status = torture_smb2_testfile(tree, fname, &h2);
1617         CHECK_STATUS(status, NT_STATUS_OK);
1618
1619         /* Setup initial parameters */
1620         lck.in.locks            = el1;
1621         lck.in.lock_count       = 0x0001;
1622         lck.in.lock_sequence    = 0x00000000;
1623         el1[0].offset           = 0;
1624         el1[0].length           = 10;
1625         el1[0].reserved         = 0x00000000;
1626
1627         /* Take exclusive lock, then unlock it with a shared-unlock call. */
1628
1629         torture_comment(torture, "Testing unlock exclusive with shared\n");
1630
1631         torture_comment(torture, "  taking exclusive lock.\n");
1632         lck.in.file.handle      = h;
1633         el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE;
1634         status = smb2_lock(tree, &lck);
1635         CHECK_STATUS(status, NT_STATUS_OK);
1636
1637         torture_comment(torture, "  try to unlock the exclusive with a shared "
1638                                  "unlock call.\n");
1639         el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
1640                                   SMB2_LOCK_FLAG_UNLOCK;
1641         status = smb2_lock(tree, &lck);
1642         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1643
1644         torture_comment(torture, "  try shared lock on h2, to test the "
1645                                  "unlock.\n");
1646         lck.in.file.handle      = h2;
1647         el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
1648                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1649         status = smb2_lock(tree, &lck);
1650         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1651
1652         torture_comment(torture, "  unlock the exclusive lock\n");
1653         lck.in.file.handle      = h;
1654         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1655         status = smb2_lock(tree, &lck);
1656         CHECK_STATUS(status, NT_STATUS_OK);
1657
1658         /* Unlock a shared lock with an exclusive-unlock call. */
1659
1660         torture_comment(torture, "Testing unlock shared with exclusive\n");
1661
1662         torture_comment(torture, "  taking shared lock.\n");
1663         lck.in.file.handle      = h;
1664         el1[0].flags            = SMB2_LOCK_FLAG_SHARED;
1665         status = smb2_lock(tree, &lck);
1666         CHECK_STATUS(status, NT_STATUS_OK);
1667
1668         torture_comment(torture, "  try to unlock the shared with an exclusive "
1669                                  "unlock call.\n");
1670         el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1671                                   SMB2_LOCK_FLAG_UNLOCK;
1672         status = smb2_lock(tree, &lck);
1673         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1674
1675         torture_comment(torture, "  try exclusive lock on h2, to test the "
1676                                  "unlock.\n");
1677         lck.in.file.handle      = h2;
1678         el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1679                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1680         status = smb2_lock(tree, &lck);
1681         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1682
1683         torture_comment(torture, "  unlock the exclusive lock\n");
1684         lck.in.file.handle      = h;
1685         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1686         status = smb2_lock(tree, &lck);
1687         CHECK_STATUS(status, NT_STATUS_OK);
1688
1689         /* Test unlocking of stacked 0-byte locks. SMB2 0-byte lock behavior
1690          * should be the same as >0-byte behavior.  Exclusive locks should be
1691          * unlocked before shared. */
1692
1693         torture_comment(torture, "Test unlocking stacked 0-byte locks\n");
1694
1695         lck.in.locks            = el1;
1696         lck.in.file.handle      = h;
1697         el1[0].offset           = 10;
1698         el1[0].length           = 0;
1699         el1[0].reserved         = 0x00000000;
1700         el2[0].offset           = 5;
1701         el2[0].length           = 10;
1702         el2[0].reserved         = 0x00000000;
1703
1704         /* lock 0-byte exclusive */
1705         el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1706                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1707         status = smb2_lock(tree, &lck);
1708         CHECK_STATUS(status, NT_STATUS_OK);
1709
1710         /* lock 0-byte shared */
1711         el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
1712                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1713         status = smb2_lock(tree, &lck);
1714         CHECK_STATUS(status, NT_STATUS_OK);
1715
1716         /* test contention */
1717         lck.in.locks            = el2;
1718         lck.in.file.handle      = h2;
1719         el2[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1720                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1721         status = smb2_lock(tree, &lck);
1722         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1723
1724         lck.in.locks            = el2;
1725         lck.in.file.handle      = h2;
1726         el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
1727                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1728         status = smb2_lock(tree, &lck);
1729         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1730
1731         /* unlock */
1732         lck.in.locks            = el1;
1733         lck.in.file.handle      = h;
1734         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1735         status = smb2_lock(tree, &lck);
1736         CHECK_STATUS(status, NT_STATUS_OK);
1737
1738         /* test - can we take a shared lock? */
1739         lck.in.locks            = el2;
1740         lck.in.file.handle      = h2;
1741         el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
1742                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1743         status = smb2_lock(tree, &lck);
1744         CHECK_STATUS(status, NT_STATUS_OK);
1745
1746         el2[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1747         status = smb2_lock(tree, &lck);
1748         CHECK_STATUS(status, NT_STATUS_OK);
1749
1750         /* cleanup */
1751         lck.in.locks            = el1;
1752         lck.in.file.handle      = h;
1753         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1754         status = smb2_lock(tree, &lck);
1755         CHECK_STATUS(status, NT_STATUS_OK);
1756
1757         /* Test unlocking of stacked exclusive, shared locks. Exclusive
1758          * should be unlocked before any shared. */
1759
1760         torture_comment(torture, "Test unlocking stacked exclusive/shared "
1761                                  "locks\n");
1762
1763         lck.in.locks            = el1;
1764         lck.in.file.handle      = h;
1765         el1[0].offset           = 10;
1766         el1[0].length           = 10;
1767         el1[0].reserved         = 0x00000000;
1768         el2[0].offset           = 5;
1769         el2[0].length           = 10;
1770         el2[0].reserved         = 0x00000000;
1771
1772         /* lock exclusive */
1773         el1[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1774                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1775         status = smb2_lock(tree, &lck);
1776         CHECK_STATUS(status, NT_STATUS_OK);
1777
1778         /* lock shared */
1779         el1[0].flags            = SMB2_LOCK_FLAG_SHARED |
1780                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1781         status = smb2_lock(tree, &lck);
1782         CHECK_STATUS(status, NT_STATUS_OK);
1783
1784         /* test contention */
1785         lck.in.locks            = el2;
1786         lck.in.file.handle      = h2;
1787         el2[0].flags            = SMB2_LOCK_FLAG_EXCLUSIVE |
1788                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1789         status = smb2_lock(tree, &lck);
1790         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1791
1792         lck.in.locks            = el2;
1793         lck.in.file.handle      = h2;
1794         el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
1795                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1796         status = smb2_lock(tree, &lck);
1797         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1798
1799         /* unlock */
1800         lck.in.locks            = el1;
1801         lck.in.file.handle      = h;
1802         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1803         status = smb2_lock(tree, &lck);
1804         CHECK_STATUS(status, NT_STATUS_OK);
1805
1806         /* test - can we take a shared lock? */
1807         lck.in.locks            = el2;
1808         lck.in.file.handle      = h2;
1809         el2[0].flags            = SMB2_LOCK_FLAG_SHARED |
1810                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1811         status = smb2_lock(tree, &lck);
1812         CHECK_STATUS(status, NT_STATUS_OK);
1813
1814         el2[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1815         status = smb2_lock(tree, &lck);
1816         CHECK_STATUS(status, NT_STATUS_OK);
1817
1818         /* cleanup */
1819         lck.in.locks            = el1;
1820         lck.in.file.handle      = h;
1821         el1[0].flags            = SMB2_LOCK_FLAG_UNLOCK;
1822         status = smb2_lock(tree, &lck);
1823         CHECK_STATUS(status, NT_STATUS_OK);
1824
1825 done:
1826         smb2_util_close(tree, h2);
1827         smb2_util_close(tree, h);
1828         smb2_deltree(tree, BASEDIR);
1829         return ret;
1830 }
1831
1832 static bool test_multiple_unlock(struct torture_context *torture,
1833                                  struct smb2_tree *tree)
1834 {
1835         NTSTATUS status;
1836         bool ret = true;
1837         struct smb2_handle h;
1838         uint8_t buf[200];
1839         struct smb2_lock lck;
1840         struct smb2_lock_element el[2];
1841
1842         const char *fname = BASEDIR "\\unlock_multiple.txt";
1843
1844         status = torture_smb2_testdir(tree, BASEDIR, &h);
1845         CHECK_STATUS(status, NT_STATUS_OK);
1846         smb2_util_close(tree, h);
1847
1848         status = torture_smb2_testfile(tree, fname, &h);
1849         CHECK_STATUS(status, NT_STATUS_OK);
1850
1851         ZERO_STRUCT(buf);
1852         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1853         CHECK_STATUS(status, NT_STATUS_OK);
1854
1855         torture_comment(torture, "Testing multiple unlocks:\n");
1856
1857         /* Setup initial parameters */
1858         lck.in.lock_count       = 0x0002;
1859         lck.in.lock_sequence    = 0x00000000;
1860         lck.in.file.handle      = h;
1861         el[0].offset            = 0;
1862         el[0].length            = 10;
1863         el[0].reserved          = 0x00000000;
1864         el[1].offset            = 10;
1865         el[1].length            = 10;
1866         el[1].reserved          = 0x00000000;
1867
1868         /* Test1: Acquire second lock, but not first. */
1869         torture_comment(torture, "  unlock 2 locks, first one not locked. "
1870                                  "Expect no locks unlocked. \n");
1871
1872         lck.in.lock_count       = 0x0001;
1873         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1874                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1875         lck.in.locks            = &el[1];
1876         status = smb2_lock(tree, &lck);
1877         CHECK_STATUS(status, NT_STATUS_OK);
1878
1879         /* Try to unlock both locks */
1880         lck.in.lock_count       = 0x0002;
1881         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1882         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
1883         lck.in.locks            = el;
1884         status = smb2_lock(tree, &lck);
1885         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1886
1887         /* Second lock should not be unlocked. */
1888         lck.in.lock_count       = 0x0001;
1889         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1890                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1891         lck.in.locks            = &el[1];
1892         status = smb2_lock(tree, &lck);
1893         if (TARGET_IS_W2K8(torture)) {
1894                 CHECK_STATUS(status, NT_STATUS_OK);
1895                 torture_warning(torture, "Target has \"pretty please\" bug. "
1896                                 "A contending lock request on the same handle "
1897                                 "unlocks the lock.\n");
1898         } else {
1899                 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1900         }
1901
1902         /* cleanup */
1903         lck.in.lock_count       = 0x0001;
1904         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
1905         lck.in.locks            = &el[1];
1906         status = smb2_lock(tree, &lck);
1907         CHECK_STATUS(status, NT_STATUS_OK);
1908
1909         /* Test2: Acquire first lock, but not second. */
1910         torture_comment(torture, "  unlock 2 locks, second one not locked. "
1911                                  "Expect first lock unlocked.\n");
1912
1913         lck.in.lock_count       = 0x0001;
1914         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1915                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1916         lck.in.locks            = &el[0];
1917         status = smb2_lock(tree, &lck);
1918         CHECK_STATUS(status, NT_STATUS_OK);
1919
1920         /* Try to unlock both locks */
1921         lck.in.lock_count       = 0x0002;
1922         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1923         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
1924         lck.in.locks            = el;
1925         status = smb2_lock(tree, &lck);
1926         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1927
1928         /* First lock should be unlocked. */
1929         lck.in.lock_count       = 0x0001;
1930         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1931                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1932         lck.in.locks            = &el[0];
1933         status = smb2_lock(tree, &lck);
1934         CHECK_STATUS(status, NT_STATUS_OK);
1935
1936         /* cleanup */
1937         lck.in.lock_count       = 0x0001;
1938         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1939         lck.in.locks            = &el[0];
1940         status = smb2_lock(tree, &lck);
1941         CHECK_STATUS(status, NT_STATUS_OK);
1942
1943         /* Test3: Request 2 locks, second will contend.  What happens to the
1944          * first? */
1945         torture_comment(torture, "  request 2 locks, second one will contend. "
1946                                  "Expect both to fail.\n");
1947
1948         /* Lock the second range */
1949         lck.in.lock_count       = 0x0001;
1950         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1951                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1952         lck.in.locks            = &el[1];
1953         status = smb2_lock(tree, &lck);
1954         CHECK_STATUS(status, NT_STATUS_OK);
1955
1956         /* Request both locks */
1957         lck.in.lock_count       = 0x0002;
1958         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
1959                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1960         lck.in.locks            = el;
1961         status = smb2_lock(tree, &lck);
1962         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1963
1964         /* First lock should be unlocked. */
1965         lck.in.lock_count       = 0x0001;
1966         lck.in.locks            = &el[0];
1967         status = smb2_lock(tree, &lck);
1968         CHECK_STATUS(status, NT_STATUS_OK);
1969
1970         /* cleanup */
1971         if (TARGET_IS_W2K8(torture)) {
1972                 lck.in.lock_count       = 0x0001;
1973                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1974                 lck.in.locks            = &el[0];
1975                 status = smb2_lock(tree, &lck);
1976                 CHECK_STATUS(status, NT_STATUS_OK);
1977                 torture_warning(torture, "Target has \"pretty please\" bug. "
1978                                 "A contending lock request on the same handle "
1979                                 "unlocks the lock.\n");
1980         } else {
1981                 lck.in.lock_count       = 0x0002;
1982                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
1983                 el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
1984                 lck.in.locks            = el;
1985                 status = smb2_lock(tree, &lck);
1986                 CHECK_STATUS(status, NT_STATUS_OK);
1987         }
1988
1989         /* Test4: Request unlock and lock.  The lock contends, is the unlock
1990          * then relocked?  SMB2 doesn't like the lock and unlock requests in the
1991          * same packet. The unlock will succeed, but the lock will return
1992          * INVALID_PARAMETER.  This behavior is described in MS-SMB2
1993          * 3.3.5.14.1 */
1994         torture_comment(torture, "  request unlock and lock, second one will "
1995                                  "error. Expect the unlock to succeed.\n");
1996
1997         /* Lock both ranges */
1998         lck.in.lock_count       = 0x0002;
1999         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2000                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2001         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2002                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2003         lck.in.locks            = el;
2004         status = smb2_lock(tree, &lck);
2005         CHECK_STATUS(status, NT_STATUS_OK);
2006
2007         /* Attempt to unlock the first range and lock the second. The lock
2008          * request will error. */
2009         lck.in.lock_count       = 0x0002;
2010         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2011         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2012                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2013         lck.in.locks            = el;
2014         status = smb2_lock(tree, &lck);
2015         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
2016
2017         /* The first lock should've been unlocked */
2018         lck.in.lock_count       = 0x0001;
2019         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2020                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2021         lck.in.locks            = &el[0];
2022         status = smb2_lock(tree, &lck);
2023         CHECK_STATUS(status, NT_STATUS_OK);
2024
2025         /* cleanup */
2026         lck.in.lock_count       = 0x0002;
2027         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2028         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
2029         lck.in.locks            = el;
2030         status = smb2_lock(tree, &lck);
2031         CHECK_STATUS(status, NT_STATUS_OK);
2032
2033         /* Test10: SMB2 only test. Request unlock and lock in same packet.
2034          * Neither contend. SMB2 doesn't like lock and unlock requests in the
2035          * same packet.  The unlock will succeed, but the lock will return
2036          * INVALID_PARAMETER. */
2037         torture_comment(torture, "  request unlock and lock.  Unlock will "
2038                                  "succeed, but lock will fail.\n");
2039
2040         /* Lock first range */
2041         lck.in.lock_count       = 0x0001;
2042         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2043                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2044         lck.in.locks            = &el[0];
2045         status = smb2_lock(tree, &lck);
2046         CHECK_STATUS(status, NT_STATUS_OK);
2047
2048         /* Attempt to unlock the first range and lock the second */
2049         lck.in.lock_count       = 0x0002;
2050         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2051         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2052                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2053         lck.in.locks            = el;
2054         status = smb2_lock(tree, &lck);
2055         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
2056
2057         /* Neither lock should still be locked */
2058         lck.in.lock_count       = 0x0002;
2059         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2060                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2061         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2062                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2063         lck.in.locks            = el;
2064         status = smb2_lock(tree, &lck);
2065         CHECK_STATUS(status, NT_STATUS_OK);
2066
2067         /* cleanup */
2068         lck.in.lock_count       = 0x0002;
2069         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2070         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
2071         lck.in.locks            = el;
2072         status = smb2_lock(tree, &lck);
2073         CHECK_STATUS(status, NT_STATUS_OK);
2074
2075         /* Test11: SMB2 only test. Request lock and unlock in same packet.
2076          * Neither contend. SMB2 doesn't like lock and unlock requests in the
2077          * same packet.  The lock will succeed, the unlock will fail with
2078          * INVALID_PARAMETER, and the lock will be unlocked before return. */
2079         torture_comment(torture, "  request lock and unlock.  Both will "
2080                                  "fail.\n");
2081
2082         /* Lock second range */
2083         lck.in.lock_count       = 0x0001;
2084         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2085                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2086         lck.in.locks            = &el[1];
2087         status = smb2_lock(tree, &lck);
2088         CHECK_STATUS(status, NT_STATUS_OK);
2089
2090         /* Attempt to lock the first range and unlock the second */
2091         lck.in.lock_count       = 0x0002;
2092         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2093                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2094         el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
2095         lck.in.locks            = el;
2096         status = smb2_lock(tree, &lck);
2097         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
2098
2099         /* First range should be unlocked, second locked. */
2100         lck.in.lock_count       = 0x0001;
2101         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2102                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2103         lck.in.locks            = &el[0];
2104         status = smb2_lock(tree, &lck);
2105         CHECK_STATUS(status, NT_STATUS_OK);
2106
2107         lck.in.lock_count       = 0x0001;
2108         el[1].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2109                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2110         lck.in.locks            = &el[1];
2111         status = smb2_lock(tree, &lck);
2112         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2113
2114         /* cleanup */
2115         if (TARGET_IS_W2K8(torture)) {
2116                 lck.in.lock_count       = 0x0001;
2117                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2118                 lck.in.locks            = &el[0];
2119                 status = smb2_lock(tree, &lck);
2120                 CHECK_STATUS(status, NT_STATUS_OK);
2121                 torture_warning(torture, "Target has \"pretty please\" bug. "
2122                                 "A contending lock request on the same handle "
2123                                 "unlocks the lock.\n");
2124         } else {
2125                 lck.in.lock_count       = 0x0002;
2126                 el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2127                 el[1].flags             = SMB2_LOCK_FLAG_UNLOCK;
2128                 lck.in.locks            = el;
2129                 status = smb2_lock(tree, &lck);
2130                 CHECK_STATUS(status, NT_STATUS_OK);
2131         }
2132
2133 done:
2134         smb2_util_close(tree, h);
2135         smb2_deltree(tree, BASEDIR);
2136         return ret;
2137 }
2138
2139 /**
2140  * Test lock stacking
2141  *  - some tests ported from BASE-LOCK-LOCK5
2142  */
2143 static bool test_stacking(struct torture_context *torture,
2144                           struct smb2_tree *tree)
2145 {
2146         NTSTATUS status;
2147         bool ret = true;
2148         struct smb2_handle h = {{0}};
2149         struct smb2_handle h2 = {{0}};
2150         uint8_t buf[200];
2151         struct smb2_lock lck;
2152         struct smb2_lock_element el[1];
2153
2154         const char *fname = BASEDIR "\\stacking.txt";
2155
2156         status = torture_smb2_testdir(tree, BASEDIR, &h);
2157         CHECK_STATUS(status, NT_STATUS_OK);
2158         smb2_util_close(tree, h);
2159
2160         status = torture_smb2_testfile(tree, fname, &h);
2161         CHECK_STATUS(status, NT_STATUS_OK);
2162
2163         ZERO_STRUCT(buf);
2164         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2165         CHECK_STATUS(status, NT_STATUS_OK);
2166
2167         status = torture_smb2_testfile(tree, fname, &h2);
2168         CHECK_STATUS(status, NT_STATUS_OK);
2169
2170         torture_comment(torture, "Testing lock stacking:\n");
2171
2172         /* Setup initial parameters */
2173         lck.in.locks            = el;
2174         lck.in.lock_count       = 0x0001;
2175         lck.in.lock_sequence    = 0x00000000;
2176         lck.in.file.handle      = h;
2177         el[0].offset            = 0;
2178         el[0].length            = 10;
2179         el[0].reserved          = 0x00000000;
2180
2181         /* Try to take a shared lock, then a shared lock on same handle */
2182         torture_comment(torture, "  stacking a shared on top of a shared"
2183                                  "lock succeeds.\n");
2184
2185         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2186                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2187         status = smb2_lock(tree, &lck);
2188         CHECK_STATUS(status, NT_STATUS_OK);
2189
2190         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2191                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2192         status = smb2_lock(tree, &lck);
2193         CHECK_STATUS(status, NT_STATUS_OK);
2194
2195         /* cleanup */
2196         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2197         status = smb2_lock(tree, &lck);
2198         CHECK_STATUS(status, NT_STATUS_OK);
2199
2200         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2201         status = smb2_lock(tree, &lck);
2202         CHECK_STATUS(status, NT_STATUS_OK);
2203
2204
2205         /* Try to take an exclusive lock, then a shared lock on same handle */
2206         torture_comment(torture, "  stacking a shared on top of an exclusive "
2207                                  "lock succeeds.\n");
2208
2209         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2210                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2211         status = smb2_lock(tree, &lck);
2212         CHECK_STATUS(status, NT_STATUS_OK);
2213
2214         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2215                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2216         status = smb2_lock(tree, &lck);
2217         CHECK_STATUS(status, NT_STATUS_OK);
2218
2219         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2220                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2221         status = smb2_lock(tree, &lck);
2222         CHECK_STATUS(status, NT_STATUS_OK);
2223
2224         /* stacking a shared from a different handle should fail */
2225         lck.in.file.handle      = h2;
2226         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2227                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2228         status = smb2_lock(tree, &lck);
2229         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2230
2231         /* cleanup */
2232         lck.in.file.handle      = h;
2233         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2234         status = smb2_lock(tree, &lck);
2235         CHECK_STATUS(status, NT_STATUS_OK);
2236
2237         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2238         status = smb2_lock(tree, &lck);
2239         CHECK_STATUS(status, NT_STATUS_OK);
2240
2241         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2242         status = smb2_lock(tree, &lck);
2243         CHECK_STATUS(status, NT_STATUS_OK);
2244
2245         /* ensure the 4th unlock fails */
2246         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2247         status = smb2_lock(tree, &lck);
2248         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2249
2250         /* ensure a second handle can now take an exclusive lock */
2251         lck.in.file.handle      = h2;
2252         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2253                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2254         status = smb2_lock(tree, &lck);
2255         CHECK_STATUS(status, NT_STATUS_OK);
2256
2257         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2258         status = smb2_lock(tree, &lck);
2259         CHECK_STATUS(status, NT_STATUS_OK);
2260
2261         /* Try to take an exclusive lock, then a shared lock on a
2262          * different handle */
2263         torture_comment(torture, "  stacking a shared on top of an exclusive "
2264                                  "lock with different handles fails.\n");
2265
2266         lck.in.file.handle      = h;
2267         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2268                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2269         status = smb2_lock(tree, &lck);
2270         CHECK_STATUS(status, NT_STATUS_OK);
2271
2272         lck.in.file.handle      = h2;
2273         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2274                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2275         status = smb2_lock(tree, &lck);
2276         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2277
2278         /* cleanup */
2279         lck.in.file.handle      = h;
2280         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2281         status = smb2_lock(tree, &lck);
2282         CHECK_STATUS(status, NT_STATUS_OK);
2283
2284         /* Try to take a shared lock, then stack an exclusive with same
2285          * handle.  */
2286         torture_comment(torture, "  stacking an exclusive on top of a shared "
2287                                  "lock fails.\n");
2288
2289         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2290                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2291         status = smb2_lock(tree, &lck);
2292         CHECK_STATUS(status, NT_STATUS_OK);
2293
2294         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2295                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2296         status = smb2_lock(tree, &lck);
2297         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2298
2299         /* cleanup */
2300         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2301         status = smb2_lock(tree, &lck);
2302         if (TARGET_IS_W2K8(torture)) {
2303                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2304                 torture_warning(torture, "Target has \"pretty please\" bug. "
2305                                 "A contending lock request on the same handle "
2306                                 "unlocks the lock.\n");
2307         } else {
2308                 CHECK_STATUS(status, NT_STATUS_OK);
2309         }
2310
2311         /* Prove that two exclusive locks do not stack on the same handle. */
2312         torture_comment(torture, "  two exclusive locks do not stack.\n");
2313
2314         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2315                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2316         status = smb2_lock(tree, &lck);
2317         CHECK_STATUS(status, NT_STATUS_OK);
2318
2319         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2320                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2321         status = smb2_lock(tree, &lck);
2322         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2323
2324         /* cleanup */
2325         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2326         status = smb2_lock(tree, &lck);
2327         if (TARGET_IS_W2K8(torture)) {
2328                 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2329                 torture_warning(torture, "Target has \"pretty please\" bug. "
2330                                 "A contending lock request on the same handle "
2331                                 "unlocks the lock.\n");
2332         } else {
2333                 CHECK_STATUS(status, NT_STATUS_OK);
2334         }
2335
2336 done:
2337         smb2_util_close(tree, h2);
2338         smb2_util_close(tree, h);
2339         smb2_deltree(tree, BASEDIR);
2340         return ret;
2341 }
2342
2343 /**
2344  * Test lock contention
2345  * - shared lock should contend with exclusive lock on different handle
2346  */
2347 static bool test_contend(struct torture_context *torture,
2348                          struct smb2_tree *tree)
2349 {
2350         NTSTATUS status;
2351         bool ret = true;
2352         struct smb2_handle h = {{0}};
2353         struct smb2_handle h2 = {{0}};
2354         uint8_t buf[200];
2355         struct smb2_lock lck;
2356         struct smb2_lock_element el[1];
2357
2358         const char *fname = BASEDIR "\\contend.txt";
2359
2360         status = torture_smb2_testdir(tree, BASEDIR, &h);
2361         CHECK_STATUS(status, NT_STATUS_OK);
2362         smb2_util_close(tree, h);
2363
2364         status = torture_smb2_testfile(tree, fname, &h);
2365         CHECK_STATUS(status, NT_STATUS_OK);
2366
2367         ZERO_STRUCT(buf);
2368         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2369         CHECK_STATUS(status, NT_STATUS_OK);
2370
2371         status = torture_smb2_testfile(tree, fname, &h2);
2372         CHECK_STATUS(status, NT_STATUS_OK);
2373
2374         torture_comment(torture, "Testing lock contention:\n");
2375
2376         /* Setup initial parameters */
2377         lck.in.locks            = el;
2378         lck.in.lock_count       = 0x0001;
2379         lck.in.lock_sequence    = 0x00000000;
2380         lck.in.file.handle      = h;
2381         el[0].offset            = 0;
2382         el[0].length            = 10;
2383         el[0].reserved          = 0x00000000;
2384
2385         /* Take an exclusive lock, then a shared lock on different handle */
2386         torture_comment(torture, "  shared should contend on exclusive on "
2387                                  "different handle.\n");
2388
2389         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2390                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2391         status = smb2_lock(tree, &lck);
2392         CHECK_STATUS(status, NT_STATUS_OK);
2393
2394         lck.in.file.handle      = h2;
2395         el[0].flags             = SMB2_LOCK_FLAG_SHARED |
2396                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2397         status = smb2_lock(tree, &lck);
2398         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2399
2400         /* cleanup */
2401         lck.in.file.handle      = h;
2402         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2403         status = smb2_lock(tree, &lck);
2404         CHECK_STATUS(status, NT_STATUS_OK);
2405
2406 done:
2407         smb2_util_close(tree, h2);
2408         smb2_util_close(tree, h);
2409         smb2_deltree(tree, BASEDIR);
2410         return ret;
2411 }
2412
2413 /**
2414  * Test locker context
2415  * - test that pid does not affect the locker context
2416  */
2417 static bool test_context(struct torture_context *torture,
2418                          struct smb2_tree *tree)
2419 {
2420         NTSTATUS status;
2421         bool ret = true;
2422         struct smb2_handle h = {{0}};
2423         struct smb2_handle h2 = {{0}};
2424         uint8_t buf[200];
2425         struct smb2_lock lck;
2426         struct smb2_lock_element el[1];
2427
2428         const char *fname = BASEDIR "\\context.txt";
2429
2430         status = torture_smb2_testdir(tree, BASEDIR, &h);
2431         CHECK_STATUS(status, NT_STATUS_OK);
2432         smb2_util_close(tree, h);
2433
2434         status = torture_smb2_testfile(tree, fname, &h);
2435         CHECK_STATUS(status, NT_STATUS_OK);
2436
2437         ZERO_STRUCT(buf);
2438         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2439         CHECK_STATUS(status, NT_STATUS_OK);
2440
2441         status = torture_smb2_testfile(tree, fname, &h2);
2442         CHECK_STATUS(status, NT_STATUS_OK);
2443
2444         torture_comment(torture, "Testing locker context:\n");
2445
2446         /* Setup initial parameters */
2447         lck.in.locks            = el;
2448         lck.in.lock_count       = 0x0001;
2449         lck.in.lock_sequence    = 0x00000000;
2450         lck.in.file.handle      = h;
2451         el[0].offset            = 0;
2452         el[0].length            = 10;
2453         el[0].reserved          = 0x00000000;
2454
2455         /* Take an exclusive lock, then try to unlock with a different pid,
2456          * same handle.  This shows that the pid doesn't affect the locker
2457          * context in SMB2. */
2458         torture_comment(torture, "  pid shouldn't affect locker context\n");
2459
2460         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2461                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2462         status = smb2_lock(tree, &lck);
2463         CHECK_STATUS(status, NT_STATUS_OK);
2464
2465         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2466         status = smb2_lock(tree, &lck);
2467         CHECK_STATUS(status, NT_STATUS_OK);
2468
2469         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2470         status = smb2_lock(tree, &lck);
2471         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2472
2473 done:
2474         smb2_util_close(tree, h2);
2475         smb2_util_close(tree, h);
2476         smb2_deltree(tree, BASEDIR);
2477         return ret;
2478 }
2479
2480 /**
2481  * Test as much of the potential lock range as possible
2482  *  - test ported from BASE-LOCK-LOCK3
2483  */
2484 static bool test_range(struct torture_context *torture,
2485                        struct smb2_tree *tree)
2486 {
2487         NTSTATUS status;
2488         bool ret = true;
2489         struct smb2_handle h = {{0}};
2490         struct smb2_handle h2 = {{0}};
2491         uint8_t buf[200];
2492         struct smb2_lock lck;
2493         struct smb2_lock_element el[1];
2494         uint64_t offset, i;
2495         extern int torture_numops;
2496
2497         const char *fname = BASEDIR "\\range.txt";
2498
2499 #define NEXT_OFFSET offset += (~(uint64_t)0) / torture_numops
2500
2501         status = torture_smb2_testdir(tree, BASEDIR, &h);
2502         CHECK_STATUS(status, NT_STATUS_OK);
2503         smb2_util_close(tree, h);
2504
2505         status = torture_smb2_testfile(tree, fname, &h);
2506         CHECK_STATUS(status, NT_STATUS_OK);
2507
2508         ZERO_STRUCT(buf);
2509         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2510         CHECK_STATUS(status, NT_STATUS_OK);
2511
2512         status = torture_smb2_testfile(tree, fname, &h2);
2513         CHECK_STATUS(status, NT_STATUS_OK);
2514
2515         torture_comment(torture, "Testing locks spread across the 64-bit "
2516                                  "offset range\n");
2517
2518         if (TARGET_IS_W2K8(torture)) {
2519                 torture_result(torture, TORTURE_SKIP,
2520                     "Target has \"pretty please\" bug. A contending lock "
2521                     "request on the same handle unlocks the lock.");
2522                 goto done;
2523         }
2524
2525         /* Setup initial parameters */
2526         lck.in.locks            = el;
2527         lck.in.lock_count       = 0x0001;
2528         lck.in.lock_sequence    = 0x00000000;
2529         lck.in.file.handle      = h;
2530         el[0].offset            = 0;
2531         el[0].length            = 1;
2532         el[0].reserved          = 0x00000000;
2533         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2534                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2535
2536         torture_comment(torture, "  establishing %d locks\n", torture_numops);
2537
2538         for (offset=i=0; i<torture_numops; i++) {
2539                 NEXT_OFFSET;
2540
2541                 lck.in.file.handle      = h;
2542                 el[0].offset            = offset - 1;
2543                 status = smb2_lock(tree, &lck);
2544                 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2545                                  talloc_asprintf(torture,
2546                                      "lock h failed at offset %#llx ",
2547                                      (unsigned long long) el[0].offset));
2548
2549                 lck.in.file.handle      = h2;
2550                 el[0].offset            = offset - 2;
2551                 status = smb2_lock(tree, &lck);
2552                 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2553                                  talloc_asprintf(torture,
2554                                      "lock h2 failed at offset %#llx ",
2555                                      (unsigned long long) el[0].offset));
2556         }
2557
2558         torture_comment(torture, "  testing %d locks\n", torture_numops);
2559
2560         for (offset=i=0; i<torture_numops; i++) {
2561                 NEXT_OFFSET;
2562
2563                 lck.in.file.handle      = h;
2564                 el[0].offset            = offset - 1;
2565                 status = smb2_lock(tree, &lck);
2566                 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2567                                  talloc_asprintf(torture,
2568                                      "lock h at offset %#llx should not have "
2569                                      "succeeded ",
2570                                      (unsigned long long) el[0].offset));
2571
2572                 lck.in.file.handle      = h;
2573                 el[0].offset            = offset - 2;
2574                 status = smb2_lock(tree, &lck);
2575                 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2576                                  talloc_asprintf(torture,
2577                                      "lock h2 at offset %#llx should not have "
2578                                      "succeeded ",
2579                                      (unsigned long long) el[0].offset));
2580
2581                 lck.in.file.handle      = h2;
2582                 el[0].offset            = offset - 1;
2583                 status = smb2_lock(tree, &lck);
2584                 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2585                                  talloc_asprintf(torture,
2586                                      "lock h at offset %#llx should not have "
2587                                      "succeeded ",
2588                                      (unsigned long long) el[0].offset));
2589
2590                 lck.in.file.handle      = h2;
2591                 el[0].offset            = offset - 2;
2592                 status = smb2_lock(tree, &lck);
2593                 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2594                                  talloc_asprintf(torture,
2595                                      "lock h2 at offset %#llx should not have "
2596                                      "succeeded ",
2597                                      (unsigned long long) el[0].offset));
2598         }
2599
2600         torture_comment(torture, "  removing %d locks\n", torture_numops);
2601
2602         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2603
2604         for (offset=i=0; i<torture_numops; i++) {
2605                 NEXT_OFFSET;
2606
2607                 lck.in.file.handle      = h;
2608                 el[0].offset            = offset - 1;
2609                 status = smb2_lock(tree, &lck);
2610                 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2611                                  talloc_asprintf(torture,
2612                                      "unlock from h failed at offset %#llx ",
2613                                      (unsigned long long) el[0].offset));
2614
2615                 lck.in.file.handle      = h2;
2616                 el[0].offset            = offset - 2;
2617                 status = smb2_lock(tree, &lck);
2618                 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2619                                  talloc_asprintf(torture,
2620                                      "unlock from h2 failed at offset %#llx ",
2621                                      (unsigned long long) el[0].offset));
2622         }
2623
2624 done:
2625         smb2_util_close(tree, h2);
2626         smb2_util_close(tree, h);
2627         smb2_deltree(tree, BASEDIR);
2628         return ret;
2629 }
2630
2631 static NTSTATUS test_smb2_lock(struct smb2_tree *tree, struct smb2_handle h,
2632                                uint64_t offset, uint64_t length, bool exclusive)
2633 {
2634         struct smb2_lock lck;
2635         struct smb2_lock_element el[1];
2636         NTSTATUS status;
2637
2638         lck.in.locks            = el;
2639         lck.in.lock_count       = 0x0001;
2640         lck.in.lock_sequence    = 0x00000000;
2641         lck.in.file.handle      = h;
2642         el[0].offset            = offset;
2643         el[0].length            = length;
2644         el[0].reserved          = 0x00000000;
2645         el[0].flags             = (exclusive ?
2646                                   SMB2_LOCK_FLAG_EXCLUSIVE :
2647                                   SMB2_LOCK_FLAG_SHARED) |
2648                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2649
2650         status = smb2_lock(tree, &lck);
2651
2652         return status;
2653 }
2654
2655 static NTSTATUS test_smb2_unlock(struct smb2_tree *tree, struct smb2_handle h,
2656                                  uint64_t offset, uint64_t length)
2657 {
2658         struct smb2_lock lck;
2659         struct smb2_lock_element el[1];
2660         NTSTATUS status;
2661
2662         lck.in.locks            = el;
2663         lck.in.lock_count       = 0x0001;
2664         lck.in.lock_sequence    = 0x00000000;
2665         lck.in.file.handle      = h;
2666         el[0].offset            = offset;
2667         el[0].length            = length;
2668         el[0].reserved          = 0x00000000;
2669         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2670
2671         status = smb2_lock(tree, &lck);
2672
2673         return status;
2674 }
2675
2676 #define EXPECTED(ret, v) if ((ret) != (v)) { \
2677         torture_result(torture, TORTURE_FAIL, __location__": subtest failed");\
2678         torture_comment(torture, "** "); correct = false; \
2679         }
2680
2681 /**
2682  * Test overlapping lock ranges from various lockers
2683  *  - some tests ported from BASE-LOCK-LOCK4
2684  */
2685 static bool test_overlap(struct torture_context *torture,
2686                          struct smb2_tree *tree,
2687                          struct smb2_tree *tree2)
2688 {
2689         NTSTATUS status;
2690         bool ret = true;
2691         struct smb2_handle h = {{0}};
2692         struct smb2_handle h2 = {{0}};
2693         struct smb2_handle h3 = {{0}};
2694         uint8_t buf[200];
2695         bool correct = true;
2696
2697         const char *fname = BASEDIR "\\overlap.txt";
2698
2699         status = torture_smb2_testdir(tree, BASEDIR, &h);
2700         CHECK_STATUS(status, NT_STATUS_OK);
2701         smb2_util_close(tree, h);
2702
2703         status = torture_smb2_testfile(tree, fname, &h);
2704         CHECK_STATUS(status, NT_STATUS_OK);
2705
2706         ZERO_STRUCT(buf);
2707         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2708         CHECK_STATUS(status, NT_STATUS_OK);
2709
2710         status = torture_smb2_testfile(tree, fname, &h2);
2711         CHECK_STATUS(status, NT_STATUS_OK);
2712
2713         status = torture_smb2_testfile(tree2, fname, &h3);
2714         CHECK_STATUS(status, NT_STATUS_OK);
2715
2716         torture_comment(torture, "Testing overlapping locks:\n");
2717
2718         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 0, 4, true)) &&
2719               NT_STATUS_IS_OK(test_smb2_lock(tree, h, 2, 4, true));
2720         EXPECTED(ret, false);
2721         torture_comment(torture, "the same session/handle %s set overlapping "
2722                                  "exclusive locks\n", ret?"can":"cannot");
2723
2724         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 10, 4, false)) &&
2725               NT_STATUS_IS_OK(test_smb2_lock(tree, h, 12, 4, false));
2726         EXPECTED(ret, true);
2727         torture_comment(torture, "the same session/handle %s set overlapping "
2728                                  "shared locks\n", ret?"can":"cannot");
2729
2730         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 20, 4, true)) &&
2731               NT_STATUS_IS_OK(test_smb2_lock(tree2, h3, 22, 4, true));
2732         EXPECTED(ret, false);
2733         torture_comment(torture, "a different session %s set overlapping "
2734                                  "exclusive locks\n", ret?"can":"cannot");
2735
2736         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 30, 4, false)) &&
2737               NT_STATUS_IS_OK(test_smb2_lock(tree2, h3, 32, 4, false));
2738         EXPECTED(ret, true);
2739         torture_comment(torture, "a different session %s set overlapping "
2740                                  "shared locks\n", ret?"can":"cannot");
2741
2742         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 40, 4, true)) &&
2743               NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 42, 4, true));
2744         EXPECTED(ret, false);
2745         torture_comment(torture, "a different handle %s set overlapping "
2746                                  "exclusive locks\n", ret?"can":"cannot");
2747
2748         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 50, 4, false)) &&
2749               NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 52, 4, false));
2750         EXPECTED(ret, true);
2751         torture_comment(torture, "a different handle %s set overlapping "
2752                                  "shared locks\n", ret?"can":"cannot");
2753
2754         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 110, 4, false)) &&
2755               NT_STATUS_IS_OK(test_smb2_lock(tree, h, 112, 4, false)) &&
2756               NT_STATUS_IS_OK(test_smb2_unlock(tree, h, 110, 6));
2757         EXPECTED(ret, false);
2758         torture_comment(torture, "the same handle %s coalesce read locks\n",
2759                                  ret?"can":"cannot");
2760
2761         smb2_util_close(tree, h2);
2762         smb2_util_close(tree, h);
2763         status = torture_smb2_testfile(tree, fname, &h);
2764         CHECK_STATUS(status, NT_STATUS_OK);
2765         status = torture_smb2_testfile(tree, fname, &h2);
2766         CHECK_STATUS(status, NT_STATUS_OK);
2767         ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 0, 8, false)) &&
2768               NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 0, 1, false)) &&
2769               NT_STATUS_IS_OK(smb2_util_close(tree, h)) &&
2770               NT_STATUS_IS_OK(torture_smb2_testfile(tree, fname, &h)) &&
2771               NT_STATUS_IS_OK(test_smb2_lock(tree, h, 7, 1, true));
2772         EXPECTED(ret, true);
2773         torture_comment(torture, "the server %s have the NT byte range lock "
2774                                  "bug\n", !ret?"does":"doesn't");
2775
2776 done:
2777         smb2_util_close(tree2, h3);
2778         smb2_util_close(tree, h2);
2779         smb2_util_close(tree, h);
2780         smb2_deltree(tree, BASEDIR);
2781         return correct;
2782 }
2783
2784 /**
2785  * Test truncation of locked file
2786  *  - some tests ported from BASE-LOCK-LOCK7
2787  */
2788 static bool test_truncate(struct torture_context *torture,
2789                           struct smb2_tree *tree)
2790 {
2791         NTSTATUS status;
2792         bool ret = true;
2793         struct smb2_handle h = {{0}};
2794         struct smb2_handle h2 = {{0}};
2795         uint8_t buf[200];
2796         struct smb2_lock lck;
2797         struct smb2_lock_element el[1];
2798         struct smb2_create io;
2799
2800         const char *fname = BASEDIR "\\truncate.txt";
2801
2802         status = torture_smb2_testdir(tree, BASEDIR, &h);
2803         CHECK_STATUS(status, NT_STATUS_OK);
2804         smb2_util_close(tree, h);
2805
2806         status = torture_smb2_testfile(tree, fname, &h);
2807         CHECK_STATUS(status, NT_STATUS_OK);
2808
2809         ZERO_STRUCT(buf);
2810         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2811         CHECK_STATUS(status, NT_STATUS_OK);
2812
2813         torture_comment(torture, "Testing truncation of locked file:\n");
2814
2815         /* Setup initial parameters */
2816         lck.in.locks            = el;
2817         lck.in.lock_count       = 0x0001;
2818         lck.in.lock_sequence    = 0x00000000;
2819         lck.in.file.handle      = h;
2820         el[0].offset            = 0;
2821         el[0].length            = 10;
2822         el[0].reserved          = 0x00000000;
2823
2824         ZERO_STRUCT(io);
2825         io.in.oplock_level = 0;
2826         io.in.desired_access = SEC_RIGHTS_FILE_ALL;
2827         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
2828         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2829         io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
2830                              NTCREATEX_SHARE_ACCESS_READ |
2831                              NTCREATEX_SHARE_ACCESS_WRITE;
2832         io.in.create_options = 0;
2833         io.in.fname = fname;
2834
2835         /* Take an exclusive lock */
2836         el[0].flags             = SMB2_LOCK_FLAG_EXCLUSIVE |
2837                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2838         status = smb2_lock(tree, &lck);
2839         CHECK_STATUS(status, NT_STATUS_OK);
2840
2841         /* On second handle open the file with OVERWRITE disposition */
2842         torture_comment(torture, "  overwrite disposition is allowed on a "
2843                                  "locked file.\n");
2844
2845         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2846         status = smb2_create(tree, tree, &io);
2847         CHECK_STATUS(status, NT_STATUS_OK);
2848         h2 = io.out.file.handle;
2849         smb2_util_close(tree, h2);
2850
2851         /* On second handle open the file with SUPERSEDE disposition */
2852         torture_comment(torture, "  supersede disposition is allowed on a "
2853                                  "locked file.\n");
2854
2855         io.in.create_disposition = NTCREATEX_DISP_SUPERSEDE;
2856         status = smb2_create(tree, tree, &io);
2857         CHECK_STATUS(status, NT_STATUS_OK);
2858         h2 = io.out.file.handle;
2859         smb2_util_close(tree, h2);
2860
2861         /* cleanup */
2862         lck.in.file.handle      = h;
2863         el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
2864         status = smb2_lock(tree, &lck);
2865         CHECK_STATUS(status, NT_STATUS_OK);
2866
2867 done:
2868         smb2_util_close(tree, h2);
2869         smb2_util_close(tree, h);
2870         smb2_deltree(tree, BASEDIR);
2871         return ret;
2872 }
2873
2874 /**
2875  * Test lock replay detection
2876  */
2877 static bool test_replay(struct torture_context *torture,
2878                           struct smb2_tree *tree)
2879 {
2880         NTSTATUS status;
2881         bool ret = true;
2882         struct smb2_handle h;
2883         struct smb2_ioctl ioctl;
2884         struct smb2_lock lck;
2885         struct smb2_lock_element el;
2886         uint8_t res_req[8];
2887         const char *fname = BASEDIR "\\replay.txt";
2888         struct smb2_transport *transport = tree->session->transport;
2889
2890         if (smbXcli_conn_protocol(transport->conn) < PROTOCOL_SMB2_10) {
2891                 torture_skip(torture, "SMB 2.100 Dialect family or above \
2892                                 required for Lock Replay tests\n");
2893         }
2894
2895         status = torture_smb2_testdir(tree, BASEDIR, &h);
2896         CHECK_STATUS(status, NT_STATUS_OK);
2897         smb2_util_close(tree, h);
2898
2899         torture_comment(torture, "Testing Open File:\n");
2900         status = torture_smb2_testfile(tree, fname, &h);
2901         CHECK_STATUS(status, NT_STATUS_OK);
2902
2903         /*
2904          * Setup initial parameters
2905          */
2906         el = (struct smb2_lock_element) {
2907                 .length = 100,
2908                 .offset = 100,
2909         };
2910         lck = (struct smb2_lock) {
2911                 .in.locks = &el,
2912                 .in.lock_count  = 0x0001,
2913                 .in.file.handle = h
2914         };
2915
2916         torture_comment(torture, "Testing Lock Replay detection [ignored]:\n");
2917         lck.in.lock_sequence = 0x010 + 0x1;
2918         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2919         status = smb2_lock(tree, &lck);
2920         CHECK_STATUS(status, NT_STATUS_OK);
2921         status = smb2_lock(tree, &lck);
2922         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2923
2924         el.flags = SMB2_LOCK_FLAG_UNLOCK;
2925         status = smb2_lock(tree, &lck);
2926         CHECK_STATUS(status, NT_STATUS_OK);
2927         status = smb2_lock(tree, &lck);
2928         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2929
2930         torture_comment(torture, "Testing Set Resiliency:\n");
2931         SIVAL(res_req, 0, 1000); /* timeout */
2932         SIVAL(res_req, 4, 0);    /* reserved */
2933         ioctl = (struct smb2_ioctl) {
2934                 .level = RAW_IOCTL_SMB2,
2935                 .in.file.handle = h,
2936                 .in.function = FSCTL_LMR_REQ_RESILIENCY,
2937                 .in.max_output_response = 0,
2938                 .in.flags = SMB2_IOCTL_FLAG_IS_FSCTL,
2939                 .in.out.data = res_req,
2940                 .in.out.length = sizeof(res_req)
2941         };
2942         status = smb2_ioctl(tree, torture, &ioctl);
2943         CHECK_STATUS(status, NT_STATUS_OK);
2944
2945         /*
2946          * Test with an invalid bucket number (only 1..64 are valid).
2947          * With an invalid number, lock replay detection is not performed.
2948          */
2949         torture_comment(torture, "Testing Lock (ignored) Replay detection "
2950                                  "(Bucket No: 0 (invalid)) [ignored]:\n");
2951         lck.in.lock_sequence = 0x000 + 0x1;
2952         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2953         status = smb2_lock(tree, &lck);
2954         CHECK_STATUS(status, NT_STATUS_OK);
2955         status = smb2_lock(tree, &lck);
2956         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2957
2958         el.flags = SMB2_LOCK_FLAG_UNLOCK;
2959         status = smb2_lock(tree, &lck);
2960         CHECK_STATUS(status, NT_STATUS_OK);
2961         status = smb2_lock(tree, &lck);
2962         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2963
2964         torture_comment(torture, "Testing Lock Replay detection "
2965                                  "(Bucket No: 1):\n");
2966
2967         /*
2968          * Obtain Exclusive Lock of length 100 bytes using Bucket Num 1
2969          * and Bucket Seq 1.
2970          */
2971         lck.in.lock_sequence = 0x010 + 0x1;
2972         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2973         status = smb2_lock(tree, &lck);
2974         CHECK_STATUS(status, NT_STATUS_OK);
2975
2976         /*
2977          * Server detects Replay of Byte Range locks using the Lock Sequence
2978          * Numbers. And ignores the requests completely.
2979          */
2980         status = smb2_lock(tree, &lck);
2981         CHECK_STATUS(status, NT_STATUS_OK);
2982         el.flags = SMB2_LOCK_FLAG_UNLOCK;
2983         status = smb2_lock(tree, &lck);
2984         CHECK_STATUS(status, NT_STATUS_OK);
2985         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2986         status = smb2_lock(tree, &lck);
2987         CHECK_STATUS(status, NT_STATUS_OK);
2988         el.flags = SMB2_LOCK_FLAG_UNLOCK;
2989         status = smb2_lock(tree, &lck);
2990         CHECK_STATUS(status, NT_STATUS_OK);
2991         status = smb2_lock(tree, &lck);
2992         CHECK_STATUS(status, NT_STATUS_OK);
2993
2994         /* status: still locked */
2995
2996         /*
2997          * Server will not grant same Byte Range using a different Bucket Seq
2998          */
2999         lck.in.lock_sequence = 0x010 + 0x2;
3000         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3001         status = smb2_lock(tree, &lck);
3002         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3003         status = smb2_lock(tree, &lck);
3004         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3005
3006         torture_comment(torture, "Testing Lock Replay detection "
3007                                  "(Bucket No: 2):\n");
3008
3009         /*
3010          * Server will not grant same Byte Range using a different Bucket Num
3011          */
3012         lck.in.lock_sequence = 0x020 + 0x1;
3013         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3014         status = smb2_lock(tree, &lck);
3015         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3016         status = smb2_lock(tree, &lck);
3017         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3018
3019         /* status: still locked */
3020
3021         /* test with invalid bucket when file is locked */
3022
3023         torture_comment(torture, "Testing Lock Replay detection "
3024                                  "(Bucket No: 65 (invalid)) [ignored]:\n");
3025
3026         lck.in.lock_sequence = 0x410 + 0x1;
3027         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3028         status = smb2_lock(tree, &lck);
3029         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3030         status = smb2_lock(tree, &lck);
3031         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3032
3033         el.flags = SMB2_LOCK_FLAG_UNLOCK;
3034         status = smb2_lock(tree, &lck);
3035         CHECK_STATUS(status, NT_STATUS_OK);
3036         status = smb2_lock(tree, &lck);
3037         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
3038
3039         /* status: unlocked */
3040
3041         /*
3042          * Lock again for the unlock replay test
3043          */
3044         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3045         status = smb2_lock(tree, &lck);
3046         CHECK_STATUS(status, NT_STATUS_OK);
3047
3048         torture_comment(torture, "Testing Lock Replay detection "
3049                                  "(Bucket No: 64):\n");
3050
3051         /*
3052          * Server will not grant same Byte Range using a different Bucket Num
3053          */
3054         lck.in.lock_sequence = 0x400 + 0x1;
3055         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3056         status = smb2_lock(tree, &lck);
3057         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3058         status = smb2_lock(tree, &lck);
3059         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
3060
3061         /*
3062          * Test Unlock replay detection
3063          */
3064         lck.in.lock_sequence = 0x400 + 0x2;
3065         el.flags = SMB2_LOCK_FLAG_UNLOCK;
3066         status = smb2_lock(tree, &lck);
3067         CHECK_STATUS(status, NT_STATUS_OK); /* new seq num ==> unlocked */
3068         status = smb2_lock(tree, &lck);
3069         CHECK_STATUS(status, NT_STATUS_OK); /* replay detected ==> ignored */
3070
3071         el.flags = SMB2_LOCK_FLAG_EXCLUSIVE | SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
3072         status = smb2_lock(tree, &lck);     /* same seq num ==> ignored */
3073         CHECK_STATUS(status, NT_STATUS_OK);
3074
3075         /* verify it's unlocked: */
3076         lck.in.lock_sequence = 0x400 + 0x3;
3077         el.flags = SMB2_LOCK_FLAG_UNLOCK;
3078         status = smb2_lock(tree, &lck);
3079         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
3080
3081         /* status: not locked */
3082
3083 done:
3084         smb2_util_close(tree, h);
3085         smb2_deltree(tree, BASEDIR);
3086         return ret;
3087 }
3088
3089 /**
3090  * Test lock interaction between smbd and ctdb with tombstone records.
3091  *
3092  * Re-locking an unlocked record could lead to a deadlock between
3093  * smbd and ctdb. Make sure we don't regress.
3094  *
3095  * https://bugzilla.samba.org/show_bug.cgi?id=12005
3096  * https://bugzilla.samba.org/show_bug.cgi?id=10008
3097  */
3098 static bool test_deadlock(struct torture_context *torture,
3099                           struct smb2_tree *tree)
3100 {
3101         NTSTATUS status;
3102         bool ret = true;
3103         struct smb2_handle _h;
3104         struct smb2_handle *h = NULL;
3105         uint8_t buf[200];
3106         const char *fname = BASEDIR "\\deadlock.txt";
3107
3108         if (!lpcfg_clustering(torture->lp_ctx)) {
3109                 torture_skip(torture, "Test must be run on a ctdb cluster\n");
3110                 return true;
3111         }
3112
3113         status = torture_smb2_testdir(tree, BASEDIR, &_h);
3114         torture_assert_ntstatus_ok(torture, status,
3115                                    "torture_smb2_testdir failed");
3116         smb2_util_close(tree, _h);
3117
3118         status = torture_smb2_testfile(tree, fname, &_h);
3119         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3120                                         "torture_smb2_testfile failed");
3121         h = &_h;
3122
3123         ZERO_STRUCT(buf);
3124         status = smb2_util_write(tree, *h, buf, 0, ARRAY_SIZE(buf));
3125         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3126                                         "smb2_util_write failed");
3127
3128         status = test_smb2_lock(tree, *h, 0, 1, true);
3129         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3130                                         "test_smb2_lock failed");
3131
3132         status = test_smb2_unlock(tree, *h, 0, 1);
3133         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3134                                         "test_smb2_unlock failed");
3135
3136         status = test_smb2_lock(tree, *h, 0, 1, true);
3137         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3138                                         "test_smb2_lock failed");
3139
3140         status = test_smb2_unlock(tree, *h, 0, 1);
3141         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3142                                         "test_smb2_unlock failed");
3143
3144 done:
3145         if (h != NULL) {
3146                 smb2_util_close(tree, *h);
3147         }
3148         smb2_deltree(tree, BASEDIR);
3149         return ret;
3150 }
3151
3152 /* basic testing of SMB2 locking
3153 */
3154 struct torture_suite *torture_smb2_lock_init(TALLOC_CTX *ctx)
3155 {
3156         struct torture_suite *suite =
3157             torture_suite_create(ctx, "lock");
3158         torture_suite_add_1smb2_test(suite, "valid-request",
3159             test_valid_request);
3160         torture_suite_add_1smb2_test(suite, "rw-none", test_lock_rw_none);
3161         torture_suite_add_1smb2_test(suite, "rw-shared", test_lock_rw_shared);
3162         torture_suite_add_1smb2_test(suite, "rw-exclusive",
3163             test_lock_rw_exclusive);
3164         torture_suite_add_1smb2_test(suite, "auto-unlock",
3165             test_lock_auto_unlock);
3166         torture_suite_add_1smb2_test(suite, "lock", test_lock);
3167         torture_suite_add_1smb2_test(suite, "async", test_async);
3168         torture_suite_add_1smb2_test(suite, "cancel", test_cancel);
3169         torture_suite_add_1smb2_test(suite, "cancel-tdis", test_cancel_tdis);
3170         torture_suite_add_1smb2_test(suite, "cancel-logoff",
3171             test_cancel_logoff);
3172         torture_suite_add_1smb2_test(suite, "errorcode", test_errorcode);
3173         torture_suite_add_1smb2_test(suite, "zerobytelength",
3174             test_zerobytelength);
3175         torture_suite_add_1smb2_test(suite, "zerobyteread",
3176             test_zerobyteread);
3177         torture_suite_add_1smb2_test(suite, "unlock", test_unlock);
3178         torture_suite_add_1smb2_test(suite, "multiple-unlock",
3179             test_multiple_unlock);
3180         torture_suite_add_1smb2_test(suite, "stacking", test_stacking);
3181         torture_suite_add_1smb2_test(suite, "contend", test_contend);
3182         torture_suite_add_1smb2_test(suite, "context", test_context);
3183         torture_suite_add_1smb2_test(suite, "range", test_range);
3184         torture_suite_add_2smb2_test(suite, "overlap", test_overlap);
3185         torture_suite_add_1smb2_test(suite, "truncate", test_truncate);
3186         torture_suite_add_1smb2_test(suite, "replay", test_replay);
3187         torture_suite_add_1smb2_test(suite, "ctdb-delrec-deadlock", test_deadlock);
3188
3189         suite->description = talloc_strdup(suite, "SMB2-LOCK tests");
3190
3191         return suite;
3192 }