s3:smbd: s/event_add_fd/tevent_add_fd and s/EVENT_FD_/TEVENT_FD_
[Samba/gebeck_regimport.git] / source4 / torture / smb2 / lock.c
blob9350c136a2186b4e5aa82edb1cf7a23e708064bd
1 /*
2 Unix SMB/CIFS implementation.
4 SMB2 lock test suite
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/>.
22 #include "includes.h"
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, \
36 ret,done,_cmt); \
37 } while (0)
39 #define CHECK_STATUS_CMT(status, correct, cmt) do { \
40 torture_assert_ntstatus_equal_goto(torture,status,correct, \
41 ret,done,cmt); \
42 } while (0)
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)); \
49 ret = false; \
50 }} while (0)
52 #define CHECK_VALUE(v, correct) do { \
53 const char *_cmt = "(" __location__ ")"; \
54 torture_assert_int_equal_goto(torture,v,correct,ret,done,_cmt); \
55 } while (0)
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 (tevent_loop_once(torture->ev) != 0) { \
66 break; \
67 } \
70 static bool test_valid_request(struct torture_context *torture,
71 struct smb2_tree *tree)
73 bool ret = true;
74 NTSTATUS status;
75 struct smb2_handle h;
76 uint8_t buf[200];
77 struct smb2_lock lck;
78 struct smb2_lock_element el[2];
80 ZERO_STRUCT(buf);
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);
88 lck.in.locks = el;
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;
105 el[0].offset = 0;
106 el[0].length = 0;
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;
115 el[0].offset = 0;
116 el[0].length = 0;
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 "
123 "parameter.\n");
124 } else {
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);
146 } else {
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);
155 } else {
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;
212 el[0].offset = 1;
213 el[0].length = 1;
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 "
221 "parameter.\n");
222 } else {
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 "
252 "parameter.\n");
253 } else {
254 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
257 torture_comment(torture, "Test return error when 2 locks are "
258 "requested\n");
260 lck.in.lock_count = 2;
261 lck.in.lock_sequence = 0;
262 lck.in.file.handle = h;
263 el[0].offset = 9999;
264 el[0].length = 1;
265 el[0].reserved = 0x00000000;
266 el[1].offset = 9999;
267 el[1].length = 1;
268 el[1].reserved = 0x00000000;
270 lck.in.lock_count = 2;
271 el[0].flags = 0;
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;
277 el[0].flags = 0;
278 el[1].flags = 0;
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 "
283 "parameter.\n");
284 } else {
285 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
288 lck.in.lock_count = 2;
289 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
290 el[1].flags = 0;
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 "
295 "parameter.\n");
296 } else {
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);
334 done:
335 return ret;
338 struct test_lock_read_write_state {
339 const char *fname;
340 uint32_t lock_flags;
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)
351 bool ret = true;
352 NTSTATUS status;
353 struct smb2_handle h1, h2;
354 uint8_t buf[200];
355 struct smb2_lock lck;
356 struct smb2_create cr;
357 struct smb2_write wr;
358 struct smb2_read rd;
359 struct smb2_lock_element el[1];
361 lck.in.locks = el;
363 ZERO_STRUCT(buf);
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;
374 el[0].offset = 0;
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);
393 ZERO_STRUCT(cr);
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;
398 cr.in.share_access =
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;
410 ZERO_STRUCT(wr);
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);
418 ZERO_STRUCT(rd);
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);
426 ZERO_STRUCT(wr);
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);
434 ZERO_STRUCT(rd);
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);
453 ZERO_STRUCT(wr);
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);
461 ZERO_STRUCT(rd);
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);
469 done:
470 return ret;
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)
528 bool ret = true;
529 NTSTATUS status;
530 struct smb2_handle h;
531 uint8_t buf[200];
532 struct smb2_lock lck;
533 struct smb2_lock_element el[1];
535 ZERO_STRUCT(buf);
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);
543 ZERO_STRUCT(lck);
544 ZERO_STRUCT(el[0]);
545 lck.in.locks = el;
546 lck.in.lock_count = 0x0001;
547 lck.in.file.handle = h;
548 el[0].offset = 0;
549 el[0].length = 1;
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");
564 } else {
565 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
568 status = smb2_lock(tree, &lck);
569 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
571 done:
572 return ret;
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)
581 NTSTATUS status;
582 bool ret = true;
583 struct smb2_handle h, h2;
584 uint8_t buf[200];
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);
597 ZERO_STRUCT(buf);
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);
604 lck.in.locks = el;
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;
647 el[0].length = 4000;
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;
664 el[0].length = 4000;
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;
680 el[0].offset = 1;
681 el[0].offset <<= 63;
682 el[0].offset--;
683 el[0].length = 1;
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;
699 el[0].offset = 1;
700 el[0].offset <<= 63;
701 el[0].length = 1;
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;
717 el[0].offset = ~0;
718 el[0].length = 0;
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;
736 el[0].offset = ~0;
737 el[0].length = 1;
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;
753 el[0].offset = ~0;
754 el[0].length = 2;
755 status = smb2_lock(tree, &lck);
756 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture)) {
757 CHECK_STATUS(status, NT_STATUS_INVALID_LOCK_RANGE);
758 } else {
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);
780 done:
781 smb2_util_close(tree, h2);
782 smb2_util_close(tree, h);
783 smb2_deltree(tree, BASEDIR);
784 return ret;
788 test SMB2 LOCK async operation
790 static bool test_async(struct torture_context *torture,
791 struct smb2_tree *tree)
793 NTSTATUS status;
794 bool ret = true;
795 struct smb2_handle h, h2;
796 uint8_t buf[200];
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);
810 ZERO_STRUCT(buf);
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);
817 lck.in.locks = el;
819 lck.in.lock_count = 0x0001;
820 lck.in.lock_sequence = 0x00000000;
821 lck.in.file.handle = h;
822 el[0].offset = 100;
823 el[0].length = 50;
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);
848 done:
849 smb2_util_close(tree, h2);
850 smb2_util_close(tree, h);
851 smb2_deltree(tree, BASEDIR);
852 return ret;
856 test SMB2 LOCK Cancel operation
858 static bool test_cancel(struct torture_context *torture,
859 struct smb2_tree *tree)
861 NTSTATUS status;
862 bool ret = true;
863 struct smb2_handle h, h2;
864 uint8_t buf[200];
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);
878 ZERO_STRUCT(buf);
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);
885 lck.in.locks = el;
887 lck.in.lock_count = 0x0001;
888 lck.in.lock_sequence = 0x00000000;
889 lck.in.file.handle = h;
890 el[0].offset = 100;
891 el[0].length = 10;
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");
907 smb2_cancel(req);
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");
938 smb2_cancel(req);
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);
976 done:
977 smb2_util_close(tree, h2);
978 smb2_util_close(tree, h);
979 smb2_deltree(tree, BASEDIR);
980 return ret;
984 test SMB2 LOCK Cancel by tree disconnect
986 static bool test_cancel_tdis(struct torture_context *torture,
987 struct smb2_tree *tree)
989 NTSTATUS status;
990 bool ret = true;
991 struct smb2_handle h, h2;
992 uint8_t buf[200];
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);
1006 ZERO_STRUCT(buf);
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);
1013 lck.in.locks = el;
1015 lck.in.lock_count = 0x0001;
1016 lck.in.lock_sequence = 0x00000000;
1017 lck.in.file.handle = h;
1018 el[0].offset = 100;
1019 el[0].length = 10;
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");
1042 smb2_tdis(tree);
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
1049 * tree is gone!! */
1050 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1051 } else {
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);
1060 * Most Windows versions have a strange order to
1061 * verify the session id, tree id and file id.
1062 * (They should be checked in that order, but windows
1063 * seems to check the file id before the others).
1065 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
1066 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1069 done:
1070 smb2_util_close(tree, h2);
1071 smb2_util_close(tree, h);
1072 smb2_deltree(tree, BASEDIR);
1073 return ret;
1077 test SMB2 LOCK Cancel by user logoff
1079 static bool test_cancel_logoff(struct torture_context *torture,
1080 struct smb2_tree *tree)
1082 NTSTATUS status;
1083 bool ret = true;
1084 struct smb2_handle h, h2;
1085 uint8_t buf[200];
1086 struct smb2_lock lck;
1087 struct smb2_lock_element el[2];
1088 struct smb2_request *req = NULL;
1090 const char *fname = BASEDIR "\\cancel_tdis.txt";
1092 status = torture_smb2_testdir(tree, BASEDIR, &h);
1093 CHECK_STATUS(status, NT_STATUS_OK);
1094 smb2_util_close(tree, h);
1096 status = torture_smb2_testfile(tree, fname, &h);
1097 CHECK_STATUS(status, NT_STATUS_OK);
1099 ZERO_STRUCT(buf);
1100 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1101 CHECK_STATUS(status, NT_STATUS_OK);
1103 status = torture_smb2_testfile(tree, fname, &h2);
1104 CHECK_STATUS(status, NT_STATUS_OK);
1106 lck.in.locks = el;
1108 lck.in.lock_count = 0x0001;
1109 lck.in.lock_sequence = 0x00000000;
1110 lck.in.file.handle = h;
1111 el[0].offset = 100;
1112 el[0].length = 10;
1113 el[0].reserved = 0x00000000;
1114 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1116 torture_comment(torture, "Testing cancel by ulogoff\n");
1118 torture_comment(torture, " Acquire first lock\n");
1119 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1120 status = smb2_lock(tree, &lck);
1121 CHECK_STATUS(status, NT_STATUS_OK);
1123 torture_comment(torture, " Second lock should pend on first\n");
1124 lck.in.file.handle = h2;
1125 req = smb2_lock_send(tree, &lck);
1126 WAIT_FOR_ASYNC_RESPONSE(req);
1128 torture_comment(torture, " Logoff user\n");
1129 smb2_logoff(tree->session);
1131 torture_comment(torture, " Check pending lock reply\n");
1132 status = smb2_lock_recv(req, &lck);
1133 if (torture_setting_bool(torture, "samba4", false)) {
1134 /* another bogus 'success' code from windows. The lock
1135 * cannot have succeeded, as we are now logged off */
1136 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1137 } else {
1138 CHECK_STATUS(status, NT_STATUS_OK);
1141 torture_comment(torture, " Attempt to unlock first lock\n");
1142 lck.in.file.handle = h;
1143 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1144 status = smb2_lock(tree, &lck);
1146 * Most Windows versions have a strange order to
1147 * verify the session id, tree id and file id.
1148 * (They should be checked in that order, but windows
1149 * seems to check the file id before the others).
1151 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
1152 CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
1155 done:
1156 smb2_util_close(tree, h2);
1157 smb2_util_close(tree, h);
1158 smb2_deltree(tree, BASEDIR);
1159 return ret;
1163 * Test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
1165 * The SMBv1 protocol returns a different error code on lock acquisition
1166 * failure depending on a number of parameters, including what error code
1167 * was returned to the previous failure.
1169 * SMBv2 has cleaned up these semantics and should always return
1170 * NT_STATUS_LOCK_NOT_GRANTED to failed lock requests, and
1171 * NT_STATUS_FILE_LOCK_CONFLICT to failed read/write requests due to a lock
1172 * being held on that range.
1174 static bool test_errorcode(struct torture_context *torture,
1175 struct smb2_tree *tree)
1177 NTSTATUS status;
1178 bool ret = true;
1179 struct smb2_handle h, h2;
1180 uint8_t buf[200];
1181 struct smb2_lock lck;
1182 struct smb2_lock_element el[2];
1184 const char *fname = BASEDIR "\\errorcode.txt";
1186 status = torture_smb2_testdir(tree, BASEDIR, &h);
1187 CHECK_STATUS(status, NT_STATUS_OK);
1188 smb2_util_close(tree, h);
1190 status = torture_smb2_testfile(tree, fname, &h);
1191 CHECK_STATUS(status, NT_STATUS_OK);
1193 ZERO_STRUCT(buf);
1194 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1195 CHECK_STATUS(status, NT_STATUS_OK);
1197 status = torture_smb2_testfile(tree, fname, &h2);
1198 CHECK_STATUS(status, NT_STATUS_OK);
1200 lck.in.locks = el;
1202 lck.in.lock_count = 0x0001;
1203 lck.in.lock_sequence = 0x00000000;
1204 lck.in.file.handle = h;
1205 el[0].offset = 100;
1206 el[0].length = 10;
1207 el[0].reserved = 0x00000000;
1208 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1209 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1211 torture_comment(torture, "Testing LOCK_NOT_GRANTED vs. "
1212 "FILE_LOCK_CONFLICT\n");
1214 if (TARGET_IS_W2K8(torture)) {
1215 torture_result(torture, TORTURE_SKIP,
1216 "Target has \"pretty please\" bug. A contending lock "
1217 "request on the same handle unlocks the lock.");
1218 goto done;
1221 status = smb2_lock(tree, &lck);
1222 CHECK_STATUS(status, NT_STATUS_OK);
1224 /* Demonstrate that the first conflicting lock on each handle gives
1225 * LOCK_NOT_GRANTED. */
1226 lck.in.file.handle = h;
1227 status = smb2_lock(tree, &lck);
1228 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1230 lck.in.file.handle = h2;
1231 status = smb2_lock(tree, &lck);
1232 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1234 /* Demonstrate that each following conflict also gives
1235 * LOCK_NOT_GRANTED */
1236 lck.in.file.handle = h;
1237 status = smb2_lock(tree, &lck);
1238 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1240 lck.in.file.handle = h2;
1241 status = smb2_lock(tree, &lck);
1242 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1244 lck.in.file.handle = h;
1245 status = smb2_lock(tree, &lck);
1246 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1248 lck.in.file.handle = h2;
1249 status = smb2_lock(tree, &lck);
1250 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1252 /* Demonstrate that the smbpid doesn't matter */
1253 lck.in.file.handle = h;
1254 status = smb2_lock(tree, &lck);
1255 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1257 lck.in.file.handle = h2;
1258 status = smb2_lock(tree, &lck);
1259 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1261 /* Demonstrate that a 0-byte lock inside the locked range still
1262 * gives the same error. */
1264 el[0].offset = 102;
1265 el[0].length = 0;
1266 lck.in.file.handle = h;
1267 status = smb2_lock(tree, &lck);
1268 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1270 lck.in.file.handle = h2;
1271 status = smb2_lock(tree, &lck);
1272 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1274 /* Demonstrate that a lock inside the locked range still gives the
1275 * same error. */
1277 el[0].offset = 102;
1278 el[0].length = 5;
1279 lck.in.file.handle = h;
1280 status = smb2_lock(tree, &lck);
1281 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1283 lck.in.file.handle = h2;
1284 status = smb2_lock(tree, &lck);
1285 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1287 done:
1288 smb2_util_close(tree, h2);
1289 smb2_util_close(tree, h);
1290 smb2_deltree(tree, BASEDIR);
1291 return ret;
1295 * Tests zero byte locks.
1298 struct double_lock_test {
1299 struct smb2_lock_element lock1;
1300 struct smb2_lock_element lock2;
1301 NTSTATUS status;
1304 static struct double_lock_test zero_byte_tests[] = {
1305 /* {offset, count, reserved, flags},
1306 * {offset, count, reserved, flags},
1307 * status */
1309 /** First, takes a zero byte lock at offset 10. Then:
1310 * - Taking 0 byte lock at 10 should succeed.
1311 * - Taking 1 byte locks at 9,10,11 should succeed.
1312 * - Taking 2 byte lock at 9 should fail.
1313 * - Taking 2 byte lock at 10 should succeed.
1314 * - Taking 3 byte lock at 9 should fail.
1316 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1317 {{10, 0, 0, 0}, {9, 1, 0, 0}, NT_STATUS_OK},
1318 {{10, 0, 0, 0}, {10, 1, 0, 0}, NT_STATUS_OK},
1319 {{10, 0, 0, 0}, {11, 1, 0, 0}, NT_STATUS_OK},
1320 {{10, 0, 0, 0}, {9, 2, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1321 {{10, 0, 0, 0}, {10, 2, 0, 0}, NT_STATUS_OK},
1322 {{10, 0, 0, 0}, {9, 3, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1324 /** Same, but opposite order. */
1325 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1326 {{9, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1327 {{10, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1328 {{11, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1329 {{9, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1330 {{10, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK},
1331 {{9, 3, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED},
1333 /** Zero zero case. */
1334 {{0, 0, 0, 0}, {0, 0, 0, 0}, NT_STATUS_OK},
1337 static bool test_zerobytelength(struct torture_context *torture,
1338 struct smb2_tree *tree)
1340 NTSTATUS status;
1341 bool ret = true;
1342 struct smb2_handle h, h2;
1343 uint8_t buf[200];
1344 struct smb2_lock lck;
1345 int i;
1347 const char *fname = BASEDIR "\\zero.txt";
1349 torture_comment(torture, "Testing zero length byte range locks:\n");
1351 status = torture_smb2_testdir(tree, BASEDIR, &h);
1352 CHECK_STATUS(status, NT_STATUS_OK);
1353 smb2_util_close(tree, h);
1355 status = torture_smb2_testfile(tree, fname, &h);
1356 CHECK_STATUS(status, NT_STATUS_OK);
1358 ZERO_STRUCT(buf);
1359 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1360 CHECK_STATUS(status, NT_STATUS_OK);
1362 status = torture_smb2_testfile(tree, fname, &h2);
1363 CHECK_STATUS(status, NT_STATUS_OK);
1365 /* Setup initial parameters */
1366 lck.in.lock_count = 0x0001;
1367 lck.in.lock_sequence = 0x00000000;
1368 lck.in.file.handle = h;
1370 /* Try every combination of locks in zero_byte_tests, using the same
1371 * handle for both locks. The first lock is assumed to succeed. The
1372 * second lock may contend, depending on the expected status. */
1373 for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1374 torture_comment(torture,
1375 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1376 (unsigned long long) zero_byte_tests[i].lock1.offset,
1377 (unsigned long long) zero_byte_tests[i].lock1.length,
1378 (unsigned long long) zero_byte_tests[i].lock2.offset,
1379 (unsigned long long) zero_byte_tests[i].lock2.length,
1380 nt_errstr(zero_byte_tests[i].status));
1382 /* Lock both locks. */
1383 lck.in.locks = &zero_byte_tests[i].lock1;
1384 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1385 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1386 status = smb2_lock(tree, &lck);
1387 CHECK_STATUS(status, NT_STATUS_OK);
1389 lck.in.locks = &zero_byte_tests[i].lock2;
1390 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1391 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1392 status = smb2_lock(tree, &lck);
1393 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1395 /* Unlock both locks in reverse order. */
1396 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1397 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1398 status = smb2_lock(tree, &lck);
1399 CHECK_STATUS(status, NT_STATUS_OK);
1402 lck.in.locks = &zero_byte_tests[i].lock1;
1403 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1404 status = smb2_lock(tree, &lck);
1405 CHECK_STATUS(status, NT_STATUS_OK);
1408 /* Try every combination of locks in zero_byte_tests, using two
1409 * different handles. */
1410 for (i = 0; i < ARRAY_SIZE(zero_byte_tests); i++) {
1411 torture_comment(torture,
1412 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1413 (unsigned long long) zero_byte_tests[i].lock1.offset,
1414 (unsigned long long) zero_byte_tests[i].lock1.length,
1415 (unsigned long long) zero_byte_tests[i].lock2.offset,
1416 (unsigned long long) zero_byte_tests[i].lock2.length,
1417 nt_errstr(zero_byte_tests[i].status));
1419 /* Lock both locks. */
1420 lck.in.file.handle = h;
1421 lck.in.locks = &zero_byte_tests[i].lock1;
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(status, NT_STATUS_OK);
1427 lck.in.file.handle = h2;
1428 lck.in.locks = &zero_byte_tests[i].lock2;
1429 lck.in.locks[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1430 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1431 status = smb2_lock(tree, &lck);
1432 CHECK_STATUS_CONT(status, zero_byte_tests[i].status);
1434 /* Unlock both locks in reverse order. */
1435 lck.in.file.handle = h2;
1436 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1437 if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1438 status = smb2_lock(tree, &lck);
1439 CHECK_STATUS(status, NT_STATUS_OK);
1442 lck.in.file.handle = h;
1443 lck.in.locks = &zero_byte_tests[i].lock1;
1444 lck.in.locks[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1445 status = smb2_lock(tree, &lck);
1446 CHECK_STATUS(status, NT_STATUS_OK);
1449 done:
1450 smb2_util_close(tree, h2);
1451 smb2_util_close(tree, h);
1452 smb2_deltree(tree, BASEDIR);
1453 return ret;
1456 static bool test_zerobyteread(struct torture_context *torture,
1457 struct smb2_tree *tree)
1459 NTSTATUS status;
1460 bool ret = true;
1461 struct smb2_handle h, h2;
1462 uint8_t buf[200];
1463 struct smb2_lock lck;
1464 struct smb2_lock_element el[1];
1465 struct smb2_read rd;
1467 const char *fname = BASEDIR "\\zerobyteread.txt";
1469 status = torture_smb2_testdir(tree, BASEDIR, &h);
1470 CHECK_STATUS(status, NT_STATUS_OK);
1471 smb2_util_close(tree, h);
1473 status = torture_smb2_testfile(tree, fname, &h);
1474 CHECK_STATUS(status, NT_STATUS_OK);
1476 ZERO_STRUCT(buf);
1477 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1478 CHECK_STATUS(status, NT_STATUS_OK);
1480 status = torture_smb2_testfile(tree, fname, &h2);
1481 CHECK_STATUS(status, NT_STATUS_OK);
1483 /* Setup initial parameters */
1484 lck.in.locks = el;
1485 lck.in.lock_count = 0x0001;
1486 lck.in.lock_sequence = 0x00000000;
1487 lck.in.file.handle = h;
1489 ZERO_STRUCT(rd);
1490 rd.in.file.handle = h2;
1492 torture_comment(torture, "Testing zero byte read on lock range:\n");
1494 /* Take an exclusive lock */
1495 torture_comment(torture, " taking exclusive lock.\n");
1496 el[0].offset = 0;
1497 el[0].length = 10;
1498 el[0].reserved = 0x00000000;
1499 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1500 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1501 status = smb2_lock(tree, &lck);
1502 CHECK_STATUS(status, NT_STATUS_OK);
1503 CHECK_VALUE(lck.out.reserved, 0);
1505 /* Try a zero byte read */
1506 torture_comment(torture, " reading 0 bytes.\n");
1507 rd.in.offset = 5;
1508 rd.in.length = 0;
1509 status = smb2_read(tree, tree, &rd);
1510 torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1511 "zero byte read did not return 0 bytes");
1512 CHECK_STATUS(status, NT_STATUS_OK);
1514 /* Unlock lock */
1515 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1516 status = smb2_lock(tree, &lck);
1517 CHECK_STATUS(status, NT_STATUS_OK);
1518 CHECK_VALUE(lck.out.reserved, 0);
1520 torture_comment(torture, "Testing zero byte read on zero byte lock "
1521 "range:\n");
1523 /* Take an exclusive lock */
1524 torture_comment(torture, " taking exclusive 0-byte lock.\n");
1525 el[0].offset = 5;
1526 el[0].length = 0;
1527 el[0].reserved = 0x00000000;
1528 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1529 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1530 status = smb2_lock(tree, &lck);
1531 CHECK_STATUS(status, NT_STATUS_OK);
1532 CHECK_VALUE(lck.out.reserved, 0);
1534 /* Try a zero byte read before the lock */
1535 torture_comment(torture, " reading 0 bytes before the lock.\n");
1536 rd.in.offset = 4;
1537 rd.in.length = 0;
1538 status = smb2_read(tree, tree, &rd);
1539 torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1540 "zero byte read did not return 0 bytes");
1541 CHECK_STATUS(status, NT_STATUS_OK);
1543 /* Try a zero byte read on the lock */
1544 torture_comment(torture, " reading 0 bytes on the lock.\n");
1545 rd.in.offset = 5;
1546 rd.in.length = 0;
1547 status = smb2_read(tree, tree, &rd);
1548 torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1549 "zero byte read did not return 0 bytes");
1550 CHECK_STATUS(status, NT_STATUS_OK);
1552 /* Try a zero byte read after the lock */
1553 torture_comment(torture, " reading 0 bytes after the lock.\n");
1554 rd.in.offset = 6;
1555 rd.in.length = 0;
1556 status = smb2_read(tree, tree, &rd);
1557 torture_assert_int_equal_goto(torture, rd.out.data.length, 0, ret, done,
1558 "zero byte read did not return 0 bytes");
1559 CHECK_STATUS(status, NT_STATUS_OK);
1561 /* Unlock lock */
1562 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1563 status = smb2_lock(tree, &lck);
1564 CHECK_STATUS(status, NT_STATUS_OK);
1565 CHECK_VALUE(lck.out.reserved, 0);
1567 done:
1568 smb2_util_close(tree, h2);
1569 smb2_util_close(tree, h);
1570 smb2_deltree(tree, BASEDIR);
1571 return ret;
1574 static bool test_unlock(struct torture_context *torture,
1575 struct smb2_tree *tree)
1577 NTSTATUS status;
1578 bool ret = true;
1579 struct smb2_handle h, h2;
1580 uint8_t buf[200];
1581 struct smb2_lock lck;
1582 struct smb2_lock_element el1[1];
1583 struct smb2_lock_element el2[1];
1585 const char *fname = BASEDIR "\\unlock.txt";
1587 status = torture_smb2_testdir(tree, BASEDIR, &h);
1588 CHECK_STATUS(status, NT_STATUS_OK);
1589 smb2_util_close(tree, h);
1591 status = torture_smb2_testfile(tree, fname, &h);
1592 CHECK_STATUS(status, NT_STATUS_OK);
1594 ZERO_STRUCT(buf);
1595 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1596 CHECK_STATUS(status, NT_STATUS_OK);
1598 status = torture_smb2_testfile(tree, fname, &h2);
1599 CHECK_STATUS(status, NT_STATUS_OK);
1601 /* Setup initial parameters */
1602 lck.in.locks = el1;
1603 lck.in.lock_count = 0x0001;
1604 lck.in.lock_sequence = 0x00000000;
1605 el1[0].offset = 0;
1606 el1[0].length = 10;
1607 el1[0].reserved = 0x00000000;
1609 /* Take exclusive lock, then unlock it with a shared-unlock call. */
1611 torture_comment(torture, "Testing unlock exclusive with shared\n");
1613 torture_comment(torture, " taking exclusive lock.\n");
1614 lck.in.file.handle = h;
1615 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE;
1616 status = smb2_lock(tree, &lck);
1617 CHECK_STATUS(status, NT_STATUS_OK);
1619 torture_comment(torture, " try to unlock the exclusive with a shared "
1620 "unlock call.\n");
1621 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1622 SMB2_LOCK_FLAG_UNLOCK;
1623 status = smb2_lock(tree, &lck);
1624 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1626 torture_comment(torture, " try shared lock on h2, to test the "
1627 "unlock.\n");
1628 lck.in.file.handle = h2;
1629 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1630 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1631 status = smb2_lock(tree, &lck);
1632 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1634 torture_comment(torture, " unlock the exclusive lock\n");
1635 lck.in.file.handle = h;
1636 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1637 status = smb2_lock(tree, &lck);
1638 CHECK_STATUS(status, NT_STATUS_OK);
1640 /* Unlock a shared lock with an exclusive-unlock call. */
1642 torture_comment(torture, "Testing unlock shared with exclusive\n");
1644 torture_comment(torture, " taking shared lock.\n");
1645 lck.in.file.handle = h;
1646 el1[0].flags = SMB2_LOCK_FLAG_SHARED;
1647 status = smb2_lock(tree, &lck);
1648 CHECK_STATUS(status, NT_STATUS_OK);
1650 torture_comment(torture, " try to unlock the shared with an exclusive "
1651 "unlock call.\n");
1652 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1653 SMB2_LOCK_FLAG_UNLOCK;
1654 status = smb2_lock(tree, &lck);
1655 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1657 torture_comment(torture, " try exclusive lock on h2, to test the "
1658 "unlock.\n");
1659 lck.in.file.handle = h2;
1660 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1661 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1662 status = smb2_lock(tree, &lck);
1663 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1665 torture_comment(torture, " unlock the exclusive lock\n");
1666 lck.in.file.handle = h;
1667 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1668 status = smb2_lock(tree, &lck);
1669 CHECK_STATUS(status, NT_STATUS_OK);
1671 /* Test unlocking of stacked 0-byte locks. SMB2 0-byte lock behavior
1672 * should be the same as >0-byte behavior. Exclusive locks should be
1673 * unlocked before shared. */
1675 torture_comment(torture, "Test unlocking stacked 0-byte locks\n");
1677 lck.in.locks = el1;
1678 lck.in.file.handle = h;
1679 el1[0].offset = 10;
1680 el1[0].length = 0;
1681 el1[0].reserved = 0x00000000;
1682 el2[0].offset = 5;
1683 el2[0].length = 10;
1684 el2[0].reserved = 0x00000000;
1686 /* lock 0-byte exclusive */
1687 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1688 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1689 status = smb2_lock(tree, &lck);
1690 CHECK_STATUS(status, NT_STATUS_OK);
1692 /* lock 0-byte shared */
1693 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1694 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1695 status = smb2_lock(tree, &lck);
1696 CHECK_STATUS(status, NT_STATUS_OK);
1698 /* test contention */
1699 lck.in.locks = el2;
1700 lck.in.file.handle = h2;
1701 el2[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1702 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1703 status = smb2_lock(tree, &lck);
1704 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1706 lck.in.locks = el2;
1707 lck.in.file.handle = h2;
1708 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1709 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1710 status = smb2_lock(tree, &lck);
1711 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1713 /* unlock */
1714 lck.in.locks = el1;
1715 lck.in.file.handle = h;
1716 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1717 status = smb2_lock(tree, &lck);
1718 CHECK_STATUS(status, NT_STATUS_OK);
1720 /* test - can we take a shared lock? */
1721 lck.in.locks = el2;
1722 lck.in.file.handle = h2;
1723 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1724 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1725 status = smb2_lock(tree, &lck);
1726 CHECK_STATUS(status, NT_STATUS_OK);
1728 el2[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1729 status = smb2_lock(tree, &lck);
1730 CHECK_STATUS(status, NT_STATUS_OK);
1732 /* cleanup */
1733 lck.in.locks = el1;
1734 lck.in.file.handle = h;
1735 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1736 status = smb2_lock(tree, &lck);
1737 CHECK_STATUS(status, NT_STATUS_OK);
1739 /* Test unlocking of stacked exclusive, shared locks. Exclusive
1740 * should be unlocked before any shared. */
1742 torture_comment(torture, "Test unlocking stacked exclusive/shared "
1743 "locks\n");
1745 lck.in.locks = el1;
1746 lck.in.file.handle = h;
1747 el1[0].offset = 10;
1748 el1[0].length = 10;
1749 el1[0].reserved = 0x00000000;
1750 el2[0].offset = 5;
1751 el2[0].length = 10;
1752 el2[0].reserved = 0x00000000;
1754 /* lock exclusive */
1755 el1[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1756 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1757 status = smb2_lock(tree, &lck);
1758 CHECK_STATUS(status, NT_STATUS_OK);
1760 /* lock shared */
1761 el1[0].flags = SMB2_LOCK_FLAG_SHARED |
1762 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1763 status = smb2_lock(tree, &lck);
1764 CHECK_STATUS(status, NT_STATUS_OK);
1766 /* test contention */
1767 lck.in.locks = el2;
1768 lck.in.file.handle = h2;
1769 el2[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1770 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1771 status = smb2_lock(tree, &lck);
1772 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1774 lck.in.locks = el2;
1775 lck.in.file.handle = h2;
1776 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1777 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1778 status = smb2_lock(tree, &lck);
1779 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1781 /* unlock */
1782 lck.in.locks = el1;
1783 lck.in.file.handle = h;
1784 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1785 status = smb2_lock(tree, &lck);
1786 CHECK_STATUS(status, NT_STATUS_OK);
1788 /* test - can we take a shared lock? */
1789 lck.in.locks = el2;
1790 lck.in.file.handle = h2;
1791 el2[0].flags = SMB2_LOCK_FLAG_SHARED |
1792 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1793 status = smb2_lock(tree, &lck);
1794 CHECK_STATUS(status, NT_STATUS_OK);
1796 el2[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1797 status = smb2_lock(tree, &lck);
1798 CHECK_STATUS(status, NT_STATUS_OK);
1800 /* cleanup */
1801 lck.in.locks = el1;
1802 lck.in.file.handle = h;
1803 el1[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1804 status = smb2_lock(tree, &lck);
1805 CHECK_STATUS(status, NT_STATUS_OK);
1807 done:
1808 smb2_util_close(tree, h2);
1809 smb2_util_close(tree, h);
1810 smb2_deltree(tree, BASEDIR);
1811 return ret;
1814 static bool test_multiple_unlock(struct torture_context *torture,
1815 struct smb2_tree *tree)
1817 NTSTATUS status;
1818 bool ret = true;
1819 struct smb2_handle h;
1820 uint8_t buf[200];
1821 struct smb2_lock lck;
1822 struct smb2_lock_element el[2];
1824 const char *fname = BASEDIR "\\unlock_multiple.txt";
1826 status = torture_smb2_testdir(tree, BASEDIR, &h);
1827 CHECK_STATUS(status, NT_STATUS_OK);
1828 smb2_util_close(tree, h);
1830 status = torture_smb2_testfile(tree, fname, &h);
1831 CHECK_STATUS(status, NT_STATUS_OK);
1833 ZERO_STRUCT(buf);
1834 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
1835 CHECK_STATUS(status, NT_STATUS_OK);
1837 torture_comment(torture, "Testing multiple unlocks:\n");
1839 /* Setup initial parameters */
1840 lck.in.lock_count = 0x0002;
1841 lck.in.lock_sequence = 0x00000000;
1842 lck.in.file.handle = h;
1843 el[0].offset = 0;
1844 el[0].length = 10;
1845 el[0].reserved = 0x00000000;
1846 el[1].offset = 10;
1847 el[1].length = 10;
1848 el[1].reserved = 0x00000000;
1850 /* Test1: Acquire second lock, but not first. */
1851 torture_comment(torture, " unlock 2 locks, first one not locked. "
1852 "Expect no locks unlocked. \n");
1854 lck.in.lock_count = 0x0001;
1855 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1856 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1857 lck.in.locks = &el[1];
1858 status = smb2_lock(tree, &lck);
1859 CHECK_STATUS(status, NT_STATUS_OK);
1861 /* Try to unlock both locks */
1862 lck.in.lock_count = 0x0002;
1863 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1864 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
1865 lck.in.locks = el;
1866 status = smb2_lock(tree, &lck);
1867 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1869 /* Second lock should not be unlocked. */
1870 lck.in.lock_count = 0x0001;
1871 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1872 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1873 lck.in.locks = &el[1];
1874 status = smb2_lock(tree, &lck);
1875 if (TARGET_IS_W2K8(torture)) {
1876 CHECK_STATUS(status, NT_STATUS_OK);
1877 torture_warning(torture, "Target has \"pretty please\" bug. "
1878 "A contending lock request on the same handle "
1879 "unlocks the lock.\n");
1880 } else {
1881 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1884 /* cleanup */
1885 lck.in.lock_count = 0x0001;
1886 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
1887 lck.in.locks = &el[1];
1888 status = smb2_lock(tree, &lck);
1889 CHECK_STATUS(status, NT_STATUS_OK);
1891 /* Test2: Acquire first lock, but not second. */
1892 torture_comment(torture, " unlock 2 locks, second one not locked. "
1893 "Expect first lock unlocked.\n");
1895 lck.in.lock_count = 0x0001;
1896 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1897 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1898 lck.in.locks = &el[0];
1899 status = smb2_lock(tree, &lck);
1900 CHECK_STATUS(status, NT_STATUS_OK);
1902 /* Try to unlock both locks */
1903 lck.in.lock_count = 0x0002;
1904 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1905 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
1906 lck.in.locks = el;
1907 status = smb2_lock(tree, &lck);
1908 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
1910 /* First lock should be unlocked. */
1911 lck.in.lock_count = 0x0001;
1912 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1913 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1914 lck.in.locks = &el[0];
1915 status = smb2_lock(tree, &lck);
1916 CHECK_STATUS(status, NT_STATUS_OK);
1918 /* cleanup */
1919 lck.in.lock_count = 0x0001;
1920 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1921 lck.in.locks = &el[0];
1922 status = smb2_lock(tree, &lck);
1923 CHECK_STATUS(status, NT_STATUS_OK);
1925 /* Test3: Request 2 locks, second will contend. What happens to the
1926 * first? */
1927 torture_comment(torture, " request 2 locks, second one will contend. "
1928 "Expect both to fail.\n");
1930 /* Lock the second range */
1931 lck.in.lock_count = 0x0001;
1932 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1933 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1934 lck.in.locks = &el[1];
1935 status = smb2_lock(tree, &lck);
1936 CHECK_STATUS(status, NT_STATUS_OK);
1938 /* Request both locks */
1939 lck.in.lock_count = 0x0002;
1940 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1941 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1942 lck.in.locks = el;
1943 status = smb2_lock(tree, &lck);
1944 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
1946 /* First lock should be unlocked. */
1947 lck.in.lock_count = 0x0001;
1948 lck.in.locks = &el[0];
1949 status = smb2_lock(tree, &lck);
1950 CHECK_STATUS(status, NT_STATUS_OK);
1952 /* cleanup */
1953 if (TARGET_IS_W2K8(torture)) {
1954 lck.in.lock_count = 0x0001;
1955 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1956 lck.in.locks = &el[0];
1957 status = smb2_lock(tree, &lck);
1958 CHECK_STATUS(status, NT_STATUS_OK);
1959 torture_warning(torture, "Target has \"pretty please\" bug. "
1960 "A contending lock request on the same handle "
1961 "unlocks the lock.\n");
1962 } else {
1963 lck.in.lock_count = 0x0002;
1964 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1965 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
1966 lck.in.locks = el;
1967 status = smb2_lock(tree, &lck);
1968 CHECK_STATUS(status, NT_STATUS_OK);
1971 /* Test4: Request unlock and lock. The lock contends, is the unlock
1972 * then relocked? SMB2 doesn't like the lock and unlock requests in the
1973 * same packet. The unlock will succeed, but the lock will return
1974 * INVALID_PARAMETER. This behavior is described in MS-SMB2
1975 * 3.3.5.14.1 */
1976 torture_comment(torture, " request unlock and lock, second one will "
1977 "error. Expect the unlock to succeed.\n");
1979 /* Lock both ranges */
1980 lck.in.lock_count = 0x0002;
1981 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1982 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1983 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1984 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1985 lck.in.locks = el;
1986 status = smb2_lock(tree, &lck);
1987 CHECK_STATUS(status, NT_STATUS_OK);
1989 /* Attempt to unlock the first range and lock the second. The lock
1990 * request will error. */
1991 lck.in.lock_count = 0x0002;
1992 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
1993 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
1994 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1995 lck.in.locks = el;
1996 status = smb2_lock(tree, &lck);
1997 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
1999 /* The first lock should've been unlocked */
2000 lck.in.lock_count = 0x0001;
2001 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2002 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2003 lck.in.locks = &el[0];
2004 status = smb2_lock(tree, &lck);
2005 CHECK_STATUS(status, NT_STATUS_OK);
2007 /* cleanup */
2008 lck.in.lock_count = 0x0002;
2009 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2010 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
2011 lck.in.locks = el;
2012 status = smb2_lock(tree, &lck);
2013 CHECK_STATUS(status, NT_STATUS_OK);
2015 /* Test10: SMB2 only test. Request unlock and lock in same packet.
2016 * Neither contend. SMB2 doesn't like lock and unlock requests in the
2017 * same packet. The unlock will succeed, but the lock will return
2018 * INVALID_PARAMETER. */
2019 torture_comment(torture, " request unlock and lock. Unlock will "
2020 "succeed, but lock will fail.\n");
2022 /* Lock first range */
2023 lck.in.lock_count = 0x0001;
2024 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2025 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2026 lck.in.locks = &el[0];
2027 status = smb2_lock(tree, &lck);
2028 CHECK_STATUS(status, NT_STATUS_OK);
2030 /* Attempt to unlock the first range and lock the second */
2031 lck.in.lock_count = 0x0002;
2032 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2033 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2034 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2035 lck.in.locks = el;
2036 status = smb2_lock(tree, &lck);
2037 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
2039 /* Neither lock should still be locked */
2040 lck.in.lock_count = 0x0002;
2041 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2042 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2043 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2044 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2045 lck.in.locks = el;
2046 status = smb2_lock(tree, &lck);
2047 CHECK_STATUS(status, NT_STATUS_OK);
2049 /* cleanup */
2050 lck.in.lock_count = 0x0002;
2051 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2052 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
2053 lck.in.locks = el;
2054 status = smb2_lock(tree, &lck);
2055 CHECK_STATUS(status, NT_STATUS_OK);
2057 /* Test11: SMB2 only test. Request lock and unlock in same packet.
2058 * Neither contend. SMB2 doesn't like lock and unlock requests in the
2059 * same packet. The lock will succeed, the unlock will fail with
2060 * INVALID_PARAMETER, and the lock will be unlocked before return. */
2061 torture_comment(torture, " request lock and unlock. Both will "
2062 "fail.\n");
2064 /* Lock second range */
2065 lck.in.lock_count = 0x0001;
2066 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2067 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2068 lck.in.locks = &el[1];
2069 status = smb2_lock(tree, &lck);
2070 CHECK_STATUS(status, NT_STATUS_OK);
2072 /* Attempt to lock the first range and unlock the second */
2073 lck.in.lock_count = 0x0002;
2074 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2075 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2076 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
2077 lck.in.locks = el;
2078 status = smb2_lock(tree, &lck);
2079 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
2081 /* First range should be unlocked, second locked. */
2082 lck.in.lock_count = 0x0001;
2083 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2084 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2085 lck.in.locks = &el[0];
2086 status = smb2_lock(tree, &lck);
2087 CHECK_STATUS(status, NT_STATUS_OK);
2089 lck.in.lock_count = 0x0001;
2090 el[1].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2091 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2092 lck.in.locks = &el[1];
2093 status = smb2_lock(tree, &lck);
2094 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2096 /* cleanup */
2097 if (TARGET_IS_W2K8(torture)) {
2098 lck.in.lock_count = 0x0001;
2099 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2100 lck.in.locks = &el[0];
2101 status = smb2_lock(tree, &lck);
2102 CHECK_STATUS(status, NT_STATUS_OK);
2103 torture_warning(torture, "Target has \"pretty please\" bug. "
2104 "A contending lock request on the same handle "
2105 "unlocks the lock.\n");
2106 } else {
2107 lck.in.lock_count = 0x0002;
2108 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2109 el[1].flags = SMB2_LOCK_FLAG_UNLOCK;
2110 lck.in.locks = el;
2111 status = smb2_lock(tree, &lck);
2112 CHECK_STATUS(status, NT_STATUS_OK);
2115 done:
2116 smb2_util_close(tree, h);
2117 smb2_deltree(tree, BASEDIR);
2118 return ret;
2122 * Test lock stacking
2123 * - some tests ported from BASE-LOCK-LOCK5
2125 static bool test_stacking(struct torture_context *torture,
2126 struct smb2_tree *tree)
2128 NTSTATUS status;
2129 bool ret = true;
2130 struct smb2_handle h, h2;
2131 uint8_t buf[200];
2132 struct smb2_lock lck;
2133 struct smb2_lock_element el[1];
2135 const char *fname = BASEDIR "\\stacking.txt";
2137 status = torture_smb2_testdir(tree, BASEDIR, &h);
2138 CHECK_STATUS(status, NT_STATUS_OK);
2139 smb2_util_close(tree, h);
2141 status = torture_smb2_testfile(tree, fname, &h);
2142 CHECK_STATUS(status, NT_STATUS_OK);
2144 ZERO_STRUCT(buf);
2145 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2146 CHECK_STATUS(status, NT_STATUS_OK);
2148 status = torture_smb2_testfile(tree, fname, &h2);
2149 CHECK_STATUS(status, NT_STATUS_OK);
2151 torture_comment(torture, "Testing lock stacking:\n");
2153 /* Setup initial parameters */
2154 lck.in.locks = el;
2155 lck.in.lock_count = 0x0001;
2156 lck.in.lock_sequence = 0x00000000;
2157 lck.in.file.handle = h;
2158 el[0].offset = 0;
2159 el[0].length = 10;
2160 el[0].reserved = 0x00000000;
2162 /* Try to take a shared lock, then a shared lock on same handle */
2163 torture_comment(torture, " stacking a shared on top of a shared"
2164 "lock succeeds.\n");
2166 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2167 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2168 status = smb2_lock(tree, &lck);
2169 CHECK_STATUS(status, NT_STATUS_OK);
2171 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2172 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2173 status = smb2_lock(tree, &lck);
2174 CHECK_STATUS(status, NT_STATUS_OK);
2176 /* cleanup */
2177 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2178 status = smb2_lock(tree, &lck);
2179 CHECK_STATUS(status, NT_STATUS_OK);
2181 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2182 status = smb2_lock(tree, &lck);
2183 CHECK_STATUS(status, NT_STATUS_OK);
2186 /* Try to take an exclusive lock, then a shared lock on same handle */
2187 torture_comment(torture, " stacking a shared on top of an exclusive "
2188 "lock succeeds.\n");
2190 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2191 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2192 status = smb2_lock(tree, &lck);
2193 CHECK_STATUS(status, NT_STATUS_OK);
2195 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2196 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2197 status = smb2_lock(tree, &lck);
2198 CHECK_STATUS(status, NT_STATUS_OK);
2200 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2201 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2202 status = smb2_lock(tree, &lck);
2203 CHECK_STATUS(status, NT_STATUS_OK);
2205 /* stacking a shared from a different handle should fail */
2206 lck.in.file.handle = h2;
2207 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2208 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2209 status = smb2_lock(tree, &lck);
2210 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2212 /* cleanup */
2213 lck.in.file.handle = h;
2214 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2215 status = smb2_lock(tree, &lck);
2216 CHECK_STATUS(status, NT_STATUS_OK);
2218 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2219 status = smb2_lock(tree, &lck);
2220 CHECK_STATUS(status, NT_STATUS_OK);
2222 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2223 status = smb2_lock(tree, &lck);
2224 CHECK_STATUS(status, NT_STATUS_OK);
2226 /* ensure the 4th unlock fails */
2227 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2228 status = smb2_lock(tree, &lck);
2229 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2231 /* ensure a second handle can now take an exclusive lock */
2232 lck.in.file.handle = h2;
2233 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2234 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2235 status = smb2_lock(tree, &lck);
2236 CHECK_STATUS(status, NT_STATUS_OK);
2238 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2239 status = smb2_lock(tree, &lck);
2240 CHECK_STATUS(status, NT_STATUS_OK);
2242 /* Try to take an exclusive lock, then a shared lock on a
2243 * different handle */
2244 torture_comment(torture, " stacking a shared on top of an exclusive "
2245 "lock with different handles fails.\n");
2247 lck.in.file.handle = h;
2248 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2249 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2250 status = smb2_lock(tree, &lck);
2251 CHECK_STATUS(status, NT_STATUS_OK);
2253 lck.in.file.handle = h2;
2254 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2255 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2256 status = smb2_lock(tree, &lck);
2257 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2259 /* cleanup */
2260 lck.in.file.handle = h;
2261 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2262 status = smb2_lock(tree, &lck);
2263 CHECK_STATUS(status, NT_STATUS_OK);
2265 /* Try to take a shared lock, then stack an exclusive with same
2266 * handle. */
2267 torture_comment(torture, " stacking an exclusive on top of a shared "
2268 "lock fails.\n");
2270 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2271 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2272 status = smb2_lock(tree, &lck);
2273 CHECK_STATUS(status, NT_STATUS_OK);
2275 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2276 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2277 status = smb2_lock(tree, &lck);
2278 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2280 /* cleanup */
2281 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2282 status = smb2_lock(tree, &lck);
2283 if (TARGET_IS_W2K8(torture)) {
2284 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2285 torture_warning(torture, "Target has \"pretty please\" bug. "
2286 "A contending lock request on the same handle "
2287 "unlocks the lock.\n");
2288 } else {
2289 CHECK_STATUS(status, NT_STATUS_OK);
2292 /* Prove that two exclusive locks do not stack on the same handle. */
2293 torture_comment(torture, " two exclusive locks do not stack.\n");
2295 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2296 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2297 status = smb2_lock(tree, &lck);
2298 CHECK_STATUS(status, NT_STATUS_OK);
2300 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2301 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2302 status = smb2_lock(tree, &lck);
2303 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2305 /* cleanup */
2306 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2307 status = smb2_lock(tree, &lck);
2308 if (TARGET_IS_W2K8(torture)) {
2309 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2310 torture_warning(torture, "Target has \"pretty please\" bug. "
2311 "A contending lock request on the same handle "
2312 "unlocks the lock.\n");
2313 } else {
2314 CHECK_STATUS(status, NT_STATUS_OK);
2317 done:
2318 smb2_util_close(tree, h2);
2319 smb2_util_close(tree, h);
2320 smb2_deltree(tree, BASEDIR);
2321 return ret;
2325 * Test lock contention
2326 * - shared lock should contend with exclusive lock on different handle
2328 static bool test_contend(struct torture_context *torture,
2329 struct smb2_tree *tree)
2331 NTSTATUS status;
2332 bool ret = true;
2333 struct smb2_handle h, h2;
2334 uint8_t buf[200];
2335 struct smb2_lock lck;
2336 struct smb2_lock_element el[1];
2338 const char *fname = BASEDIR "\\contend.txt";
2340 status = torture_smb2_testdir(tree, BASEDIR, &h);
2341 CHECK_STATUS(status, NT_STATUS_OK);
2342 smb2_util_close(tree, h);
2344 status = torture_smb2_testfile(tree, fname, &h);
2345 CHECK_STATUS(status, NT_STATUS_OK);
2347 ZERO_STRUCT(buf);
2348 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2349 CHECK_STATUS(status, NT_STATUS_OK);
2351 status = torture_smb2_testfile(tree, fname, &h2);
2352 CHECK_STATUS(status, NT_STATUS_OK);
2354 torture_comment(torture, "Testing lock contention:\n");
2356 /* Setup initial parameters */
2357 lck.in.locks = el;
2358 lck.in.lock_count = 0x0001;
2359 lck.in.lock_sequence = 0x00000000;
2360 lck.in.file.handle = h;
2361 el[0].offset = 0;
2362 el[0].length = 10;
2363 el[0].reserved = 0x00000000;
2365 /* Take an exclusive lock, then a shared lock on different handle */
2366 torture_comment(torture, " shared should contend on exclusive on "
2367 "different handle.\n");
2369 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2370 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2371 status = smb2_lock(tree, &lck);
2372 CHECK_STATUS(status, NT_STATUS_OK);
2374 lck.in.file.handle = h2;
2375 el[0].flags = SMB2_LOCK_FLAG_SHARED |
2376 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2377 status = smb2_lock(tree, &lck);
2378 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
2380 /* cleanup */
2381 lck.in.file.handle = h;
2382 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2383 status = smb2_lock(tree, &lck);
2384 CHECK_STATUS(status, NT_STATUS_OK);
2386 done:
2387 smb2_util_close(tree, h2);
2388 smb2_util_close(tree, h);
2389 smb2_deltree(tree, BASEDIR);
2390 return ret;
2394 * Test locker context
2395 * - test that pid does not affect the locker context
2397 static bool test_context(struct torture_context *torture,
2398 struct smb2_tree *tree)
2400 NTSTATUS status;
2401 bool ret = true;
2402 struct smb2_handle h, h2;
2403 uint8_t buf[200];
2404 struct smb2_lock lck;
2405 struct smb2_lock_element el[1];
2407 const char *fname = BASEDIR "\\context.txt";
2409 status = torture_smb2_testdir(tree, BASEDIR, &h);
2410 CHECK_STATUS(status, NT_STATUS_OK);
2411 smb2_util_close(tree, h);
2413 status = torture_smb2_testfile(tree, fname, &h);
2414 CHECK_STATUS(status, NT_STATUS_OK);
2416 ZERO_STRUCT(buf);
2417 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2418 CHECK_STATUS(status, NT_STATUS_OK);
2420 status = torture_smb2_testfile(tree, fname, &h2);
2421 CHECK_STATUS(status, NT_STATUS_OK);
2423 torture_comment(torture, "Testing locker context:\n");
2425 /* Setup initial parameters */
2426 lck.in.locks = el;
2427 lck.in.lock_count = 0x0001;
2428 lck.in.lock_sequence = 0x00000000;
2429 lck.in.file.handle = h;
2430 el[0].offset = 0;
2431 el[0].length = 10;
2432 el[0].reserved = 0x00000000;
2434 /* Take an exclusive lock, then try to unlock with a different pid,
2435 * same handle. This shows that the pid doesn't affect the locker
2436 * context in SMB2. */
2437 torture_comment(torture, " pid shouldn't affect locker context\n");
2439 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2440 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2441 status = smb2_lock(tree, &lck);
2442 CHECK_STATUS(status, NT_STATUS_OK);
2444 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2445 status = smb2_lock(tree, &lck);
2446 CHECK_STATUS(status, NT_STATUS_OK);
2448 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2449 status = smb2_lock(tree, &lck);
2450 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
2452 done:
2453 smb2_util_close(tree, h2);
2454 smb2_util_close(tree, h);
2455 smb2_deltree(tree, BASEDIR);
2456 return ret;
2460 * Test as much of the potential lock range as possible
2461 * - test ported from BASE-LOCK-LOCK3
2463 static bool test_range(struct torture_context *torture,
2464 struct smb2_tree *tree)
2466 NTSTATUS status;
2467 bool ret = true;
2468 struct smb2_handle h, h2;
2469 uint8_t buf[200];
2470 struct smb2_lock lck;
2471 struct smb2_lock_element el[1];
2472 uint64_t offset, i;
2473 extern int torture_numops;
2475 const char *fname = BASEDIR "\\range.txt";
2477 #define NEXT_OFFSET offset += (~(uint64_t)0) / torture_numops
2479 status = torture_smb2_testdir(tree, BASEDIR, &h);
2480 CHECK_STATUS(status, NT_STATUS_OK);
2481 smb2_util_close(tree, h);
2483 status = torture_smb2_testfile(tree, fname, &h);
2484 CHECK_STATUS(status, NT_STATUS_OK);
2486 ZERO_STRUCT(buf);
2487 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2488 CHECK_STATUS(status, NT_STATUS_OK);
2490 status = torture_smb2_testfile(tree, fname, &h2);
2491 CHECK_STATUS(status, NT_STATUS_OK);
2493 torture_comment(torture, "Testing locks spread across the 64-bit "
2494 "offset range\n");
2496 if (TARGET_IS_W2K8(torture)) {
2497 torture_result(torture, TORTURE_SKIP,
2498 "Target has \"pretty please\" bug. A contending lock "
2499 "request on the same handle unlocks the lock.");
2500 goto done;
2503 /* Setup initial parameters */
2504 lck.in.locks = el;
2505 lck.in.lock_count = 0x0001;
2506 lck.in.lock_sequence = 0x00000000;
2507 lck.in.file.handle = h;
2508 el[0].offset = 0;
2509 el[0].length = 1;
2510 el[0].reserved = 0x00000000;
2511 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2512 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2514 torture_comment(torture, " establishing %d locks\n", torture_numops);
2516 for (offset=i=0; i<torture_numops; i++) {
2517 NEXT_OFFSET;
2519 lck.in.file.handle = h;
2520 el[0].offset = offset - 1;
2521 status = smb2_lock(tree, &lck);
2522 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2523 talloc_asprintf(torture,
2524 "lock h failed at offset %#llx ",
2525 (unsigned long long) el[0].offset));
2527 lck.in.file.handle = h2;
2528 el[0].offset = offset - 2;
2529 status = smb2_lock(tree, &lck);
2530 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2531 talloc_asprintf(torture,
2532 "lock h2 failed at offset %#llx ",
2533 (unsigned long long) el[0].offset));
2536 torture_comment(torture, " testing %d locks\n", torture_numops);
2538 for (offset=i=0; i<torture_numops; i++) {
2539 NEXT_OFFSET;
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_LOCK_NOT_GRANTED,
2545 talloc_asprintf(torture,
2546 "lock h at offset %#llx should not have "
2547 "succeeded ",
2548 (unsigned long long) el[0].offset));
2550 lck.in.file.handle = h;
2551 el[0].offset = offset - 2;
2552 status = smb2_lock(tree, &lck);
2553 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2554 talloc_asprintf(torture,
2555 "lock h2 at offset %#llx should not have "
2556 "succeeded ",
2557 (unsigned long long) el[0].offset));
2559 lck.in.file.handle = h2;
2560 el[0].offset = offset - 1;
2561 status = smb2_lock(tree, &lck);
2562 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2563 talloc_asprintf(torture,
2564 "lock h at offset %#llx should not have "
2565 "succeeded ",
2566 (unsigned long long) el[0].offset));
2568 lck.in.file.handle = h2;
2569 el[0].offset = offset - 2;
2570 status = smb2_lock(tree, &lck);
2571 CHECK_STATUS_CMT(status, NT_STATUS_LOCK_NOT_GRANTED,
2572 talloc_asprintf(torture,
2573 "lock h2 at offset %#llx should not have "
2574 "succeeded ",
2575 (unsigned long long) el[0].offset));
2578 torture_comment(torture, " removing %d locks\n", torture_numops);
2580 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2582 for (offset=i=0; i<torture_numops; i++) {
2583 NEXT_OFFSET;
2585 lck.in.file.handle = h;
2586 el[0].offset = offset - 1;
2587 status = smb2_lock(tree, &lck);
2588 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2589 talloc_asprintf(torture,
2590 "unlock from h failed at offset %#llx ",
2591 (unsigned long long) el[0].offset));
2593 lck.in.file.handle = h2;
2594 el[0].offset = offset - 2;
2595 status = smb2_lock(tree, &lck);
2596 CHECK_STATUS_CMT(status, NT_STATUS_OK,
2597 talloc_asprintf(torture,
2598 "unlock from h2 failed at offset %#llx ",
2599 (unsigned long long) el[0].offset));
2602 done:
2603 smb2_util_close(tree, h2);
2604 smb2_util_close(tree, h);
2605 smb2_deltree(tree, BASEDIR);
2606 return ret;
2609 static NTSTATUS test_smb2_lock(struct smb2_tree *tree, struct smb2_handle h,
2610 uint64_t offset, uint64_t length, bool exclusive)
2612 struct smb2_lock lck;
2613 struct smb2_lock_element el[1];
2614 NTSTATUS status;
2616 lck.in.locks = el;
2617 lck.in.lock_count = 0x0001;
2618 lck.in.lock_sequence = 0x00000000;
2619 lck.in.file.handle = h;
2620 el[0].offset = offset;
2621 el[0].length = length;
2622 el[0].reserved = 0x00000000;
2623 el[0].flags = (exclusive ?
2624 SMB2_LOCK_FLAG_EXCLUSIVE :
2625 SMB2_LOCK_FLAG_SHARED) |
2626 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2628 status = smb2_lock(tree, &lck);
2630 return status;
2633 static NTSTATUS test_smb2_unlock(struct smb2_tree *tree, struct smb2_handle h,
2634 uint64_t offset, uint64_t length)
2636 struct smb2_lock lck;
2637 struct smb2_lock_element el[1];
2638 NTSTATUS status;
2640 lck.in.locks = el;
2641 lck.in.lock_count = 0x0001;
2642 lck.in.lock_sequence = 0x00000000;
2643 lck.in.file.handle = h;
2644 el[0].offset = offset;
2645 el[0].length = length;
2646 el[0].reserved = 0x00000000;
2647 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2649 status = smb2_lock(tree, &lck);
2651 return status;
2654 #define EXPECTED(ret, v) if ((ret) != (v)) { \
2655 torture_result(torture, TORTURE_FAIL, __location__": subtest failed");\
2656 torture_comment(torture, "** "); correct = false; \
2660 * Test overlapping lock ranges from various lockers
2661 * - some tests ported from BASE-LOCK-LOCK4
2663 static bool test_overlap(struct torture_context *torture,
2664 struct smb2_tree *tree,
2665 struct smb2_tree *tree2)
2667 NTSTATUS status;
2668 bool ret = true;
2669 struct smb2_handle h, h2, h3;
2670 uint8_t buf[200];
2671 bool correct = true;
2673 const char *fname = BASEDIR "\\overlap.txt";
2675 status = torture_smb2_testdir(tree, BASEDIR, &h);
2676 CHECK_STATUS(status, NT_STATUS_OK);
2677 smb2_util_close(tree, h);
2679 status = torture_smb2_testfile(tree, fname, &h);
2680 CHECK_STATUS(status, NT_STATUS_OK);
2682 ZERO_STRUCT(buf);
2683 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2684 CHECK_STATUS(status, NT_STATUS_OK);
2686 status = torture_smb2_testfile(tree, fname, &h2);
2687 CHECK_STATUS(status, NT_STATUS_OK);
2689 status = torture_smb2_testfile(tree2, fname, &h3);
2690 CHECK_STATUS(status, NT_STATUS_OK);
2692 torture_comment(torture, "Testing overlapping locks:\n");
2694 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 0, 4, true)) &&
2695 NT_STATUS_IS_OK(test_smb2_lock(tree, h, 2, 4, true));
2696 EXPECTED(ret, false);
2697 torture_comment(torture, "the same session/handle %s set overlapping "
2698 "exclusive locks\n", ret?"can":"cannot");
2700 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 10, 4, false)) &&
2701 NT_STATUS_IS_OK(test_smb2_lock(tree, h, 12, 4, false));
2702 EXPECTED(ret, true);
2703 torture_comment(torture, "the same session/handle %s set overlapping "
2704 "shared locks\n", ret?"can":"cannot");
2706 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 20, 4, true)) &&
2707 NT_STATUS_IS_OK(test_smb2_lock(tree2, h3, 22, 4, true));
2708 EXPECTED(ret, false);
2709 torture_comment(torture, "a different session %s set overlapping "
2710 "exclusive locks\n", ret?"can":"cannot");
2712 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 30, 4, false)) &&
2713 NT_STATUS_IS_OK(test_smb2_lock(tree2, h3, 32, 4, false));
2714 EXPECTED(ret, true);
2715 torture_comment(torture, "a different session %s set overlapping "
2716 "shared locks\n", ret?"can":"cannot");
2718 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 40, 4, true)) &&
2719 NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 42, 4, true));
2720 EXPECTED(ret, false);
2721 torture_comment(torture, "a different handle %s set overlapping "
2722 "exclusive locks\n", ret?"can":"cannot");
2724 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 50, 4, false)) &&
2725 NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 52, 4, false));
2726 EXPECTED(ret, true);
2727 torture_comment(torture, "a different handle %s set overlapping "
2728 "shared locks\n", ret?"can":"cannot");
2730 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 110, 4, false)) &&
2731 NT_STATUS_IS_OK(test_smb2_lock(tree, h, 112, 4, false)) &&
2732 NT_STATUS_IS_OK(test_smb2_unlock(tree, h, 110, 6));
2733 EXPECTED(ret, false);
2734 torture_comment(torture, "the same handle %s coalesce read locks\n",
2735 ret?"can":"cannot");
2737 smb2_util_close(tree, h2);
2738 smb2_util_close(tree, h);
2739 status = torture_smb2_testfile(tree, fname, &h);
2740 CHECK_STATUS(status, NT_STATUS_OK);
2741 status = torture_smb2_testfile(tree, fname, &h2);
2742 CHECK_STATUS(status, NT_STATUS_OK);
2743 ret = NT_STATUS_IS_OK(test_smb2_lock(tree, h, 0, 8, false)) &&
2744 NT_STATUS_IS_OK(test_smb2_lock(tree, h2, 0, 1, false)) &&
2745 NT_STATUS_IS_OK(smb2_util_close(tree, h)) &&
2746 NT_STATUS_IS_OK(torture_smb2_testfile(tree, fname, &h)) &&
2747 NT_STATUS_IS_OK(test_smb2_lock(tree, h, 7, 1, true));
2748 EXPECTED(ret, true);
2749 torture_comment(torture, "the server %s have the NT byte range lock "
2750 "bug\n", !ret?"does":"doesn't");
2752 done:
2753 smb2_util_close(tree2, h3);
2754 smb2_util_close(tree, h2);
2755 smb2_util_close(tree, h);
2756 smb2_deltree(tree, BASEDIR);
2757 return correct;
2761 * Test truncation of locked file
2762 * - some tests ported from BASE-LOCK-LOCK7
2764 static bool test_truncate(struct torture_context *torture,
2765 struct smb2_tree *tree)
2767 NTSTATUS status;
2768 bool ret = true;
2769 struct smb2_handle h, h2;
2770 uint8_t buf[200];
2771 struct smb2_lock lck;
2772 struct smb2_lock_element el[1];
2773 struct smb2_create io;
2775 const char *fname = BASEDIR "\\truncate.txt";
2777 status = torture_smb2_testdir(tree, BASEDIR, &h);
2778 CHECK_STATUS(status, NT_STATUS_OK);
2779 smb2_util_close(tree, h);
2781 status = torture_smb2_testfile(tree, fname, &h);
2782 CHECK_STATUS(status, NT_STATUS_OK);
2784 ZERO_STRUCT(buf);
2785 status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
2786 CHECK_STATUS(status, NT_STATUS_OK);
2788 torture_comment(torture, "Testing truncation of locked file:\n");
2790 /* Setup initial parameters */
2791 lck.in.locks = el;
2792 lck.in.lock_count = 0x0001;
2793 lck.in.lock_sequence = 0x00000000;
2794 lck.in.file.handle = h;
2795 el[0].offset = 0;
2796 el[0].length = 10;
2797 el[0].reserved = 0x00000000;
2799 ZERO_STRUCT(io);
2800 io.in.oplock_level = 0;
2801 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
2802 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
2803 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2804 io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE |
2805 NTCREATEX_SHARE_ACCESS_READ |
2806 NTCREATEX_SHARE_ACCESS_WRITE;
2807 io.in.create_options = 0;
2808 io.in.fname = fname;
2810 /* Take an exclusive lock */
2811 el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
2812 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
2813 status = smb2_lock(tree, &lck);
2814 CHECK_STATUS(status, NT_STATUS_OK);
2816 /* On second handle open the file with OVERWRITE disposition */
2817 torture_comment(torture, " overwrite disposition is allowed on a "
2818 "locked file.\n");
2820 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE;
2821 status = smb2_create(tree, tree, &io);
2822 CHECK_STATUS(status, NT_STATUS_OK);
2823 h2 = io.out.file.handle;
2824 smb2_util_close(tree, h2);
2826 /* On second handle open the file with SUPERSEDE disposition */
2827 torture_comment(torture, " supersede disposition is allowed on a "
2828 "locked file.\n");
2830 io.in.create_disposition = NTCREATEX_DISP_SUPERSEDE;
2831 status = smb2_create(tree, tree, &io);
2832 CHECK_STATUS(status, NT_STATUS_OK);
2833 h2 = io.out.file.handle;
2834 smb2_util_close(tree, h2);
2836 /* cleanup */
2837 lck.in.file.handle = h;
2838 el[0].flags = SMB2_LOCK_FLAG_UNLOCK;
2839 status = smb2_lock(tree, &lck);
2840 CHECK_STATUS(status, NT_STATUS_OK);
2842 done:
2843 smb2_util_close(tree, h2);
2844 smb2_util_close(tree, h);
2845 smb2_deltree(tree, BASEDIR);
2846 return ret;
2849 /* basic testing of SMB2 locking
2851 struct torture_suite *torture_smb2_lock_init(void)
2853 struct torture_suite *suite =
2854 torture_suite_create(talloc_autofree_context(), "lock");
2856 torture_suite_add_1smb2_test(suite, "valid-request",
2857 test_valid_request);
2858 torture_suite_add_1smb2_test(suite, "rw-none", test_lock_rw_none);
2859 torture_suite_add_1smb2_test(suite, "rw-shared", test_lock_rw_shared);
2860 torture_suite_add_1smb2_test(suite, "rw-exclusive",
2861 test_lock_rw_exclusive);
2862 torture_suite_add_1smb2_test(suite, "auto-unlock",
2863 test_lock_auto_unlock);
2864 torture_suite_add_1smb2_test(suite, "lock", test_lock);
2865 torture_suite_add_1smb2_test(suite, "async", test_async);
2866 torture_suite_add_1smb2_test(suite, "cancel", test_cancel);
2867 torture_suite_add_1smb2_test(suite, "cancel-tdis", test_cancel_tdis);
2868 torture_suite_add_1smb2_test(suite, "cancel-logoff",
2869 test_cancel_logoff);
2870 torture_suite_add_1smb2_test(suite, "errorcode", test_errorcode);
2871 torture_suite_add_1smb2_test(suite, "zerobytelength",
2872 test_zerobytelength);
2873 torture_suite_add_1smb2_test(suite, "zerobyteread",
2874 test_zerobyteread);
2875 torture_suite_add_1smb2_test(suite, "unlock", test_unlock);
2876 torture_suite_add_1smb2_test(suite, "multiple-unlock",
2877 test_multiple_unlock);
2878 torture_suite_add_1smb2_test(suite, "stacking", test_stacking);
2879 torture_suite_add_1smb2_test(suite, "contend", test_contend);
2880 torture_suite_add_1smb2_test(suite, "context", test_context);
2881 torture_suite_add_1smb2_test(suite, "range", test_range);
2882 torture_suite_add_2smb2_test(suite, "overlap", test_overlap);
2883 torture_suite_add_1smb2_test(suite, "truncate", test_truncate);
2885 suite->description = talloc_strdup(suite, "SMB2-LOCK tests");
2887 return suite;