sync'ing up for 3.0alpha20 release
[Samba.git] / source / torture / torture.c
blobfb62b13657fe5d380fbef035355fa905d95338b4
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 char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 int torture_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 static char *client_txt = "client_oplocks.txt";
36 static BOOL use_kerberos;
38 BOOL torture_showall = False;
40 static double create_procs(BOOL (*fn)(int), BOOL *result);
43 static struct timeval tp1,tp2;
45 void start_timer(void)
47 gettimeofday(&tp1,NULL);
50 double end_timer(void)
52 gettimeofday(&tp2,NULL);
53 return((tp2.tv_sec - tp1.tv_sec) +
54 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
58 /* return a pointer to a anonymous shared memory segment of size "size"
59 which will persist across fork() but will disappear when all processes
60 exit
62 The memory is not zeroed
64 This function uses system5 shared memory. It takes advantage of a property
65 that the memory is not destroyed if it is attached when the id is removed
67 void *shm_setup(int size)
69 int shmid;
70 void *ret;
72 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
73 if (shmid == -1) {
74 printf("can't get shared memory\n");
75 exit(1);
77 ret = (void *)shmat(shmid, 0, 0);
78 if (!ret || ret == (void *)-1) {
79 printf("can't attach to shared memory\n");
80 return NULL;
82 /* the following releases the ipc, but note that this process
83 and all its children will still have access to the memory, its
84 just that the shmid is no longer valid for other shm calls. This
85 means we don't leave behind lots of shm segments after we exit
87 See Stevens "advanced programming in unix env" for details
89 shmctl(shmid, IPC_RMID, 0);
91 return ret;
95 static BOOL open_nbt_connection(struct cli_state *c)
97 struct nmb_name called, calling;
98 struct in_addr ip;
100 ZERO_STRUCTP(c);
102 make_nmb_name(&calling, myname, 0x0);
103 make_nmb_name(&called , host, 0x20);
105 zero_ip(&ip);
107 if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
108 printf("Failed to connect with %s\n", host);
109 return False;
112 c->use_kerberos = use_kerberos;
114 c->timeout = 120000; /* set a really long timeout (2 minutes) */
115 if (use_oplocks) c->use_oplocks = True;
116 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
118 if (!cli_session_request(c, &calling, &called)) {
119 printf("%s rejected the session\n",host);
120 cli_shutdown(c);
121 return False;
124 return True;
127 BOOL torture_open_connection(struct cli_state *c)
129 ZERO_STRUCTP(c);
131 if (!open_nbt_connection(c)) {
132 return False;
135 if (!cli_negprot(c)) {
136 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
137 cli_shutdown(c);
138 return False;
141 if (!cli_session_setup(c, username,
142 password, strlen(password),
143 password, strlen(password),
144 workgroup)) {
145 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
146 cli_shutdown(c);
147 return False;
150 if (!cli_send_tconX(c, share, "?????",
151 password, strlen(password)+1)) {
152 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
153 cli_shutdown(c);
154 return False;
157 return True;
161 BOOL torture_close_connection(struct cli_state *c)
163 BOOL ret = True;
164 if (!cli_tdis(c)) {
165 printf("tdis failed (%s)\n", cli_errstr(c));
166 ret = False;
169 cli_shutdown(c);
171 return ret;
175 /* check if the server produced the expected error code */
176 static BOOL check_error(int line, struct cli_state *c,
177 uint8 eclass, uint32 ecode, NTSTATUS nterr)
179 if (cli_is_dos_error(c)) {
180 uint8 class;
181 uint32 num;
183 /* Check DOS error */
185 cli_dos_error(c, &class, &num);
187 if (eclass != class || ecode != num) {
188 printf("unexpected error code class=%d code=%d\n",
189 (int)class, (int)num);
190 printf(" expected %d/%d %s (line=%d)\n",
191 (int)eclass, (int)ecode, nt_errstr(nterr), line);
192 return False;
195 } else {
196 NTSTATUS status;
198 /* Check NT error */
200 status = cli_nt_error(c);
202 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
203 printf("unexpected error code %s\n", nt_errstr(status));
204 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
205 return False;
209 return True;
213 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
215 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
216 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
218 return True;
222 static BOOL rw_torture(struct cli_state *c)
224 char *lockfname = "\\torture.lck";
225 fstring fname;
226 int fnum;
227 int fnum2;
228 pid_t pid2, pid = getpid();
229 int i, j;
230 char buf[1024];
231 BOOL correct = True;
233 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
234 DENY_NONE);
235 if (fnum2 == -1)
236 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
237 if (fnum2 == -1) {
238 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
239 return False;
243 for (i=0;i<torture_numops;i++) {
244 unsigned n = (unsigned)sys_random()%10;
245 if (i % 10 == 0) {
246 printf("%d\r", i); fflush(stdout);
248 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
250 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
251 return False;
254 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
255 if (fnum == -1) {
256 printf("open failed (%s)\n", cli_errstr(c));
257 correct = False;
258 break;
261 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
262 printf("write failed (%s)\n", cli_errstr(c));
263 correct = False;
266 for (j=0;j<50;j++) {
267 if (cli_write(c, fnum, 0, (char *)buf,
268 sizeof(pid)+(j*sizeof(buf)),
269 sizeof(buf)) != sizeof(buf)) {
270 printf("write failed (%s)\n", cli_errstr(c));
271 correct = False;
275 pid2 = 0;
277 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
278 printf("read failed (%s)\n", cli_errstr(c));
279 correct = False;
282 if (pid2 != pid) {
283 printf("data corruption!\n");
284 correct = False;
287 if (!cli_close(c, fnum)) {
288 printf("close failed (%s)\n", cli_errstr(c));
289 correct = False;
292 if (!cli_unlink(c, fname)) {
293 printf("unlink failed (%s)\n", cli_errstr(c));
294 correct = False;
297 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
298 printf("unlock failed (%s)\n", cli_errstr(c));
299 correct = False;
303 cli_close(c, fnum2);
304 cli_unlink(c, lockfname);
306 printf("%d\n", i);
308 return correct;
311 static BOOL run_torture(int dummy)
313 struct cli_state cli;
314 BOOL ret;
316 cli = current_cli;
318 cli_sockopt(&cli, sockops);
320 ret = rw_torture(&cli);
322 if (!torture_close_connection(&cli)) {
323 ret = False;
326 return ret;
329 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
331 int fnum = -1;
332 int i = 0;
333 char buf[131072];
334 char buf_rd[131072];
335 unsigned count;
336 unsigned countprev = 0;
337 ssize_t sent = 0;
338 BOOL correct = True;
340 srandom(1);
341 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
343 SIVAL(buf, i, sys_random());
346 if (procnum == 0)
348 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
349 DENY_NONE);
350 if (fnum == -1) {
351 printf("first open read/write of %s failed (%s)\n",
352 lockfname, cli_errstr(c));
353 return False;
356 else
358 for (i = 0; i < 500 && fnum == -1; i++)
360 fnum = cli_open(c, lockfname, O_RDONLY,
361 DENY_NONE);
362 msleep(10);
364 if (fnum == -1) {
365 printf("second open read-only of %s failed (%s)\n",
366 lockfname, cli_errstr(c));
367 return False;
371 i = 0;
372 for (count = 0; count < sizeof(buf); count += sent)
374 if (count >= countprev) {
375 printf("%d %8d\r", i, count);
376 fflush(stdout);
377 i++;
378 countprev += (sizeof(buf) / 20);
381 if (procnum == 0)
383 sent = ((unsigned)sys_random()%(20))+ 1;
384 if (sent > sizeof(buf) - count)
386 sent = sizeof(buf) - count;
389 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
390 printf("write failed (%s)\n", cli_errstr(c));
391 correct = False;
394 else
396 sent = cli_read(c, fnum, buf_rd+count, count,
397 sizeof(buf)-count);
398 if (sent < 0)
400 printf("read failed offset:%d size:%d (%s)\n",
401 count, sizeof(buf)-count,
402 cli_errstr(c));
403 correct = False;
404 sent = 0;
406 if (sent > 0)
408 if (memcmp(buf_rd+count, buf+count, sent) != 0)
410 printf("read/write compare failed\n");
411 printf("offset: %d req %d recvd %d\n",
412 count, sizeof(buf)-count, sent);
413 correct = False;
414 break;
421 if (!cli_close(c, fnum)) {
422 printf("close failed (%s)\n", cli_errstr(c));
423 correct = False;
426 return correct;
429 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
431 char *lockfname = "\\torture2.lck";
432 int fnum1;
433 int fnum2;
434 int i;
435 uchar buf[131072];
436 uchar buf_rd[131072];
437 BOOL correct = True;
438 ssize_t bytes_read;
440 if (!cli_unlink(c1, lockfname)) {
441 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
444 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
445 DENY_NONE);
446 if (fnum1 == -1) {
447 printf("first open read/write of %s failed (%s)\n",
448 lockfname, cli_errstr(c1));
449 return False;
451 fnum2 = cli_open(c2, lockfname, O_RDONLY,
452 DENY_NONE);
453 if (fnum2 == -1) {
454 printf("second open read-only of %s failed (%s)\n",
455 lockfname, cli_errstr(c2));
456 cli_close(c1, fnum1);
457 return False;
460 for (i=0;i<torture_numops;i++)
462 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
463 if (i % 10 == 0) {
464 printf("%d\r", i); fflush(stdout);
467 generate_random_buffer(buf, buf_size, False);
469 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
470 printf("write failed (%s)\n", cli_errstr(c1));
471 correct = False;
474 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
475 printf("read failed (%s)\n", cli_errstr(c2));
476 printf("read %d, expected %d\n", bytes_read, buf_size);
477 correct = False;
480 if (memcmp(buf_rd, buf, buf_size) != 0)
482 printf("read/write compare failed\n");
483 correct = False;
487 if (!cli_close(c2, fnum2)) {
488 printf("close failed (%s)\n", cli_errstr(c2));
489 correct = False;
491 if (!cli_close(c1, fnum1)) {
492 printf("close failed (%s)\n", cli_errstr(c1));
493 correct = False;
496 if (!cli_unlink(c1, lockfname)) {
497 printf("unlink failed (%s)\n", cli_errstr(c1));
498 correct = False;
501 return correct;
504 static BOOL run_readwritetest(int dummy)
506 static struct cli_state cli1, cli2;
507 BOOL test1, test2;
509 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
510 return False;
512 cli_sockopt(&cli1, sockops);
513 cli_sockopt(&cli2, sockops);
515 printf("starting readwritetest\n");
517 test1 = rw_torture2(&cli1, &cli2);
518 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
520 test2 = rw_torture2(&cli1, &cli1);
521 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
523 if (!torture_close_connection(&cli1)) {
524 test1 = False;
527 if (!torture_close_connection(&cli2)) {
528 test2 = False;
531 return (test1 && test2);
534 static BOOL run_readwritemulti(int dummy)
536 static struct cli_state cli;
537 BOOL test;
539 cli = current_cli;
541 cli_sockopt(&cli, sockops);
543 printf("run_readwritemulti: fname %s\n", randomfname);
544 test = rw_torture3(&cli, randomfname);
546 if (!torture_close_connection(&cli)) {
547 test = False;
550 return test;
553 static BOOL run_readwritelarge(int dummy)
555 static struct cli_state cli1;
556 int fnum1;
557 char *lockfname = "\\large.dat";
558 size_t fsize;
559 char buf[126*1024];
560 BOOL correct = True;
562 if (!torture_open_connection(&cli1)) {
563 return False;
565 cli_sockopt(&cli1, sockops);
566 memset(buf,'\0',sizeof(buf));
568 cli1.max_xmit = 128*1024;
570 printf("starting readwritelarge\n");
572 cli_unlink(&cli1, lockfname);
574 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
575 if (fnum1 == -1) {
576 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
577 return False;
580 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
582 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
583 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
584 correct = False;
587 if (fsize == sizeof(buf))
588 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
589 else {
590 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
591 correct = False;
594 if (!cli_close(&cli1, fnum1)) {
595 printf("close failed (%s)\n", cli_errstr(&cli1));
596 correct = False;
599 if (!cli_unlink(&cli1, lockfname)) {
600 printf("unlink failed (%s)\n", cli_errstr(&cli1));
601 correct = False;
604 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
605 if (fnum1 == -1) {
606 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
607 return False;
610 cli1.max_xmit = 4*1024;
612 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
614 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
615 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
616 correct = False;
619 if (fsize == sizeof(buf))
620 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
621 else {
622 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
623 correct = False;
626 #if 0
627 /* ToDo - set allocation. JRA */
628 if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
629 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
630 return False;
632 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
633 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
634 correct = False;
636 if (fsize != 0)
637 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
638 #endif
640 if (!cli_close(&cli1, fnum1)) {
641 printf("close failed (%s)\n", cli_errstr(&cli1));
642 correct = False;
645 if (!torture_close_connection(&cli1)) {
646 correct = False;
648 return correct;
651 int line_count = 0;
652 int nbio_id;
654 #define ival(s) strtol(s, NULL, 0)
656 /* run a test that simulates an approximate netbench client load */
657 static BOOL run_netbench(int client)
659 struct cli_state cli;
660 int i;
661 fstring fname;
662 pstring line;
663 char cname[20];
664 FILE *f;
665 char *params[20];
666 BOOL correct = True;
668 cli = current_cli;
670 nbio_id = client;
672 cli_sockopt(&cli, sockops);
674 nb_setup(&cli);
676 slprintf(cname,sizeof(fname), "client%d", client);
678 f = fopen(client_txt, "r");
680 if (!f) {
681 perror(client_txt);
682 return False;
685 while (fgets(line, sizeof(line)-1, f)) {
686 line_count++;
688 line[strlen(line)-1] = 0;
690 /* printf("[%d] %s\n", line_count, line); */
692 all_string_sub(line,"client1", cname, sizeof(line));
694 /* parse the command parameters */
695 params[0] = strtok(line," ");
696 i = 0;
697 while (params[i]) params[++i] = strtok(NULL," ");
699 params[i] = "";
701 if (i < 2) continue;
703 if (!strncmp(params[0],"SMB", 3)) {
704 printf("ERROR: You are using a dbench 1 load file\n");
705 exit(1);
708 if (!strcmp(params[0],"NTCreateX")) {
709 nb_createx(params[1], ival(params[2]), ival(params[3]),
710 ival(params[4]));
711 } else if (!strcmp(params[0],"Close")) {
712 nb_close(ival(params[1]));
713 } else if (!strcmp(params[0],"Rename")) {
714 nb_rename(params[1], params[2]);
715 } else if (!strcmp(params[0],"Unlink")) {
716 nb_unlink(params[1]);
717 } else if (!strcmp(params[0],"Deltree")) {
718 nb_deltree(params[1]);
719 } else if (!strcmp(params[0],"Rmdir")) {
720 nb_rmdir(params[1]);
721 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
722 nb_qpathinfo(params[1]);
723 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
724 nb_qfileinfo(ival(params[1]));
725 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
726 nb_qfsinfo(ival(params[1]));
727 } else if (!strcmp(params[0],"FIND_FIRST")) {
728 nb_findfirst(params[1]);
729 } else if (!strcmp(params[0],"WriteX")) {
730 nb_writex(ival(params[1]),
731 ival(params[2]), ival(params[3]), ival(params[4]));
732 } else if (!strcmp(params[0],"ReadX")) {
733 nb_readx(ival(params[1]),
734 ival(params[2]), ival(params[3]), ival(params[4]));
735 } else if (!strcmp(params[0],"Flush")) {
736 nb_flush(ival(params[1]));
737 } else {
738 printf("Unknown operation %s\n", params[0]);
739 exit(1);
742 fclose(f);
744 nb_cleanup();
746 if (!torture_close_connection(&cli)) {
747 correct = False;
750 return correct;
754 /* run a test that simulates an approximate netbench client load */
755 static BOOL run_nbench(int dummy)
757 double t;
758 BOOL correct = True;
760 nbio_shmem(nprocs);
762 nbio_id = -1;
764 signal(SIGALRM, nb_alarm);
765 alarm(1);
766 t = create_procs(run_netbench, &correct);
767 alarm(0);
769 printf("\nThroughput %g MB/sec\n",
770 1.0e-6 * nbio_total() / t);
771 return correct;
776 This test checks for two things:
778 1) correct support for retaining locks over a close (ie. the server
779 must not use posix semantics)
780 2) support for lock timeouts
782 static BOOL run_locktest1(int dummy)
784 static struct cli_state cli1, cli2;
785 char *fname = "\\lockt1.lck";
786 int fnum1, fnum2, fnum3;
787 time_t t1, t2;
788 unsigned lock_timeout;
790 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
791 return False;
793 cli_sockopt(&cli1, sockops);
794 cli_sockopt(&cli2, sockops);
796 printf("starting locktest1\n");
798 cli_unlink(&cli1, fname);
800 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
801 if (fnum1 == -1) {
802 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
803 return False;
805 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
806 if (fnum2 == -1) {
807 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
808 return False;
810 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
811 if (fnum3 == -1) {
812 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
813 return False;
816 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
817 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
818 return False;
822 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
823 printf("lock2 succeeded! This is a locking bug\n");
824 return False;
825 } else {
826 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
827 NT_STATUS_LOCK_NOT_GRANTED)) return False;
831 lock_timeout = (1 + (random() % 20));
832 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
833 t1 = time(NULL);
834 if (cli_lock(&cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
835 printf("lock3 succeeded! This is a locking bug\n");
836 return False;
837 } else {
838 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
839 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
841 t2 = time(NULL);
843 if (t2 - t1 < 5) {
844 printf("error: This server appears not to support timed lock requests\n");
846 printf("server slept for %u seconds for a %u second timeout\n",
847 (unsigned int)(t2-t1), lock_timeout);
849 if (!cli_close(&cli1, fnum2)) {
850 printf("close1 failed (%s)\n", cli_errstr(&cli1));
851 return False;
854 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
855 printf("lock4 succeeded! This is a locking bug\n");
856 return False;
857 } else {
858 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
859 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
862 if (!cli_close(&cli1, fnum1)) {
863 printf("close2 failed (%s)\n", cli_errstr(&cli1));
864 return False;
867 if (!cli_close(&cli2, fnum3)) {
868 printf("close3 failed (%s)\n", cli_errstr(&cli2));
869 return False;
872 if (!cli_unlink(&cli1, fname)) {
873 printf("unlink failed (%s)\n", cli_errstr(&cli1));
874 return False;
878 if (!torture_close_connection(&cli1)) {
879 return False;
882 if (!torture_close_connection(&cli2)) {
883 return False;
886 printf("Passed locktest1\n");
887 return True;
891 checks for correct tconX support
893 static BOOL run_tcon_test(int dummy)
895 static struct cli_state cli1;
896 char *fname = "\\tcontest.tmp";
897 int fnum1;
898 uint16 cnum;
899 char buf[4];
901 if (!torture_open_connection(&cli1)) {
902 return False;
904 cli_sockopt(&cli1, sockops);
906 printf("starting tcontest\n");
908 cli_unlink(&cli1, fname);
910 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
911 if (fnum1 == -1)
913 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
914 return False;
917 cnum = cli1.cnum;
919 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
921 printf("write failed (%s)", cli_errstr(&cli1));
922 return False;
925 if (!cli_send_tconX(&cli1, share, "?????",
926 password, strlen(password)+1)) {
927 printf("%s refused 2nd tree connect (%s)\n", host,
928 cli_errstr(&cli1));
929 cli_shutdown(&cli1);
930 return False;
933 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
935 printf("write succeeded (%s)", cli_errstr(&cli1));
936 return False;
939 if (cli_close(&cli1, fnum1)) {
940 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
941 return False;
944 if (!cli_tdis(&cli1)) {
945 printf("tdis failed (%s)\n", cli_errstr(&cli1));
946 return False;
949 cli1.cnum = cnum;
951 if (!cli_close(&cli1, fnum1)) {
952 printf("close2 failed (%s)\n", cli_errstr(&cli1));
953 return False;
956 if (!torture_close_connection(&cli1)) {
957 return False;
960 printf("Passed tcontest\n");
961 return True;
966 This test checks that
968 1) the server supports multiple locking contexts on the one SMB
969 connection, distinguished by PID.
971 2) the server correctly fails overlapping locks made by the same PID (this
972 goes against POSIX behaviour, which is why it is tricky to implement)
974 3) the server denies unlock requests by an incorrect client PID
976 static BOOL run_locktest2(int dummy)
978 static struct cli_state cli;
979 char *fname = "\\lockt2.lck";
980 int fnum1, fnum2, fnum3;
981 BOOL correct = True;
983 if (!torture_open_connection(&cli)) {
984 return False;
987 cli_sockopt(&cli, sockops);
989 printf("starting locktest2\n");
991 cli_unlink(&cli, fname);
993 cli_setpid(&cli, 1);
995 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
996 if (fnum1 == -1) {
997 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
998 return False;
1001 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1002 if (fnum2 == -1) {
1003 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
1004 return False;
1007 cli_setpid(&cli, 2);
1009 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1010 if (fnum3 == -1) {
1011 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
1012 return False;
1015 cli_setpid(&cli, 1);
1017 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1018 printf("lock1 failed (%s)\n", cli_errstr(&cli));
1019 return False;
1022 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1023 printf("WRITE lock1 succeeded! This is a locking bug\n");
1024 correct = False;
1025 } else {
1026 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1027 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1030 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1031 printf("WRITE lock2 succeeded! This is a locking bug\n");
1032 correct = False;
1033 } else {
1034 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1035 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1038 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1039 printf("READ lock2 succeeded! This is a locking bug\n");
1040 correct = False;
1041 } else {
1042 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1043 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1046 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1047 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1049 cli_setpid(&cli, 2);
1050 if (cli_unlock(&cli, fnum1, 100, 4)) {
1051 printf("unlock at 100 succeeded! This is a locking bug\n");
1052 correct = False;
1055 if (cli_unlock(&cli, fnum1, 0, 4)) {
1056 printf("unlock1 succeeded! This is a locking bug\n");
1057 correct = False;
1058 } else {
1059 if (!check_error(__LINE__, &cli,
1060 ERRDOS, ERRlock,
1061 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1064 if (cli_unlock(&cli, fnum1, 0, 8)) {
1065 printf("unlock2 succeeded! This is a locking bug\n");
1066 correct = False;
1067 } else {
1068 if (!check_error(__LINE__, &cli,
1069 ERRDOS, ERRlock,
1070 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1073 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1074 printf("lock3 succeeded! This is a locking bug\n");
1075 correct = False;
1076 } else {
1077 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1080 cli_setpid(&cli, 1);
1082 if (!cli_close(&cli, fnum1)) {
1083 printf("close1 failed (%s)\n", cli_errstr(&cli));
1084 return False;
1087 if (!cli_close(&cli, fnum2)) {
1088 printf("close2 failed (%s)\n", cli_errstr(&cli));
1089 return False;
1092 if (!cli_close(&cli, fnum3)) {
1093 printf("close3 failed (%s)\n", cli_errstr(&cli));
1094 return False;
1097 if (!torture_close_connection(&cli)) {
1098 correct = False;
1101 printf("locktest2 finished\n");
1103 return correct;
1108 This test checks that
1110 1) the server supports the full offset range in lock requests
1112 static BOOL run_locktest3(int dummy)
1114 static struct cli_state cli1, cli2;
1115 char *fname = "\\lockt3.lck";
1116 int fnum1, fnum2, i;
1117 uint32 offset;
1118 BOOL correct = True;
1120 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1122 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1123 return False;
1125 cli_sockopt(&cli1, sockops);
1126 cli_sockopt(&cli2, sockops);
1128 printf("starting locktest3\n");
1130 cli_unlink(&cli1, fname);
1132 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1133 if (fnum1 == -1) {
1134 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1135 return False;
1137 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1138 if (fnum2 == -1) {
1139 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1140 return False;
1143 for (offset=i=0;i<torture_numops;i++) {
1144 NEXT_OFFSET;
1145 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1146 printf("lock1 %d failed (%s)\n",
1148 cli_errstr(&cli1));
1149 return False;
1152 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1153 printf("lock2 %d failed (%s)\n",
1155 cli_errstr(&cli1));
1156 return False;
1160 for (offset=i=0;i<torture_numops;i++) {
1161 NEXT_OFFSET;
1163 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1164 printf("error: lock1 %d succeeded!\n", i);
1165 return False;
1168 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1169 printf("error: lock2 %d succeeded!\n", i);
1170 return False;
1173 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1174 printf("error: lock3 %d succeeded!\n", i);
1175 return False;
1178 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1179 printf("error: lock4 %d succeeded!\n", i);
1180 return False;
1184 for (offset=i=0;i<torture_numops;i++) {
1185 NEXT_OFFSET;
1187 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1188 printf("unlock1 %d failed (%s)\n",
1190 cli_errstr(&cli1));
1191 return False;
1194 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1195 printf("unlock2 %d failed (%s)\n",
1197 cli_errstr(&cli1));
1198 return False;
1202 if (!cli_close(&cli1, fnum1)) {
1203 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1204 return False;
1207 if (!cli_close(&cli2, fnum2)) {
1208 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1209 return False;
1212 if (!cli_unlink(&cli1, fname)) {
1213 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1214 return False;
1217 if (!torture_close_connection(&cli1)) {
1218 correct = False;
1221 if (!torture_close_connection(&cli2)) {
1222 correct = False;
1225 printf("finished locktest3\n");
1227 return correct;
1230 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1231 printf("** "); correct = False; \
1235 looks at overlapping locks
1237 static BOOL run_locktest4(int dummy)
1239 static struct cli_state cli1, cli2;
1240 char *fname = "\\lockt4.lck";
1241 int fnum1, fnum2, f;
1242 BOOL ret;
1243 char buf[1000];
1244 BOOL correct = True;
1246 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1247 return False;
1250 cli_sockopt(&cli1, sockops);
1251 cli_sockopt(&cli2, sockops);
1253 printf("starting locktest4\n");
1255 cli_unlink(&cli1, fname);
1257 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1258 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1260 memset(buf, 0, sizeof(buf));
1262 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1263 printf("Failed to create file\n");
1264 correct = False;
1265 goto fail;
1268 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1269 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1270 EXPECTED(ret, False);
1271 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1273 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1274 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1275 EXPECTED(ret, True);
1276 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1278 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1279 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1280 EXPECTED(ret, False);
1281 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1283 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1284 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1285 EXPECTED(ret, True);
1286 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1288 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1289 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1290 EXPECTED(ret, False);
1291 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1293 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1294 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1295 EXPECTED(ret, True);
1296 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1298 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1299 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1300 EXPECTED(ret, True);
1301 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1303 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1304 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1305 EXPECTED(ret, False);
1306 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1308 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1309 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1310 EXPECTED(ret, False);
1311 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1313 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1314 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1315 EXPECTED(ret, True);
1316 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1318 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1319 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1320 EXPECTED(ret, False);
1321 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1323 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1324 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1325 cli_unlock(&cli1, fnum1, 110, 6);
1326 EXPECTED(ret, False);
1327 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1330 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1331 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1332 EXPECTED(ret, False);
1333 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1335 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1336 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1337 EXPECTED(ret, False);
1338 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1341 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1342 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1343 cli_unlock(&cli1, fnum1, 140, 4) &&
1344 cli_unlock(&cli1, fnum1, 140, 4);
1345 EXPECTED(ret, True);
1346 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1349 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1350 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1351 cli_unlock(&cli1, fnum1, 150, 4) &&
1352 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1353 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1354 cli_unlock(&cli1, fnum1, 150, 4);
1355 EXPECTED(ret, True);
1356 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1358 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1359 cli_unlock(&cli1, fnum1, 160, 4) &&
1360 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1361 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1362 EXPECTED(ret, True);
1363 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1365 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1366 cli_unlock(&cli1, fnum1, 170, 4) &&
1367 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1368 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1369 EXPECTED(ret, True);
1370 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1372 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1373 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1374 cli_unlock(&cli1, fnum1, 190, 4) &&
1375 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1376 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1377 EXPECTED(ret, True);
1378 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1380 cli_close(&cli1, fnum1);
1381 cli_close(&cli2, fnum2);
1382 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1383 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1384 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1385 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1386 cli_close(&cli1, fnum1) &&
1387 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1388 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1389 cli_close(&cli1, f);
1390 cli_close(&cli1, fnum1);
1391 EXPECTED(ret, True);
1392 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1394 fail:
1395 cli_close(&cli1, fnum1);
1396 cli_close(&cli2, fnum2);
1397 cli_unlink(&cli1, fname);
1398 torture_close_connection(&cli1);
1399 torture_close_connection(&cli2);
1401 printf("finished locktest4\n");
1402 return correct;
1406 looks at lock upgrade/downgrade.
1408 static BOOL run_locktest5(int dummy)
1410 static struct cli_state cli1, cli2;
1411 char *fname = "\\lockt5.lck";
1412 int fnum1, fnum2, fnum3;
1413 BOOL ret;
1414 char buf[1000];
1415 BOOL correct = True;
1417 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1418 return False;
1421 cli_sockopt(&cli1, sockops);
1422 cli_sockopt(&cli2, sockops);
1424 printf("starting locktest5\n");
1426 cli_unlink(&cli1, fname);
1428 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1429 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1430 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1432 memset(buf, 0, sizeof(buf));
1434 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1435 printf("Failed to create file\n");
1436 correct = False;
1437 goto fail;
1440 /* Check for NT bug... */
1441 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1442 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1443 cli_close(&cli1, fnum1);
1444 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1445 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1446 EXPECTED(ret, True);
1447 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1448 cli_close(&cli1, fnum1);
1449 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1450 cli_unlock(&cli1, fnum3, 0, 1);
1452 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1453 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1454 EXPECTED(ret, True);
1455 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1457 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1458 EXPECTED(ret, False);
1460 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1462 /* Unlock the process 2 lock. */
1463 cli_unlock(&cli2, fnum2, 0, 4);
1465 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1466 EXPECTED(ret, False);
1468 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1470 /* Unlock the process 1 fnum3 lock. */
1471 cli_unlock(&cli1, fnum3, 0, 4);
1473 /* Stack 2 more locks here. */
1474 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1475 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1477 EXPECTED(ret, True);
1478 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1480 /* Unlock the first process lock, then check this was the WRITE lock that was
1481 removed. */
1483 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1484 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1486 EXPECTED(ret, True);
1487 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1489 /* Unlock the process 2 lock. */
1490 cli_unlock(&cli2, fnum2, 0, 4);
1492 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1494 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1495 cli_unlock(&cli1, fnum1, 0, 4) &&
1496 cli_unlock(&cli1, fnum1, 0, 4);
1498 EXPECTED(ret, True);
1499 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1501 /* Ensure the next unlock fails. */
1502 ret = cli_unlock(&cli1, fnum1, 0, 4);
1503 EXPECTED(ret, False);
1504 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1506 /* Ensure connection 2 can get a write lock. */
1507 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1508 EXPECTED(ret, True);
1510 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1513 fail:
1514 cli_close(&cli1, fnum1);
1515 cli_close(&cli2, fnum2);
1516 cli_unlink(&cli1, fname);
1517 if (!torture_close_connection(&cli1)) {
1518 correct = False;
1520 if (!torture_close_connection(&cli2)) {
1521 correct = False;
1524 printf("finished locktest5\n");
1526 return correct;
1530 tries the unusual lockingX locktype bits
1532 static BOOL run_locktest6(int dummy)
1534 static struct cli_state cli;
1535 char *fname[1] = { "\\lock6.txt" };
1536 int i;
1537 int fnum;
1538 NTSTATUS status;
1540 if (!torture_open_connection(&cli)) {
1541 return False;
1544 cli_sockopt(&cli, sockops);
1546 printf("starting locktest6\n");
1548 for (i=0;i<1;i++) {
1549 printf("Testing %s\n", fname[i]);
1551 cli_unlink(&cli, fname[i]);
1553 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1554 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1555 cli_close(&cli, fnum);
1556 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1558 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1559 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1560 cli_close(&cli, fnum);
1561 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1563 cli_unlink(&cli, fname[i]);
1566 torture_close_connection(&cli);
1568 printf("finished locktest6\n");
1569 return True;
1573 test whether fnums and tids open on one VC are available on another (a major
1574 security hole)
1576 static BOOL run_fdpasstest(int dummy)
1578 static struct cli_state cli1, cli2, cli3;
1579 char *fname = "\\fdpass.tst";
1580 int fnum1;
1581 pstring buf;
1583 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1584 return False;
1586 cli_sockopt(&cli1, sockops);
1587 cli_sockopt(&cli2, sockops);
1589 printf("starting fdpasstest\n");
1591 cli_unlink(&cli1, fname);
1593 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1594 if (fnum1 == -1) {
1595 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1596 return False;
1599 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1600 printf("write failed (%s)\n", cli_errstr(&cli1));
1601 return False;
1604 cli3 = cli2;
1605 cli3.vuid = cli1.vuid;
1606 cli3.cnum = cli1.cnum;
1607 cli3.pid = cli1.pid;
1609 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1610 printf("read succeeded! nasty security hole [%s]\n",
1611 buf);
1612 return False;
1615 cli_close(&cli1, fnum1);
1616 cli_unlink(&cli1, fname);
1618 torture_close_connection(&cli1);
1619 torture_close_connection(&cli2);
1621 printf("finished fdpasstest\n");
1622 return True;
1627 This test checks that
1629 1) the server does not allow an unlink on a file that is open
1631 static BOOL run_unlinktest(int dummy)
1633 static struct cli_state cli;
1634 char *fname = "\\unlink.tst";
1635 int fnum;
1636 BOOL correct = True;
1638 if (!torture_open_connection(&cli)) {
1639 return False;
1642 cli_sockopt(&cli, sockops);
1644 printf("starting unlink test\n");
1646 cli_unlink(&cli, fname);
1648 cli_setpid(&cli, 1);
1650 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1651 if (fnum == -1) {
1652 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1653 return False;
1656 if (cli_unlink(&cli, fname)) {
1657 printf("error: server allowed unlink on an open file\n");
1658 correct = False;
1659 } else {
1660 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare,
1661 NT_STATUS_SHARING_VIOLATION);
1664 cli_close(&cli, fnum);
1665 cli_unlink(&cli, fname);
1667 if (!torture_close_connection(&cli)) {
1668 correct = False;
1671 printf("unlink test finished\n");
1673 return correct;
1678 test how many open files this server supports on the one socket
1680 static BOOL run_maxfidtest(int dummy)
1682 static struct cli_state cli;
1683 char *template = "\\maxfid.%d.%d";
1684 fstring fname;
1685 int fnums[0x11000], i;
1686 int retries=4;
1687 BOOL correct = True;
1689 cli = current_cli;
1691 if (retries <= 0) {
1692 printf("failed to connect\n");
1693 return False;
1696 cli_sockopt(&cli, sockops);
1698 for (i=0; i<0x11000; i++) {
1699 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1700 if ((fnums[i] = cli_open(&cli, fname,
1701 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1702 -1) {
1703 printf("open of %s failed (%s)\n",
1704 fname, cli_errstr(&cli));
1705 printf("maximum fnum is %d\n", i);
1706 break;
1708 printf("%6d\r", i);
1710 printf("%6d\n", i);
1711 i--;
1713 printf("cleaning up\n");
1714 for (;i>=0;i--) {
1715 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1716 cli_close(&cli, fnums[i]);
1717 if (!cli_unlink(&cli, fname)) {
1718 printf("unlink of %s failed (%s)\n",
1719 fname, cli_errstr(&cli));
1720 correct = False;
1722 printf("%6d\r", i);
1724 printf("%6d\n", 0);
1726 printf("maxfid test finished\n");
1727 if (!torture_close_connection(&cli)) {
1728 correct = False;
1730 return correct;
1733 /* generate a random buffer */
1734 static void rand_buf(char *buf, int len)
1736 while (len--) {
1737 *buf = (char)sys_random();
1738 buf++;
1742 /* send smb negprot commands, not reading the response */
1743 static BOOL run_negprot_nowait(int dummy)
1745 int i;
1746 static struct cli_state cli;
1747 BOOL correct = True;
1749 printf("starting negprot nowait test\n");
1751 if (!open_nbt_connection(&cli)) {
1752 return False;
1755 for (i=0;i<50000;i++) {
1756 cli_negprot_send(&cli);
1759 if (!torture_close_connection(&cli)) {
1760 correct = False;
1763 printf("finished negprot nowait test\n");
1765 return correct;
1769 /* send random IPC commands */
1770 static BOOL run_randomipc(int dummy)
1772 char *rparam = NULL;
1773 char *rdata = NULL;
1774 int rdrcnt,rprcnt;
1775 pstring param;
1776 int api, param_len, i;
1777 static struct cli_state cli;
1778 BOOL correct = True;
1779 int count = 50000;
1781 printf("starting random ipc test\n");
1783 if (!torture_open_connection(&cli)) {
1784 return False;
1787 for (i=0;i<count;i++) {
1788 api = sys_random() % 500;
1789 param_len = (sys_random() % 64);
1791 rand_buf(param, param_len);
1793 SSVAL(param,0,api);
1795 cli_api(&cli,
1796 param, param_len, 8,
1797 NULL, 0, BUFFER_SIZE,
1798 &rparam, &rprcnt,
1799 &rdata, &rdrcnt);
1800 if (i % 100 == 0) {
1801 printf("%d/%d\r", i,count);
1804 printf("%d/%d\n", i, count);
1806 if (!torture_close_connection(&cli)) {
1807 correct = False;
1810 printf("finished random ipc test\n");
1812 return correct;
1817 static void browse_callback(const char *sname, uint32 stype,
1818 const char *comment, void *state)
1820 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1826 This test checks the browse list code
1829 static BOOL run_browsetest(int dummy)
1831 static struct cli_state cli;
1832 BOOL correct = True;
1834 printf("starting browse test\n");
1836 if (!torture_open_connection(&cli)) {
1837 return False;
1840 printf("domain list:\n");
1841 cli_NetServerEnum(&cli, cli.server_domain,
1842 SV_TYPE_DOMAIN_ENUM,
1843 browse_callback, NULL);
1845 printf("machine list:\n");
1846 cli_NetServerEnum(&cli, cli.server_domain,
1847 SV_TYPE_ALL,
1848 browse_callback, NULL);
1850 if (!torture_close_connection(&cli)) {
1851 correct = False;
1854 printf("browse test finished\n");
1856 return correct;
1862 This checks how the getatr calls works
1864 static BOOL run_attrtest(int dummy)
1866 static struct cli_state cli;
1867 int fnum;
1868 time_t t, t2;
1869 char *fname = "\\attrib.tst";
1870 BOOL correct = True;
1872 printf("starting attrib test\n");
1874 if (!torture_open_connection(&cli)) {
1875 return False;
1878 cli_unlink(&cli, fname);
1879 fnum = cli_open(&cli, fname,
1880 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1881 cli_close(&cli, fnum);
1882 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1883 printf("getatr failed (%s)\n", cli_errstr(&cli));
1884 correct = False;
1887 if (abs(t - time(NULL)) > 60*60*24*10) {
1888 printf("ERROR: SMBgetatr bug. time is %s",
1889 ctime(&t));
1890 t = time(NULL);
1891 correct = True;
1894 t2 = t-60*60*24; /* 1 day ago */
1896 if (!cli_setatr(&cli, fname, 0, t2)) {
1897 printf("setatr failed (%s)\n", cli_errstr(&cli));
1898 correct = True;
1901 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1902 printf("getatr failed (%s)\n", cli_errstr(&cli));
1903 correct = True;
1906 if (t != t2) {
1907 printf("ERROR: getatr/setatr bug. times are\n%s",
1908 ctime(&t));
1909 printf("%s", ctime(&t2));
1910 correct = True;
1913 cli_unlink(&cli, fname);
1915 if (!torture_close_connection(&cli)) {
1916 correct = False;
1919 printf("attrib test finished\n");
1921 return correct;
1926 This checks a couple of trans2 calls
1928 static BOOL run_trans2test(int dummy)
1930 static struct cli_state cli;
1931 int fnum;
1932 size_t size;
1933 time_t c_time, a_time, m_time, w_time, m_time2;
1934 char *fname = "\\trans2.tst";
1935 char *dname = "\\trans2";
1936 char *fname2 = "\\trans2\\trans2.tst";
1937 pstring pname;
1938 BOOL correct = True;
1940 printf("starting trans2 test\n");
1942 if (!torture_open_connection(&cli)) {
1943 return False;
1946 cli_unlink(&cli, fname);
1947 fnum = cli_open(&cli, fname,
1948 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1949 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1950 NULL, NULL)) {
1951 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1952 correct = False;
1955 if (!cli_qfilename(&cli, fnum, pname)) {
1956 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
1957 correct = False;
1960 if (strcmp(pname, fname)) {
1961 printf("qfilename gave different name? [%s] [%s]\n",
1962 fname, pname);
1963 correct = False;
1966 cli_close(&cli, fnum);
1968 sleep(2);
1970 cli_unlink(&cli, fname);
1971 fnum = cli_open(&cli, fname,
1972 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1973 if (fnum == -1) {
1974 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1975 return False;
1977 cli_close(&cli, fnum);
1979 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1980 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1981 correct = False;
1982 } else {
1983 if (c_time != m_time) {
1984 printf("create time=%s", ctime(&c_time));
1985 printf("modify time=%s", ctime(&m_time));
1986 printf("This system appears to have sticky create times\n");
1987 correct = False;
1989 if (a_time % (60*60) == 0) {
1990 printf("access time=%s", ctime(&a_time));
1991 printf("This system appears to set a midnight access time\n");
1992 correct = False;
1995 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1996 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1997 correct = False;
2002 cli_unlink(&cli, fname);
2003 fnum = cli_open(&cli, fname,
2004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2005 cli_close(&cli, fnum);
2006 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2007 &w_time, &size, NULL, NULL)) {
2008 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2009 correct = False;
2010 } else {
2011 if (w_time < 60*60*24*2) {
2012 printf("write time=%s", ctime(&w_time));
2013 printf("This system appears to set a initial 0 write time\n");
2014 correct = False;
2018 cli_unlink(&cli, fname);
2021 /* check if the server updates the directory modification time
2022 when creating a new file */
2023 if (!cli_mkdir(&cli, dname)) {
2024 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2025 correct = False;
2027 sleep(3);
2028 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2029 &w_time, &size, NULL, NULL)) {
2030 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2031 correct = False;
2034 fnum = cli_open(&cli, fname2,
2035 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2036 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2037 cli_close(&cli, fnum);
2038 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2039 &w_time, &size, NULL, NULL)) {
2040 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2041 correct = False;
2042 } else {
2043 if (m_time2 == m_time) {
2044 printf("This system does not update directory modification times\n");
2045 correct = False;
2048 cli_unlink(&cli, fname2);
2049 cli_rmdir(&cli, dname);
2051 if (!torture_close_connection(&cli)) {
2052 correct = False;
2055 printf("trans2 test finished\n");
2057 return correct;
2061 This checks new W2K calls.
2064 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2066 char buf[4096];
2067 BOOL correct = True;
2069 memset(buf, 0xff, sizeof(buf));
2071 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2072 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2073 correct = False;
2074 } else {
2075 printf("qfileinfo: level %d\n", level);
2076 dump_data(0, buf, 256);
2077 printf("\n");
2079 return correct;
2082 static BOOL run_w2ktest(int dummy)
2084 static struct cli_state cli;
2085 int fnum;
2086 char *fname = "\\w2ktest\\w2k.tst";
2087 int level;
2088 BOOL correct = True;
2090 printf("starting w2k test\n");
2092 if (!torture_open_connection(&cli)) {
2093 return False;
2096 fnum = cli_open(&cli, fname,
2097 O_RDWR | O_CREAT , DENY_NONE);
2099 for (level = 1004; level < 1040; level++) {
2100 new_trans(&cli, fnum, level);
2103 cli_close(&cli, fnum);
2105 if (!torture_close_connection(&cli)) {
2106 correct = False;
2109 printf("w2k test finished\n");
2111 return correct;
2116 this is a harness for some oplock tests
2118 static BOOL run_oplock1(int dummy)
2120 static struct cli_state cli1;
2121 char *fname = "\\lockt1.lck";
2122 int fnum1;
2123 BOOL correct = True;
2125 printf("starting oplock test 1\n");
2127 if (!torture_open_connection(&cli1)) {
2128 return False;
2131 cli_unlink(&cli1, fname);
2133 cli_sockopt(&cli1, sockops);
2135 cli1.use_oplocks = True;
2137 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2138 if (fnum1 == -1) {
2139 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2140 return False;
2143 cli1.use_oplocks = False;
2145 cli_unlink(&cli1, fname);
2146 cli_unlink(&cli1, fname);
2148 if (!cli_close(&cli1, fnum1)) {
2149 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2150 return False;
2153 if (!cli_unlink(&cli1, fname)) {
2154 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2155 return False;
2158 if (!torture_close_connection(&cli1)) {
2159 correct = False;
2162 printf("finished oplock test 1\n");
2164 return correct;
2167 static BOOL run_oplock2(int dummy)
2169 static struct cli_state cli1, cli2;
2170 char *fname = "\\lockt2.lck";
2171 int fnum1, fnum2;
2172 int saved_use_oplocks = use_oplocks;
2173 char buf[4];
2174 BOOL correct = True;
2175 volatile BOOL *shared_correct;
2177 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2178 *shared_correct = True;
2180 use_level_II_oplocks = True;
2181 use_oplocks = True;
2183 printf("starting oplock test 2\n");
2185 if (!torture_open_connection(&cli1)) {
2186 use_level_II_oplocks = False;
2187 use_oplocks = saved_use_oplocks;
2188 return False;
2191 cli1.use_oplocks = True;
2192 cli1.use_level_II_oplocks = True;
2194 if (!torture_open_connection(&cli2)) {
2195 use_level_II_oplocks = False;
2196 use_oplocks = saved_use_oplocks;
2197 return False;
2200 cli2.use_oplocks = True;
2201 cli2.use_level_II_oplocks = True;
2203 cli_unlink(&cli1, fname);
2205 cli_sockopt(&cli1, sockops);
2206 cli_sockopt(&cli2, sockops);
2208 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2209 if (fnum1 == -1) {
2210 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2211 return False;
2214 /* Don't need the globals any more. */
2215 use_level_II_oplocks = False;
2216 use_oplocks = saved_use_oplocks;
2218 if (fork() == 0) {
2219 /* Child code */
2220 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2221 if (fnum2 == -1) {
2222 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2223 *shared_correct = False;
2224 exit(0);
2227 sleep(2);
2229 if (!cli_close(&cli2, fnum2)) {
2230 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2231 *shared_correct = False;
2234 exit(0);
2237 sleep(2);
2239 /* Ensure cli1 processes the break. */
2241 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2242 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2243 correct = False;
2246 /* Should now be at level II. */
2247 /* Test if sending a write locks causes a break to none. */
2249 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2250 printf("lock failed (%s)\n", cli_errstr(&cli1));
2251 correct = False;
2254 cli_unlock(&cli1, fnum1, 0, 4);
2256 sleep(2);
2258 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2259 printf("lock failed (%s)\n", cli_errstr(&cli1));
2260 correct = False;
2263 cli_unlock(&cli1, fnum1, 0, 4);
2265 sleep(2);
2267 cli_read(&cli1, fnum1, buf, 0, 4);
2269 #if 0
2270 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2271 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2272 correct = False;
2274 #endif
2276 if (!cli_close(&cli1, fnum1)) {
2277 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2278 correct = False;
2281 sleep(4);
2283 if (!cli_unlink(&cli1, fname)) {
2284 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2285 correct = False;
2288 if (!torture_close_connection(&cli1)) {
2289 correct = False;
2292 if (!*shared_correct) {
2293 correct = False;
2296 printf("finished oplock test 2\n");
2298 return correct;
2301 /* handler for oplock 3 tests */
2302 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2304 printf("got oplock break fnum=%d level=%d\n",
2305 fnum, level);
2306 return cli_oplock_ack(cli, fnum, level);
2309 static BOOL run_oplock3(int dummy)
2311 static struct cli_state cli;
2312 char *fname = "\\oplockt3.dat";
2313 int fnum;
2314 char buf[4] = "abcd";
2315 BOOL correct = True;
2316 volatile BOOL *shared_correct;
2318 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2319 *shared_correct = True;
2321 printf("starting oplock test 3\n");
2323 if (fork() == 0) {
2324 /* Child code */
2325 use_oplocks = True;
2326 use_level_II_oplocks = True;
2327 if (!torture_open_connection(&cli)) {
2328 *shared_correct = False;
2329 exit(0);
2331 sleep(2);
2332 /* try to trigger a oplock break in parent */
2333 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2334 cli_write(&cli, fnum, 0, buf, 0, 4);
2335 exit(0);
2338 /* parent code */
2339 use_oplocks = True;
2340 use_level_II_oplocks = True;
2341 if (!torture_open_connection(&cli)) {
2342 return False;
2344 cli_oplock_handler(&cli, oplock3_handler);
2345 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2346 cli_write(&cli, fnum, 0, buf, 0, 4);
2347 cli_close(&cli, fnum);
2348 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2349 cli.timeout = 20000;
2350 cli_receive_smb(&cli);
2351 printf("finished oplock test 3\n");
2353 return (correct && *shared_correct);
2355 /* What are we looking for here? What's sucess and what's FAILURE? */
2361 Test delete on close semantics.
2363 static BOOL run_deletetest(int dummy)
2365 static struct cli_state cli1;
2366 static struct cli_state cli2;
2367 char *fname = "\\delete.file";
2368 int fnum1 = -1;
2369 int fnum2 = -1;
2370 BOOL correct = True;
2372 printf("starting delete test\n");
2374 ZERO_STRUCT(cli1);
2375 ZERO_STRUCT(cli2);
2377 if (!torture_open_connection(&cli1)) {
2378 return False;
2381 cli_sockopt(&cli1, sockops);
2383 /* Test 1 - this should *NOT* delete the file on close. */
2385 cli_setatr(&cli1, fname, 0, 0);
2386 cli_unlink(&cli1, fname);
2388 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2389 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2390 DELETE_ON_CLOSE_FLAG);
2392 if (fnum1 == -1) {
2393 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2394 correct = False;
2395 goto fail;
2398 if (!cli_close(&cli1, fnum1)) {
2399 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2400 correct = False;
2401 goto fail;
2404 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2405 if (fnum1 == -1) {
2406 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2407 correct = False;
2408 goto fail;
2411 if (!cli_close(&cli1, fnum1)) {
2412 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2413 correct = False;
2414 goto fail;
2417 printf("first delete on close test succeeded.\n");
2419 /* Test 2 - this should delete the file on close. */
2421 cli_setatr(&cli1, fname, 0, 0);
2422 cli_unlink(&cli1, fname);
2424 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2425 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2426 FILE_OVERWRITE_IF, 0);
2428 if (fnum1 == -1) {
2429 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2430 correct = False;
2431 goto fail;
2434 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2435 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2436 correct = False;
2437 goto fail;
2440 if (!cli_close(&cli1, fnum1)) {
2441 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2442 correct = False;
2443 goto fail;
2446 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2447 if (fnum1 != -1) {
2448 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2449 if (!cli_close(&cli1, fnum1)) {
2450 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2451 correct = False;
2452 goto fail;
2454 cli_unlink(&cli1, fname);
2455 } else
2456 printf("second delete on close test succeeded.\n");
2458 /* Test 3 - ... */
2459 cli_setatr(&cli1, fname, 0, 0);
2460 cli_unlink(&cli1, fname);
2462 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2463 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2465 if (fnum1 == -1) {
2466 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2467 correct = False;
2468 goto fail;
2471 /* This should fail with a sharing violation - open for delete is only compatible
2472 with SHARE_DELETE. */
2474 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2475 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2477 if (fnum2 != -1) {
2478 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2479 correct = False;
2480 goto fail;
2483 /* This should succeed. */
2485 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2486 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2488 if (fnum2 == -1) {
2489 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2490 correct = False;
2491 goto fail;
2494 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2495 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2496 correct = False;
2497 goto fail;
2500 if (!cli_close(&cli1, fnum1)) {
2501 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2502 correct = False;
2503 goto fail;
2506 if (!cli_close(&cli1, fnum2)) {
2507 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2508 correct = False;
2509 goto fail;
2512 /* This should fail - file should no longer be there. */
2514 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2515 if (fnum1 != -1) {
2516 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2517 if (!cli_close(&cli1, fnum1)) {
2518 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2520 cli_unlink(&cli1, fname);
2521 correct = False;
2522 goto fail;
2523 } else
2524 printf("third delete on close test succeeded.\n");
2526 /* Test 4 ... */
2527 cli_setatr(&cli1, fname, 0, 0);
2528 cli_unlink(&cli1, fname);
2530 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2531 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2533 if (fnum1 == -1) {
2534 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2535 correct = False;
2536 goto fail;
2539 /* This should succeed. */
2540 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2541 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2542 if (fnum2 == -1) {
2543 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2544 correct = False;
2545 goto fail;
2548 if (!cli_close(&cli1, fnum2)) {
2549 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2550 correct = False;
2551 goto fail;
2554 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2555 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2556 correct = False;
2557 goto fail;
2560 /* This should fail - no more opens once delete on close set. */
2561 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2562 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2563 if (fnum2 != -1) {
2564 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2565 correct = False;
2566 goto fail;
2567 } else
2568 printf("fourth delete on close test succeeded.\n");
2570 if (!cli_close(&cli1, fnum1)) {
2571 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2572 correct = False;
2573 goto fail;
2576 /* Test 5 ... */
2577 cli_setatr(&cli1, fname, 0, 0);
2578 cli_unlink(&cli1, fname);
2580 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2581 if (fnum1 == -1) {
2582 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2583 correct = False;
2584 goto fail;
2587 /* This should fail - only allowed on NT opens with DELETE access. */
2589 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2590 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2591 correct = False;
2592 goto fail;
2595 if (!cli_close(&cli1, fnum1)) {
2596 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2597 correct = False;
2598 goto fail;
2601 printf("fifth delete on close test succeeded.\n");
2603 /* Test 6 ... */
2604 cli_setatr(&cli1, fname, 0, 0);
2605 cli_unlink(&cli1, fname);
2607 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2608 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2609 FILE_OVERWRITE_IF, 0);
2611 if (fnum1 == -1) {
2612 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2613 correct = False;
2614 goto fail;
2617 /* This should fail - only allowed on NT opens with DELETE access. */
2619 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2620 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2621 correct = False;
2622 goto fail;
2625 if (!cli_close(&cli1, fnum1)) {
2626 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2627 correct = False;
2628 goto fail;
2631 printf("sixth delete on close test succeeded.\n");
2633 /* Test 7 ... */
2634 cli_setatr(&cli1, fname, 0, 0);
2635 cli_unlink(&cli1, fname);
2637 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2638 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2640 if (fnum1 == -1) {
2641 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2642 correct = False;
2643 goto fail;
2646 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2647 printf("[7] setting delete_on_close on file failed !\n");
2648 correct = False;
2649 goto fail;
2652 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2653 printf("[7] unsetting delete_on_close on file failed !\n");
2654 correct = False;
2655 goto fail;
2658 if (!cli_close(&cli1, fnum1)) {
2659 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2660 correct = False;
2661 goto fail;
2664 /* This next open should succeed - we reset the flag. */
2666 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2667 if (fnum1 == -1) {
2668 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2669 correct = False;
2670 goto fail;
2673 if (!cli_close(&cli1, fnum1)) {
2674 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2675 correct = False;
2676 goto fail;
2679 printf("seventh delete on close test succeeded.\n");
2681 /* Test 7 ... */
2682 cli_setatr(&cli1, fname, 0, 0);
2683 cli_unlink(&cli1, fname);
2685 if (!torture_open_connection(&cli2)) {
2686 printf("[8] failed to open second connection.\n");
2687 correct = False;
2688 goto fail;
2691 cli_sockopt(&cli1, sockops);
2693 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2694 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2696 if (fnum1 == -1) {
2697 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2698 correct = False;
2699 goto fail;
2702 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2703 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2705 if (fnum2 == -1) {
2706 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2707 correct = False;
2708 goto fail;
2711 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2712 printf("[8] setting delete_on_close on file failed !\n");
2713 correct = False;
2714 goto fail;
2717 if (!cli_close(&cli1, fnum1)) {
2718 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2719 correct = False;
2720 goto fail;
2723 if (!cli_close(&cli2, fnum2)) {
2724 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2725 correct = False;
2726 goto fail;
2729 /* This should fail.. */
2730 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2731 if (fnum1 != -1) {
2732 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2733 goto fail;
2734 correct = False;
2735 } else
2736 printf("eighth delete on close test succeeded.\n");
2738 /* This should fail - we need to set DELETE_ACCESS. */
2739 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2740 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2742 if (fnum1 != -1) {
2743 printf("[9] open of %s succeeded should have failed!\n", fname);
2744 correct = False;
2745 goto fail;
2748 printf("ninth delete on close test succeeded.\n");
2750 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2751 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2752 if (fnum1 == -1) {
2753 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2754 correct = False;
2755 goto fail;
2758 /* This should delete the file. */
2759 if (!cli_close(&cli1, fnum1)) {
2760 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2761 correct = False;
2762 goto fail;
2765 /* This should fail.. */
2766 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2767 if (fnum1 != -1) {
2768 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2769 goto fail;
2770 correct = False;
2771 } else
2772 printf("tenth delete on close test succeeded.\n");
2773 printf("finished delete test\n");
2775 fail:
2777 cli_close(&cli1, fnum1);
2778 cli_close(&cli1, fnum2);
2779 cli_setatr(&cli1, fname, 0, 0);
2780 cli_unlink(&cli1, fname);
2782 if (!torture_close_connection(&cli1)) {
2783 correct = False;
2785 if (!torture_close_connection(&cli2)) {
2786 correct = False;
2788 return correct;
2793 print out server properties
2795 static BOOL run_properties(int dummy)
2797 static struct cli_state cli;
2798 BOOL correct = True;
2800 printf("starting properties test\n");
2802 ZERO_STRUCT(cli);
2804 if (!torture_open_connection(&cli)) {
2805 return False;
2808 cli_sockopt(&cli, sockops);
2810 d_printf("Capabilities 0x%08x\n", cli.capabilities);
2812 if (!torture_close_connection(&cli)) {
2813 correct = False;
2816 return correct;
2821 /* FIRST_DESIRED_ACCESS 0xf019f */
2822 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2823 FILE_READ_EA| /* 0xf */ \
2824 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
2825 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2826 DELETE_ACCESS|READ_CONTROL_ACCESS|\
2827 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
2828 /* SECOND_DESIRED_ACCESS 0xe0080 */
2829 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2830 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2831 WRITE_OWNER_ACCESS /* 0xe0000 */
2833 #if 0
2834 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2835 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2836 FILE_READ_DATA|\
2837 WRITE_OWNER_ACCESS /* */
2838 #endif
2841 Test ntcreate calls made by xcopy
2843 static BOOL run_xcopy(int dummy)
2845 static struct cli_state cli1;
2846 char *fname = "\\test.txt";
2847 BOOL correct = True;
2848 int fnum1, fnum2;
2850 printf("starting xcopy test\n");
2852 if (!torture_open_connection(&cli1)) {
2853 return False;
2856 fnum1 = cli_nt_create_full(&cli1, fname,
2857 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2858 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
2859 0x4044);
2861 if (fnum1 == -1) {
2862 printf("First open failed - %s\n", cli_errstr(&cli1));
2863 return False;
2866 fnum2 = cli_nt_create_full(&cli1, fname,
2867 SECOND_DESIRED_ACCESS, 0,
2868 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
2869 0x200000);
2870 if (fnum2 == -1) {
2871 printf("second open failed - %s\n", cli_errstr(&cli1));
2872 return False;
2875 if (!torture_close_connection(&cli1)) {
2876 correct = False;
2879 return correct;
2883 Test rename on files open with share delete and no share delete.
2885 static BOOL run_rename(int dummy)
2887 static struct cli_state cli1;
2888 char *fname = "\\test.txt";
2889 char *fname1 = "\\test1.txt";
2890 BOOL correct = True;
2891 int fnum1;
2893 printf("starting rename test\n");
2895 if (!torture_open_connection(&cli1)) {
2896 return False;
2899 cli_unlink(&cli1, fname);
2900 cli_unlink(&cli1, fname1);
2901 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2902 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2904 if (fnum1 == -1) {
2905 printf("First open failed - %s\n", cli_errstr(&cli1));
2906 return False;
2909 if (!cli_rename(&cli1, fname, fname1)) {
2910 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
2911 } else {
2912 printf("First rename succeeded - this should have failed !\n");
2913 correct = False;
2916 if (!cli_close(&cli1, fnum1)) {
2917 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
2918 return False;
2921 cli_unlink(&cli1, fname);
2922 cli_unlink(&cli1, fname1);
2923 fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2924 #if 0
2925 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2926 #else
2927 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2928 #endif
2930 if (fnum1 == -1) {
2931 printf("Second open failed - %s\n", cli_errstr(&cli1));
2932 return False;
2935 if (!cli_rename(&cli1, fname, fname1)) {
2936 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2937 correct = False;
2938 } else {
2939 printf("Second rename succeeded\n");
2942 if (!cli_close(&cli1, fnum1)) {
2943 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
2944 return False;
2947 cli_unlink(&cli1, fname);
2948 cli_unlink(&cli1, fname1);
2950 fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2951 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2953 if (fnum1 == -1) {
2954 printf("Third open failed - %s\n", cli_errstr(&cli1));
2955 return False;
2959 #if 0
2961 int fnum2;
2963 fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2964 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2966 if (fnum2 == -1) {
2967 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
2968 return False;
2970 if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
2971 printf("[8] setting delete_on_close on file failed !\n");
2972 return False;
2975 if (!cli_close(&cli1, fnum2)) {
2976 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
2977 return False;
2980 #endif
2982 if (!cli_rename(&cli1, fname, fname1)) {
2983 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2984 correct = False;
2985 } else {
2986 printf("Third rename succeeded\n");
2989 if (!cli_close(&cli1, fnum1)) {
2990 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
2991 return False;
2994 cli_unlink(&cli1, fname);
2995 cli_unlink(&cli1, fname1);
2997 if (!torture_close_connection(&cli1)) {
2998 correct = False;
3001 return correct;
3004 static BOOL run_pipe_number(int dummy)
3006 static struct cli_state cli1;
3007 char *pipe_name = "\\SPOOLSS";
3008 int fnum;
3009 int num_pipes = 0;
3011 printf("starting pipenumber test\n");
3012 if (!torture_open_connection(&cli1)) {
3013 return False;
3016 cli_sockopt(&cli1, sockops);
3017 while(1) {
3018 fnum = cli_nt_create_full(&cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3019 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
3021 if (fnum == -1) {
3022 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(&cli1));
3023 break;
3025 num_pipes++;
3028 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3029 torture_close_connection(&cli1);
3030 return True;
3034 Test open mode returns on read-only files.
3036 static BOOL run_opentest(int dummy)
3038 static struct cli_state cli1;
3039 static struct cli_state cli2;
3040 char *fname = "\\readonly.file";
3041 int fnum1, fnum2;
3042 char buf[20];
3043 size_t fsize;
3044 BOOL correct = True;
3045 char *tmp_path;
3047 printf("starting open test\n");
3049 if (!torture_open_connection(&cli1)) {
3050 return False;
3053 cli_setatr(&cli1, fname, 0, 0);
3054 cli_unlink(&cli1, fname);
3056 cli_sockopt(&cli1, sockops);
3058 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3059 if (fnum1 == -1) {
3060 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3061 return False;
3064 if (!cli_close(&cli1, fnum1)) {
3065 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3066 return False;
3069 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3070 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3071 return False;
3074 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3075 if (fnum1 == -1) {
3076 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3077 return False;
3080 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3081 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3083 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess,
3084 NT_STATUS_ACCESS_DENIED)) {
3085 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3088 printf("finished open test 1\n");
3090 cli_close(&cli1, fnum1);
3092 /* Now try not readonly and ensure ERRbadshare is returned. */
3094 cli_setatr(&cli1, fname, 0, 0);
3096 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3097 if (fnum1 == -1) {
3098 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3099 return False;
3102 /* This will fail - but the error should be ERRshare. */
3103 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3105 if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare,
3106 NT_STATUS_SHARING_VIOLATION)) {
3107 printf("correct error code ERRDOS/ERRbadshare returned\n");
3110 if (!cli_close(&cli1, fnum1)) {
3111 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3112 return False;
3115 cli_unlink(&cli1, fname);
3117 printf("finished open test 2\n");
3119 /* Test truncate open disposition on file opened for read. */
3121 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3122 if (fnum1 == -1) {
3123 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3124 return False;
3127 /* write 20 bytes. */
3129 memset(buf, '\0', 20);
3131 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3132 printf("write failed (%s)\n", cli_errstr(&cli1));
3133 correct = False;
3136 if (!cli_close(&cli1, fnum1)) {
3137 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3138 return False;
3141 /* Ensure size == 20. */
3142 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3143 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3144 return False;
3147 if (fsize != 20) {
3148 printf("(3) file size != 20\n");
3149 return False;
3152 /* Now test if we can truncate a file opened for readonly. */
3154 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3155 if (fnum1 == -1) {
3156 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3157 return False;
3160 if (!cli_close(&cli1, fnum1)) {
3161 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3162 return False;
3165 /* Ensure size == 0. */
3166 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3167 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3168 return False;
3171 if (fsize != 0) {
3172 printf("(3) file size != 0\n");
3173 return False;
3175 printf("finished open test 3\n");
3177 cli_unlink(&cli1, fname);
3180 printf("testing ctemp\n");
3181 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3182 if (fnum1 == -1) {
3183 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3184 return False;
3186 printf("ctemp gave path %s\n", tmp_path);
3187 if (!cli_close(&cli1, fnum1)) {
3188 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3190 if (!cli_unlink(&cli1, tmp_path)) {
3191 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3194 /* Test the non-io opens... */
3196 if (!torture_open_connection(&cli2)) {
3197 return False;
3200 cli_setatr(&cli2, fname, 0, 0);
3201 cli_unlink(&cli2, fname);
3203 cli_sockopt(&cli2, sockops);
3205 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3207 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3208 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3210 if (fnum1 == -1) {
3211 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3212 return False;
3215 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3216 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3218 if (fnum2 == -1) {
3219 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3220 return False;
3223 if (!cli_close(&cli1, fnum1)) {
3224 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3225 return False;
3227 if (!cli_close(&cli2, fnum2)) {
3228 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3229 return False;
3232 printf("non-io open test #1 passed.\n");
3234 cli_unlink(&cli1, fname);
3236 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3238 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3239 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3241 if (fnum1 == -1) {
3242 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3243 return False;
3246 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3247 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3249 if (fnum2 == -1) {
3250 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3251 return False;
3254 if (!cli_close(&cli1, fnum1)) {
3255 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3256 return False;
3258 if (!cli_close(&cli2, fnum2)) {
3259 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3260 return False;
3263 printf("non-io open test #2 passed.\n");
3265 cli_unlink(&cli1, fname);
3267 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3269 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3270 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3272 if (fnum1 == -1) {
3273 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3274 return False;
3277 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3278 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3280 if (fnum2 == -1) {
3281 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3282 return False;
3285 if (!cli_close(&cli1, fnum1)) {
3286 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3287 return False;
3289 if (!cli_close(&cli2, fnum2)) {
3290 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3291 return False;
3294 printf("non-io open test #3 passed.\n");
3296 cli_unlink(&cli1, fname);
3298 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3300 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3301 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3303 if (fnum1 == -1) {
3304 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3305 return False;
3308 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3309 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3311 if (fnum2 != -1) {
3312 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3313 return False;
3316 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3318 if (!cli_close(&cli1, fnum1)) {
3319 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3320 return False;
3323 printf("non-io open test #4 passed.\n");
3325 cli_unlink(&cli1, fname);
3327 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3329 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3330 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3332 if (fnum1 == -1) {
3333 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3334 return False;
3337 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3338 FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3340 if (fnum2 == -1) {
3341 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3342 return False;
3345 if (!cli_close(&cli1, fnum1)) {
3346 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3347 return False;
3350 if (!cli_close(&cli2, fnum2)) {
3351 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3352 return False;
3355 printf("non-io open test #5 passed.\n");
3357 printf("TEST #6 testing 1 non-io open, one io open\n");
3359 cli_unlink(&cli1, fname);
3361 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3362 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3364 if (fnum1 == -1) {
3365 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3366 return False;
3369 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3370 FILE_SHARE_READ, FILE_OPEN_IF, 0);
3372 if (fnum2 == -1) {
3373 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3374 return False;
3377 if (!cli_close(&cli1, fnum1)) {
3378 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3379 return False;
3382 if (!cli_close(&cli2, fnum2)) {
3383 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3384 return False;
3387 printf("non-io open test #6 passed.\n");
3389 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3391 cli_unlink(&cli1, fname);
3393 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3394 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3396 if (fnum1 == -1) {
3397 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3398 return False;
3401 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3402 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3404 if (fnum2 != -1) {
3405 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3406 return False;
3409 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3411 if (!cli_close(&cli1, fnum1)) {
3412 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3413 return False;
3416 printf("non-io open test #7 passed.\n");
3418 cli_unlink(&cli1, fname);
3420 /* Test 8 - attributes test test... */
3421 fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN,
3422 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3424 if (fnum1 == -1) {
3425 printf("test 8 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3426 return False;
3429 if (!cli_close(&cli1, fnum1)) {
3430 printf("test 8 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3431 return False;
3434 /* FILE_SUPERSEDE && FILE_OVERWRITE_IF have the same effect here. */
3435 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL,
3436 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3438 if (fnum1 == -1) {
3439 printf("test 8 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3440 return False;
3443 if (!cli_close(&cli1, fnum1)) {
3444 printf("test 8 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3445 return False;
3448 /* This open should fail with ACCESS_DENIED for FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF. */
3449 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3450 FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3452 if (fnum1 != -1) {
3453 printf("test 8 open 3 of %s succeeded - should have failed with (NT_STATUS_ACCESS_DENIED)\n", fname);
3454 correct = False;
3455 cli_close(&cli1, fnum1);
3456 } else {
3457 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED)) {
3458 printf("correct error code NT_STATUS_ACCESS_DENIED/ERRDOS:ERRnoaccess returned\n");
3462 printf("Attribute open test #8 %s.\n", correct ? "passed" : "failed");
3464 cli_unlink(&cli1, fname);
3466 if (!torture_close_connection(&cli1)) {
3467 correct = False;
3469 if (!torture_close_connection(&cli2)) {
3470 correct = False;
3473 return correct;
3476 static void list_fn(file_info *finfo, const char *name, void *state)
3482 test directory listing speed
3484 static BOOL run_dirtest(int dummy)
3486 int i;
3487 static struct cli_state cli;
3488 int fnum;
3489 double t1;
3490 BOOL correct = True;
3492 printf("starting directory test\n");
3494 if (!torture_open_connection(&cli)) {
3495 return False;
3498 cli_sockopt(&cli, sockops);
3500 srandom(0);
3501 for (i=0;i<torture_numops;i++) {
3502 fstring fname;
3503 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3504 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3505 if (fnum == -1) {
3506 fprintf(stderr,"Failed to open %s\n", fname);
3507 return False;
3509 cli_close(&cli, fnum);
3512 t1 = end_timer();
3514 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3515 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3516 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3518 printf("dirtest core %g seconds\n", end_timer() - t1);
3520 srandom(0);
3521 for (i=0;i<torture_numops;i++) {
3522 fstring fname;
3523 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3524 cli_unlink(&cli, fname);
3527 if (!torture_close_connection(&cli)) {
3528 correct = False;
3531 printf("finished dirtest\n");
3533 return correct;
3536 static void del_fn(file_info *finfo, const char *mask, void *state)
3538 struct cli_state *pcli = (struct cli_state *)state;
3539 fstring fname;
3540 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3542 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3543 return;
3545 if (finfo->mode & aDIR) {
3546 if (!cli_rmdir(pcli, fname))
3547 printf("del_fn: failed to rmdir %s\n,", fname );
3548 } else {
3549 if (!cli_unlink(pcli, fname))
3550 printf("del_fn: failed to unlink %s\n,", fname );
3554 static BOOL run_dirtest1(int dummy)
3556 int i;
3557 static struct cli_state cli;
3558 int fnum, num_seen;
3559 BOOL correct = True;
3561 printf("starting directory test\n");
3563 if (!torture_open_connection(&cli)) {
3564 return False;
3567 cli_sockopt(&cli, sockops);
3569 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3570 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3571 cli_rmdir(&cli, "\\LISTDIR");
3572 cli_mkdir(&cli, "\\LISTDIR");
3574 /* Create 1000 files and 1000 directories. */
3575 for (i=0;i<1000;i++) {
3576 fstring fname;
3577 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
3578 fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3579 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
3580 if (fnum == -1) {
3581 fprintf(stderr,"Failed to open %s\n", fname);
3582 return False;
3584 cli_close(&cli, fnum);
3586 for (i=0;i<1000;i++) {
3587 fstring fname;
3588 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
3589 if (!cli_mkdir(&cli, fname)) {
3590 fprintf(stderr,"Failed to open %s\n", fname);
3591 return False;
3595 /* Now ensure that doing an old list sees both files and directories. */
3596 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
3597 printf("num_seen = %d\n", num_seen );
3598 /* We should see 100 files + 1000 directories + . and .. */
3599 if (num_seen != 2002)
3600 correct = False;
3602 /* Ensure if we have the "must have" bits we only see the
3603 * relevent entries.
3605 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
3606 printf("num_seen = %d\n", num_seen );
3607 if (num_seen != 1002)
3608 correct = False;
3610 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
3611 printf("num_seen = %d\n", num_seen );
3612 if (num_seen != 1000)
3613 correct = False;
3615 /* Delete everything. */
3616 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3617 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3618 cli_rmdir(&cli, "\\LISTDIR");
3620 #if 0
3621 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3622 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3623 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3624 #endif
3626 if (!torture_close_connection(&cli)) {
3627 correct = False;
3630 printf("finished dirtest1\n");
3632 return correct;
3635 static BOOL run_error_map_extract(int dummy) {
3637 static struct cli_state c_dos;
3638 static struct cli_state c_nt;
3640 uint32 error;
3642 uint32 flgs2, errnum;
3643 uint8 errclass;
3645 NTSTATUS nt_status;
3647 fstring user;
3649 /* NT-Error connection */
3651 if (!open_nbt_connection(&c_nt)) {
3652 return False;
3655 c_nt.use_spnego = False;
3657 if (!cli_negprot(&c_nt)) {
3658 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3659 cli_shutdown(&c_nt);
3660 return False;
3663 if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3664 workgroup)) {
3665 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3666 return False;
3669 /* DOS-Error connection */
3671 if (!open_nbt_connection(&c_dos)) {
3672 return False;
3675 c_dos.use_spnego = False;
3676 c_dos.force_dos_errors = True;
3678 if (!cli_negprot(&c_dos)) {
3679 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3680 cli_shutdown(&c_dos);
3681 return False;
3684 if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3685 workgroup)) {
3686 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3687 return False;
3690 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3691 snprintf(user, sizeof(user), "%X", error);
3693 if (cli_session_setup(&c_nt, user,
3694 password, strlen(password),
3695 password, strlen(password),
3696 workgroup)) {
3697 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3700 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3702 /* Case #1: 32-bit NT errors */
3703 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3704 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3705 } else {
3706 printf("/** Dos error on NT connection! (%s) */\n",
3707 cli_errstr(&c_nt));
3708 nt_status = NT_STATUS(0xc0000000);
3711 if (cli_session_setup(&c_dos, user,
3712 password, strlen(password),
3713 password, strlen(password),
3714 workgroup)) {
3715 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3717 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3719 /* Case #1: 32-bit NT errors */
3720 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3721 printf("/** NT error on DOS connection! (%s) */\n",
3722 cli_errstr(&c_nt));
3723 errnum = errclass = 0;
3724 } else {
3725 cli_dos_error(&c_dos, &errclass, &errnum);
3728 if (NT_STATUS_V(nt_status) != error) {
3729 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
3730 get_nt_error_c_code(NT_STATUS(error)),
3731 get_nt_error_c_code(nt_status));
3734 printf("\t{%s,\t%s,\t%s},\n",
3735 smb_dos_err_class(errclass),
3736 smb_dos_err_name(errclass, errnum),
3737 get_nt_error_c_code(NT_STATUS(error)));
3739 return True;
3742 static double create_procs(BOOL (*fn)(int), BOOL *result)
3744 int i, status;
3745 volatile pid_t *child_status;
3746 volatile BOOL *child_status_out;
3747 int synccount;
3748 int tries = 8;
3750 synccount = 0;
3752 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3753 if (!child_status) {
3754 printf("Failed to setup shared memory\n");
3755 return -1;
3758 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3759 if (!child_status_out) {
3760 printf("Failed to setup result status shared memory\n");
3761 return -1;
3764 for (i = 0; i < nprocs; i++) {
3765 child_status[i] = 0;
3766 child_status_out[i] = True;
3769 start_timer();
3771 for (i=0;i<nprocs;i++) {
3772 procnum = i;
3773 if (fork() == 0) {
3774 pid_t mypid = getpid();
3775 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3777 slprintf(myname,sizeof(myname),"CLIENT%d", i);
3779 while (1) {
3780 memset(&current_cli, 0, sizeof(current_cli));
3781 if (torture_open_connection(&current_cli)) break;
3782 if (tries-- == 0) {
3783 printf("pid %d failed to start\n", (int)getpid());
3784 _exit(1);
3786 msleep(10);
3789 child_status[i] = getpid();
3791 while (child_status[i] && end_timer() < 5) msleep(2);
3793 child_status_out[i] = fn(i);
3794 _exit(0);
3798 do {
3799 synccount = 0;
3800 for (i=0;i<nprocs;i++) {
3801 if (child_status[i]) synccount++;
3803 if (synccount == nprocs) break;
3804 msleep(10);
3805 } while (end_timer() < 30);
3807 if (synccount != nprocs) {
3808 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3809 *result = False;
3810 return end_timer();
3813 /* start the client load */
3814 start_timer();
3816 for (i=0;i<nprocs;i++) {
3817 child_status[i] = 0;
3820 printf("%d clients started\n", nprocs);
3822 for (i=0;i<nprocs;i++) {
3823 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3826 printf("\n");
3828 for (i=0;i<nprocs;i++) {
3829 if (!child_status_out[i]) {
3830 *result = False;
3833 return end_timer();
3836 #define FLAG_MULTIPROC 1
3838 static struct {
3839 char *name;
3840 BOOL (*fn)(int);
3841 unsigned flags;
3842 } torture_ops[] = {
3843 {"FDPASS", run_fdpasstest, 0},
3844 {"LOCK1", run_locktest1, 0},
3845 {"LOCK2", run_locktest2, 0},
3846 {"LOCK3", run_locktest3, 0},
3847 {"LOCK4", run_locktest4, 0},
3848 {"LOCK5", run_locktest5, 0},
3849 {"LOCK6", run_locktest6, 0},
3850 {"UNLINK", run_unlinktest, 0},
3851 {"BROWSE", run_browsetest, 0},
3852 {"ATTR", run_attrtest, 0},
3853 {"TRANS2", run_trans2test, 0},
3854 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3855 {"TORTURE",run_torture, FLAG_MULTIPROC},
3856 {"RANDOMIPC", run_randomipc, 0},
3857 {"NEGNOWAIT", run_negprot_nowait, 0},
3858 {"NBENCH", run_nbench, 0},
3859 {"OPLOCK1", run_oplock1, 0},
3860 {"OPLOCK2", run_oplock2, 0},
3861 {"OPLOCK3", run_oplock3, 0},
3862 {"DIR", run_dirtest, 0},
3863 {"DIR1", run_dirtest1, 0},
3864 {"DENY1", torture_denytest1, 0},
3865 {"DENY2", torture_denytest2, 0},
3866 {"TCON", run_tcon_test, 0},
3867 {"RW1", run_readwritetest, 0},
3868 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
3869 {"RW3", run_readwritelarge, 0},
3870 {"OPEN", run_opentest, 0},
3871 {"XCOPY", run_xcopy, 0},
3872 {"RENAME", run_rename, 0},
3873 {"DELETE", run_deletetest, 0},
3874 {"PROPERTIES", run_properties, 0},
3875 {"MANGLE", torture_mangle, 0},
3876 {"W2K", run_w2ktest, 0},
3877 {"TRANS2SCAN", torture_trans2_scan, 0},
3878 {"NTTRANSSCAN", torture_nttrans_scan, 0},
3879 {"UTABLE", torture_utable, 0},
3880 {"CASETABLE", torture_casetable, 0},
3881 {"ERRMAPEXTRACT", run_error_map_extract, 0},
3882 {"PIPE_NUMBER", run_pipe_number, 0},
3883 {NULL, NULL, 0}};
3887 /****************************************************************************
3888 run a specified test or "ALL"
3889 ****************************************************************************/
3890 static BOOL run_test(char *name)
3892 BOOL ret = True;
3893 BOOL result = True;
3894 int i;
3895 double t;
3896 if (strequal(name,"ALL")) {
3897 for (i=0;torture_ops[i].name;i++) {
3898 run_test(torture_ops[i].name);
3902 for (i=0;torture_ops[i].name;i++) {
3903 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
3904 (unsigned)random());
3906 if (strequal(name, torture_ops[i].name)) {
3907 printf("Running %s\n", name);
3908 if (torture_ops[i].flags & FLAG_MULTIPROC) {
3909 t = create_procs(torture_ops[i].fn, &result);
3910 if (!result) {
3911 ret = False;
3912 printf("TEST %s FAILED!\n", name);
3915 } else {
3916 start_timer();
3917 if (!torture_ops[i].fn(0)) {
3918 ret = False;
3919 printf("TEST %s FAILED!\n", name);
3921 t = end_timer();
3923 printf("%s took %g secs\n\n", name, t);
3926 return ret;
3930 static void usage(void)
3932 int i;
3934 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3936 printf("\t-d debuglevel\n");
3937 printf("\t-U user%%pass\n");
3938 printf("\t-k use kerberos\n");
3939 printf("\t-N numprocs\n");
3940 printf("\t-n my_netbios_name\n");
3941 printf("\t-W workgroup\n");
3942 printf("\t-o num_operations\n");
3943 printf("\t-O socket_options\n");
3944 printf("\t-m maximum protocol\n");
3945 printf("\t-L use oplocks\n");
3946 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
3947 printf("\t-A showall\n");
3948 printf("\t-s seed\n");
3949 printf("\n\n");
3951 printf("tests are:");
3952 for (i=0;torture_ops[i].name;i++) {
3953 printf(" %s", torture_ops[i].name);
3955 printf("\n");
3957 printf("default test is ALL\n");
3959 exit(1);
3966 /****************************************************************************
3967 main program
3968 ****************************************************************************/
3969 int main(int argc,char *argv[])
3971 int opt, i;
3972 char *p;
3973 int gotpass = 0;
3974 extern char *optarg;
3975 extern int optind;
3976 BOOL correct = True;
3978 dbf = x_stdout;
3980 #ifdef HAVE_SETBUFFER
3981 setbuffer(stdout, NULL, 0);
3982 #endif
3984 lp_load(dyn_CONFIGFILE,True,False,False);
3985 load_interfaces();
3987 if (argc < 2) {
3988 usage();
3991 for(p = argv[1]; *p; p++)
3992 if(*p == '\\')
3993 *p = '/';
3995 if (strncmp(argv[1], "//", 2)) {
3996 usage();
3999 fstrcpy(host, &argv[1][2]);
4000 p = strchr_m(&host[2],'/');
4001 if (!p) {
4002 usage();
4004 *p = 0;
4005 fstrcpy(share, p+1);
4007 get_myname(myname);
4009 if (*username == 0 && getenv("LOGNAME")) {
4010 pstrcpy(username,getenv("LOGNAME"));
4013 argc--;
4014 argv++;
4016 srandom(time(NULL));
4018 fstrcpy(workgroup, lp_workgroup());
4020 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4021 switch (opt) {
4022 case 's':
4023 srandom(atoi(optarg));
4024 break;
4025 case 'W':
4026 fstrcpy(workgroup,optarg);
4027 break;
4028 case 'm':
4029 max_protocol = interpret_protocol(optarg, max_protocol);
4030 break;
4031 case 'N':
4032 nprocs = atoi(optarg);
4033 break;
4034 case 'o':
4035 torture_numops = atoi(optarg);
4036 break;
4037 case 'd':
4038 DEBUGLEVEL = atoi(optarg);
4039 break;
4040 case 'O':
4041 sockops = optarg;
4042 break;
4043 case 'L':
4044 use_oplocks = True;
4045 break;
4046 case 'A':
4047 torture_showall = True;
4048 break;
4049 case 'n':
4050 fstrcpy(myname, optarg);
4051 break;
4052 case 'c':
4053 client_txt = optarg;
4054 break;
4055 case 'k':
4056 #ifdef HAVE_KRB5
4057 use_kerberos = True;
4058 gotpass = True;
4059 #else
4060 d_printf("No kerberos support compiled in\n");
4061 exit(1);
4062 #endif
4063 break;
4064 case 'U':
4065 pstrcpy(username,optarg);
4066 p = strchr_m(username,'%');
4067 if (p) {
4068 *p = 0;
4069 pstrcpy(password, p+1);
4070 gotpass = 1;
4072 break;
4073 default:
4074 printf("Unknown option %c (%d)\n", (char)opt, opt);
4075 usage();
4080 while (!gotpass) {
4081 p = getpass("Password:");
4082 if (p) {
4083 pstrcpy(password, p);
4084 gotpass = 1;
4088 printf("host=%s share=%s user=%s myname=%s\n",
4089 host, share, username, myname);
4091 if (argc == 1) {
4092 correct = run_test("ALL");
4093 } else {
4094 for (i=1;i<argc;i++) {
4095 if (!run_test(argv[i])) {
4096 correct = False;
4101 if (correct) {
4102 return(0);
4103 } else {
4104 return(1);