r17099: Samba3 now passes RAW-LOCK completely, no need for
[Samba/aatanasov.git] / source / torture / raw / lock.c
blob6d58b9d6aaaf7116ed06cd8bde619b27c6c4b301
1 /*
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.
21 #include "includes.h"
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)); \
36 ret = False; \
37 goto done; \
38 }} while (0)
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); \
44 ret = False; \
45 goto done; \
46 }} while (0)
48 #define BASEDIR "\\testlock"
52 test SMBlock and SMBunlock ops
54 static BOOL test_lock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
56 union smb_lock io;
57 NTSTATUS status;
58 BOOL ret = True;
59 int fnum;
60 const char *fname = BASEDIR "\\test.txt";
62 if (!torture_setup_dir(cli, BASEDIR)) {
63 return False;
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);
70 if (fnum == -1) {
71 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
72 ret = False;
73 goto done;
76 printf("Trying 0/0 lock\n");
77 io.lock.level = RAW_LOCK_LOCK;
78 io.lock.in.file.fnum = fnum;
79 io.lock.in.count = 0;
80 io.lock.in.offset = 0;
81 status = smb_raw_lock(cli->tree, &io);
82 CHECK_STATUS(status, NT_STATUS_OK);
83 cli->session->pid++;
84 status = smb_raw_lock(cli->tree, &io);
85 CHECK_STATUS(status, NT_STATUS_OK);
86 cli->session->pid--;
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;
94 io.lock.in.count = 1;
95 io.lock.in.offset = 0;
96 status = smb_raw_lock(cli->tree, &io);
97 CHECK_STATUS(status, NT_STATUS_OK);
98 cli->session->pid++;
99 status = smb_raw_lock(cli->tree, &io);
100 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
101 cli->session->pid--;
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);
116 cli->session->pid++;
117 status = smb_raw_lock(cli->tree, &io);
118 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
119 cli->session->pid--;
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);
134 cli->session->pid++;
135 status = smb_raw_lock(cli->tree, &io);
136 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
137 cli->session->pid--;
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);
152 cli->session->pid++;
153 status = smb_raw_lock(cli->tree, &io);
154 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
155 cli->session->pid--;
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);
170 cli->session->pid++;
171 io.lock.level = RAW_LOCK_UNLOCK;
172 status = smb_raw_lock(cli->tree, &io);
173 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
174 cli->session->pid--;
175 status = smb_raw_lock(cli->tree, &io);
176 CHECK_STATUS(status, NT_STATUS_OK);
178 done:
179 smbcli_close(cli->tree, fnum);
180 smb_raw_exit(cli->session);
181 smbcli_deltree(cli->tree, BASEDIR);
182 return ret;
187 test locking&X ops
189 static BOOL test_lockx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
191 union smb_lock io;
192 struct smb_lock_entry lock[1];
193 NTSTATUS status;
194 BOOL ret = True;
195 int fnum;
196 const char *fname = BASEDIR "\\test.txt";
198 if (!torture_setup_dir(cli, BASEDIR)) {
199 return False;
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);
206 if (fnum == -1) {
207 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
208 ret = False;
209 goto done;
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;
219 lock[0].offset = 10;
220 lock[0].count = 1;
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);
233 lock[0].pid++;
234 status = smb_raw_lock(cli->tree, &io);
235 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
236 lock[0].pid--;
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);
251 lock[0].pid++;
252 status = smb_raw_lock(cli->tree, &io);
253 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
254 lock[0].pid--;
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;
265 lock[0].count = 0;
266 lock[0].offset = ~0;
267 status = smb_raw_lock(cli->tree, &io);
268 CHECK_STATUS(status, NT_STATUS_OK);
269 lock[0].pid++;
270 status = smb_raw_lock(cli->tree, &io);
271 CHECK_STATUS(status, NT_STATUS_OK);
272 lock[0].pid--;
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;
283 lock[0].count = 0;
284 lock[0].offset = ~0;
285 status = smb_raw_lock(cli->tree, &io);
286 CHECK_STATUS(status, NT_STATUS_OK);
287 lock[0].pid++;
288 status = smb_raw_lock(cli->tree, &io);
289 CHECK_STATUS(status, NT_STATUS_OK);
290 lock[0].pid--;
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;
301 lock[0].count = 1;
302 lock[0].offset = 1;
303 lock[0].offset <<= 63;
304 status = smb_raw_lock(cli->tree, &io);
305 CHECK_STATUS(status, NT_STATUS_OK);
306 lock[0].pid++;
307 status = smb_raw_lock(cli->tree, &io);
308 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
309 lock[0].pid--;
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;
320 lock[0].count = 1;
321 lock[0].offset = 1;
322 lock[0].offset <<= 63;
323 lock[0].offset--;
324 status = smb_raw_lock(cli->tree, &io);
325 CHECK_STATUS(status, NT_STATUS_OK);
326 lock[0].pid++;
327 status = smb_raw_lock(cli->tree, &io);
328 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
329 lock[0].pid--;
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;
340 lock[0].count = 1;
341 lock[0].offset = ~0;
342 status = smb_raw_lock(cli->tree, &io);
343 CHECK_STATUS(status, NT_STATUS_OK);
344 lock[0].pid++;
345 lock[0].count = 2;
346 status = smb_raw_lock(cli->tree, &io);
347 CHECK_STATUS(status, NT_STATUS_OK);
348 lock[0].pid--;
349 io.lockx.in.ulock_cnt = 1;
350 io.lockx.in.lock_cnt = 0;
351 lock[0].count = 1;
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);
357 done:
358 smbcli_close(cli->tree, fnum);
359 smb_raw_exit(cli->session);
360 smbcli_deltree(cli->tree, BASEDIR);
361 return ret;
366 test high pid
368 static BOOL test_pidhigh(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
370 union smb_lock io;
371 struct smb_lock_entry lock[1];
372 NTSTATUS status;
373 BOOL ret = True;
374 int fnum;
375 const char *fname = BASEDIR "\\test.txt";
376 uint8_t c = 1;
378 if (!torture_setup_dir(cli, BASEDIR)) {
379 return False;
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);
388 if (fnum == -1) {
389 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
390 ret = False;
391 goto done;
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));
396 ret = False;
397 goto done;
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;
407 lock[0].offset = 0;
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));
415 ret = False;
416 goto done;
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");
425 ret = False;
426 goto done;
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");
433 ret = False;
434 } else {
435 printf("High pid is not used on this server (correct)\n");
438 done:
439 smbcli_close(cli->tree, fnum);
440 smb_raw_exit(cli->session);
441 smbcli_deltree(cli->tree, BASEDIR);
442 return ret;
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;
454 union smb_tcon tcon;
455 const char *host, *share;
456 union smb_lock io;
457 struct smb_lock_entry lock[2];
458 NTSTATUS status;
459 BOOL ret = True;
460 int fnum;
461 const char *fname = BASEDIR "\\test.txt";
462 time_t t;
463 struct smbcli_request *req;
465 if (!torture_setup_dir(cli, BASEDIR)) {
466 return False;
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);
473 if (fnum == -1) {
474 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
475 ret = False;
476 goto done;
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;
487 lock[0].count = 10;
488 io.lockx.in.locks = &lock[0];
489 status = smb_raw_lock(cli->tree, &io);
490 CHECK_STATUS(status, NT_STATUS_OK);
492 t = time(NULL);
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);
499 if (req == NULL) {
500 printf("Failed to setup timed lock (%s)\n", __location__);
501 ret = False;
502 goto done;
505 /* cancel the wrong range */
506 lock[0].offset = 0;
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__);
532 ret = False;
533 goto done;
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);
546 if (req == NULL) {
547 printf("Failed to setup timed lock (%s)\n", __location__);
548 ret = False;
549 goto done;
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);
557 t = time(NULL);
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));
564 ret = False;
565 goto done;
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);
576 t = time(NULL);
577 io.lockx.in.timeout = 10000;
578 req = smb_raw_lock_send(cli->tree, &io);
579 if (req == NULL) {
580 printf("Failed to setup timed lock (%s)\n", __location__);
581 ret = False;
582 goto done;
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__);
593 ret = False;
594 goto done;
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);
623 if (fnum == -1) {
624 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(tree));
625 ret = False;
626 goto done;
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;
636 lock[0].count = 10;
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;
649 t = time(NULL);
650 req = smb_raw_lock_send(tree, &io);
651 if (req == NULL) {
652 printf("Failed to setup timed lock (%s)\n", __location__);
653 ret = False;
654 goto done;
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__);
665 ret = False;
666 goto done;
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);
672 if (fnum == -1) {
673 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(tree));
674 ret = False;
675 goto done;
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;
685 lock[0].count = 10;
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;
698 t = time(NULL);
699 req = smb_raw_lock_send(tree, &io);
700 if (req == NULL) {
701 printf("Failed to setup timed lock (%s)\n", __location__);
702 ret = False;
703 goto done;
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",
712 nt_errstr(status));
713 smb_tree_disconnect(tree);
714 smb_raw_exit(session);
715 goto done;
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__);
721 ret = False;
722 goto done;
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);
730 if (fnum == -1) {
731 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(tree));
732 ret = False;
733 goto done;
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;
743 lock[0].count = 10;
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;
752 t = time(NULL);
753 req = smb_raw_lock_send(tree, &io);
754 if (req == NULL) {
755 printf("Failed to setup timed lock (%s)\n", __location__);
756 ret = False;
757 goto done;
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__);
768 ret = False;
769 goto done;
772 done:
773 smb_raw_exit(cli->session);
774 smbcli_deltree(cli->tree, BASEDIR);
775 return ret;
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)
783 union smb_lock io;
784 union smb_open op;
785 struct smb_lock_entry lock[2];
786 NTSTATUS status;
787 BOOL ret = True;
788 int fnum, fnum2;
789 const char *fname;
790 struct smbcli_request *req;
791 time_t start;
792 int t;
794 if (!torture_setup_dir(cli, BASEDIR)) {
795 return False;
798 printf("Testing LOCK_NOT_GRANTED vs. FILE_LOCK_CONFLICT\n");
800 printf("testing with timeout = 0\n");
801 fname = BASEDIR "\\test0.txt";
802 t = 0;
805 * the first run is with t = 0,
806 * the second with t > 0 (=1)
808 next_run:
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;
840 lock[0].count = 10;
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 */
876 lock[0].pid++;
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);
884 lock[0].pid--;
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;
891 lock[0].count = 0;
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;
901 lock[0].count = 10;
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;
915 lock[0].count = 0;
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;
925 lock[0].count = 10;
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);
934 lock[0].offset = 99;
935 lock[0].count = 0;
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;
945 lock[0].count = 10;
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;
956 lock[0].count = 5;
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;
966 lock[0].count = 15;
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;
980 lock[0].count = 0;
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;
994 lock[0].count = 10;
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;
1009 lock[0].count = 10;
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;
1023 lock[0].count = 10;
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;
1037 lock[0].count = 9;
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;
1051 lock[0].count = 10;
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;
1070 lock[0].count = 15;
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;
1080 lock[0].count = 10;
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 */
1094 if (t == 0) {
1095 smb_raw_exit(cli->session);
1096 printf("testing with timeout > 0 (=1)\n");
1097 fname = BASEDIR "\\test1.txt";
1098 t = 1;
1099 goto next_run;
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);
1111 if (fnum == -1) {
1112 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree));
1113 ret = False;
1114 goto done;
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;
1124 lock[0].count = 10;
1125 io.lockx.in.locks = &lock[0];
1126 status = smb_raw_lock(cli->tree, &io);
1127 CHECK_STATUS(status, NT_STATUS_OK);
1129 start = time(NULL);
1130 io.lockx.in.timeout = 1000;
1131 req = smb_raw_lock_send(cli->tree, &io);
1132 if (req == NULL) {
1133 printf("Failed to setup timed lock (%s)\n", __location__);
1134 ret = False;
1135 goto done;
1138 io.lockx.in.timeout = 0;
1139 lock[0].offset = 105;
1140 lock[0].count = 10;
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__);
1152 ret = False;
1153 goto done;
1156 smbcli_close(cli->tree, fnum);
1157 fname = BASEDIR "\\test3.txt";
1158 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1159 if (fnum == -1) {
1160 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree));
1161 ret = False;
1162 goto done;
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;
1172 lock[0].count = 10;
1173 io.lockx.in.locks = &lock[0];
1174 status = smb_raw_lock(cli->tree, &io);
1175 CHECK_STATUS(status, NT_STATUS_OK);
1177 start = time(NULL);
1178 io.lockx.in.timeout = 1000;
1179 req = smb_raw_lock_send(cli->tree, &io);
1180 if (req == NULL) {
1181 printf("Failed to setup timed lock (%s)\n", __location__);
1182 ret = False;
1183 goto done;
1186 io.lockx.in.timeout = 0;
1187 lock[0].offset = 105;
1188 lock[0].count = 10;
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;
1196 lock[0].count = 10;
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__);
1202 ret = False;
1203 goto done;
1206 smbcli_close(cli->tree, fnum);
1207 fname = BASEDIR "\\test4.txt";
1208 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1209 if (fnum == -1) {
1210 printf("Failed to reopen %s - %s\n", fname, smbcli_errstr(cli->tree));
1211 ret = False;
1212 goto done;
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;
1222 lock[0].count = 10;
1223 io.lockx.in.locks = &lock[0];
1224 status = smb_raw_lock(cli->tree, &io);
1225 CHECK_STATUS(status, NT_STATUS_OK);
1227 start = time(NULL);
1228 io.lockx.in.timeout = 1000;
1229 req = smb_raw_lock_send(cli->tree, &io);
1230 if (req == NULL) {
1231 printf("Failed to setup timed lock (%s)\n", __location__);
1232 ret = False;
1233 goto done;
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__);
1248 ret = False;
1249 goto done;
1252 done:
1253 smb_raw_exit(cli->session);
1254 smbcli_deltree(cli->tree, BASEDIR);
1255 return ret;
1260 test LOCKING_ANDX_CHANGE_LOCKTYPE
1262 static BOOL test_changetype(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
1264 union smb_lock io;
1265 struct smb_lock_entry lock[2];
1266 NTSTATUS status;
1267 BOOL ret = True;
1268 int fnum;
1269 uint8_t c = 0;
1270 const char *fname = BASEDIR "\\test.txt";
1272 if (!torture_setup_dir(cli, BASEDIR)) {
1273 return False;
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);
1280 if (fnum == -1) {
1281 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
1282 ret = False;
1283 goto done;
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;
1294 lock[0].count = 10;
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__);
1301 ret = False;
1302 goto done;
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__);
1312 ret = False;
1313 goto done;
1316 done:
1317 smbcli_close(cli->tree, fnum);
1318 smb_raw_exit(cli->session);
1319 smbcli_deltree(cli->tree, BASEDIR);
1320 return ret;
1325 basic testing of lock calls
1327 BOOL torture_raw_lock(struct torture_context *torture)
1329 struct smbcli_state *cli;
1330 BOOL ret = True;
1331 TALLOC_CTX *mem_ctx;
1333 if (!torture_open_connection(&cli, 0)) {
1334 return False;
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);
1348 return ret;