old merge from 2.2
[Samba/gbeck.git] / source / torture / torture.c
blobe92c933015fe1c0a551875b479d449194a14f0af
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB torture tester
5 Copyright (C) Andrew Tridgell 1997-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define NO_SYSLOG
24 #include "includes.h"
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static char *sockops="TCP_NODELAY";
29 static int nprocs=1, numops=100;
30 static int procnum; /* records process count number when forking */
31 static struct cli_state current_cli;
32 static fstring randomfname;
33 static BOOL use_oplocks;
34 static BOOL use_level_II_oplocks;
35 BOOL torture_showall = False;
37 static double create_procs(BOOL (*fn)(int), BOOL *result);
40 static struct timeval tp1,tp2;
42 static void start_timer(void)
44 gettimeofday(&tp1,NULL);
47 static double end_timer(void)
49 gettimeofday(&tp2,NULL);
50 return((tp2.tv_sec - tp1.tv_sec) +
51 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
55 /* return a pointer to a anonymous shared memory segment of size "size"
56 which will persist across fork() but will disappear when all processes
57 exit
59 The memory is not zeroed
61 This function uses system5 shared memory. It takes advantage of a property
62 that the memory is not destroyed if it is attached when the id is removed
64 static void *shm_setup(int size)
66 int shmid;
67 void *ret;
69 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
70 if (shmid == -1) {
71 printf("can't get shared memory\n");
72 exit(1);
74 ret = (void *)shmat(shmid, 0, 0);
75 if (!ret || ret == (void *)-1) {
76 printf("can't attach to shared memory\n");
77 return NULL;
79 /* the following releases the ipc, but note that this process
80 and all its children will still have access to the memory, its
81 just that the shmid is no longer valid for other shm calls. This
82 means we don't leave behind lots of shm segments after we exit
84 See Stevens "advanced programming in unix env" for details
86 shmctl(shmid, IPC_RMID, 0);
88 return ret;
92 static BOOL open_nbt_connection(struct cli_state *c)
94 struct nmb_name called, calling;
95 struct in_addr ip;
96 extern struct in_addr ipzero;
98 ZERO_STRUCTP(c);
100 make_nmb_name(&calling, myname, 0x0);
101 make_nmb_name(&called , host, 0x20);
103 ip = ipzero;
105 if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
106 printf("Failed to connect with %s\n", host);
107 return False;
110 c->timeout = 120000; /* set a really long timeout (2 minutes) */
111 if (use_oplocks) c->use_oplocks = True;
112 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
114 if (!cli_session_request(c, &calling, &called)) {
115 printf("%s rejected the session\n",host);
116 cli_shutdown(c);
117 return False;
120 return True;
123 BOOL torture_open_connection(struct cli_state *c)
125 ZERO_STRUCTP(c);
127 if (!open_nbt_connection(c)) {
128 return False;
131 if (!cli_negprot(c)) {
132 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
133 cli_shutdown(c);
134 return False;
137 if (!cli_session_setup(c, username,
138 password, strlen(password),
139 password, strlen(password),
140 workgroup)) {
141 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
142 cli_shutdown(c);
143 return False;
146 if (!cli_send_tconX(c, share, "?????",
147 password, strlen(password)+1)) {
148 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
149 cli_shutdown(c);
150 return False;
153 return True;
157 BOOL torture_close_connection(struct cli_state *c)
159 BOOL ret = True;
160 if (!cli_tdis(c)) {
161 printf("tdis failed (%s)\n", cli_errstr(c));
162 ret = False;
165 cli_shutdown(c);
167 return ret;
171 /* check if the server produced the expected error code */
172 static BOOL check_error(int line, struct cli_state *c,
173 uint8 eclass, uint32 ecode, NTSTATUS nterr)
175 if (cli_is_dos_error(c)) {
176 uint8 class;
177 uint32 num;
179 /* Check DOS error */
181 cli_dos_error(c, &class, &num);
183 if (eclass != class || ecode != num) {
184 printf("unexpected error code class=%d code=%d\n",
185 (int)class, (int)num);
186 printf(" expected %d/%d %s (line=%d)\n",
187 (int)eclass, (int)ecode, get_nt_error_msg(nterr), line);
188 return False;
191 } else {
192 NTSTATUS status;
194 /* Check NT error */
196 status = cli_nt_error(c);
198 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
199 printf("unexpected error code %s\n", get_nt_error_msg(status));
200 printf(" expected %s (line=%d)\n", get_nt_error_msg(nterr), line);
201 return False;
205 return True;
209 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
211 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
212 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
214 return True;
218 static BOOL rw_torture(struct cli_state *c)
220 char *lockfname = "\\torture.lck";
221 fstring fname;
222 int fnum;
223 int fnum2;
224 pid_t pid2, pid = getpid();
225 int i, j;
226 char buf[1024];
227 BOOL correct = True;
229 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
230 DENY_NONE);
231 if (fnum2 == -1)
232 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
233 if (fnum2 == -1) {
234 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
235 return False;
239 for (i=0;i<numops;i++) {
240 unsigned n = (unsigned)sys_random()%10;
241 if (i % 10 == 0) {
242 printf("%d\r", i); fflush(stdout);
244 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
246 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
247 return False;
250 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
251 if (fnum == -1) {
252 printf("open failed (%s)\n", cli_errstr(c));
253 correct = False;
254 break;
257 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
258 printf("write failed (%s)\n", cli_errstr(c));
259 correct = False;
262 for (j=0;j<50;j++) {
263 if (cli_write(c, fnum, 0, (char *)buf,
264 sizeof(pid)+(j*sizeof(buf)),
265 sizeof(buf)) != sizeof(buf)) {
266 printf("write failed (%s)\n", cli_errstr(c));
267 correct = False;
271 pid2 = 0;
273 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
274 printf("read failed (%s)\n", cli_errstr(c));
275 correct = False;
278 if (pid2 != pid) {
279 printf("data corruption!\n");
280 correct = False;
283 if (!cli_close(c, fnum)) {
284 printf("close failed (%s)\n", cli_errstr(c));
285 correct = False;
288 if (!cli_unlink(c, fname)) {
289 printf("unlink failed (%s)\n", cli_errstr(c));
290 correct = False;
293 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
294 printf("unlock failed (%s)\n", cli_errstr(c));
295 correct = False;
299 cli_close(c, fnum2);
300 cli_unlink(c, lockfname);
302 printf("%d\n", i);
304 return correct;
307 static BOOL run_torture(int dummy)
309 struct cli_state cli;
310 BOOL ret;
312 cli = current_cli;
314 cli_sockopt(&cli, sockops);
316 ret = rw_torture(&cli);
318 if (!torture_close_connection(&cli)) {
319 ret = False;
322 return ret;
325 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
327 int fnum = -1;
328 int i = 0;
329 char buf[131072];
330 char buf_rd[131072];
331 unsigned count;
332 unsigned countprev = 0;
333 ssize_t sent = 0;
334 BOOL correct = True;
336 srandom(1);
337 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
339 SIVAL(buf, i, sys_random());
342 if (procnum == 0)
344 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
345 DENY_NONE);
346 if (fnum == -1) {
347 printf("first open read/write of %s failed (%s)\n",
348 lockfname, cli_errstr(c));
349 return False;
352 else
354 for (i = 0; i < 500 && fnum == -1; i++)
356 fnum = cli_open(c, lockfname, O_RDONLY,
357 DENY_NONE);
358 msleep(10);
360 if (fnum == -1) {
361 printf("second open read-only of %s failed (%s)\n",
362 lockfname, cli_errstr(c));
363 return False;
367 i = 0;
368 for (count = 0; count < sizeof(buf); count += sent)
370 if (count >= countprev) {
371 printf("%d %8d\r", i, count);
372 fflush(stdout);
373 i++;
374 countprev += (sizeof(buf) / 20);
377 if (procnum == 0)
379 sent = ((unsigned)sys_random()%(20))+ 1;
380 if (sent > sizeof(buf) - count)
382 sent = sizeof(buf) - count;
385 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
386 printf("write failed (%s)\n", cli_errstr(c));
387 correct = False;
390 else
392 sent = cli_read(c, fnum, buf_rd+count, count,
393 sizeof(buf)-count);
394 if (sent < 0)
396 printf("read failed offset:%d size:%d (%s)\n",
397 count, sizeof(buf)-count,
398 cli_errstr(c));
399 correct = False;
400 sent = 0;
402 if (sent > 0)
404 if (memcmp(buf_rd+count, buf+count, sent) != 0)
406 printf("read/write compare failed\n");
407 printf("offset: %d req %d recvd %d\n",
408 count, sizeof(buf)-count, sent);
409 correct = False;
410 break;
417 if (!cli_close(c, fnum)) {
418 printf("close failed (%s)\n", cli_errstr(c));
419 correct = False;
422 return correct;
425 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
427 char *lockfname = "\\torture2.lck";
428 int fnum1;
429 int fnum2;
430 int i;
431 uchar buf[131072];
432 uchar buf_rd[131072];
433 BOOL correct = True;
434 ssize_t bytes_read;
436 if (!cli_unlink(c1, lockfname)) {
437 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
440 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
441 DENY_NONE);
442 if (fnum1 == -1) {
443 printf("first open read/write of %s failed (%s)\n",
444 lockfname, cli_errstr(c1));
445 return False;
447 fnum2 = cli_open(c2, lockfname, O_RDONLY,
448 DENY_NONE);
449 if (fnum2 == -1) {
450 printf("second open read-only of %s failed (%s)\n",
451 lockfname, cli_errstr(c2));
452 cli_close(c1, fnum1);
453 return False;
456 for (i=0;i<numops;i++)
458 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
459 if (i % 10 == 0) {
460 printf("%d\r", i); fflush(stdout);
463 generate_random_buffer(buf, buf_size, False);
465 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
466 printf("write failed (%s)\n", cli_errstr(c1));
467 correct = False;
470 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
471 printf("read failed (%s)\n", cli_errstr(c2));
472 printf("read %d, expected %d\n", bytes_read, buf_size);
473 correct = False;
476 if (memcmp(buf_rd, buf, buf_size) != 0)
478 printf("read/write compare failed\n");
479 correct = False;
483 if (!cli_close(c2, fnum2)) {
484 printf("close failed (%s)\n", cli_errstr(c2));
485 correct = False;
487 if (!cli_close(c1, fnum1)) {
488 printf("close failed (%s)\n", cli_errstr(c1));
489 correct = False;
492 if (!cli_unlink(c1, lockfname)) {
493 printf("unlink failed (%s)\n", cli_errstr(c1));
494 correct = False;
497 return correct;
500 static BOOL run_readwritetest(int dummy)
502 static struct cli_state cli1, cli2;
503 BOOL test1, test2;
505 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
506 return False;
508 cli_sockopt(&cli1, sockops);
509 cli_sockopt(&cli2, sockops);
511 printf("starting readwritetest\n");
513 test1 = rw_torture2(&cli1, &cli2);
514 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
516 test2 = rw_torture2(&cli1, &cli1);
517 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
519 if (!torture_close_connection(&cli1)) {
520 test1 = False;
523 if (!torture_close_connection(&cli2)) {
524 test2 = False;
527 return (test1 && test2);
530 static BOOL run_readwritemulti(int dummy)
532 static struct cli_state cli;
533 BOOL test;
535 cli = current_cli;
537 cli_sockopt(&cli, sockops);
539 printf("run_readwritemulti: fname %s\n", randomfname);
540 test = rw_torture3(&cli, randomfname);
542 if (!torture_close_connection(&cli)) {
543 test = False;
546 return test;
549 static BOOL run_readwritelarge(int dummy)
551 static struct cli_state cli1;
552 int fnum1;
553 char *lockfname = "\\large.dat";
554 size_t fsize;
555 char buf[0x10000];
556 BOOL correct = True;
558 if (!torture_open_connection(&cli1)) {
559 return False;
561 cli_sockopt(&cli1, sockops);
562 memset(buf,'\0',sizeof(buf));
564 cli1.max_xmit = 0x11000;
566 printf("starting readwritelarge\n");
568 cli_unlink(&cli1, lockfname);
570 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
571 if (fnum1 == -1) {
572 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
573 return False;
576 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
578 if (!cli_close(&cli1, fnum1)) {
579 printf("close failed (%s)\n", cli_errstr(&cli1));
580 correct = False;
583 if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
584 printf("qpathinfo 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_unlink(&cli1, lockfname)) {
596 printf("unlink failed (%s)\n", cli_errstr(&cli1));
597 correct = False;
600 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
601 if (fnum1 == -1) {
602 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
603 return False;
606 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
608 if (!cli_close(&cli1, fnum1)) {
609 printf("close failed (%s)\n", cli_errstr(&cli1));
610 correct = False;
613 if (!torture_close_connection(&cli1)) {
614 correct = False;
616 return correct;
619 int line_count = 0;
621 /* run a test that simulates an approximate netbench client load */
622 static BOOL run_netbench(int client)
624 struct cli_state cli;
625 int i;
626 fstring fname;
627 pstring line;
628 char cname[20];
629 FILE *f;
630 char *params[20];
631 BOOL correct = True;
633 cli = current_cli;
635 cli_sockopt(&cli, sockops);
637 nb_setup(&cli);
639 slprintf(cname,sizeof(fname), "CLIENT%d", client);
641 f = fopen("client.txt", "r");
643 if (!f) {
644 perror("client.txt");
645 return False;
648 while (fgets(line, sizeof(line)-1, f)) {
649 line_count++;
651 line[strlen(line)-1] = 0;
653 /* printf("[%d] %s\n", line_count, line); */
655 all_string_sub(line,"CLIENT1", cname, sizeof(line));
657 for (i=0;i<20;i++) params[i] = "";
659 /* parse the command parameters */
660 params[0] = strtok(line," ");
661 i = 0;
662 while (params[i]) params[++i] = strtok(NULL," ");
664 params[i] = "";
666 if (i < 2) continue;
668 if (strcmp(params[1],"REQUEST") == 0) {
669 if (!strcmp(params[0],"SMBopenX")) {
670 fstrcpy(fname, params[5]);
671 } else if (!strcmp(params[0],"SMBclose")) {
672 nb_close(atoi(params[3]));
673 } else if (!strcmp(params[0],"SMBmkdir")) {
674 nb_mkdir(params[3]);
675 } else if (!strcmp(params[0],"CREATE")) {
676 nb_create(params[3], atoi(params[5]));
677 } else if (!strcmp(params[0],"SMBrmdir")) {
678 nb_rmdir(params[3]);
679 } else if (!strcmp(params[0],"SMBunlink")) {
680 fstrcpy(fname, params[3]);
681 } else if (!strcmp(params[0],"SMBmv")) {
682 nb_rename(params[3], params[5]);
683 } else if (!strcmp(params[0],"SMBgetatr")) {
684 fstrcpy(fname, params[3]);
685 } else if (!strcmp(params[0],"SMBwrite")) {
686 nb_write(atoi(params[3]),
687 atoi(params[5]), atoi(params[7]));
688 } else if (!strcmp(params[0],"SMBwritebraw")) {
689 nb_write(atoi(params[3]),
690 atoi(params[7]), atoi(params[5]));
691 } else if (!strcmp(params[0],"SMBreadbraw")) {
692 nb_read(atoi(params[3]),
693 atoi(params[7]), atoi(params[5]));
694 } else if (!strcmp(params[0],"SMBread")) {
695 nb_read(atoi(params[3]),
696 atoi(params[5]), atoi(params[7]));
698 } else {
699 if (!strcmp(params[0],"SMBopenX")) {
700 if (!strncmp(params[2], "ERR", 3)) continue;
701 nb_open(fname, atoi(params[3]), atoi(params[5]));
702 } else if (!strcmp(params[0],"SMBgetatr")) {
703 if (!strncmp(params[2], "ERR", 3)) continue;
704 nb_stat(fname, atoi(params[3]));
705 } else if (!strcmp(params[0],"SMBunlink")) {
706 if (!strncmp(params[2], "ERR", 3)) continue;
707 nb_unlink(fname);
711 fclose(f);
713 slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
714 rmdir(fname);
715 rmdir("CLIENTS");
717 printf("+");
719 if (!torture_close_connection(&cli)) {
720 correct = False;
723 return correct;
727 /* run a test that simulates an approximate netbench w9X client load */
728 static BOOL run_nbw95(int dummy)
730 double t;
731 BOOL correct = True;
732 t = create_procs(run_netbench, &correct);
733 /* to produce a netbench result we scale accoding to the
734 netbench measured throughput for the run that produced the
735 sniff that was used to produce client.txt. That run used 2
736 clients and ran for 660 seconds to produce a result of
737 4MBit/sec. */
738 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
739 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
740 return correct;
743 /* run a test that simulates an approximate netbench wNT client load */
744 static BOOL run_nbwnt(int dummy)
746 double t;
747 BOOL correct = True;
748 t = create_procs(run_netbench, &correct);
749 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
750 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
751 return correct;
757 This test checks for two things:
759 1) correct support for retaining locks over a close (ie. the server
760 must not use posix semantics)
761 2) support for lock timeouts
763 static BOOL run_locktest1(int dummy)
765 static struct cli_state cli1, cli2;
766 char *fname = "\\lockt1.lck";
767 int fnum1, fnum2, fnum3;
768 time_t t1, t2;
770 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
771 return False;
773 cli_sockopt(&cli1, sockops);
774 cli_sockopt(&cli2, sockops);
776 printf("starting locktest1\n");
778 cli_unlink(&cli1, fname);
780 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
781 if (fnum1 == -1) {
782 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
783 return False;
785 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
786 if (fnum2 == -1) {
787 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
788 return False;
790 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
791 if (fnum3 == -1) {
792 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
793 return False;
796 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
797 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
798 return False;
802 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
803 printf("lock2 succeeded! This is a locking bug\n");
804 return False;
805 } else {
806 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
807 NT_STATUS_LOCK_NOT_GRANTED)) return False;
811 printf("Testing lock timeouts\n");
812 t1 = time(NULL);
813 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
814 printf("lock3 succeeded! This is a locking bug\n");
815 return False;
816 } else {
817 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
818 NT_STATUS_LOCK_NOT_GRANTED)) return False;
820 t2 = time(NULL);
822 if (t2 - t1 < 5) {
823 printf("error: This server appears not to support timed lock requests\n");
826 if (!cli_close(&cli1, fnum2)) {
827 printf("close1 failed (%s)\n", cli_errstr(&cli1));
828 return False;
831 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
832 printf("lock4 succeeded! This is a locking bug\n");
833 return False;
834 } else {
835 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
836 NT_STATUS_LOCK_NOT_GRANTED)) return False;
839 if (!cli_close(&cli1, fnum1)) {
840 printf("close2 failed (%s)\n", cli_errstr(&cli1));
841 return False;
844 if (!cli_close(&cli2, fnum3)) {
845 printf("close3 failed (%s)\n", cli_errstr(&cli2));
846 return False;
849 if (!cli_unlink(&cli1, fname)) {
850 printf("unlink failed (%s)\n", cli_errstr(&cli1));
851 return False;
855 if (!torture_close_connection(&cli1)) {
856 return False;
859 if (!torture_close_connection(&cli2)) {
860 return False;
863 printf("Passed locktest1\n");
864 return True;
868 checks for correct tconX support
870 static BOOL run_tcon_test(int dummy)
872 static struct cli_state cli1;
873 char *fname = "\\tcontest.tmp";
874 int fnum1;
875 uint16 cnum;
876 char buf[4];
878 if (!torture_open_connection(&cli1)) {
879 return False;
881 cli_sockopt(&cli1, sockops);
883 printf("starting tcontest\n");
885 cli_unlink(&cli1, fname);
887 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
888 if (fnum1 == -1)
890 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
891 return False;
894 cnum = cli1.cnum;
896 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
898 printf("write failed (%s)", cli_errstr(&cli1));
899 return False;
902 if (!cli_send_tconX(&cli1, share, "?????",
903 password, strlen(password)+1)) {
904 printf("%s refused 2nd tree connect (%s)\n", host,
905 cli_errstr(&cli1));
906 cli_shutdown(&cli1);
907 return False;
910 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
912 printf("write succeeded (%s)", cli_errstr(&cli1));
913 return False;
916 if (cli_close(&cli1, fnum1)) {
917 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
918 return False;
921 if (!cli_tdis(&cli1)) {
922 printf("tdis failed (%s)\n", cli_errstr(&cli1));
923 return False;
926 cli1.cnum = cnum;
928 if (!cli_close(&cli1, fnum1)) {
929 printf("close2 failed (%s)\n", cli_errstr(&cli1));
930 return False;
933 if (!torture_close_connection(&cli1)) {
934 return False;
937 printf("Passed tcontest\n");
938 return True;
943 This test checks that
945 1) the server supports multiple locking contexts on the one SMB
946 connection, distinguished by PID.
948 2) the server correctly fails overlapping locks made by the same PID (this
949 goes against POSIX behaviour, which is why it is tricky to implement)
951 3) the server denies unlock requests by an incorrect client PID
953 static BOOL run_locktest2(int dummy)
955 static struct cli_state cli;
956 char *fname = "\\lockt2.lck";
957 int fnum1, fnum2, fnum3;
958 BOOL correct = True;
960 if (!torture_open_connection(&cli)) {
961 return False;
964 cli_sockopt(&cli, sockops);
966 printf("starting locktest2\n");
968 cli_unlink(&cli, fname);
970 cli_setpid(&cli, 1);
972 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
973 if (fnum1 == -1) {
974 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
975 return False;
978 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
979 if (fnum2 == -1) {
980 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
981 return False;
984 cli_setpid(&cli, 2);
986 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
987 if (fnum3 == -1) {
988 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
989 return False;
992 cli_setpid(&cli, 1);
994 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
995 printf("lock1 failed (%s)\n", cli_errstr(&cli));
996 return False;
999 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1000 printf("WRITE lock1 succeeded! This is a locking bug\n");
1001 correct = False;
1002 } else {
1003 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1004 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1007 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1008 printf("WRITE lock2 succeeded! This is a locking bug\n");
1009 correct = False;
1010 } else {
1011 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1012 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1015 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1016 printf("READ lock2 succeeded! This is a locking bug\n");
1017 correct = False;
1018 } else {
1019 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1020 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1023 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1024 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1026 cli_setpid(&cli, 2);
1027 if (cli_unlock(&cli, fnum1, 100, 4)) {
1028 printf("unlock at 100 succeeded! This is a locking bug\n");
1029 correct = False;
1032 if (cli_unlock(&cli, fnum1, 0, 4)) {
1033 printf("unlock1 succeeded! This is a locking bug\n");
1034 correct = False;
1035 } else {
1036 if (!check_error(__LINE__, &cli,
1037 ERRDOS, ERRlock,
1038 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1041 if (cli_unlock(&cli, fnum1, 0, 8)) {
1042 printf("unlock2 succeeded! This is a locking bug\n");
1043 correct = False;
1044 } else {
1045 if (!check_error(__LINE__, &cli,
1046 ERRDOS, ERRlock,
1047 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1050 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1051 printf("lock3 succeeded! This is a locking bug\n");
1052 correct = False;
1053 } else {
1054 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1057 cli_setpid(&cli, 1);
1059 if (!cli_close(&cli, fnum1)) {
1060 printf("close1 failed (%s)\n", cli_errstr(&cli));
1061 return False;
1064 if (!cli_close(&cli, fnum2)) {
1065 printf("close2 failed (%s)\n", cli_errstr(&cli));
1066 return False;
1069 if (!cli_close(&cli, fnum3)) {
1070 printf("close3 failed (%s)\n", cli_errstr(&cli));
1071 return False;
1074 if (!torture_close_connection(&cli)) {
1075 correct = False;
1078 printf("locktest2 finished\n");
1080 return correct;
1085 This test checks that
1087 1) the server supports the full offset range in lock requests
1089 static BOOL run_locktest3(int dummy)
1091 static struct cli_state cli1, cli2;
1092 char *fname = "\\lockt3.lck";
1093 int fnum1, fnum2, i;
1094 uint32 offset;
1095 BOOL correct = True;
1097 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1099 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1100 return False;
1102 cli_sockopt(&cli1, sockops);
1103 cli_sockopt(&cli2, sockops);
1105 printf("starting locktest3\n");
1107 cli_unlink(&cli1, fname);
1109 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1110 if (fnum1 == -1) {
1111 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1112 return False;
1114 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1115 if (fnum2 == -1) {
1116 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1117 return False;
1120 for (offset=i=0;i<numops;i++) {
1121 NEXT_OFFSET;
1122 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1123 printf("lock1 %d failed (%s)\n",
1125 cli_errstr(&cli1));
1126 return False;
1129 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1130 printf("lock2 %d failed (%s)\n",
1132 cli_errstr(&cli1));
1133 return False;
1137 for (offset=i=0;i<numops;i++) {
1138 NEXT_OFFSET;
1140 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1141 printf("error: lock1 %d succeeded!\n", i);
1142 return False;
1145 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1146 printf("error: lock2 %d succeeded!\n", i);
1147 return False;
1150 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1151 printf("error: lock3 %d succeeded!\n", i);
1152 return False;
1155 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1156 printf("error: lock4 %d succeeded!\n", i);
1157 return False;
1161 for (offset=i=0;i<numops;i++) {
1162 NEXT_OFFSET;
1164 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1165 printf("unlock1 %d failed (%s)\n",
1167 cli_errstr(&cli1));
1168 return False;
1171 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1172 printf("unlock2 %d failed (%s)\n",
1174 cli_errstr(&cli1));
1175 return False;
1179 if (!cli_close(&cli1, fnum1)) {
1180 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1181 return False;
1184 if (!cli_close(&cli2, fnum2)) {
1185 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1186 return False;
1189 if (!cli_unlink(&cli1, fname)) {
1190 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1191 return False;
1194 if (!torture_close_connection(&cli1)) {
1195 correct = False;
1198 if (!torture_close_connection(&cli2)) {
1199 correct = False;
1202 printf("finished locktest3\n");
1204 return correct;
1207 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1208 printf("** "); correct = False; \
1212 looks at overlapping locks
1214 static BOOL run_locktest4(int dummy)
1216 static struct cli_state cli1, cli2;
1217 char *fname = "\\lockt4.lck";
1218 int fnum1, fnum2, f;
1219 BOOL ret;
1220 char buf[1000];
1221 BOOL correct = True;
1223 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1224 return False;
1227 cli_sockopt(&cli1, sockops);
1228 cli_sockopt(&cli2, sockops);
1230 printf("starting locktest4\n");
1232 cli_unlink(&cli1, fname);
1234 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1235 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1237 memset(buf, 0, sizeof(buf));
1239 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1240 printf("Failed to create file\n");
1241 correct = False;
1242 goto fail;
1245 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1246 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1247 EXPECTED(ret, False);
1248 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1250 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1251 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1252 EXPECTED(ret, True);
1253 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1255 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1256 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1257 EXPECTED(ret, False);
1258 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1260 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1261 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1262 EXPECTED(ret, True);
1263 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1265 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1266 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1267 EXPECTED(ret, False);
1268 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1270 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1271 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1272 EXPECTED(ret, True);
1273 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1275 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1276 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1277 EXPECTED(ret, True);
1278 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1280 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1281 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1282 EXPECTED(ret, False);
1283 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1285 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1286 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1287 EXPECTED(ret, False);
1288 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1290 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1291 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1292 EXPECTED(ret, True);
1293 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1295 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1296 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1297 EXPECTED(ret, False);
1298 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1300 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1301 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1302 cli_unlock(&cli1, fnum1, 110, 6);
1303 EXPECTED(ret, False);
1304 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1307 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1308 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1309 EXPECTED(ret, False);
1310 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1312 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1313 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1314 EXPECTED(ret, False);
1315 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1318 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1319 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1320 cli_unlock(&cli1, fnum1, 140, 4) &&
1321 cli_unlock(&cli1, fnum1, 140, 4);
1322 EXPECTED(ret, True);
1323 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1326 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1327 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1328 cli_unlock(&cli1, fnum1, 150, 4) &&
1329 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1330 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1331 cli_unlock(&cli1, fnum1, 150, 4);
1332 EXPECTED(ret, True);
1333 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1335 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1336 cli_unlock(&cli1, fnum1, 160, 4) &&
1337 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1338 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1339 EXPECTED(ret, True);
1340 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1342 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1343 cli_unlock(&cli1, fnum1, 170, 4) &&
1344 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1345 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1346 EXPECTED(ret, True);
1347 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1349 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1350 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1351 cli_unlock(&cli1, fnum1, 190, 4) &&
1352 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1353 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1354 EXPECTED(ret, True);
1355 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1357 cli_close(&cli1, fnum1);
1358 cli_close(&cli2, fnum2);
1359 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1360 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1361 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1362 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1363 cli_close(&cli1, fnum1) &&
1364 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1365 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1366 cli_close(&cli1, f);
1367 EXPECTED(ret, True);
1368 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1370 fail:
1371 cli_close(&cli1, fnum1);
1372 cli_close(&cli2, fnum2);
1373 cli_unlink(&cli1, fname);
1374 torture_close_connection(&cli1);
1375 torture_close_connection(&cli2);
1377 printf("finished locktest4\n");
1378 return correct;
1382 looks at lock upgrade/downgrade.
1384 static BOOL run_locktest5(int dummy)
1386 static struct cli_state cli1, cli2;
1387 char *fname = "\\lockt5.lck";
1388 int fnum1, fnum2, fnum3;
1389 BOOL ret;
1390 char buf[1000];
1391 BOOL correct = True;
1393 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1394 return False;
1397 cli_sockopt(&cli1, sockops);
1398 cli_sockopt(&cli2, sockops);
1400 printf("starting locktest5\n");
1402 cli_unlink(&cli1, fname);
1404 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1405 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1406 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1408 memset(buf, 0, sizeof(buf));
1410 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1411 printf("Failed to create file\n");
1412 correct = False;
1413 goto fail;
1416 /* Check for NT bug... */
1417 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1418 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1419 cli_close(&cli1, fnum1);
1420 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1421 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1422 EXPECTED(ret, True);
1423 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1424 cli_close(&cli1, fnum1);
1425 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1426 cli_unlock(&cli1, fnum3, 0, 1);
1428 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1429 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1430 EXPECTED(ret, True);
1431 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1433 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1434 EXPECTED(ret, False);
1436 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1438 /* Unlock the process 2 lock. */
1439 cli_unlock(&cli2, fnum2, 0, 4);
1441 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1442 EXPECTED(ret, False);
1444 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1446 /* Unlock the process 1 fnum3 lock. */
1447 cli_unlock(&cli1, fnum3, 0, 4);
1449 /* Stack 2 more locks here. */
1450 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1451 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1453 EXPECTED(ret, True);
1454 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1456 /* Unlock the first process lock, then check this was the WRITE lock that was
1457 removed. */
1459 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1460 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1462 EXPECTED(ret, True);
1463 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1465 /* Unlock the process 2 lock. */
1466 cli_unlock(&cli2, fnum2, 0, 4);
1468 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1470 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1471 cli_unlock(&cli1, fnum1, 0, 4) &&
1472 cli_unlock(&cli1, fnum1, 0, 4);
1474 EXPECTED(ret, True);
1475 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1477 /* Ensure the next unlock fails. */
1478 ret = cli_unlock(&cli1, fnum1, 0, 4);
1479 EXPECTED(ret, False);
1480 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1482 /* Ensure connection 2 can get a write lock. */
1483 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1484 EXPECTED(ret, True);
1486 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1489 fail:
1490 cli_close(&cli1, fnum1);
1491 cli_close(&cli2, fnum2);
1492 cli_unlink(&cli1, fname);
1493 if (!torture_close_connection(&cli1)) {
1494 correct = False;
1496 if (!torture_close_connection(&cli2)) {
1497 correct = False;
1500 printf("finished locktest5\n");
1502 return correct;
1506 test whether fnums and tids open on one VC are available on another (a major
1507 security hole)
1509 static BOOL run_fdpasstest(int dummy)
1511 static struct cli_state cli1, cli2, cli3;
1512 char *fname = "\\fdpass.tst";
1513 int fnum1;
1514 pstring buf;
1516 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1517 return False;
1519 cli_sockopt(&cli1, sockops);
1520 cli_sockopt(&cli2, sockops);
1522 printf("starting fdpasstest\n");
1524 cli_unlink(&cli1, fname);
1526 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1527 if (fnum1 == -1) {
1528 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1529 return False;
1532 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1533 printf("write failed (%s)\n", cli_errstr(&cli1));
1534 return False;
1537 cli3 = cli2;
1538 cli3.vuid = cli1.vuid;
1539 cli3.cnum = cli1.cnum;
1540 cli3.pid = cli1.pid;
1542 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1543 printf("read succeeded! nasty security hole [%s]\n",
1544 buf);
1545 return False;
1548 cli_close(&cli1, fnum1);
1549 cli_unlink(&cli1, fname);
1551 torture_close_connection(&cli1);
1552 torture_close_connection(&cli2);
1554 printf("finished fdpasstest\n");
1555 return True;
1560 This test checks that
1562 1) the server does not allow an unlink on a file that is open
1564 static BOOL run_unlinktest(int dummy)
1566 static struct cli_state cli;
1567 char *fname = "\\unlink.tst";
1568 int fnum;
1569 BOOL correct = True;
1571 if (!torture_open_connection(&cli)) {
1572 return False;
1575 cli_sockopt(&cli, sockops);
1577 printf("starting unlink test\n");
1579 cli_unlink(&cli, fname);
1581 cli_setpid(&cli, 1);
1583 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1584 if (fnum == -1) {
1585 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1586 return False;
1589 if (cli_unlink(&cli, fname)) {
1590 printf("error: server allowed unlink on an open file\n");
1591 correct = False;
1592 } else {
1593 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare,
1594 NT_STATUS_SHARING_VIOLATION);
1597 cli_close(&cli, fnum);
1598 cli_unlink(&cli, fname);
1600 if (!torture_close_connection(&cli)) {
1601 correct = False;
1604 printf("unlink test finished\n");
1606 return correct;
1611 test how many open files this server supports on the one socket
1613 static BOOL run_maxfidtest(int dummy)
1615 static struct cli_state cli;
1616 char *template = "\\maxfid.%d.%d";
1617 fstring fname;
1618 int fnums[0x11000], i;
1619 int retries=4;
1620 BOOL correct = True;
1622 cli = current_cli;
1624 if (retries <= 0) {
1625 printf("failed to connect\n");
1626 return False;
1629 cli_sockopt(&cli, sockops);
1631 for (i=0; i<0x11000; i++) {
1632 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1633 if ((fnums[i] = cli_open(&cli, fname,
1634 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1635 -1) {
1636 printf("open of %s failed (%s)\n",
1637 fname, cli_errstr(&cli));
1638 printf("maximum fnum is %d\n", i);
1639 break;
1641 printf("%6d\r", i);
1643 printf("%6d\n", i);
1645 printf("cleaning up\n");
1646 for (;i>=0;i--) {
1647 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1648 cli_close(&cli, fnums[i]);
1649 if (!cli_unlink(&cli, fname)) {
1650 printf("unlink of %s failed (%s)\n",
1651 fname, cli_errstr(&cli));
1652 correct = False;
1654 printf("%6d\r", i);
1656 printf("%6d\n", 0);
1658 printf("maxfid test finished\n");
1659 if (!torture_close_connection(&cli)) {
1660 correct = False;
1662 return correct;
1665 /* generate a random buffer */
1666 static void rand_buf(char *buf, int len)
1668 while (len--) {
1669 *buf = (char)sys_random();
1670 buf++;
1674 /* send smb negprot commands, not reading the response */
1675 static BOOL run_negprot_nowait(int dummy)
1677 int i;
1678 static struct cli_state cli;
1679 BOOL correct = True;
1681 printf("starting negprot nowait test\n");
1683 if (!open_nbt_connection(&cli)) {
1684 return False;
1687 for (i=0;i<50000;i++) {
1688 cli_negprot_send(&cli);
1691 if (!torture_close_connection(&cli)) {
1692 correct = False;
1695 printf("finished negprot nowait test\n");
1697 return correct;
1701 /* send random IPC commands */
1702 static BOOL run_randomipc(int dummy)
1704 char *rparam = NULL;
1705 char *rdata = NULL;
1706 int rdrcnt,rprcnt;
1707 pstring param;
1708 int api, param_len, i;
1709 static struct cli_state cli;
1710 BOOL correct = True;
1711 int count = 50000;
1713 printf("starting random ipc test\n");
1715 if (!torture_open_connection(&cli)) {
1716 return False;
1719 for (i=0;i<count;i++) {
1720 api = sys_random() % 500;
1721 param_len = (sys_random() % 64);
1723 rand_buf(param, param_len);
1725 SSVAL(param,0,api);
1727 cli_api(&cli,
1728 param, param_len, 8,
1729 NULL, 0, BUFFER_SIZE,
1730 &rparam, &rprcnt,
1731 &rdata, &rdrcnt);
1732 if (i % 100 == 0) {
1733 printf("%d/%d\r", i,count);
1736 printf("%d/%d\n", i, count);
1738 if (!torture_close_connection(&cli)) {
1739 correct = False;
1742 printf("finished random ipc test\n");
1744 return correct;
1749 static void browse_callback(const char *sname, uint32 stype,
1750 const char *comment, void *state)
1752 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1758 This test checks the browse list code
1761 static BOOL run_browsetest(int dummy)
1763 static struct cli_state cli;
1764 BOOL correct = True;
1766 printf("starting browse test\n");
1768 if (!torture_open_connection(&cli)) {
1769 return False;
1772 printf("domain list:\n");
1773 cli_NetServerEnum(&cli, cli.server_domain,
1774 SV_TYPE_DOMAIN_ENUM,
1775 browse_callback, NULL);
1777 printf("machine list:\n");
1778 cli_NetServerEnum(&cli, cli.server_domain,
1779 SV_TYPE_ALL,
1780 browse_callback, NULL);
1782 if (!torture_close_connection(&cli)) {
1783 correct = False;
1786 printf("browse test finished\n");
1788 return correct;
1794 This checks how the getatr calls works
1796 static BOOL run_attrtest(int dummy)
1798 static struct cli_state cli;
1799 int fnum;
1800 time_t t, t2;
1801 char *fname = "\\attrib.tst";
1802 BOOL correct = True;
1804 printf("starting attrib test\n");
1806 if (!torture_open_connection(&cli)) {
1807 return False;
1810 cli_unlink(&cli, fname);
1811 fnum = cli_open(&cli, fname,
1812 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1813 cli_close(&cli, fnum);
1814 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1815 printf("getatr failed (%s)\n", cli_errstr(&cli));
1816 correct = False;
1819 if (abs(t - time(NULL)) > 2) {
1820 printf("ERROR: SMBgetatr bug. time is %s",
1821 ctime(&t));
1822 t = time(NULL);
1823 correct = True;
1826 t2 = t-60*60*24; /* 1 day ago */
1828 if (!cli_setatr(&cli, fname, 0, t2)) {
1829 printf("setatr failed (%s)\n", cli_errstr(&cli));
1830 correct = True;
1833 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1834 printf("getatr failed (%s)\n", cli_errstr(&cli));
1835 correct = True;
1838 if (t != t2) {
1839 printf("ERROR: getatr/setatr bug. times are\n%s",
1840 ctime(&t));
1841 printf("%s", ctime(&t2));
1842 correct = True;
1845 cli_unlink(&cli, fname);
1847 if (!torture_close_connection(&cli)) {
1848 correct = False;
1851 printf("attrib test finished\n");
1853 return correct;
1858 This checks a couple of trans2 calls
1860 static BOOL run_trans2test(int dummy)
1862 static struct cli_state cli;
1863 int fnum;
1864 size_t size;
1865 time_t c_time, a_time, m_time, w_time, m_time2;
1866 char *fname = "\\trans2.tst";
1867 char *dname = "\\trans2";
1868 char *fname2 = "\\trans2\\trans2.tst";
1869 BOOL correct = True;
1871 printf("starting trans2 test\n");
1873 if (!torture_open_connection(&cli)) {
1874 return False;
1877 cli_unlink(&cli, fname);
1878 fnum = cli_open(&cli, fname,
1879 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1880 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1881 NULL, NULL)) {
1882 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1883 correct = False;
1885 cli_close(&cli, fnum);
1887 sleep(2);
1889 cli_unlink(&cli, fname);
1890 fnum = cli_open(&cli, fname,
1891 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1892 if (fnum == -1) {
1893 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1894 return False;
1896 cli_close(&cli, fnum);
1898 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1899 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1900 correct = False;
1901 } else {
1902 if (c_time != m_time) {
1903 printf("create time=%s", ctime(&c_time));
1904 printf("modify time=%s", ctime(&m_time));
1905 printf("This system appears to have sticky create times\n");
1906 correct = False;
1908 if (a_time % (60*60) == 0) {
1909 printf("access time=%s", ctime(&a_time));
1910 printf("This system appears to set a midnight access time\n");
1911 correct = False;
1914 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1915 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1916 correct = False;
1921 cli_unlink(&cli, fname);
1922 fnum = cli_open(&cli, fname,
1923 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1924 cli_close(&cli, fnum);
1925 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
1926 &w_time, &size, NULL, NULL)) {
1927 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1928 correct = False;
1929 } else {
1930 if (w_time < 60*60*24*2) {
1931 printf("write time=%s", ctime(&w_time));
1932 printf("This system appears to set a initial 0 write time\n");
1933 correct = False;
1937 cli_unlink(&cli, fname);
1940 /* check if the server updates the directory modification time
1941 when creating a new file */
1942 if (!cli_mkdir(&cli, dname)) {
1943 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
1944 correct = False;
1946 sleep(3);
1947 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
1948 &w_time, &size, NULL, NULL)) {
1949 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1950 correct = False;
1953 fnum = cli_open(&cli, fname2,
1954 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1955 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
1956 cli_close(&cli, fnum);
1957 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
1958 &w_time, &size, NULL, NULL)) {
1959 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1960 correct = False;
1961 } else {
1962 if (m_time2 == m_time) {
1963 printf("This system does not update directory modification times\n");
1964 correct = False;
1967 cli_unlink(&cli, fname2);
1968 cli_rmdir(&cli, dname);
1970 if (!torture_close_connection(&cli)) {
1971 correct = False;
1974 printf("trans2 test finished\n");
1976 return correct;
1980 This checks new W2K calls.
1983 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
1985 char buf[4096];
1986 BOOL correct = True;
1988 memset(buf, 0xff, sizeof(buf));
1990 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
1991 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
1992 correct = False;
1993 } else {
1994 printf("qfileinfo: level %d\n", level);
1995 dump_data(0, buf, 256);
1996 printf("\n");
1998 return correct;
2001 static BOOL run_w2ktest(int dummy)
2003 static struct cli_state cli;
2004 int fnum;
2005 char *fname = "\\w2ktest\\w2k.tst";
2006 int level;
2007 BOOL correct = True;
2009 printf("starting w2k test\n");
2011 if (!torture_open_connection(&cli)) {
2012 return False;
2015 fnum = cli_open(&cli, fname,
2016 O_RDWR | O_CREAT , DENY_NONE);
2018 for (level = 1004; level < 1040; level++) {
2019 new_trans(&cli, fnum, level);
2022 cli_close(&cli, fnum);
2024 if (!torture_close_connection(&cli)) {
2025 correct = False;
2028 printf("w2k test finished\n");
2030 return correct;
2035 this is a harness for some oplock tests
2037 static BOOL run_oplock1(int dummy)
2039 static struct cli_state cli1;
2040 char *fname = "\\lockt1.lck";
2041 int fnum1;
2042 BOOL correct = True;
2044 printf("starting oplock test 1\n");
2046 if (!torture_open_connection(&cli1)) {
2047 return False;
2050 cli_unlink(&cli1, fname);
2052 cli_sockopt(&cli1, sockops);
2054 cli1.use_oplocks = True;
2056 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2057 if (fnum1 == -1) {
2058 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2059 return False;
2062 cli1.use_oplocks = False;
2064 cli_unlink(&cli1, fname);
2065 cli_unlink(&cli1, fname);
2067 if (!cli_close(&cli1, fnum1)) {
2068 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2069 return False;
2072 if (!cli_unlink(&cli1, fname)) {
2073 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2074 return False;
2077 if (!torture_close_connection(&cli1)) {
2078 correct = False;
2081 printf("finished oplock test 1\n");
2083 return correct;
2086 static BOOL run_oplock2(int dummy)
2088 static struct cli_state cli1, cli2;
2089 char *fname = "\\lockt2.lck";
2090 int fnum1, fnum2;
2091 int saved_use_oplocks = use_oplocks;
2092 char buf[4];
2093 BOOL correct = True;
2094 volatile BOOL *shared_correct;
2096 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2097 *shared_correct = True;
2099 use_level_II_oplocks = True;
2100 use_oplocks = True;
2102 printf("starting oplock test 2\n");
2104 if (!torture_open_connection(&cli1)) {
2105 use_level_II_oplocks = False;
2106 use_oplocks = saved_use_oplocks;
2107 return False;
2110 cli1.use_oplocks = True;
2111 cli1.use_level_II_oplocks = True;
2113 if (!torture_open_connection(&cli2)) {
2114 use_level_II_oplocks = False;
2115 use_oplocks = saved_use_oplocks;
2116 return False;
2119 cli2.use_oplocks = True;
2120 cli2.use_level_II_oplocks = True;
2122 cli_unlink(&cli1, fname);
2124 cli_sockopt(&cli1, sockops);
2125 cli_sockopt(&cli2, sockops);
2127 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2128 if (fnum1 == -1) {
2129 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2130 return False;
2133 /* Don't need the globals any more. */
2134 use_level_II_oplocks = False;
2135 use_oplocks = saved_use_oplocks;
2137 if (fork() == 0) {
2138 /* Child code */
2139 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2140 if (fnum2 == -1) {
2141 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2142 *shared_correct = False;
2143 exit(0);
2146 sleep(2);
2148 if (!cli_close(&cli2, fnum2)) {
2149 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2150 *shared_correct = False;
2153 exit(0);
2156 sleep(2);
2158 /* Ensure cli1 processes the break. */
2160 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2161 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2162 correct = False;
2165 /* Should now be at level II. */
2166 /* Test if sending a write locks causes a break to none. */
2168 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2169 printf("lock failed (%s)\n", cli_errstr(&cli1));
2170 correct = False;
2173 cli_unlock(&cli1, fnum1, 0, 4);
2175 sleep(2);
2177 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2178 printf("lock failed (%s)\n", cli_errstr(&cli1));
2179 correct = False;
2182 cli_unlock(&cli1, fnum1, 0, 4);
2184 sleep(2);
2186 cli_read(&cli1, fnum1, buf, 0, 4);
2188 #if 0
2189 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2190 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2191 correct = False;
2193 #endif
2195 if (!cli_close(&cli1, fnum1)) {
2196 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2197 correct = False;
2200 sleep(4);
2202 if (!cli_unlink(&cli1, fname)) {
2203 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2204 correct = False;
2207 if (!torture_close_connection(&cli1)) {
2208 correct = False;
2211 if (!*shared_correct) {
2212 correct = False;
2215 printf("finished oplock test 2\n");
2217 return correct;
2220 /* handler for oplock 3 tests */
2221 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2223 printf("got oplock break fnum=%d level=%d\n",
2224 fnum, level);
2225 return cli_oplock_ack(cli, fnum, level);
2228 static BOOL run_oplock3(int dummy)
2230 static struct cli_state cli;
2231 char *fname = "\\oplockt3.dat";
2232 int fnum;
2233 char buf[4] = "abcd";
2234 BOOL correct = True;
2235 volatile BOOL *shared_correct;
2237 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2238 *shared_correct = True;
2240 printf("starting oplock test 3\n");
2242 if (fork() == 0) {
2243 /* Child code */
2244 use_oplocks = True;
2245 use_level_II_oplocks = True;
2246 if (!torture_open_connection(&cli)) {
2247 *shared_correct = False;
2248 exit(0);
2250 sleep(2);
2251 /* try to trigger a oplock break in parent */
2252 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2253 cli_write(&cli, fnum, 0, buf, 0, 4);
2254 exit(0);
2257 /* parent code */
2258 use_oplocks = True;
2259 use_level_II_oplocks = True;
2260 if (!torture_open_connection(&cli)) {
2261 return False;
2263 cli_oplock_handler(&cli, oplock3_handler);
2264 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2265 cli_write(&cli, fnum, 0, buf, 0, 4);
2266 cli_close(&cli, fnum);
2267 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2268 cli.timeout = 20000;
2269 cli_receive_smb(&cli);
2270 printf("finished oplock test 3\n");
2272 return (correct && *shared_correct);
2274 /* What are we looking for here? What's sucess and what's FAILURE? */
2280 Test delete on close semantics.
2282 static BOOL run_deletetest(int dummy)
2284 static struct cli_state cli1;
2285 static struct cli_state cli2;
2286 char *fname = "\\delete.file";
2287 int fnum1, fnum2;
2288 BOOL correct = True;
2290 printf("starting delete test\n");
2292 if (!torture_open_connection(&cli1)) {
2293 return False;
2296 cli_sockopt(&cli1, sockops);
2298 /* Test 1 - this should *NOT* delete the file on close. */
2300 cli_setatr(&cli1, fname, 0, 0);
2301 cli_unlink(&cli1, fname);
2303 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2304 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2305 DELETE_ON_CLOSE_FLAG);
2307 if (fnum1 == -1) {
2308 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2309 return False;
2312 if (!cli_close(&cli1, fnum1)) {
2313 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2314 return False;
2317 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2318 if (fnum1 == -1) {
2319 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2320 return False;
2323 if (!cli_close(&cli1, fnum1)) {
2324 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2325 return False;
2328 printf("first delete on close test succeeded.\n");
2330 /* Test 2 - this should delete the file on close. */
2332 cli_setatr(&cli1, fname, 0, 0);
2333 cli_unlink(&cli1, fname);
2335 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2336 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2337 FILE_OVERWRITE_IF, 0);
2339 if (fnum1 == -1) {
2340 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2341 return False;
2344 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2345 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2346 return False;
2349 if (!cli_close(&cli1, fnum1)) {
2350 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2351 return False;
2354 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2355 if (fnum1 != -1) {
2356 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2357 if (!cli_close(&cli1, fnum1)) {
2358 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2359 correct = False;
2361 cli_unlink(&cli1, fname);
2362 } else
2363 printf("second delete on close test succeeded.\n");
2365 /* Test 3 - ... */
2366 cli_setatr(&cli1, fname, 0, 0);
2367 cli_unlink(&cli1, fname);
2369 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2370 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2372 if (fnum1 == -1) {
2373 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2374 return False;
2377 /* This should fail with a sharing violation - open for delete is only compatible
2378 with SHARE_DELETE. */
2380 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2381 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2383 if (fnum2 != -1) {
2384 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2385 return False;
2388 /* This should succeed. */
2390 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2391 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2393 if (fnum2 == -1) {
2394 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2395 return False;
2398 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2399 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2400 return False;
2403 if (!cli_close(&cli1, fnum1)) {
2404 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2405 return False;
2408 if (!cli_close(&cli1, fnum2)) {
2409 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2410 return False;
2413 /* This should fail - file should no longer be there. */
2415 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2416 if (fnum1 != -1) {
2417 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2418 if (!cli_close(&cli1, fnum1)) {
2419 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2421 cli_unlink(&cli1, fname);
2422 correct = False;
2423 } else
2424 printf("third delete on close test succeeded.\n");
2426 /* Test 4 ... */
2427 cli_setatr(&cli1, fname, 0, 0);
2428 cli_unlink(&cli1, fname);
2430 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2431 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2433 if (fnum1 == -1) {
2434 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2435 return False;
2438 /* This should succeed. */
2439 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2440 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2441 if (fnum2 == -1) {
2442 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2443 return False;
2446 if (!cli_close(&cli1, fnum2)) {
2447 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2448 return False;
2451 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2452 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2453 return False;
2456 /* This should fail - no more opens once delete on close set. */
2457 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2458 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2459 if (fnum2 != -1) {
2460 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2461 return False;
2462 } else
2463 printf("fourth delete on close test succeeded.\n");
2465 if (!cli_close(&cli1, fnum1)) {
2466 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2467 return False;
2470 /* Test 5 ... */
2471 cli_setatr(&cli1, fname, 0, 0);
2472 cli_unlink(&cli1, fname);
2474 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2475 if (fnum1 == -1) {
2476 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2477 return False;
2480 /* This should fail - only allowed on NT opens with DELETE access. */
2482 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2483 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2484 return False;
2487 if (!cli_close(&cli1, fnum1)) {
2488 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2489 return False;
2492 printf("fifth delete on close test succeeded.\n");
2494 /* Test 6 ... */
2495 cli_setatr(&cli1, fname, 0, 0);
2496 cli_unlink(&cli1, fname);
2498 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2499 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2500 FILE_OVERWRITE_IF, 0);
2502 if (fnum1 == -1) {
2503 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2504 return False;
2507 /* This should fail - only allowed on NT opens with DELETE access. */
2509 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2510 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2511 return False;
2514 if (!cli_close(&cli1, fnum1)) {
2515 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2516 return False;
2519 printf("sixth delete on close test succeeded.\n");
2521 /* Test 7 ... */
2522 cli_setatr(&cli1, fname, 0, 0);
2523 cli_unlink(&cli1, fname);
2525 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2526 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2528 if (fnum1 == -1) {
2529 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2530 return False;
2533 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2534 printf("[7] setting delete_on_close on file failed !\n");
2535 return False;
2538 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2539 printf("[7] unsetting delete_on_close on file failed !\n");
2540 return False;
2543 if (!cli_close(&cli1, fnum1)) {
2544 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2545 return False;
2548 /* This next open should succeed - we reset the flag. */
2550 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2551 if (fnum1 == -1) {
2552 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2553 return False;
2556 if (!cli_close(&cli1, fnum1)) {
2557 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2558 return False;
2561 printf("seventh delete on close test succeeded.\n");
2563 /* Test 7 ... */
2564 cli_setatr(&cli1, fname, 0, 0);
2565 cli_unlink(&cli1, fname);
2567 if (!torture_open_connection(&cli2)) {
2568 printf("[8] failed to open second connection.\n");
2569 return False;
2572 cli_sockopt(&cli1, sockops);
2574 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2575 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2577 if (fnum1 == -1) {
2578 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2579 return False;
2582 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2583 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2585 if (fnum2 == -1) {
2586 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2587 return False;
2590 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2591 printf("[8] setting delete_on_close on file failed !\n");
2592 return False;
2595 if (!cli_close(&cli1, fnum1)) {
2596 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2597 return False;
2600 if (!cli_close(&cli2, fnum2)) {
2601 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2602 return False;
2605 /* This should fail.. */
2606 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2607 if (fnum1 != -1) {
2608 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2609 if (!cli_close(&cli1, fnum1)) {
2610 printf("[8] close failed (%s)\n", cli_errstr(&cli1));
2612 cli_unlink(&cli1, fname);
2613 correct = False;
2614 } else
2615 printf("eighth delete on close test succeeded.\n");
2617 printf("finished delete test\n");
2619 cli_setatr(&cli1, fname, 0, 0);
2620 cli_unlink(&cli1, fname);
2622 if (!torture_close_connection(&cli1)) {
2623 correct = False;
2625 if (!torture_close_connection(&cli2)) {
2626 correct = False;
2628 return correct;
2632 Test open mode returns on read-only files.
2634 static BOOL run_opentest(int dummy)
2636 static struct cli_state cli1;
2637 char *fname = "\\readonly.file";
2638 int fnum1, fnum2;
2639 char buf[20];
2640 size_t fsize;
2641 BOOL correct = True;
2642 char *tmp_path;
2644 printf("starting open test\n");
2646 if (!torture_open_connection(&cli1)) {
2647 return False;
2650 cli_setatr(&cli1, fname, 0, 0);
2651 cli_unlink(&cli1, fname);
2653 cli_sockopt(&cli1, sockops);
2655 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2656 if (fnum1 == -1) {
2657 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2658 return False;
2661 if (!cli_close(&cli1, fnum1)) {
2662 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2663 return False;
2666 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2667 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2668 return False;
2671 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2672 if (fnum1 == -1) {
2673 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2674 return False;
2677 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2678 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2680 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess,
2681 NT_STATUS_ACCESS_DENIED)) {
2682 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2685 printf("finished open test 1\n");
2687 cli_close(&cli1, fnum1);
2689 /* Now try not readonly and ensure ERRbadshare is returned. */
2691 cli_setatr(&cli1, fname, 0, 0);
2693 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2694 if (fnum1 == -1) {
2695 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2696 return False;
2699 /* This will fail - but the error should be ERRshare. */
2700 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2702 if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare,
2703 NT_STATUS_SHARING_VIOLATION)) {
2704 printf("correct error code ERRDOS/ERRbadshare returned\n");
2707 if (!cli_close(&cli1, fnum1)) {
2708 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2709 return False;
2712 cli_unlink(&cli1, fname);
2714 printf("finished open test 2\n");
2716 /* Test truncate open disposition on file opened for read. */
2718 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2719 if (fnum1 == -1) {
2720 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2721 return False;
2724 /* write 20 bytes. */
2726 memset(buf, '\0', 20);
2728 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
2729 printf("write failed (%s)\n", cli_errstr(&cli1));
2730 correct = False;
2733 if (!cli_close(&cli1, fnum1)) {
2734 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
2735 return False;
2738 /* Ensure size == 20. */
2739 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2740 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2741 return False;
2744 if (fsize != 20) {
2745 printf("(3) file size != 20\n");
2746 return False;
2749 /* Now test if we can truncate a file opened for readonly. */
2751 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2752 if (fnum1 == -1) {
2753 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2754 return False;
2757 if (!cli_close(&cli1, fnum1)) {
2758 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2759 return False;
2762 /* Ensure size == 0. */
2763 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2764 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2765 return False;
2768 if (fsize != 0) {
2769 printf("(3) file size != 0\n");
2770 return False;
2772 printf("finished open test 3\n");
2774 cli_unlink(&cli1, fname);
2777 printf("testing ctemp\n");
2778 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
2779 if (fnum1 == -1) {
2780 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
2781 return False;
2783 printf("ctemp gave path %s\n", tmp_path);
2784 if (!cli_close(&cli1, fnum1)) {
2785 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
2787 if (!cli_unlink(&cli1, tmp_path)) {
2788 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
2791 if (!torture_close_connection(&cli1)) {
2792 correct = False;
2795 return correct;
2798 static void list_fn(file_info *finfo, const char *name, void *state)
2804 test directory listing speed
2806 static BOOL run_dirtest(int dummy)
2808 int i;
2809 static struct cli_state cli;
2810 int fnum;
2811 double t1;
2812 BOOL correct = True;
2814 printf("starting directory test\n");
2816 if (!torture_open_connection(&cli)) {
2817 return False;
2820 cli_sockopt(&cli, sockops);
2822 srandom(0);
2823 for (i=0;i<numops;i++) {
2824 fstring fname;
2825 slprintf(fname, sizeof(fname), "%x", (int)random());
2826 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2827 if (fnum == -1) {
2828 fprintf(stderr,"Failed to open %s\n", fname);
2829 return False;
2831 cli_close(&cli, fnum);
2834 t1 = end_timer();
2836 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
2837 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
2838 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
2840 printf("dirtest core %g seconds\n", end_timer() - t1);
2842 srandom(0);
2843 for (i=0;i<numops;i++) {
2844 fstring fname;
2845 slprintf(fname, sizeof(fname), "%x", (int)random());
2846 cli_unlink(&cli, fname);
2849 if (!torture_close_connection(&cli)) {
2850 correct = False;
2853 printf("finished dirtest\n");
2855 return correct;
2860 static double create_procs(BOOL (*fn)(int), BOOL *result)
2862 int i, status;
2863 volatile pid_t *child_status;
2864 volatile BOOL *child_status_out;
2865 int synccount;
2866 int tries = 8;
2868 synccount = 0;
2870 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
2871 if (!child_status) {
2872 printf("Failed to setup shared memory\n");
2873 return -1;
2876 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
2877 if (!child_status_out) {
2878 printf("Failed to setup result status shared memory\n");
2879 return -1;
2882 memset((void *)child_status, 0, sizeof(pid_t)*nprocs);
2883 memset((void *)child_status_out, True, sizeof(BOOL)*nprocs);
2885 start_timer();
2887 for (i=0;i<nprocs;i++) {
2888 procnum = i;
2889 if (fork() == 0) {
2890 pid_t mypid = getpid();
2891 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
2893 slprintf(myname,sizeof(myname),"CLIENT%d", i);
2895 while (1) {
2896 memset(&current_cli, 0, sizeof(current_cli));
2897 if (torture_open_connection(&current_cli)) break;
2898 if (tries-- == 0) {
2899 printf("pid %d failed to start\n", (int)getpid());
2900 _exit(1);
2902 msleep(10);
2905 child_status[i] = getpid();
2907 while (child_status[i]) msleep(2);
2909 child_status_out[i] = fn(i);
2910 _exit(0);
2914 do {
2915 synccount = 0;
2916 for (i=0;i<nprocs;i++) {
2917 if (child_status[i]) synccount++;
2919 if (synccount == nprocs) break;
2920 msleep(10);
2921 } while (end_timer() < 30);
2923 if (synccount != nprocs) {
2924 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
2925 *result = False;
2926 return end_timer();
2929 /* start the client load */
2930 start_timer();
2932 for (i=0;i<nprocs;i++) {
2933 child_status[i] = 0;
2936 printf("%d clients started\n", nprocs);
2938 for (i=0;i<nprocs;i++) {
2939 waitpid(0, &status, 0);
2940 printf("*");
2943 printf("\n");
2945 for (i=0;i<nprocs;i++) {
2946 if (!child_status_out[i]) {
2947 *result = False;
2950 return end_timer();
2954 #define FLAG_MULTIPROC 1
2956 static struct {
2957 char *name;
2958 BOOL (*fn)(int);
2959 unsigned flags;
2960 } torture_ops[] = {
2961 {"FDPASS", run_fdpasstest, 0},
2962 {"LOCK1", run_locktest1, 0},
2963 {"LOCK2", run_locktest2, 0},
2964 {"LOCK3", run_locktest3, 0},
2965 {"LOCK4", run_locktest4, 0},
2966 {"LOCK5", run_locktest5, 0},
2967 {"UNLINK", run_unlinktest, 0},
2968 {"BROWSE", run_browsetest, 0},
2969 {"ATTR", run_attrtest, 0},
2970 {"TRANS2", run_trans2test, 0},
2971 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
2972 {"TORTURE",run_torture, FLAG_MULTIPROC},
2973 {"RANDOMIPC", run_randomipc, 0},
2974 {"NEGNOWAIT", run_negprot_nowait, 0},
2975 {"NBW95", run_nbw95, 0},
2976 {"NBWNT", run_nbwnt, 0},
2977 {"OPLOCK1", run_oplock1, 0},
2978 {"OPLOCK2", run_oplock2, 0},
2979 {"OPLOCK3", run_oplock3, 0},
2980 {"DIR", run_dirtest, 0},
2981 {"DENY1", torture_denytest1, 0},
2982 {"DENY2", torture_denytest2, 0},
2983 {"TCON", run_tcon_test, 0},
2984 {"RW1", run_readwritetest, 0},
2985 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
2986 {"RW3", run_readwritelarge, 0},
2987 {"OPEN", run_opentest, 0},
2988 {"DELETE", run_deletetest, 0},
2989 {"W2K", run_w2ktest, 0},
2990 {"TRANS2SCAN", torture_trans2_scan, 0},
2991 {"NTTRANSSCAN", torture_nttrans_scan, 0},
2992 {"UTABLE", torture_utable, 0},
2993 {"CASETABLE", torture_casetable, 0},
2994 {NULL, NULL, 0}};
2998 /****************************************************************************
2999 run a specified test or "ALL"
3000 ****************************************************************************/
3001 static BOOL run_test(char *name)
3003 BOOL ret = True;
3004 BOOL result = True;
3005 int i;
3006 double t;
3007 if (strequal(name,"ALL")) {
3008 for (i=0;torture_ops[i].name;i++) {
3009 run_test(torture_ops[i].name);
3013 for (i=0;torture_ops[i].name;i++) {
3014 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
3015 (unsigned)random());
3017 if (strequal(name, torture_ops[i].name)) {
3018 printf("Running %s\n", name);
3019 if (torture_ops[i].flags & FLAG_MULTIPROC) {
3020 t = create_procs(torture_ops[i].fn, &result);
3021 if (!result) {
3022 ret = False;
3023 printf("TEST %s FAILED!\n", name);
3026 } else {
3027 start_timer();
3028 if (!torture_ops[i].fn(0)) {
3029 ret = False;
3030 printf("TEST %s FAILED!\n", name);
3032 t = end_timer();
3034 printf("%s took %g secs\n\n", name, t);
3037 return ret;
3041 static void usage(void)
3043 int i;
3045 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3047 printf("\t-d debuglevel\n");
3048 printf("\t-U user%%pass\n");
3049 printf("\t-N numprocs\n");
3050 printf("\t-n my_netbios_name\n");
3051 printf("\t-W workgroup\n");
3052 printf("\t-o num_operations\n");
3053 printf("\t-O socket_options\n");
3054 printf("\t-m maximum protocol\n");
3055 printf("\t-L use oplocks\n");
3056 printf("\t-A showall\n");
3057 printf("\n\n");
3059 printf("tests are:");
3060 for (i=0;torture_ops[i].name;i++) {
3061 printf(" %s", torture_ops[i].name);
3063 printf("\n");
3065 printf("default test is ALL\n");
3067 exit(1);
3074 /****************************************************************************
3075 main program
3076 ****************************************************************************/
3077 int main(int argc,char *argv[])
3079 int opt, i;
3080 char *p;
3081 int gotpass = 0;
3082 extern char *optarg;
3083 extern int optind;
3084 static pstring servicesf = CONFIGFILE;
3085 BOOL correct = True;
3087 dbf = x_stdout;
3089 #ifdef HAVE_SETBUFFER
3090 setbuffer(stdout, NULL, 0);
3091 #endif
3093 lp_load(servicesf,True,False,False);
3094 load_interfaces();
3096 if (argc < 2) {
3097 usage();
3100 for(p = argv[1]; *p; p++)
3101 if(*p == '\\')
3102 *p = '/';
3104 if (strncmp(argv[1], "//", 2)) {
3105 usage();
3108 fstrcpy(host, &argv[1][2]);
3109 p = strchr_m(&host[2],'/');
3110 if (!p) {
3111 usage();
3113 *p = 0;
3114 fstrcpy(share, p+1);
3116 get_myname(myname);
3118 if (*username == 0 && getenv("LOGNAME")) {
3119 pstrcpy(username,getenv("LOGNAME"));
3122 argc--;
3123 argv++;
3126 fstrcpy(workgroup, lp_workgroup());
3128 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:A")) != EOF) {
3129 switch (opt) {
3130 case 'W':
3131 fstrcpy(workgroup,optarg);
3132 break;
3133 case 'm':
3134 max_protocol = interpret_protocol(optarg, max_protocol);
3135 break;
3136 case 'N':
3137 nprocs = atoi(optarg);
3138 break;
3139 case 'o':
3140 numops = atoi(optarg);
3141 break;
3142 case 'd':
3143 DEBUGLEVEL = atoi(optarg);
3144 break;
3145 case 'O':
3146 sockops = optarg;
3147 break;
3148 case 'L':
3149 use_oplocks = True;
3150 break;
3151 case 'A':
3152 torture_showall = True;
3153 break;
3154 case 'n':
3155 fstrcpy(myname, optarg);
3156 break;
3157 case 'U':
3158 pstrcpy(username,optarg);
3159 p = strchr_m(username,'%');
3160 if (p) {
3161 *p = 0;
3162 pstrcpy(password, p+1);
3163 gotpass = 1;
3165 break;
3166 default:
3167 printf("Unknown option %c (%d)\n", (char)opt, opt);
3168 usage();
3173 while (!gotpass) {
3174 p = getpass("Password:");
3175 if (p) {
3176 pstrcpy(password, p);
3177 gotpass = 1;
3181 printf("host=%s share=%s user=%s myname=%s\n",
3182 host, share, username, myname);
3184 if (argc == 1) {
3185 correct = run_test("ALL");
3186 } else {
3187 for (i=1;i<argc;i++) {
3188 if (!run_test(argv[i])) {
3189 correct = False;
3194 if (correct) {
3195 return(0);
3196 } else {
3197 return(1);