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;
80 lock_timeout = (6 + (random() % 20));
81 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
83 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
84 printf("lock3 succeeded! This is a locking bug\n");
87 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
88 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
93 printf("error: This server appears not to support timed lock requests\n");
95 printf("server slept for %u seconds for a %u second timeout\n",
96 (uint_t)(t2-t1), lock_timeout);
98 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
99 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
103 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
104 printf("lock4 succeeded! This is a locking bug\n");
107 if (!check_error(__location__, cli2, ERRDOS, ERRlock,
108 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
111 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
112 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
116 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
117 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
121 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
122 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
127 if (!torture_close_connection(cli1)) {
131 if (!torture_close_connection(cli2)) {
135 printf("Passed locktest1\n");
141 This test checks that
143 1) the server supports multiple locking contexts on the one SMB
144 connection, distinguished by PID.
146 2) the server correctly fails overlapping locks made by the same PID (this
147 goes against POSIX behaviour, which is why it is tricky to implement)
149 3) the server denies unlock requests by an incorrect client PID
151 BOOL torture_locktest2(int dummy)
153 struct smbcli_state *cli;
154 const char *fname = "\\lockt2.lck";
155 int fnum1, fnum2, fnum3;
158 if (!torture_open_connection(&cli)) {
162 printf("starting locktest2\n");
164 smbcli_unlink(cli->tree, fname);
166 printf("Testing pid context\n");
168 cli->session->pid = 1;
170 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
172 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
176 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
178 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
182 cli->session->pid = 2;
184 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
186 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
190 cli->session->pid = 1;
192 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
193 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
197 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
198 printf("WRITE lock1 succeeded! This is a locking bug\n");
201 if (!check_error(__location__, cli, ERRDOS, ERRlock,
202 NT_STATUS_LOCK_NOT_GRANTED)) return False;
205 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
206 printf("WRITE lock2 succeeded! This is a locking bug\n");
209 if (!check_error(__location__, cli, ERRDOS, ERRlock,
210 NT_STATUS_LOCK_NOT_GRANTED)) return False;
213 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
214 printf("READ lock2 succeeded! This is a locking bug\n");
217 if (!check_error(__location__, cli, ERRDOS, ERRlock,
218 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
221 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
222 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
225 cli->session->pid = 2;
227 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
228 printf("unlock at 100 succeeded! This is a locking bug\n");
232 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
233 printf("unlock1 succeeded! This is a locking bug\n");
236 if (!check_error(__location__, cli,
238 NT_STATUS_RANGE_NOT_LOCKED)) return False;
241 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
242 printf("unlock2 succeeded! This is a locking bug\n");
245 if (!check_error(__location__, cli,
247 NT_STATUS_RANGE_NOT_LOCKED)) return False;
250 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
251 printf("lock3 succeeded! This is a locking bug\n");
254 if (!check_error(__location__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
257 cli->session->pid = 1;
259 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
260 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
264 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
265 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
269 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
270 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
274 if (!torture_close_connection(cli)) {
278 printf("locktest2 finished\n");
285 This test checks that
287 1) the server supports the full offset range in lock requests
289 BOOL torture_locktest3(int dummy)
291 struct smbcli_state *cli1, *cli2;
292 const char *fname = "\\lockt3.lck";
296 extern int torture_numops;
298 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
300 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
304 printf("starting locktest3\n");
306 printf("Testing 32 bit offset ranges\n");
308 smbcli_unlink(cli1->tree, fname);
310 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
312 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
315 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
317 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
321 printf("Establishing %d locks\n", torture_numops);
323 for (offset=i=0;i<torture_numops;i++) {
325 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
326 printf("lock1 %d failed (%s)\n",
328 smbcli_errstr(cli1->tree));
332 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
333 printf("lock2 %d failed (%s)\n",
335 smbcli_errstr(cli1->tree));
340 printf("Testing %d locks\n", torture_numops);
342 for (offset=i=0;i<torture_numops;i++) {
345 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
346 printf("error: lock1 %d succeeded!\n", i);
350 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
351 printf("error: lock2 %d succeeded!\n", i);
355 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
356 printf("error: lock3 %d succeeded!\n", i);
360 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
361 printf("error: lock4 %d succeeded!\n", i);
366 printf("Removing %d locks\n", torture_numops);
368 for (offset=i=0;i<torture_numops;i++) {
371 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
372 printf("unlock1 %d failed (%s)\n",
374 smbcli_errstr(cli1->tree));
378 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
379 printf("unlock2 %d failed (%s)\n",
381 smbcli_errstr(cli1->tree));
386 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
387 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
391 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
392 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
396 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
397 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
401 if (!torture_close_connection(cli1)) {
405 if (!torture_close_connection(cli2)) {
409 printf("finished locktest3\n");
414 #define EXPECTED(ret, v) if ((ret) != (v)) { \
415 printf("** "); correct = False; \
419 looks at overlapping locks
421 BOOL torture_locktest4(int dummy)
423 struct smbcli_state *cli1, *cli2;
424 const char *fname = "\\lockt4.lck";
430 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
434 printf("starting locktest4\n");
436 smbcli_unlink(cli1->tree, fname);
438 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
439 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
441 memset(buf, 0, sizeof(buf));
443 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
444 printf("Failed to create file\n");
449 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
450 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
451 EXPECTED(ret, False);
452 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
454 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
455 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
457 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
459 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
460 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
461 EXPECTED(ret, False);
462 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
464 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
465 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
467 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
469 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
470 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
471 EXPECTED(ret, False);
472 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
474 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
475 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
477 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
479 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
480 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
482 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
484 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
485 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
486 EXPECTED(ret, False);
487 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
489 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
490 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
491 EXPECTED(ret, False);
492 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
494 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
495 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
497 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
499 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
500 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
501 EXPECTED(ret, False);
502 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
504 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
505 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
506 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
507 EXPECTED(ret, False);
508 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
511 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
512 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
513 EXPECTED(ret, False);
514 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
516 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
517 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
518 EXPECTED(ret, False);
519 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
522 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
523 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
524 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
525 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
527 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
530 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
531 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
532 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
533 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
534 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
535 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
537 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
539 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
540 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
541 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
542 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
544 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
546 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
547 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
548 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
549 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
551 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
553 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
554 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
555 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
556 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
557 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
559 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
561 smbcli_close(cli1->tree, fnum1);
562 smbcli_close(cli2->tree, fnum2);
563 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
564 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
565 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
566 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
567 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
568 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
569 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
570 smbcli_close(cli1->tree, f);
571 smbcli_close(cli1->tree, fnum1);
573 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
576 smbcli_close(cli1->tree, fnum1);
577 smbcli_close(cli2->tree, fnum2);
578 smbcli_unlink(cli1->tree, fname);
579 torture_close_connection(cli1);
580 torture_close_connection(cli2);
582 printf("finished locktest4\n");
587 looks at lock upgrade/downgrade.
589 BOOL torture_locktest5(int dummy)
591 struct smbcli_state *cli1, *cli2;
592 const char *fname = "\\lockt5.lck";
593 int fnum1, fnum2, fnum3;
598 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
602 printf("starting locktest5\n");
604 smbcli_unlink(cli1->tree, fname);
606 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
607 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
608 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
610 memset(buf, 0, sizeof(buf));
612 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
613 printf("Failed to create file\n");
618 /* Check for NT bug... */
619 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
620 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
621 smbcli_close(cli1->tree, fnum1);
622 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
623 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
625 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
626 smbcli_close(cli1->tree, fnum1);
627 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
628 smbcli_unlock(cli1->tree, fnum3, 0, 1);
630 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
631 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
633 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
635 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
636 EXPECTED(ret, False);
638 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
640 /* Unlock the process 2 lock. */
641 smbcli_unlock(cli2->tree, fnum2, 0, 4);
643 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
644 EXPECTED(ret, False);
646 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
648 /* Unlock the process 1 fnum3 lock. */
649 smbcli_unlock(cli1->tree, fnum3, 0, 4);
651 /* Stack 2 more locks here. */
652 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
653 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
656 printf("the same process %s stack read locks\n", ret?"can":"cannot");
658 /* Unlock the first process lock, then check this was the WRITE lock that was
661 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
662 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
665 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
667 /* Unlock the process 2 lock. */
668 smbcli_unlock(cli2->tree, fnum2, 0, 4);
670 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
672 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
673 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
674 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
677 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
679 /* Ensure the next unlock fails. */
680 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
681 EXPECTED(ret, False);
682 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
684 /* Ensure connection 2 can get a write lock. */
685 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
688 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
692 smbcli_close(cli1->tree, fnum1);
693 smbcli_close(cli2->tree, fnum2);
694 smbcli_unlink(cli1->tree, fname);
695 if (!torture_close_connection(cli1)) {
698 if (!torture_close_connection(cli2)) {
702 printf("finished locktest5\n");
708 tries the unusual lockingX locktype bits
710 BOOL torture_locktest6(int dummy)
712 struct smbcli_state *cli;
713 const char *fname[1] = { "\\lock6.txt" };
718 if (!torture_open_connection(&cli)) {
722 printf("starting locktest6\n");
725 printf("Testing %s\n", fname[i]);
727 smbcli_unlink(cli->tree, fname[i]);
729 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
730 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
731 smbcli_close(cli->tree, fnum);
732 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
734 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
735 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
736 smbcli_close(cli->tree, fnum);
737 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
739 smbcli_unlink(cli->tree, fname[i]);
742 torture_close_connection(cli);
744 printf("finished locktest6\n");
748 BOOL torture_locktest7(int dummy)
750 struct smbcli_state *cli1;
751 const char *fname = "\\lockt7.lck";
756 BOOL correct = False;
758 if (!torture_open_connection(&cli1)) {
762 printf("starting locktest7\n");
764 smbcli_unlink(cli1->tree, fname);
766 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
768 memset(buf, 0, sizeof(buf));
770 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
771 printf("Failed to create file\n");
775 cli1->session->pid = 1;
777 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
778 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
781 printf("pid1 successfully locked range 130:4 for READ\n");
784 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
785 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
788 printf("pid1 successfully read the range 130:4\n");
791 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
792 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
793 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
794 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
798 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
802 cli1->session->pid = 2;
804 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
805 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
807 printf("pid2 successfully read the range 130:4\n");
810 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
811 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
812 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
813 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
817 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
821 cli1->session->pid = 1;
822 smbcli_unlock(cli1->tree, fnum1, 130, 4);
824 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
825 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
828 printf("pid1 successfully locked range 130:4 for WRITE\n");
831 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
832 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
835 printf("pid1 successfully read the range 130:4\n");
838 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
839 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
842 printf("pid1 successfully wrote to the range 130:4\n");
845 cli1->session->pid = 2;
847 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
848 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
849 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
850 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
854 printf("pid2 successfully read the range 130:4 (should be denied)\n");
858 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
859 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
860 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
861 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
865 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
869 printf("Testing truncate of locked file.\n");
871 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
874 printf("Unable to truncate locked file.\n");
878 printf("Truncated locked file.\n");
881 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
882 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
888 printf("Unable to truncate locked file. Size was %u\n", size);
893 cli1->session->pid = 1;
895 smbcli_unlock(cli1->tree, fnum1, 130, 4);
899 smbcli_close(cli1->tree, fnum1);
900 smbcli_close(cli1->tree, fnum2);
901 smbcli_unlink(cli1->tree, fname);
902 torture_close_connection(cli1);
904 printf("finished locktest7\n");