2 Unix SMB/CIFS implementation.
3 test suite for various lock operations
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28 #include "libcli/composite/composite.h"
29 #include "libcli/smb_composite/smb_composite.h"
30 #include "lib/cmdline/popt_common.h"
32 #define CHECK_STATUS(status, correct) do { \
33 if (!NT_STATUS_EQUAL(status, correct)) { \
34 printf("(%s) Incorrect status %s - should be %s\n", \
35 __location__, nt_errstr(status), nt_errstr(correct)); \
40 #define CHECK_VALUE(v, correct) do { \
41 if ((v) != (correct)) { \
42 printf("(%s) Incorrect value %s=%d - should be %d\n", \
43 __location__, #v, v, correct); \
48 #define BASEDIR "\\testlock"
52 test SMBlock and SMBunlock ops
54 static BOOL
test_lock(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
60 const char *fname
= BASEDIR
"\\test.txt";
62 if (!torture_setup_dir(cli
, BASEDIR
)) {
66 printf("Testing RAW_LOCK_LOCK\n");
67 io
.generic
.level
= RAW_LOCK_LOCK
;
69 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
71 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
76 printf("Trying 0/0 lock\n");
77 io
.lock
.level
= RAW_LOCK_LOCK
;
78 io
.lock
.in
.file
.fnum
= fnum
;
80 io
.lock
.in
.offset
= 0;
81 status
= smb_raw_lock(cli
->tree
, &io
);
82 CHECK_STATUS(status
, NT_STATUS_OK
);
84 status
= smb_raw_lock(cli
->tree
, &io
);
85 CHECK_STATUS(status
, NT_STATUS_OK
);
87 io
.lock
.level
= RAW_LOCK_UNLOCK
;
88 status
= smb_raw_lock(cli
->tree
, &io
);
89 CHECK_STATUS(status
, NT_STATUS_OK
);
91 printf("Trying 0/1 lock\n");
92 io
.lock
.level
= RAW_LOCK_LOCK
;
93 io
.lock
.in
.file
.fnum
= fnum
;
95 io
.lock
.in
.offset
= 0;
96 status
= smb_raw_lock(cli
->tree
, &io
);
97 CHECK_STATUS(status
, NT_STATUS_OK
);
99 status
= smb_raw_lock(cli
->tree
, &io
);
100 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
102 io
.lock
.level
= RAW_LOCK_UNLOCK
;
103 status
= smb_raw_lock(cli
->tree
, &io
);
104 CHECK_STATUS(status
, NT_STATUS_OK
);
105 io
.lock
.level
= RAW_LOCK_UNLOCK
;
106 status
= smb_raw_lock(cli
->tree
, &io
);
107 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
109 printf("Trying 0xEEFFFFFF lock\n");
110 io
.lock
.level
= RAW_LOCK_LOCK
;
111 io
.lock
.in
.file
.fnum
= fnum
;
112 io
.lock
.in
.count
= 4000;
113 io
.lock
.in
.offset
= 0xEEFFFFFF;
114 status
= smb_raw_lock(cli
->tree
, &io
);
115 CHECK_STATUS(status
, NT_STATUS_OK
);
117 status
= smb_raw_lock(cli
->tree
, &io
);
118 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
120 io
.lock
.level
= RAW_LOCK_UNLOCK
;
121 status
= smb_raw_lock(cli
->tree
, &io
);
122 CHECK_STATUS(status
, NT_STATUS_OK
);
123 io
.lock
.level
= RAW_LOCK_UNLOCK
;
124 status
= smb_raw_lock(cli
->tree
, &io
);
125 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
127 printf("Trying 0xEF000000 lock\n");
128 io
.lock
.level
= RAW_LOCK_LOCK
;
129 io
.lock
.in
.file
.fnum
= fnum
;
130 io
.lock
.in
.count
= 4000;
131 io
.lock
.in
.offset
= 0xEEFFFFFF;
132 status
= smb_raw_lock(cli
->tree
, &io
);
133 CHECK_STATUS(status
, NT_STATUS_OK
);
135 status
= smb_raw_lock(cli
->tree
, &io
);
136 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
138 io
.lock
.level
= RAW_LOCK_UNLOCK
;
139 status
= smb_raw_lock(cli
->tree
, &io
);
140 CHECK_STATUS(status
, NT_STATUS_OK
);
141 io
.lock
.level
= RAW_LOCK_UNLOCK
;
142 status
= smb_raw_lock(cli
->tree
, &io
);
143 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
145 printf("Trying max lock\n");
146 io
.lock
.level
= RAW_LOCK_LOCK
;
147 io
.lock
.in
.file
.fnum
= fnum
;
148 io
.lock
.in
.count
= 4000;
149 io
.lock
.in
.offset
= 0xEF000000;
150 status
= smb_raw_lock(cli
->tree
, &io
);
151 CHECK_STATUS(status
, NT_STATUS_OK
);
153 status
= smb_raw_lock(cli
->tree
, &io
);
154 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
156 io
.lock
.level
= RAW_LOCK_UNLOCK
;
157 status
= smb_raw_lock(cli
->tree
, &io
);
158 CHECK_STATUS(status
, NT_STATUS_OK
);
159 io
.lock
.level
= RAW_LOCK_UNLOCK
;
160 status
= smb_raw_lock(cli
->tree
, &io
);
161 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
163 printf("Trying wrong pid unlock\n");
164 io
.lock
.level
= RAW_LOCK_LOCK
;
165 io
.lock
.in
.file
.fnum
= fnum
;
166 io
.lock
.in
.count
= 4002;
167 io
.lock
.in
.offset
= 10001;
168 status
= smb_raw_lock(cli
->tree
, &io
);
169 CHECK_STATUS(status
, NT_STATUS_OK
);
171 io
.lock
.level
= RAW_LOCK_UNLOCK
;
172 status
= smb_raw_lock(cli
->tree
, &io
);
173 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
175 status
= smb_raw_lock(cli
->tree
, &io
);
176 CHECK_STATUS(status
, NT_STATUS_OK
);
179 smbcli_close(cli
->tree
, fnum
);
180 smb_raw_exit(cli
->session
);
181 smbcli_deltree(cli
->tree
, BASEDIR
);
189 static BOOL
test_lockx(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
192 struct smb_lock_entry lock
[1];
196 const char *fname
= BASEDIR
"\\test.txt";
198 if (!torture_setup_dir(cli
, BASEDIR
)) {
202 printf("Testing RAW_LOCK_LOCKX\n");
203 io
.generic
.level
= RAW_LOCK_LOCKX
;
205 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
207 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
212 io
.lockx
.level
= RAW_LOCK_LOCKX
;
213 io
.lockx
.in
.file
.fnum
= fnum
;
214 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
215 io
.lockx
.in
.timeout
= 0;
216 io
.lockx
.in
.ulock_cnt
= 0;
217 io
.lockx
.in
.lock_cnt
= 1;
218 lock
[0].pid
= cli
->session
->pid
;
221 io
.lockx
.in
.locks
= &lock
[0];
222 status
= smb_raw_lock(cli
->tree
, &io
);
223 CHECK_STATUS(status
, NT_STATUS_OK
);
226 printf("Trying 0xEEFFFFFF lock\n");
227 io
.lockx
.in
.ulock_cnt
= 0;
228 io
.lockx
.in
.lock_cnt
= 1;
229 lock
[0].count
= 4000;
230 lock
[0].offset
= 0xEEFFFFFF;
231 status
= smb_raw_lock(cli
->tree
, &io
);
232 CHECK_STATUS(status
, NT_STATUS_OK
);
234 status
= smb_raw_lock(cli
->tree
, &io
);
235 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
237 io
.lockx
.in
.ulock_cnt
= 1;
238 io
.lockx
.in
.lock_cnt
= 0;
239 status
= smb_raw_lock(cli
->tree
, &io
);
240 CHECK_STATUS(status
, NT_STATUS_OK
);
241 status
= smb_raw_lock(cli
->tree
, &io
);
242 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
244 printf("Trying 0xEF000000 lock\n");
245 io
.lockx
.in
.ulock_cnt
= 0;
246 io
.lockx
.in
.lock_cnt
= 1;
247 lock
[0].count
= 4000;
248 lock
[0].offset
= 0xEF000000;
249 status
= smb_raw_lock(cli
->tree
, &io
);
250 CHECK_STATUS(status
, NT_STATUS_OK
);
252 status
= smb_raw_lock(cli
->tree
, &io
);
253 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
255 io
.lockx
.in
.ulock_cnt
= 1;
256 io
.lockx
.in
.lock_cnt
= 0;
257 status
= smb_raw_lock(cli
->tree
, &io
);
258 CHECK_STATUS(status
, NT_STATUS_OK
);
259 status
= smb_raw_lock(cli
->tree
, &io
);
260 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
262 printf("Trying zero lock\n");
263 io
.lockx
.in
.ulock_cnt
= 0;
264 io
.lockx
.in
.lock_cnt
= 1;
267 status
= smb_raw_lock(cli
->tree
, &io
);
268 CHECK_STATUS(status
, NT_STATUS_OK
);
270 status
= smb_raw_lock(cli
->tree
, &io
);
271 CHECK_STATUS(status
, NT_STATUS_OK
);
273 io
.lockx
.in
.ulock_cnt
= 1;
274 io
.lockx
.in
.lock_cnt
= 0;
275 status
= smb_raw_lock(cli
->tree
, &io
);
276 CHECK_STATUS(status
, NT_STATUS_OK
);
277 status
= smb_raw_lock(cli
->tree
, &io
);
278 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
280 printf("Trying max lock\n");
281 io
.lockx
.in
.ulock_cnt
= 0;
282 io
.lockx
.in
.lock_cnt
= 1;
285 status
= smb_raw_lock(cli
->tree
, &io
);
286 CHECK_STATUS(status
, NT_STATUS_OK
);
288 status
= smb_raw_lock(cli
->tree
, &io
);
289 CHECK_STATUS(status
, NT_STATUS_OK
);
291 io
.lockx
.in
.ulock_cnt
= 1;
292 io
.lockx
.in
.lock_cnt
= 0;
293 status
= smb_raw_lock(cli
->tree
, &io
);
294 CHECK_STATUS(status
, NT_STATUS_OK
);
295 status
= smb_raw_lock(cli
->tree
, &io
);
296 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
298 printf("Trying 2^63\n");
299 io
.lockx
.in
.ulock_cnt
= 0;
300 io
.lockx
.in
.lock_cnt
= 1;
303 lock
[0].offset
<<= 63;
304 status
= smb_raw_lock(cli
->tree
, &io
);
305 CHECK_STATUS(status
, NT_STATUS_OK
);
307 status
= smb_raw_lock(cli
->tree
, &io
);
308 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
310 io
.lockx
.in
.ulock_cnt
= 1;
311 io
.lockx
.in
.lock_cnt
= 0;
312 status
= smb_raw_lock(cli
->tree
, &io
);
313 CHECK_STATUS(status
, NT_STATUS_OK
);
314 status
= smb_raw_lock(cli
->tree
, &io
);
315 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
317 printf("Trying 2^63 - 1\n");
318 io
.lockx
.in
.ulock_cnt
= 0;
319 io
.lockx
.in
.lock_cnt
= 1;
322 lock
[0].offset
<<= 63;
324 status
= smb_raw_lock(cli
->tree
, &io
);
325 CHECK_STATUS(status
, NT_STATUS_OK
);
327 status
= smb_raw_lock(cli
->tree
, &io
);
328 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
330 io
.lockx
.in
.ulock_cnt
= 1;
331 io
.lockx
.in
.lock_cnt
= 0;
332 status
= smb_raw_lock(cli
->tree
, &io
);
333 CHECK_STATUS(status
, NT_STATUS_OK
);
334 status
= smb_raw_lock(cli
->tree
, &io
);
335 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
337 printf("Trying max lock 2\n");
338 io
.lockx
.in
.ulock_cnt
= 0;
339 io
.lockx
.in
.lock_cnt
= 1;
342 status
= smb_raw_lock(cli
->tree
, &io
);
343 CHECK_STATUS(status
, NT_STATUS_OK
);
346 status
= smb_raw_lock(cli
->tree
, &io
);
347 CHECK_STATUS(status
, NT_STATUS_OK
);
349 io
.lockx
.in
.ulock_cnt
= 1;
350 io
.lockx
.in
.lock_cnt
= 0;
352 status
= smb_raw_lock(cli
->tree
, &io
);
353 CHECK_STATUS(status
, NT_STATUS_OK
);
354 status
= smb_raw_lock(cli
->tree
, &io
);
355 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
358 smbcli_close(cli
->tree
, fnum
);
359 smb_raw_exit(cli
->session
);
360 smbcli_deltree(cli
->tree
, BASEDIR
);
368 static BOOL
test_pidhigh(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
371 struct smb_lock_entry lock
[1];
375 const char *fname
= BASEDIR
"\\test.txt";
378 if (!torture_setup_dir(cli
, BASEDIR
)) {
382 printf("Testing high pid\n");
383 io
.generic
.level
= RAW_LOCK_LOCKX
;
385 cli
->session
->pid
= 1;
387 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
389 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
394 if (smbcli_write(cli
->tree
, fnum
, 0, &c
, 0, 1) != 1) {
395 printf("Failed to write 1 byte - %s\n", smbcli_errstr(cli
->tree
));
400 io
.lockx
.level
= RAW_LOCK_LOCKX
;
401 io
.lockx
.in
.file
.fnum
= fnum
;
402 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
403 io
.lockx
.in
.timeout
= 0;
404 io
.lockx
.in
.ulock_cnt
= 0;
405 io
.lockx
.in
.lock_cnt
= 1;
406 lock
[0].pid
= cli
->session
->pid
;
408 lock
[0].count
= 0xFFFFFFFF;
409 io
.lockx
.in
.locks
= &lock
[0];
410 status
= smb_raw_lock(cli
->tree
, &io
);
411 CHECK_STATUS(status
, NT_STATUS_OK
);
413 if (smbcli_read(cli
->tree
, fnum
, &c
, 0, 1) != 1) {
414 printf("Failed to read 1 byte - %s\n", smbcli_errstr(cli
->tree
));
419 cli
->session
->pid
|= 0x10000;
421 cli
->session
->pid
= 2;
423 if (smbcli_read(cli
->tree
, fnum
, &c
, 0, 1) == 1) {
424 printf("pid is incorrect handled for read with lock!\n");
429 cli
->session
->pid
= 0x10001;
431 if (smbcli_read(cli
->tree
, fnum
, &c
, 0, 1) != 1) {
432 printf("High pid is used on this server!\n");
435 printf("High pid is not used on this server (correct)\n");
439 smbcli_close(cli
->tree
, fnum
);
440 smb_raw_exit(cli
->session
);
441 smbcli_deltree(cli
->tree
, BASEDIR
);
447 test locking&X async operation
449 static BOOL
test_async(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
451 struct smbcli_session
*session
;
452 struct smb_composite_sesssetup setup
;
453 struct smbcli_tree
*tree
;
455 const char *host
, *share
;
457 struct smb_lock_entry lock
[2];
461 const char *fname
= BASEDIR
"\\test.txt";
463 struct smbcli_request
*req
;
465 if (!torture_setup_dir(cli
, BASEDIR
)) {
469 printf("Testing LOCKING_ANDX_CANCEL_LOCK\n");
470 io
.generic
.level
= RAW_LOCK_LOCKX
;
472 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
474 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
479 io
.lockx
.level
= RAW_LOCK_LOCKX
;
480 io
.lockx
.in
.file
.fnum
= fnum
;
481 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
482 io
.lockx
.in
.timeout
= 0;
483 io
.lockx
.in
.ulock_cnt
= 0;
484 io
.lockx
.in
.lock_cnt
= 1;
485 lock
[0].pid
= cli
->session
->pid
;
486 lock
[0].offset
= 100;
488 io
.lockx
.in
.locks
= &lock
[0];
489 status
= smb_raw_lock(cli
->tree
, &io
);
490 CHECK_STATUS(status
, NT_STATUS_OK
);
494 printf("testing cancel by CANCEL_LOCK\n");
496 /* setup a timed lock */
497 io
.lockx
.in
.timeout
= 10000;
498 req
= smb_raw_lock_send(cli
->tree
, &io
);
500 printf("Failed to setup timed lock (%s)\n", __location__
);
505 /* cancel the wrong range */
507 io
.lockx
.in
.timeout
= 0;
508 io
.lockx
.in
.mode
= LOCKING_ANDX_CANCEL_LOCK
;
509 status
= smb_raw_lock(cli
->tree
, &io
);
510 CHECK_STATUS(status
, NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
));
512 /* cancel with the wrong bits set */
513 lock
[0].offset
= 100;
514 io
.lockx
.in
.timeout
= 0;
515 io
.lockx
.in
.mode
= LOCKING_ANDX_CANCEL_LOCK
;
516 status
= smb_raw_lock(cli
->tree
, &io
);
517 CHECK_STATUS(status
, NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
));
519 /* cancel the right range */
520 lock
[0].offset
= 100;
521 io
.lockx
.in
.timeout
= 0;
522 io
.lockx
.in
.mode
= LOCKING_ANDX_CANCEL_LOCK
| LOCKING_ANDX_LARGE_FILES
;
523 status
= smb_raw_lock(cli
->tree
, &io
);
524 CHECK_STATUS(status
, NT_STATUS_OK
);
526 /* receive the failed lock request */
527 status
= smbcli_request_simple_recv(req
);
528 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
530 if (time(NULL
) > t
+2) {
531 printf("lock cancel was not immediate (%s)\n", __location__
);
536 printf("testing cancel by unlock\n");
537 io
.lockx
.in
.ulock_cnt
= 0;
538 io
.lockx
.in
.lock_cnt
= 1;
539 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
540 io
.lockx
.in
.timeout
= 0;
541 status
= smb_raw_lock(cli
->tree
, &io
);
542 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
544 io
.lockx
.in
.timeout
= 5000;
545 req
= smb_raw_lock_send(cli
->tree
, &io
);
547 printf("Failed to setup timed lock (%s)\n", __location__
);
552 io
.lockx
.in
.ulock_cnt
= 1;
553 io
.lockx
.in
.lock_cnt
= 0;
554 status
= smb_raw_lock(cli
->tree
, &io
);
555 CHECK_STATUS(status
, NT_STATUS_OK
);
558 status
= smbcli_request_simple_recv(req
);
559 CHECK_STATUS(status
, NT_STATUS_OK
);
561 if (time(NULL
) > t
+2) {
562 printf("lock cancel by unlock was not immediate (%s) - took %d secs\n",
563 __location__
, (int)(time(NULL
)-t
));
568 printf("testing cancel by close\n");
569 io
.lockx
.in
.ulock_cnt
= 0;
570 io
.lockx
.in
.lock_cnt
= 1;
571 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
572 io
.lockx
.in
.timeout
= 0;
573 status
= smb_raw_lock(cli
->tree
, &io
);
574 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
577 io
.lockx
.in
.timeout
= 10000;
578 req
= smb_raw_lock_send(cli
->tree
, &io
);
580 printf("Failed to setup timed lock (%s)\n", __location__
);
585 status
= smbcli_close(cli
->tree
, fnum
);
586 CHECK_STATUS(status
, NT_STATUS_OK
);
588 status
= smbcli_request_simple_recv(req
);
589 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
591 if (time(NULL
) > t
+2) {
592 printf("lock cancel by close was not immediate (%s)\n", __location__
);
597 printf("create a new sessions\n");
598 session
= smbcli_session_init(cli
->transport
, mem_ctx
, False
);
599 setup
.in
.sesskey
= cli
->transport
->negotiate
.sesskey
;
600 setup
.in
.capabilities
= cli
->transport
->negotiate
.capabilities
;
601 setup
.in
.workgroup
= lp_workgroup();
602 setup
.in
.credentials
= cmdline_credentials
;
603 status
= smb_composite_sesssetup(session
, &setup
);
604 CHECK_STATUS(status
, NT_STATUS_OK
);
605 session
->vuid
= setup
.out
.vuid
;
607 printf("create new tree context\n");
608 share
= lp_parm_string(-1, "torture", "share");
609 host
= lp_parm_string(-1, "torture", "host");
610 tree
= smbcli_tree_init(session
, mem_ctx
, False
);
611 tcon
.generic
.level
= RAW_TCON_TCONX
;
612 tcon
.tconx
.in
.flags
= 0;
613 tcon
.tconx
.in
.password
= data_blob(NULL
, 0);
614 tcon
.tconx
.in
.path
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s", host
, share
);
615 tcon
.tconx
.in
.device
= "A:";
616 status
= smb_raw_tcon(tree
, mem_ctx
, &tcon
);
617 CHECK_STATUS(status
, NT_STATUS_OK
);
618 tree
->tid
= tcon
.tconx
.out
.tid
;
620 printf("testing cancel by exit\n");
621 fname
= BASEDIR
"\\test_exit.txt";
622 fnum
= smbcli_open(tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
624 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(tree
));
628 io
.lockx
.level
= RAW_LOCK_LOCKX
;
629 io
.lockx
.in
.file
.fnum
= fnum
;
630 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
631 io
.lockx
.in
.timeout
= 0;
632 io
.lockx
.in
.ulock_cnt
= 0;
633 io
.lockx
.in
.lock_cnt
= 1;
634 lock
[0].pid
= session
->pid
;
635 lock
[0].offset
= 100;
637 io
.lockx
.in
.locks
= &lock
[0];
638 status
= smb_raw_lock(tree
, &io
);
639 CHECK_STATUS(status
, NT_STATUS_OK
);
641 io
.lockx
.in
.ulock_cnt
= 0;
642 io
.lockx
.in
.lock_cnt
= 1;
643 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
644 io
.lockx
.in
.timeout
= 0;
645 status
= smb_raw_lock(tree
, &io
);
646 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
648 io
.lockx
.in
.timeout
= 10000;
650 req
= smb_raw_lock_send(tree
, &io
);
652 printf("Failed to setup timed lock (%s)\n", __location__
);
657 status
= smb_raw_exit(session
);
658 CHECK_STATUS(status
, NT_STATUS_OK
);
660 status
= smbcli_request_simple_recv(req
);
661 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
663 if (time(NULL
) > t
+2) {
664 printf("lock cancel by exit was not immediate (%s)\n", __location__
);
669 printf("testing cancel by ulogoff\n");
670 fname
= BASEDIR
"\\test_ulogoff.txt";
671 fnum
= smbcli_open(tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
673 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(tree
));
677 io
.lockx
.level
= RAW_LOCK_LOCKX
;
678 io
.lockx
.in
.file
.fnum
= fnum
;
679 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
680 io
.lockx
.in
.timeout
= 0;
681 io
.lockx
.in
.ulock_cnt
= 0;
682 io
.lockx
.in
.lock_cnt
= 1;
683 lock
[0].pid
= session
->pid
;
684 lock
[0].offset
= 100;
686 io
.lockx
.in
.locks
= &lock
[0];
687 status
= smb_raw_lock(tree
, &io
);
688 CHECK_STATUS(status
, NT_STATUS_OK
);
690 io
.lockx
.in
.ulock_cnt
= 0;
691 io
.lockx
.in
.lock_cnt
= 1;
692 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
693 io
.lockx
.in
.timeout
= 0;
694 status
= smb_raw_lock(tree
, &io
);
695 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
697 io
.lockx
.in
.timeout
= 10000;
699 req
= smb_raw_lock_send(tree
, &io
);
701 printf("Failed to setup timed lock (%s)\n", __location__
);
706 status
= smb_raw_ulogoff(session
);
707 CHECK_STATUS(status
, NT_STATUS_OK
);
709 status
= smbcli_request_simple_recv(req
);
710 if (NT_STATUS_EQUAL(NT_STATUS_FILE_LOCK_CONFLICT
, status
)) {
711 printf("lock not canceled by ulogoff - %s (ignored because of vfs_vifs fails it)\n",
713 smb_tree_disconnect(tree
);
714 smb_raw_exit(session
);
717 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
719 if (time(NULL
) > t
+2) {
720 printf("lock cancel by ulogoff was not immediate (%s)\n", __location__
);
725 printf("testing cancel by tdis\n");
726 tree
->session
= cli
->session
;
728 fname
= BASEDIR
"\\test_tdis.txt";
729 fnum
= smbcli_open(tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
731 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(tree
));
735 io
.lockx
.level
= RAW_LOCK_LOCKX
;
736 io
.lockx
.in
.file
.fnum
= fnum
;
737 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
738 io
.lockx
.in
.timeout
= 0;
739 io
.lockx
.in
.ulock_cnt
= 0;
740 io
.lockx
.in
.lock_cnt
= 1;
741 lock
[0].pid
= cli
->session
->pid
;
742 lock
[0].offset
= 100;
744 io
.lockx
.in
.locks
= &lock
[0];
745 status
= smb_raw_lock(tree
, &io
);
746 CHECK_STATUS(status
, NT_STATUS_OK
);
748 status
= smb_raw_lock(tree
, &io
);
749 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
751 io
.lockx
.in
.timeout
= 10000;
753 req
= smb_raw_lock_send(tree
, &io
);
755 printf("Failed to setup timed lock (%s)\n", __location__
);
760 status
= smb_tree_disconnect(tree
);
761 CHECK_STATUS(status
, NT_STATUS_OK
);
763 status
= smbcli_request_simple_recv(req
);
764 CHECK_STATUS(status
, NT_STATUS_RANGE_NOT_LOCKED
);
766 if (time(NULL
) > t
+2) {
767 printf("lock cancel by tdis was not immediate (%s)\n", __location__
);
773 smb_raw_exit(cli
->session
);
774 smbcli_deltree(cli
->tree
, BASEDIR
);
779 test NT_STATUS_LOCK_NOT_GRANTED vs. NT_STATUS_FILE_LOCK_CONFLICT
781 static BOOL
test_errorcode(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
785 struct smb_lock_entry lock
[2];
790 struct smbcli_request
*req
;
794 if (!torture_setup_dir(cli
, BASEDIR
)) {
798 printf("Testing LOCK_NOT_GRANTED vs. FILE_LOCK_CONFLICT\n");
800 printf("testing with timeout = 0\n");
801 fname
= BASEDIR
"\\test0.txt";
805 * the first run is with t = 0,
806 * the second with t > 0 (=1)
810 * use the DENY_DOS mode, that creates two fnum's of one low-level file handle,
811 * this demonstrates that the cache is per fnum
813 op
.openx
.level
= RAW_OPEN_OPENX
;
814 op
.openx
.in
.fname
= fname
;
815 op
.openx
.in
.flags
= OPENX_FLAGS_ADDITIONAL_INFO
;
816 op
.openx
.in
.open_mode
= OPENX_MODE_ACCESS_RDWR
| OPENX_MODE_DENY_DOS
;
817 op
.openx
.in
.open_func
= OPENX_OPEN_FUNC_OPEN
| OPENX_OPEN_FUNC_CREATE
;
818 op
.openx
.in
.search_attrs
= 0;
819 op
.openx
.in
.file_attrs
= 0;
820 op
.openx
.in
.write_time
= 0;
821 op
.openx
.in
.size
= 0;
822 op
.openx
.in
.timeout
= 0;
824 status
= smb_raw_open(cli
->tree
, mem_ctx
, &op
);
825 CHECK_STATUS(status
, NT_STATUS_OK
);
826 fnum
= op
.openx
.out
.file
.fnum
;
828 status
= smb_raw_open(cli
->tree
, mem_ctx
, &op
);
829 CHECK_STATUS(status
, NT_STATUS_OK
);
830 fnum2
= op
.openx
.out
.file
.fnum
;
832 io
.lockx
.level
= RAW_LOCK_LOCKX
;
833 io
.lockx
.in
.file
.fnum
= fnum
;
834 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
835 io
.lockx
.in
.timeout
= t
;
836 io
.lockx
.in
.ulock_cnt
= 0;
837 io
.lockx
.in
.lock_cnt
= 1;
838 lock
[0].pid
= cli
->session
->pid
;
839 lock
[0].offset
= 100;
841 io
.lockx
.in
.locks
= &lock
[0];
842 status
= smb_raw_lock(cli
->tree
, &io
);
843 CHECK_STATUS(status
, NT_STATUS_OK
);
846 * demonstrate that the first conflicting lock on each handle give LOCK_NOT_GRANTED
847 * this also demonstrates that the error code cache is per file handle
848 * (LOCK_NOT_GRANTED is only be used when timeout is 0!)
850 io
.lockx
.in
.file
.fnum
= fnum2
;
851 status
= smb_raw_lock(cli
->tree
, &io
);
852 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
854 io
.lockx
.in
.file
.fnum
= fnum
;
855 status
= smb_raw_lock(cli
->tree
, &io
);
856 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
858 /* demonstrate that each following conflict gives FILE_LOCK_CONFLICT */
859 io
.lockx
.in
.file
.fnum
= fnum
;
860 status
= smb_raw_lock(cli
->tree
, &io
);
861 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
863 io
.lockx
.in
.file
.fnum
= fnum2
;
864 status
= smb_raw_lock(cli
->tree
, &io
);
865 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
867 io
.lockx
.in
.file
.fnum
= fnum
;
868 status
= smb_raw_lock(cli
->tree
, &io
);
869 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
871 io
.lockx
.in
.file
.fnum
= fnum2
;
872 status
= smb_raw_lock(cli
->tree
, &io
);
873 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
875 /* demonstrate that the smbpid doesn't matter */
877 io
.lockx
.in
.file
.fnum
= fnum
;
878 status
= smb_raw_lock(cli
->tree
, &io
);
879 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
881 io
.lockx
.in
.file
.fnum
= fnum2
;
882 status
= smb_raw_lock(cli
->tree
, &io
);
883 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
887 * demonstrate the a successful lock with count = 0 and the same offset,
888 * doesn't reset the error cache
890 lock
[0].offset
= 100;
892 io
.lockx
.in
.file
.fnum
= fnum
;
893 status
= smb_raw_lock(cli
->tree
, &io
);
894 CHECK_STATUS(status
, NT_STATUS_OK
);
896 io
.lockx
.in
.file
.fnum
= fnum2
;
897 status
= smb_raw_lock(cli
->tree
, &io
);
898 CHECK_STATUS(status
, NT_STATUS_OK
);
900 lock
[0].offset
= 100;
902 io
.lockx
.in
.file
.fnum
= fnum
;
903 status
= smb_raw_lock(cli
->tree
, &io
);
904 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
906 io
.lockx
.in
.file
.fnum
= fnum2
;
907 status
= smb_raw_lock(cli
->tree
, &io
);
908 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
911 * demonstrate the a successful lock with count = 0 and outside the locked range,
912 * doesn't reset the error cache
914 lock
[0].offset
= 110;
916 io
.lockx
.in
.file
.fnum
= fnum
;
917 status
= smb_raw_lock(cli
->tree
, &io
);
918 CHECK_STATUS(status
, NT_STATUS_OK
);
920 io
.lockx
.in
.file
.fnum
= fnum2
;
921 status
= smb_raw_lock(cli
->tree
, &io
);
922 CHECK_STATUS(status
, NT_STATUS_OK
);
924 lock
[0].offset
= 100;
926 io
.lockx
.in
.file
.fnum
= fnum
;
927 status
= smb_raw_lock(cli
->tree
, &io
);
928 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
930 io
.lockx
.in
.file
.fnum
= fnum2
;
931 status
= smb_raw_lock(cli
->tree
, &io
);
932 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
936 io
.lockx
.in
.file
.fnum
= fnum
;
937 status
= smb_raw_lock(cli
->tree
, &io
);
938 CHECK_STATUS(status
, NT_STATUS_OK
);
940 io
.lockx
.in
.file
.fnum
= fnum2
;
941 status
= smb_raw_lock(cli
->tree
, &io
);
942 CHECK_STATUS(status
, NT_STATUS_OK
);
944 lock
[0].offset
= 100;
946 io
.lockx
.in
.file
.fnum
= fnum
;
947 status
= smb_raw_lock(cli
->tree
, &io
);
948 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
950 io
.lockx
.in
.file
.fnum
= fnum2
;
951 status
= smb_raw_lock(cli
->tree
, &io
);
952 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
954 /* demonstrate that a changing count doesn't reset the error cache */
955 lock
[0].offset
= 100;
957 io
.lockx
.in
.file
.fnum
= fnum
;
958 status
= smb_raw_lock(cli
->tree
, &io
);
959 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
961 io
.lockx
.in
.file
.fnum
= fnum2
;
962 status
= smb_raw_lock(cli
->tree
, &io
);
963 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
965 lock
[0].offset
= 100;
967 io
.lockx
.in
.file
.fnum
= fnum
;
968 status
= smb_raw_lock(cli
->tree
, &io
);
969 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
971 io
.lockx
.in
.file
.fnum
= fnum2
;
972 status
= smb_raw_lock(cli
->tree
, &io
);
973 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
976 * demonstrate the a lock with count = 0 and inside the locked range,
977 * fails and resets the error cache
979 lock
[0].offset
= 101;
981 io
.lockx
.in
.file
.fnum
= fnum
;
982 status
= smb_raw_lock(cli
->tree
, &io
);
983 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
984 status
= smb_raw_lock(cli
->tree
, &io
);
985 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
987 io
.lockx
.in
.file
.fnum
= fnum2
;
988 status
= smb_raw_lock(cli
->tree
, &io
);
989 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
990 status
= smb_raw_lock(cli
->tree
, &io
);
991 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
993 lock
[0].offset
= 100;
995 io
.lockx
.in
.file
.fnum
= fnum
;
996 status
= smb_raw_lock(cli
->tree
, &io
);
997 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
998 status
= smb_raw_lock(cli
->tree
, &io
);
999 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1001 io
.lockx
.in
.file
.fnum
= fnum2
;
1002 status
= smb_raw_lock(cli
->tree
, &io
);
1003 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1004 status
= smb_raw_lock(cli
->tree
, &io
);
1005 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1007 /* demonstrate the a changing offset, resets the error cache */
1008 lock
[0].offset
= 105;
1010 io
.lockx
.in
.file
.fnum
= fnum
;
1011 status
= smb_raw_lock(cli
->tree
, &io
);
1012 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1013 status
= smb_raw_lock(cli
->tree
, &io
);
1014 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1016 io
.lockx
.in
.file
.fnum
= fnum2
;
1017 status
= smb_raw_lock(cli
->tree
, &io
);
1018 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1019 status
= smb_raw_lock(cli
->tree
, &io
);
1020 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1022 lock
[0].offset
= 100;
1024 io
.lockx
.in
.file
.fnum
= fnum
;
1025 status
= smb_raw_lock(cli
->tree
, &io
);
1026 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1027 status
= smb_raw_lock(cli
->tree
, &io
);
1028 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1030 io
.lockx
.in
.file
.fnum
= fnum2
;
1031 status
= smb_raw_lock(cli
->tree
, &io
);
1032 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1033 status
= smb_raw_lock(cli
->tree
, &io
);
1034 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1036 lock
[0].offset
= 95;
1038 io
.lockx
.in
.file
.fnum
= fnum
;
1039 status
= smb_raw_lock(cli
->tree
, &io
);
1040 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1041 status
= smb_raw_lock(cli
->tree
, &io
);
1042 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1044 io
.lockx
.in
.file
.fnum
= fnum2
;
1045 status
= smb_raw_lock(cli
->tree
, &io
);
1046 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1047 status
= smb_raw_lock(cli
->tree
, &io
);
1048 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1050 lock
[0].offset
= 100;
1052 io
.lockx
.in
.file
.fnum
= fnum
;
1053 status
= smb_raw_lock(cli
->tree
, &io
);
1054 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1055 status
= smb_raw_lock(cli
->tree
, &io
);
1056 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1058 io
.lockx
.in
.file
.fnum
= fnum2
;
1059 status
= smb_raw_lock(cli
->tree
, &io
);
1060 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1061 status
= smb_raw_lock(cli
->tree
, &io
);
1062 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1065 * demonstrate the a successful lock in a different range,
1066 * doesn't reset the cache, the failing lock on the 2nd handle
1067 * resets the resets the cache
1069 lock
[0].offset
= 120;
1071 io
.lockx
.in
.file
.fnum
= fnum
;
1072 status
= smb_raw_lock(cli
->tree
, &io
);
1073 CHECK_STATUS(status
, NT_STATUS_OK
);
1075 io
.lockx
.in
.file
.fnum
= fnum2
;
1076 status
= smb_raw_lock(cli
->tree
, &io
);
1077 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1079 lock
[0].offset
= 100;
1081 io
.lockx
.in
.file
.fnum
= fnum
;
1082 status
= smb_raw_lock(cli
->tree
, &io
);
1083 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1084 status
= smb_raw_lock(cli
->tree
, &io
);
1085 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1087 io
.lockx
.in
.file
.fnum
= fnum2
;
1088 status
= smb_raw_lock(cli
->tree
, &io
);
1089 CHECK_STATUS(status
, (t
?NT_STATUS_FILE_LOCK_CONFLICT
:NT_STATUS_LOCK_NOT_GRANTED
));
1090 status
= smb_raw_lock(cli
->tree
, &io
);
1091 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1093 /* end of the loop */
1095 smb_raw_exit(cli
->session
);
1096 printf("testing with timeout > 0 (=1)\n");
1097 fname
= BASEDIR
"\\test1.txt";
1103 * the following 3 test sections demonstrate that
1104 * the cache is only set when the error is reported
1105 * to the client (after the timeout went by)
1107 smb_raw_exit(cli
->session
);
1108 printf("testing a conflict while a lock is pending\n");
1109 fname
= BASEDIR
"\\test2.txt";
1110 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1112 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
1116 io
.lockx
.level
= RAW_LOCK_LOCKX
;
1117 io
.lockx
.in
.file
.fnum
= fnum
;
1118 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
1119 io
.lockx
.in
.timeout
= 0;
1120 io
.lockx
.in
.ulock_cnt
= 0;
1121 io
.lockx
.in
.lock_cnt
= 1;
1122 lock
[0].pid
= cli
->session
->pid
;
1123 lock
[0].offset
= 100;
1125 io
.lockx
.in
.locks
= &lock
[0];
1126 status
= smb_raw_lock(cli
->tree
, &io
);
1127 CHECK_STATUS(status
, NT_STATUS_OK
);
1130 io
.lockx
.in
.timeout
= 1000;
1131 req
= smb_raw_lock_send(cli
->tree
, &io
);
1133 printf("Failed to setup timed lock (%s)\n", __location__
);
1138 io
.lockx
.in
.timeout
= 0;
1139 lock
[0].offset
= 105;
1141 status
= smb_raw_lock(cli
->tree
, &io
);
1142 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1144 status
= smbcli_request_simple_recv(req
);
1145 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1147 status
= smb_raw_lock(cli
->tree
, &io
);
1148 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1150 if (time(NULL
) < start
+1) {
1151 printf("lock comes back to early (%s)\n", __location__
);
1156 smbcli_close(cli
->tree
, fnum
);
1157 fname
= BASEDIR
"\\test3.txt";
1158 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1160 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
1164 io
.lockx
.level
= RAW_LOCK_LOCKX
;
1165 io
.lockx
.in
.file
.fnum
= fnum
;
1166 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
1167 io
.lockx
.in
.timeout
= 0;
1168 io
.lockx
.in
.ulock_cnt
= 0;
1169 io
.lockx
.in
.lock_cnt
= 1;
1170 lock
[0].pid
= cli
->session
->pid
;
1171 lock
[0].offset
= 100;
1173 io
.lockx
.in
.locks
= &lock
[0];
1174 status
= smb_raw_lock(cli
->tree
, &io
);
1175 CHECK_STATUS(status
, NT_STATUS_OK
);
1178 io
.lockx
.in
.timeout
= 1000;
1179 req
= smb_raw_lock_send(cli
->tree
, &io
);
1181 printf("Failed to setup timed lock (%s)\n", __location__
);
1186 io
.lockx
.in
.timeout
= 0;
1187 lock
[0].offset
= 105;
1189 status
= smb_raw_lock(cli
->tree
, &io
);
1190 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1192 status
= smbcli_request_simple_recv(req
);
1193 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1195 lock
[0].offset
= 100;
1197 status
= smb_raw_lock(cli
->tree
, &io
);
1198 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1200 if (time(NULL
) < start
+1) {
1201 printf("lock comes back to early (%s)\n", __location__
);
1206 smbcli_close(cli
->tree
, fnum
);
1207 fname
= BASEDIR
"\\test4.txt";
1208 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1210 printf("Failed to reopen %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
1214 io
.lockx
.level
= RAW_LOCK_LOCKX
;
1215 io
.lockx
.in
.file
.fnum
= fnum
;
1216 io
.lockx
.in
.mode
= LOCKING_ANDX_LARGE_FILES
;
1217 io
.lockx
.in
.timeout
= 0;
1218 io
.lockx
.in
.ulock_cnt
= 0;
1219 io
.lockx
.in
.lock_cnt
= 1;
1220 lock
[0].pid
= cli
->session
->pid
;
1221 lock
[0].offset
= 100;
1223 io
.lockx
.in
.locks
= &lock
[0];
1224 status
= smb_raw_lock(cli
->tree
, &io
);
1225 CHECK_STATUS(status
, NT_STATUS_OK
);
1228 io
.lockx
.in
.timeout
= 1000;
1229 req
= smb_raw_lock_send(cli
->tree
, &io
);
1231 printf("Failed to setup timed lock (%s)\n", __location__
);
1236 io
.lockx
.in
.timeout
= 0;
1237 status
= smb_raw_lock(cli
->tree
, &io
);
1238 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
1240 status
= smbcli_request_simple_recv(req
);
1241 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1243 status
= smb_raw_lock(cli
->tree
, &io
);
1244 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
1246 if (time(NULL
) < start
+1) {
1247 printf("lock comes back to early (%s)\n", __location__
);
1253 smb_raw_exit(cli
->session
);
1254 smbcli_deltree(cli
->tree
, BASEDIR
);
1260 test LOCKING_ANDX_CHANGE_LOCKTYPE
1262 static BOOL
test_changetype(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
1265 struct smb_lock_entry lock
[2];
1270 const char *fname
= BASEDIR
"\\test.txt";
1272 if (!torture_setup_dir(cli
, BASEDIR
)) {
1276 printf("Testing LOCKING_ANDX_CHANGE_LOCKTYPE\n");
1277 io
.generic
.level
= RAW_LOCK_LOCKX
;
1279 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1281 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
1286 io
.lockx
.level
= RAW_LOCK_LOCKX
;
1287 io
.lockx
.in
.file
.fnum
= fnum
;
1288 io
.lockx
.in
.mode
= LOCKING_ANDX_SHARED_LOCK
;
1289 io
.lockx
.in
.timeout
= 0;
1290 io
.lockx
.in
.ulock_cnt
= 0;
1291 io
.lockx
.in
.lock_cnt
= 1;
1292 lock
[0].pid
= cli
->session
->pid
;
1293 lock
[0].offset
= 100;
1295 io
.lockx
.in
.locks
= &lock
[0];
1296 status
= smb_raw_lock(cli
->tree
, &io
);
1297 CHECK_STATUS(status
, NT_STATUS_OK
);
1299 if (smbcli_write(cli
->tree
, fnum
, 0, &c
, 100, 1) == 1) {
1300 printf("allowed write on read locked region (%s)\n", __location__
);
1305 /* windows server don't seem to support this */
1306 io
.lockx
.in
.mode
= LOCKING_ANDX_CHANGE_LOCKTYPE
;
1307 status
= smb_raw_lock(cli
->tree
, &io
);
1308 CHECK_STATUS(status
, NT_STATUS_DOS(ERRDOS
, ERRnoatomiclocks
));
1310 if (smbcli_write(cli
->tree
, fnum
, 0, &c
, 100, 1) == 1) {
1311 printf("allowed write after lock change (%s)\n", __location__
);
1317 smbcli_close(cli
->tree
, fnum
);
1318 smb_raw_exit(cli
->session
);
1319 smbcli_deltree(cli
->tree
, BASEDIR
);
1325 basic testing of lock calls
1327 BOOL
torture_raw_lock(struct torture_context
*torture
)
1329 struct smbcli_state
*cli
;
1331 TALLOC_CTX
*mem_ctx
;
1333 if (!torture_open_connection(&cli
, 0)) {
1337 mem_ctx
= talloc_init("torture_raw_lock");
1339 ret
&= test_lockx(cli
, mem_ctx
);
1340 ret
&= test_lock(cli
, mem_ctx
);
1341 ret
&= test_pidhigh(cli
, mem_ctx
);
1342 ret
&= test_async(cli
, mem_ctx
);
1343 ret
&= test_errorcode(cli
, mem_ctx
);
1344 ret
&= test_changetype(cli
, mem_ctx
);
1346 torture_close_connection(cli
);
1347 talloc_free(mem_ctx
);