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"
25 #include "../libcli/smb/smbXcli_base.h"
27 #include "torture/torture.h"
28 #include "torture/smb2/proto.h"
29 #include "torture/util.h"
31 #include "lib/events/events.h"
32 #include "param/param.h"
34 #define CHECK_STATUS(status, correct) do { \
35 const char *_cmt = "(" __location__ ")"; \
36 torture_assert_ntstatus_equal_goto(torture,status,correct, \
40 #define CHECK_STATUS_CMT(status, correct, cmt) do { \
41 torture_assert_ntstatus_equal_goto(torture,status,correct, \
45 #define CHECK_STATUS_CONT(status, correct) do { \
46 if (!NT_STATUS_EQUAL(status, correct)) { \
47 torture_result(torture, TORTURE_FAIL, \
48 "(%s) Incorrect status %s - should be %s\n", \
49 __location__, nt_errstr(status), nt_errstr(correct)); \
53 #define CHECK_VALUE(v, correct) do { \
54 const char *_cmt = "(" __location__ ")"; \
55 torture_assert_int_equal_goto(torture,v,correct,ret,done,_cmt); \
58 #define BASEDIR "testlock"
60 #define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
61 (torture_setting_bool(_tctx, "invalid_lock_range_support", true))
62 #define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
64 #define WAIT_FOR_ASYNC_RESPONSE(req) \
65 while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
66 if (tevent_loop_once(torture->ev) != 0) { \
71 static bool test_valid_request(struct torture_context
*torture
,
72 struct smb2_tree
*tree
)
79 struct smb2_lock_element el
[2];
83 status
= torture_smb2_testfile(tree
, "lock1.txt", &h
);
84 CHECK_STATUS(status
, NT_STATUS_OK
);
86 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
87 CHECK_STATUS(status
, NT_STATUS_OK
);
91 torture_comment(torture
, "Test request with 0 locks.\n");
93 lck
.in
.lock_count
= 0x0000;
94 lck
.in
.lock_sequence
= 0x00000000;
95 lck
.in
.file
.handle
= h
;
96 el
[0].offset
= 0x0000000000000000;
97 el
[0].length
= 0x0000000000000000;
98 el
[0].reserved
= 0x0000000000000000;
99 el
[0].flags
= 0x00000000;
100 status
= smb2_lock(tree
, &lck
);
101 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
103 lck
.in
.lock_count
= 0x0000;
104 lck
.in
.lock_sequence
= 0x00000000;
105 lck
.in
.file
.handle
= h
;
108 el
[0].reserved
= 0x00000000;
109 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
;
110 status
= smb2_lock(tree
, &lck
);
111 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
113 lck
.in
.lock_count
= 0x0001;
114 lck
.in
.lock_sequence
= 0x00000000;
115 lck
.in
.file
.handle
= h
;
118 el
[0].reserved
= 0x00000000;
119 el
[0].flags
= SMB2_LOCK_FLAG_NONE
;
120 status
= smb2_lock(tree
, &lck
);
121 if (TARGET_IS_W2K8(torture
)) {
122 CHECK_STATUS(status
, NT_STATUS_OK
);
123 torture_warning(torture
, "Target has bug validating lock flags "
126 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
129 torture_comment(torture
, "Test >63-bit lock requests.\n");
131 lck
.in
.file
.handle
.data
[0] +=1;
132 status
= smb2_lock(tree
, &lck
);
133 CHECK_STATUS(status
, NT_STATUS_FILE_CLOSED
);
134 lck
.in
.file
.handle
.data
[0] -=1;
136 lck
.in
.lock_count
= 0x0001;
137 lck
.in
.lock_sequence
= 0x123ab1;
138 lck
.in
.file
.handle
= h
;
139 el
[0].offset
= UINT64_MAX
;
140 el
[0].length
= UINT64_MAX
;
141 el
[0].reserved
= 0x00000000;
142 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
143 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
144 status
= smb2_lock(tree
, &lck
);
145 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture
)) {
146 CHECK_STATUS(status
, NT_STATUS_INVALID_LOCK_RANGE
);
148 CHECK_STATUS(status
, NT_STATUS_OK
);
149 CHECK_VALUE(lck
.out
.reserved
, 0);
152 lck
.in
.lock_sequence
= 0x123ab2;
153 status
= smb2_lock(tree
, &lck
);
154 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture
)) {
155 CHECK_STATUS(status
, NT_STATUS_INVALID_LOCK_RANGE
);
157 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
160 torture_comment(torture
, "Test basic lock stacking.\n");
162 lck
.in
.lock_count
= 0x0001;
163 lck
.in
.lock_sequence
= 0x12345678;
164 lck
.in
.file
.handle
= h
;
165 el
[0].offset
= UINT32_MAX
;
166 el
[0].length
= UINT32_MAX
;
167 el
[0].reserved
= 0x87654321;
168 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
169 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
170 status
= smb2_lock(tree
, &lck
);
171 CHECK_STATUS(status
, NT_STATUS_OK
);
172 CHECK_VALUE(lck
.out
.reserved
, 0);
174 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
;
175 status
= smb2_lock(tree
, &lck
);
176 CHECK_STATUS(status
, NT_STATUS_OK
);
177 CHECK_VALUE(lck
.out
.reserved
, 0);
179 status
= smb2_lock(tree
, &lck
);
180 CHECK_STATUS(status
, NT_STATUS_OK
);
181 CHECK_VALUE(lck
.out
.reserved
, 0);
183 lck
.in
.lock_count
= 0x0001;
184 lck
.in
.lock_sequence
= 0x87654321;
185 lck
.in
.file
.handle
= h
;
186 el
[0].offset
= 0x00000000FFFFFFFF;
187 el
[0].length
= 0x00000000FFFFFFFF;
188 el
[0].reserved
= 0x1234567;
189 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
190 status
= smb2_lock(tree
, &lck
);
191 CHECK_STATUS(status
, NT_STATUS_OK
);
193 lck
.in
.lock_count
= 0x0001;
194 lck
.in
.lock_sequence
= 0x1234567;
195 lck
.in
.file
.handle
= h
;
196 el
[0].offset
= 0x00000000FFFFFFFF;
197 el
[0].length
= 0x00000000FFFFFFFF;
198 el
[0].reserved
= 0x00000000;
199 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
200 status
= smb2_lock(tree
, &lck
);
201 CHECK_STATUS(status
, NT_STATUS_OK
);
203 status
= smb2_lock(tree
, &lck
);
204 CHECK_STATUS(status
, NT_STATUS_OK
);
205 status
= smb2_lock(tree
, &lck
);
206 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
208 torture_comment(torture
, "Test flags field permutations.\n");
210 lck
.in
.lock_count
= 0x0001;
211 lck
.in
.lock_sequence
= 0;
212 lck
.in
.file
.handle
= h
;
215 el
[0].reserved
= 0x00000000;
216 el
[0].flags
= ~SMB2_LOCK_FLAG_ALL_MASK
;
218 status
= smb2_lock(tree
, &lck
);
219 if (TARGET_IS_W2K8(torture
)) {
220 CHECK_STATUS(status
, NT_STATUS_OK
);
221 torture_warning(torture
, "Target has bug validating lock flags "
224 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
227 if (TARGET_IS_W2K8(torture
)) {
228 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
229 status
= smb2_lock(tree
, &lck
);
230 CHECK_STATUS(status
, NT_STATUS_OK
);
233 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
234 status
= smb2_lock(tree
, &lck
);
235 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
237 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
|
238 SMB2_LOCK_FLAG_EXCLUSIVE
;
239 status
= smb2_lock(tree
, &lck
);
240 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
242 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
|
243 SMB2_LOCK_FLAG_SHARED
;
244 status
= smb2_lock(tree
, &lck
);
245 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
247 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
|
248 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
249 status
= smb2_lock(tree
, &lck
);
250 if (TARGET_IS_W2K8(torture
)) {
251 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
252 torture_warning(torture
, "Target has bug validating lock flags "
255 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
258 torture_comment(torture
, "Test return error when 2 locks are "
261 lck
.in
.lock_count
= 2;
262 lck
.in
.lock_sequence
= 0;
263 lck
.in
.file
.handle
= h
;
266 el
[0].reserved
= 0x00000000;
269 el
[1].reserved
= 0x00000000;
271 lck
.in
.lock_count
= 2;
273 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
274 status
= smb2_lock(tree
, &lck
);
275 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
277 lck
.in
.lock_count
= 2;
278 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
279 el
[1].flags
= SMB2_LOCK_FLAG_SHARED
;
280 status
= smb2_lock(tree
, &lck
);
281 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
283 lck
.in
.lock_count
= 2;
286 status
= smb2_lock(tree
, &lck
);
287 if (TARGET_IS_W2K8(torture
)) {
288 CHECK_STATUS(status
, NT_STATUS_OK
);
289 torture_warning(torture
, "Target has bug validating lock flags "
292 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
295 lck
.in
.lock_count
= 2;
296 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
298 status
= smb2_lock(tree
, &lck
);
299 if (TARGET_IS_W2K8(torture
)) {
300 CHECK_STATUS(status
, NT_STATUS_OK
);
301 torture_warning(torture
, "Target has bug validating lock flags "
304 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
307 lck
.in
.lock_count
= 1;
308 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
309 status
= smb2_lock(tree
, &lck
);
310 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
312 lck
.in
.lock_count
= 1;
313 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
314 status
= smb2_lock(tree
, &lck
);
315 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
317 lck
.in
.lock_count
= 1;
318 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
319 status
= smb2_lock(tree
, &lck
);
320 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
322 lck
.in
.lock_count
= 1;
323 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
;
324 status
= smb2_lock(tree
, &lck
);
325 CHECK_STATUS(status
, NT_STATUS_OK
);
327 status
= smb2_lock(tree
, &lck
);
328 CHECK_STATUS(status
, NT_STATUS_OK
);
330 lck
.in
.lock_count
= 2;
331 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
332 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
333 status
= smb2_lock(tree
, &lck
);
334 CHECK_STATUS(status
, NT_STATUS_OK
);
336 lck
.in
.lock_count
= 1;
337 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
338 status
= smb2_lock(tree
, &lck
);
339 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
345 struct test_lock_read_write_state
{
348 NTSTATUS write_h1_status
;
349 NTSTATUS read_h1_status
;
350 NTSTATUS write_h2_status
;
351 NTSTATUS read_h2_status
;
354 static bool test_lock_read_write(struct torture_context
*torture
,
355 struct smb2_tree
*tree
,
356 struct test_lock_read_write_state
*s
)
360 struct smb2_handle h1
, h2
;
362 struct smb2_lock lck
;
363 struct smb2_create cr
;
364 struct smb2_write wr
;
366 struct smb2_lock_element el
[1];
372 status
= torture_smb2_testfile(tree
, s
->fname
, &h1
);
373 CHECK_STATUS(status
, NT_STATUS_OK
);
375 status
= smb2_util_write(tree
, h1
, buf
, 0, ARRAY_SIZE(buf
));
376 CHECK_STATUS(status
, NT_STATUS_OK
);
378 lck
.in
.lock_count
= 0x0001;
379 lck
.in
.lock_sequence
= 0x00000000;
380 lck
.in
.file
.handle
= h1
;
382 el
[0].length
= ARRAY_SIZE(buf
)/2;
383 el
[0].reserved
= 0x00000000;
384 el
[0].flags
= s
->lock_flags
;
385 status
= smb2_lock(tree
, &lck
);
386 CHECK_STATUS(status
, NT_STATUS_OK
);
387 CHECK_VALUE(lck
.out
.reserved
, 0);
389 lck
.in
.lock_count
= 0x0001;
390 lck
.in
.lock_sequence
= 0x00000000;
391 lck
.in
.file
.handle
= h1
;
392 el
[0].offset
= ARRAY_SIZE(buf
)/2;
393 el
[0].length
= ARRAY_SIZE(buf
)/2;
394 el
[0].reserved
= 0x00000000;
395 el
[0].flags
= s
->lock_flags
;
396 status
= smb2_lock(tree
, &lck
);
397 CHECK_STATUS(status
, NT_STATUS_OK
);
398 CHECK_VALUE(lck
.out
.reserved
, 0);
401 cr
.in
.oplock_level
= 0;
402 cr
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
403 cr
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
404 cr
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
406 NTCREATEX_SHARE_ACCESS_DELETE
|
407 NTCREATEX_SHARE_ACCESS_READ
|
408 NTCREATEX_SHARE_ACCESS_WRITE
;
409 cr
.in
.create_options
= 0;
410 cr
.in
.fname
= s
->fname
;
412 status
= smb2_create(tree
, tree
, &cr
);
413 CHECK_STATUS(status
, NT_STATUS_OK
);
415 h2
= cr
.out
.file
.handle
;
418 wr
.in
.file
.handle
= h1
;
419 wr
.in
.offset
= ARRAY_SIZE(buf
)/2;
420 wr
.in
.data
= data_blob_const(buf
, ARRAY_SIZE(buf
)/2);
422 status
= smb2_write(tree
, &wr
);
423 CHECK_STATUS(status
, s
->write_h1_status
);
426 rd
.in
.file
.handle
= h1
;
427 rd
.in
.offset
= ARRAY_SIZE(buf
)/2;
428 rd
.in
.length
= ARRAY_SIZE(buf
)/2;
430 status
= smb2_read(tree
, tree
, &rd
);
431 CHECK_STATUS(status
, s
->read_h1_status
);
434 wr
.in
.file
.handle
= h2
;
435 wr
.in
.offset
= ARRAY_SIZE(buf
)/2;
436 wr
.in
.data
= data_blob_const(buf
, ARRAY_SIZE(buf
)/2);
438 status
= smb2_write(tree
, &wr
);
439 CHECK_STATUS(status
, s
->write_h2_status
);
442 rd
.in
.file
.handle
= h2
;
443 rd
.in
.offset
= ARRAY_SIZE(buf
)/2;
444 rd
.in
.length
= ARRAY_SIZE(buf
)/2;
446 status
= smb2_read(tree
, tree
, &rd
);
447 CHECK_STATUS(status
, s
->read_h2_status
);
449 lck
.in
.lock_count
= 0x0001;
450 lck
.in
.lock_sequence
= 0x00000000;
451 lck
.in
.file
.handle
= h1
;
452 el
[0].offset
= ARRAY_SIZE(buf
)/2;
453 el
[0].length
= ARRAY_SIZE(buf
)/2;
454 el
[0].reserved
= 0x00000000;
455 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
456 status
= smb2_lock(tree
, &lck
);
457 CHECK_STATUS(status
, NT_STATUS_OK
);
458 CHECK_VALUE(lck
.out
.reserved
, 0);
461 wr
.in
.file
.handle
= h2
;
462 wr
.in
.offset
= ARRAY_SIZE(buf
)/2;
463 wr
.in
.data
= data_blob_const(buf
, ARRAY_SIZE(buf
)/2);
465 status
= smb2_write(tree
, &wr
);
466 CHECK_STATUS(status
, NT_STATUS_OK
);
469 rd
.in
.file
.handle
= h2
;
470 rd
.in
.offset
= ARRAY_SIZE(buf
)/2;
471 rd
.in
.length
= ARRAY_SIZE(buf
)/2;
473 status
= smb2_read(tree
, tree
, &rd
);
474 CHECK_STATUS(status
, NT_STATUS_OK
);
480 static bool test_lock_rw_none(struct torture_context
*torture
,
481 struct smb2_tree
*tree
)
483 struct test_lock_read_write_state s
= {
484 .fname
= "lock_rw_none.dat",
485 .lock_flags
= SMB2_LOCK_FLAG_NONE
,
486 .write_h1_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
487 .read_h1_status
= NT_STATUS_OK
,
488 .write_h2_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
489 .read_h2_status
= NT_STATUS_OK
,
492 if (!TARGET_IS_W2K8(torture
)) {
493 torture_skip(torture
, "RW-NONE tests the behavior of a "
494 "NONE-type lock, which is the same as a SHARED "
495 "lock but is granted due to a bug in W2K8. If "
496 "target is not W2K8 we skip this test.\n");
499 return test_lock_read_write(torture
, tree
, &s
);
502 static bool test_lock_rw_shared(struct torture_context
*torture
,
503 struct smb2_tree
*tree
)
505 struct test_lock_read_write_state s
= {
506 .fname
= "lock_rw_shared.dat",
507 .lock_flags
= SMB2_LOCK_FLAG_SHARED
,
508 .write_h1_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
509 .read_h1_status
= NT_STATUS_OK
,
510 .write_h2_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
511 .read_h2_status
= NT_STATUS_OK
,
514 return test_lock_read_write(torture
, tree
, &s
);
517 static bool test_lock_rw_exclusive(struct torture_context
*torture
,
518 struct smb2_tree
*tree
)
520 struct test_lock_read_write_state s
= {
521 .fname
= "lock_rw_exclusive.dat",
522 .lock_flags
= SMB2_LOCK_FLAG_EXCLUSIVE
,
523 .write_h1_status
= NT_STATUS_OK
,
524 .read_h1_status
= NT_STATUS_OK
,
525 .write_h2_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
526 .read_h2_status
= NT_STATUS_FILE_LOCK_CONFLICT
,
529 return test_lock_read_write(torture
, tree
, &s
);
532 static bool test_lock_auto_unlock(struct torture_context
*torture
,
533 struct smb2_tree
*tree
)
537 struct smb2_handle h
;
539 struct smb2_lock lck
;
540 struct smb2_lock_element el
[1];
544 status
= torture_smb2_testfile(tree
, "autounlock.txt", &h
);
545 CHECK_STATUS(status
, NT_STATUS_OK
);
547 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
548 CHECK_STATUS(status
, NT_STATUS_OK
);
553 lck
.in
.lock_count
= 0x0001;
554 lck
.in
.file
.handle
= h
;
557 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
558 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
559 status
= smb2_lock(tree
, &lck
);
560 CHECK_STATUS(status
, NT_STATUS_OK
);
562 status
= smb2_lock(tree
, &lck
);
563 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
565 status
= smb2_lock(tree
, &lck
);
566 if (TARGET_IS_W2K8(torture
)) {
567 CHECK_STATUS(status
, NT_STATUS_OK
);
568 torture_warning(torture
, "Target has \"pretty please\" bug. "
569 "A contending lock request on the same handle "
570 "unlocks the lock.\n");
572 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
575 status
= smb2_lock(tree
, &lck
);
576 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
583 test different lock ranges and see if different handles conflict
585 static bool test_lock(struct torture_context
*torture
,
586 struct smb2_tree
*tree
)
590 struct smb2_handle h
= {{0}};
591 struct smb2_handle h2
= {{0}};
593 struct smb2_lock lck
;
594 struct smb2_lock_element el
[2];
596 const char *fname
= BASEDIR
"\\async.txt";
598 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
599 CHECK_STATUS(status
, NT_STATUS_OK
);
600 smb2_util_close(tree
, h
);
602 status
= torture_smb2_testfile(tree
, fname
, &h
);
603 CHECK_STATUS(status
, NT_STATUS_OK
);
606 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
607 CHECK_STATUS(status
, NT_STATUS_OK
);
609 status
= torture_smb2_testfile(tree
, fname
, &h2
);
610 CHECK_STATUS(status
, NT_STATUS_OK
);
614 lck
.in
.lock_count
= 0x0001;
615 lck
.in
.lock_sequence
= 0x00000000;
616 lck
.in
.file
.handle
= h
;
617 el
[0].reserved
= 0x00000000;
618 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
619 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
621 torture_comment(torture
, "Trying 0/0 lock\n");
622 el
[0].offset
= 0x0000000000000000;
623 el
[0].length
= 0x0000000000000000;
624 status
= smb2_lock(tree
, &lck
);
625 CHECK_STATUS(status
, NT_STATUS_OK
);
626 lck
.in
.file
.handle
= h2
;
627 status
= smb2_lock(tree
, &lck
);
628 CHECK_STATUS(status
, NT_STATUS_OK
);
629 lck
.in
.file
.handle
= h
;
630 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
631 status
= smb2_lock(tree
, &lck
);
632 CHECK_STATUS(status
, NT_STATUS_OK
);
634 torture_comment(torture
, "Trying 0/1 lock\n");
635 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
636 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
637 el
[0].offset
= 0x0000000000000000;
638 el
[0].length
= 0x0000000000000001;
639 status
= smb2_lock(tree
, &lck
);
640 CHECK_STATUS(status
, NT_STATUS_OK
);
641 lck
.in
.file
.handle
= h2
;
642 status
= smb2_lock(tree
, &lck
);
643 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
644 lck
.in
.file
.handle
= h
;
645 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
646 status
= smb2_lock(tree
, &lck
);
647 CHECK_STATUS(status
, NT_STATUS_OK
);
648 status
= smb2_lock(tree
, &lck
);
649 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
651 torture_comment(torture
, "Trying 0xEEFFFFF lock\n");
652 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
653 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
654 el
[0].offset
= 0xEEFFFFFF;
656 status
= smb2_lock(tree
, &lck
);
657 CHECK_STATUS(status
, NT_STATUS_OK
);
658 lck
.in
.file
.handle
= h2
;
659 status
= smb2_lock(tree
, &lck
);
660 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
661 lck
.in
.file
.handle
= h
;
662 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
663 status
= smb2_lock(tree
, &lck
);
664 CHECK_STATUS(status
, NT_STATUS_OK
);
665 status
= smb2_lock(tree
, &lck
);
666 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
668 torture_comment(torture
, "Trying 0xEF00000 lock\n");
669 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
670 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
671 el
[0].offset
= 0xEF000000;
673 status
= smb2_lock(tree
, &lck
);
674 CHECK_STATUS(status
, NT_STATUS_OK
);
675 lck
.in
.file
.handle
= h2
;
676 status
= smb2_lock(tree
, &lck
);
677 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
678 lck
.in
.file
.handle
= h
;
679 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
680 status
= smb2_lock(tree
, &lck
);
681 CHECK_STATUS(status
, NT_STATUS_OK
);
682 status
= smb2_lock(tree
, &lck
);
683 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
685 torture_comment(torture
, "Trying (2^63 - 1)/1\n");
686 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
687 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
692 status
= smb2_lock(tree
, &lck
);
693 CHECK_STATUS(status
, NT_STATUS_OK
);
694 lck
.in
.file
.handle
= h2
;
695 status
= smb2_lock(tree
, &lck
);
696 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
697 lck
.in
.file
.handle
= h
;
698 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
699 status
= smb2_lock(tree
, &lck
);
700 CHECK_STATUS(status
, NT_STATUS_OK
);
701 status
= smb2_lock(tree
, &lck
);
702 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
704 torture_comment(torture
, "Trying 2^63/1\n");
705 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
706 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
710 status
= smb2_lock(tree
, &lck
);
711 CHECK_STATUS(status
, NT_STATUS_OK
);
712 lck
.in
.file
.handle
= h2
;
713 status
= smb2_lock(tree
, &lck
);
714 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
715 lck
.in
.file
.handle
= h
;
716 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
717 status
= smb2_lock(tree
, &lck
);
718 CHECK_STATUS(status
, NT_STATUS_OK
);
719 status
= smb2_lock(tree
, &lck
);
720 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
722 torture_comment(torture
, "Trying max/0 lock\n");
723 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
724 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
727 status
= smb2_lock(tree
, &lck
);
728 CHECK_STATUS(status
, NT_STATUS_OK
);
729 lck
.in
.file
.handle
= h2
;
730 status
= smb2_lock(tree
, &lck
);
731 CHECK_STATUS(status
, NT_STATUS_OK
);
732 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
733 status
= smb2_lock(tree
, &lck
);
734 CHECK_STATUS(status
, NT_STATUS_OK
);
735 lck
.in
.file
.handle
= h
;
736 status
= smb2_lock(tree
, &lck
);
737 CHECK_STATUS(status
, NT_STATUS_OK
);
738 status
= smb2_lock(tree
, &lck
);
739 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
741 torture_comment(torture
, "Trying max/1 lock\n");
742 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
743 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
746 status
= smb2_lock(tree
, &lck
);
747 CHECK_STATUS(status
, NT_STATUS_OK
);
748 lck
.in
.file
.handle
= h2
;
749 status
= smb2_lock(tree
, &lck
);
750 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
751 lck
.in
.file
.handle
= h
;
752 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
753 status
= smb2_lock(tree
, &lck
);
754 CHECK_STATUS(status
, NT_STATUS_OK
);
755 status
= smb2_lock(tree
, &lck
);
756 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
758 torture_comment(torture
, "Trying max/2 lock\n");
759 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
760 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
763 status
= smb2_lock(tree
, &lck
);
764 if (TARGET_SUPPORTS_INVALID_LOCK_RANGE(torture
)) {
765 CHECK_STATUS(status
, NT_STATUS_INVALID_LOCK_RANGE
);
767 CHECK_STATUS(status
, NT_STATUS_OK
);
768 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
769 status
= smb2_lock(tree
, &lck
);
770 CHECK_STATUS(status
, NT_STATUS_OK
);
773 torture_comment(torture
, "Trying wrong handle unlock\n");
774 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
775 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
776 el
[0].offset
= 10001;
777 el
[0].length
= 40002;
778 status
= smb2_lock(tree
, &lck
);
779 CHECK_STATUS(status
, NT_STATUS_OK
);
780 lck
.in
.file
.handle
= h2
;
781 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
782 status
= smb2_lock(tree
, &lck
);
783 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
784 lck
.in
.file
.handle
= h
;
785 status
= smb2_lock(tree
, &lck
);
786 CHECK_STATUS(status
, NT_STATUS_OK
);
789 smb2_util_close(tree
, h2
);
790 smb2_util_close(tree
, h
);
791 smb2_deltree(tree
, BASEDIR
);
796 test SMB2 LOCK async operation
798 static bool test_async(struct torture_context
*torture
,
799 struct smb2_tree
*tree
)
803 struct smb2_handle h
= {{0}};
804 struct smb2_handle h2
= {{0}};
806 struct smb2_lock lck
;
807 struct smb2_lock_element el
[2];
808 struct smb2_request
*req
= NULL
;
810 const char *fname
= BASEDIR
"\\async.txt";
812 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
813 CHECK_STATUS(status
, NT_STATUS_OK
);
814 smb2_util_close(tree
, h
);
816 status
= torture_smb2_testfile(tree
, fname
, &h
);
817 CHECK_STATUS(status
, NT_STATUS_OK
);
820 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
821 CHECK_STATUS(status
, NT_STATUS_OK
);
823 status
= torture_smb2_testfile(tree
, fname
, &h2
);
824 CHECK_STATUS(status
, NT_STATUS_OK
);
828 lck
.in
.lock_count
= 0x0001;
829 lck
.in
.lock_sequence
= 0x00000000;
830 lck
.in
.file
.handle
= h
;
833 el
[0].reserved
= 0x00000000;
834 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
836 torture_comment(torture
, " Acquire first lock\n");
837 status
= smb2_lock(tree
, &lck
);
838 CHECK_STATUS(status
, NT_STATUS_OK
);
840 torture_comment(torture
, " Second lock should pend on first\n");
841 lck
.in
.file
.handle
= h2
;
842 req
= smb2_lock_send(tree
, &lck
);
843 WAIT_FOR_ASYNC_RESPONSE(req
);
845 torture_comment(torture
, " Unlock first lock\n");
846 lck
.in
.file
.handle
= h
;
847 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
848 status
= smb2_lock(tree
, &lck
);
849 CHECK_STATUS(status
, NT_STATUS_OK
);
851 torture_comment(torture
, " Second lock should now succeed\n");
852 lck
.in
.file
.handle
= h2
;
853 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
854 status
= smb2_lock_recv(req
, &lck
);
855 CHECK_STATUS(status
, NT_STATUS_OK
);
858 smb2_util_close(tree
, h2
);
859 smb2_util_close(tree
, h
);
860 smb2_deltree(tree
, BASEDIR
);
865 test SMB2 LOCK Cancel operation
867 static bool test_cancel(struct torture_context
*torture
,
868 struct smb2_tree
*tree
)
872 struct smb2_handle h
= {{0}};
873 struct smb2_handle h2
= {{0}};
875 struct smb2_lock lck
;
876 struct smb2_lock_element el
[2];
877 struct smb2_request
*req
= NULL
;
879 const char *fname
= BASEDIR
"\\cancel.txt";
881 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
882 CHECK_STATUS(status
, NT_STATUS_OK
);
883 smb2_util_close(tree
, h
);
885 status
= torture_smb2_testfile(tree
, fname
, &h
);
886 CHECK_STATUS(status
, NT_STATUS_OK
);
889 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
890 CHECK_STATUS(status
, NT_STATUS_OK
);
892 status
= torture_smb2_testfile(tree
, fname
, &h2
);
893 CHECK_STATUS(status
, NT_STATUS_OK
);
897 lck
.in
.lock_count
= 0x0001;
898 lck
.in
.lock_sequence
= 0x00000000;
899 lck
.in
.file
.handle
= h
;
902 el
[0].reserved
= 0x00000000;
903 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
905 torture_comment(torture
, "Testing basic cancel\n");
907 torture_comment(torture
, " Acquire first lock\n");
908 status
= smb2_lock(tree
, &lck
);
909 CHECK_STATUS(status
, NT_STATUS_OK
);
911 torture_comment(torture
, " Second lock should pend on first\n");
912 lck
.in
.file
.handle
= h2
;
913 req
= smb2_lock_send(tree
, &lck
);
914 WAIT_FOR_ASYNC_RESPONSE(req
);
916 torture_comment(torture
, " Cancel the second lock\n");
918 lck
.in
.file
.handle
= h2
;
919 status
= smb2_lock_recv(req
, &lck
);
920 CHECK_STATUS(status
, NT_STATUS_CANCELLED
);
922 torture_comment(torture
, " Unlock first lock\n");
923 lck
.in
.file
.handle
= h
;
924 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
925 status
= smb2_lock(tree
, &lck
);
926 CHECK_STATUS(status
, NT_STATUS_OK
);
929 torture_comment(torture
, "Testing cancel by unlock\n");
931 torture_comment(torture
, " Acquire first lock\n");
932 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
933 status
= smb2_lock(tree
, &lck
);
934 CHECK_STATUS(status
, NT_STATUS_OK
);
936 torture_comment(torture
, " Second lock should pend on first\n");
937 lck
.in
.file
.handle
= h2
;
938 req
= smb2_lock_send(tree
, &lck
);
939 WAIT_FOR_ASYNC_RESPONSE(req
);
941 torture_comment(torture
, " Attempt to unlock pending second lock\n");
942 lck
.in
.file
.handle
= h2
;
943 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
944 status
= smb2_lock(tree
, &lck
);
945 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
947 torture_comment(torture
, " Now cancel the second lock\n");
949 lck
.in
.file
.handle
= h2
;
950 status
= smb2_lock_recv(req
, &lck
);
951 CHECK_STATUS(status
, NT_STATUS_CANCELLED
);
953 torture_comment(torture
, " Unlock first lock\n");
954 lck
.in
.file
.handle
= h
;
955 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
956 status
= smb2_lock(tree
, &lck
);
957 CHECK_STATUS(status
, NT_STATUS_OK
);
960 torture_comment(torture
, "Testing cancel by close\n");
962 torture_comment(torture
, " Acquire first lock\n");
963 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
964 status
= smb2_lock(tree
, &lck
);
965 CHECK_STATUS(status
, NT_STATUS_OK
);
967 torture_comment(torture
, " Second lock should pend on first\n");
968 lck
.in
.file
.handle
= h2
;
969 req
= smb2_lock_send(tree
, &lck
);
970 WAIT_FOR_ASYNC_RESPONSE(req
);
972 torture_comment(torture
, " Close the second lock handle\n");
973 smb2_util_close(tree
, h2
);
974 CHECK_STATUS(status
, NT_STATUS_OK
);
976 torture_comment(torture
, " Check pending lock reply\n");
977 status
= smb2_lock_recv(req
, &lck
);
978 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
980 torture_comment(torture
, " Unlock first lock\n");
981 lck
.in
.file
.handle
= h
;
982 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
983 status
= smb2_lock(tree
, &lck
);
984 CHECK_STATUS(status
, NT_STATUS_OK
);
987 smb2_util_close(tree
, h2
);
988 smb2_util_close(tree
, h
);
989 smb2_deltree(tree
, BASEDIR
);
994 test SMB2 LOCK Cancel by tree disconnect
996 static bool test_cancel_tdis(struct torture_context
*torture
,
997 struct smb2_tree
*tree
)
1001 struct smb2_handle h
= {{0}};
1002 struct smb2_handle h2
= {{0}};
1004 struct smb2_lock lck
;
1005 struct smb2_lock_element el
[2];
1006 struct smb2_request
*req
= NULL
;
1008 const char *fname
= BASEDIR
"\\cancel_tdis.txt";
1010 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1011 CHECK_STATUS(status
, NT_STATUS_OK
);
1012 smb2_util_close(tree
, h
);
1014 status
= torture_smb2_testfile(tree
, fname
, &h
);
1015 CHECK_STATUS(status
, NT_STATUS_OK
);
1018 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1019 CHECK_STATUS(status
, NT_STATUS_OK
);
1021 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1022 CHECK_STATUS(status
, NT_STATUS_OK
);
1026 lck
.in
.lock_count
= 0x0001;
1027 lck
.in
.lock_sequence
= 0x00000000;
1028 lck
.in
.file
.handle
= h
;
1031 el
[0].reserved
= 0x00000000;
1032 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
1034 torture_comment(torture
, "Testing cancel by tree disconnect\n");
1036 status
= torture_smb2_testfile(tree
, fname
, &h
);
1037 CHECK_STATUS(status
, NT_STATUS_OK
);
1039 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1040 CHECK_STATUS(status
, NT_STATUS_OK
);
1042 torture_comment(torture
, " Acquire first lock\n");
1043 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
1044 status
= smb2_lock(tree
, &lck
);
1045 CHECK_STATUS(status
, NT_STATUS_OK
);
1047 torture_comment(torture
, " Second lock should pend on first\n");
1048 lck
.in
.file
.handle
= h2
;
1049 req
= smb2_lock_send(tree
, &lck
);
1050 WAIT_FOR_ASYNC_RESPONSE(req
);
1052 torture_comment(torture
, " Disconnect the tree\n");
1054 CHECK_STATUS(status
, NT_STATUS_OK
);
1056 torture_comment(torture
, " Check pending lock reply\n");
1057 status
= smb2_lock_recv(req
, &lck
);
1058 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RANGE_NOT_LOCKED
)) {
1060 * The status depends on the server internals
1061 * the order in which the files are closed
1064 CHECK_STATUS(status
, NT_STATUS_OK
);
1067 torture_comment(torture
, " Attempt to unlock first lock\n");
1068 lck
.in
.file
.handle
= h
;
1069 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1070 status
= smb2_lock(tree
, &lck
);
1072 * Most Windows versions have a strange order to
1073 * verify the session id, tree id and file id.
1074 * (They should be checked in that order, but windows
1075 * seems to check the file id before the others).
1077 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_NAME_DELETED
)) {
1078 CHECK_STATUS(status
, NT_STATUS_FILE_CLOSED
);
1082 smb2_util_close(tree
, h2
);
1083 smb2_util_close(tree
, h
);
1084 smb2_deltree(tree
, BASEDIR
);
1089 test SMB2 LOCK Cancel by user logoff
1091 static bool test_cancel_logoff(struct torture_context
*torture
,
1092 struct smb2_tree
*tree
)
1096 struct smb2_handle h
= {{0}};
1097 struct smb2_handle h2
= {{0}};
1099 struct smb2_lock lck
;
1100 struct smb2_lock_element el
[2];
1101 struct smb2_request
*req
= NULL
;
1103 const char *fname
= BASEDIR
"\\cancel_logoff.txt";
1105 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1106 CHECK_STATUS(status
, NT_STATUS_OK
);
1107 smb2_util_close(tree
, h
);
1109 status
= torture_smb2_testfile(tree
, fname
, &h
);
1110 CHECK_STATUS(status
, NT_STATUS_OK
);
1113 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1114 CHECK_STATUS(status
, NT_STATUS_OK
);
1116 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1117 CHECK_STATUS(status
, NT_STATUS_OK
);
1121 lck
.in
.lock_count
= 0x0001;
1122 lck
.in
.lock_sequence
= 0x00000000;
1123 lck
.in
.file
.handle
= h
;
1126 el
[0].reserved
= 0x00000000;
1127 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
1129 torture_comment(torture
, "Testing cancel by ulogoff\n");
1131 torture_comment(torture
, " Acquire first lock\n");
1132 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
1133 status
= smb2_lock(tree
, &lck
);
1134 CHECK_STATUS(status
, NT_STATUS_OK
);
1136 torture_comment(torture
, " Second lock should pend on first\n");
1137 lck
.in
.file
.handle
= h2
;
1138 req
= smb2_lock_send(tree
, &lck
);
1139 WAIT_FOR_ASYNC_RESPONSE(req
);
1141 torture_comment(torture
, " Logoff user\n");
1142 smb2_logoff(tree
->session
);
1144 torture_comment(torture
, " Check pending lock reply\n");
1145 status
= smb2_lock_recv(req
, &lck
);
1146 if (!NT_STATUS_EQUAL(status
, NT_STATUS_RANGE_NOT_LOCKED
)) {
1148 * The status depends on the server internals
1149 * the order in which the files are closed
1152 CHECK_STATUS(status
, NT_STATUS_OK
);
1155 torture_comment(torture
, " Attempt to unlock first lock\n");
1156 lck
.in
.file
.handle
= h
;
1157 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1158 status
= smb2_lock(tree
, &lck
);
1160 * Most Windows versions have a strange order to
1161 * verify the session id, tree id and file id.
1162 * (They should be checked in that order, but windows
1163 * seems to check the file id before the others).
1165 if (!NT_STATUS_EQUAL(status
, NT_STATUS_USER_SESSION_DELETED
)) {
1166 CHECK_STATUS(status
, NT_STATUS_FILE_CLOSED
);
1170 smb2_util_close(tree
, h2
);
1171 smb2_util_close(tree
, h
);
1172 smb2_deltree(tree
, BASEDIR
);
1177 * Test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
1179 * The SMBv1 protocol returns a different error code on lock acquisition
1180 * failure depending on a number of parameters, including what error code
1181 * was returned to the previous failure.
1183 * SMBv2 has cleaned up these semantics and should always return
1184 * NT_STATUS_LOCK_NOT_GRANTED to failed lock requests, and
1185 * NT_STATUS_FILE_LOCK_CONFLICT to failed read/write requests due to a lock
1186 * being held on that range.
1188 static bool test_errorcode(struct torture_context
*torture
,
1189 struct smb2_tree
*tree
)
1193 struct smb2_handle h
= {{0}};
1194 struct smb2_handle h2
= {{0}};
1196 struct smb2_lock lck
;
1197 struct smb2_lock_element el
[2];
1199 const char *fname
= BASEDIR
"\\errorcode.txt";
1201 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1202 CHECK_STATUS(status
, NT_STATUS_OK
);
1203 smb2_util_close(tree
, h
);
1205 status
= torture_smb2_testfile(tree
, fname
, &h
);
1206 CHECK_STATUS(status
, NT_STATUS_OK
);
1209 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1210 CHECK_STATUS(status
, NT_STATUS_OK
);
1212 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1213 CHECK_STATUS(status
, NT_STATUS_OK
);
1217 lck
.in
.lock_count
= 0x0001;
1218 lck
.in
.lock_sequence
= 0x00000000;
1219 lck
.in
.file
.handle
= h
;
1222 el
[0].reserved
= 0x00000000;
1223 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1224 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1226 torture_comment(torture
, "Testing LOCK_NOT_GRANTED vs. "
1227 "FILE_LOCK_CONFLICT\n");
1229 if (TARGET_IS_W2K8(torture
)) {
1230 torture_result(torture
, TORTURE_SKIP
,
1231 "Target has \"pretty please\" bug. A contending lock "
1232 "request on the same handle unlocks the lock.");
1236 status
= smb2_lock(tree
, &lck
);
1237 CHECK_STATUS(status
, NT_STATUS_OK
);
1239 /* Demonstrate that the first conflicting lock on each handle gives
1240 * LOCK_NOT_GRANTED. */
1241 lck
.in
.file
.handle
= h
;
1242 status
= smb2_lock(tree
, &lck
);
1243 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1245 lck
.in
.file
.handle
= h2
;
1246 status
= smb2_lock(tree
, &lck
);
1247 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1249 /* Demonstrate that each following conflict also gives
1250 * LOCK_NOT_GRANTED */
1251 lck
.in
.file
.handle
= h
;
1252 status
= smb2_lock(tree
, &lck
);
1253 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1255 lck
.in
.file
.handle
= h2
;
1256 status
= smb2_lock(tree
, &lck
);
1257 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
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 the smbpid doesn't matter */
1268 lck
.in
.file
.handle
= h
;
1269 status
= smb2_lock(tree
, &lck
);
1270 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1272 lck
.in
.file
.handle
= h2
;
1273 status
= smb2_lock(tree
, &lck
);
1274 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1276 /* Demonstrate that a 0-byte lock inside the locked range still
1277 * gives the same error. */
1281 lck
.in
.file
.handle
= h
;
1282 status
= smb2_lock(tree
, &lck
);
1283 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1285 lck
.in
.file
.handle
= h2
;
1286 status
= smb2_lock(tree
, &lck
);
1287 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1289 /* Demonstrate that a lock inside the locked range still gives the
1294 lck
.in
.file
.handle
= h
;
1295 status
= smb2_lock(tree
, &lck
);
1296 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1298 lck
.in
.file
.handle
= h2
;
1299 status
= smb2_lock(tree
, &lck
);
1300 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1303 smb2_util_close(tree
, h2
);
1304 smb2_util_close(tree
, h
);
1305 smb2_deltree(tree
, BASEDIR
);
1310 * Tests zero byte locks.
1313 struct double_lock_test
{
1314 struct smb2_lock_element lock1
;
1315 struct smb2_lock_element lock2
;
1319 static struct double_lock_test zero_byte_tests
[] = {
1320 /* {offset, count, reserved, flags},
1321 * {offset, count, reserved, flags},
1324 /** First, takes a zero byte lock at offset 10. Then:
1325 * - Taking 0 byte lock at 10 should succeed.
1326 * - Taking 1 byte locks at 9,10,11 should succeed.
1327 * - Taking 2 byte lock at 9 should fail.
1328 * - Taking 2 byte lock at 10 should succeed.
1329 * - Taking 3 byte lock at 9 should fail.
1331 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1332 {{10, 0, 0, 0}, {9, 1, 0, 0}, NT_STATUS_OK
},
1333 {{10, 0, 0, 0}, {10, 1, 0, 0}, NT_STATUS_OK
},
1334 {{10, 0, 0, 0}, {11, 1, 0, 0}, NT_STATUS_OK
},
1335 {{10, 0, 0, 0}, {9, 2, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED
},
1336 {{10, 0, 0, 0}, {10, 2, 0, 0}, NT_STATUS_OK
},
1337 {{10, 0, 0, 0}, {9, 3, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED
},
1339 /** Same, but opposite order. */
1340 {{10, 0, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1341 {{9, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1342 {{10, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1343 {{11, 1, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1344 {{9, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED
},
1345 {{10, 2, 0, 0}, {10, 0, 0, 0}, NT_STATUS_OK
},
1346 {{9, 3, 0, 0}, {10, 0, 0, 0}, NT_STATUS_LOCK_NOT_GRANTED
},
1348 /** Zero zero case. */
1349 {{0, 0, 0, 0}, {0, 0, 0, 0}, NT_STATUS_OK
},
1352 static bool test_zerobytelength(struct torture_context
*torture
,
1353 struct smb2_tree
*tree
)
1357 struct smb2_handle h
= {{0}};
1358 struct smb2_handle h2
= {{0}};
1360 struct smb2_lock lck
;
1363 const char *fname
= BASEDIR
"\\zero.txt";
1365 torture_comment(torture
, "Testing zero length byte range locks:\n");
1367 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1368 CHECK_STATUS(status
, NT_STATUS_OK
);
1369 smb2_util_close(tree
, h
);
1371 status
= torture_smb2_testfile(tree
, fname
, &h
);
1372 CHECK_STATUS(status
, NT_STATUS_OK
);
1375 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1376 CHECK_STATUS(status
, NT_STATUS_OK
);
1378 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1379 CHECK_STATUS(status
, NT_STATUS_OK
);
1381 /* Setup initial parameters */
1382 lck
.in
.lock_count
= 0x0001;
1383 lck
.in
.lock_sequence
= 0x00000000;
1384 lck
.in
.file
.handle
= h
;
1386 /* Try every combination of locks in zero_byte_tests, using the same
1387 * handle for both locks. The first lock is assumed to succeed. The
1388 * second lock may contend, depending on the expected status. */
1389 for (i
= 0; i
< ARRAY_SIZE(zero_byte_tests
); i
++) {
1390 torture_comment(torture
,
1391 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1392 (unsigned long long) zero_byte_tests
[i
].lock1
.offset
,
1393 (unsigned long long) zero_byte_tests
[i
].lock1
.length
,
1394 (unsigned long long) zero_byte_tests
[i
].lock2
.offset
,
1395 (unsigned long long) zero_byte_tests
[i
].lock2
.length
,
1396 nt_errstr(zero_byte_tests
[i
].status
));
1398 /* Lock both locks. */
1399 lck
.in
.locks
= &zero_byte_tests
[i
].lock1
;
1400 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1401 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1402 status
= smb2_lock(tree
, &lck
);
1403 CHECK_STATUS(status
, NT_STATUS_OK
);
1405 lck
.in
.locks
= &zero_byte_tests
[i
].lock2
;
1406 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1407 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1408 status
= smb2_lock(tree
, &lck
);
1409 CHECK_STATUS_CONT(status
, zero_byte_tests
[i
].status
);
1411 /* Unlock both locks in reverse order. */
1412 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1413 if (NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
1414 status
= smb2_lock(tree
, &lck
);
1415 CHECK_STATUS(status
, NT_STATUS_OK
);
1418 lck
.in
.locks
= &zero_byte_tests
[i
].lock1
;
1419 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1420 status
= smb2_lock(tree
, &lck
);
1421 CHECK_STATUS(status
, NT_STATUS_OK
);
1424 /* Try every combination of locks in zero_byte_tests, using two
1425 * different handles. */
1426 for (i
= 0; i
< ARRAY_SIZE(zero_byte_tests
); i
++) {
1427 torture_comment(torture
,
1428 " ... {%llu, %llu} + {%llu, %llu} = %s\n",
1429 (unsigned long long) zero_byte_tests
[i
].lock1
.offset
,
1430 (unsigned long long) zero_byte_tests
[i
].lock1
.length
,
1431 (unsigned long long) zero_byte_tests
[i
].lock2
.offset
,
1432 (unsigned long long) zero_byte_tests
[i
].lock2
.length
,
1433 nt_errstr(zero_byte_tests
[i
].status
));
1435 /* Lock both locks. */
1436 lck
.in
.file
.handle
= h
;
1437 lck
.in
.locks
= &zero_byte_tests
[i
].lock1
;
1438 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1439 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1440 status
= smb2_lock(tree
, &lck
);
1441 CHECK_STATUS(status
, NT_STATUS_OK
);
1443 lck
.in
.file
.handle
= h2
;
1444 lck
.in
.locks
= &zero_byte_tests
[i
].lock2
;
1445 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1446 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1447 status
= smb2_lock(tree
, &lck
);
1448 CHECK_STATUS_CONT(status
, zero_byte_tests
[i
].status
);
1450 /* Unlock both locks in reverse order. */
1451 lck
.in
.file
.handle
= h2
;
1452 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1453 if (NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
1454 status
= smb2_lock(tree
, &lck
);
1455 CHECK_STATUS(status
, NT_STATUS_OK
);
1458 lck
.in
.file
.handle
= h
;
1459 lck
.in
.locks
= &zero_byte_tests
[i
].lock1
;
1460 lck
.in
.locks
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1461 status
= smb2_lock(tree
, &lck
);
1462 CHECK_STATUS(status
, NT_STATUS_OK
);
1466 smb2_util_close(tree
, h2
);
1467 smb2_util_close(tree
, h
);
1468 smb2_deltree(tree
, BASEDIR
);
1472 static bool test_zerobyteread(struct torture_context
*torture
,
1473 struct smb2_tree
*tree
)
1477 struct smb2_handle h
= {{0}};
1478 struct smb2_handle h2
= {{0}};
1480 struct smb2_lock lck
;
1481 struct smb2_lock_element el
[1];
1482 struct smb2_read rd
;
1484 const char *fname
= BASEDIR
"\\zerobyteread.txt";
1486 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1487 CHECK_STATUS(status
, NT_STATUS_OK
);
1488 smb2_util_close(tree
, h
);
1490 status
= torture_smb2_testfile(tree
, fname
, &h
);
1491 CHECK_STATUS(status
, NT_STATUS_OK
);
1494 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1495 CHECK_STATUS(status
, NT_STATUS_OK
);
1497 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1498 CHECK_STATUS(status
, NT_STATUS_OK
);
1500 /* Setup initial parameters */
1502 lck
.in
.lock_count
= 0x0001;
1503 lck
.in
.lock_sequence
= 0x00000000;
1504 lck
.in
.file
.handle
= h
;
1507 rd
.in
.file
.handle
= h2
;
1509 torture_comment(torture
, "Testing zero byte read on lock range:\n");
1511 /* Take an exclusive lock */
1512 torture_comment(torture
, " taking exclusive lock.\n");
1515 el
[0].reserved
= 0x00000000;
1516 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1517 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1518 status
= smb2_lock(tree
, &lck
);
1519 CHECK_STATUS(status
, NT_STATUS_OK
);
1520 CHECK_VALUE(lck
.out
.reserved
, 0);
1522 /* Try a zero byte read */
1523 torture_comment(torture
, " reading 0 bytes.\n");
1526 status
= smb2_read(tree
, tree
, &rd
);
1527 torture_assert_int_equal_goto(torture
, rd
.out
.data
.length
, 0, ret
, done
,
1528 "zero byte read did not return 0 bytes");
1529 CHECK_STATUS(status
, NT_STATUS_OK
);
1532 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1533 status
= smb2_lock(tree
, &lck
);
1534 CHECK_STATUS(status
, NT_STATUS_OK
);
1535 CHECK_VALUE(lck
.out
.reserved
, 0);
1537 torture_comment(torture
, "Testing zero byte read on zero byte lock "
1540 /* Take an exclusive lock */
1541 torture_comment(torture
, " taking exclusive 0-byte lock.\n");
1544 el
[0].reserved
= 0x00000000;
1545 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1546 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1547 status
= smb2_lock(tree
, &lck
);
1548 CHECK_STATUS(status
, NT_STATUS_OK
);
1549 CHECK_VALUE(lck
.out
.reserved
, 0);
1551 /* Try a zero byte read before the lock */
1552 torture_comment(torture
, " reading 0 bytes before the lock.\n");
1555 status
= smb2_read(tree
, tree
, &rd
);
1556 torture_assert_int_equal_goto(torture
, rd
.out
.data
.length
, 0, ret
, done
,
1557 "zero byte read did not return 0 bytes");
1558 CHECK_STATUS(status
, NT_STATUS_OK
);
1560 /* Try a zero byte read on the lock */
1561 torture_comment(torture
, " reading 0 bytes on the lock.\n");
1564 status
= smb2_read(tree
, tree
, &rd
);
1565 torture_assert_int_equal_goto(torture
, rd
.out
.data
.length
, 0, ret
, done
,
1566 "zero byte read did not return 0 bytes");
1567 CHECK_STATUS(status
, NT_STATUS_OK
);
1569 /* Try a zero byte read after the lock */
1570 torture_comment(torture
, " reading 0 bytes after the lock.\n");
1573 status
= smb2_read(tree
, tree
, &rd
);
1574 torture_assert_int_equal_goto(torture
, rd
.out
.data
.length
, 0, ret
, done
,
1575 "zero byte read did not return 0 bytes");
1576 CHECK_STATUS(status
, NT_STATUS_OK
);
1579 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1580 status
= smb2_lock(tree
, &lck
);
1581 CHECK_STATUS(status
, NT_STATUS_OK
);
1582 CHECK_VALUE(lck
.out
.reserved
, 0);
1585 smb2_util_close(tree
, h2
);
1586 smb2_util_close(tree
, h
);
1587 smb2_deltree(tree
, BASEDIR
);
1591 static bool test_unlock(struct torture_context
*torture
,
1592 struct smb2_tree
*tree
)
1596 struct smb2_handle h
= {{0}};
1597 struct smb2_handle h2
= {{0}};
1599 struct smb2_lock lck
;
1600 struct smb2_lock_element el1
[1];
1601 struct smb2_lock_element el2
[1];
1603 const char *fname
= BASEDIR
"\\unlock.txt";
1605 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1606 CHECK_STATUS(status
, NT_STATUS_OK
);
1607 smb2_util_close(tree
, h
);
1609 status
= torture_smb2_testfile(tree
, fname
, &h
);
1610 CHECK_STATUS(status
, NT_STATUS_OK
);
1613 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1614 CHECK_STATUS(status
, NT_STATUS_OK
);
1616 status
= torture_smb2_testfile(tree
, fname
, &h2
);
1617 CHECK_STATUS(status
, NT_STATUS_OK
);
1619 /* Setup initial parameters */
1621 lck
.in
.lock_count
= 0x0001;
1622 lck
.in
.lock_sequence
= 0x00000000;
1625 el1
[0].reserved
= 0x00000000;
1627 /* Take exclusive lock, then unlock it with a shared-unlock call. */
1629 torture_comment(torture
, "Testing unlock exclusive with shared\n");
1631 torture_comment(torture
, " taking exclusive lock.\n");
1632 lck
.in
.file
.handle
= h
;
1633 el1
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
;
1634 status
= smb2_lock(tree
, &lck
);
1635 CHECK_STATUS(status
, NT_STATUS_OK
);
1637 torture_comment(torture
, " try to unlock the exclusive with a shared "
1639 el1
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1640 SMB2_LOCK_FLAG_UNLOCK
;
1641 status
= smb2_lock(tree
, &lck
);
1642 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
1644 torture_comment(torture
, " try shared lock on h2, to test the "
1646 lck
.in
.file
.handle
= h2
;
1647 el1
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1648 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1649 status
= smb2_lock(tree
, &lck
);
1650 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1652 torture_comment(torture
, " unlock the exclusive lock\n");
1653 lck
.in
.file
.handle
= h
;
1654 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1655 status
= smb2_lock(tree
, &lck
);
1656 CHECK_STATUS(status
, NT_STATUS_OK
);
1658 /* Unlock a shared lock with an exclusive-unlock call. */
1660 torture_comment(torture
, "Testing unlock shared with exclusive\n");
1662 torture_comment(torture
, " taking shared lock.\n");
1663 lck
.in
.file
.handle
= h
;
1664 el1
[0].flags
= SMB2_LOCK_FLAG_SHARED
;
1665 status
= smb2_lock(tree
, &lck
);
1666 CHECK_STATUS(status
, NT_STATUS_OK
);
1668 torture_comment(torture
, " try to unlock the shared with an exclusive "
1670 el1
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1671 SMB2_LOCK_FLAG_UNLOCK
;
1672 status
= smb2_lock(tree
, &lck
);
1673 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
1675 torture_comment(torture
, " try exclusive lock on h2, to test the "
1677 lck
.in
.file
.handle
= h2
;
1678 el1
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1679 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1680 status
= smb2_lock(tree
, &lck
);
1681 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1683 torture_comment(torture
, " unlock the exclusive lock\n");
1684 lck
.in
.file
.handle
= h
;
1685 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1686 status
= smb2_lock(tree
, &lck
);
1687 CHECK_STATUS(status
, NT_STATUS_OK
);
1689 /* Test unlocking of stacked 0-byte locks. SMB2 0-byte lock behavior
1690 * should be the same as >0-byte behavior. Exclusive locks should be
1691 * unlocked before shared. */
1693 torture_comment(torture
, "Test unlocking stacked 0-byte locks\n");
1696 lck
.in
.file
.handle
= h
;
1699 el1
[0].reserved
= 0x00000000;
1702 el2
[0].reserved
= 0x00000000;
1704 /* lock 0-byte exclusive */
1705 el1
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1706 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1707 status
= smb2_lock(tree
, &lck
);
1708 CHECK_STATUS(status
, NT_STATUS_OK
);
1710 /* lock 0-byte shared */
1711 el1
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1712 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1713 status
= smb2_lock(tree
, &lck
);
1714 CHECK_STATUS(status
, NT_STATUS_OK
);
1716 /* test contention */
1718 lck
.in
.file
.handle
= h2
;
1719 el2
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1720 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1721 status
= smb2_lock(tree
, &lck
);
1722 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1725 lck
.in
.file
.handle
= h2
;
1726 el2
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1727 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1728 status
= smb2_lock(tree
, &lck
);
1729 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1733 lck
.in
.file
.handle
= h
;
1734 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1735 status
= smb2_lock(tree
, &lck
);
1736 CHECK_STATUS(status
, NT_STATUS_OK
);
1738 /* test - can we take a shared lock? */
1740 lck
.in
.file
.handle
= h2
;
1741 el2
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1742 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1743 status
= smb2_lock(tree
, &lck
);
1744 CHECK_STATUS(status
, NT_STATUS_OK
);
1746 el2
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1747 status
= smb2_lock(tree
, &lck
);
1748 CHECK_STATUS(status
, NT_STATUS_OK
);
1752 lck
.in
.file
.handle
= h
;
1753 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1754 status
= smb2_lock(tree
, &lck
);
1755 CHECK_STATUS(status
, NT_STATUS_OK
);
1757 /* Test unlocking of stacked exclusive, shared locks. Exclusive
1758 * should be unlocked before any shared. */
1760 torture_comment(torture
, "Test unlocking stacked exclusive/shared "
1764 lck
.in
.file
.handle
= h
;
1767 el1
[0].reserved
= 0x00000000;
1770 el2
[0].reserved
= 0x00000000;
1772 /* lock exclusive */
1773 el1
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1774 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1775 status
= smb2_lock(tree
, &lck
);
1776 CHECK_STATUS(status
, NT_STATUS_OK
);
1779 el1
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1780 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1781 status
= smb2_lock(tree
, &lck
);
1782 CHECK_STATUS(status
, NT_STATUS_OK
);
1784 /* test contention */
1786 lck
.in
.file
.handle
= h2
;
1787 el2
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1788 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1789 status
= smb2_lock(tree
, &lck
);
1790 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1793 lck
.in
.file
.handle
= h2
;
1794 el2
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1795 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1796 status
= smb2_lock(tree
, &lck
);
1797 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1801 lck
.in
.file
.handle
= h
;
1802 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1803 status
= smb2_lock(tree
, &lck
);
1804 CHECK_STATUS(status
, NT_STATUS_OK
);
1806 /* test - can we take a shared lock? */
1808 lck
.in
.file
.handle
= h2
;
1809 el2
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
1810 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1811 status
= smb2_lock(tree
, &lck
);
1812 CHECK_STATUS(status
, NT_STATUS_OK
);
1814 el2
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1815 status
= smb2_lock(tree
, &lck
);
1816 CHECK_STATUS(status
, NT_STATUS_OK
);
1820 lck
.in
.file
.handle
= h
;
1821 el1
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1822 status
= smb2_lock(tree
, &lck
);
1823 CHECK_STATUS(status
, NT_STATUS_OK
);
1826 smb2_util_close(tree
, h2
);
1827 smb2_util_close(tree
, h
);
1828 smb2_deltree(tree
, BASEDIR
);
1832 static bool test_multiple_unlock(struct torture_context
*torture
,
1833 struct smb2_tree
*tree
)
1837 struct smb2_handle h
;
1839 struct smb2_lock lck
;
1840 struct smb2_lock_element el
[2];
1842 const char *fname
= BASEDIR
"\\unlock_multiple.txt";
1844 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
1845 CHECK_STATUS(status
, NT_STATUS_OK
);
1846 smb2_util_close(tree
, h
);
1848 status
= torture_smb2_testfile(tree
, fname
, &h
);
1849 CHECK_STATUS(status
, NT_STATUS_OK
);
1852 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
1853 CHECK_STATUS(status
, NT_STATUS_OK
);
1855 torture_comment(torture
, "Testing multiple unlocks:\n");
1857 /* Setup initial parameters */
1858 lck
.in
.lock_count
= 0x0002;
1859 lck
.in
.lock_sequence
= 0x00000000;
1860 lck
.in
.file
.handle
= h
;
1863 el
[0].reserved
= 0x00000000;
1866 el
[1].reserved
= 0x00000000;
1868 /* Test1: Acquire second lock, but not first. */
1869 torture_comment(torture
, " unlock 2 locks, first one not locked. "
1870 "Expect no locks unlocked. \n");
1872 lck
.in
.lock_count
= 0x0001;
1873 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1874 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1875 lck
.in
.locks
= &el
[1];
1876 status
= smb2_lock(tree
, &lck
);
1877 CHECK_STATUS(status
, NT_STATUS_OK
);
1879 /* Try to unlock both locks */
1880 lck
.in
.lock_count
= 0x0002;
1881 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1882 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1884 status
= smb2_lock(tree
, &lck
);
1885 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
1887 /* Second lock should not be unlocked. */
1888 lck
.in
.lock_count
= 0x0001;
1889 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1890 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1891 lck
.in
.locks
= &el
[1];
1892 status
= smb2_lock(tree
, &lck
);
1893 if (TARGET_IS_W2K8(torture
)) {
1894 CHECK_STATUS(status
, NT_STATUS_OK
);
1895 torture_warning(torture
, "Target has \"pretty please\" bug. "
1896 "A contending lock request on the same handle "
1897 "unlocks the lock.\n");
1899 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1903 lck
.in
.lock_count
= 0x0001;
1904 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1905 lck
.in
.locks
= &el
[1];
1906 status
= smb2_lock(tree
, &lck
);
1907 CHECK_STATUS(status
, NT_STATUS_OK
);
1909 /* Test2: Acquire first lock, but not second. */
1910 torture_comment(torture
, " unlock 2 locks, second one not locked. "
1911 "Expect first lock unlocked.\n");
1913 lck
.in
.lock_count
= 0x0001;
1914 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1915 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1916 lck
.in
.locks
= &el
[0];
1917 status
= smb2_lock(tree
, &lck
);
1918 CHECK_STATUS(status
, NT_STATUS_OK
);
1920 /* Try to unlock both locks */
1921 lck
.in
.lock_count
= 0x0002;
1922 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1923 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1925 status
= smb2_lock(tree
, &lck
);
1926 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
1928 /* First lock should be unlocked. */
1929 lck
.in
.lock_count
= 0x0001;
1930 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1931 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1932 lck
.in
.locks
= &el
[0];
1933 status
= smb2_lock(tree
, &lck
);
1934 CHECK_STATUS(status
, NT_STATUS_OK
);
1937 lck
.in
.lock_count
= 0x0001;
1938 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1939 lck
.in
.locks
= &el
[0];
1940 status
= smb2_lock(tree
, &lck
);
1941 CHECK_STATUS(status
, NT_STATUS_OK
);
1943 /* Test3: Request 2 locks, second will contend. What happens to the
1945 torture_comment(torture
, " request 2 locks, second one will contend. "
1946 "Expect both to fail.\n");
1948 /* Lock the second range */
1949 lck
.in
.lock_count
= 0x0001;
1950 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1951 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1952 lck
.in
.locks
= &el
[1];
1953 status
= smb2_lock(tree
, &lck
);
1954 CHECK_STATUS(status
, NT_STATUS_OK
);
1956 /* Request both locks */
1957 lck
.in
.lock_count
= 0x0002;
1958 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
1959 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
1961 status
= smb2_lock(tree
, &lck
);
1962 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1964 /* First lock should be unlocked. */
1965 lck
.in
.lock_count
= 0x0001;
1966 lck
.in
.locks
= &el
[0];
1967 status
= smb2_lock(tree
, &lck
);
1968 CHECK_STATUS(status
, NT_STATUS_OK
);
1971 if (TARGET_IS_W2K8(torture
)) {
1972 lck
.in
.lock_count
= 0x0001;
1973 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1974 lck
.in
.locks
= &el
[0];
1975 status
= smb2_lock(tree
, &lck
);
1976 CHECK_STATUS(status
, NT_STATUS_OK
);
1977 torture_warning(torture
, "Target has \"pretty please\" bug. "
1978 "A contending lock request on the same handle "
1979 "unlocks the lock.\n");
1981 lck
.in
.lock_count
= 0x0002;
1982 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1983 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
1985 status
= smb2_lock(tree
, &lck
);
1986 CHECK_STATUS(status
, NT_STATUS_OK
);
1989 /* Test4: Request unlock and lock. The lock contends, is the unlock
1990 * then relocked? SMB2 doesn't like the lock and unlock requests in the
1991 * same packet. The unlock will succeed, but the lock will return
1992 * INVALID_PARAMETER. This behavior is described in MS-SMB2
1994 torture_comment(torture
, " request unlock and lock, second one will "
1995 "error. Expect the unlock to succeed.\n");
1997 /* Lock both ranges */
1998 lck
.in
.lock_count
= 0x0002;
1999 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2000 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2001 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2002 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2004 status
= smb2_lock(tree
, &lck
);
2005 CHECK_STATUS(status
, NT_STATUS_OK
);
2007 /* Attempt to unlock the first range and lock the second. The lock
2008 * request will error. */
2009 lck
.in
.lock_count
= 0x0002;
2010 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2011 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2012 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2014 status
= smb2_lock(tree
, &lck
);
2015 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
2017 /* The first lock should've been unlocked */
2018 lck
.in
.lock_count
= 0x0001;
2019 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2020 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2021 lck
.in
.locks
= &el
[0];
2022 status
= smb2_lock(tree
, &lck
);
2023 CHECK_STATUS(status
, NT_STATUS_OK
);
2026 lck
.in
.lock_count
= 0x0002;
2027 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2028 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2030 status
= smb2_lock(tree
, &lck
);
2031 CHECK_STATUS(status
, NT_STATUS_OK
);
2033 /* Test10: SMB2 only test. Request unlock and lock in same packet.
2034 * Neither contend. SMB2 doesn't like lock and unlock requests in the
2035 * same packet. The unlock will succeed, but the lock will return
2036 * INVALID_PARAMETER. */
2037 torture_comment(torture
, " request unlock and lock. Unlock will "
2038 "succeed, but lock will fail.\n");
2040 /* Lock first range */
2041 lck
.in
.lock_count
= 0x0001;
2042 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2043 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2044 lck
.in
.locks
= &el
[0];
2045 status
= smb2_lock(tree
, &lck
);
2046 CHECK_STATUS(status
, NT_STATUS_OK
);
2048 /* Attempt to unlock the first range and lock the second */
2049 lck
.in
.lock_count
= 0x0002;
2050 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2051 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2052 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2054 status
= smb2_lock(tree
, &lck
);
2055 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
2057 /* Neither lock should still be locked */
2058 lck
.in
.lock_count
= 0x0002;
2059 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2060 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2061 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2062 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2064 status
= smb2_lock(tree
, &lck
);
2065 CHECK_STATUS(status
, NT_STATUS_OK
);
2068 lck
.in
.lock_count
= 0x0002;
2069 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2070 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2072 status
= smb2_lock(tree
, &lck
);
2073 CHECK_STATUS(status
, NT_STATUS_OK
);
2075 /* Test11: SMB2 only test. Request lock and unlock in same packet.
2076 * Neither contend. SMB2 doesn't like lock and unlock requests in the
2077 * same packet. The lock will succeed, the unlock will fail with
2078 * INVALID_PARAMETER, and the lock will be unlocked before return. */
2079 torture_comment(torture
, " request lock and unlock. Both will "
2082 /* Lock second range */
2083 lck
.in
.lock_count
= 0x0001;
2084 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2085 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2086 lck
.in
.locks
= &el
[1];
2087 status
= smb2_lock(tree
, &lck
);
2088 CHECK_STATUS(status
, NT_STATUS_OK
);
2090 /* Attempt to lock the first range and unlock the second */
2091 lck
.in
.lock_count
= 0x0002;
2092 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2093 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2094 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2096 status
= smb2_lock(tree
, &lck
);
2097 CHECK_STATUS(status
, NT_STATUS_INVALID_PARAMETER
);
2099 /* First range should be unlocked, second locked. */
2100 lck
.in
.lock_count
= 0x0001;
2101 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2102 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2103 lck
.in
.locks
= &el
[0];
2104 status
= smb2_lock(tree
, &lck
);
2105 CHECK_STATUS(status
, NT_STATUS_OK
);
2107 lck
.in
.lock_count
= 0x0001;
2108 el
[1].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2109 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2110 lck
.in
.locks
= &el
[1];
2111 status
= smb2_lock(tree
, &lck
);
2112 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2115 if (TARGET_IS_W2K8(torture
)) {
2116 lck
.in
.lock_count
= 0x0001;
2117 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2118 lck
.in
.locks
= &el
[0];
2119 status
= smb2_lock(tree
, &lck
);
2120 CHECK_STATUS(status
, NT_STATUS_OK
);
2121 torture_warning(torture
, "Target has \"pretty please\" bug. "
2122 "A contending lock request on the same handle "
2123 "unlocks the lock.\n");
2125 lck
.in
.lock_count
= 0x0002;
2126 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2127 el
[1].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2129 status
= smb2_lock(tree
, &lck
);
2130 CHECK_STATUS(status
, NT_STATUS_OK
);
2134 smb2_util_close(tree
, h
);
2135 smb2_deltree(tree
, BASEDIR
);
2140 * Test lock stacking
2141 * - some tests ported from BASE-LOCK-LOCK5
2143 static bool test_stacking(struct torture_context
*torture
,
2144 struct smb2_tree
*tree
)
2148 struct smb2_handle h
= {{0}};
2149 struct smb2_handle h2
= {{0}};
2151 struct smb2_lock lck
;
2152 struct smb2_lock_element el
[1];
2154 const char *fname
= BASEDIR
"\\stacking.txt";
2156 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2157 CHECK_STATUS(status
, NT_STATUS_OK
);
2158 smb2_util_close(tree
, h
);
2160 status
= torture_smb2_testfile(tree
, fname
, &h
);
2161 CHECK_STATUS(status
, NT_STATUS_OK
);
2164 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2165 CHECK_STATUS(status
, NT_STATUS_OK
);
2167 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2168 CHECK_STATUS(status
, NT_STATUS_OK
);
2170 torture_comment(torture
, "Testing lock stacking:\n");
2172 /* Setup initial parameters */
2174 lck
.in
.lock_count
= 0x0001;
2175 lck
.in
.lock_sequence
= 0x00000000;
2176 lck
.in
.file
.handle
= h
;
2179 el
[0].reserved
= 0x00000000;
2181 /* Try to take a shared lock, then a shared lock on same handle */
2182 torture_comment(torture
, " stacking a shared on top of a shared"
2183 "lock succeeds.\n");
2185 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2186 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2187 status
= smb2_lock(tree
, &lck
);
2188 CHECK_STATUS(status
, NT_STATUS_OK
);
2190 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2191 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2192 status
= smb2_lock(tree
, &lck
);
2193 CHECK_STATUS(status
, NT_STATUS_OK
);
2196 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2197 status
= smb2_lock(tree
, &lck
);
2198 CHECK_STATUS(status
, NT_STATUS_OK
);
2200 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2201 status
= smb2_lock(tree
, &lck
);
2202 CHECK_STATUS(status
, NT_STATUS_OK
);
2205 /* Try to take an exclusive lock, then a shared lock on same handle */
2206 torture_comment(torture
, " stacking a shared on top of an exclusive "
2207 "lock succeeds.\n");
2209 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2210 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2211 status
= smb2_lock(tree
, &lck
);
2212 CHECK_STATUS(status
, NT_STATUS_OK
);
2214 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2215 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2216 status
= smb2_lock(tree
, &lck
);
2217 CHECK_STATUS(status
, NT_STATUS_OK
);
2219 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2220 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2221 status
= smb2_lock(tree
, &lck
);
2222 CHECK_STATUS(status
, NT_STATUS_OK
);
2224 /* stacking a shared from a different handle should fail */
2225 lck
.in
.file
.handle
= h2
;
2226 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2227 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2228 status
= smb2_lock(tree
, &lck
);
2229 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2232 lck
.in
.file
.handle
= h
;
2233 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2234 status
= smb2_lock(tree
, &lck
);
2235 CHECK_STATUS(status
, NT_STATUS_OK
);
2237 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2238 status
= smb2_lock(tree
, &lck
);
2239 CHECK_STATUS(status
, NT_STATUS_OK
);
2241 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2242 status
= smb2_lock(tree
, &lck
);
2243 CHECK_STATUS(status
, NT_STATUS_OK
);
2245 /* ensure the 4th unlock fails */
2246 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2247 status
= smb2_lock(tree
, &lck
);
2248 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
2250 /* ensure a second handle can now take an exclusive lock */
2251 lck
.in
.file
.handle
= h2
;
2252 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2253 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2254 status
= smb2_lock(tree
, &lck
);
2255 CHECK_STATUS(status
, NT_STATUS_OK
);
2257 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2258 status
= smb2_lock(tree
, &lck
);
2259 CHECK_STATUS(status
, NT_STATUS_OK
);
2261 /* Try to take an exclusive lock, then a shared lock on a
2262 * different handle */
2263 torture_comment(torture
, " stacking a shared on top of an exclusive "
2264 "lock with different handles fails.\n");
2266 lck
.in
.file
.handle
= h
;
2267 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2268 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2269 status
= smb2_lock(tree
, &lck
);
2270 CHECK_STATUS(status
, NT_STATUS_OK
);
2272 lck
.in
.file
.handle
= h2
;
2273 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2274 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2275 status
= smb2_lock(tree
, &lck
);
2276 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2279 lck
.in
.file
.handle
= h
;
2280 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2281 status
= smb2_lock(tree
, &lck
);
2282 CHECK_STATUS(status
, NT_STATUS_OK
);
2284 /* Try to take a shared lock, then stack an exclusive with same
2286 torture_comment(torture
, " stacking an exclusive on top of a shared "
2289 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2290 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2291 status
= smb2_lock(tree
, &lck
);
2292 CHECK_STATUS(status
, NT_STATUS_OK
);
2294 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2295 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2296 status
= smb2_lock(tree
, &lck
);
2297 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2300 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2301 status
= smb2_lock(tree
, &lck
);
2302 if (TARGET_IS_W2K8(torture
)) {
2303 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
2304 torture_warning(torture
, "Target has \"pretty please\" bug. "
2305 "A contending lock request on the same handle "
2306 "unlocks the lock.\n");
2308 CHECK_STATUS(status
, NT_STATUS_OK
);
2311 /* Prove that two exclusive locks do not stack on the same handle. */
2312 torture_comment(torture
, " two exclusive locks do not stack.\n");
2314 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2315 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2316 status
= smb2_lock(tree
, &lck
);
2317 CHECK_STATUS(status
, NT_STATUS_OK
);
2319 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2320 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2321 status
= smb2_lock(tree
, &lck
);
2322 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2325 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2326 status
= smb2_lock(tree
, &lck
);
2327 if (TARGET_IS_W2K8(torture
)) {
2328 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
2329 torture_warning(torture
, "Target has \"pretty please\" bug. "
2330 "A contending lock request on the same handle "
2331 "unlocks the lock.\n");
2333 CHECK_STATUS(status
, NT_STATUS_OK
);
2337 smb2_util_close(tree
, h2
);
2338 smb2_util_close(tree
, h
);
2339 smb2_deltree(tree
, BASEDIR
);
2344 * Test lock contention
2345 * - shared lock should contend with exclusive lock on different handle
2347 static bool test_contend(struct torture_context
*torture
,
2348 struct smb2_tree
*tree
)
2352 struct smb2_handle h
= {{0}};
2353 struct smb2_handle h2
= {{0}};
2355 struct smb2_lock lck
;
2356 struct smb2_lock_element el
[1];
2358 const char *fname
= BASEDIR
"\\contend.txt";
2360 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2361 CHECK_STATUS(status
, NT_STATUS_OK
);
2362 smb2_util_close(tree
, h
);
2364 status
= torture_smb2_testfile(tree
, fname
, &h
);
2365 CHECK_STATUS(status
, NT_STATUS_OK
);
2368 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2369 CHECK_STATUS(status
, NT_STATUS_OK
);
2371 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2372 CHECK_STATUS(status
, NT_STATUS_OK
);
2374 torture_comment(torture
, "Testing lock contention:\n");
2376 /* Setup initial parameters */
2378 lck
.in
.lock_count
= 0x0001;
2379 lck
.in
.lock_sequence
= 0x00000000;
2380 lck
.in
.file
.handle
= h
;
2383 el
[0].reserved
= 0x00000000;
2385 /* Take an exclusive lock, then a shared lock on different handle */
2386 torture_comment(torture
, " shared should contend on exclusive on "
2387 "different handle.\n");
2389 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2390 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2391 status
= smb2_lock(tree
, &lck
);
2392 CHECK_STATUS(status
, NT_STATUS_OK
);
2394 lck
.in
.file
.handle
= h2
;
2395 el
[0].flags
= SMB2_LOCK_FLAG_SHARED
|
2396 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2397 status
= smb2_lock(tree
, &lck
);
2398 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2401 lck
.in
.file
.handle
= h
;
2402 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2403 status
= smb2_lock(tree
, &lck
);
2404 CHECK_STATUS(status
, NT_STATUS_OK
);
2407 smb2_util_close(tree
, h2
);
2408 smb2_util_close(tree
, h
);
2409 smb2_deltree(tree
, BASEDIR
);
2414 * Test locker context
2415 * - test that pid does not affect the locker context
2417 static bool test_context(struct torture_context
*torture
,
2418 struct smb2_tree
*tree
)
2422 struct smb2_handle h
= {{0}};
2423 struct smb2_handle h2
= {{0}};
2425 struct smb2_lock lck
;
2426 struct smb2_lock_element el
[1];
2428 const char *fname
= BASEDIR
"\\context.txt";
2430 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2431 CHECK_STATUS(status
, NT_STATUS_OK
);
2432 smb2_util_close(tree
, h
);
2434 status
= torture_smb2_testfile(tree
, fname
, &h
);
2435 CHECK_STATUS(status
, NT_STATUS_OK
);
2438 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2439 CHECK_STATUS(status
, NT_STATUS_OK
);
2441 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2442 CHECK_STATUS(status
, NT_STATUS_OK
);
2444 torture_comment(torture
, "Testing locker context:\n");
2446 /* Setup initial parameters */
2448 lck
.in
.lock_count
= 0x0001;
2449 lck
.in
.lock_sequence
= 0x00000000;
2450 lck
.in
.file
.handle
= h
;
2453 el
[0].reserved
= 0x00000000;
2455 /* Take an exclusive lock, then try to unlock with a different pid,
2456 * same handle. This shows that the pid doesn't affect the locker
2457 * context in SMB2. */
2458 torture_comment(torture
, " pid shouldn't affect locker context\n");
2460 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2461 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2462 status
= smb2_lock(tree
, &lck
);
2463 CHECK_STATUS(status
, NT_STATUS_OK
);
2465 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2466 status
= smb2_lock(tree
, &lck
);
2467 CHECK_STATUS(status
, NT_STATUS_OK
);
2469 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2470 status
= smb2_lock(tree
, &lck
);
2471 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
2474 smb2_util_close(tree
, h2
);
2475 smb2_util_close(tree
, h
);
2476 smb2_deltree(tree
, BASEDIR
);
2481 * Test as much of the potential lock range as possible
2482 * - test ported from BASE-LOCK-LOCK3
2484 static bool test_range(struct torture_context
*torture
,
2485 struct smb2_tree
*tree
)
2489 struct smb2_handle h
= {{0}};
2490 struct smb2_handle h2
= {{0}};
2492 struct smb2_lock lck
;
2493 struct smb2_lock_element el
[1];
2495 extern int torture_numops
;
2497 const char *fname
= BASEDIR
"\\range.txt";
2499 #define NEXT_OFFSET offset += (~(uint64_t)0) / torture_numops
2501 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2502 CHECK_STATUS(status
, NT_STATUS_OK
);
2503 smb2_util_close(tree
, h
);
2505 status
= torture_smb2_testfile(tree
, fname
, &h
);
2506 CHECK_STATUS(status
, NT_STATUS_OK
);
2509 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2510 CHECK_STATUS(status
, NT_STATUS_OK
);
2512 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2513 CHECK_STATUS(status
, NT_STATUS_OK
);
2515 torture_comment(torture
, "Testing locks spread across the 64-bit "
2518 if (TARGET_IS_W2K8(torture
)) {
2519 torture_result(torture
, TORTURE_SKIP
,
2520 "Target has \"pretty please\" bug. A contending lock "
2521 "request on the same handle unlocks the lock.");
2525 /* Setup initial parameters */
2527 lck
.in
.lock_count
= 0x0001;
2528 lck
.in
.lock_sequence
= 0x00000000;
2529 lck
.in
.file
.handle
= h
;
2532 el
[0].reserved
= 0x00000000;
2533 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2534 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2536 torture_comment(torture
, " establishing %d locks\n", torture_numops
);
2538 for (offset
=i
=0; i
<torture_numops
; i
++) {
2541 lck
.in
.file
.handle
= h
;
2542 el
[0].offset
= offset
- 1;
2543 status
= smb2_lock(tree
, &lck
);
2544 CHECK_STATUS_CMT(status
, NT_STATUS_OK
,
2545 talloc_asprintf(torture
,
2546 "lock h failed at offset %#llx ",
2547 (unsigned long long) el
[0].offset
));
2549 lck
.in
.file
.handle
= h2
;
2550 el
[0].offset
= offset
- 2;
2551 status
= smb2_lock(tree
, &lck
);
2552 CHECK_STATUS_CMT(status
, NT_STATUS_OK
,
2553 talloc_asprintf(torture
,
2554 "lock h2 failed at offset %#llx ",
2555 (unsigned long long) el
[0].offset
));
2558 torture_comment(torture
, " testing %d locks\n", torture_numops
);
2560 for (offset
=i
=0; i
<torture_numops
; i
++) {
2563 lck
.in
.file
.handle
= h
;
2564 el
[0].offset
= offset
- 1;
2565 status
= smb2_lock(tree
, &lck
);
2566 CHECK_STATUS_CMT(status
, NT_STATUS_LOCK_NOT_GRANTED
,
2567 talloc_asprintf(torture
,
2568 "lock h at offset %#llx should not have "
2570 (unsigned long long) el
[0].offset
));
2572 lck
.in
.file
.handle
= h
;
2573 el
[0].offset
= offset
- 2;
2574 status
= smb2_lock(tree
, &lck
);
2575 CHECK_STATUS_CMT(status
, NT_STATUS_LOCK_NOT_GRANTED
,
2576 talloc_asprintf(torture
,
2577 "lock h2 at offset %#llx should not have "
2579 (unsigned long long) el
[0].offset
));
2581 lck
.in
.file
.handle
= h2
;
2582 el
[0].offset
= offset
- 1;
2583 status
= smb2_lock(tree
, &lck
);
2584 CHECK_STATUS_CMT(status
, NT_STATUS_LOCK_NOT_GRANTED
,
2585 talloc_asprintf(torture
,
2586 "lock h at offset %#llx should not have "
2588 (unsigned long long) el
[0].offset
));
2590 lck
.in
.file
.handle
= h2
;
2591 el
[0].offset
= offset
- 2;
2592 status
= smb2_lock(tree
, &lck
);
2593 CHECK_STATUS_CMT(status
, NT_STATUS_LOCK_NOT_GRANTED
,
2594 talloc_asprintf(torture
,
2595 "lock h2 at offset %#llx should not have "
2597 (unsigned long long) el
[0].offset
));
2600 torture_comment(torture
, " removing %d locks\n", torture_numops
);
2602 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2604 for (offset
=i
=0; i
<torture_numops
; i
++) {
2607 lck
.in
.file
.handle
= h
;
2608 el
[0].offset
= offset
- 1;
2609 status
= smb2_lock(tree
, &lck
);
2610 CHECK_STATUS_CMT(status
, NT_STATUS_OK
,
2611 talloc_asprintf(torture
,
2612 "unlock from h failed at offset %#llx ",
2613 (unsigned long long) el
[0].offset
));
2615 lck
.in
.file
.handle
= h2
;
2616 el
[0].offset
= offset
- 2;
2617 status
= smb2_lock(tree
, &lck
);
2618 CHECK_STATUS_CMT(status
, NT_STATUS_OK
,
2619 talloc_asprintf(torture
,
2620 "unlock from h2 failed at offset %#llx ",
2621 (unsigned long long) el
[0].offset
));
2625 smb2_util_close(tree
, h2
);
2626 smb2_util_close(tree
, h
);
2627 smb2_deltree(tree
, BASEDIR
);
2631 static NTSTATUS
test_smb2_lock(struct smb2_tree
*tree
, struct smb2_handle h
,
2632 uint64_t offset
, uint64_t length
, bool exclusive
)
2634 struct smb2_lock lck
;
2635 struct smb2_lock_element el
[1];
2639 lck
.in
.lock_count
= 0x0001;
2640 lck
.in
.lock_sequence
= 0x00000000;
2641 lck
.in
.file
.handle
= h
;
2642 el
[0].offset
= offset
;
2643 el
[0].length
= length
;
2644 el
[0].reserved
= 0x00000000;
2645 el
[0].flags
= (exclusive
?
2646 SMB2_LOCK_FLAG_EXCLUSIVE
:
2647 SMB2_LOCK_FLAG_SHARED
) |
2648 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2650 status
= smb2_lock(tree
, &lck
);
2655 static NTSTATUS
test_smb2_unlock(struct smb2_tree
*tree
, struct smb2_handle h
,
2656 uint64_t offset
, uint64_t length
)
2658 struct smb2_lock lck
;
2659 struct smb2_lock_element el
[1];
2663 lck
.in
.lock_count
= 0x0001;
2664 lck
.in
.lock_sequence
= 0x00000000;
2665 lck
.in
.file
.handle
= h
;
2666 el
[0].offset
= offset
;
2667 el
[0].length
= length
;
2668 el
[0].reserved
= 0x00000000;
2669 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2671 status
= smb2_lock(tree
, &lck
);
2676 #define EXPECTED(ret, v) if ((ret) != (v)) { \
2677 torture_result(torture, TORTURE_FAIL, __location__": subtest failed");\
2678 torture_comment(torture, "** "); correct = false; \
2682 * Test overlapping lock ranges from various lockers
2683 * - some tests ported from BASE-LOCK-LOCK4
2685 static bool test_overlap(struct torture_context
*torture
,
2686 struct smb2_tree
*tree
,
2687 struct smb2_tree
*tree2
)
2691 struct smb2_handle h
= {{0}};
2692 struct smb2_handle h2
= {{0}};
2693 struct smb2_handle h3
= {{0}};
2695 bool correct
= true;
2697 const char *fname
= BASEDIR
"\\overlap.txt";
2699 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2700 CHECK_STATUS(status
, NT_STATUS_OK
);
2701 smb2_util_close(tree
, h
);
2703 status
= torture_smb2_testfile(tree
, fname
, &h
);
2704 CHECK_STATUS(status
, NT_STATUS_OK
);
2707 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2708 CHECK_STATUS(status
, NT_STATUS_OK
);
2710 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2711 CHECK_STATUS(status
, NT_STATUS_OK
);
2713 status
= torture_smb2_testfile(tree2
, fname
, &h3
);
2714 CHECK_STATUS(status
, NT_STATUS_OK
);
2716 torture_comment(torture
, "Testing overlapping locks:\n");
2718 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 0, 4, true)) &&
2719 NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 2, 4, true));
2720 EXPECTED(ret
, false);
2721 torture_comment(torture
, "the same session/handle %s set overlapping "
2722 "exclusive locks\n", ret
?"can":"cannot");
2724 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 10, 4, false)) &&
2725 NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 12, 4, false));
2726 EXPECTED(ret
, true);
2727 torture_comment(torture
, "the same session/handle %s set overlapping "
2728 "shared locks\n", ret
?"can":"cannot");
2730 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 20, 4, true)) &&
2731 NT_STATUS_IS_OK(test_smb2_lock(tree2
, h3
, 22, 4, true));
2732 EXPECTED(ret
, false);
2733 torture_comment(torture
, "a different session %s set overlapping "
2734 "exclusive locks\n", ret
?"can":"cannot");
2736 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 30, 4, false)) &&
2737 NT_STATUS_IS_OK(test_smb2_lock(tree2
, h3
, 32, 4, false));
2738 EXPECTED(ret
, true);
2739 torture_comment(torture
, "a different session %s set overlapping "
2740 "shared locks\n", ret
?"can":"cannot");
2742 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 40, 4, true)) &&
2743 NT_STATUS_IS_OK(test_smb2_lock(tree
, h2
, 42, 4, true));
2744 EXPECTED(ret
, false);
2745 torture_comment(torture
, "a different handle %s set overlapping "
2746 "exclusive locks\n", ret
?"can":"cannot");
2748 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 50, 4, false)) &&
2749 NT_STATUS_IS_OK(test_smb2_lock(tree
, h2
, 52, 4, false));
2750 EXPECTED(ret
, true);
2751 torture_comment(torture
, "a different handle %s set overlapping "
2752 "shared locks\n", ret
?"can":"cannot");
2754 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 110, 4, false)) &&
2755 NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 112, 4, false)) &&
2756 NT_STATUS_IS_OK(test_smb2_unlock(tree
, h
, 110, 6));
2757 EXPECTED(ret
, false);
2758 torture_comment(torture
, "the same handle %s coalesce read locks\n",
2759 ret
?"can":"cannot");
2761 smb2_util_close(tree
, h2
);
2762 smb2_util_close(tree
, h
);
2763 status
= torture_smb2_testfile(tree
, fname
, &h
);
2764 CHECK_STATUS(status
, NT_STATUS_OK
);
2765 status
= torture_smb2_testfile(tree
, fname
, &h2
);
2766 CHECK_STATUS(status
, NT_STATUS_OK
);
2767 ret
= NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 0, 8, false)) &&
2768 NT_STATUS_IS_OK(test_smb2_lock(tree
, h2
, 0, 1, false)) &&
2769 NT_STATUS_IS_OK(smb2_util_close(tree
, h
)) &&
2770 NT_STATUS_IS_OK(torture_smb2_testfile(tree
, fname
, &h
)) &&
2771 NT_STATUS_IS_OK(test_smb2_lock(tree
, h
, 7, 1, true));
2772 EXPECTED(ret
, true);
2773 torture_comment(torture
, "the server %s have the NT byte range lock "
2774 "bug\n", !ret
?"does":"doesn't");
2777 smb2_util_close(tree2
, h3
);
2778 smb2_util_close(tree
, h2
);
2779 smb2_util_close(tree
, h
);
2780 smb2_deltree(tree
, BASEDIR
);
2785 * Test truncation of locked file
2786 * - some tests ported from BASE-LOCK-LOCK7
2788 static bool test_truncate(struct torture_context
*torture
,
2789 struct smb2_tree
*tree
)
2793 struct smb2_handle h
= {{0}};
2794 struct smb2_handle h2
= {{0}};
2796 struct smb2_lock lck
;
2797 struct smb2_lock_element el
[1];
2798 struct smb2_create io
;
2800 const char *fname
= BASEDIR
"\\truncate.txt";
2802 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2803 CHECK_STATUS(status
, NT_STATUS_OK
);
2804 smb2_util_close(tree
, h
);
2806 status
= torture_smb2_testfile(tree
, fname
, &h
);
2807 CHECK_STATUS(status
, NT_STATUS_OK
);
2810 status
= smb2_util_write(tree
, h
, buf
, 0, ARRAY_SIZE(buf
));
2811 CHECK_STATUS(status
, NT_STATUS_OK
);
2813 torture_comment(torture
, "Testing truncation of locked file:\n");
2815 /* Setup initial parameters */
2817 lck
.in
.lock_count
= 0x0001;
2818 lck
.in
.lock_sequence
= 0x00000000;
2819 lck
.in
.file
.handle
= h
;
2822 el
[0].reserved
= 0x00000000;
2825 io
.in
.oplock_level
= 0;
2826 io
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
2827 io
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
2828 io
.in
.create_disposition
= NTCREATEX_DISP_OVERWRITE
;
2829 io
.in
.share_access
= NTCREATEX_SHARE_ACCESS_DELETE
|
2830 NTCREATEX_SHARE_ACCESS_READ
|
2831 NTCREATEX_SHARE_ACCESS_WRITE
;
2832 io
.in
.create_options
= 0;
2833 io
.in
.fname
= fname
;
2835 /* Take an exclusive lock */
2836 el
[0].flags
= SMB2_LOCK_FLAG_EXCLUSIVE
|
2837 SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2838 status
= smb2_lock(tree
, &lck
);
2839 CHECK_STATUS(status
, NT_STATUS_OK
);
2841 /* On second handle open the file with OVERWRITE disposition */
2842 torture_comment(torture
, " overwrite disposition is allowed on a "
2845 io
.in
.create_disposition
= NTCREATEX_DISP_OVERWRITE
;
2846 status
= smb2_create(tree
, tree
, &io
);
2847 CHECK_STATUS(status
, NT_STATUS_OK
);
2848 h2
= io
.out
.file
.handle
;
2849 smb2_util_close(tree
, h2
);
2851 /* On second handle open the file with SUPERSEDE disposition */
2852 torture_comment(torture
, " supersede disposition is allowed on a "
2855 io
.in
.create_disposition
= NTCREATEX_DISP_SUPERSEDE
;
2856 status
= smb2_create(tree
, tree
, &io
);
2857 CHECK_STATUS(status
, NT_STATUS_OK
);
2858 h2
= io
.out
.file
.handle
;
2859 smb2_util_close(tree
, h2
);
2862 lck
.in
.file
.handle
= h
;
2863 el
[0].flags
= SMB2_LOCK_FLAG_UNLOCK
;
2864 status
= smb2_lock(tree
, &lck
);
2865 CHECK_STATUS(status
, NT_STATUS_OK
);
2868 smb2_util_close(tree
, h2
);
2869 smb2_util_close(tree
, h
);
2870 smb2_deltree(tree
, BASEDIR
);
2875 * Test lock replay detection
2877 * This test checks the SMB 2.1.0 behaviour of lock sequence checking,
2878 * which is only turned on for resilient handles.
2880 * Make it clear that this test is supposed to pass against the legacy
2881 * Windows servers which violate the specification:
2883 * [MS-SMB2] 3.3.5.14 Receiving an SMB2 LOCK Request
2887 * ... if Open.IsResilient or Open.IsDurable or Open.IsPersistent is
2888 * TRUE or if Connection.Dialect belongs to the SMB 3.x dialect family
2889 * and Connection.ServerCapabilities includes
2890 * SMB2_GLOBAL_CAP_MULTI_CHANNEL bit, the server SHOULD<314>
2891 * perform lock sequence verification ...
2895 * <314> Section 3.3.5.14: Windows 7 and Windows Server 2008 R2 perform
2896 * lock sequence verification only when Open.IsResilient is TRUE.
2897 * Windows 8 through Windows 10 v1909 and Windows Server 2012 through
2898 * Windows Server v1909 perform lock sequence verification only when
2899 * Open.IsResilient or Open.IsPersistent is TRUE.
2901 * Note <314> also applies to all versions (at least) up to Windows Server v2004.
2903 * Hopefully this will be fixed in future Windows versions and they
2904 * will avoid Note <314>.
2906 static bool test_replay_broken_windows(struct torture_context
*torture
,
2907 struct smb2_tree
*tree
)
2911 struct smb2_handle h
;
2912 struct smb2_ioctl ioctl
;
2913 struct smb2_lock lck
;
2914 struct smb2_lock_element el
;
2916 const char *fname
= BASEDIR
"\\replay_broken_windows.txt";
2917 struct smb2_transport
*transport
= tree
->session
->transport
;
2919 if (smbXcli_conn_protocol(transport
->conn
) < PROTOCOL_SMB2_10
) {
2920 torture_skip(torture
, "SMB 2.1.0 Dialect family or above \
2921 required for Lock Replay tests\n");
2924 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
2925 CHECK_STATUS(status
, NT_STATUS_OK
);
2926 smb2_util_close(tree
, h
);
2928 torture_comment(torture
, "Testing Open File:\n");
2929 status
= torture_smb2_testfile(tree
, fname
, &h
);
2930 CHECK_STATUS(status
, NT_STATUS_OK
);
2933 * Setup initial parameters
2935 el
= (struct smb2_lock_element
) {
2939 lck
= (struct smb2_lock
) {
2941 .in
.lock_count
= 0x0001,
2945 torture_comment(torture
, "Testing Lock Replay detection [ignored]:\n");
2946 lck
.in
.lock_sequence
= 0x010 + 0x1;
2947 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
2948 status
= smb2_lock(tree
, &lck
);
2949 CHECK_STATUS(status
, NT_STATUS_OK
);
2950 status
= smb2_lock(tree
, &lck
);
2951 if (NT_STATUS_IS_OK(status
)) {
2952 lck
.in
.lock_sequence
= 0x020 + 0x2;
2953 status
= smb2_lock(tree
, &lck
);
2954 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2955 lck
.in
.lock_sequence
= 0x010 + 0x1;
2956 status
= smb2_lock(tree
, &lck
);
2957 CHECK_STATUS(status
, NT_STATUS_OK
);
2958 if (smbXcli_conn_protocol(transport
->conn
) > PROTOCOL_SMB2_10
) {
2959 torture_skip_goto(torture
, done
,
2960 "SMB3 Server implements LockSequence "
2961 "for all handles\n");
2964 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
2965 if (smbXcli_conn_protocol(transport
->conn
) > PROTOCOL_SMB2_10
) {
2966 torture_comment(torture
,
2967 "\nSMB3 Server implements LockSequence as SMB 2.1.0"
2968 " LEGACY BROKEN Windows!!!\n\n");
2970 torture_comment(torture
,
2971 "Testing SMB 2.1.0 LockSequence for ResilientHandles\n");
2973 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
2974 status
= smb2_lock(tree
, &lck
);
2975 CHECK_STATUS(status
, NT_STATUS_OK
);
2976 status
= smb2_lock(tree
, &lck
);
2977 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
2979 torture_comment(torture
, "Testing Set Resiliency:\n");
2980 SIVAL(res_req
, 0, 1000); /* timeout */
2981 SIVAL(res_req
, 4, 0); /* reserved */
2982 ioctl
= (struct smb2_ioctl
) {
2983 .level
= RAW_IOCTL_SMB2
,
2984 .in
.file
.handle
= h
,
2985 .in
.function
= FSCTL_LMR_REQ_RESILIENCY
,
2986 .in
.max_output_response
= 0,
2987 .in
.flags
= SMB2_IOCTL_FLAG_IS_FSCTL
,
2988 .in
.out
.data
= res_req
,
2989 .in
.out
.length
= sizeof(res_req
)
2991 status
= smb2_ioctl(tree
, torture
, &ioctl
);
2992 CHECK_STATUS(status
, NT_STATUS_OK
);
2995 * Test with an invalid bucket number (only 1..64 are valid).
2996 * With an invalid number, lock replay detection is not performed.
2998 torture_comment(torture
, "Testing Lock (ignored) Replay detection "
2999 "(Bucket No: 0 (invalid)) [ignored]:\n");
3000 lck
.in
.lock_sequence
= 0x000 + 0x1;
3001 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3002 status
= smb2_lock(tree
, &lck
);
3003 CHECK_STATUS(status
, NT_STATUS_OK
);
3004 status
= smb2_lock(tree
, &lck
);
3005 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3007 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3008 status
= smb2_lock(tree
, &lck
);
3009 CHECK_STATUS(status
, NT_STATUS_OK
);
3010 status
= smb2_lock(tree
, &lck
);
3011 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3013 torture_comment(torture
, "Testing Lock Replay detection "
3014 "(Bucket No: 1):\n");
3017 * Obtain Exclusive Lock of length 100 bytes using Bucket Num 1
3020 lck
.in
.lock_sequence
= 0x010 + 0x1;
3021 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3022 status
= smb2_lock(tree
, &lck
);
3023 CHECK_STATUS(status
, NT_STATUS_OK
);
3026 * Server detects Replay of Byte Range locks using the Lock Sequence
3027 * Numbers. And ignores the requests completely.
3029 status
= smb2_lock(tree
, &lck
);
3030 CHECK_STATUS(status
, NT_STATUS_OK
);
3031 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3032 status
= smb2_lock(tree
, &lck
);
3033 CHECK_STATUS(status
, NT_STATUS_OK
);
3034 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3035 status
= smb2_lock(tree
, &lck
);
3036 CHECK_STATUS(status
, NT_STATUS_OK
);
3037 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3038 status
= smb2_lock(tree
, &lck
);
3039 CHECK_STATUS(status
, NT_STATUS_OK
);
3040 status
= smb2_lock(tree
, &lck
);
3041 CHECK_STATUS(status
, NT_STATUS_OK
);
3043 /* status: still locked */
3046 * Server will not grant same Byte Range using a different Bucket Seq
3048 lck
.in
.lock_sequence
= 0x010 + 0x2;
3049 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3050 status
= smb2_lock(tree
, &lck
);
3051 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3052 status
= smb2_lock(tree
, &lck
);
3053 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3055 torture_comment(torture
, "Testing Lock Replay detection "
3056 "(Bucket No: 2):\n");
3059 * Server will not grant same Byte Range using a different Bucket Num
3061 lck
.in
.lock_sequence
= 0x020 + 0x1;
3062 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3063 status
= smb2_lock(tree
, &lck
);
3064 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3065 status
= smb2_lock(tree
, &lck
);
3066 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3068 /* status: still locked */
3070 /* test with invalid bucket when file is locked */
3072 torture_comment(torture
, "Testing Lock Replay detection "
3073 "(Bucket No: 65 (invalid)) [ignored]:\n");
3075 lck
.in
.lock_sequence
= 0x410 + 0x1;
3076 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3077 status
= smb2_lock(tree
, &lck
);
3078 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3079 status
= smb2_lock(tree
, &lck
);
3080 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3082 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3083 status
= smb2_lock(tree
, &lck
);
3084 CHECK_STATUS(status
, NT_STATUS_OK
);
3085 status
= smb2_lock(tree
, &lck
);
3086 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3088 /* status: unlocked */
3091 * Lock again for the unlock replay test
3093 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3094 status
= smb2_lock(tree
, &lck
);
3095 CHECK_STATUS(status
, NT_STATUS_OK
);
3097 torture_comment(torture
, "Testing Lock Replay detection "
3098 "(Bucket No: 64):\n");
3101 * Server will not grant same Byte Range using a different Bucket Num
3103 lck
.in
.lock_sequence
= 0x400 + 0x1;
3104 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3105 status
= smb2_lock(tree
, &lck
);
3106 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3107 status
= smb2_lock(tree
, &lck
);
3108 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3111 * Test Unlock replay detection
3113 lck
.in
.lock_sequence
= 0x400 + 0x2;
3114 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3115 status
= smb2_lock(tree
, &lck
);
3116 CHECK_STATUS(status
, NT_STATUS_OK
); /* new seq num ==> unlocked */
3117 status
= smb2_lock(tree
, &lck
);
3118 CHECK_STATUS(status
, NT_STATUS_OK
); /* replay detected ==> ignored */
3120 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3121 status
= smb2_lock(tree
, &lck
); /* same seq num ==> ignored */
3122 CHECK_STATUS(status
, NT_STATUS_OK
);
3124 /* verify it's unlocked: */
3125 lck
.in
.lock_sequence
= 0x400 + 0x3;
3126 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3127 status
= smb2_lock(tree
, &lck
);
3128 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3130 /* status: not locked */
3133 smb2_util_close(tree
, h
);
3134 smb2_deltree(tree
, BASEDIR
);
3139 * Test lock replay detection
3141 * This test check the SMB 3 behaviour of lock sequence checking,
3142 * which should be implemented for all handles.
3144 * Make it clear that this test is supposed to pass a
3145 * server implementing the specification:
3147 * [MS-SMB2] 3.3.5.14 Receiving an SMB2 LOCK Request
3151 * ... if Open.IsResilient or Open.IsDurable or Open.IsPersistent is
3152 * TRUE or if Connection.Dialect belongs to the SMB 3.x dialect family
3153 * and Connection.ServerCapabilities includes
3154 * SMB2_GLOBAL_CAP_MULTI_CHANNEL bit, the server SHOULD<314>
3155 * perform lock sequence verification ...
3159 * <314> Section 3.3.5.14: Windows 7 and Windows Server 2008 R2 perform
3160 * lock sequence verification only when Open.IsResilient is TRUE.
3161 * Windows 8 through Windows 10 v1909 and Windows Server 2012 through
3162 * Windows Server v1909 perform lock sequence verification only when
3163 * Open.IsResilient or Open.IsPersistent is TRUE.
3165 * Note <314> also applies to all versions (at least) up to Windows Server v2004.
3167 * Hopefully this will be fixed in future Windows versions and they
3168 * will avoid Note <314>.
3170 static bool _test_replay_smb3_specification(struct torture_context
*torture
,
3171 struct smb2_tree
*tree
,
3172 const char *testname
,
3177 struct smb2_create io
;
3178 struct smb2_handle h
;
3179 struct smb2_lock lck
;
3180 struct smb2_lock_element el
;
3182 struct smb2_transport
*transport
= tree
->session
->transport
;
3184 if (smbXcli_conn_protocol(transport
->conn
) < PROTOCOL_SMB3_00
) {
3185 torture_skip(torture
, "SMB 3.0.0 Dialect family or above \
3186 required for Lock Replay tests\n");
3189 snprintf(fname
, sizeof(fname
), "%s\\%s.dat", BASEDIR
, testname
);
3191 status
= torture_smb2_testdir(tree
, BASEDIR
, &h
);
3192 CHECK_STATUS(status
, NT_STATUS_OK
);
3193 smb2_util_close(tree
, h
);
3195 torture_comment(torture
, "%s: Testing Open File:\n", testname
);
3197 smb2_oplock_create_share(&io
, fname
,
3198 smb2_util_share_access(""),
3199 smb2_util_oplock_level("b"));
3200 io
.in
.durable_open
= use_durable
;
3202 status
= smb2_create(tree
, torture
, &io
);
3203 CHECK_STATUS(status
, NT_STATUS_OK
);
3204 h
= io
.out
.file
.handle
;
3205 CHECK_VALUE(io
.out
.oplock_level
, smb2_util_oplock_level("b"));
3206 CHECK_VALUE(io
.out
.durable_open
, use_durable
);
3207 CHECK_VALUE(io
.out
.durable_open_v2
, false);
3208 CHECK_VALUE(io
.out
.persistent_open
, false);
3211 * Setup initial parameters
3213 el
= (struct smb2_lock_element
) {
3217 lck
= (struct smb2_lock
) {
3219 .in
.lock_count
= 0x0001,
3223 torture_comment(torture
,
3224 "Testing SMB 3 LockSequence for all Handles\n");
3227 * Test with an invalid bucket number (only 1..64 are valid).
3228 * With an invalid number, lock replay detection is not performed.
3230 torture_comment(torture
, "Testing Lock (ignored) Replay detection "
3231 "(Bucket No: 0 (invalid)) [ignored]:\n");
3232 lck
.in
.lock_sequence
= 0x000 + 0x1;
3233 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3234 status
= smb2_lock(tree
, &lck
);
3235 CHECK_STATUS(status
, NT_STATUS_OK
);
3236 status
= smb2_lock(tree
, &lck
);
3237 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3239 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3240 status
= smb2_lock(tree
, &lck
);
3241 CHECK_STATUS(status
, NT_STATUS_OK
);
3242 status
= smb2_lock(tree
, &lck
);
3243 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3245 torture_comment(torture
, "Testing Lock Replay detection "
3246 "(Bucket No: 1):\n");
3249 * Obtain Exclusive Lock of length 100 bytes using Bucket Num 1
3252 lck
.in
.lock_sequence
= 0x010 + 0x1;
3253 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3254 status
= smb2_lock(tree
, &lck
);
3255 CHECK_STATUS(status
, NT_STATUS_OK
);
3258 * Server detects Replay of Byte Range locks using the Lock Sequence
3259 * Numbers. And ignores the requests completely.
3261 status
= smb2_lock(tree
, &lck
);
3262 CHECK_STATUS(status
, NT_STATUS_OK
);
3263 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3264 status
= smb2_lock(tree
, &lck
);
3265 CHECK_STATUS(status
, NT_STATUS_OK
);
3266 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3267 status
= smb2_lock(tree
, &lck
);
3268 CHECK_STATUS(status
, NT_STATUS_OK
);
3269 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3270 status
= smb2_lock(tree
, &lck
);
3271 CHECK_STATUS(status
, NT_STATUS_OK
);
3272 status
= smb2_lock(tree
, &lck
);
3273 CHECK_STATUS(status
, NT_STATUS_OK
);
3275 /* status: still locked */
3278 * Server will not grant same Byte Range using a different Bucket Seq
3280 lck
.in
.lock_sequence
= 0x010 + 0x2;
3281 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3282 status
= smb2_lock(tree
, &lck
);
3283 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3284 status
= smb2_lock(tree
, &lck
);
3285 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3287 torture_comment(torture
, "Testing Lock Replay detection "
3288 "(Bucket No: 2):\n");
3291 * Server will not grant same Byte Range using a different Bucket Num
3293 lck
.in
.lock_sequence
= 0x020 + 0x1;
3294 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3295 status
= smb2_lock(tree
, &lck
);
3296 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3297 status
= smb2_lock(tree
, &lck
);
3298 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3300 /* status: still locked */
3302 /* test with invalid bucket when file is locked */
3304 torture_comment(torture
, "Testing Lock Replay detection "
3305 "(Bucket No: 65 (invalid)) [ignored]:\n");
3307 lck
.in
.lock_sequence
= 0x410 + 0x1;
3308 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3309 status
= smb2_lock(tree
, &lck
);
3310 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3311 status
= smb2_lock(tree
, &lck
);
3312 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3314 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3315 status
= smb2_lock(tree
, &lck
);
3316 CHECK_STATUS(status
, NT_STATUS_OK
);
3317 status
= smb2_lock(tree
, &lck
);
3318 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3320 /* status: unlocked */
3323 * Lock again for the unlock replay test
3325 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3326 status
= smb2_lock(tree
, &lck
);
3327 CHECK_STATUS(status
, NT_STATUS_OK
);
3329 torture_comment(torture
, "Testing Lock Replay detection "
3330 "(Bucket No: 64):\n");
3333 * Server will not grant same Byte Range using a different Bucket Num
3335 lck
.in
.lock_sequence
= 0x400 + 0x1;
3336 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3337 status
= smb2_lock(tree
, &lck
);
3338 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3339 status
= smb2_lock(tree
, &lck
);
3340 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
3343 * Test Unlock replay detection
3345 lck
.in
.lock_sequence
= 0x400 + 0x2;
3346 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3347 status
= smb2_lock(tree
, &lck
);
3348 CHECK_STATUS(status
, NT_STATUS_OK
); /* new seq num ==> unlocked */
3349 status
= smb2_lock(tree
, &lck
);
3350 CHECK_STATUS(status
, NT_STATUS_OK
); /* replay detected ==> ignored */
3352 el
.flags
= SMB2_LOCK_FLAG_EXCLUSIVE
| SMB2_LOCK_FLAG_FAIL_IMMEDIATELY
;
3353 status
= smb2_lock(tree
, &lck
); /* same seq num ==> ignored */
3354 CHECK_STATUS(status
, NT_STATUS_OK
);
3356 /* verify it's unlocked: */
3357 lck
.in
.lock_sequence
= 0x400 + 0x3;
3358 el
.flags
= SMB2_LOCK_FLAG_UNLOCK
;
3359 status
= smb2_lock(tree
, &lck
);
3360 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
3362 /* status: not locked */
3365 smb2_util_close(tree
, h
);
3366 smb2_deltree(tree
, BASEDIR
);
3370 static bool test_replay_smb3_specification_durable(struct torture_context
*torture
,
3371 struct smb2_tree
*tree
)
3373 const char *testname
= "replay_smb3_specification_durable";
3374 struct smb2_transport
*transport
= tree
->session
->transport
;
3376 if (smbXcli_conn_protocol(transport
->conn
) < PROTOCOL_SMB2_10
) {
3377 torture_skip(torture
, "SMB 2.1.0 Dialect family or above \
3378 required for Lock Replay tests on durable handles\n");
3381 return _test_replay_smb3_specification(torture
, tree
, testname
, true);
3384 static bool test_replay_smb3_specification_multi(struct torture_context
*torture
,
3385 struct smb2_tree
*tree
)
3387 const char *testname
= "replay_smb3_specification_multi";
3388 struct smb2_transport
*transport
= tree
->session
->transport
;
3389 uint32_t server_capabilities
;
3391 if (smbXcli_conn_protocol(transport
->conn
) < PROTOCOL_SMB3_00
) {
3392 torture_skip(torture
, "SMB 3.0.0 Dialect family or above \
3393 required for Lock Replay tests on without durable handles\n");
3396 server_capabilities
= smb2cli_conn_server_capabilities(transport
->conn
);
3397 if (!(server_capabilities
& SMB2_CAP_MULTI_CHANNEL
)) {
3398 torture_skip(torture
, "MULTI_CHANNEL is \
3399 required for Lock Replay tests on without durable handles\n");
3402 return _test_replay_smb3_specification(torture
, tree
, testname
, false);
3406 * Test lock interaction between smbd and ctdb with tombstone records.
3408 * Re-locking an unlocked record could lead to a deadlock between
3409 * smbd and ctdb. Make sure we don't regress.
3411 * https://bugzilla.samba.org/show_bug.cgi?id=12005
3412 * https://bugzilla.samba.org/show_bug.cgi?id=10008
3414 static bool test_deadlock(struct torture_context
*torture
,
3415 struct smb2_tree
*tree
)
3419 struct smb2_handle _h
;
3420 struct smb2_handle
*h
= NULL
;
3422 const char *fname
= BASEDIR
"\\deadlock.txt";
3424 if (!lpcfg_clustering(torture
->lp_ctx
)) {
3425 torture_skip(torture
, "Test must be run on a ctdb cluster\n");
3429 status
= torture_smb2_testdir(tree
, BASEDIR
, &_h
);
3430 torture_assert_ntstatus_ok(torture
, status
,
3431 "torture_smb2_testdir failed");
3432 smb2_util_close(tree
, _h
);
3434 status
= torture_smb2_testfile(tree
, fname
, &_h
);
3435 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3436 "torture_smb2_testfile failed");
3440 status
= smb2_util_write(tree
, *h
, buf
, 0, ARRAY_SIZE(buf
));
3441 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3442 "smb2_util_write failed");
3444 status
= test_smb2_lock(tree
, *h
, 0, 1, true);
3445 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3446 "test_smb2_lock failed");
3448 status
= test_smb2_unlock(tree
, *h
, 0, 1);
3449 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3450 "test_smb2_unlock failed");
3452 status
= test_smb2_lock(tree
, *h
, 0, 1, true);
3453 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3454 "test_smb2_lock failed");
3456 status
= test_smb2_unlock(tree
, *h
, 0, 1);
3457 torture_assert_ntstatus_ok_goto(torture
, status
, ret
, done
,
3458 "test_smb2_unlock failed");
3462 smb2_util_close(tree
, *h
);
3464 smb2_deltree(tree
, BASEDIR
);
3468 /* basic testing of SMB2 locking
3470 struct torture_suite
*torture_smb2_lock_init(TALLOC_CTX
*ctx
)
3472 struct torture_suite
*suite
=
3473 torture_suite_create(ctx
, "lock");
3474 torture_suite_add_1smb2_test(suite
, "valid-request",
3475 test_valid_request
);
3476 torture_suite_add_1smb2_test(suite
, "rw-none", test_lock_rw_none
);
3477 torture_suite_add_1smb2_test(suite
, "rw-shared", test_lock_rw_shared
);
3478 torture_suite_add_1smb2_test(suite
, "rw-exclusive",
3479 test_lock_rw_exclusive
);
3480 torture_suite_add_1smb2_test(suite
, "auto-unlock",
3481 test_lock_auto_unlock
);
3482 torture_suite_add_1smb2_test(suite
, "lock", test_lock
);
3483 torture_suite_add_1smb2_test(suite
, "async", test_async
);
3484 torture_suite_add_1smb2_test(suite
, "cancel", test_cancel
);
3485 torture_suite_add_1smb2_test(suite
, "cancel-tdis", test_cancel_tdis
);
3486 torture_suite_add_1smb2_test(suite
, "cancel-logoff",
3487 test_cancel_logoff
);
3488 torture_suite_add_1smb2_test(suite
, "errorcode", test_errorcode
);
3489 torture_suite_add_1smb2_test(suite
, "zerobytelength",
3490 test_zerobytelength
);
3491 torture_suite_add_1smb2_test(suite
, "zerobyteread",
3493 torture_suite_add_1smb2_test(suite
, "unlock", test_unlock
);
3494 torture_suite_add_1smb2_test(suite
, "multiple-unlock",
3495 test_multiple_unlock
);
3496 torture_suite_add_1smb2_test(suite
, "stacking", test_stacking
);
3497 torture_suite_add_1smb2_test(suite
, "contend", test_contend
);
3498 torture_suite_add_1smb2_test(suite
, "context", test_context
);
3499 torture_suite_add_1smb2_test(suite
, "range", test_range
);
3500 torture_suite_add_2smb2_test(suite
, "overlap", test_overlap
);
3501 torture_suite_add_1smb2_test(suite
, "truncate", test_truncate
);
3502 torture_suite_add_1smb2_test(suite
, "replay_broken_windows",
3503 test_replay_broken_windows
);
3504 torture_suite_add_1smb2_test(suite
, "replay_smb3_specification_durable",
3505 test_replay_smb3_specification_durable
);
3506 torture_suite_add_1smb2_test(suite
, "replay_smb3_specification_multi",
3507 test_replay_smb3_specification_multi
);
3508 torture_suite_add_1smb2_test(suite
, "ctdb-delrec-deadlock", test_deadlock
);
3510 suite
->description
= talloc_strdup(suite
, "SMB2-LOCK tests");