2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2000-2004
7 Copyright (C) Jeremy Allison 2000-2004
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 This test checks for two things:
29 1) correct support for retaining locks over a close (ie. the server
30 must not use posix semantics)
31 2) support for lock timeouts
33 BOOL torture_locktest1(int dummy)
35 struct smbcli_state *cli1, *cli2;
36 const char *fname = "\\lockt1.lck";
37 int fnum1, fnum2, fnum3;
41 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
45 printf("starting locktest1\n");
47 smbcli_unlink(cli1->tree, fname);
49 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
51 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
54 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
56 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
59 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
61 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
65 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
66 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
71 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
72 printf("lock2 succeeded! This is a locking bug\n");
75 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
76 NT_STATUS_LOCK_NOT_GRANTED)) return False;
79 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
80 printf("lock2 succeeded! This is a locking bug\n");
83 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
84 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
87 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 5, 9, 0, WRITE_LOCK))) {
88 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
92 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 5, 9, 0, WRITE_LOCK))) {
93 printf("lock2 succeeded! This is a locking bug\n");
96 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
97 NT_STATUS_LOCK_NOT_GRANTED)) return False;
100 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
101 printf("lock2 succeeded! This is a locking bug\n");
104 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
105 NT_STATUS_LOCK_NOT_GRANTED)) return False;
108 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
109 printf("lock2 succeeded! This is a locking bug\n");
112 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
113 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
116 lock_timeout = (6 + (random() % 20));
117 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
119 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
120 printf("lock3 succeeded! This is a locking bug\n");
123 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
124 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
129 printf("error: This server appears not to support timed lock requests\n");
131 printf("server slept for %u seconds for a %u second timeout\n",
132 (uint_t)(t2-t1), lock_timeout);
134 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
135 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
139 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
140 printf("lock4 succeeded! This is a locking bug\n");
143 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
144 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
147 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
148 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
152 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
153 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
157 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
158 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
163 if (!torture_close_connection(cli1)) {
167 if (!torture_close_connection(cli2)) {
171 printf("Passed locktest1\n");
177 This test checks that
179 1) the server supports multiple locking contexts on the one SMB
180 connection, distinguished by PID.
182 2) the server correctly fails overlapping locks made by the same PID (this
183 goes against POSIX behaviour, which is why it is tricky to implement)
185 3) the server denies unlock requests by an incorrect client PID
187 BOOL torture_locktest2(int dummy)
189 struct smbcli_state *cli;
190 const char *fname = "\\lockt2.lck";
191 int fnum1, fnum2, fnum3;
194 if (!torture_open_connection(&cli)) {
198 printf("starting locktest2\n");
200 smbcli_unlink(cli->tree, fname);
202 printf("Testing pid context\n");
204 cli->session->pid = 1;
206 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
208 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
212 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
214 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
218 cli->session->pid = 2;
220 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
222 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
226 cli->session->pid = 1;
228 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
229 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
233 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
234 printf("WRITE lock1 succeeded! This is a locking bug\n");
237 if (!check_error(__location__, cli, ERRDOS, ERRlock,
238 NT_STATUS_LOCK_NOT_GRANTED)) return False;
241 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
242 printf("WRITE lock2 succeeded! This is a locking bug\n");
245 if (!check_error(__location__, cli, ERRDOS, ERRlock,
246 NT_STATUS_LOCK_NOT_GRANTED)) return False;
249 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
250 printf("READ lock2 succeeded! This is a locking bug\n");
253 if (!check_error(__location__, cli, ERRDOS, ERRlock,
254 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
257 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
258 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
261 cli->session->pid = 2;
263 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
264 printf("unlock at 100 succeeded! This is a locking bug\n");
268 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
269 printf("unlock1 succeeded! This is a locking bug\n");
272 if (!check_error(__location__, cli,
274 NT_STATUS_RANGE_NOT_LOCKED)) return False;
277 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
278 printf("unlock2 succeeded! This is a locking bug\n");
281 if (!check_error(__location__, cli,
283 NT_STATUS_RANGE_NOT_LOCKED)) return False;
286 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
287 printf("lock3 succeeded! This is a locking bug\n");
290 if (!check_error(__location__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
293 cli->session->pid = 1;
295 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
296 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
300 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
301 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
305 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
306 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
310 if (!torture_close_connection(cli)) {
314 printf("locktest2 finished\n");
321 This test checks that
323 1) the server supports the full offset range in lock requests
325 BOOL torture_locktest3(int dummy)
327 struct smbcli_state *cli1, *cli2;
328 const char *fname = "\\lockt3.lck";
332 extern int torture_numops;
334 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
336 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
340 printf("starting locktest3\n");
342 printf("Testing 32 bit offset ranges\n");
344 smbcli_unlink(cli1->tree, fname);
346 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
348 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
351 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
353 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
357 printf("Establishing %d locks\n", torture_numops);
359 for (offset=i=0;i<torture_numops;i++) {
361 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
362 printf("lock1 %d failed (%s)\n",
364 smbcli_errstr(cli1->tree));
368 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
369 printf("lock2 %d failed (%s)\n",
371 smbcli_errstr(cli1->tree));
376 printf("Testing %d locks\n", torture_numops);
378 for (offset=i=0;i<torture_numops;i++) {
381 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
382 printf("error: lock1 %d succeeded!\n", i);
386 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
387 printf("error: lock2 %d succeeded!\n", i);
391 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
392 printf("error: lock3 %d succeeded!\n", i);
396 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
397 printf("error: lock4 %d succeeded!\n", i);
402 printf("Removing %d locks\n", torture_numops);
404 for (offset=i=0;i<torture_numops;i++) {
407 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
408 printf("unlock1 %d failed (%s)\n",
410 smbcli_errstr(cli1->tree));
414 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
415 printf("unlock2 %d failed (%s)\n",
417 smbcli_errstr(cli1->tree));
422 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
423 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
427 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
428 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
432 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
433 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
437 if (!torture_close_connection(cli1)) {
441 if (!torture_close_connection(cli2)) {
445 printf("finished locktest3\n");
450 #define EXPECTED(ret, v) if ((ret) != (v)) { \
451 printf("** "); correct = False; \
455 looks at overlapping locks
457 BOOL torture_locktest4(int dummy)
459 struct smbcli_state *cli1, *cli2;
460 const char *fname = "\\lockt4.lck";
466 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
470 printf("starting locktest4\n");
472 smbcli_unlink(cli1->tree, fname);
474 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
475 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
477 memset(buf, 0, sizeof(buf));
479 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
480 printf("Failed to create file\n");
485 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
486 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
487 EXPECTED(ret, False);
488 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
490 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
491 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
493 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
495 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
496 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
497 EXPECTED(ret, False);
498 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
500 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
501 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
503 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
505 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
506 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
507 EXPECTED(ret, False);
508 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
510 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
511 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
513 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
515 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
516 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
518 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
520 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
521 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
522 EXPECTED(ret, False);
523 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
525 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
526 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
527 EXPECTED(ret, False);
528 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
530 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
531 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
533 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
535 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
536 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
537 EXPECTED(ret, False);
538 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
540 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
541 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
542 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
543 EXPECTED(ret, False);
544 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
547 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
548 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
549 EXPECTED(ret, False);
550 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
552 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
553 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
554 EXPECTED(ret, False);
555 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
558 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
559 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
560 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
561 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
563 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
566 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
567 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
568 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
569 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
570 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
571 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
573 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
575 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
576 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
577 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
578 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
580 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
582 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
583 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
584 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
585 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
587 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
589 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
590 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
591 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
592 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
593 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
595 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
597 smbcli_close(cli1->tree, fnum1);
598 smbcli_close(cli2->tree, fnum2);
599 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
600 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
601 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
602 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
603 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
604 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
605 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
606 smbcli_close(cli1->tree, f);
607 smbcli_close(cli1->tree, fnum1);
609 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
612 smbcli_close(cli1->tree, fnum1);
613 smbcli_close(cli2->tree, fnum2);
614 smbcli_unlink(cli1->tree, fname);
615 torture_close_connection(cli1);
616 torture_close_connection(cli2);
618 printf("finished locktest4\n");
623 looks at lock upgrade/downgrade.
625 BOOL torture_locktest5(int dummy)
627 struct smbcli_state *cli1, *cli2;
628 const char *fname = "\\lockt5.lck";
629 int fnum1, fnum2, fnum3;
634 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
638 printf("starting locktest5\n");
640 smbcli_unlink(cli1->tree, fname);
642 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
643 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
644 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
646 memset(buf, 0, sizeof(buf));
648 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
649 printf("Failed to create file\n");
654 /* Check for NT bug... */
655 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
656 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
657 smbcli_close(cli1->tree, fnum1);
658 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
659 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
661 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
662 smbcli_close(cli1->tree, fnum1);
663 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
664 smbcli_unlock(cli1->tree, fnum3, 0, 1);
666 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
667 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
669 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
671 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
672 EXPECTED(ret, False);
674 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
676 /* Unlock the process 2 lock. */
677 smbcli_unlock(cli2->tree, fnum2, 0, 4);
679 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
680 EXPECTED(ret, False);
682 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
684 /* Unlock the process 1 fnum3 lock. */
685 smbcli_unlock(cli1->tree, fnum3, 0, 4);
687 /* Stack 2 more locks here. */
688 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
689 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
692 printf("the same process %s stack read locks\n", ret?"can":"cannot");
694 /* Unlock the first process lock, then check this was the WRITE lock that was
697 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
698 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
701 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
703 /* Unlock the process 2 lock. */
704 smbcli_unlock(cli2->tree, fnum2, 0, 4);
706 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
708 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
709 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
710 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
713 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
715 /* Ensure the next unlock fails. */
716 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
717 EXPECTED(ret, False);
718 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
720 /* Ensure connection 2 can get a write lock. */
721 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
724 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
728 smbcli_close(cli1->tree, fnum1);
729 smbcli_close(cli2->tree, fnum2);
730 smbcli_unlink(cli1->tree, fname);
731 if (!torture_close_connection(cli1)) {
734 if (!torture_close_connection(cli2)) {
738 printf("finished locktest5\n");
744 tries the unusual lockingX locktype bits
746 BOOL torture_locktest6(int dummy)
748 struct smbcli_state *cli;
749 const char *fname[1] = { "\\lock6.txt" };
754 if (!torture_open_connection(&cli)) {
758 printf("starting locktest6\n");
761 printf("Testing %s\n", fname[i]);
763 smbcli_unlink(cli->tree, fname[i]);
765 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
766 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
767 smbcli_close(cli->tree, fnum);
768 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
770 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
771 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
772 smbcli_close(cli->tree, fnum);
773 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
775 smbcli_unlink(cli->tree, fname[i]);
778 torture_close_connection(cli);
780 printf("finished locktest6\n");
784 BOOL torture_locktest7(int dummy)
786 struct smbcli_state *cli1;
787 const char *fname = "\\lockt7.lck";
792 BOOL correct = False;
794 if (!torture_open_connection(&cli1)) {
798 printf("starting locktest7\n");
800 smbcli_unlink(cli1->tree, fname);
802 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
804 memset(buf, 0, sizeof(buf));
806 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
807 printf("Failed to create file (%s)\n", __location__);
811 cli1->session->pid = 1;
813 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
814 printf("Unable to apply read lock on range 130:4, error was %s (%s)\n",
815 smbcli_errstr(cli1->tree), __location__);
818 printf("pid1 successfully locked range 130:4 for READ\n");
821 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
822 printf("pid1 unable to read the range 130:4, error was %s (%s)\n",
823 smbcli_errstr(cli1->tree), __location__);
826 printf("pid1 successfully read the range 130:4\n");
829 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
830 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
831 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
832 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
837 printf("pid1 successfully wrote to the range 130:4 (should be denied) (%s)\n",
842 cli1->session->pid = 2;
844 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
845 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
847 printf("pid2 successfully read the range 130:4\n");
850 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
851 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
852 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
853 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
858 printf("pid2 successfully wrote to the range 130:4 (should be denied) (%s)\n",
863 cli1->session->pid = 1;
864 smbcli_unlock(cli1->tree, fnum1, 130, 4);
866 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
867 printf("Unable to apply write lock on range 130:4, error was %s (%s)\n",
868 smbcli_errstr(cli1->tree), __location__);
871 printf("pid1 successfully locked range 130:4 for WRITE\n");
874 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
875 printf("pid1 unable to read the range 130:4, error was %s (%s)\n",
876 smbcli_errstr(cli1->tree), __location__);
879 printf("pid1 successfully read the range 130:4\n");
882 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
883 printf("pid1 unable to write to the range 130:4, error was %s (%s)\n",
884 smbcli_errstr(cli1->tree), __location__);
887 printf("pid1 successfully wrote to the range 130:4\n");
890 cli1->session->pid = 2;
892 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
893 printf("pid2 unable to read the range 130:4, error was %s\n",
894 smbcli_errstr(cli1->tree));
895 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
896 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
901 printf("pid2 successfully read the range 130:4 (should be denied) (%s)\n",
906 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
907 printf("pid2 unable to write to the range 130:4, error was %s\n",
908 smbcli_errstr(cli1->tree));
909 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
910 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
915 printf("pid2 successfully wrote to the range 130:4 (should be denied) (%s)\n",
920 printf("Testing truncate of locked file.\n");
922 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
925 printf("Unable to truncate locked file (%s)\n", __location__);
929 printf("Truncated locked file.\n");
932 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
933 printf("getatr failed (%s) (%s)\n", smbcli_errstr(cli1->tree), __location__);
939 printf("Unable to truncate locked file. Size was %u (%s)\n", size, __location__);
944 cli1->session->pid = 1;
946 smbcli_unlock(cli1->tree, fnum1, 130, 4);
950 smbcli_close(cli1->tree, fnum1);
951 smbcli_close(cli1->tree, fnum2);
952 smbcli_unlink(cli1->tree, fname);
953 torture_close_connection(cli1);
955 printf("finished locktest7\n");