2 Unix SMB/CIFS implementation.
6 Copyright (C) Stefan Metzmacher 2006
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28 #include "torture/util.h"
30 #include "lib/events/events.h"
31 #include "param/param.h"
33 #define CHECK_STATUS(status, correct) do { \
34 const char *_cmt = "(" __location__ ")"; \
35 torture_assert_ntstatus_equal_goto(torture,status,correct, \
39 #define CHECK_STATUS_CMT(status, correct, cmt) do { \
40 torture_assert_ntstatus_equal_goto(torture,status,correct, \
44 #define CHECK_STATUS_CONT(status, correct) do { \
45 if (!NT_STATUS_EQUAL(status, correct)) { \
46 torture_result(torture, TORTURE_FAIL, \
47 "(%s) Incorrect status %s - should be %s\n", \
48 __location__, nt_errstr(status), nt_errstr(correct)); \
52 #define CHECK_VALUE(v, correct) do { \
53 const char *_cmt = "(" __location__ ")"; \
54 torture_assert_int_equal_goto(torture,v,correct,ret,done,_cmt); \
57 #define BASEDIR "testlock"
59 #define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
60 (torture_setting_bool(_tctx, "invalid_lock_range_support", true))
61 #define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
63 #define WAIT_FOR_ASYNC_RESPONSE(req) \
64 while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
65 if (event_loop_once(req->transport->socket->event.ctx) != 0) { \
70 static bool test_valid_request(struct torture_context *torture,
71 struct smb2_tree *tree)
78 struct smb2_lock_element el[2];
82 status = torture_smb2_testfile(tree, "lock1.txt", &h);
83 CHECK_STATUS(status, NT_STATUS_OK);
85 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
86 CHECK_STATUS(status, NT_STATUS_OK);
90 torture_comment(torture, "Test request with 0 locks.\n");
92 lck.in.lock_count = 0x0000;
93 lck.in.lock_sequence = 0x00000000;
94 lck.in.file.handle = h;
95 el[0].offset = 0x0000000000000000;
96 el[0].length = 0x0000000000000000;
97 el[0].reserved = 0x0000000000000000;
98 el[0].flags = 0x00000000;
99 status = smb2_lock(tree, &lck);
100 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
102 lck.in.lock_count = 0x0000;
103 lck.in.lock_sequence = 0x00000000;
104 lck.in.file.handle = h;
107 el[0].reserved = 0x00000000;
108 el[0].flags = SMB2_LOCK_FLAG_SHARED;
109 status = smb2_lock(tree, &lck);
110 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
112 lck.in.lock_count = 0x0001;
113 lck.in.lock_sequence = 0x00000000;
114 lck.in.file.handle = h;
117 el[0].reserved = 0x00000000;
118 el[0].flags = SMB2_LOCK_FLAG_NONE;
119 status = smb2_lock(tree, &lck);
120 if (TARGET_IS_W2K8(torture)) {
121 CHECK_STATUS(status, NT_STATUS_OK);
122 torture_warning(torture, "Target has bug validating lock flags "
125 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
128 torture_comment(torture, "Test >63-bit lock requests.\n");
130 lck.in.file.handle.data[0] +=1;
131 status = smb2_lock(tree, &lck);
132 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
133 lck.in.file.handle.data[0] -=1;
135 lck.in.lock_count = 0x0001;
136 lck.in.lock_sequence = 0x123ab1;
137 lck.in.file.handle = h;
138 el[0].offset = UINT64_MAX;
139 el[0].length = UINT64_MAX;
140 el[0].reserved = 0x00000000;
141 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
142 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
143 status = smb2_lock(tree, &lck);
144 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
145 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
147 CHECK_STATUS(status, NT_STATUS_OK);
148 CHECK_VALUE(lck.out.reserved, 0);
151 lck.in.lock_sequence = 0x123ab2;
152 status = smb2_lock(tree, &lck);
153 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
154 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
156 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
159 torture_comment(torture, "Test basic lock stacking.\n");
161 lck.in.lock_count = 0x0001;
162 lck.in.lock_sequence = 0x12345678;
163 lck.in.file.handle = h;
164 el[0].offset = UINT32_MAX;
165 el[0].length = UINT32_MAX;
166 el[0].reserved = 0x87654321;
167 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
168 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
169 status = smb2_lock(tree, &lck);
170 CHECK_STATUS(status, NT_STATUS_OK);
171 CHECK_VALUE(lck.out.reserved, 0);
173 el[0].flags = SMB2_LOCK_FLAG_SHARED;
174 status = smb2_lock(tree, &lck);
175 CHECK_STATUS(status, NT_STATUS_OK);
176 CHECK_VALUE(lck.out.reserved, 0);
178 status = smb2_lock(tree, &lck);
179 CHECK_STATUS(status, NT_STATUS_OK);
180 CHECK_VALUE(lck.out.reserved, 0);
182 lck.in.lock_count = 0x0001;
183 lck.in.lock_sequence = 0x87654321;
184 lck.in.file.handle = h;
185 el[0].offset = 0x00000000FFFFFFFF;
186 el[0].length = 0x00000000FFFFFFFF;
187 el[0].reserved = 0x1234567;
188 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
189 status = smb2_lock(tree, &lck);
190 CHECK_STATUS(status, NT_STATUS_OK);
192 lck.in.lock_count = 0x0001;
193 lck.in.lock_sequence = 0x1234567;
194 lck.in.file.handle = h;
195 el[0].offset = 0x00000000FFFFFFFF;
196 el[0].length = 0x00000000FFFFFFFF;
197 el[0].reserved = 0x00000000;
198 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
199 status = smb2_lock(tree, &lck);
200 CHECK_STATUS(status, NT_STATUS_OK);
202 status = smb2_lock(tree, &lck);
203 CHECK_STATUS(status, NT_STATUS_OK);
204 status = smb2_lock(tree, &lck);
205 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
207 torture_comment(torture, "Test flags field permutations.\n");
209 lck.in.lock_count = 0x0001;
210 lck.in.lock_sequence = 0;
211 lck.in.file.handle = h;
214 el[0].reserved = 0x00000000;
215 el[0].flags = ~SMB2_LOCK_FLAG_ALL_MASK;
217 status = smb2_lock(tree, &lck);
218 if (TARGET_IS_W2K8(torture)) {
219 CHECK_STATUS(status, NT_STATUS_OK);
220 torture_warning(torture, "Target has bug validating lock flags "
223 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
226 if (TARGET_IS_W2K8(torture)) {
227 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
228 status = smb2_lock(tree, &lck);
229 CHECK_STATUS(status, NT_STATUS_OK);
232 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
233 status = smb2_lock(tree, &lck);
234 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
236 el[0].flags = SMB2_LOCK_FLAG_UNLOCK |
237 SMB2_LOCK_FLAG_EXCLUSIVE;
238 status = smb2_lock(tree, &lck);
239 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
241 el[0].flags = SMB2_LOCK_FLAG_UNLOCK |
242 SMB2_LOCK_FLAG_SHARED;
243 status = smb2_lock(tree, &lck);
244 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
246 el[0].flags = SMB2_LOCK_FLAG_UNLOCK |
247 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
248 status = smb2_lock(tree, &lck);
249 if (TARGET_IS_W2K8(torture)) {
250 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
251 torture_warning(torture, "Target has bug validating lock flags "
254 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
257 torture_comment(torture, "Test return error when 2 locks are "
260 lck.in.lock_count = 2;
261 lck.in.lock_sequence = 0;
262 lck.in.file.handle = h;
265 el[0].reserved = 0x00000000;
268 el[1].reserved = 0x00000000;
270 lck.in.lock_count = 2;
272 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
273 status = smb2_lock(tree, &lck);
274 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
276 lck.in.lock_count = 2;
279 status = smb2_lock(tree, &lck);
280 if (TARGET_IS_W2K8(torture)) {
281 CHECK_STATUS(status, NT_STATUS_OK);
282 torture_warning(torture, "Target has bug validating lock flags "
285 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
288 lck.in.lock_count = 2;
289 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
291 status = smb2_lock(tree, &lck);
292 if (TARGET_IS_W2K8(torture)) {
293 CHECK_STATUS(status, NT_STATUS_OK);
294 torture_warning(torture, "Target has bug validating lock flags "
297 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
300 lck.in.lock_count = 1;
301 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
302 status = smb2_lock(tree, &lck);
303 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
305 lck.in.lock_count = 1;
306 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
307 status = smb2_lock(tree, &lck);
308 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
310 lck.in.lock_count = 1;
311 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
312 status = smb2_lock(tree, &lck);
313 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
315 lck.in.lock_count = 1;
316 el[0].flags = SMB2_LOCK_FLAG_SHARED;
317 status = smb2_lock(tree, &lck);
318 CHECK_STATUS(status, NT_STATUS_OK);
320 status = smb2_lock(tree, &lck);
321 CHECK_STATUS(status, NT_STATUS_OK);
323 lck.in.lock_count = 2;
324 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
325 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
326 status = smb2_lock(tree, &lck);
327 CHECK_STATUS(status, NT_STATUS_OK);
329 lck.in.lock_count = 1;
330 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
331 status = smb2_lock(tree, &lck);
332 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
338 struct test_lock_read_write_state {
341 NTSTATUS write_h1_status;
342 NTSTATUS read_h1_status;
343 NTSTATUS write_h2_status;
344 NTSTATUS read_h2_status;
347 static bool test_lock_read_write(struct torture_context *torture,
348 struct smb2_tree *tree,
349 struct test_lock_read_write_state *s)
353 struct smb2_handle h1, h2;
355 struct smb2_lock lck;
356 struct smb2_create cr;
357 struct smb2_write wr;
359 struct smb2_lock_element el[1];
365 status = torture_smb2_testfile(tree, s->fname, &h1);
366 CHECK_STATUS(status, NT_STATUS_OK);
368 status = smb2_util_write(tree, h1, buf, 0, ARRAY_SIZE(buf));
369 CHECK_STATUS(status, NT_STATUS_OK);
371 lck.in.lock_count = 0x0001;
372 lck.in.lock_sequence = 0x00000000;
373 lck.in.file.handle = h1;
375 el[0].length = ARRAY_SIZE(buf)/2;
376 el[0].reserved = 0x00000000;
377 el[0].flags = s->lock_flags;
378 status = smb2_lock(tree, &lck);
379 CHECK_STATUS(status, NT_STATUS_OK);
380 CHECK_VALUE(lck.out.reserved, 0);
382 lck.in.lock_count = 0x0001;
383 lck.in.lock_sequence = 0x00000000;
384 lck.in.file.handle = h1;
385 el[0].offset = ARRAY_SIZE(buf)/2;
386 el[0].length = ARRAY_SIZE(buf)/2;
387 el[0].reserved = 0x00000000;
388 el[0].flags = s->lock_flags;
389 status = smb2_lock(tree, &lck);
390 CHECK_STATUS(status, NT_STATUS_OK);
391 CHECK_VALUE(lck.out.reserved, 0);
394 cr.in.oplock_level = 0;
395 cr.in.desired_access = SEC_RIGHTS_FILE_ALL;
396 cr.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
397 cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
399 NTCREATEX_SHARE_ACCESS_DELETE|
400 NTCREATEX_SHARE_ACCESS_READ|
401 NTCREATEX_SHARE_ACCESS_WRITE;
402 cr.in.create_options = 0;
403 cr.in.fname = s->fname;
405 status = smb2_create(tree, tree, &cr);
406 CHECK_STATUS(status, NT_STATUS_OK);
408 h2 = cr.out.file.handle;
411 wr.in.file.handle = h1;
412 wr.in.offset = ARRAY_SIZE(buf)/2;
413 wr.in.data = data_blob_const(buf, ARRAY_SIZE(buf)/2);
415 status = smb2_write(tree, &wr);
416 CHECK_STATUS(status, s->write_h1_status);
419 rd.in.file.handle = h1;
420 rd.in.offset = ARRAY_SIZE(buf)/2;
421 rd.in.length = ARRAY_SIZE(buf)/2;
423 status = smb2_read(tree, tree, &rd);
424 CHECK_STATUS(status, s->read_h1_status);
427 wr.in.file.handle = h2;
428 wr.in.offset = ARRAY_SIZE(buf)/2;
429 wr.in.data = data_blob_const(buf, ARRAY_SIZE(buf)/2);
431 status = smb2_write(tree, &wr);
432 CHECK_STATUS(status, s->write_h2_status);
435 rd.in.file.handle = h2;
436 rd.in.offset = ARRAY_SIZE(buf)/2;
437 rd.in.length = ARRAY_SIZE(buf)/2;
439 status = smb2_read(tree, tree, &rd);
440 CHECK_STATUS(status, s->read_h2_status);
442 lck.in.lock_count = 0x0001;
443 lck.in.lock_sequence = 0x00000000;
444 lck.in.file.handle = h1;
445 el[0].offset = ARRAY_SIZE(buf)/2;
446 el[0].length = ARRAY_SIZE(buf)/2;
447 el[0].reserved = 0x00000000;
448 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
449 status = smb2_lock(tree, &lck);
450 CHECK_STATUS(status, NT_STATUS_OK);
451 CHECK_VALUE(lck.out.reserved, 0);
454 wr.in.file.handle = h2;
455 wr.in.offset = ARRAY_SIZE(buf)/2;
456 wr.in.data = data_blob_const(buf, ARRAY_SIZE(buf)/2);
458 status = smb2_write(tree, &wr);
459 CHECK_STATUS(status, NT_STATUS_OK);
462 rd.in.file.handle = h2;
463 rd.in.offset = ARRAY_SIZE(buf)/2;
464 rd.in.length = ARRAY_SIZE(buf)/2;
466 status = smb2_read(tree, tree, &rd);
467 CHECK_STATUS(status, NT_STATUS_OK);
473 static bool test_lock_rw_none(struct torture_context *torture,
474 struct smb2_tree *tree)
476 struct test_lock_read_write_state s = {
477 .fname = "lock_rw_none.dat",
478 .lock_flags = SMB2_LOCK_FLAG_NONE,
479 .write_h1_status = NT_STATUS_FILE_LOCK_CONFLICT,
480 .read_h1_status = NT_STATUS_OK,
481 .write_h2_status = NT_STATUS_FILE_LOCK_CONFLICT,
482 .read_h2_status = NT_STATUS_OK,
485 if (!TARGET_IS_W2K8(torture)) {
486 torture_skip(torture, "RW-NONE tests the behavior of a "
487 "NONE-type lock, which is the same as a SHARED "
488 "lock but is granted due to a bug in W2K8. If "
489 "target is not W2K8 we skip this test.\n");
492 return test_lock_read_write(torture, tree, &s);
495 static bool test_lock_rw_shared(struct torture_context *torture,
496 struct smb2_tree *tree)
498 struct test_lock_read_write_state s = {
499 .fname = "lock_rw_shared.dat",
500 .lock_flags = SMB2_LOCK_FLAG_SHARED,
501 .write_h1_status = NT_STATUS_FILE_LOCK_CONFLICT,
502 .read_h1_status = NT_STATUS_OK,
503 .write_h2_status = NT_STATUS_FILE_LOCK_CONFLICT,
504 .read_h2_status = NT_STATUS_OK,
507 return test_lock_read_write(torture, tree, &s);
510 static bool test_lock_rw_exclusive(struct torture_context *torture,
511 struct smb2_tree *tree)
513 struct test_lock_read_write_state s = {
514 .fname = "lock_rw_exclusive.dat",
515 .lock_flags = SMB2_LOCK_FLAG_EXCLUSIVE,
516 .write_h1_status = NT_STATUS_OK,
517 .read_h1_status = NT_STATUS_OK,
518 .write_h2_status = NT_STATUS_FILE_LOCK_CONFLICT,
519 .read_h2_status = NT_STATUS_FILE_LOCK_CONFLICT,
522 return test_lock_read_write(torture, tree, &s);
525 static bool test_lock_auto_unlock(struct torture_context *torture,
526 struct smb2_tree *tree)
530 struct smb2_handle h;
532 struct smb2_lock lck;
533 struct smb2_lock_element el[1];
537 status = torture_smb2_testfile(tree, "autounlock.txt", &h);
538 CHECK_STATUS(status, NT_STATUS_OK);
540 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
541 CHECK_STATUS(status, NT_STATUS_OK);
546 lck.in.lock_count = 0x0001;
547 lck.in.file.handle = h;
550 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
551 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
552 status = smb2_lock(tree, &lck);
553 CHECK_STATUS(status, NT_STATUS_OK);
555 status = smb2_lock(tree, &lck);
556 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
558 status = smb2_lock(tree, &lck);
559 if (TARGET_IS_W2K8(torture)) {
560 CHECK_STATUS(status, NT_STATUS_OK);
561 torture_warning(torture, "Target has \"pretty please\" bug. "
562 "A contending lock request on the same handle "
563 "unlocks the lock.\n");
565 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
568 status = smb2_lock(tree, &lck);
569 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
576 test different lock ranges and see if different handles conflict
578 static bool test_lock(struct torture_context *torture,
579 struct smb2_tree *tree)
583 struct smb2_handle h, h2;
585 struct smb2_lock lck;
586 struct smb2_lock_element el[2];
588 const char *fname = BASEDIR "\\async.txt";
590 status = torture_smb2_testdir(tree, BASEDIR, &h);
591 CHECK_STATUS(status, NT_STATUS_OK);
592 smb2_util_close(tree, h);
594 status = torture_smb2_testfile(tree, fname, &h);
595 CHECK_STATUS(status, NT_STATUS_OK);
598 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
599 CHECK_STATUS(status, NT_STATUS_OK);
601 status = torture_smb2_testfile(tree, fname, &h2);
602 CHECK_STATUS(status, NT_STATUS_OK);
606 lck.in.lock_count = 0x0001;
607 lck.in.lock_sequence = 0x00000000;
608 lck.in.file.handle = h;
609 el[0].reserved = 0x00000000;
610 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
611 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
613 torture_comment(torture, "Trying 0/0 lock\n");
614 el[0].offset = 0x0000000000000000;
615 el[0].length = 0x0000000000000000;
616 status = smb2_lock(tree, &lck);
617 CHECK_STATUS(status, NT_STATUS_OK);
618 lck.in.file.handle = h2;
619 status = smb2_lock(tree, &lck);
620 CHECK_STATUS(status, NT_STATUS_OK);
621 lck.in.file.handle = h;
622 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
623 status = smb2_lock(tree, &lck);
624 CHECK_STATUS(status, NT_STATUS_OK);
626 torture_comment(torture, "Trying 0/1 lock\n");
627 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
628 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
629 el[0].offset = 0x0000000000000000;
630 el[0].length = 0x0000000000000001;
631 status = smb2_lock(tree, &lck);
632 CHECK_STATUS(status, NT_STATUS_OK);
633 lck.in.file.handle = h2;
634 status = smb2_lock(tree, &lck);
635 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
636 lck.in.file.handle = h;
637 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
638 status = smb2_lock(tree, &lck);
639 CHECK_STATUS(status, NT_STATUS_OK);
640 status = smb2_lock(tree, &lck);
641 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
643 torture_comment(torture, "Trying 0xEEFFFFF lock\n");
644 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
645 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
646 el[0].offset = 0xEEFFFFFF;
648 status = smb2_lock(tree, &lck);
649 CHECK_STATUS(status, NT_STATUS_OK);
650 lck.in.file.handle = h2;
651 status = smb2_lock(tree, &lck);
652 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
653 lck.in.file.handle = h;
654 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
655 status = smb2_lock(tree, &lck);
656 CHECK_STATUS(status, NT_STATUS_OK);
657 status = smb2_lock(tree, &lck);
658 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
660 torture_comment(torture, "Trying 0xEF00000 lock\n");
661 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
662 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
663 el[0].offset = 0xEF000000;
665 status = smb2_lock(tree, &lck);
666 CHECK_STATUS(status, NT_STATUS_OK);
667 lck.in.file.handle = h2;
668 status = smb2_lock(tree, &lck);
669 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
670 lck.in.file.handle = h;
671 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
672 status = smb2_lock(tree, &lck);
673 CHECK_STATUS(status, NT_STATUS_OK);
674 status = smb2_lock(tree, &lck);
675 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
677 torture_comment(torture, "Trying (2^63 - 1)/1\n");
678 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
679 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
684 status = smb2_lock(tree, &lck);
685 CHECK_STATUS(status, NT_STATUS_OK);
686 lck.in.file.handle = h2;
687 status = smb2_lock(tree, &lck);
688 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
689 lck.in.file.handle = h;
690 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
691 status = smb2_lock(tree, &lck);
692 CHECK_STATUS(status, NT_STATUS_OK);
693 status = smb2_lock(tree, &lck);
694 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
696 torture_comment(torture, "Trying 2^63/1\n");
697 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
698 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
702 status = smb2_lock(tree, &lck);
703 CHECK_STATUS(status, NT_STATUS_OK);
704 lck.in.file.handle = h2;
705 status = smb2_lock(tree, &lck);
706 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
707 lck.in.file.handle = h;
708 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
709 status = smb2_lock(tree, &lck);
710 CHECK_STATUS(status, NT_STATUS_OK);
711 status = smb2_lock(tree, &lck);
712 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
714 torture_comment(torture, "Trying max/0 lock\n");
715 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
716 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
719 status = smb2_lock(tree, &lck);
720 CHECK_STATUS(status, NT_STATUS_OK);
721 lck.in.file.handle = h2;
722 status = smb2_lock(tree, &lck);
723 CHECK_STATUS(status, NT_STATUS_OK);
724 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
725 status = smb2_lock(tree, &lck);
726 CHECK_STATUS(status, NT_STATUS_OK);
727 lck.in.file.handle = h;
728 status = smb2_lock(tree, &lck);
729 CHECK_STATUS(status, NT_STATUS_OK);
730 status = smb2_lock(tree, &lck);
731 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
733 torture_comment(torture, "Trying max/1 lock\n");
734 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
735 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
738 status = smb2_lock(tree, &lck);
739 CHECK_STATUS(status, NT_STATUS_OK);
740 lck.in.file.handle = h2;
741 status = smb2_lock(tree, &lck);
742 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
743 lck.in.file.handle = h;
744 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
745 status = smb2_lock(tree, &lck);
746 CHECK_STATUS(status, NT_STATUS_OK);
747 status = smb2_lock(tree, &lck);
748 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
750 torture_comment(torture, "Trying max/2 lock\n");
751 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
752 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
755 status = smb2_lock(tree, &lck);
756 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
757 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
759 CHECK_STATUS(status, NT_STATUS_OK);
760 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
761 status = smb2_lock(tree, &lck);
762 CHECK_STATUS(status, NT_STATUS_OK);
765 torture_comment(torture, "Trying wrong handle unlock\n");
766 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
767 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
768 el[0].offset = 10001;
769 el[0].length = 40002;
770 status = smb2_lock(tree, &lck);
771 CHECK_STATUS(status, NT_STATUS_OK);
772 lck.in.file.handle = h2;
773 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
774 status = smb2_lock(tree, &lck);
775 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
776 lck.in.file.handle = h;
777 status = smb2_lock(tree, &lck);
778 CHECK_STATUS(status, NT_STATUS_OK);
781 smb2_util_close(tree, h2);
782 smb2_util_close(tree, h);
783 smb2_deltree(tree, BASEDIR);
788 test SMB2 LOCK async operation
790 static bool test_async(struct torture_context *torture,
791 struct smb2_tree *tree)
795 struct smb2_handle h, h2;
797 struct smb2_lock lck;
798 struct smb2_lock_element el[2];
799 struct smb2_request *req = NULL;
801 const char *fname = BASEDIR "\\async.txt";
803 status = torture_smb2_testdir(tree, BASEDIR, &h);
804 CHECK_STATUS(status, NT_STATUS_OK);
805 smb2_util_close(tree, h);
807 status = torture_smb2_testfile(tree, fname, &h);
808 CHECK_STATUS(status, NT_STATUS_OK);
811 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
812 CHECK_STATUS(status, NT_STATUS_OK);
814 status = torture_smb2_testfile(tree, fname, &h2);
815 CHECK_STATUS(status, NT_STATUS_OK);
819 lck.in.lock_count = 0x0001;
820 lck.in.lock_sequence = 0x00000000;
821 lck.in.file.handle = h;
824 el[0].reserved = 0x00000000;
825 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
827 torture_comment(torture, " Acquire first lock\n");
828 status = smb2_lock(tree, &lck);
829 CHECK_STATUS(status, NT_STATUS_OK);
831 torture_comment(torture, " Second lock should pend on first\n");
832 lck.in.file.handle = h2;
833 req = smb2_lock_send(tree, &lck);
834 WAIT_FOR_ASYNC_RESPONSE(req);
836 torture_comment(torture, " Unlock first lock\n");
837 lck.in.file.handle = h;
838 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
839 status = smb2_lock(tree, &lck);
840 CHECK_STATUS(status, NT_STATUS_OK);
842 torture_comment(torture, " Second lock should now succeed\n");
843 lck.in.file.handle = h2;
844 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
845 status = smb2_lock_recv(req, &lck);
846 CHECK_STATUS(status, NT_STATUS_OK);
849 smb2_util_close(tree, h2);
850 smb2_util_close(tree, h);
851 smb2_deltree(tree, BASEDIR);
856 test SMB2 LOCK Cancel operation
858 static bool test_cancel(struct torture_context *torture,
859 struct smb2_tree *tree)
863 struct smb2_handle h, h2;
865 struct smb2_lock lck;
866 struct smb2_lock_element el[2];
867 struct smb2_request *req = NULL;
869 const char *fname = BASEDIR "\\cancel.txt";
871 status = torture_smb2_testdir(tree, BASEDIR, &h);
872 CHECK_STATUS(status, NT_STATUS_OK);
873 smb2_util_close(tree, h);
875 status = torture_smb2_testfile(tree, fname, &h);
876 CHECK_STATUS(status, NT_STATUS_OK);
879 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
880 CHECK_STATUS(status, NT_STATUS_OK);
882 status = torture_smb2_testfile(tree, fname, &h2);
883 CHECK_STATUS(status, NT_STATUS_OK);
887 lck.in.lock_count = 0x0001;
888 lck.in.lock_sequence = 0x00000000;
889 lck.in.file.handle = h;
892 el[0].reserved = 0x00000000;
893 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
895 torture_comment(torture, "Testing basic cancel\n");
897 torture_comment(torture, " Acquire first lock\n");
898 status = smb2_lock(tree, &lck);
899 CHECK_STATUS(status, NT_STATUS_OK);
901 torture_comment(torture, " Second lock should pend on first\n");
902 lck.in.file.handle = h2;
903 req = smb2_lock_send(tree, &lck);
904 WAIT_FOR_ASYNC_RESPONSE(req);
906 torture_comment(torture, " Cancel the second lock\n");
908 lck.in.file.handle = h2;
909 status = smb2_lock_recv(req, &lck);
910 CHECK_STATUS(status, NT_STATUS_CANCELLED);
912 torture_comment(torture, " Unlock first lock\n");
913 lck.in.file.handle = h;
914 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
915 status = smb2_lock(tree, &lck);
916 CHECK_STATUS(status, NT_STATUS_OK);
919 torture_comment(torture, "Testing cancel by unlock\n");
921 torture_comment(torture, " Acquire first lock\n");
922 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
923 status = smb2_lock(tree, &lck);
924 CHECK_STATUS(status, NT_STATUS_OK);
926 torture_comment(torture, " Second lock should pend on first\n");
927 lck.in.file.handle = h2;
928 req = smb2_lock_send(tree, &lck);
929 WAIT_FOR_ASYNC_RESPONSE(req);
931 torture_comment(torture, " Attempt to unlock pending second lock\n");
932 lck.in.file.handle = h2;
933 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
934 status = smb2_lock(tree, &lck);
935 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
937 torture_comment(torture, " Now cancel the second lock\n");
939 lck.in.file.handle = h2;
940 status = smb2_lock_recv(req, &lck);
941 CHECK_STATUS(status, NT_STATUS_CANCELLED);
943 torture_comment(torture, " Unlock first lock\n");
944 lck.in.file.handle = h;
945 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
946 status = smb2_lock(tree, &lck);
947 CHECK_STATUS(status, NT_STATUS_OK);
950 torture_comment(torture, "Testing cancel by close\n");
952 torture_comment(torture, " Acquire first lock\n");
953 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
954 status = smb2_lock(tree, &lck);
955 CHECK_STATUS(status, NT_STATUS_OK);
957 torture_comment(torture, " Second lock should pend on first\n");
958 lck.in.file.handle = h2;
959 req = smb2_lock_send(tree, &lck);
960 WAIT_FOR_ASYNC_RESPONSE(req);
962 torture_comment(torture, " Close the second lock handle\n");
963 smb2_util_close(tree, h2);
964 CHECK_STATUS(status, NT_STATUS_OK);
966 torture_comment(torture, " Check pending lock reply\n");
967 status = smb2_lock_recv(req, &lck);
968 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
970 torture_comment(torture, " Unlock first lock\n");
971 lck.in.file.handle = h;
972 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
973 status = smb2_lock(tree, &lck);
974 CHECK_STATUS(status, NT_STATUS_OK);
977 smb2_util_close(tree, h2);
978 smb2_util_close(tree, h);
979 smb2_deltree(tree, BASEDIR);
984 test SMB2 LOCK Cancel by tree disconnect
986 static bool test_cancel_tdis(struct torture_context *torture,
987 struct smb2_tree *tree)
991 struct smb2_handle h, h2;
993 struct smb2_lock lck;
994 struct smb2_lock_element el[2];
995 struct smb2_request *req = NULL;
997 const char *fname = BASEDIR "\\cancel_tdis.txt";
999 status = torture_smb2_testdir(tree, BASEDIR, &h);
1000 CHECK_STATUS(status, NT_STATUS_OK);
1001 smb2_util_close(tree, h);
1003 status = torture_smb2_testfile(tree, fname, &h);
1004 CHECK_STATUS(status, NT_STATUS_OK);
1007 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1008 CHECK_STATUS(status, NT_STATUS_OK);
1010 status = torture_smb2_testfile(tree, fname, &h2);
1011 CHECK_STATUS(status, NT_STATUS_OK);
1015 lck.in.lock_count = 0x0001;
1016 lck.in.lock_sequence = 0x00000000;
1017 lck.in.file.handle = h;
1020 el[0].reserved = 0x00000000;
1021 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1023 torture_comment(torture, "Testing cancel by tree disconnect\n");
1025 status = torture_smb2_testfile(tree, fname, &h);
1026 CHECK_STATUS(status, NT_STATUS_OK);
1028 status = torture_smb2_testfile(tree, fname, &h2);
1029 CHECK_STATUS(status, NT_STATUS_OK);
1031 torture_comment(torture, " Acquire first lock\n");
1032 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1033 status = smb2_lock(tree, &lck);
1034 CHECK_STATUS(status, NT_STATUS_OK);
1036 torture_comment(torture, " Second lock should pend on first\n");
1037 lck.in.file.handle = h2;
1038 req = smb2_lock_send(tree, &lck);
1039 WAIT_FOR_ASYNC_RESPONSE(req);
1041 torture_comment(torture, " Disconnect the tree\n");
1043 CHECK_STATUS(status, NT_STATUS_OK);
1045 torture_comment(torture, " Check pending lock reply\n");
1046 status = smb2_lock_recv(req, &lck);
1047 if (torture_setting_bool(torture, "samba4", false)) {
1048 /* saying that this lock succeeded is nonsense - the
1050 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1052 CHECK_STATUS(status, NT_STATUS_OK);
1055 torture_comment(torture, " Attempt to unlock first lock\n");
1056 lck.in.file.handle = h;
1057 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1058 status = smb2_lock(tree, &lck);
1059 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1062 smb2_util_close(tree, h2);
1063 smb2_util_close(tree, h);
1064 smb2_deltree(tree, BASEDIR);
1069 test SMB2 LOCK Cancel by user logoff
1071 static bool test_cancel_logoff(struct torture_context *torture,
1072 struct smb2_tree *tree)
1076 struct smb2_handle h, h2;
1078 struct smb2_lock lck;
1079 struct smb2_lock_element el[2];
1080 struct smb2_request *req = NULL;
1082 const char *fname = BASEDIR "\\cancel_tdis.txt";
1084 status = torture_smb2_testdir(tree, BASEDIR, &h);
1085 CHECK_STATUS(status, NT_STATUS_OK);
1086 smb2_util_close(tree, h);
1088 status = torture_smb2_testfile(tree, fname, &h);
1089 CHECK_STATUS(status, NT_STATUS_OK);
1092 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1093 CHECK_STATUS(status, NT_STATUS_OK);
1095 status = torture_smb2_testfile(tree, fname, &h2);
1096 CHECK_STATUS(status, NT_STATUS_OK);
1100 lck.in.lock_count = 0x0001;
1101 lck.in.lock_sequence = 0x00000000;
1102 lck.in.file.handle = h;
1105 el[0].reserved = 0x00000000;
1106 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1108 torture_comment(torture, "Testing cancel by ulogoff\n");
1110 torture_comment(torture, " Acquire first lock\n");
1111 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1112 status = smb2_lock(tree, &lck);
1113 CHECK_STATUS(status, NT_STATUS_OK);
1115 torture_comment(torture, " Second lock should pend on first\n");
1116 lck.in.file.handle = h2;
1117 req = smb2_lock_send(tree, &lck);
1118 WAIT_FOR_ASYNC_RESPONSE(req);
1120 torture_comment(torture, " Logoff user\n");
1121 smb2_logoff(tree->session);
1123 torture_comment(torture, " Check pending lock reply\n");
1124 status = smb2_lock_recv(req, &lck);
1125 if (torture_setting_bool(torture, "samba4", false)) {
1126 /* another bogus 'success' code from windows. The lock
1127 * cannot have succeeded, as we are now logged off */
1128 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1130 CHECK_STATUS(status, NT_STATUS_OK);
1133 torture_comment(torture, " Attempt to unlock first lock\n");
1134 lck.in.file.handle = h;
1135 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1136 status = smb2_lock(tree, &lck);
1137 if (torture_setting_bool(torture, "samba4", false)) {
1138 /* checking if the credential supplied are still valid
1139 * should happen before you validate a file handle,
1140 * so we should return USER_SESSION_DELETED */
1141 CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
1143 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1147 smb2_util_close(tree, h2);
1148 smb2_util_close(tree, h);
1149 smb2_deltree(tree, BASEDIR);
1154 * Test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
1156 * The SMBv1 protocol returns a different error code on lock acquisition
1157 * failure depending on a number of parameters, including what error code
1158 * was returned to the previous failure.
1160 * SMBv2 has cleaned up these semantics and should always return
1161 * NT_STATUS_LOCK_NOT_GRANTED to failed lock requests, and
1162 * NT_STATUS_FILE_LOCK_CONFLICT to failed read/write requests due to a lock
1163 * being held on that range.
1165 static bool test_errorcode(struct torture_context *torture,
1166 struct smb2_tree *tree)
1170 struct smb2_handle h, h2;
1172 struct smb2_lock lck;
1173 struct smb2_lock_element el[2];
1175 const char *fname = BASEDIR "\\errorcode.txt";
1177 status = torture_smb2_testdir(tree, BASEDIR, &h);
1178 CHECK_STATUS(status, NT_STATUS_OK);
1179 smb2_util_close(tree, h);
1181 status = torture_smb2_testfile(tree, fname, &h);
1182 CHECK_STATUS(status, NT_STATUS_OK);
1185 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1186 CHECK_STATUS(status, NT_STATUS_OK);
1188 status = torture_smb2_testfile(tree, fname, &h2);
1189 CHECK_STATUS(status, NT_STATUS_OK);
1193 lck.in.lock_count = 0x0001;
1194 lck.in.lock_sequence = 0x00000000;
1195 lck.in.file.handle = h;
1198 el[0].reserved = 0x00000000;
1199 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1200 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1202 torture_comment(torture, "Testing LOCK_NOT_GRANTED vs. "
1203 "FILE_LOCK_CONFLICT\n");
1205 if (TARGET_IS_W2K8(torture)) {
1206 torture_result(torture, TORTURE_SKIP,
1207 "Target has \"pretty please\" bug. A contending lock "
1208 "request on the same handle unlocks the lock.");
1212 status = smb2_lock(tree, &lck);
1213 CHECK_STATUS(status, NT_STATUS_OK);
1215 /* Demonstrate that the first conflicting lock on each handle gives
1216 * LOCK_NOT_GRANTED. */
1217 lck.in.file.handle = h;
1218 status = smb2_lock(tree, &lck);
1219 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1221 lck.in.file.handle = h2;
1222 status = smb2_lock(tree, &lck);
1223 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1225 /* Demonstrate that each following conflict also gives
1226 * LOCK_NOT_GRANTED */
1227 lck.in.file.handle = h;
1228 status = smb2_lock(tree, &lck);
1229 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1231 lck.in.file.handle = h2;
1232 status = smb2_lock(tree, &lck);
1233 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1235 lck.in.file.handle = h;
1236 status = smb2_lock(tree, &lck);
1237 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1239 lck.in.file.handle = h2;
1240 status = smb2_lock(tree, &lck);
1241 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1243 /* Demonstrate that the smbpid doesn't matter */
1244 tree->session->pid++;
1245 lck.in.file.handle = h;
1246 status = smb2_lock(tree, &lck);
1247 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1249 lck.in.file.handle = h2;
1250 status = smb2_lock(tree, &lck);
1251 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1252 tree->session->pid--;
1254 /* Demonstrate that a 0-byte lock inside the locked range still
1255 * gives the same error. */
1259 lck.in.file.handle = h;
1260 status = smb2_lock(tree, &lck);
1261 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1263 lck.in.file.handle = h2;
1264 status = smb2_lock(tree, &lck);
1265 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1267 /* Demonstrate that a lock inside the locked range still gives the
1272 lck.in.file.handle = h;
1273 status = smb2_lock(tree, &lck);
1274 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1276 lck.in.file.handle = h2;
1277 status = smb2_lock(tree, &lck);
1278 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1281 smb2_util_close(tree, h2);
1282 smb2_util_close(tree, h);
1283 smb2_deltree(tree, BASEDIR);
1288 * Tests zero byte locks.
1291 struct double_lock_test {
1292 struct smb2_lock_element lock1;
1293 struct smb2_lock_element lock2;
1297 static struct double_lock_test zero_byte_tests[] = {
1298 /* {offset, count, reserved, flags},
1299 * {offset, count, reserved, flags},
1302 /** First, takes a zero byte lock at offset 10. Then:
1303 * - Taking 0 byte lock at 10 should succeed.
1304 * - Taking 1 byte locks at 9,10,11 should succeed.
1305 * - Taking 2 byte lock at 9 should fail.
1306 * - Taking 2 byte lock at 10 should succeed.
1307 * - Taking 3 byte lock at 9 should fail.
1309 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1310 {{10, 0, 0, 0}, {9, 1, 0, 0}, NT_STATUS_OK},
1311 {{10, 0, 0, 0}, {10, 1, 0, 0}, NT_STATUS_OK},
1312 {{10, 0, 0, 0}, {11, 1, 0, 0}, NT_STATUS_OK},
1313 {{10, 0, 0, 0}, {9, 2, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1314 {{10, 0, 0, 0}, {10, 2, 0, 0}, NT_STATUS_OK},
1315 {{10, 0, 0, 0}, {9, 3, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1317 /** Same, but opposite order. */
1318 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1319 {{9, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1320 {{10, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1321 {{11, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1322 {{9, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1323 {{10, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1324 {{9, 3, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1326 /** Zero zero case. */
1327 {{0, 0, 0, 0}, {0, 0, 0, 0}, NT_STATUS_OK},
1330 static bool test_zerobytelength(struct torture_context *torture,
1331 struct smb2_tree *tree)
1335 struct smb2_handle h, h2;
1337 struct smb2_lock lck;
1340 const char *fname = BASEDIR "\\zero.txt";
1342 torture_comment(torture, "Testing zero length byte range locks:\n");
1344 status = torture_smb2_testdir(tree, BASEDIR, &h);
1345 CHECK_STATUS(status, NT_STATUS_OK);
1346 smb2_util_close(tree, h);
1348 status = torture_smb2_testfile(tree, fname, &h);
1349 CHECK_STATUS(status, NT_STATUS_OK);
1352 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1353 CHECK_STATUS(status, NT_STATUS_OK);
1355 status = torture_smb2_testfile(tree, fname, &h2);
1356 CHECK_STATUS(status, NT_STATUS_OK);
1358 /* Setup initial parameters */
1359 lck.in.lock_count = 0x0001;
1360 lck.in.lock_sequence = 0x00000000;
1361 lck.in.file.handle = h;
1363 /* Try every combination of locks in zero_byte_tests, using the same
1364 * handle for both locks. The first lock is assumed to succeed. The
1365 * second lock may contend, depending on the expected status. */
1366 for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1367 torture_comment(torture,
1368 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1369 zero_byte_tests[i].lock1.offset,
1370 zero_byte_tests[i].lock1.length,
1371 zero_byte_tests[i].lock2.offset,
1372 zero_byte_tests[i].lock2.length,
1373 nt_errstr(zero_byte_tests[i].status));
1375 /* Lock both locks. */
1376 lck.in.locks = &zero_byte_tests[i].lock1;
1377 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1378 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1379 status = smb2_lock(tree, &lck);
1380 CHECK_STATUS(status, NT_STATUS_OK);
1382 lck.in.locks = &zero_byte_tests[i].lock2;
1383 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1384 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1385 status = smb2_lock(tree, &lck);
1386 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1388 /* Unlock both locks in reverse order. */
1389 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1390 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1391 status = smb2_lock(tree, &lck);
1392 CHECK_STATUS(status, NT_STATUS_OK);
1395 lck.in.locks = &zero_byte_tests[i].lock1;
1396 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1397 status = smb2_lock(tree, &lck);
1398 CHECK_STATUS(status, NT_STATUS_OK);
1401 /* Try every combination of locks in zero_byte_tests, using two
1402 * different handles. */
1403 for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1404 torture_comment(torture,
1405 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1406 zero_byte_tests[i].lock1.offset,
1407 zero_byte_tests[i].lock1.length,
1408 zero_byte_tests[i].lock2.offset,
1409 zero_byte_tests[i].lock2.length,
1410 nt_errstr(zero_byte_tests[i].status));
1412 /* Lock both locks. */
1413 lck.in.file.handle = h;
1414 lck.in.locks = &zero_byte_tests[i].lock1;
1415 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1416 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1417 status = smb2_lock(tree, &lck);
1418 CHECK_STATUS(status, NT_STATUS_OK);
1420 lck.in.file.handle = h2;
1421 lck.in.locks = &zero_byte_tests[i].lock2;
1422 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1423 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1424 status = smb2_lock(tree, &lck);
1425 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1427 /* Unlock both locks in reverse order. */
1428 lck.in.file.handle = h2;
1429 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1430 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1431 status = smb2_lock(tree, &lck);
1432 CHECK_STATUS(status, NT_STATUS_OK);
1435 lck.in.file.handle = h;
1436 lck.in.locks = &zero_byte_tests[i].lock1;
1437 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1438 status = smb2_lock(tree, &lck);
1439 CHECK_STATUS(status, NT_STATUS_OK);
1443 smb2_util_close(tree, h2);
1444 smb2_util_close(tree, h);
1445 smb2_deltree(tree, BASEDIR);
1449 static bool test_unlock(struct torture_context *torture,
1450 struct smb2_tree *tree)
1454 struct smb2_handle h, h2;
1456 struct smb2_lock lck;
1457 struct smb2_lock_element el1[1];
1458 struct smb2_lock_element el2[1];
1460 const char *fname = BASEDIR "\\unlock.txt";
1462 status = torture_smb2_testdir(tree, BASEDIR, &h);
1463 CHECK_STATUS(status, NT_STATUS_OK);
1464 smb2_util_close(tree, h);
1466 status = torture_smb2_testfile(tree, fname, &h);
1467 CHECK_STATUS(status, NT_STATUS_OK);
1470 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1471 CHECK_STATUS(status, NT_STATUS_OK);
1473 status = torture_smb2_testfile(tree, fname, &h2);
1474 CHECK_STATUS(status, NT_STATUS_OK);
1476 /* Setup initial parameters */
1478 lck.in.lock_count = 0x0001;
1479 lck.in.lock_sequence = 0x00000000;
1482 el1[0].reserved = 0x00000000;
1484 /* Take exclusive lock, then unlock it with a shared-unlock call. */
1486 torture_comment(torture, "Testing unlock exclusive with shared\n");
1488 torture_comment(torture, " taking exclusive lock.\n");
1489 lck.in.file.handle = h;
1490 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1491 status = smb2_lock(tree, &lck);
1492 CHECK_STATUS(status, NT_STATUS_OK);
1494 torture_comment(torture, " try to unlock the exclusive with a shared "
1496 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1497 SMB2_LOCK_FLAG_UNLOCK;
1498 status = smb2_lock(tree, &lck);
1499 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1501 torture_comment(torture, " try shared lock on h2, to test the "
1503 lck.in.file.handle = h2;
1504 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1505 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1506 status = smb2_lock(tree, &lck);
1507 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1509 torture_comment(torture, " unlock the exclusive lock\n");
1510 lck.in.file.handle = h;
1511 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1512 status = smb2_lock(tree, &lck);
1513 CHECK_STATUS(status, NT_STATUS_OK);
1515 /* Unlock a shared lock with an exclusive-unlock call. */
1517 torture_comment(torture, "Testing unlock shared with exclusive\n");
1519 torture_comment(torture, " taking shared lock.\n");
1520 lck.in.file.handle = h;
1521 el1[0].flags = SMB2_LOCK_FLAG_SHARED;
1522 status = smb2_lock(tree, &lck);
1523 CHECK_STATUS(status, NT_STATUS_OK);
1525 torture_comment(torture, " try to unlock the shared with an exclusive "
1527 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1528 SMB2_LOCK_FLAG_UNLOCK;
1529 status = smb2_lock(tree, &lck);
1530 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1532 torture_comment(torture, " try exclusive lock on h2, to test the "
1534 lck.in.file.handle = h2;
1535 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1536 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1537 status = smb2_lock(tree, &lck);
1538 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1540 torture_comment(torture, " unlock the exclusive lock\n");
1541 lck.in.file.handle = h;
1542 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1543 status = smb2_lock(tree, &lck);
1544 CHECK_STATUS(status, NT_STATUS_OK);
1546 /* Test unlocking of stacked 0-byte locks. SMB2 0-byte lock behavior
1547 * should be the same as >0-byte behavior. Exclusive locks should be
1548 * unlocked before shared. */
1550 torture_comment(torture, "Test unlocking stacked 0-byte locks\n");
1553 lck.in.file.handle = h;
1556 el1[0].reserved = 0x00000000;
1559 el2[0].reserved = 0x00000000;
1561 /* lock 0-byte exclusive */
1562 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1563 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1564 status = smb2_lock(tree, &lck);
1565 CHECK_STATUS(status, NT_STATUS_OK);
1567 /* lock 0-byte shared */
1568 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1569 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1570 status = smb2_lock(tree, &lck);
1571 CHECK_STATUS(status, NT_STATUS_OK);
1573 /* test contention */
1575 lck.in.file.handle = h2;
1576 el2[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1577 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1578 status = smb2_lock(tree, &lck);
1579 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1582 lck.in.file.handle = h2;
1583 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1584 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1585 status = smb2_lock(tree, &lck);
1586 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1590 lck.in.file.handle = h;
1591 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1592 status = smb2_lock(tree, &lck);
1593 CHECK_STATUS(status, NT_STATUS_OK);
1595 /* test - can we take a shared lock? */
1597 lck.in.file.handle = h2;
1598 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1599 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1600 status = smb2_lock(tree, &lck);
1601 CHECK_STATUS(status, NT_STATUS_OK);
1603 el2[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1604 status = smb2_lock(tree, &lck);
1605 CHECK_STATUS(status, NT_STATUS_OK);
1609 lck.in.file.handle = h;
1610 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1611 status = smb2_lock(tree, &lck);
1612 CHECK_STATUS(status, NT_STATUS_OK);
1614 /* Test unlocking of stacked exclusive, shared locks. Exclusive
1615 * should be unlocked before any shared. */
1617 torture_comment(torture, "Test unlocking stacked exclusive/shared "
1621 lck.in.file.handle = h;
1624 el1[0].reserved = 0x00000000;
1627 el2[0].reserved = 0x00000000;
1629 /* lock exclusive */
1630 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1631 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1632 status = smb2_lock(tree, &lck);
1633 CHECK_STATUS(status, NT_STATUS_OK);
1636 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1637 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1638 status = smb2_lock(tree, &lck);
1639 CHECK_STATUS(status, NT_STATUS_OK);
1641 /* test contention */
1643 lck.in.file.handle = h2;
1644 el2[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1645 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1646 status = smb2_lock(tree, &lck);
1647 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1650 lck.in.file.handle = h2;
1651 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1652 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1653 status = smb2_lock(tree, &lck);
1654 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1658 lck.in.file.handle = h;
1659 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1660 status = smb2_lock(tree, &lck);
1661 CHECK_STATUS(status, NT_STATUS_OK);
1663 /* test - can we take a shared lock? */
1665 lck.in.file.handle = h2;
1666 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1667 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1668 status = smb2_lock(tree, &lck);
1669 CHECK_STATUS(status, NT_STATUS_OK);
1671 el2[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1672 status = smb2_lock(tree, &lck);
1673 CHECK_STATUS(status, NT_STATUS_OK);
1677 lck.in.file.handle = h;
1678 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1679 status = smb2_lock(tree, &lck);
1680 CHECK_STATUS(status, NT_STATUS_OK);
1683 smb2_util_close(tree, h2);
1684 smb2_util_close(tree, h);
1685 smb2_deltree(tree, BASEDIR);
1689 static bool test_multiple_unlock(struct torture_context *torture,
1690 struct smb2_tree *tree)
1694 struct smb2_handle h;
1696 struct smb2_lock lck;
1697 struct smb2_lock_element el[2];
1698 struct smb2_lock_element el0, el1;
1700 const char *fname = BASEDIR "\\unlock_multiple.txt";
1702 status = torture_smb2_testdir(tree, BASEDIR, &h);
1703 CHECK_STATUS(status, NT_STATUS_OK);
1704 smb2_util_close(tree, h);
1706 status = torture_smb2_testfile(tree, fname, &h);
1707 CHECK_STATUS(status, NT_STATUS_OK);
1710 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1711 CHECK_STATUS(status, NT_STATUS_OK);
1713 torture_comment(torture, "Testing multiple unlocks:\n");
1715 /* Setup initial parameters */
1716 lck.in.lock_count = 0x0002;
1717 lck.in.lock_sequence = 0x00000000;
1718 lck.in.file.handle = h;
1721 el0.reserved = 0x00000000;
1724 el1.reserved = 0x00000000;
1728 /* Test1: Acquire second lock, but not first. */
1729 torture_comment(torture, " unlock 2 locks, first one not locked. "
1730 "Expect no locks unlocked. \n");
1732 lck.in.lock_count = 0x0001;
1733 el1.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1734 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1735 lck.in.locks = &el1;
1736 status = smb2_lock(tree, &lck);
1737 CHECK_STATUS(status, NT_STATUS_OK);
1739 /* Try to unlock both locks */
1740 lck.in.lock_count = 0x0002;
1741 el0.flags = SMB2_LOCK_FLAG_UNLOCK;
1742 el1.flags = SMB2_LOCK_FLAG_UNLOCK;
1746 status = smb2_lock(tree, &lck);
1747 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1749 /* Second lock should not be unlocked. */
1750 lck.in.lock_count = 0x0001;
1751 el1.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1752 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1753 lck.in.locks = &el1;
1754 status = smb2_lock(tree, &lck);
1755 if (TARGET_IS_W2K8(torture)) {
1756 CHECK_STATUS(status, NT_STATUS_OK);
1757 torture_warning(torture, "Target has \"pretty please\" bug. "
1758 "A contending lock request on the same handle "
1759 "unlocks the lock.\n");
1761 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1765 lck.in.lock_count = 0x0001;
1766 el1.flags = SMB2_LOCK_FLAG_UNLOCK;
1767 lck.in.locks = &el1;
1768 status = smb2_lock(tree, &lck);
1769 CHECK_STATUS(status, NT_STATUS_OK);
1771 /* Test2: Acquire first lock, but not second. */
1772 torture_comment(torture, " unlock 2 locks, second one not locked. "
1773 "Expect first lock unlocked.\n");
1775 lck.in.lock_count = 0x0001;
1776 el0.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1777 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1778 lck.in.locks = &el0;
1779 status = smb2_lock(tree, &lck);
1780 CHECK_STATUS(status, NT_STATUS_OK);
1782 /* Try to unlock both locks */
1783 lck.in.lock_count = 0x0002;
1784 el0.flags = SMB2_LOCK_FLAG_UNLOCK;
1785 el1.flags = SMB2_LOCK_FLAG_UNLOCK;
1789 status = smb2_lock(tree, &lck);
1790 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1792 /* First lock should be unlocked. */
1793 lck.in.lock_count = 0x0001;
1794 el0.flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1795 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1796 lck.in.locks = &el0;
1797 status = smb2_lock(tree, &lck);
1798 CHECK_STATUS(status, NT_STATUS_OK);
1801 lck.in.lock_count = 0x0001;
1802 el0.flags = SMB2_LOCK_FLAG_UNLOCK;
1803 lck.in.locks = &el0;
1804 status = smb2_lock(tree, &lck);
1805 CHECK_STATUS(status, NT_STATUS_OK);
1808 smb2_util_close(tree, h);
1809 smb2_deltree(tree, BASEDIR);
1814 * Test lock stacking
1815 * - some tests ported from BASE-LOCK-LOCK5
1817 static bool test_stacking(struct torture_context *torture,
1818 struct smb2_tree *tree)
1822 struct smb2_handle h, h2;
1824 struct smb2_lock lck;
1825 struct smb2_lock_element el[1];
1827 const char *fname = BASEDIR "\\stacking.txt";
1829 status = torture_smb2_testdir(tree, BASEDIR, &h);
1830 CHECK_STATUS(status, NT_STATUS_OK);
1831 smb2_util_close(tree, h);
1833 status = torture_smb2_testfile(tree, fname, &h);
1834 CHECK_STATUS(status, NT_STATUS_OK);
1837 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1838 CHECK_STATUS(status, NT_STATUS_OK);
1840 status = torture_smb2_testfile(tree, fname, &h2);
1841 CHECK_STATUS(status, NT_STATUS_OK);
1843 torture_comment(torture, "Testing lock stacking:\n");
1845 /* Setup initial parameters */
1847 lck.in.lock_count = 0x0001;
1848 lck.in.lock_sequence = 0x00000000;
1849 lck.in.file.handle = h;
1852 el[0].reserved = 0x00000000;
1854 /* Try to take a shared lock, then a shared lock on same handle */
1855 torture_comment(torture, " stacking a shared on top of a shared"
1856 "lock succeeds.\n");
1858 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1859 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1860 status = smb2_lock(tree, &lck);
1861 CHECK_STATUS(status, NT_STATUS_OK);
1863 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1864 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1865 status = smb2_lock(tree, &lck);
1866 CHECK_STATUS(status, NT_STATUS_OK);
1869 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1870 status = smb2_lock(tree, &lck);
1871 CHECK_STATUS(status, NT_STATUS_OK);
1873 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1874 status = smb2_lock(tree, &lck);
1875 CHECK_STATUS(status, NT_STATUS_OK);
1878 /* Try to take an exclusive lock, then a shared lock on same handle */
1879 torture_comment(torture, " stacking a shared on top of an exclusive "
1880 "lock succeeds.\n");
1882 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1883 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1884 status = smb2_lock(tree, &lck);
1885 CHECK_STATUS(status, NT_STATUS_OK);
1887 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1888 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1889 status = smb2_lock(tree, &lck);
1890 CHECK_STATUS(status, NT_STATUS_OK);
1892 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1893 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1894 status = smb2_lock(tree, &lck);
1895 CHECK_STATUS(status, NT_STATUS_OK);
1897 /* stacking a shared from a different handle should fail */
1898 lck.in.file.handle = h2;
1899 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1900 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1901 status = smb2_lock(tree, &lck);
1902 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1905 lck.in.file.handle = h;
1906 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1907 status = smb2_lock(tree, &lck);
1908 CHECK_STATUS(status, NT_STATUS_OK);
1910 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1911 status = smb2_lock(tree, &lck);
1912 CHECK_STATUS(status, NT_STATUS_OK);
1914 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1915 status = smb2_lock(tree, &lck);
1916 CHECK_STATUS(status, NT_STATUS_OK);
1918 /* ensure the 4th unlock fails */
1919 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1920 status = smb2_lock(tree, &lck);
1921 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1923 /* ensure a second handle can now take an exclusive lock */
1924 lck.in.file.handle = h2;
1925 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1926 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1927 status = smb2_lock(tree, &lck);
1928 CHECK_STATUS(status, NT_STATUS_OK);
1930 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1931 status = smb2_lock(tree, &lck);
1932 CHECK_STATUS(status, NT_STATUS_OK);
1934 /* Try to take an exclusive lock, then a shared lock on a
1935 * different handle */
1936 torture_comment(torture, " stacking a shared on top of an exclusive "
1937 "lock with different handles fails.\n");
1939 lck.in.file.handle = h;
1940 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1941 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1942 status = smb2_lock(tree, &lck);
1943 CHECK_STATUS(status, NT_STATUS_OK);
1945 lck.in.file.handle = h2;
1946 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1947 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1948 status = smb2_lock(tree, &lck);
1949 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1952 lck.in.file.handle = h;
1953 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1954 status = smb2_lock(tree, &lck);
1955 CHECK_STATUS(status, NT_STATUS_OK);
1957 /* Try to take a shared lock, then stack an exclusive with same
1959 torture_comment(torture, " stacking an exclusive on top of a shared "
1962 el[0].flags = SMB2_LOCK_FLAG_SHARED |
1963 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1964 status = smb2_lock(tree, &lck);
1965 CHECK_STATUS(status, NT_STATUS_OK);
1967 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1968 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1969 status = smb2_lock(tree, &lck);
1970 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1973 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1974 status = smb2_lock(tree, &lck);
1975 if (TARGET_IS_W2K8(torture)) {
1976 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1977 torture_warning(torture, "Target has \"pretty please\" bug. "
1978 "A contending lock request on the same handle "
1979 "unlocks the lock.\n");
1981 CHECK_STATUS(status, NT_STATUS_OK);
1984 /* Prove that two exclusive locks do not stack on the same handle. */
1985 torture_comment(torture, " two exclusive locks do not stack.\n");
1987 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1988 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1989 status = smb2_lock(tree, &lck);
1990 CHECK_STATUS(status, NT_STATUS_OK);
1992 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1993 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1994 status = smb2_lock(tree, &lck);
1995 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1998 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1999 status = smb2_lock(tree, &lck);
2000 if (TARGET_IS_W2K8(torture)) {
2001 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2002 torture_warning(torture, "Target has \"pretty please\" bug. "
2003 "A contending lock request on the same handle "
2004 "unlocks the lock.\n");
2006 CHECK_STATUS(status, NT_STATUS_OK);
2010 smb2_util_close(tree, h2);
2011 smb2_util_close(tree, h);
2012 smb2_deltree(tree, BASEDIR);
2017 * Test lock contention
2018 * - shared lock should contend with exclusive lock on different handle
2020 static bool test_contend(struct torture_context *torture,
2021 struct smb2_tree *tree)
2025 struct smb2_handle h, h2;
2027 struct smb2_lock lck;
2028 struct smb2_lock_element el[1];
2030 const char *fname = BASEDIR "\\contend.txt";
2032 status = torture_smb2_testdir(tree, BASEDIR, &h);
2033 CHECK_STATUS(status, NT_STATUS_OK);
2034 smb2_util_close(tree, h);
2036 status = torture_smb2_testfile(tree, fname, &h);
2037 CHECK_STATUS(status, NT_STATUS_OK);
2040 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2041 CHECK_STATUS(status, NT_STATUS_OK);
2043 status = torture_smb2_testfile(tree, fname, &h2);
2044 CHECK_STATUS(status, NT_STATUS_OK);
2046 torture_comment(torture, "Testing lock contention:\n");
2048 /* Setup initial parameters */
2050 lck.in.lock_count = 0x0001;
2051 lck.in.lock_sequence = 0x00000000;
2052 lck.in.file.handle = h;
2055 el[0].reserved = 0x00000000;
2057 /* Take an exclusive lock, then a shared lock on different handle */
2058 torture_comment(torture, " shared should contend on exclusive on "
2059 "different handle.\n");
2061 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2062 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2063 status = smb2_lock(tree, &lck);
2064 CHECK_STATUS(status, NT_STATUS_OK);
2066 lck.in.file.handle = h2;
2067 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2068 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2069 status = smb2_lock(tree, &lck);
2070 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2073 lck.in.file.handle = h;
2074 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2075 status = smb2_lock(tree, &lck);
2076 CHECK_STATUS(status, NT_STATUS_OK);
2079 smb2_util_close(tree, h2);
2080 smb2_util_close(tree, h);
2081 smb2_deltree(tree, BASEDIR);
2086 * Test locker context
2087 * - test that pid does not affect the locker context
2089 static bool test_context(struct torture_context *torture,
2090 struct smb2_tree *tree)
2094 struct smb2_handle h, h2;
2096 struct smb2_lock lck;
2097 struct smb2_lock_element el[1];
2099 const char *fname = BASEDIR "\\context.txt";
2101 status = torture_smb2_testdir(tree, BASEDIR, &h);
2102 CHECK_STATUS(status, NT_STATUS_OK);
2103 smb2_util_close(tree, h);
2105 status = torture_smb2_testfile(tree, fname, &h);
2106 CHECK_STATUS(status, NT_STATUS_OK);
2109 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2110 CHECK_STATUS(status, NT_STATUS_OK);
2112 status = torture_smb2_testfile(tree, fname, &h2);
2113 CHECK_STATUS(status, NT_STATUS_OK);
2115 torture_comment(torture, "Testing locker context:\n");
2117 /* Setup initial parameters */
2119 lck.in.lock_count = 0x0001;
2120 lck.in.lock_sequence = 0x00000000;
2121 lck.in.file.handle = h;
2124 el[0].reserved = 0x00000000;
2126 /* Take an exclusive lock, then try to unlock with a different pid,
2127 * same handle. This shows that the pid doesn't affect the locker
2128 * context in SMB2. */
2129 torture_comment(torture, " pid shouldn't affect locker context\n");
2131 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2132 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2133 status = smb2_lock(tree, &lck);
2134 CHECK_STATUS(status, NT_STATUS_OK);
2136 tree->session->pid++;
2137 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2138 status = smb2_lock(tree, &lck);
2139 CHECK_STATUS(status, NT_STATUS_OK);
2141 tree->session->pid--;
2142 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2143 status = smb2_lock(tree, &lck);
2144 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2147 smb2_util_close(tree, h2);
2148 smb2_util_close(tree, h);
2149 smb2_deltree(tree, BASEDIR);
2154 * Test as much of the potential lock range as possible
2155 * - test ported from BASE-LOCK-LOCK3
2157 static bool test_range(struct torture_context *torture,
2158 struct smb2_tree *tree)
2162 struct smb2_handle h, h2;
2164 struct smb2_lock lck;
2165 struct smb2_lock_element el[1];
2167 extern int torture_numops;
2169 const char *fname = BASEDIR "\\range.txt";
2171 #define NEXT_OFFSET offset += (~(uint64_t)0) / torture_numops
2173 status = torture_smb2_testdir(tree, BASEDIR, &h);
2174 CHECK_STATUS(status, NT_STATUS_OK);
2175 smb2_util_close(tree, h);
2177 status = torture_smb2_testfile(tree, fname, &h);
2178 CHECK_STATUS(status, NT_STATUS_OK);
2181 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2182 CHECK_STATUS(status, NT_STATUS_OK);
2184 status = torture_smb2_testfile(tree, fname, &h2);
2185 CHECK_STATUS(status, NT_STATUS_OK);
2187 torture_comment(torture, "Testing locks spread across the 64-bit "
2190 if (TARGET_IS_W2K8(torture)) {
2191 torture_result(torture, TORTURE_SKIP,
2192 "Target has \"pretty please\" bug. A contending lock "
2193 "request on the same handle unlocks the lock.");
2197 /* Setup initial parameters */
2199 lck.in.lock_count = 0x0001;
2200 lck.in.lock_sequence = 0x00000000;
2201 lck.in.file.handle = h;
2204 el[0].reserved = 0x00000000;
2205 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2206 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2208 torture_comment(torture, " establishing %d locks\n", torture_numops);
2210 for (offset=i=0; i<torture_numops; i++) {
2213 lck.in.file.handle = h;
2214 el[0].offset = offset - 1;
2215 status = smb2_lock(tree, &lck);
2216 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2217 talloc_asprintf(torture,
2218 "lock h failed at offset %#llx ",
2221 lck.in.file.handle = h2;
2222 el[0].offset = offset - 2;
2223 status = smb2_lock(tree, &lck);
2224 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2225 talloc_asprintf(torture,
2226 "lock h2 failed at offset %#llx ",
2230 torture_comment(torture, " testing %d locks\n", torture_numops);
2232 for (offset=i=0; i<torture_numops; i++) {
2235 lck.in.file.handle = h;
2236 el[0].offset = offset - 1;
2237 status = smb2_lock(tree, &lck);
2238 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2239 talloc_asprintf(torture,
2240 "lock h at offset %#llx should not have "
2241 "succeeded ", el[0].offset));
2243 lck.in.file.handle = h;
2244 el[0].offset = offset - 2;
2245 status = smb2_lock(tree, &lck);
2246 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2247 talloc_asprintf(torture,
2248 "lock h2 at offset %#llx should not have "
2249 "succeeded ", el[0].offset));
2251 lck.in.file.handle = h2;
2252 el[0].offset = offset - 1;
2253 status = smb2_lock(tree, &lck);
2254 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2255 talloc_asprintf(torture,
2256 "lock h at offset %#llx should not have "
2257 "succeeded ", el[0].offset));
2259 lck.in.file.handle = h2;
2260 el[0].offset = offset - 2;
2261 status = smb2_lock(tree, &lck);
2262 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2263 talloc_asprintf(torture,
2264 "lock h2 at offset %#llx should not have "
2265 "succeeded ", el[0].offset));
2268 torture_comment(torture, " removing %d locks\n", torture_numops);
2270 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2272 for (offset=i=0; i<torture_numops; i++) {
2275 lck.in.file.handle = h;
2276 el[0].offset = offset - 1;
2277 status = smb2_lock(tree, &lck);
2278 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2279 talloc_asprintf(torture,
2280 "unlock from h failed at offset %#llx ",
2283 lck.in.file.handle = h2;
2284 el[0].offset = offset - 2;
2285 status = smb2_lock(tree, &lck);
2286 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2287 talloc_asprintf(torture,
2288 "unlock from h2 failed at offset %#llx ",
2293 smb2_util_close(tree, h2);
2294 smb2_util_close(tree, h);
2295 smb2_deltree(tree, BASEDIR);
2299 static NTSTATUS smb2cli_lock(struct smb2_tree *tree, struct smb2_handle h,
2300 uint64_t offset, uint64_t length, bool exclusive)
2302 struct smb2_lock lck;
2303 struct smb2_lock_element el[1];
2307 lck.in.lock_count = 0x0001;
2308 lck.in.lock_sequence = 0x00000000;
2309 lck.in.file.handle = h;
2310 el[0].offset = offset;
2311 el[0].length = length;
2312 el[0].reserved = 0x00000000;
2313 el[0].flags = (exclusive ?
2314 SMB2_LOCK_FLAG_EXCLUSIVE :
2315 SMB2_LOCK_FLAG_SHARED) |
2316 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2318 status = smb2_lock(tree, &lck);
2323 static NTSTATUS smb2cli_unlock(struct smb2_tree *tree, struct smb2_handle h,
2324 uint64_t offset, uint64_t length)
2326 struct smb2_lock lck;
2327 struct smb2_lock_element el[1];
2331 lck.in.lock_count = 0x0001;
2332 lck.in.lock_sequence = 0x00000000;
2333 lck.in.file.handle = h;
2334 el[0].offset = offset;
2335 el[0].length = length;
2336 el[0].reserved = 0x00000000;
2337 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2339 status = smb2_lock(tree, &lck);
2344 #define EXPECTED(ret, v) if ((ret) != (v)) { \
2345 torture_result(torture, TORTURE_FAIL, __location__": subtest failed");\
2346 torture_comment(torture, "** "); correct = false; \
2350 * Test overlapping lock ranges from various lockers
2351 * - some tests ported from BASE-LOCK-LOCK4
2353 static bool test_overlap(struct torture_context *torture,
2354 struct smb2_tree *tree,
2355 struct smb2_tree *tree2)
2359 struct smb2_handle h, h2, h3;
2361 bool correct = true;
2363 const char *fname = BASEDIR "\\overlap.txt";
2365 status = torture_smb2_testdir(tree, BASEDIR, &h);
2366 CHECK_STATUS(status, NT_STATUS_OK);
2367 smb2_util_close(tree, h);
2369 status = torture_smb2_testfile(tree, fname, &h);
2370 CHECK_STATUS(status, NT_STATUS_OK);
2373 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2374 CHECK_STATUS(status, NT_STATUS_OK);
2376 status = torture_smb2_testfile(tree, fname, &h2);
2377 CHECK_STATUS(status, NT_STATUS_OK);
2379 status = torture_smb2_testfile(tree2, fname, &h3);
2380 CHECK_STATUS(status, NT_STATUS_OK);
2382 torture_comment(torture, "Testing overlapping locks:\n");
2384 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 0, 4, true)) &&
2385 NT_STATUS_IS_OK(smb2cli_lock(tree, h, 2, 4, true));
2386 EXPECTED(ret, false);
2387 torture_comment(torture, "the same session/handle %s set overlapping "
2388 "exclusive locks\n", ret?"can":"cannot");
2390 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 10, 4, false)) &&
2391 NT_STATUS_IS_OK(smb2cli_lock(tree, h, 12, 4, false));
2392 EXPECTED(ret, true);
2393 torture_comment(torture, "the same session/handle %s set overlapping "
2394 "shared locks\n", ret?"can":"cannot");
2396 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 20, 4, true)) &&
2397 NT_STATUS_IS_OK(smb2cli_lock(tree2, h3, 22, 4, true));
2398 EXPECTED(ret, false);
2399 torture_comment(torture, "a different session %s set overlapping "
2400 "exclusive locks\n", ret?"can":"cannot");
2402 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 30, 4, false)) &&
2403 NT_STATUS_IS_OK(smb2cli_lock(tree2, h3, 32, 4, false));
2404 EXPECTED(ret, true);
2405 torture_comment(torture, "a different session %s set overlapping "
2406 "shared locks\n", ret?"can":"cannot");
2408 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 40, 4, true)) &&
2409 NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 42, 4, true));
2410 EXPECTED(ret, false);
2411 torture_comment(torture, "a different handle %s set overlapping "
2412 "exclusive locks\n", ret?"can":"cannot");
2414 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 50, 4, false)) &&
2415 NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 52, 4, false));
2416 EXPECTED(ret, true);
2417 torture_comment(torture, "a different handle %s set overlapping "
2418 "shared locks\n", ret?"can":"cannot");
2420 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 110, 4, false)) &&
2421 NT_STATUS_IS_OK(smb2cli_lock(tree, h, 112, 4, false)) &&
2422 NT_STATUS_IS_OK(smb2cli_unlock(tree, h, 110, 6));
2423 EXPECTED(ret, false);
2424 torture_comment(torture, "the same handle %s coalesce read locks\n",
2425 ret?"can":"cannot");
2427 smb2_util_close(tree, h2);
2428 smb2_util_close(tree, h);
2429 status = torture_smb2_testfile(tree, fname, &h);
2430 CHECK_STATUS(status, NT_STATUS_OK);
2431 status = torture_smb2_testfile(tree, fname, &h2);
2432 CHECK_STATUS(status, NT_STATUS_OK);
2433 ret = NT_STATUS_IS_OK(smb2cli_lock(tree, h, 0, 8, false)) &&
2434 NT_STATUS_IS_OK(smb2cli_lock(tree, h2, 0, 1, false)) &&
2435 NT_STATUS_IS_OK(smb2_util_close(tree, h)) &&
2436 NT_STATUS_IS_OK(torture_smb2_testfile(tree, fname, &h)) &&
2437 NT_STATUS_IS_OK(smb2cli_lock(tree, h, 7, 1, true));
2438 EXPECTED(ret, true);
2439 torture_comment(torture, "the server %s have the NT byte range lock bug\n",
2440 !ret?"does":"doesn't");
2443 smb2_util_close(tree2, h3);
2444 smb2_util_close(tree, h2);
2445 smb2_util_close(tree, h);
2446 smb2_deltree(tree, BASEDIR);
2451 * Test truncation of locked file
2452 * - some tests ported from BASE-LOCK-LOCK7
2454 static bool test_truncate(struct torture_context *torture,
2455 struct smb2_tree *tree)
2459 struct smb2_handle h, h2;
2461 struct smb2_lock lck;
2462 struct smb2_lock_element el[1];
2463 struct smb2_create io;
2465 const char *fname = BASEDIR "\\truncate.txt";
2467 status = torture_smb2_testdir(tree, BASEDIR, &h);
2468 CHECK_STATUS(status, NT_STATUS_OK);
2469 smb2_util_close(tree, h);
2471 status = torture_smb2_testfile(tree, fname, &h);
2472 CHECK_STATUS(status, NT_STATUS_OK);
2475 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2476 CHECK_STATUS(status, NT_STATUS_OK);
2478 torture_comment(torture, "Testing truncation of locked file:\n");
2480 /* Setup initial parameters */
2482 lck.in.lock_count = 0x0001;
2483 lck.in.lock_sequence = 0x00000000;
2484 lck.in.file.handle = h;
2487 el[0].reserved = 0x00000000;
2490 io.in.oplock_level = 0;
2491 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
2492 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2493 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2494 io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
2495 NTCREATEX_SHARE_ACCESS_READ |
2496 NTCREATEX_SHARE_ACCESS_WRITE;
2497 io.in.create_options = 0;
2498 io.in.fname = fname;
2500 /* Take an exclusive lock */
2501 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2502 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2503 status = smb2_lock(tree, &lck);
2504 CHECK_STATUS(status, NT_STATUS_OK);
2506 /* On second handle open the file with OVERWRITE disposition */
2507 torture_comment(torture, " overwrite disposition is allowed on a locked "
2510 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2511 status = smb2_create(tree, tree, &io);
2512 CHECK_STATUS(status, NT_STATUS_OK);
2513 h2 = io.out.file.handle;
2514 smb2_util_close(tree, h2);
2516 /* On second handle open the file with SUPERSEDE disposition */
2517 torture_comment(torture, " supersede disposition is allowed on a locked "
2520 io.in.create_disposition = NTCREATEX_DISP_SUPERSEDE;
2521 status = smb2_create(tree, tree, &io);
2522 CHECK_STATUS(status, NT_STATUS_OK);
2523 h2 = io.out.file.handle;
2524 smb2_util_close(tree, h2);
2527 lck.in.file.handle = h;
2528 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2529 status = smb2_lock(tree, &lck);
2530 CHECK_STATUS(status, NT_STATUS_OK);
2533 smb2_util_close(tree, h2);
2534 smb2_util_close(tree, h);
2535 smb2_deltree(tree, BASEDIR);
2539 /* basic testing of SMB2 locking
2541 struct torture_suite *torture_smb2_lock_init(void)
2543 struct torture_suite *suite =
2544 torture_suite_create(talloc_autofree_context(), "LOCK");
2546 torture_suite_add_1smb2_test(suite, "VALID-REQUEST",
2547 test_valid_request);
2548 torture_suite_add_1smb2_test(suite, "RW-NONE", test_lock_rw_none);
2549 torture_suite_add_1smb2_test(suite, "RW-SHARED", test_lock_rw_shared);
2550 torture_suite_add_1smb2_test(suite, "RW-EXCLUSIVE",
2551 test_lock_rw_exclusive);
2552 torture_suite_add_1smb2_test(suite, "AUTO-UNLOCK",
2553 test_lock_auto_unlock);
2554 torture_suite_add_1smb2_test(suite, "LOCK", test_lock);
2555 torture_suite_add_1smb2_test(suite, "ASYNC", test_async);
2556 torture_suite_add_1smb2_test(suite, "CANCEL", test_cancel);
2557 torture_suite_add_1smb2_test(suite, "CANCEL-TDIS", test_cancel_tdis);
2558 torture_suite_add_1smb2_test(suite, "CANCEL-LOGOFF",
2559 test_cancel_logoff);
2560 torture_suite_add_1smb2_test(suite, "ERRORCODE", test_errorcode);
2561 torture_suite_add_1smb2_test(suite, "ZEROBYTELENGTH",
2562 test_zerobytelength);
2563 torture_suite_add_1smb2_test(suite, "UNLOCK", test_unlock);
2564 torture_suite_add_1smb2_test(suite, "MULTIPLE-UNLOCK",
2565 test_multiple_unlock);
2566 torture_suite_add_1smb2_test(suite, "STACKING", test_stacking);
2567 torture_suite_add_1smb2_test(suite, "CONTEND", test_contend);
2568 torture_suite_add_1smb2_test(suite, "CONTEXT", test_context);
2569 torture_suite_add_1smb2_test(suite, "RANGE", test_range);
2570 torture_suite_add_2smb2_test(suite, "OVERLAP", test_overlap);
2571 torture_suite_add_1smb2_test(suite, "TRUNCATE", test_truncate);
2573 suite->description = talloc_strdup(suite, "SMB2-LOCK tests");