Janitorial duties to make autogen.sh portable.
[Samba/gebeck_regimport.git] / source3 / torture / torture.c
bloba4dfac849003043bdbdf9ad6b3c22d798e7a537e
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
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 #define NO_SYSLOG
23 #include "includes.h"
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 static int port_to_use=0;
30 int torture_numops=100;
31 static int procnum; /* records process count number when forking */
32 static struct cli_state current_cli;
33 static fstring randomfname;
34 static BOOL use_oplocks;
35 static BOOL use_level_II_oplocks;
36 static const char *client_txt = "client_oplocks.txt";
37 static BOOL use_kerberos;
39 BOOL torture_showall = False;
41 static double create_procs(BOOL (*fn)(int), BOOL *result);
44 static struct timeval tp1,tp2;
46 void start_timer(void)
48 gettimeofday(&tp1,NULL);
51 double end_timer(void)
53 gettimeofday(&tp2,NULL);
54 return((tp2.tv_sec - tp1.tv_sec) +
55 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
59 /* return a pointer to a anonymous shared memory segment of size "size"
60 which will persist across fork() but will disappear when all processes
61 exit
63 The memory is not zeroed
65 This function uses system5 shared memory. It takes advantage of a property
66 that the memory is not destroyed if it is attached when the id is removed
68 void *shm_setup(int size)
70 int shmid;
71 void *ret;
73 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
74 if (shmid == -1) {
75 printf("can't get shared memory\n");
76 exit(1);
78 ret = (void *)shmat(shmid, 0, 0);
79 if (!ret || ret == (void *)-1) {
80 printf("can't attach to shared memory\n");
81 return NULL;
83 /* the following releases the ipc, but note that this process
84 and all its children will still have access to the memory, its
85 just that the shmid is no longer valid for other shm calls. This
86 means we don't leave behind lots of shm segments after we exit
88 See Stevens "advanced programming in unix env" for details
90 shmctl(shmid, IPC_RMID, 0);
92 return ret;
96 static BOOL open_nbt_connection(struct cli_state *c)
98 struct nmb_name called, calling;
99 struct in_addr ip;
101 ZERO_STRUCTP(c);
103 make_nmb_name(&calling, myname, 0x0);
104 make_nmb_name(&called , host, 0x20);
106 zero_ip(&ip);
108 if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
109 printf("Failed to connect with %s\n", host);
110 return False;
113 c->use_kerberos = use_kerberos;
115 c->timeout = 120000; /* set a really long timeout (2 minutes) */
116 if (use_oplocks) c->use_oplocks = True;
117 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
119 if (!cli_session_request(c, &calling, &called)) {
120 printf("%s rejected the session\n",host);
121 cli_shutdown(c);
122 return False;
125 return True;
128 BOOL torture_open_connection(struct cli_state *c)
130 ZERO_STRUCTP(c);
132 if (!open_nbt_connection(c)) {
133 return False;
136 if (!cli_negprot(c)) {
137 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
138 cli_shutdown(c);
139 return False;
142 if (!cli_session_setup(c, username,
143 password, strlen(password),
144 password, strlen(password),
145 workgroup)) {
146 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
147 cli_shutdown(c);
148 return False;
151 if (!cli_send_tconX(c, share, "?????",
152 password, strlen(password)+1)) {
153 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
154 cli_shutdown(c);
155 return False;
158 return True;
162 BOOL torture_close_connection(struct cli_state *c)
164 BOOL ret = True;
165 if (!cli_tdis(c)) {
166 printf("tdis failed (%s)\n", cli_errstr(c));
167 ret = False;
170 cli_shutdown(c);
172 return ret;
176 /* check if the server produced the expected error code */
177 static BOOL check_error(int line, struct cli_state *c,
178 uint8 eclass, uint32 ecode, NTSTATUS nterr)
180 if (cli_is_dos_error(c)) {
181 uint8 class;
182 uint32 num;
184 /* Check DOS error */
186 cli_dos_error(c, &class, &num);
188 if (eclass != class || ecode != num) {
189 printf("unexpected error code class=%d code=%d\n",
190 (int)class, (int)num);
191 printf(" expected %d/%d %s (line=%d)\n",
192 (int)eclass, (int)ecode, nt_errstr(nterr), line);
193 return False;
196 } else {
197 NTSTATUS status;
199 /* Check NT error */
201 status = cli_nt_error(c);
203 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
204 printf("unexpected error code %s\n", nt_errstr(status));
205 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
206 return False;
210 return True;
214 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
216 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
217 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
219 return True;
223 static BOOL rw_torture(struct cli_state *c)
225 const char *lockfname = "\\torture.lck";
226 fstring fname;
227 int fnum;
228 int fnum2;
229 pid_t pid2, pid = getpid();
230 int i, j;
231 char buf[1024];
232 BOOL correct = True;
234 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
235 DENY_NONE);
236 if (fnum2 == -1)
237 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
238 if (fnum2 == -1) {
239 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
240 return False;
244 for (i=0;i<torture_numops;i++) {
245 unsigned n = (unsigned)sys_random()%10;
246 if (i % 10 == 0) {
247 printf("%d\r", i); fflush(stdout);
249 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
251 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
252 return False;
255 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
256 if (fnum == -1) {
257 printf("open failed (%s)\n", cli_errstr(c));
258 correct = False;
259 break;
262 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
263 printf("write failed (%s)\n", cli_errstr(c));
264 correct = False;
267 for (j=0;j<50;j++) {
268 if (cli_write(c, fnum, 0, (char *)buf,
269 sizeof(pid)+(j*sizeof(buf)),
270 sizeof(buf)) != sizeof(buf)) {
271 printf("write failed (%s)\n", cli_errstr(c));
272 correct = False;
276 pid2 = 0;
278 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
279 printf("read failed (%s)\n", cli_errstr(c));
280 correct = False;
283 if (pid2 != pid) {
284 printf("data corruption!\n");
285 correct = False;
288 if (!cli_close(c, fnum)) {
289 printf("close failed (%s)\n", cli_errstr(c));
290 correct = False;
293 if (!cli_unlink(c, fname)) {
294 printf("unlink failed (%s)\n", cli_errstr(c));
295 correct = False;
298 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
299 printf("unlock failed (%s)\n", cli_errstr(c));
300 correct = False;
304 cli_close(c, fnum2);
305 cli_unlink(c, lockfname);
307 printf("%d\n", i);
309 return correct;
312 static BOOL run_torture(int dummy)
314 struct cli_state cli;
315 BOOL ret;
317 cli = current_cli;
319 cli_sockopt(&cli, sockops);
321 ret = rw_torture(&cli);
323 if (!torture_close_connection(&cli)) {
324 ret = False;
327 return ret;
330 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
332 int fnum = -1;
333 int i = 0;
334 char buf[131072];
335 char buf_rd[131072];
336 unsigned count;
337 unsigned countprev = 0;
338 ssize_t sent = 0;
339 BOOL correct = True;
341 srandom(1);
342 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
344 SIVAL(buf, i, sys_random());
347 if (procnum == 0)
349 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
350 DENY_NONE);
351 if (fnum == -1) {
352 printf("first open read/write of %s failed (%s)\n",
353 lockfname, cli_errstr(c));
354 return False;
357 else
359 for (i = 0; i < 500 && fnum == -1; i++)
361 fnum = cli_open(c, lockfname, O_RDONLY,
362 DENY_NONE);
363 msleep(10);
365 if (fnum == -1) {
366 printf("second open read-only of %s failed (%s)\n",
367 lockfname, cli_errstr(c));
368 return False;
372 i = 0;
373 for (count = 0; count < sizeof(buf); count += sent)
375 if (count >= countprev) {
376 printf("%d %8d\r", i, count);
377 fflush(stdout);
378 i++;
379 countprev += (sizeof(buf) / 20);
382 if (procnum == 0)
384 sent = ((unsigned)sys_random()%(20))+ 1;
385 if (sent > sizeof(buf) - count)
387 sent = sizeof(buf) - count;
390 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
391 printf("write failed (%s)\n", cli_errstr(c));
392 correct = False;
395 else
397 sent = cli_read(c, fnum, buf_rd+count, count,
398 sizeof(buf)-count);
399 if (sent < 0)
401 printf("read failed offset:%d size:%d (%s)\n",
402 count, sizeof(buf)-count,
403 cli_errstr(c));
404 correct = False;
405 sent = 0;
407 if (sent > 0)
409 if (memcmp(buf_rd+count, buf+count, sent) != 0)
411 printf("read/write compare failed\n");
412 printf("offset: %d req %d recvd %d\n",
413 count, sizeof(buf)-count, sent);
414 correct = False;
415 break;
422 if (!cli_close(c, fnum)) {
423 printf("close failed (%s)\n", cli_errstr(c));
424 correct = False;
427 return correct;
430 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
432 const char *lockfname = "\\torture2.lck";
433 int fnum1;
434 int fnum2;
435 int i;
436 uchar buf[131072];
437 uchar buf_rd[131072];
438 BOOL correct = True;
439 ssize_t bytes_read;
441 if (!cli_unlink(c1, lockfname)) {
442 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
445 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
446 DENY_NONE);
447 if (fnum1 == -1) {
448 printf("first open read/write of %s failed (%s)\n",
449 lockfname, cli_errstr(c1));
450 return False;
452 fnum2 = cli_open(c2, lockfname, O_RDONLY,
453 DENY_NONE);
454 if (fnum2 == -1) {
455 printf("second open read-only of %s failed (%s)\n",
456 lockfname, cli_errstr(c2));
457 cli_close(c1, fnum1);
458 return False;
461 for (i=0;i<torture_numops;i++)
463 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
464 if (i % 10 == 0) {
465 printf("%d\r", i); fflush(stdout);
468 generate_random_buffer(buf, buf_size, False);
470 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
471 printf("write failed (%s)\n", cli_errstr(c1));
472 correct = False;
475 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
476 printf("read failed (%s)\n", cli_errstr(c2));
477 printf("read %d, expected %d\n", bytes_read, buf_size);
478 correct = False;
481 if (memcmp(buf_rd, buf, buf_size) != 0)
483 printf("read/write compare failed\n");
484 correct = False;
488 if (!cli_close(c2, fnum2)) {
489 printf("close failed (%s)\n", cli_errstr(c2));
490 correct = False;
492 if (!cli_close(c1, fnum1)) {
493 printf("close failed (%s)\n", cli_errstr(c1));
494 correct = False;
497 if (!cli_unlink(c1, lockfname)) {
498 printf("unlink failed (%s)\n", cli_errstr(c1));
499 correct = False;
502 return correct;
505 static BOOL run_readwritetest(int dummy)
507 static struct cli_state cli1, cli2;
508 BOOL test1, test2;
510 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
511 return False;
513 cli_sockopt(&cli1, sockops);
514 cli_sockopt(&cli2, sockops);
516 printf("starting readwritetest\n");
518 test1 = rw_torture2(&cli1, &cli2);
519 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
521 test2 = rw_torture2(&cli1, &cli1);
522 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
524 if (!torture_close_connection(&cli1)) {
525 test1 = False;
528 if (!torture_close_connection(&cli2)) {
529 test2 = False;
532 return (test1 && test2);
535 static BOOL run_readwritemulti(int dummy)
537 static struct cli_state cli;
538 BOOL test;
540 cli = current_cli;
542 cli_sockopt(&cli, sockops);
544 printf("run_readwritemulti: fname %s\n", randomfname);
545 test = rw_torture3(&cli, randomfname);
547 if (!torture_close_connection(&cli)) {
548 test = False;
551 return test;
554 static BOOL run_readwritelarge(int dummy)
556 static struct cli_state cli1;
557 int fnum1;
558 const char *lockfname = "\\large.dat";
559 size_t fsize;
560 char buf[126*1024];
561 BOOL correct = True;
563 if (!torture_open_connection(&cli1)) {
564 return False;
566 cli_sockopt(&cli1, sockops);
567 memset(buf,'\0',sizeof(buf));
569 cli1.max_xmit = 128*1024;
571 printf("starting readwritelarge\n");
573 cli_unlink(&cli1, lockfname);
575 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
576 if (fnum1 == -1) {
577 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
578 return False;
581 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
583 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
584 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
585 correct = False;
588 if (fsize == sizeof(buf))
589 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
590 else {
591 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
592 correct = False;
595 if (!cli_close(&cli1, fnum1)) {
596 printf("close failed (%s)\n", cli_errstr(&cli1));
597 correct = False;
600 if (!cli_unlink(&cli1, lockfname)) {
601 printf("unlink failed (%s)\n", cli_errstr(&cli1));
602 correct = False;
605 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
606 if (fnum1 == -1) {
607 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
608 return False;
611 cli1.max_xmit = 4*1024;
613 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
615 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
616 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
617 correct = False;
620 if (fsize == sizeof(buf))
621 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
622 else {
623 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
624 correct = False;
627 #if 0
628 /* ToDo - set allocation. JRA */
629 if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
630 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
631 return False;
633 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
634 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
635 correct = False;
637 if (fsize != 0)
638 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
639 #endif
641 if (!cli_close(&cli1, fnum1)) {
642 printf("close failed (%s)\n", cli_errstr(&cli1));
643 correct = False;
646 if (!torture_close_connection(&cli1)) {
647 correct = False;
649 return correct;
652 int line_count = 0;
653 int nbio_id;
655 #define ival(s) strtol(s, NULL, 0)
657 /* run a test that simulates an approximate netbench client load */
658 static BOOL run_netbench(int client)
660 struct cli_state cli;
661 int i;
662 fstring fname;
663 pstring line;
664 char cname[20];
665 FILE *f;
666 char *params[20];
667 BOOL correct = True;
669 cli = current_cli;
671 nbio_id = client;
673 cli_sockopt(&cli, sockops);
675 nb_setup(&cli);
677 slprintf(cname,sizeof(fname), "client%d", client);
679 f = fopen(client_txt, "r");
681 if (!f) {
682 perror(client_txt);
683 return False;
686 while (fgets(line, sizeof(line)-1, f)) {
687 line_count++;
689 line[strlen(line)-1] = 0;
691 /* printf("[%d] %s\n", line_count, line); */
693 all_string_sub(line,"client1", cname, sizeof(line));
695 /* parse the command parameters */
696 params[0] = strtok(line," ");
697 i = 0;
698 while (params[i]) params[++i] = strtok(NULL," ");
700 params[i] = "";
702 if (i < 2) continue;
704 if (!strncmp(params[0],"SMB", 3)) {
705 printf("ERROR: You are using a dbench 1 load file\n");
706 exit(1);
709 if (!strcmp(params[0],"NTCreateX")) {
710 nb_createx(params[1], ival(params[2]), ival(params[3]),
711 ival(params[4]));
712 } else if (!strcmp(params[0],"Close")) {
713 nb_close(ival(params[1]));
714 } else if (!strcmp(params[0],"Rename")) {
715 nb_rename(params[1], params[2]);
716 } else if (!strcmp(params[0],"Unlink")) {
717 nb_unlink(params[1]);
718 } else if (!strcmp(params[0],"Deltree")) {
719 nb_deltree(params[1]);
720 } else if (!strcmp(params[0],"Rmdir")) {
721 nb_rmdir(params[1]);
722 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
723 nb_qpathinfo(params[1]);
724 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
725 nb_qfileinfo(ival(params[1]));
726 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
727 nb_qfsinfo(ival(params[1]));
728 } else if (!strcmp(params[0],"FIND_FIRST")) {
729 nb_findfirst(params[1]);
730 } else if (!strcmp(params[0],"WriteX")) {
731 nb_writex(ival(params[1]),
732 ival(params[2]), ival(params[3]), ival(params[4]));
733 } else if (!strcmp(params[0],"ReadX")) {
734 nb_readx(ival(params[1]),
735 ival(params[2]), ival(params[3]), ival(params[4]));
736 } else if (!strcmp(params[0],"Flush")) {
737 nb_flush(ival(params[1]));
738 } else {
739 printf("Unknown operation %s\n", params[0]);
740 exit(1);
743 fclose(f);
745 nb_cleanup();
747 if (!torture_close_connection(&cli)) {
748 correct = False;
751 return correct;
755 /* run a test that simulates an approximate netbench client load */
756 static BOOL run_nbench(int dummy)
758 double t;
759 BOOL correct = True;
761 nbio_shmem(nprocs);
763 nbio_id = -1;
765 signal(SIGALRM, nb_alarm);
766 alarm(1);
767 t = create_procs(run_netbench, &correct);
768 alarm(0);
770 printf("\nThroughput %g MB/sec\n",
771 1.0e-6 * nbio_total() / t);
772 return correct;
777 This test checks for two things:
779 1) correct support for retaining locks over a close (ie. the server
780 must not use posix semantics)
781 2) support for lock timeouts
783 static BOOL run_locktest1(int dummy)
785 static struct cli_state cli1, cli2;
786 const char *fname = "\\lockt1.lck";
787 int fnum1, fnum2, fnum3;
788 time_t t1, t2;
789 unsigned lock_timeout;
791 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
792 return False;
794 cli_sockopt(&cli1, sockops);
795 cli_sockopt(&cli2, sockops);
797 printf("starting locktest1\n");
799 cli_unlink(&cli1, fname);
801 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
802 if (fnum1 == -1) {
803 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
804 return False;
806 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
807 if (fnum2 == -1) {
808 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
809 return False;
811 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
812 if (fnum3 == -1) {
813 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
814 return False;
817 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
818 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
819 return False;
823 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
824 printf("lock2 succeeded! This is a locking bug\n");
825 return False;
826 } else {
827 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
828 NT_STATUS_LOCK_NOT_GRANTED)) return False;
832 lock_timeout = (1 + (random() % 20));
833 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
834 t1 = time(NULL);
835 if (cli_lock(&cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
836 printf("lock3 succeeded! This is a locking bug\n");
837 return False;
838 } else {
839 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
840 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
842 t2 = time(NULL);
844 if (t2 - t1 < 5) {
845 printf("error: This server appears not to support timed lock requests\n");
847 printf("server slept for %u seconds for a %u second timeout\n",
848 (unsigned int)(t2-t1), lock_timeout);
850 if (!cli_close(&cli1, fnum2)) {
851 printf("close1 failed (%s)\n", cli_errstr(&cli1));
852 return False;
855 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
856 printf("lock4 succeeded! This is a locking bug\n");
857 return False;
858 } else {
859 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
860 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
863 if (!cli_close(&cli1, fnum1)) {
864 printf("close2 failed (%s)\n", cli_errstr(&cli1));
865 return False;
868 if (!cli_close(&cli2, fnum3)) {
869 printf("close3 failed (%s)\n", cli_errstr(&cli2));
870 return False;
873 if (!cli_unlink(&cli1, fname)) {
874 printf("unlink failed (%s)\n", cli_errstr(&cli1));
875 return False;
879 if (!torture_close_connection(&cli1)) {
880 return False;
883 if (!torture_close_connection(&cli2)) {
884 return False;
887 printf("Passed locktest1\n");
888 return True;
892 checks for correct tconX support
894 static BOOL run_tcon_test(int dummy)
896 static struct cli_state cli1;
897 const char *fname = "\\tcontest.tmp";
898 int fnum1;
899 uint16 cnum;
900 char buf[4];
902 if (!torture_open_connection(&cli1)) {
903 return False;
905 cli_sockopt(&cli1, sockops);
907 printf("starting tcontest\n");
909 cli_unlink(&cli1, fname);
911 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
912 if (fnum1 == -1)
914 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
915 return False;
918 cnum = cli1.cnum;
920 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
922 printf("write failed (%s)", cli_errstr(&cli1));
923 return False;
926 if (!cli_send_tconX(&cli1, share, "?????",
927 password, strlen(password)+1)) {
928 printf("%s refused 2nd tree connect (%s)\n", host,
929 cli_errstr(&cli1));
930 cli_shutdown(&cli1);
931 return False;
934 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
936 printf("write succeeded (%s)", cli_errstr(&cli1));
937 return False;
940 if (cli_close(&cli1, fnum1)) {
941 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
942 return False;
945 if (!cli_tdis(&cli1)) {
946 printf("tdis failed (%s)\n", cli_errstr(&cli1));
947 return False;
950 cli1.cnum = cnum;
952 if (!cli_close(&cli1, fnum1)) {
953 printf("close2 failed (%s)\n", cli_errstr(&cli1));
954 return False;
957 if (!torture_close_connection(&cli1)) {
958 return False;
961 printf("Passed tcontest\n");
962 return True;
965 static BOOL tcon_devtest(struct cli_state *cli,
966 const char *myshare, const char *devtype,
967 NTSTATUS expected_error)
969 BOOL status;
970 BOOL ret;
972 status = cli_send_tconX(cli, myshare, devtype,
973 password, strlen(password)+1);
975 if (NT_STATUS_IS_OK(expected_error)) {
976 if (status) {
977 ret = True;
978 } else {
979 printf("tconX to share %s with type %s "
980 "should have succeeded but failed\n",
981 myshare, devtype);
982 ret = False;
984 cli_tdis(cli);
985 } else {
986 if (status) {
987 printf("tconx to share %s with type %s "
988 "should have failed but succeeded\n",
989 myshare, devtype);
990 ret = False;
991 } else {
992 if (NT_STATUS_EQUAL(cli_nt_error(cli),
993 expected_error)) {
994 ret = True;
995 } else {
996 printf("Returned unexpected error\n");
997 ret = False;
1001 return ret;
1005 checks for correct tconX support
1007 static BOOL run_tcon_devtype_test(int dummy)
1009 static struct cli_state *cli1 = NULL;
1010 BOOL retry;
1011 int flags = 0;
1012 NTSTATUS status;
1013 BOOL ret;
1015 status = cli_full_connection(&cli1, myname,
1016 host, NULL, port_to_use,
1017 NULL, NULL,
1018 username, workgroup,
1019 password, flags, &retry);
1021 if (!NT_STATUS_IS_OK(status)) {
1022 printf("could not open connection\n");
1023 return False;
1026 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
1027 ret = False;
1029 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
1030 ret = False;
1032 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1033 ret = False;
1035 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
1036 ret = False;
1038 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1039 ret = False;
1041 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
1042 ret = False;
1044 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
1045 ret = False;
1047 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1048 ret = False;
1050 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
1051 ret = False;
1053 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1054 ret = False;
1056 cli_shutdown(cli1);
1058 if (ret)
1059 printf("Passed tcondevtest\n");
1061 return ret;
1066 This test checks that
1068 1) the server supports multiple locking contexts on the one SMB
1069 connection, distinguished by PID.
1071 2) the server correctly fails overlapping locks made by the same PID (this
1072 goes against POSIX behaviour, which is why it is tricky to implement)
1074 3) the server denies unlock requests by an incorrect client PID
1076 static BOOL run_locktest2(int dummy)
1078 static struct cli_state cli;
1079 const char *fname = "\\lockt2.lck";
1080 int fnum1, fnum2, fnum3;
1081 BOOL correct = True;
1083 if (!torture_open_connection(&cli)) {
1084 return False;
1087 cli_sockopt(&cli, sockops);
1089 printf("starting locktest2\n");
1091 cli_unlink(&cli, fname);
1093 cli_setpid(&cli, 1);
1095 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1096 if (fnum1 == -1) {
1097 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1098 return False;
1101 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1102 if (fnum2 == -1) {
1103 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
1104 return False;
1107 cli_setpid(&cli, 2);
1109 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1110 if (fnum3 == -1) {
1111 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
1112 return False;
1115 cli_setpid(&cli, 1);
1117 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1118 printf("lock1 failed (%s)\n", cli_errstr(&cli));
1119 return False;
1122 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1123 printf("WRITE lock1 succeeded! This is a locking bug\n");
1124 correct = False;
1125 } else {
1126 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1127 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1130 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1131 printf("WRITE lock2 succeeded! This is a locking bug\n");
1132 correct = False;
1133 } else {
1134 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1135 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1138 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1139 printf("READ lock2 succeeded! This is a locking bug\n");
1140 correct = False;
1141 } else {
1142 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1143 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1146 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1147 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1149 cli_setpid(&cli, 2);
1150 if (cli_unlock(&cli, fnum1, 100, 4)) {
1151 printf("unlock at 100 succeeded! This is a locking bug\n");
1152 correct = False;
1155 if (cli_unlock(&cli, fnum1, 0, 4)) {
1156 printf("unlock1 succeeded! This is a locking bug\n");
1157 correct = False;
1158 } else {
1159 if (!check_error(__LINE__, &cli,
1160 ERRDOS, ERRlock,
1161 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1164 if (cli_unlock(&cli, fnum1, 0, 8)) {
1165 printf("unlock2 succeeded! This is a locking bug\n");
1166 correct = False;
1167 } else {
1168 if (!check_error(__LINE__, &cli,
1169 ERRDOS, ERRlock,
1170 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1173 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1174 printf("lock3 succeeded! This is a locking bug\n");
1175 correct = False;
1176 } else {
1177 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1180 cli_setpid(&cli, 1);
1182 if (!cli_close(&cli, fnum1)) {
1183 printf("close1 failed (%s)\n", cli_errstr(&cli));
1184 return False;
1187 if (!cli_close(&cli, fnum2)) {
1188 printf("close2 failed (%s)\n", cli_errstr(&cli));
1189 return False;
1192 if (!cli_close(&cli, fnum3)) {
1193 printf("close3 failed (%s)\n", cli_errstr(&cli));
1194 return False;
1197 if (!torture_close_connection(&cli)) {
1198 correct = False;
1201 printf("locktest2 finished\n");
1203 return correct;
1208 This test checks that
1210 1) the server supports the full offset range in lock requests
1212 static BOOL run_locktest3(int dummy)
1214 static struct cli_state cli1, cli2;
1215 const char *fname = "\\lockt3.lck";
1216 int fnum1, fnum2, i;
1217 uint32 offset;
1218 BOOL correct = True;
1220 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1222 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1223 return False;
1225 cli_sockopt(&cli1, sockops);
1226 cli_sockopt(&cli2, sockops);
1228 printf("starting locktest3\n");
1230 cli_unlink(&cli1, fname);
1232 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1233 if (fnum1 == -1) {
1234 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1235 return False;
1237 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1238 if (fnum2 == -1) {
1239 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1240 return False;
1243 for (offset=i=0;i<torture_numops;i++) {
1244 NEXT_OFFSET;
1245 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1246 printf("lock1 %d failed (%s)\n",
1248 cli_errstr(&cli1));
1249 return False;
1252 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1253 printf("lock2 %d failed (%s)\n",
1255 cli_errstr(&cli1));
1256 return False;
1260 for (offset=i=0;i<torture_numops;i++) {
1261 NEXT_OFFSET;
1263 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1264 printf("error: lock1 %d succeeded!\n", i);
1265 return False;
1268 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1269 printf("error: lock2 %d succeeded!\n", i);
1270 return False;
1273 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1274 printf("error: lock3 %d succeeded!\n", i);
1275 return False;
1278 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1279 printf("error: lock4 %d succeeded!\n", i);
1280 return False;
1284 for (offset=i=0;i<torture_numops;i++) {
1285 NEXT_OFFSET;
1287 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1288 printf("unlock1 %d failed (%s)\n",
1290 cli_errstr(&cli1));
1291 return False;
1294 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1295 printf("unlock2 %d failed (%s)\n",
1297 cli_errstr(&cli1));
1298 return False;
1302 if (!cli_close(&cli1, fnum1)) {
1303 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1304 return False;
1307 if (!cli_close(&cli2, fnum2)) {
1308 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1309 return False;
1312 if (!cli_unlink(&cli1, fname)) {
1313 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1314 return False;
1317 if (!torture_close_connection(&cli1)) {
1318 correct = False;
1321 if (!torture_close_connection(&cli2)) {
1322 correct = False;
1325 printf("finished locktest3\n");
1327 return correct;
1330 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1331 printf("** "); correct = False; \
1335 looks at overlapping locks
1337 static BOOL run_locktest4(int dummy)
1339 static struct cli_state cli1, cli2;
1340 const char *fname = "\\lockt4.lck";
1341 int fnum1, fnum2, f;
1342 BOOL ret;
1343 char buf[1000];
1344 BOOL correct = True;
1346 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1347 return False;
1350 cli_sockopt(&cli1, sockops);
1351 cli_sockopt(&cli2, sockops);
1353 printf("starting locktest4\n");
1355 cli_unlink(&cli1, fname);
1357 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1358 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1360 memset(buf, 0, sizeof(buf));
1362 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1363 printf("Failed to create file\n");
1364 correct = False;
1365 goto fail;
1368 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1369 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1370 EXPECTED(ret, False);
1371 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1373 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1374 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1375 EXPECTED(ret, True);
1376 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1378 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1379 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1380 EXPECTED(ret, False);
1381 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1383 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1384 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1385 EXPECTED(ret, True);
1386 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1388 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1389 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1390 EXPECTED(ret, False);
1391 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1393 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1394 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1395 EXPECTED(ret, True);
1396 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1398 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1399 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1400 EXPECTED(ret, True);
1401 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1403 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1404 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1405 EXPECTED(ret, False);
1406 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1408 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1409 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1410 EXPECTED(ret, False);
1411 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1413 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1414 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1415 EXPECTED(ret, True);
1416 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1418 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1419 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1420 EXPECTED(ret, False);
1421 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1423 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1424 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1425 cli_unlock(&cli1, fnum1, 110, 6);
1426 EXPECTED(ret, False);
1427 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1430 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1431 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1432 EXPECTED(ret, False);
1433 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1435 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1436 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1437 EXPECTED(ret, False);
1438 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1441 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1442 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1443 cli_unlock(&cli1, fnum1, 140, 4) &&
1444 cli_unlock(&cli1, fnum1, 140, 4);
1445 EXPECTED(ret, True);
1446 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1449 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1450 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1451 cli_unlock(&cli1, fnum1, 150, 4) &&
1452 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1453 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1454 cli_unlock(&cli1, fnum1, 150, 4);
1455 EXPECTED(ret, True);
1456 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1458 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1459 cli_unlock(&cli1, fnum1, 160, 4) &&
1460 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1461 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1462 EXPECTED(ret, True);
1463 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1465 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1466 cli_unlock(&cli1, fnum1, 170, 4) &&
1467 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1468 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1469 EXPECTED(ret, True);
1470 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1472 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1473 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1474 cli_unlock(&cli1, fnum1, 190, 4) &&
1475 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1476 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1477 EXPECTED(ret, True);
1478 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1480 cli_close(&cli1, fnum1);
1481 cli_close(&cli2, fnum2);
1482 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1483 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1484 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1485 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1486 cli_close(&cli1, fnum1) &&
1487 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1488 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1489 cli_close(&cli1, f);
1490 cli_close(&cli1, fnum1);
1491 EXPECTED(ret, True);
1492 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1494 fail:
1495 cli_close(&cli1, fnum1);
1496 cli_close(&cli2, fnum2);
1497 cli_unlink(&cli1, fname);
1498 torture_close_connection(&cli1);
1499 torture_close_connection(&cli2);
1501 printf("finished locktest4\n");
1502 return correct;
1506 looks at lock upgrade/downgrade.
1508 static BOOL run_locktest5(int dummy)
1510 static struct cli_state cli1, cli2;
1511 const char *fname = "\\lockt5.lck";
1512 int fnum1, fnum2, fnum3;
1513 BOOL ret;
1514 char buf[1000];
1515 BOOL correct = True;
1517 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1518 return False;
1521 cli_sockopt(&cli1, sockops);
1522 cli_sockopt(&cli2, sockops);
1524 printf("starting locktest5\n");
1526 cli_unlink(&cli1, fname);
1528 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1529 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1530 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1532 memset(buf, 0, sizeof(buf));
1534 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1535 printf("Failed to create file\n");
1536 correct = False;
1537 goto fail;
1540 /* Check for NT bug... */
1541 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1542 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1543 cli_close(&cli1, fnum1);
1544 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1545 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1546 EXPECTED(ret, True);
1547 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1548 cli_close(&cli1, fnum1);
1549 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1550 cli_unlock(&cli1, fnum3, 0, 1);
1552 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1553 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1554 EXPECTED(ret, True);
1555 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1557 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1558 EXPECTED(ret, False);
1560 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1562 /* Unlock the process 2 lock. */
1563 cli_unlock(&cli2, fnum2, 0, 4);
1565 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1566 EXPECTED(ret, False);
1568 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1570 /* Unlock the process 1 fnum3 lock. */
1571 cli_unlock(&cli1, fnum3, 0, 4);
1573 /* Stack 2 more locks here. */
1574 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1575 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1577 EXPECTED(ret, True);
1578 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1580 /* Unlock the first process lock, then check this was the WRITE lock that was
1581 removed. */
1583 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1584 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1586 EXPECTED(ret, True);
1587 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1589 /* Unlock the process 2 lock. */
1590 cli_unlock(&cli2, fnum2, 0, 4);
1592 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1594 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1595 cli_unlock(&cli1, fnum1, 0, 4) &&
1596 cli_unlock(&cli1, fnum1, 0, 4);
1598 EXPECTED(ret, True);
1599 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1601 /* Ensure the next unlock fails. */
1602 ret = cli_unlock(&cli1, fnum1, 0, 4);
1603 EXPECTED(ret, False);
1604 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1606 /* Ensure connection 2 can get a write lock. */
1607 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1608 EXPECTED(ret, True);
1610 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1613 fail:
1614 cli_close(&cli1, fnum1);
1615 cli_close(&cli2, fnum2);
1616 cli_unlink(&cli1, fname);
1617 if (!torture_close_connection(&cli1)) {
1618 correct = False;
1620 if (!torture_close_connection(&cli2)) {
1621 correct = False;
1624 printf("finished locktest5\n");
1626 return correct;
1630 tries the unusual lockingX locktype bits
1632 static BOOL run_locktest6(int dummy)
1634 static struct cli_state cli;
1635 const char *fname[1] = { "\\lock6.txt" };
1636 int i;
1637 int fnum;
1638 NTSTATUS status;
1640 if (!torture_open_connection(&cli)) {
1641 return False;
1644 cli_sockopt(&cli, sockops);
1646 printf("starting locktest6\n");
1648 for (i=0;i<1;i++) {
1649 printf("Testing %s\n", fname[i]);
1651 cli_unlink(&cli, fname[i]);
1653 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1654 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1655 cli_close(&cli, fnum);
1656 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1658 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1659 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1660 cli_close(&cli, fnum);
1661 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1663 cli_unlink(&cli, fname[i]);
1666 torture_close_connection(&cli);
1668 printf("finished locktest6\n");
1669 return True;
1673 test whether fnums and tids open on one VC are available on another (a major
1674 security hole)
1676 static BOOL run_fdpasstest(int dummy)
1678 static struct cli_state cli1, cli2, cli3;
1679 const char *fname = "\\fdpass.tst";
1680 int fnum1;
1681 pstring buf;
1683 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1684 return False;
1686 cli_sockopt(&cli1, sockops);
1687 cli_sockopt(&cli2, sockops);
1689 printf("starting fdpasstest\n");
1691 cli_unlink(&cli1, fname);
1693 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1694 if (fnum1 == -1) {
1695 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1696 return False;
1699 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1700 printf("write failed (%s)\n", cli_errstr(&cli1));
1701 return False;
1704 cli3 = cli2;
1705 cli3.vuid = cli1.vuid;
1706 cli3.cnum = cli1.cnum;
1707 cli3.pid = cli1.pid;
1709 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1710 printf("read succeeded! nasty security hole [%s]\n",
1711 buf);
1712 return False;
1715 cli_close(&cli1, fnum1);
1716 cli_unlink(&cli1, fname);
1718 torture_close_connection(&cli1);
1719 torture_close_connection(&cli2);
1721 printf("finished fdpasstest\n");
1722 return True;
1727 This test checks that
1729 1) the server does not allow an unlink on a file that is open
1731 static BOOL run_unlinktest(int dummy)
1733 static struct cli_state cli;
1734 const char *fname = "\\unlink.tst";
1735 int fnum;
1736 BOOL correct = True;
1738 if (!torture_open_connection(&cli)) {
1739 return False;
1742 cli_sockopt(&cli, sockops);
1744 printf("starting unlink test\n");
1746 cli_unlink(&cli, fname);
1748 cli_setpid(&cli, 1);
1750 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1751 if (fnum == -1) {
1752 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1753 return False;
1756 if (cli_unlink(&cli, fname)) {
1757 printf("error: server allowed unlink on an open file\n");
1758 correct = False;
1759 } else {
1760 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare,
1761 NT_STATUS_SHARING_VIOLATION);
1764 cli_close(&cli, fnum);
1765 cli_unlink(&cli, fname);
1767 if (!torture_close_connection(&cli)) {
1768 correct = False;
1771 printf("unlink test finished\n");
1773 return correct;
1778 test how many open files this server supports on the one socket
1780 static BOOL run_maxfidtest(int dummy)
1782 static struct cli_state cli;
1783 const char *template = "\\maxfid.%d.%d";
1784 fstring fname;
1785 int fnums[0x11000], i;
1786 int retries=4;
1787 BOOL correct = True;
1789 cli = current_cli;
1791 if (retries <= 0) {
1792 printf("failed to connect\n");
1793 return False;
1796 cli_sockopt(&cli, sockops);
1798 for (i=0; i<0x11000; i++) {
1799 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1800 if ((fnums[i] = cli_open(&cli, fname,
1801 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1802 -1) {
1803 printf("open of %s failed (%s)\n",
1804 fname, cli_errstr(&cli));
1805 printf("maximum fnum is %d\n", i);
1806 break;
1808 printf("%6d\r", i);
1810 printf("%6d\n", i);
1811 i--;
1813 printf("cleaning up\n");
1814 for (;i>=0;i--) {
1815 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1816 cli_close(&cli, fnums[i]);
1817 if (!cli_unlink(&cli, fname)) {
1818 printf("unlink of %s failed (%s)\n",
1819 fname, cli_errstr(&cli));
1820 correct = False;
1822 printf("%6d\r", i);
1824 printf("%6d\n", 0);
1826 printf("maxfid test finished\n");
1827 if (!torture_close_connection(&cli)) {
1828 correct = False;
1830 return correct;
1833 /* generate a random buffer */
1834 static void rand_buf(char *buf, int len)
1836 while (len--) {
1837 *buf = (char)sys_random();
1838 buf++;
1842 /* send smb negprot commands, not reading the response */
1843 static BOOL run_negprot_nowait(int dummy)
1845 int i;
1846 static struct cli_state cli;
1847 BOOL correct = True;
1849 printf("starting negprot nowait test\n");
1851 if (!open_nbt_connection(&cli)) {
1852 return False;
1855 for (i=0;i<50000;i++) {
1856 cli_negprot_send(&cli);
1859 if (!torture_close_connection(&cli)) {
1860 correct = False;
1863 printf("finished negprot nowait test\n");
1865 return correct;
1869 /* send random IPC commands */
1870 static BOOL run_randomipc(int dummy)
1872 char *rparam = NULL;
1873 char *rdata = NULL;
1874 int rdrcnt,rprcnt;
1875 pstring param;
1876 int api, param_len, i;
1877 static struct cli_state cli;
1878 BOOL correct = True;
1879 int count = 50000;
1881 printf("starting random ipc test\n");
1883 if (!torture_open_connection(&cli)) {
1884 return False;
1887 for (i=0;i<count;i++) {
1888 api = sys_random() % 500;
1889 param_len = (sys_random() % 64);
1891 rand_buf(param, param_len);
1893 SSVAL(param,0,api);
1895 cli_api(&cli,
1896 param, param_len, 8,
1897 NULL, 0, BUFFER_SIZE,
1898 &rparam, &rprcnt,
1899 &rdata, &rdrcnt);
1900 if (i % 100 == 0) {
1901 printf("%d/%d\r", i,count);
1904 printf("%d/%d\n", i, count);
1906 if (!torture_close_connection(&cli)) {
1907 correct = False;
1910 printf("finished random ipc test\n");
1912 return correct;
1917 static void browse_callback(const char *sname, uint32 stype,
1918 const char *comment, void *state)
1920 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1926 This test checks the browse list code
1929 static BOOL run_browsetest(int dummy)
1931 static struct cli_state cli;
1932 BOOL correct = True;
1934 printf("starting browse test\n");
1936 if (!torture_open_connection(&cli)) {
1937 return False;
1940 printf("domain list:\n");
1941 cli_NetServerEnum(&cli, cli.server_domain,
1942 SV_TYPE_DOMAIN_ENUM,
1943 browse_callback, NULL);
1945 printf("machine list:\n");
1946 cli_NetServerEnum(&cli, cli.server_domain,
1947 SV_TYPE_ALL,
1948 browse_callback, NULL);
1950 if (!torture_close_connection(&cli)) {
1951 correct = False;
1954 printf("browse test finished\n");
1956 return correct;
1962 This checks how the getatr calls works
1964 static BOOL run_attrtest(int dummy)
1966 static struct cli_state cli;
1967 int fnum;
1968 time_t t, t2;
1969 const char *fname = "\\attrib.tst";
1970 BOOL correct = True;
1972 printf("starting attrib test\n");
1974 if (!torture_open_connection(&cli)) {
1975 return False;
1978 cli_unlink(&cli, fname);
1979 fnum = cli_open(&cli, fname,
1980 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1981 cli_close(&cli, fnum);
1982 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1983 printf("getatr failed (%s)\n", cli_errstr(&cli));
1984 correct = False;
1987 if (abs(t - time(NULL)) > 60*60*24*10) {
1988 printf("ERROR: SMBgetatr bug. time is %s",
1989 ctime(&t));
1990 t = time(NULL);
1991 correct = True;
1994 t2 = t-60*60*24; /* 1 day ago */
1996 if (!cli_setatr(&cli, fname, 0, t2)) {
1997 printf("setatr failed (%s)\n", cli_errstr(&cli));
1998 correct = True;
2001 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2002 printf("getatr failed (%s)\n", cli_errstr(&cli));
2003 correct = True;
2006 if (t != t2) {
2007 printf("ERROR: getatr/setatr bug. times are\n%s",
2008 ctime(&t));
2009 printf("%s", ctime(&t2));
2010 correct = True;
2013 cli_unlink(&cli, fname);
2015 if (!torture_close_connection(&cli)) {
2016 correct = False;
2019 printf("attrib test finished\n");
2021 return correct;
2026 This checks a couple of trans2 calls
2028 static BOOL run_trans2test(int dummy)
2030 static struct cli_state cli;
2031 int fnum;
2032 size_t size;
2033 time_t c_time, a_time, m_time, w_time, m_time2;
2034 const char *fname = "\\trans2.tst";
2035 const char *dname = "\\trans2";
2036 const char *fname2 = "\\trans2\\trans2.tst";
2037 pstring pname;
2038 BOOL correct = True;
2040 printf("starting trans2 test\n");
2042 if (!torture_open_connection(&cli)) {
2043 return False;
2046 cli_unlink(&cli, fname);
2047 fnum = cli_open(&cli, fname,
2048 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2049 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2050 NULL, NULL)) {
2051 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
2052 correct = False;
2055 if (!cli_qfilename(&cli, fnum, pname)) {
2056 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
2057 correct = False;
2060 if (strcmp(pname, fname)) {
2061 printf("qfilename gave different name? [%s] [%s]\n",
2062 fname, pname);
2063 correct = False;
2066 cli_close(&cli, fnum);
2068 sleep(2);
2070 cli_unlink(&cli, fname);
2071 fnum = cli_open(&cli, fname,
2072 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2073 if (fnum == -1) {
2074 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
2075 return False;
2077 cli_close(&cli, fnum);
2079 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2080 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
2081 correct = False;
2082 } else {
2083 if (c_time != m_time) {
2084 printf("create time=%s", ctime(&c_time));
2085 printf("modify time=%s", ctime(&m_time));
2086 printf("This system appears to have sticky create times\n");
2087 correct = False;
2089 if (a_time % (60*60) == 0) {
2090 printf("access time=%s", ctime(&a_time));
2091 printf("This system appears to set a midnight access time\n");
2092 correct = False;
2095 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2096 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2097 correct = False;
2102 cli_unlink(&cli, fname);
2103 fnum = cli_open(&cli, fname,
2104 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2105 cli_close(&cli, fnum);
2106 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2107 &w_time, &size, NULL, NULL)) {
2108 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2109 correct = False;
2110 } else {
2111 if (w_time < 60*60*24*2) {
2112 printf("write time=%s", ctime(&w_time));
2113 printf("This system appears to set a initial 0 write time\n");
2114 correct = False;
2118 cli_unlink(&cli, fname);
2121 /* check if the server updates the directory modification time
2122 when creating a new file */
2123 if (!cli_mkdir(&cli, dname)) {
2124 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2125 correct = False;
2127 sleep(3);
2128 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2129 &w_time, &size, NULL, NULL)) {
2130 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2131 correct = False;
2134 fnum = cli_open(&cli, fname2,
2135 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2136 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2137 cli_close(&cli, fnum);
2138 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2139 &w_time, &size, NULL, NULL)) {
2140 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2141 correct = False;
2142 } else {
2143 if (m_time2 == m_time) {
2144 printf("This system does not update directory modification times\n");
2145 correct = False;
2148 cli_unlink(&cli, fname2);
2149 cli_rmdir(&cli, dname);
2151 if (!torture_close_connection(&cli)) {
2152 correct = False;
2155 printf("trans2 test finished\n");
2157 return correct;
2161 This checks new W2K calls.
2164 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2166 char buf[4096];
2167 BOOL correct = True;
2169 memset(buf, 0xff, sizeof(buf));
2171 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2172 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2173 correct = False;
2174 } else {
2175 printf("qfileinfo: level %d\n", level);
2176 dump_data(0, buf, 256);
2177 printf("\n");
2179 return correct;
2182 static BOOL run_w2ktest(int dummy)
2184 static struct cli_state cli;
2185 int fnum;
2186 const char *fname = "\\w2ktest\\w2k.tst";
2187 int level;
2188 BOOL correct = True;
2190 printf("starting w2k test\n");
2192 if (!torture_open_connection(&cli)) {
2193 return False;
2196 fnum = cli_open(&cli, fname,
2197 O_RDWR | O_CREAT , DENY_NONE);
2199 for (level = 1004; level < 1040; level++) {
2200 new_trans(&cli, fnum, level);
2203 cli_close(&cli, fnum);
2205 if (!torture_close_connection(&cli)) {
2206 correct = False;
2209 printf("w2k test finished\n");
2211 return correct;
2216 this is a harness for some oplock tests
2218 static BOOL run_oplock1(int dummy)
2220 static struct cli_state cli1;
2221 const char *fname = "\\lockt1.lck";
2222 int fnum1;
2223 BOOL correct = True;
2225 printf("starting oplock test 1\n");
2227 if (!torture_open_connection(&cli1)) {
2228 return False;
2231 cli_unlink(&cli1, fname);
2233 cli_sockopt(&cli1, sockops);
2235 cli1.use_oplocks = True;
2237 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2238 if (fnum1 == -1) {
2239 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2240 return False;
2243 cli1.use_oplocks = False;
2245 cli_unlink(&cli1, fname);
2246 cli_unlink(&cli1, fname);
2248 if (!cli_close(&cli1, fnum1)) {
2249 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2250 return False;
2253 if (!cli_unlink(&cli1, fname)) {
2254 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2255 return False;
2258 if (!torture_close_connection(&cli1)) {
2259 correct = False;
2262 printf("finished oplock test 1\n");
2264 return correct;
2267 static BOOL run_oplock2(int dummy)
2269 static struct cli_state cli1, cli2;
2270 const char *fname = "\\lockt2.lck";
2271 int fnum1, fnum2;
2272 int saved_use_oplocks = use_oplocks;
2273 char buf[4];
2274 BOOL correct = True;
2275 volatile BOOL *shared_correct;
2277 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2278 *shared_correct = True;
2280 use_level_II_oplocks = True;
2281 use_oplocks = True;
2283 printf("starting oplock test 2\n");
2285 if (!torture_open_connection(&cli1)) {
2286 use_level_II_oplocks = False;
2287 use_oplocks = saved_use_oplocks;
2288 return False;
2291 cli1.use_oplocks = True;
2292 cli1.use_level_II_oplocks = True;
2294 if (!torture_open_connection(&cli2)) {
2295 use_level_II_oplocks = False;
2296 use_oplocks = saved_use_oplocks;
2297 return False;
2300 cli2.use_oplocks = True;
2301 cli2.use_level_II_oplocks = True;
2303 cli_unlink(&cli1, fname);
2305 cli_sockopt(&cli1, sockops);
2306 cli_sockopt(&cli2, sockops);
2308 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2309 if (fnum1 == -1) {
2310 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2311 return False;
2314 /* Don't need the globals any more. */
2315 use_level_II_oplocks = False;
2316 use_oplocks = saved_use_oplocks;
2318 if (fork() == 0) {
2319 /* Child code */
2320 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2321 if (fnum2 == -1) {
2322 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2323 *shared_correct = False;
2324 exit(0);
2327 sleep(2);
2329 if (!cli_close(&cli2, fnum2)) {
2330 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2331 *shared_correct = False;
2334 exit(0);
2337 sleep(2);
2339 /* Ensure cli1 processes the break. */
2341 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2342 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2343 correct = False;
2346 /* Should now be at level II. */
2347 /* Test if sending a write locks causes a break to none. */
2349 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2350 printf("lock failed (%s)\n", cli_errstr(&cli1));
2351 correct = False;
2354 cli_unlock(&cli1, fnum1, 0, 4);
2356 sleep(2);
2358 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2359 printf("lock failed (%s)\n", cli_errstr(&cli1));
2360 correct = False;
2363 cli_unlock(&cli1, fnum1, 0, 4);
2365 sleep(2);
2367 cli_read(&cli1, fnum1, buf, 0, 4);
2369 #if 0
2370 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2371 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2372 correct = False;
2374 #endif
2376 if (!cli_close(&cli1, fnum1)) {
2377 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2378 correct = False;
2381 sleep(4);
2383 if (!cli_unlink(&cli1, fname)) {
2384 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2385 correct = False;
2388 if (!torture_close_connection(&cli1)) {
2389 correct = False;
2392 if (!*shared_correct) {
2393 correct = False;
2396 printf("finished oplock test 2\n");
2398 return correct;
2401 /* handler for oplock 3 tests */
2402 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2404 printf("got oplock break fnum=%d level=%d\n",
2405 fnum, level);
2406 return cli_oplock_ack(cli, fnum, level);
2409 static BOOL run_oplock3(int dummy)
2411 static struct cli_state cli;
2412 const char *fname = "\\oplockt3.dat";
2413 int fnum;
2414 char buf[4] = "abcd";
2415 BOOL correct = True;
2416 volatile BOOL *shared_correct;
2418 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2419 *shared_correct = True;
2421 printf("starting oplock test 3\n");
2423 if (fork() == 0) {
2424 /* Child code */
2425 use_oplocks = True;
2426 use_level_II_oplocks = True;
2427 if (!torture_open_connection(&cli)) {
2428 *shared_correct = False;
2429 exit(0);
2431 sleep(2);
2432 /* try to trigger a oplock break in parent */
2433 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2434 cli_write(&cli, fnum, 0, buf, 0, 4);
2435 exit(0);
2438 /* parent code */
2439 use_oplocks = True;
2440 use_level_II_oplocks = True;
2441 if (!torture_open_connection(&cli)) {
2442 return False;
2444 cli_oplock_handler(&cli, oplock3_handler);
2445 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2446 cli_write(&cli, fnum, 0, buf, 0, 4);
2447 cli_close(&cli, fnum);
2448 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2449 cli.timeout = 20000;
2450 cli_receive_smb(&cli);
2451 printf("finished oplock test 3\n");
2453 return (correct && *shared_correct);
2455 /* What are we looking for here? What's sucess and what's FAILURE? */
2461 Test delete on close semantics.
2463 static BOOL run_deletetest(int dummy)
2465 static struct cli_state cli1;
2466 static struct cli_state cli2;
2467 const char *fname = "\\delete.file";
2468 int fnum1 = -1;
2469 int fnum2 = -1;
2470 BOOL correct = True;
2472 printf("starting delete test\n");
2474 ZERO_STRUCT(cli1);
2475 ZERO_STRUCT(cli2);
2477 if (!torture_open_connection(&cli1)) {
2478 return False;
2481 cli_sockopt(&cli1, sockops);
2483 /* Test 1 - this should *NOT* delete the file on close. */
2485 cli_setatr(&cli1, fname, 0, 0);
2486 cli_unlink(&cli1, fname);
2488 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2489 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2490 DELETE_ON_CLOSE_FLAG);
2492 if (fnum1 == -1) {
2493 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2494 correct = False;
2495 goto fail;
2498 if (!cli_close(&cli1, fnum1)) {
2499 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2500 correct = False;
2501 goto fail;
2504 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2505 if (fnum1 == -1) {
2506 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2507 correct = False;
2508 goto fail;
2511 if (!cli_close(&cli1, fnum1)) {
2512 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2513 correct = False;
2514 goto fail;
2517 printf("first delete on close test succeeded.\n");
2519 /* Test 2 - this should delete the file on close. */
2521 cli_setatr(&cli1, fname, 0, 0);
2522 cli_unlink(&cli1, fname);
2524 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2525 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2526 FILE_OVERWRITE_IF, 0);
2528 if (fnum1 == -1) {
2529 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2530 correct = False;
2531 goto fail;
2534 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2535 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2536 correct = False;
2537 goto fail;
2540 if (!cli_close(&cli1, fnum1)) {
2541 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2542 correct = False;
2543 goto fail;
2546 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2547 if (fnum1 != -1) {
2548 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2549 if (!cli_close(&cli1, fnum1)) {
2550 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2551 correct = False;
2552 goto fail;
2554 cli_unlink(&cli1, fname);
2555 } else
2556 printf("second delete on close test succeeded.\n");
2558 /* Test 3 - ... */
2559 cli_setatr(&cli1, fname, 0, 0);
2560 cli_unlink(&cli1, fname);
2562 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2563 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2565 if (fnum1 == -1) {
2566 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2567 correct = False;
2568 goto fail;
2571 /* This should fail with a sharing violation - open for delete is only compatible
2572 with SHARE_DELETE. */
2574 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2575 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2577 if (fnum2 != -1) {
2578 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2579 correct = False;
2580 goto fail;
2583 /* This should succeed. */
2585 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2586 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2588 if (fnum2 == -1) {
2589 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2590 correct = False;
2591 goto fail;
2594 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2595 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2596 correct = False;
2597 goto fail;
2600 if (!cli_close(&cli1, fnum1)) {
2601 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2602 correct = False;
2603 goto fail;
2606 if (!cli_close(&cli1, fnum2)) {
2607 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2608 correct = False;
2609 goto fail;
2612 /* This should fail - file should no longer be there. */
2614 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2615 if (fnum1 != -1) {
2616 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2617 if (!cli_close(&cli1, fnum1)) {
2618 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2620 cli_unlink(&cli1, fname);
2621 correct = False;
2622 goto fail;
2623 } else
2624 printf("third delete on close test succeeded.\n");
2626 /* Test 4 ... */
2627 cli_setatr(&cli1, fname, 0, 0);
2628 cli_unlink(&cli1, fname);
2630 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2631 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2633 if (fnum1 == -1) {
2634 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2635 correct = False;
2636 goto fail;
2639 /* This should succeed. */
2640 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2641 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2642 if (fnum2 == -1) {
2643 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2644 correct = False;
2645 goto fail;
2648 if (!cli_close(&cli1, fnum2)) {
2649 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2650 correct = False;
2651 goto fail;
2654 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2655 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2656 correct = False;
2657 goto fail;
2660 /* This should fail - no more opens once delete on close set. */
2661 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2662 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2663 if (fnum2 != -1) {
2664 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2665 correct = False;
2666 goto fail;
2667 } else
2668 printf("fourth delete on close test succeeded.\n");
2670 if (!cli_close(&cli1, fnum1)) {
2671 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2672 correct = False;
2673 goto fail;
2676 /* Test 5 ... */
2677 cli_setatr(&cli1, fname, 0, 0);
2678 cli_unlink(&cli1, fname);
2680 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2681 if (fnum1 == -1) {
2682 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2683 correct = False;
2684 goto fail;
2687 /* This should fail - only allowed on NT opens with DELETE access. */
2689 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2690 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2691 correct = False;
2692 goto fail;
2695 if (!cli_close(&cli1, fnum1)) {
2696 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2697 correct = False;
2698 goto fail;
2701 printf("fifth delete on close test succeeded.\n");
2703 /* Test 6 ... */
2704 cli_setatr(&cli1, fname, 0, 0);
2705 cli_unlink(&cli1, fname);
2707 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2708 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2709 FILE_OVERWRITE_IF, 0);
2711 if (fnum1 == -1) {
2712 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2713 correct = False;
2714 goto fail;
2717 /* This should fail - only allowed on NT opens with DELETE access. */
2719 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2720 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2721 correct = False;
2722 goto fail;
2725 if (!cli_close(&cli1, fnum1)) {
2726 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2727 correct = False;
2728 goto fail;
2731 printf("sixth delete on close test succeeded.\n");
2733 /* Test 7 ... */
2734 cli_setatr(&cli1, fname, 0, 0);
2735 cli_unlink(&cli1, fname);
2737 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2738 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2740 if (fnum1 == -1) {
2741 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2742 correct = False;
2743 goto fail;
2746 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2747 printf("[7] setting delete_on_close on file failed !\n");
2748 correct = False;
2749 goto fail;
2752 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2753 printf("[7] unsetting delete_on_close on file failed !\n");
2754 correct = False;
2755 goto fail;
2758 if (!cli_close(&cli1, fnum1)) {
2759 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2760 correct = False;
2761 goto fail;
2764 /* This next open should succeed - we reset the flag. */
2766 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2767 if (fnum1 == -1) {
2768 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2769 correct = False;
2770 goto fail;
2773 if (!cli_close(&cli1, fnum1)) {
2774 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2775 correct = False;
2776 goto fail;
2779 printf("seventh delete on close test succeeded.\n");
2781 /* Test 7 ... */
2782 cli_setatr(&cli1, fname, 0, 0);
2783 cli_unlink(&cli1, fname);
2785 if (!torture_open_connection(&cli2)) {
2786 printf("[8] failed to open second connection.\n");
2787 correct = False;
2788 goto fail;
2791 cli_sockopt(&cli1, sockops);
2793 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2794 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2796 if (fnum1 == -1) {
2797 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2798 correct = False;
2799 goto fail;
2802 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2803 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2805 if (fnum2 == -1) {
2806 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2807 correct = False;
2808 goto fail;
2811 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2812 printf("[8] setting delete_on_close on file failed !\n");
2813 correct = False;
2814 goto fail;
2817 if (!cli_close(&cli1, fnum1)) {
2818 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2819 correct = False;
2820 goto fail;
2823 if (!cli_close(&cli2, fnum2)) {
2824 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2825 correct = False;
2826 goto fail;
2829 /* This should fail.. */
2830 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2831 if (fnum1 != -1) {
2832 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2833 goto fail;
2834 correct = False;
2835 } else
2836 printf("eighth delete on close test succeeded.\n");
2838 /* This should fail - we need to set DELETE_ACCESS. */
2839 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2840 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2842 if (fnum1 != -1) {
2843 printf("[9] open of %s succeeded should have failed!\n", fname);
2844 correct = False;
2845 goto fail;
2848 printf("ninth delete on close test succeeded.\n");
2850 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2851 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2852 if (fnum1 == -1) {
2853 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2854 correct = False;
2855 goto fail;
2858 /* This should delete the file. */
2859 if (!cli_close(&cli1, fnum1)) {
2860 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2861 correct = False;
2862 goto fail;
2865 /* This should fail.. */
2866 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2867 if (fnum1 != -1) {
2868 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2869 goto fail;
2870 correct = False;
2871 } else
2872 printf("tenth delete on close test succeeded.\n");
2873 printf("finished delete test\n");
2875 fail:
2877 cli_close(&cli1, fnum1);
2878 cli_close(&cli1, fnum2);
2879 cli_setatr(&cli1, fname, 0, 0);
2880 cli_unlink(&cli1, fname);
2882 if (!torture_close_connection(&cli1)) {
2883 correct = False;
2885 if (!torture_close_connection(&cli2)) {
2886 correct = False;
2888 return correct;
2893 print out server properties
2895 static BOOL run_properties(int dummy)
2897 static struct cli_state cli;
2898 BOOL correct = True;
2900 printf("starting properties test\n");
2902 ZERO_STRUCT(cli);
2904 if (!torture_open_connection(&cli)) {
2905 return False;
2908 cli_sockopt(&cli, sockops);
2910 d_printf("Capabilities 0x%08x\n", cli.capabilities);
2912 if (!torture_close_connection(&cli)) {
2913 correct = False;
2916 return correct;
2921 /* FIRST_DESIRED_ACCESS 0xf019f */
2922 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2923 FILE_READ_EA| /* 0xf */ \
2924 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
2925 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2926 DELETE_ACCESS|READ_CONTROL_ACCESS|\
2927 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
2928 /* SECOND_DESIRED_ACCESS 0xe0080 */
2929 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2930 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2931 WRITE_OWNER_ACCESS /* 0xe0000 */
2933 #if 0
2934 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2935 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2936 FILE_READ_DATA|\
2937 WRITE_OWNER_ACCESS /* */
2938 #endif
2941 Test ntcreate calls made by xcopy
2943 static BOOL run_xcopy(int dummy)
2945 static struct cli_state cli1;
2946 const char *fname = "\\test.txt";
2947 BOOL correct = True;
2948 int fnum1, fnum2;
2950 printf("starting xcopy test\n");
2952 if (!torture_open_connection(&cli1)) {
2953 return False;
2956 fnum1 = cli_nt_create_full(&cli1, fname,
2957 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2958 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
2959 0x4044);
2961 if (fnum1 == -1) {
2962 printf("First open failed - %s\n", cli_errstr(&cli1));
2963 return False;
2966 fnum2 = cli_nt_create_full(&cli1, fname,
2967 SECOND_DESIRED_ACCESS, 0,
2968 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
2969 0x200000);
2970 if (fnum2 == -1) {
2971 printf("second open failed - %s\n", cli_errstr(&cli1));
2972 return False;
2975 if (!torture_close_connection(&cli1)) {
2976 correct = False;
2979 return correct;
2983 Test rename on files open with share delete and no share delete.
2985 static BOOL run_rename(int dummy)
2987 static struct cli_state cli1;
2988 const char *fname = "\\test.txt";
2989 const char *fname1 = "\\test1.txt";
2990 BOOL correct = True;
2991 int fnum1;
2993 printf("starting rename test\n");
2995 if (!torture_open_connection(&cli1)) {
2996 return False;
2999 cli_unlink(&cli1, fname);
3000 cli_unlink(&cli1, fname1);
3001 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3002 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3004 if (fnum1 == -1) {
3005 printf("First open failed - %s\n", cli_errstr(&cli1));
3006 return False;
3009 if (!cli_rename(&cli1, fname, fname1)) {
3010 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
3011 } else {
3012 printf("First rename succeeded - this should have failed !\n");
3013 correct = False;
3016 if (!cli_close(&cli1, fnum1)) {
3017 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
3018 return False;
3021 cli_unlink(&cli1, fname);
3022 cli_unlink(&cli1, fname1);
3023 fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3024 #if 0
3025 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3026 #else
3027 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3028 #endif
3030 if (fnum1 == -1) {
3031 printf("Second open failed - %s\n", cli_errstr(&cli1));
3032 return False;
3035 if (!cli_rename(&cli1, fname, fname1)) {
3036 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
3037 correct = False;
3038 } else {
3039 printf("Second rename succeeded\n");
3042 if (!cli_close(&cli1, fnum1)) {
3043 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
3044 return False;
3047 cli_unlink(&cli1, fname);
3048 cli_unlink(&cli1, fname1);
3050 fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3051 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3053 if (fnum1 == -1) {
3054 printf("Third open failed - %s\n", cli_errstr(&cli1));
3055 return False;
3059 #if 0
3061 int fnum2;
3063 fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3064 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3066 if (fnum2 == -1) {
3067 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
3068 return False;
3070 if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
3071 printf("[8] setting delete_on_close on file failed !\n");
3072 return False;
3075 if (!cli_close(&cli1, fnum2)) {
3076 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
3077 return False;
3080 #endif
3082 if (!cli_rename(&cli1, fname, fname1)) {
3083 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
3084 correct = False;
3085 } else {
3086 printf("Third rename succeeded\n");
3089 if (!cli_close(&cli1, fnum1)) {
3090 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
3091 return False;
3094 cli_unlink(&cli1, fname);
3095 cli_unlink(&cli1, fname1);
3097 if (!torture_close_connection(&cli1)) {
3098 correct = False;
3101 return correct;
3104 static BOOL run_pipe_number(int dummy)
3106 static struct cli_state cli1;
3107 const char *pipe_name = "\\SPOOLSS";
3108 int fnum;
3109 int num_pipes = 0;
3111 printf("starting pipenumber test\n");
3112 if (!torture_open_connection(&cli1)) {
3113 return False;
3116 cli_sockopt(&cli1, sockops);
3117 while(1) {
3118 fnum = cli_nt_create_full(&cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3119 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
3121 if (fnum == -1) {
3122 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(&cli1));
3123 break;
3125 num_pipes++;
3128 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3129 torture_close_connection(&cli1);
3130 return True;
3134 Test open mode returns on read-only files.
3136 static BOOL run_opentest(int dummy)
3138 static struct cli_state cli1;
3139 static struct cli_state cli2;
3140 const char *fname = "\\readonly.file";
3141 int fnum1, fnum2;
3142 char buf[20];
3143 size_t fsize;
3144 BOOL correct = True;
3145 char *tmp_path;
3146 uint16 attr;
3148 printf("starting open test\n");
3150 if (!torture_open_connection(&cli1)) {
3151 return False;
3154 cli_setatr(&cli1, fname, 0, 0);
3155 cli_unlink(&cli1, fname);
3157 cli_sockopt(&cli1, sockops);
3159 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3160 if (fnum1 == -1) {
3161 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3162 return False;
3165 if (!cli_close(&cli1, fnum1)) {
3166 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3167 return False;
3170 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3171 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3172 return False;
3175 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3176 if (fnum1 == -1) {
3177 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3178 return False;
3181 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3182 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3184 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess,
3185 NT_STATUS_ACCESS_DENIED)) {
3186 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3189 printf("finished open test 1\n");
3191 cli_close(&cli1, fnum1);
3193 /* Now try not readonly and ensure ERRbadshare is returned. */
3195 cli_setatr(&cli1, fname, 0, 0);
3197 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3198 if (fnum1 == -1) {
3199 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3200 return False;
3203 /* This will fail - but the error should be ERRshare. */
3204 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3206 if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare,
3207 NT_STATUS_SHARING_VIOLATION)) {
3208 printf("correct error code ERRDOS/ERRbadshare returned\n");
3211 if (!cli_close(&cli1, fnum1)) {
3212 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3213 return False;
3216 cli_unlink(&cli1, fname);
3218 printf("finished open test 2\n");
3220 /* Test truncate open disposition on file opened for read. */
3222 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3223 if (fnum1 == -1) {
3224 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3225 return False;
3228 /* write 20 bytes. */
3230 memset(buf, '\0', 20);
3232 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3233 printf("write failed (%s)\n", cli_errstr(&cli1));
3234 correct = False;
3237 if (!cli_close(&cli1, fnum1)) {
3238 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3239 return False;
3242 /* Ensure size == 20. */
3243 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3244 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3245 return False;
3248 if (fsize != 20) {
3249 printf("(3) file size != 20\n");
3250 return False;
3253 /* Now test if we can truncate a file opened for readonly. */
3255 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3256 if (fnum1 == -1) {
3257 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3258 return False;
3261 if (!cli_close(&cli1, fnum1)) {
3262 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3263 return False;
3266 /* Ensure size == 0. */
3267 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3268 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3269 return False;
3272 if (fsize != 0) {
3273 printf("(3) file size != 0\n");
3274 return False;
3276 printf("finished open test 3\n");
3278 cli_unlink(&cli1, fname);
3281 printf("testing ctemp\n");
3282 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3283 if (fnum1 == -1) {
3284 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3285 return False;
3287 printf("ctemp gave path %s\n", tmp_path);
3288 if (!cli_close(&cli1, fnum1)) {
3289 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3291 if (!cli_unlink(&cli1, tmp_path)) {
3292 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3295 /* Test the non-io opens... */
3297 if (!torture_open_connection(&cli2)) {
3298 return False;
3301 cli_setatr(&cli2, fname, 0, 0);
3302 cli_unlink(&cli2, fname);
3304 cli_sockopt(&cli2, sockops);
3306 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3308 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3309 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3311 if (fnum1 == -1) {
3312 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3313 return False;
3316 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3317 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3319 if (fnum2 == -1) {
3320 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3321 return False;
3324 if (!cli_close(&cli1, fnum1)) {
3325 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3326 return False;
3328 if (!cli_close(&cli2, fnum2)) {
3329 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3330 return False;
3333 printf("non-io open test #1 passed.\n");
3335 cli_unlink(&cli1, fname);
3337 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3339 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3340 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3342 if (fnum1 == -1) {
3343 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3344 return False;
3347 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3348 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3350 if (fnum2 == -1) {
3351 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3352 return False;
3355 if (!cli_close(&cli1, fnum1)) {
3356 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3357 return False;
3359 if (!cli_close(&cli2, fnum2)) {
3360 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3361 return False;
3364 printf("non-io open test #2 passed.\n");
3366 cli_unlink(&cli1, fname);
3368 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3370 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3371 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3373 if (fnum1 == -1) {
3374 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3375 return False;
3378 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3379 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3381 if (fnum2 == -1) {
3382 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3383 return False;
3386 if (!cli_close(&cli1, fnum1)) {
3387 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3388 return False;
3390 if (!cli_close(&cli2, fnum2)) {
3391 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3392 return False;
3395 printf("non-io open test #3 passed.\n");
3397 cli_unlink(&cli1, fname);
3399 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3401 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3402 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3404 if (fnum1 == -1) {
3405 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3406 return False;
3409 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3410 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3412 if (fnum2 != -1) {
3413 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3414 return False;
3417 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3419 if (!cli_close(&cli1, fnum1)) {
3420 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3421 return False;
3424 printf("non-io open test #4 passed.\n");
3426 cli_unlink(&cli1, fname);
3428 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3430 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3431 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3433 if (fnum1 == -1) {
3434 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3435 return False;
3438 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3439 FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3441 if (fnum2 == -1) {
3442 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3443 return False;
3446 if (!cli_close(&cli1, fnum1)) {
3447 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3448 return False;
3451 if (!cli_close(&cli2, fnum2)) {
3452 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3453 return False;
3456 printf("non-io open test #5 passed.\n");
3458 printf("TEST #6 testing 1 non-io open, one io open\n");
3460 cli_unlink(&cli1, fname);
3462 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3463 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3465 if (fnum1 == -1) {
3466 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3467 return False;
3470 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3471 FILE_SHARE_READ, FILE_OPEN_IF, 0);
3473 if (fnum2 == -1) {
3474 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3475 return False;
3478 if (!cli_close(&cli1, fnum1)) {
3479 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3480 return False;
3483 if (!cli_close(&cli2, fnum2)) {
3484 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3485 return False;
3488 printf("non-io open test #6 passed.\n");
3490 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3492 cli_unlink(&cli1, fname);
3494 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3495 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3497 if (fnum1 == -1) {
3498 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3499 return False;
3502 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3503 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3505 if (fnum2 != -1) {
3506 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3507 return False;
3510 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3512 if (!cli_close(&cli1, fnum1)) {
3513 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3514 return False;
3517 printf("non-io open test #7 passed.\n");
3519 cli_unlink(&cli1, fname);
3521 /* Test 8 - attributes test #1... */
3522 fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN,
3523 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3525 if (fnum1 == -1) {
3526 printf("test 8 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3527 return False;
3530 if (!cli_close(&cli1, fnum1)) {
3531 printf("test 8 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3532 return False;
3535 /* FILE_SUPERSEDE && FILE_OVERWRITE_IF have the same effect here. */
3536 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL,
3537 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3539 if (fnum1 == -1) {
3540 printf("test 8 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3541 return False;
3544 if (!cli_close(&cli1, fnum1)) {
3545 printf("test 8 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3546 return False;
3549 /* This open should fail with ACCESS_DENIED for FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF. */
3550 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3551 FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3553 if (fnum1 != -1) {
3554 printf("test 8 open 3 of %s succeeded - should have failed with (NT_STATUS_ACCESS_DENIED)\n", fname);
3555 correct = False;
3556 cli_close(&cli1, fnum1);
3557 } else {
3558 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED)) {
3559 printf("correct error code NT_STATUS_ACCESS_DENIED/ERRDOS:ERRnoaccess returned\n");
3563 printf("Attribute open test #8 %s.\n", correct ? "passed" : "failed");
3565 cli_unlink(&cli1, fname);
3568 * Test #9. Open with NORMAL, close, then re-open with attribute
3569 * HIDDEN and request to truncate.
3572 fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
3573 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3575 if (fnum1 == -1) {
3576 printf("test 9 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3577 return False;
3580 if (!cli_close(&cli1, fnum1)) {
3581 printf("test 9 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3582 return False;
3585 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN,
3586 FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3588 if (fnum1 == -1) {
3589 printf("test 9 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3590 return False;
3593 if (!cli_close(&cli1, fnum1)) {
3594 printf("test 9 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3595 return False;
3598 /* Ensure we have attr hidden. */
3599 if (!cli_getatr(&cli1, fname, &attr, NULL, NULL)) {
3600 printf("test 9 getatr(2) failed (%s)\n", cli_errstr(&cli1));
3601 return False;
3604 if (!(attr & FILE_ATTRIBUTE_HIDDEN)) {
3605 printf("test 9 getatr didn't have HIDDEN attribute\n");
3606 cli_unlink(&cli1, fname);
3607 return False;
3610 printf("Attribute open test #9 %s.\n", correct ? "passed" : "failed");
3612 cli_unlink(&cli1, fname);
3614 if (!torture_close_connection(&cli1)) {
3615 correct = False;
3617 if (!torture_close_connection(&cli2)) {
3618 correct = False;
3621 return correct;
3624 static void list_fn(file_info *finfo, const char *name, void *state)
3630 test directory listing speed
3632 static BOOL run_dirtest(int dummy)
3634 int i;
3635 static struct cli_state cli;
3636 int fnum;
3637 double t1;
3638 BOOL correct = True;
3640 printf("starting directory test\n");
3642 if (!torture_open_connection(&cli)) {
3643 return False;
3646 cli_sockopt(&cli, sockops);
3648 srandom(0);
3649 for (i=0;i<torture_numops;i++) {
3650 fstring fname;
3651 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3652 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3653 if (fnum == -1) {
3654 fprintf(stderr,"Failed to open %s\n", fname);
3655 return False;
3657 cli_close(&cli, fnum);
3660 t1 = end_timer();
3662 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3663 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3664 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3666 printf("dirtest core %g seconds\n", end_timer() - t1);
3668 srandom(0);
3669 for (i=0;i<torture_numops;i++) {
3670 fstring fname;
3671 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3672 cli_unlink(&cli, fname);
3675 if (!torture_close_connection(&cli)) {
3676 correct = False;
3679 printf("finished dirtest\n");
3681 return correct;
3684 static void del_fn(file_info *finfo, const char *mask, void *state)
3686 struct cli_state *pcli = (struct cli_state *)state;
3687 fstring fname;
3688 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3690 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3691 return;
3693 if (finfo->mode & aDIR) {
3694 if (!cli_rmdir(pcli, fname))
3695 printf("del_fn: failed to rmdir %s\n,", fname );
3696 } else {
3697 if (!cli_unlink(pcli, fname))
3698 printf("del_fn: failed to unlink %s\n,", fname );
3702 static BOOL run_dirtest1(int dummy)
3704 int i;
3705 static struct cli_state cli;
3706 int fnum, num_seen;
3707 BOOL correct = True;
3709 printf("starting directory test\n");
3711 if (!torture_open_connection(&cli)) {
3712 return False;
3715 cli_sockopt(&cli, sockops);
3717 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3718 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3719 cli_rmdir(&cli, "\\LISTDIR");
3720 cli_mkdir(&cli, "\\LISTDIR");
3722 /* Create 1000 files and 1000 directories. */
3723 for (i=0;i<1000;i++) {
3724 fstring fname;
3725 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
3726 fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3727 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
3728 if (fnum == -1) {
3729 fprintf(stderr,"Failed to open %s\n", fname);
3730 return False;
3732 cli_close(&cli, fnum);
3734 for (i=0;i<1000;i++) {
3735 fstring fname;
3736 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
3737 if (!cli_mkdir(&cli, fname)) {
3738 fprintf(stderr,"Failed to open %s\n", fname);
3739 return False;
3743 /* Now ensure that doing an old list sees both files and directories. */
3744 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
3745 printf("num_seen = %d\n", num_seen );
3746 /* We should see 100 files + 1000 directories + . and .. */
3747 if (num_seen != 2002)
3748 correct = False;
3750 /* Ensure if we have the "must have" bits we only see the
3751 * relevent entries.
3753 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
3754 printf("num_seen = %d\n", num_seen );
3755 if (num_seen != 1002)
3756 correct = False;
3758 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
3759 printf("num_seen = %d\n", num_seen );
3760 if (num_seen != 1000)
3761 correct = False;
3763 /* Delete everything. */
3764 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3765 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3766 cli_rmdir(&cli, "\\LISTDIR");
3768 #if 0
3769 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3770 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3771 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3772 #endif
3774 if (!torture_close_connection(&cli)) {
3775 correct = False;
3778 printf("finished dirtest1\n");
3780 return correct;
3783 static BOOL run_error_map_extract(int dummy) {
3785 static struct cli_state c_dos;
3786 static struct cli_state c_nt;
3788 uint32 error;
3790 uint32 flgs2, errnum;
3791 uint8 errclass;
3793 NTSTATUS nt_status;
3795 fstring user;
3797 /* NT-Error connection */
3799 if (!open_nbt_connection(&c_nt)) {
3800 return False;
3803 c_nt.use_spnego = False;
3805 if (!cli_negprot(&c_nt)) {
3806 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3807 cli_shutdown(&c_nt);
3808 return False;
3811 if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3812 workgroup)) {
3813 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3814 return False;
3817 /* DOS-Error connection */
3819 if (!open_nbt_connection(&c_dos)) {
3820 return False;
3823 c_dos.use_spnego = False;
3824 c_dos.force_dos_errors = True;
3826 if (!cli_negprot(&c_dos)) {
3827 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3828 cli_shutdown(&c_dos);
3829 return False;
3832 if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3833 workgroup)) {
3834 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3835 return False;
3838 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3839 snprintf(user, sizeof(user), "%X", error);
3841 if (cli_session_setup(&c_nt, user,
3842 password, strlen(password),
3843 password, strlen(password),
3844 workgroup)) {
3845 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3848 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3850 /* Case #1: 32-bit NT errors */
3851 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3852 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3853 } else {
3854 printf("/** Dos error on NT connection! (%s) */\n",
3855 cli_errstr(&c_nt));
3856 nt_status = NT_STATUS(0xc0000000);
3859 if (cli_session_setup(&c_dos, user,
3860 password, strlen(password),
3861 password, strlen(password),
3862 workgroup)) {
3863 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3865 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3867 /* Case #1: 32-bit NT errors */
3868 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3869 printf("/** NT error on DOS connection! (%s) */\n",
3870 cli_errstr(&c_nt));
3871 errnum = errclass = 0;
3872 } else {
3873 cli_dos_error(&c_dos, &errclass, &errnum);
3876 if (NT_STATUS_V(nt_status) != error) {
3877 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
3878 get_nt_error_c_code(NT_STATUS(error)),
3879 get_nt_error_c_code(nt_status));
3882 printf("\t{%s,\t%s,\t%s},\n",
3883 smb_dos_err_class(errclass),
3884 smb_dos_err_name(errclass, errnum),
3885 get_nt_error_c_code(NT_STATUS(error)));
3887 return True;
3890 static double create_procs(BOOL (*fn)(int), BOOL *result)
3892 int i, status;
3893 volatile pid_t *child_status;
3894 volatile BOOL *child_status_out;
3895 int synccount;
3896 int tries = 8;
3898 synccount = 0;
3900 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3901 if (!child_status) {
3902 printf("Failed to setup shared memory\n");
3903 return -1;
3906 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3907 if (!child_status_out) {
3908 printf("Failed to setup result status shared memory\n");
3909 return -1;
3912 for (i = 0; i < nprocs; i++) {
3913 child_status[i] = 0;
3914 child_status_out[i] = True;
3917 start_timer();
3919 for (i=0;i<nprocs;i++) {
3920 procnum = i;
3921 if (fork() == 0) {
3922 pid_t mypid = getpid();
3923 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3925 slprintf(myname,sizeof(myname),"CLIENT%d", i);
3927 while (1) {
3928 memset(&current_cli, 0, sizeof(current_cli));
3929 if (torture_open_connection(&current_cli)) break;
3930 if (tries-- == 0) {
3931 printf("pid %d failed to start\n", (int)getpid());
3932 _exit(1);
3934 msleep(10);
3937 child_status[i] = getpid();
3939 while (child_status[i] && end_timer() < 5) msleep(2);
3941 child_status_out[i] = fn(i);
3942 _exit(0);
3946 do {
3947 synccount = 0;
3948 for (i=0;i<nprocs;i++) {
3949 if (child_status[i]) synccount++;
3951 if (synccount == nprocs) break;
3952 msleep(10);
3953 } while (end_timer() < 30);
3955 if (synccount != nprocs) {
3956 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3957 *result = False;
3958 return end_timer();
3961 /* start the client load */
3962 start_timer();
3964 for (i=0;i<nprocs;i++) {
3965 child_status[i] = 0;
3968 printf("%d clients started\n", nprocs);
3970 for (i=0;i<nprocs;i++) {
3971 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3974 printf("\n");
3976 for (i=0;i<nprocs;i++) {
3977 if (!child_status_out[i]) {
3978 *result = False;
3981 return end_timer();
3984 #define FLAG_MULTIPROC 1
3986 static struct {
3987 const char *name;
3988 BOOL (*fn)(int);
3989 unsigned flags;
3990 } torture_ops[] = {
3991 {"FDPASS", run_fdpasstest, 0},
3992 {"LOCK1", run_locktest1, 0},
3993 {"LOCK2", run_locktest2, 0},
3994 {"LOCK3", run_locktest3, 0},
3995 {"LOCK4", run_locktest4, 0},
3996 {"LOCK5", run_locktest5, 0},
3997 {"LOCK6", run_locktest6, 0},
3998 {"UNLINK", run_unlinktest, 0},
3999 {"BROWSE", run_browsetest, 0},
4000 {"ATTR", run_attrtest, 0},
4001 {"TRANS2", run_trans2test, 0},
4002 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4003 {"TORTURE",run_torture, FLAG_MULTIPROC},
4004 {"RANDOMIPC", run_randomipc, 0},
4005 {"NEGNOWAIT", run_negprot_nowait, 0},
4006 {"NBENCH", run_nbench, 0},
4007 {"OPLOCK1", run_oplock1, 0},
4008 {"OPLOCK2", run_oplock2, 0},
4009 {"OPLOCK3", run_oplock3, 0},
4010 {"DIR", run_dirtest, 0},
4011 {"DIR1", run_dirtest1, 0},
4012 {"DENY1", torture_denytest1, 0},
4013 {"DENY2", torture_denytest2, 0},
4014 {"TCON", run_tcon_test, 0},
4015 {"TCONDEV", run_tcon_devtype_test, 0},
4016 {"RW1", run_readwritetest, 0},
4017 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4018 {"RW3", run_readwritelarge, 0},
4019 {"OPEN", run_opentest, 0},
4020 {"XCOPY", run_xcopy, 0},
4021 {"RENAME", run_rename, 0},
4022 {"DELETE", run_deletetest, 0},
4023 {"PROPERTIES", run_properties, 0},
4024 {"MANGLE", torture_mangle, 0},
4025 {"W2K", run_w2ktest, 0},
4026 {"TRANS2SCAN", torture_trans2_scan, 0},
4027 {"NTTRANSSCAN", torture_nttrans_scan, 0},
4028 {"UTABLE", torture_utable, 0},
4029 {"CASETABLE", torture_casetable, 0},
4030 {"ERRMAPEXTRACT", run_error_map_extract, 0},
4031 {"PIPE_NUMBER", run_pipe_number, 0},
4032 {NULL, NULL, 0}};
4036 /****************************************************************************
4037 run a specified test or "ALL"
4038 ****************************************************************************/
4039 static BOOL run_test(const char *name)
4041 BOOL ret = True;
4042 BOOL result = True;
4043 int i;
4044 double t;
4045 if (strequal(name,"ALL")) {
4046 for (i=0;torture_ops[i].name;i++) {
4047 run_test(torture_ops[i].name);
4051 for (i=0;torture_ops[i].name;i++) {
4052 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
4053 (unsigned)random());
4055 if (strequal(name, torture_ops[i].name)) {
4056 printf("Running %s\n", name);
4057 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4058 t = create_procs(torture_ops[i].fn, &result);
4059 if (!result) {
4060 ret = False;
4061 printf("TEST %s FAILED!\n", name);
4064 } else {
4065 start_timer();
4066 if (!torture_ops[i].fn(0)) {
4067 ret = False;
4068 printf("TEST %s FAILED!\n", name);
4070 t = end_timer();
4072 printf("%s took %g secs\n\n", name, t);
4075 return ret;
4079 static void usage(void)
4081 int i;
4083 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4085 printf("\t-d debuglevel\n");
4086 printf("\t-U user%%pass\n");
4087 printf("\t-k use kerberos\n");
4088 printf("\t-N numprocs\n");
4089 printf("\t-n my_netbios_name\n");
4090 printf("\t-W workgroup\n");
4091 printf("\t-o num_operations\n");
4092 printf("\t-O socket_options\n");
4093 printf("\t-m maximum protocol\n");
4094 printf("\t-L use oplocks\n");
4095 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4096 printf("\t-A showall\n");
4097 printf("\t-s seed\n");
4098 printf("\n\n");
4100 printf("tests are:");
4101 for (i=0;torture_ops[i].name;i++) {
4102 printf(" %s", torture_ops[i].name);
4104 printf("\n");
4106 printf("default test is ALL\n");
4108 exit(1);
4115 /****************************************************************************
4116 main program
4117 ****************************************************************************/
4118 int main(int argc,char *argv[])
4120 int opt, i;
4121 char *p;
4122 int gotuser = 0;
4123 int gotpass = 0;
4124 extern char *optarg;
4125 extern int optind;
4126 BOOL correct = True;
4128 dbf = x_stdout;
4130 #ifdef HAVE_SETBUFFER
4131 setbuffer(stdout, NULL, 0);
4132 #endif
4134 lp_load(dyn_CONFIGFILE,True,False,False);
4135 load_interfaces();
4137 if (argc < 2) {
4138 usage();
4141 for(p = argv[1]; *p; p++)
4142 if(*p == '\\')
4143 *p = '/';
4145 if (strncmp(argv[1], "//", 2)) {
4146 usage();
4149 fstrcpy(host, &argv[1][2]);
4150 p = strchr_m(&host[2],'/');
4151 if (!p) {
4152 usage();
4154 *p = 0;
4155 fstrcpy(share, p+1);
4157 get_myname(myname);
4159 if (*username == 0 && getenv("LOGNAME")) {
4160 fstrcpy(username,getenv("LOGNAME"));
4163 argc--;
4164 argv++;
4166 srandom(time(NULL));
4168 fstrcpy(workgroup, lp_workgroup());
4170 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4171 switch (opt) {
4172 case 's':
4173 srandom(atoi(optarg));
4174 break;
4175 case 'W':
4176 fstrcpy(workgroup,optarg);
4177 break;
4178 case 'm':
4179 max_protocol = interpret_protocol(optarg, max_protocol);
4180 break;
4181 case 'N':
4182 nprocs = atoi(optarg);
4183 break;
4184 case 'o':
4185 torture_numops = atoi(optarg);
4186 break;
4187 case 'd':
4188 DEBUGLEVEL = atoi(optarg);
4189 break;
4190 case 'O':
4191 sockops = optarg;
4192 break;
4193 case 'L':
4194 use_oplocks = True;
4195 break;
4196 case 'A':
4197 torture_showall = True;
4198 break;
4199 case 'n':
4200 fstrcpy(myname, optarg);
4201 break;
4202 case 'c':
4203 client_txt = optarg;
4204 break;
4205 case 'k':
4206 #ifdef HAVE_KRB5
4207 use_kerberos = True;
4208 #else
4209 d_printf("No kerberos support compiled in\n");
4210 exit(1);
4211 #endif
4212 break;
4213 case 'U':
4214 gotuser = 1;
4215 fstrcpy(username,optarg);
4216 p = strchr_m(username,'%');
4217 if (p) {
4218 *p = 0;
4219 fstrcpy(password, p+1);
4220 gotpass = 1;
4222 break;
4223 default:
4224 printf("Unknown option %c (%d)\n", (char)opt, opt);
4225 usage();
4229 if(use_kerberos && !gotuser) gotpass = True;
4231 while (!gotpass) {
4232 p = getpass("Password:");
4233 if (p) {
4234 fstrcpy(password, p);
4235 gotpass = 1;
4239 printf("host=%s share=%s user=%s myname=%s\n",
4240 host, share, username, myname);
4242 if (argc == 1) {
4243 correct = run_test("ALL");
4244 } else {
4245 for (i=1;i<argc;i++) {
4246 if (!run_test(argv[i])) {
4247 correct = False;
4252 if (correct) {
4253 return(0);
4254 } else {
4255 return(1);