the beginning of a test to determine and display a servers properties
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    
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.
10    
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.
15    
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.
19 */
20
21 #define NO_SYSLOG
22
23 #include "includes.h"
24
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, numops=100;
29 static int procnum; /* records process count number when forking */
30 static struct cli_state current_cli;
31 static fstring randomfname;
32 static BOOL use_oplocks;
33 static BOOL use_level_II_oplocks;
34 static char *client_txt = "client_oplocks.txt";
35 static BOOL use_kerberos;
36
37 BOOL torture_showall = False;
38
39 static double create_procs(BOOL (*fn)(int), BOOL *result);
40
41
42 static struct timeval tp1,tp2;
43
44 void start_timer(void)
45 {
46         gettimeofday(&tp1,NULL);
47 }
48
49 double end_timer(void)
50 {
51         gettimeofday(&tp2,NULL);
52         return((tp2.tv_sec - tp1.tv_sec) + 
53                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
54 }
55
56
57 /* return a pointer to a anonymous shared memory segment of size "size"
58    which will persist across fork() but will disappear when all processes
59    exit 
60
61    The memory is not zeroed 
62
63    This function uses system5 shared memory. It takes advantage of a property
64    that the memory is not destroyed if it is attached when the id is removed
65    */
66 void *shm_setup(int size)
67 {
68         int shmid;
69         void *ret;
70
71         shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
72         if (shmid == -1) {
73                 printf("can't get shared memory\n");
74                 exit(1);
75         }
76         ret = (void *)shmat(shmid, 0, 0);
77         if (!ret || ret == (void *)-1) {
78                 printf("can't attach to shared memory\n");
79                 return NULL;
80         }
81         /* the following releases the ipc, but note that this process
82            and all its children will still have access to the memory, its
83            just that the shmid is no longer valid for other shm calls. This
84            means we don't leave behind lots of shm segments after we exit 
85
86            See Stevens "advanced programming in unix env" for details
87            */
88         shmctl(shmid, IPC_RMID, 0);
89         
90         return ret;
91 }
92
93
94 static BOOL open_nbt_connection(struct cli_state *c)
95 {
96         struct nmb_name called, calling;
97         struct in_addr ip;
98
99         ZERO_STRUCTP(c);
100
101         make_nmb_name(&calling, myname, 0x0);
102         make_nmb_name(&called , host, 0x20);
103
104         zero_ip(&ip);
105
106         if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
107                 printf("Failed to connect with %s\n", host);
108                 return False;
109         }
110
111         c->use_kerberos = use_kerberos;
112
113         c->timeout = 120000; /* set a really long timeout (2 minutes) */
114         if (use_oplocks) c->use_oplocks = True;
115         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
116
117         if (!cli_session_request(c, &calling, &called)) {
118                 printf("%s rejected the session\n",host);
119                 cli_shutdown(c);
120                 return False;
121         }
122
123         return True;
124 }
125
126 BOOL torture_open_connection(struct cli_state *c)
127 {
128         ZERO_STRUCTP(c);
129
130         if (!open_nbt_connection(c)) {
131                 return False;
132         }
133
134         if (!cli_negprot(c)) {
135                 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
136                 cli_shutdown(c);
137                 return False;
138         }
139
140         if (!cli_session_setup(c, username, 
141                                password, strlen(password),
142                                password, strlen(password),
143                                workgroup)) {
144                 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
145                 cli_shutdown(c);
146                 return False;
147         }
148
149         if (!cli_send_tconX(c, share, "?????",
150                             password, strlen(password)+1)) {
151                 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
152                 cli_shutdown(c);
153                 return False;
154         }
155
156         return True;
157 }
158
159
160 BOOL torture_close_connection(struct cli_state *c)
161 {
162         BOOL ret = True;
163         if (!cli_tdis(c)) {
164                 printf("tdis failed (%s)\n", cli_errstr(c));
165                 ret = False;
166         }
167
168         cli_shutdown(c);
169
170         return ret;
171 }
172
173
174 /* check if the server produced the expected error code */
175 static BOOL check_error(int line, struct cli_state *c, 
176                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
177 {
178         if (cli_is_dos_error(c)) {
179                 uint8 class;
180                 uint32 num;
181
182                 /* Check DOS error */
183
184                 cli_dos_error(c, &class, &num);
185
186                 if (eclass != class || ecode != num) {
187                         printf("unexpected error code class=%d code=%d\n", 
188                                (int)class, (int)num);
189                         printf(" expected %d/%d %s (line=%d)\n", 
190                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
191                         return False;
192                 }
193
194         } else {
195                 NTSTATUS status;
196
197                 /* Check NT error */
198
199                 status = cli_nt_error(c);
200
201                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
202                         printf("unexpected error code %s\n", nt_errstr(status));
203                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
204                         return False;
205                 }
206         }
207
208         return True;
209 }
210
211
212 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
213 {
214         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
215                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
216         }
217         return True;
218 }
219
220
221 static BOOL rw_torture(struct cli_state *c)
222 {
223         char *lockfname = "\\torture.lck";
224         fstring fname;
225         int fnum;
226         int fnum2;
227         pid_t pid2, pid = getpid();
228         int i, j;
229         char buf[1024];
230         BOOL correct = True;
231
232         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
233                          DENY_NONE);
234         if (fnum2 == -1)
235                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
236         if (fnum2 == -1) {
237                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
238                 return False;
239         }
240
241
242         for (i=0;i<numops;i++) {
243                 unsigned n = (unsigned)sys_random()%10;
244                 if (i % 10 == 0) {
245                         printf("%d\r", i); fflush(stdout);
246                 }
247                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
248
249                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
250                         return False;
251                 }
252
253                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
254                 if (fnum == -1) {
255                         printf("open failed (%s)\n", cli_errstr(c));
256                         correct = False;
257                         break;
258                 }
259
260                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
261                         printf("write failed (%s)\n", cli_errstr(c));
262                         correct = False;
263                 }
264
265                 for (j=0;j<50;j++) {
266                         if (cli_write(c, fnum, 0, (char *)buf, 
267                                       sizeof(pid)+(j*sizeof(buf)), 
268                                       sizeof(buf)) != sizeof(buf)) {
269                                 printf("write failed (%s)\n", cli_errstr(c));
270                                 correct = False;
271                         }
272                 }
273
274                 pid2 = 0;
275
276                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
277                         printf("read failed (%s)\n", cli_errstr(c));
278                         correct = False;
279                 }
280
281                 if (pid2 != pid) {
282                         printf("data corruption!\n");
283                         correct = False;
284                 }
285
286                 if (!cli_close(c, fnum)) {
287                         printf("close failed (%s)\n", cli_errstr(c));
288                         correct = False;
289                 }
290
291                 if (!cli_unlink(c, fname)) {
292                         printf("unlink failed (%s)\n", cli_errstr(c));
293                         correct = False;
294                 }
295
296                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
297                         printf("unlock failed (%s)\n", cli_errstr(c));
298                         correct = False;
299                 }
300         }
301
302         cli_close(c, fnum2);
303         cli_unlink(c, lockfname);
304
305         printf("%d\n", i);
306
307         return correct;
308 }
309
310 static BOOL run_torture(int dummy)
311 {
312         struct cli_state cli;
313         BOOL ret;
314
315         cli = current_cli;
316
317         cli_sockopt(&cli, sockops);
318
319         ret = rw_torture(&cli);
320         
321         if (!torture_close_connection(&cli)) {
322                 ret = False;
323         }
324
325         return ret;
326 }
327
328 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
329 {
330         int fnum = -1;
331         int i = 0;
332         char buf[131072];
333         char buf_rd[131072];
334         unsigned count;
335         unsigned countprev = 0;
336         ssize_t sent = 0;
337         BOOL correct = True;
338
339         srandom(1);
340         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
341         {
342                 SIVAL(buf, i, sys_random());
343         }
344
345         if (procnum == 0)
346         {
347                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
348                                  DENY_NONE);
349                 if (fnum == -1) {
350                         printf("first open read/write of %s failed (%s)\n",
351                                         lockfname, cli_errstr(c));
352                         return False;
353                 }
354         }
355         else
356         {
357                 for (i = 0; i < 500 && fnum == -1; i++)
358                 {
359                         fnum = cli_open(c, lockfname, O_RDONLY, 
360                                          DENY_NONE);
361                         msleep(10);
362                 }
363                 if (fnum == -1) {
364                         printf("second open read-only of %s failed (%s)\n",
365                                         lockfname, cli_errstr(c));
366                         return False;
367                 }
368         }
369
370         i = 0;
371         for (count = 0; count < sizeof(buf); count += sent)
372         {
373                 if (count >= countprev) {
374                         printf("%d %8d\r", i, count);
375                         fflush(stdout);
376                         i++;
377                         countprev += (sizeof(buf) / 20);
378                 }
379
380                 if (procnum == 0)
381                 {
382                         sent = ((unsigned)sys_random()%(20))+ 1;
383                         if (sent > sizeof(buf) - count)
384                         {
385                                 sent = sizeof(buf) - count;
386                         }
387
388                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
389                                 printf("write failed (%s)\n", cli_errstr(c));
390                                 correct = False;
391                         }
392                 }
393                 else
394                 {
395                         sent = cli_read(c, fnum, buf_rd+count, count,
396                                                   sizeof(buf)-count);
397                         if (sent < 0)
398                         {
399                                 printf("read failed offset:%d size:%d (%s)\n",
400                                                 count, sizeof(buf)-count,
401                                                 cli_errstr(c));
402                                 correct = False;
403                                 sent = 0;
404                         }
405                         if (sent > 0)
406                         {
407                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
408                                 {
409                                         printf("read/write compare failed\n");
410                                         printf("offset: %d req %d recvd %d\n",
411                                                 count, sizeof(buf)-count, sent);
412                                         correct = False;
413                                         break;
414                                 }
415                         }
416                 }
417
418         }
419
420         if (!cli_close(c, fnum)) {
421                 printf("close failed (%s)\n", cli_errstr(c));
422                 correct = False;
423         }
424
425         return correct;
426 }
427
428 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
429 {
430         char *lockfname = "\\torture2.lck";
431         int fnum1;
432         int fnum2;
433         int i;
434         uchar buf[131072];
435         uchar buf_rd[131072];
436         BOOL correct = True;
437         ssize_t bytes_read;
438
439         if (!cli_unlink(c1, lockfname)) {
440                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
441         }
442
443         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
444                          DENY_NONE);
445         if (fnum1 == -1) {
446                 printf("first open read/write of %s failed (%s)\n",
447                                 lockfname, cli_errstr(c1));
448                 return False;
449         }
450         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
451                          DENY_NONE);
452         if (fnum2 == -1) {
453                 printf("second open read-only of %s failed (%s)\n",
454                                 lockfname, cli_errstr(c2));
455                 cli_close(c1, fnum1);
456                 return False;
457         }
458
459         for (i=0;i<numops;i++)
460         {
461                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
462                 if (i % 10 == 0) {
463                         printf("%d\r", i); fflush(stdout);
464                 }
465
466                 generate_random_buffer(buf, buf_size, False);
467
468                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
469                         printf("write failed (%s)\n", cli_errstr(c1));
470                         correct = False;
471                 }
472
473                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
474                         printf("read failed (%s)\n", cli_errstr(c2));
475                         printf("read %d, expected %d\n", bytes_read, buf_size); 
476                         correct = False;
477                 }
478
479                 if (memcmp(buf_rd, buf, buf_size) != 0)
480                 {
481                         printf("read/write compare failed\n");
482                         correct = False;
483                 }
484         }
485
486         if (!cli_close(c2, fnum2)) {
487                 printf("close failed (%s)\n", cli_errstr(c2));
488                 correct = False;
489         }
490         if (!cli_close(c1, fnum1)) {
491                 printf("close failed (%s)\n", cli_errstr(c1));
492                 correct = False;
493         }
494
495         if (!cli_unlink(c1, lockfname)) {
496                 printf("unlink failed (%s)\n", cli_errstr(c1));
497                 correct = False;
498         }
499
500         return correct;
501 }
502
503 static BOOL run_readwritetest(int dummy)
504 {
505         static struct cli_state cli1, cli2;
506         BOOL test1, test2;
507
508         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
509                 return False;
510         }
511         cli_sockopt(&cli1, sockops);
512         cli_sockopt(&cli2, sockops);
513
514         printf("starting readwritetest\n");
515
516         test1 = rw_torture2(&cli1, &cli2);
517         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
518
519         test2 = rw_torture2(&cli1, &cli1);
520         printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
521
522         if (!torture_close_connection(&cli1)) {
523                 test1 = False;
524         }
525
526         if (!torture_close_connection(&cli2)) {
527                 test2 = False;
528         }
529
530         return (test1 && test2);
531 }
532
533 static BOOL run_readwritemulti(int dummy)
534 {
535         static struct cli_state cli;
536         BOOL test;
537
538         cli = current_cli;
539
540         cli_sockopt(&cli, sockops);
541
542         printf("run_readwritemulti: fname %s\n", randomfname);
543         test = rw_torture3(&cli, randomfname);
544
545         if (!torture_close_connection(&cli)) {
546                 test = False;
547         }
548         
549         return test;
550 }
551
552 static BOOL run_readwritelarge(int dummy)
553 {
554         static struct cli_state cli1;
555         int fnum1;
556         char *lockfname = "\\large.dat";
557         size_t fsize;
558         char buf[0x10000];
559         BOOL correct = True;
560  
561         if (!torture_open_connection(&cli1)) {
562                 return False;
563         }
564         cli_sockopt(&cli1, sockops);
565         memset(buf,'\0',sizeof(buf));
566         
567         cli1.max_xmit = 0x11000;
568         
569         printf("starting readwritelarge\n");
570  
571         cli_unlink(&cli1, lockfname);
572
573         fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
574         if (fnum1 == -1) {
575                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
576                 return False;
577         }
578    
579         cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
580
581         if (!cli_close(&cli1, fnum1)) {
582                 printf("close failed (%s)\n", cli_errstr(&cli1));
583                 correct = False;
584         }
585
586         if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
587                 printf("qpathinfo failed (%s)\n", cli_errstr(&cli1));
588                 correct = False;
589         }
590
591         if (fsize == sizeof(buf))
592                 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
593         else {
594                 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
595                 correct = False;
596         }
597
598         if (!cli_unlink(&cli1, lockfname)) {
599                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
600                 correct = False;
601         }
602
603         fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
604         if (fnum1 == -1) {
605                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
606                 return False;
607         }
608         
609         cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
610         
611         if (!cli_close(&cli1, fnum1)) {
612                 printf("close failed (%s)\n", cli_errstr(&cli1));
613                 correct = False;
614         }
615         
616         if (!torture_close_connection(&cli1)) {
617                 correct = False;
618         }
619         return correct;
620         }
621
622 int line_count = 0;
623 int nbio_id;
624
625 #define ival(s) strtol(s, NULL, 0)
626
627 /* run a test that simulates an approximate netbench client load */
628 static BOOL run_netbench(int client)
629 {
630         struct cli_state cli;
631         int i;
632         fstring fname;
633         pstring line;
634         char cname[20];
635         FILE *f;
636         char *params[20];
637         BOOL correct = True;
638
639         cli = current_cli;
640
641         nbio_id = client;
642
643         cli_sockopt(&cli, sockops);
644
645         nb_setup(&cli);
646
647         slprintf(cname,sizeof(fname), "client%d", client);
648
649         f = fopen(client_txt, "r");
650
651         if (!f) {
652                 perror(client_txt);
653                 return False;
654         }
655
656         while (fgets(line, sizeof(line)-1, f)) {
657                 line_count++;
658
659                 line[strlen(line)-1] = 0;
660
661                 /* printf("[%d] %s\n", line_count, line); */
662
663                 all_string_sub(line,"client1", cname, sizeof(line));
664                 
665                 /* parse the command parameters */
666                 params[0] = strtok(line," ");
667                 i = 0;
668                 while (params[i]) params[++i] = strtok(NULL," ");
669
670                 params[i] = "";
671
672                 if (i < 2) continue;
673
674                 if (!strncmp(params[0],"SMB", 3)) {
675                         printf("ERROR: You are using a dbench 1 load file\n");
676                         exit(1);
677                 }
678
679                 if (!strcmp(params[0],"NTCreateX")) {
680                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
681                                    ival(params[4]));
682                 } else if (!strcmp(params[0],"Close")) {
683                         nb_close(ival(params[1]));
684                 } else if (!strcmp(params[0],"Rename")) {
685                         nb_rename(params[1], params[2]);
686                 } else if (!strcmp(params[0],"Unlink")) {
687                         nb_unlink(params[1]);
688                 } else if (!strcmp(params[0],"Deltree")) {
689                         nb_deltree(params[1]);
690                 } else if (!strcmp(params[0],"Rmdir")) {
691                         nb_rmdir(params[1]);
692                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
693                         nb_qpathinfo(params[1]);
694                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
695                         nb_qfileinfo(ival(params[1]));
696                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
697                         nb_qfsinfo(ival(params[1]));
698                 } else if (!strcmp(params[0],"FIND_FIRST")) {
699                         nb_findfirst(params[1]);
700                 } else if (!strcmp(params[0],"WriteX")) {
701                         nb_writex(ival(params[1]), 
702                                   ival(params[2]), ival(params[3]), ival(params[4]));
703                 } else if (!strcmp(params[0],"ReadX")) {
704                         nb_readx(ival(params[1]), 
705                                   ival(params[2]), ival(params[3]), ival(params[4]));
706                 } else if (!strcmp(params[0],"Flush")) {
707                         nb_flush(ival(params[1]));
708                 } else {
709                         printf("Unknown operation %s\n", params[0]);
710                         exit(1);
711                 }
712         }
713         fclose(f);
714
715         nb_cleanup();
716
717         if (!torture_close_connection(&cli)) {
718                 correct = False;
719         }
720         
721         return correct;
722 }
723
724
725 /* run a test that simulates an approximate netbench client load */
726 static BOOL run_nbench(int dummy)
727 {
728         double t;
729         BOOL correct = True;
730
731         nbio_shmem(nprocs);
732
733         nbio_id = -1;
734
735         signal(SIGALRM, nb_alarm);
736         alarm(1);
737         t = create_procs(run_netbench, &correct);
738         alarm(0);
739
740         printf("\nThroughput %g MB/sec\n", 
741                1.0e-6 * nbio_total() / t);
742         return correct;
743 }
744
745
746 /*
747   This test checks for two things:
748
749   1) correct support for retaining locks over a close (ie. the server
750      must not use posix semantics)
751   2) support for lock timeouts
752  */
753 static BOOL run_locktest1(int dummy)
754 {
755         static struct cli_state cli1, cli2;
756         char *fname = "\\lockt1.lck";
757         int fnum1, fnum2, fnum3;
758         time_t t1, t2;
759
760         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
761                 return False;
762         }
763         cli_sockopt(&cli1, sockops);
764         cli_sockopt(&cli2, sockops);
765
766         printf("starting locktest1\n");
767
768         cli_unlink(&cli1, fname);
769
770         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
771         if (fnum1 == -1) {
772                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
773                 return False;
774         }
775         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
776         if (fnum2 == -1) {
777                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
778                 return False;
779         }
780         fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
781         if (fnum3 == -1) {
782                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
783                 return False;
784         }
785
786         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
787                 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
788                 return False;
789         }
790
791
792         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
793                 printf("lock2 succeeded! This is a locking bug\n");
794                 return False;
795         } else {
796                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
797                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
798         }
799
800
801         printf("Testing lock timeouts\n");
802         t1 = time(NULL);
803         if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
804                 printf("lock3 succeeded! This is a locking bug\n");
805                 return False;
806         } else {
807                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
808                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
809         }
810         t2 = time(NULL);
811
812         if (t2 - t1 < 5) {
813                 printf("error: This server appears not to support timed lock requests\n");
814         }
815
816         if (!cli_close(&cli1, fnum2)) {
817                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
818                 return False;
819         }
820
821         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
822                 printf("lock4 succeeded! This is a locking bug\n");
823                 return False;
824         } else {
825                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
826                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
827         }
828
829         if (!cli_close(&cli1, fnum1)) {
830                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
831                 return False;
832         }
833
834         if (!cli_close(&cli2, fnum3)) {
835                 printf("close3 failed (%s)\n", cli_errstr(&cli2));
836                 return False;
837         }
838
839         if (!cli_unlink(&cli1, fname)) {
840                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
841                 return False;
842         }
843
844
845         if (!torture_close_connection(&cli1)) {
846                 return False;
847         }
848
849         if (!torture_close_connection(&cli2)) {
850                 return False;
851         }
852
853         printf("Passed locktest1\n");
854         return True;
855 }
856
857 /*
858  checks for correct tconX support
859  */
860 static BOOL run_tcon_test(int dummy)
861 {
862         static struct cli_state cli1;
863         char *fname = "\\tcontest.tmp";
864         int fnum1;
865         uint16 cnum;
866         char buf[4];
867
868         if (!torture_open_connection(&cli1)) {
869                 return False;
870         }
871         cli_sockopt(&cli1, sockops);
872
873         printf("starting tcontest\n");
874
875         cli_unlink(&cli1, fname);
876
877         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
878         if (fnum1 == -1)
879         {
880                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
881                 return False;
882         }
883
884         cnum = cli1.cnum;
885
886         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
887         {
888                 printf("write failed (%s)", cli_errstr(&cli1));
889                 return False;
890         }
891
892         if (!cli_send_tconX(&cli1, share, "?????",
893                             password, strlen(password)+1)) {
894                 printf("%s refused 2nd tree connect (%s)\n", host,
895                            cli_errstr(&cli1));
896                 cli_shutdown(&cli1);
897                 return False;
898         }
899
900         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
901         {
902                 printf("write succeeded (%s)", cli_errstr(&cli1));
903                 return False;
904         }
905
906         if (cli_close(&cli1, fnum1)) {
907                 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
908                 return False;
909         }
910
911         if (!cli_tdis(&cli1)) {
912                 printf("tdis failed (%s)\n", cli_errstr(&cli1));
913                 return False;
914         }
915
916         cli1.cnum = cnum;
917
918         if (!cli_close(&cli1, fnum1)) {
919                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
920                 return False;
921         }
922
923         if (!torture_close_connection(&cli1)) {
924                 return False;
925         }
926
927         printf("Passed tcontest\n");
928         return True;
929 }
930
931
932 /*
933   This test checks that 
934
935   1) the server supports multiple locking contexts on the one SMB
936   connection, distinguished by PID.  
937
938   2) the server correctly fails overlapping locks made by the same PID (this
939      goes against POSIX behaviour, which is why it is tricky to implement)
940
941   3) the server denies unlock requests by an incorrect client PID
942 */
943 static BOOL run_locktest2(int dummy)
944 {
945         static struct cli_state cli;
946         char *fname = "\\lockt2.lck";
947         int fnum1, fnum2, fnum3;
948         BOOL correct = True;
949
950         if (!torture_open_connection(&cli)) {
951                 return False;
952         }
953
954         cli_sockopt(&cli, sockops);
955
956         printf("starting locktest2\n");
957
958         cli_unlink(&cli, fname);
959
960         cli_setpid(&cli, 1);
961
962         fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
963         if (fnum1 == -1) {
964                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
965                 return False;
966         }
967
968         fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
969         if (fnum2 == -1) {
970                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
971                 return False;
972         }
973
974         cli_setpid(&cli, 2);
975
976         fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
977         if (fnum3 == -1) {
978                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
979                 return False;
980         }
981
982         cli_setpid(&cli, 1);
983
984         if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
985                 printf("lock1 failed (%s)\n", cli_errstr(&cli));
986                 return False;
987         }
988
989         if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
990                 printf("WRITE lock1 succeeded! This is a locking bug\n");
991                 correct = False;
992         } else {
993                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
994                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
995         }
996
997         if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
998                 printf("WRITE lock2 succeeded! This is a locking bug\n");
999                 correct = False;
1000         } else {
1001                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1002                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1003         }
1004
1005         if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1006                 printf("READ lock2 succeeded! This is a locking bug\n");
1007                 correct = False;
1008         } else {
1009                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1010                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1011         }
1012
1013         if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1014                 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1015         }
1016         cli_setpid(&cli, 2);
1017         if (cli_unlock(&cli, fnum1, 100, 4)) {
1018                 printf("unlock at 100 succeeded! This is a locking bug\n");
1019                 correct = False;
1020         }
1021
1022         if (cli_unlock(&cli, fnum1, 0, 4)) {
1023                 printf("unlock1 succeeded! This is a locking bug\n");
1024                 correct = False;
1025         } else {
1026                 if (!check_error(__LINE__, &cli, 
1027                                  ERRDOS, ERRlock, 
1028                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1029         }
1030
1031         if (cli_unlock(&cli, fnum1, 0, 8)) {
1032                 printf("unlock2 succeeded! This is a locking bug\n");
1033                 correct = False;
1034         } else {
1035                 if (!check_error(__LINE__, &cli, 
1036                                  ERRDOS, ERRlock, 
1037                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1038         }
1039
1040         if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1041                 printf("lock3 succeeded! This is a locking bug\n");
1042                 correct = False;
1043         } else {
1044                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1045         }
1046
1047         cli_setpid(&cli, 1);
1048
1049         if (!cli_close(&cli, fnum1)) {
1050                 printf("close1 failed (%s)\n", cli_errstr(&cli));
1051                 return False;
1052         }
1053
1054         if (!cli_close(&cli, fnum2)) {
1055                 printf("close2 failed (%s)\n", cli_errstr(&cli));
1056                 return False;
1057         }
1058
1059         if (!cli_close(&cli, fnum3)) {
1060                 printf("close3 failed (%s)\n", cli_errstr(&cli));
1061                 return False;
1062         }
1063
1064         if (!torture_close_connection(&cli)) {
1065                 correct = False;
1066         }
1067
1068         printf("locktest2 finished\n");
1069
1070         return correct;
1071 }
1072
1073
1074 /*
1075   This test checks that 
1076
1077   1) the server supports the full offset range in lock requests
1078 */
1079 static BOOL run_locktest3(int dummy)
1080 {
1081         static struct cli_state cli1, cli2;
1082         char *fname = "\\lockt3.lck";
1083         int fnum1, fnum2, i;
1084         uint32 offset;
1085         BOOL correct = True;
1086
1087 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1088
1089         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1090                 return False;
1091         }
1092         cli_sockopt(&cli1, sockops);
1093         cli_sockopt(&cli2, sockops);
1094
1095         printf("starting locktest3\n");
1096
1097         cli_unlink(&cli1, fname);
1098
1099         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1100         if (fnum1 == -1) {
1101                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1102                 return False;
1103         }
1104         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1105         if (fnum2 == -1) {
1106                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1107                 return False;
1108         }
1109
1110         for (offset=i=0;i<numops;i++) {
1111                 NEXT_OFFSET;
1112                 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1113                         printf("lock1 %d failed (%s)\n", 
1114                                i,
1115                                cli_errstr(&cli1));
1116                         return False;
1117                 }
1118
1119                 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1120                         printf("lock2 %d failed (%s)\n", 
1121                                i,
1122                                cli_errstr(&cli1));
1123                         return False;
1124                 }
1125         }
1126
1127         for (offset=i=0;i<numops;i++) {
1128                 NEXT_OFFSET;
1129
1130                 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1131                         printf("error: lock1 %d succeeded!\n", i);
1132                         return False;
1133                 }
1134
1135                 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1136                         printf("error: lock2 %d succeeded!\n", i);
1137                         return False;
1138                 }
1139
1140                 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1141                         printf("error: lock3 %d succeeded!\n", i);
1142                         return False;
1143                 }
1144
1145                 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1146                         printf("error: lock4 %d succeeded!\n", i);
1147                         return False;
1148                 }
1149         }
1150
1151         for (offset=i=0;i<numops;i++) {
1152                 NEXT_OFFSET;
1153
1154                 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1155                         printf("unlock1 %d failed (%s)\n", 
1156                                i,
1157                                cli_errstr(&cli1));
1158                         return False;
1159                 }
1160
1161                 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1162                         printf("unlock2 %d failed (%s)\n", 
1163                                i,
1164                                cli_errstr(&cli1));
1165                         return False;
1166                 }
1167         }
1168
1169         if (!cli_close(&cli1, fnum1)) {
1170                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1171                 return False;
1172         }
1173
1174         if (!cli_close(&cli2, fnum2)) {
1175                 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1176                 return False;
1177         }
1178
1179         if (!cli_unlink(&cli1, fname)) {
1180                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1181                 return False;
1182         }
1183
1184         if (!torture_close_connection(&cli1)) {
1185                 correct = False;
1186         }
1187         
1188         if (!torture_close_connection(&cli2)) {
1189                 correct = False;
1190         }
1191
1192         printf("finished locktest3\n");
1193
1194         return correct;
1195 }
1196
1197 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1198         printf("** "); correct = False; \
1199         }
1200
1201 /*
1202   looks at overlapping locks
1203 */
1204 static BOOL run_locktest4(int dummy)
1205 {
1206         static struct cli_state cli1, cli2;
1207         char *fname = "\\lockt4.lck";
1208         int fnum1, fnum2, f;
1209         BOOL ret;
1210         char buf[1000];
1211         BOOL correct = True;
1212
1213         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1214                 return False;
1215         }
1216
1217         cli_sockopt(&cli1, sockops);
1218         cli_sockopt(&cli2, sockops);
1219
1220         printf("starting locktest4\n");
1221
1222         cli_unlink(&cli1, fname);
1223
1224         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1225         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1226
1227         memset(buf, 0, sizeof(buf));
1228
1229         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1230                 printf("Failed to create file\n");
1231                 correct = False;
1232                 goto fail;
1233         }
1234
1235         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1236               cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1237         EXPECTED(ret, False);
1238         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1239             
1240         ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1241               cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1242         EXPECTED(ret, True);
1243         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1244
1245         ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1246               cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1247         EXPECTED(ret, False);
1248         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1249             
1250         ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1251               cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1252         EXPECTED(ret, True);
1253         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1254         
1255         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1256               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1257         EXPECTED(ret, False);
1258         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1259             
1260         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1261               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1262         EXPECTED(ret, True);
1263         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1264
1265         ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1266               cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1267         EXPECTED(ret, True);
1268         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1269
1270         ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1271               cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1272         EXPECTED(ret, False);
1273         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1274
1275         ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1276               cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1277         EXPECTED(ret, False);
1278         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1279
1280         ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1281               cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1282         EXPECTED(ret, True);
1283         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1284
1285         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1286               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1287         EXPECTED(ret, False);
1288         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1289
1290         ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1291               cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1292               cli_unlock(&cli1, fnum1, 110, 6);
1293         EXPECTED(ret, False);
1294         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1295
1296
1297         ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1298               (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1299         EXPECTED(ret, False);
1300         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1301
1302         ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1303               (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1304         EXPECTED(ret, False);
1305         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1306
1307
1308         ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1309               cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1310               cli_unlock(&cli1, fnum1, 140, 4) &&
1311               cli_unlock(&cli1, fnum1, 140, 4);
1312         EXPECTED(ret, True);
1313         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1314
1315
1316         ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1317               cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1318               cli_unlock(&cli1, fnum1, 150, 4) &&
1319               (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1320               !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1321               cli_unlock(&cli1, fnum1, 150, 4);
1322         EXPECTED(ret, True);
1323         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1324
1325         ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1326               cli_unlock(&cli1, fnum1, 160, 4) &&
1327               (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&         
1328               (cli_read(&cli2, fnum2, buf, 160, 4) == 4);               
1329         EXPECTED(ret, True);
1330         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1331
1332         ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1333               cli_unlock(&cli1, fnum1, 170, 4) &&
1334               (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&         
1335               (cli_read(&cli2, fnum2, buf, 170, 4) == 4);               
1336         EXPECTED(ret, True);
1337         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1338
1339         ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1340               cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1341               cli_unlock(&cli1, fnum1, 190, 4) &&
1342               !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&                
1343               (cli_read(&cli2, fnum2, buf, 190, 4) == 4);               
1344         EXPECTED(ret, True);
1345         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1346
1347         cli_close(&cli1, fnum1);
1348         cli_close(&cli2, fnum2);
1349         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1350         f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1351         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1352               cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1353               cli_close(&cli1, fnum1) &&
1354               ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1355               cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1356         cli_close(&cli1, f);
1357         cli_close(&cli1, fnum1);
1358         EXPECTED(ret, True);
1359         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1360
1361  fail:
1362         cli_close(&cli1, fnum1);
1363         cli_close(&cli2, fnum2);
1364         cli_unlink(&cli1, fname);
1365         torture_close_connection(&cli1);
1366         torture_close_connection(&cli2);
1367
1368         printf("finished locktest4\n");
1369         return correct;
1370 }
1371
1372 /*
1373   looks at lock upgrade/downgrade.
1374 */
1375 static BOOL run_locktest5(int dummy)
1376 {
1377         static struct cli_state cli1, cli2;
1378         char *fname = "\\lockt5.lck";
1379         int fnum1, fnum2, fnum3;
1380         BOOL ret;
1381         char buf[1000];
1382         BOOL correct = True;
1383
1384         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1385                 return False;
1386         }
1387
1388         cli_sockopt(&cli1, sockops);
1389         cli_sockopt(&cli2, sockops);
1390
1391         printf("starting locktest5\n");
1392
1393         cli_unlink(&cli1, fname);
1394
1395         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1396         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1397         fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1398
1399         memset(buf, 0, sizeof(buf));
1400
1401         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1402                 printf("Failed to create file\n");
1403                 correct = False;
1404                 goto fail;
1405         }
1406
1407         /* Check for NT bug... */
1408         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1409                   cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1410         cli_close(&cli1, fnum1);
1411         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1412         ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1413         EXPECTED(ret, True);
1414         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1415         cli_close(&cli1, fnum1);
1416         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1417         cli_unlock(&cli1, fnum3, 0, 1);
1418
1419         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1420               cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1421         EXPECTED(ret, True);
1422         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1423
1424         ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1425         EXPECTED(ret, False);
1426
1427         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1428
1429         /* Unlock the process 2 lock. */
1430         cli_unlock(&cli2, fnum2, 0, 4);
1431
1432         ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1433         EXPECTED(ret, False);
1434
1435         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1436
1437         /* Unlock the process 1 fnum3 lock. */
1438         cli_unlock(&cli1, fnum3, 0, 4);
1439
1440         /* Stack 2 more locks here. */
1441         ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1442                   cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1443
1444         EXPECTED(ret, True);
1445         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1446
1447         /* Unlock the first process lock, then check this was the WRITE lock that was
1448                 removed. */
1449
1450         ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1451                         cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1452
1453         EXPECTED(ret, True);
1454         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1455
1456         /* Unlock the process 2 lock. */
1457         cli_unlock(&cli2, fnum2, 0, 4);
1458
1459         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1460
1461         ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1462                   cli_unlock(&cli1, fnum1, 0, 4) &&
1463                   cli_unlock(&cli1, fnum1, 0, 4);
1464
1465         EXPECTED(ret, True);
1466         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1467
1468         /* Ensure the next unlock fails. */
1469         ret = cli_unlock(&cli1, fnum1, 0, 4);
1470         EXPECTED(ret, False);
1471         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1472
1473         /* Ensure connection 2 can get a write lock. */
1474         ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1475         EXPECTED(ret, True);
1476
1477         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1478
1479
1480  fail:
1481         cli_close(&cli1, fnum1);
1482         cli_close(&cli2, fnum2);
1483         cli_unlink(&cli1, fname);
1484         if (!torture_close_connection(&cli1)) {
1485                 correct = False;
1486         }
1487         if (!torture_close_connection(&cli2)) {
1488                 correct = False;
1489         }
1490
1491         printf("finished locktest5\n");
1492        
1493         return correct;
1494 }
1495
1496 /*
1497   tries the unusual lockingX locktype bits
1498 */
1499 static BOOL run_locktest6(int dummy)
1500 {
1501         static struct cli_state cli;
1502         char *fname[1] = { "\\lock6.txt" };
1503         int i;
1504         int fnum;
1505         NTSTATUS status;
1506
1507         if (!torture_open_connection(&cli)) {
1508                 return False;
1509         }
1510
1511         cli_sockopt(&cli, sockops);
1512
1513         printf("starting locktest6\n");
1514
1515         for (i=0;i<1;i++) {
1516                 printf("Testing %s\n", fname[i]);
1517
1518                 cli_unlink(&cli, fname[i]);
1519
1520                 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1521                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1522                 cli_close(&cli, fnum);
1523                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1524
1525                 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1526                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1527                 cli_close(&cli, fnum);
1528                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1529
1530                 cli_unlink(&cli, fname[i]);
1531         }
1532
1533         torture_close_connection(&cli);
1534
1535         printf("finished locktest6\n");
1536         return True;
1537 }
1538
1539 /*
1540 test whether fnums and tids open on one VC are available on another (a major
1541 security hole)
1542 */
1543 static BOOL run_fdpasstest(int dummy)
1544 {
1545         static struct cli_state cli1, cli2, cli3;
1546         char *fname = "\\fdpass.tst";
1547         int fnum1;
1548         pstring buf;
1549
1550         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1551                 return False;
1552         }
1553         cli_sockopt(&cli1, sockops);
1554         cli_sockopt(&cli2, sockops);
1555
1556         printf("starting fdpasstest\n");
1557
1558         cli_unlink(&cli1, fname);
1559
1560         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1561         if (fnum1 == -1) {
1562                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1563                 return False;
1564         }
1565
1566         if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1567                 printf("write failed (%s)\n", cli_errstr(&cli1));
1568                 return False;
1569         }
1570
1571         cli3 = cli2;
1572         cli3.vuid = cli1.vuid;
1573         cli3.cnum = cli1.cnum;
1574         cli3.pid = cli1.pid;
1575
1576         if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1577                 printf("read succeeded! nasty security hole [%s]\n",
1578                        buf);
1579                 return False;
1580         }
1581
1582         cli_close(&cli1, fnum1);
1583         cli_unlink(&cli1, fname);
1584
1585         torture_close_connection(&cli1);
1586         torture_close_connection(&cli2);
1587
1588         printf("finished fdpasstest\n");
1589         return True;
1590 }
1591
1592
1593 /*
1594   This test checks that 
1595
1596   1) the server does not allow an unlink on a file that is open
1597 */
1598 static BOOL run_unlinktest(int dummy)
1599 {
1600         static struct cli_state cli;
1601         char *fname = "\\unlink.tst";
1602         int fnum;
1603         BOOL correct = True;
1604
1605         if (!torture_open_connection(&cli)) {
1606                 return False;
1607         }
1608
1609         cli_sockopt(&cli, sockops);
1610
1611         printf("starting unlink test\n");
1612
1613         cli_unlink(&cli, fname);
1614
1615         cli_setpid(&cli, 1);
1616
1617         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1618         if (fnum == -1) {
1619                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1620                 return False;
1621         }
1622
1623         if (cli_unlink(&cli, fname)) {
1624                 printf("error: server allowed unlink on an open file\n");
1625                 correct = False;
1626         } else {
1627                 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare, 
1628                                       NT_STATUS_SHARING_VIOLATION);
1629         }
1630
1631         cli_close(&cli, fnum);
1632         cli_unlink(&cli, fname);
1633
1634         if (!torture_close_connection(&cli)) {
1635                 correct = False;
1636         }
1637
1638         printf("unlink test finished\n");
1639         
1640         return correct;
1641 }
1642
1643
1644 /*
1645 test how many open files this server supports on the one socket
1646 */
1647 static BOOL run_maxfidtest(int dummy)
1648 {
1649         static struct cli_state cli;
1650         char *template = "\\maxfid.%d.%d";
1651         fstring fname;
1652         int fnums[0x11000], i;
1653         int retries=4;
1654         BOOL correct = True;
1655
1656         cli = current_cli;
1657
1658         if (retries <= 0) {
1659                 printf("failed to connect\n");
1660                 return False;
1661         }
1662
1663         cli_sockopt(&cli, sockops);
1664
1665         for (i=0; i<0x11000; i++) {
1666                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1667                 if ((fnums[i] = cli_open(&cli, fname, 
1668                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1669                     -1) {
1670                         printf("open of %s failed (%s)\n", 
1671                                fname, cli_errstr(&cli));
1672                         printf("maximum fnum is %d\n", i);
1673                         break;
1674                 }
1675                 printf("%6d\r", i);
1676         }
1677         printf("%6d\n", i);
1678         i--;
1679
1680         printf("cleaning up\n");
1681         for (;i>=0;i--) {
1682                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1683                 cli_close(&cli, fnums[i]);
1684                 if (!cli_unlink(&cli, fname)) {
1685                         printf("unlink of %s failed (%s)\n", 
1686                                fname, cli_errstr(&cli));
1687                         correct = False;
1688                 }
1689                 printf("%6d\r", i);
1690         }
1691         printf("%6d\n", 0);
1692
1693         printf("maxfid test finished\n");
1694         if (!torture_close_connection(&cli)) {
1695                 correct = False;
1696         }
1697         return correct;
1698 }
1699
1700 /* generate a random buffer */
1701 static void rand_buf(char *buf, int len)
1702 {
1703         while (len--) {
1704                 *buf = (char)sys_random();
1705                 buf++;
1706         }
1707 }
1708
1709 /* send smb negprot commands, not reading the response */
1710 static BOOL run_negprot_nowait(int dummy)
1711 {
1712         int i;
1713         static struct cli_state cli;
1714         BOOL correct = True;
1715
1716         printf("starting negprot nowait test\n");
1717
1718         if (!open_nbt_connection(&cli)) {
1719                 return False;
1720         }
1721
1722         for (i=0;i<50000;i++) {
1723                 cli_negprot_send(&cli);
1724         }
1725
1726         if (!torture_close_connection(&cli)) {
1727                 correct = False;
1728         }
1729
1730         printf("finished negprot nowait test\n");
1731
1732         return correct;
1733 }
1734
1735
1736 /* send random IPC commands */
1737 static BOOL run_randomipc(int dummy)
1738 {
1739         char *rparam = NULL;
1740         char *rdata = NULL;
1741         int rdrcnt,rprcnt;
1742         pstring param;
1743         int api, param_len, i;
1744         static struct cli_state cli;
1745         BOOL correct = True;
1746         int count = 50000;
1747
1748         printf("starting random ipc test\n");
1749
1750         if (!torture_open_connection(&cli)) {
1751                 return False;
1752         }
1753
1754         for (i=0;i<count;i++) {
1755                 api = sys_random() % 500;
1756                 param_len = (sys_random() % 64);
1757
1758                 rand_buf(param, param_len);
1759   
1760                 SSVAL(param,0,api); 
1761
1762                 cli_api(&cli, 
1763                         param, param_len, 8,  
1764                         NULL, 0, BUFFER_SIZE, 
1765                         &rparam, &rprcnt,     
1766                         &rdata, &rdrcnt);
1767                 if (i % 100 == 0) {
1768                         printf("%d/%d\r", i,count);
1769                 }
1770         }
1771         printf("%d/%d\n", i, count);
1772
1773         if (!torture_close_connection(&cli)) {
1774                 correct = False;
1775         }
1776
1777         printf("finished random ipc test\n");
1778
1779         return correct;
1780 }
1781
1782
1783
1784 static void browse_callback(const char *sname, uint32 stype, 
1785                             const char *comment, void *state)
1786 {
1787         printf("\t%20.20s %08x %s\n", sname, stype, comment);
1788 }
1789
1790
1791
1792 /*
1793   This test checks the browse list code
1794
1795 */
1796 static BOOL run_browsetest(int dummy)
1797 {
1798         static struct cli_state cli;
1799         BOOL correct = True;
1800
1801         printf("starting browse test\n");
1802
1803         if (!torture_open_connection(&cli)) {
1804                 return False;
1805         }
1806
1807         printf("domain list:\n");
1808         cli_NetServerEnum(&cli, cli.server_domain, 
1809                           SV_TYPE_DOMAIN_ENUM,
1810                           browse_callback, NULL);
1811
1812         printf("machine list:\n");
1813         cli_NetServerEnum(&cli, cli.server_domain, 
1814                           SV_TYPE_ALL,
1815                           browse_callback, NULL);
1816
1817         if (!torture_close_connection(&cli)) {
1818                 correct = False;
1819         }
1820
1821         printf("browse test finished\n");
1822
1823         return correct;
1824
1825 }
1826
1827
1828 /*
1829   This checks how the getatr calls works
1830 */
1831 static BOOL run_attrtest(int dummy)
1832 {
1833         static struct cli_state cli;
1834         int fnum;
1835         time_t t, t2;
1836         char *fname = "\\attrib.tst";
1837         BOOL correct = True;
1838
1839         printf("starting attrib test\n");
1840
1841         if (!torture_open_connection(&cli)) {
1842                 return False;
1843         }
1844
1845         cli_unlink(&cli, fname);
1846         fnum = cli_open(&cli, fname, 
1847                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1848         cli_close(&cli, fnum);
1849         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1850                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1851                 correct = False;
1852         }
1853
1854         if (abs(t - time(NULL)) > 60*60*24*10) {
1855                 printf("ERROR: SMBgetatr bug. time is %s",
1856                        ctime(&t));
1857                 t = time(NULL);
1858                 correct = True;
1859         }
1860
1861         t2 = t-60*60*24; /* 1 day ago */
1862
1863         if (!cli_setatr(&cli, fname, 0, t2)) {
1864                 printf("setatr failed (%s)\n", cli_errstr(&cli));
1865                 correct = True;
1866         }
1867
1868         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1869                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1870                 correct = True;
1871         }
1872
1873         if (t != t2) {
1874                 printf("ERROR: getatr/setatr bug. times are\n%s",
1875                        ctime(&t));
1876                 printf("%s", ctime(&t2));
1877                 correct = True;
1878         }
1879
1880         cli_unlink(&cli, fname);
1881
1882         if (!torture_close_connection(&cli)) {
1883                 correct = False;
1884         }
1885
1886         printf("attrib test finished\n");
1887
1888         return correct;
1889 }
1890
1891
1892 /*
1893   This checks a couple of trans2 calls
1894 */
1895 static BOOL run_trans2test(int dummy)
1896 {
1897         static struct cli_state cli;
1898         int fnum;
1899         size_t size;
1900         time_t c_time, a_time, m_time, w_time, m_time2;
1901         char *fname = "\\trans2.tst";
1902         char *dname = "\\trans2";
1903         char *fname2 = "\\trans2\\trans2.tst";
1904         pstring pname;
1905         BOOL correct = True;
1906
1907         printf("starting trans2 test\n");
1908
1909         if (!torture_open_connection(&cli)) {
1910                 return False;
1911         }
1912
1913         cli_unlink(&cli, fname);
1914         fnum = cli_open(&cli, fname, 
1915                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1916         if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1917                            NULL, NULL)) {
1918                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1919                 correct = False;
1920         }
1921
1922         if (!cli_qfilename(&cli, fnum, pname)) {
1923                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
1924                 correct = False;
1925         }
1926
1927         if (strcmp(pname, fname)) {
1928                 printf("qfilename gave different name? [%s] [%s]\n",
1929                        fname, pname);
1930                 correct = False;
1931         }
1932
1933         cli_close(&cli, fnum);
1934
1935         sleep(2);
1936
1937         cli_unlink(&cli, fname);
1938         fnum = cli_open(&cli, fname, 
1939                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1940         if (fnum == -1) {
1941                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1942                 return False;
1943         }
1944         cli_close(&cli, fnum);
1945
1946         if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1947                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1948                 correct = False;
1949         } else {
1950                 if (c_time != m_time) {
1951                         printf("create time=%s", ctime(&c_time));
1952                         printf("modify time=%s", ctime(&m_time));
1953                         printf("This system appears to have sticky create times\n");
1954                         correct = False;
1955                 }
1956                 if (a_time % (60*60) == 0) {
1957                         printf("access time=%s", ctime(&a_time));
1958                         printf("This system appears to set a midnight access time\n");
1959                         correct = False;
1960                 }
1961
1962                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1963                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1964                         correct = False;
1965                 }
1966         }
1967
1968
1969         cli_unlink(&cli, fname);
1970         fnum = cli_open(&cli, fname, 
1971                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1972         cli_close(&cli, fnum);
1973         if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
1974                             &w_time, &size, NULL, NULL)) {
1975                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1976                 correct = False;
1977         } else {
1978                 if (w_time < 60*60*24*2) {
1979                         printf("write time=%s", ctime(&w_time));
1980                         printf("This system appears to set a initial 0 write time\n");
1981                         correct = False;
1982                 }
1983         }
1984
1985         cli_unlink(&cli, fname);
1986
1987
1988         /* check if the server updates the directory modification time
1989            when creating a new file */
1990         if (!cli_mkdir(&cli, dname)) {
1991                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
1992                 correct = False;
1993         }
1994         sleep(3);
1995         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
1996                             &w_time, &size, NULL, NULL)) {
1997                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1998                 correct = False;
1999         }
2000
2001         fnum = cli_open(&cli, fname2, 
2002                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2003         cli_write(&cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2004         cli_close(&cli, fnum);
2005         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
2006                             &w_time, &size, NULL, NULL)) {
2007                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2008                 correct = False;
2009         } else {
2010                 if (m_time2 == m_time) {
2011                         printf("This system does not update directory modification times\n");
2012                         correct = False;
2013                 }
2014         }
2015         cli_unlink(&cli, fname2);
2016         cli_rmdir(&cli, dname);
2017
2018         if (!torture_close_connection(&cli)) {
2019                 correct = False;
2020         }
2021
2022         printf("trans2 test finished\n");
2023
2024         return correct;
2025 }
2026
2027 /*
2028   This checks new W2K calls.
2029 */
2030
2031 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2032 {
2033         char buf[4096];
2034         BOOL correct = True;
2035
2036         memset(buf, 0xff, sizeof(buf));
2037
2038         if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2039                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2040                 correct = False;
2041         } else {
2042                 printf("qfileinfo: level %d\n", level);
2043                 dump_data(0, buf, 256);
2044                 printf("\n");
2045         }
2046         return correct;
2047 }
2048
2049 static BOOL run_w2ktest(int dummy)
2050 {
2051         static struct cli_state cli;
2052         int fnum;
2053         char *fname = "\\w2ktest\\w2k.tst";
2054         int level;
2055         BOOL correct = True;
2056
2057         printf("starting w2k test\n");
2058
2059         if (!torture_open_connection(&cli)) {
2060                 return False;
2061         }
2062
2063         fnum = cli_open(&cli, fname, 
2064                         O_RDWR | O_CREAT , DENY_NONE);
2065
2066         for (level = 1004; level < 1040; level++) {
2067                 new_trans(&cli, fnum, level);
2068         }
2069
2070         cli_close(&cli, fnum);
2071
2072         if (!torture_close_connection(&cli)) {
2073                 correct = False;
2074         }
2075
2076         printf("w2k test finished\n");
2077         
2078         return correct;
2079 }
2080
2081
2082 /*
2083   this is a harness for some oplock tests
2084  */
2085 static BOOL run_oplock1(int dummy)
2086 {
2087         static struct cli_state cli1;
2088         char *fname = "\\lockt1.lck";
2089         int fnum1;
2090         BOOL correct = True;
2091
2092         printf("starting oplock test 1\n");
2093
2094         if (!torture_open_connection(&cli1)) {
2095                 return False;
2096         }
2097
2098         cli_unlink(&cli1, fname);
2099
2100         cli_sockopt(&cli1, sockops);
2101
2102         cli1.use_oplocks = True;
2103
2104         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2105         if (fnum1 == -1) {
2106                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2107                 return False;
2108         }
2109
2110         cli1.use_oplocks = False;
2111
2112         cli_unlink(&cli1, fname);
2113         cli_unlink(&cli1, fname);
2114
2115         if (!cli_close(&cli1, fnum1)) {
2116                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2117                 return False;
2118         }
2119
2120         if (!cli_unlink(&cli1, fname)) {
2121                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2122                 return False;
2123         }
2124
2125         if (!torture_close_connection(&cli1)) {
2126                 correct = False;
2127         }
2128
2129         printf("finished oplock test 1\n");
2130
2131         return correct;
2132 }
2133
2134 static BOOL run_oplock2(int dummy)
2135 {
2136         static struct cli_state cli1, cli2;
2137         char *fname = "\\lockt2.lck";
2138         int fnum1, fnum2;
2139         int saved_use_oplocks = use_oplocks;
2140         char buf[4];
2141         BOOL correct = True;
2142         volatile BOOL *shared_correct;
2143
2144         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2145         *shared_correct = True;
2146
2147         use_level_II_oplocks = True;
2148         use_oplocks = True;
2149
2150         printf("starting oplock test 2\n");
2151
2152         if (!torture_open_connection(&cli1)) {
2153                 use_level_II_oplocks = False;
2154                 use_oplocks = saved_use_oplocks;
2155                 return False;
2156         }
2157
2158         cli1.use_oplocks = True;
2159         cli1.use_level_II_oplocks = True;
2160
2161         if (!torture_open_connection(&cli2)) {
2162                 use_level_II_oplocks = False;
2163                 use_oplocks = saved_use_oplocks;
2164                 return False;
2165         }
2166
2167         cli2.use_oplocks = True;
2168         cli2.use_level_II_oplocks = True;
2169
2170         cli_unlink(&cli1, fname);
2171
2172         cli_sockopt(&cli1, sockops);
2173         cli_sockopt(&cli2, sockops);
2174
2175         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2176         if (fnum1 == -1) {
2177                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2178                 return False;
2179         }
2180
2181         /* Don't need the globals any more. */
2182         use_level_II_oplocks = False;
2183         use_oplocks = saved_use_oplocks;
2184
2185         if (fork() == 0) {
2186                 /* Child code */
2187                 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2188                 if (fnum2 == -1) {
2189                         printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2190                         *shared_correct = False;
2191                         exit(0);
2192                 }
2193
2194                 sleep(2);
2195
2196                 if (!cli_close(&cli2, fnum2)) {
2197                         printf("close2 failed (%s)\n", cli_errstr(&cli1));
2198                         *shared_correct = False;
2199                 }
2200
2201                 exit(0);
2202         }
2203
2204         sleep(2);
2205
2206         /* Ensure cli1 processes the break. */
2207
2208         if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2209                 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2210                 correct = False;
2211         }
2212
2213         /* Should now be at level II. */
2214         /* Test if sending a write locks causes a break to none. */
2215
2216         if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2217                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2218                 correct = False;
2219         }
2220
2221         cli_unlock(&cli1, fnum1, 0, 4);
2222
2223         sleep(2);
2224
2225         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2226                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2227                 correct = False;
2228         }
2229
2230         cli_unlock(&cli1, fnum1, 0, 4);
2231
2232         sleep(2);
2233
2234         cli_read(&cli1, fnum1, buf, 0, 4);
2235
2236 #if 0
2237         if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2238                 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2239                 correct = False;
2240         }
2241 #endif
2242
2243         if (!cli_close(&cli1, fnum1)) {
2244                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2245                 correct = False;
2246         }
2247
2248         sleep(4);
2249
2250         if (!cli_unlink(&cli1, fname)) {
2251                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2252                 correct = False;
2253         }
2254
2255         if (!torture_close_connection(&cli1)) {
2256                 correct = False;
2257         }
2258
2259         if (!*shared_correct) {
2260                 correct = False;
2261         }
2262
2263         printf("finished oplock test 2\n");
2264
2265         return correct;
2266 }
2267
2268 /* handler for oplock 3 tests */
2269 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2270 {
2271         printf("got oplock break fnum=%d level=%d\n",
2272                fnum, level);
2273         return cli_oplock_ack(cli, fnum, level);
2274 }
2275
2276 static BOOL run_oplock3(int dummy)
2277 {
2278         static struct cli_state cli;
2279         char *fname = "\\oplockt3.dat";
2280         int fnum;
2281         char buf[4] = "abcd";
2282         BOOL correct = True;
2283         volatile BOOL *shared_correct;
2284
2285         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2286         *shared_correct = True;
2287
2288         printf("starting oplock test 3\n");
2289
2290         if (fork() == 0) {
2291                 /* Child code */
2292                 use_oplocks = True;
2293                 use_level_II_oplocks = True;
2294                 if (!torture_open_connection(&cli)) {
2295                         *shared_correct = False;
2296                         exit(0);
2297                 } 
2298                 sleep(2);
2299                 /* try to trigger a oplock break in parent */
2300                 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2301                 cli_write(&cli, fnum, 0, buf, 0, 4);
2302                 exit(0);
2303         }
2304
2305         /* parent code */
2306         use_oplocks = True;
2307         use_level_II_oplocks = True;
2308         if (!torture_open_connection(&cli)) { 
2309                 return False;
2310         }
2311         cli_oplock_handler(&cli, oplock3_handler);
2312         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2313         cli_write(&cli, fnum, 0, buf, 0, 4);
2314         cli_close(&cli, fnum);
2315         fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2316         cli.timeout = 20000;
2317         cli_receive_smb(&cli);
2318         printf("finished oplock test 3\n");
2319
2320         return (correct && *shared_correct);
2321
2322 /* What are we looking for here?  What's sucess and what's FAILURE? */
2323 }
2324
2325
2326
2327 /*
2328   Test delete on close semantics.
2329  */
2330 static BOOL run_deletetest(int dummy)
2331 {
2332         static struct cli_state cli1;
2333         static struct cli_state cli2;
2334         char *fname = "\\delete.file";
2335         int fnum1 = -1;
2336         int fnum2 = -1;
2337         BOOL correct = True;
2338         
2339         printf("starting delete test\n");
2340         
2341         ZERO_STRUCT(cli1);
2342         ZERO_STRUCT(cli2);
2343
2344         if (!torture_open_connection(&cli1)) {
2345                 return False;
2346         }
2347         
2348         cli_sockopt(&cli1, sockops);
2349
2350         /* Test 1 - this should *NOT* delete the file on close. */
2351         
2352         cli_setatr(&cli1, fname, 0, 0);
2353         cli_unlink(&cli1, fname);
2354         
2355         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2356                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
2357                                    DELETE_ON_CLOSE_FLAG);
2358         
2359         if (fnum1 == -1) {
2360                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2361                 correct = False;
2362                 goto fail;
2363         }
2364         
2365         if (!cli_close(&cli1, fnum1)) {
2366                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2367                 correct = False;
2368                 goto fail;
2369         }
2370
2371         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2372         if (fnum1 == -1) {
2373                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2374                 correct = False;
2375                 goto fail;
2376         }
2377         
2378         if (!cli_close(&cli1, fnum1)) {
2379                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2380                 correct = False;
2381                 goto fail;
2382         }
2383         
2384         printf("first delete on close test succeeded.\n");
2385         
2386         /* Test 2 - this should delete the file on close. */
2387         
2388         cli_setatr(&cli1, fname, 0, 0);
2389         cli_unlink(&cli1, fname);
2390         
2391         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2392                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2393                                    FILE_OVERWRITE_IF, 0);
2394         
2395         if (fnum1 == -1) {
2396                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2397                 correct = False;
2398                 goto fail;
2399         }
2400         
2401         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2402                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2403                 correct = False;
2404                 goto fail;
2405         }
2406         
2407         if (!cli_close(&cli1, fnum1)) {
2408                 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2409                 correct = False;
2410                 goto fail;
2411         }
2412         
2413         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2414         if (fnum1 != -1) {
2415                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2416                 if (!cli_close(&cli1, fnum1)) {
2417                         printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2418                         correct = False;
2419                         goto fail;
2420                 }
2421                 cli_unlink(&cli1, fname);
2422         } else
2423                 printf("second delete on close test succeeded.\n");
2424         
2425         /* Test 3 - ... */
2426         cli_setatr(&cli1, fname, 0, 0);
2427         cli_unlink(&cli1, fname);
2428
2429         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2430                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2431
2432         if (fnum1 == -1) {
2433                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2434                 correct = False;
2435                 goto fail;
2436         }
2437
2438         /* This should fail with a sharing violation - open for delete is only compatible
2439            with SHARE_DELETE. */
2440
2441         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2442                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2443
2444         if (fnum2 != -1) {
2445                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2446                 correct = False;
2447                 goto fail;
2448         }
2449
2450         /* This should succeed. */
2451
2452         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2453                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2454
2455         if (fnum2 == -1) {
2456                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2457                 correct = False;
2458                 goto fail;
2459         }
2460
2461         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2462                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2463                 correct = False;
2464                 goto fail;
2465         }
2466         
2467         if (!cli_close(&cli1, fnum1)) {
2468                 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2469                 correct = False;
2470                 goto fail;
2471         }
2472         
2473         if (!cli_close(&cli1, fnum2)) {
2474                 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2475                 correct = False;
2476                 goto fail;
2477         }
2478         
2479         /* This should fail - file should no longer be there. */
2480
2481         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2482         if (fnum1 != -1) {
2483                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2484                 if (!cli_close(&cli1, fnum1)) {
2485                         printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2486                 }
2487                 cli_unlink(&cli1, fname);
2488                 correct = False;
2489                 goto fail;
2490         } else
2491                 printf("third delete on close test succeeded.\n");
2492
2493         /* Test 4 ... */
2494         cli_setatr(&cli1, fname, 0, 0);
2495         cli_unlink(&cli1, fname);
2496
2497         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2498                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2499                                                                 
2500         if (fnum1 == -1) {
2501                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2502                 correct = False;
2503                 goto fail;
2504         }
2505
2506         /* This should succeed. */
2507         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2508                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2509         if (fnum2 == -1) {
2510                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2511                 correct = False;
2512                 goto fail;
2513         }
2514         
2515         if (!cli_close(&cli1, fnum2)) {
2516                 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2517                 correct = False;
2518                 goto fail;
2519         }
2520         
2521         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2522                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2523                 correct = False;
2524                 goto fail;
2525         }
2526         
2527         /* This should fail - no more opens once delete on close set. */
2528         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2529                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2530         if (fnum2 != -1) {
2531                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2532                 correct = False;
2533                 goto fail;
2534         } else
2535                 printf("fourth delete on close test succeeded.\n");
2536         
2537         if (!cli_close(&cli1, fnum1)) {
2538                 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2539                 correct = False;
2540                 goto fail;
2541         }
2542         
2543         /* Test 5 ... */
2544         cli_setatr(&cli1, fname, 0, 0);
2545         cli_unlink(&cli1, fname);
2546         
2547         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2548         if (fnum1 == -1) {
2549                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2550                 correct = False;
2551                 goto fail;
2552         }
2553
2554         /* This should fail - only allowed on NT opens with DELETE access. */
2555
2556         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2557                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2558                 correct = False;
2559                 goto fail;
2560         }
2561
2562         if (!cli_close(&cli1, fnum1)) {
2563                 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2564                 correct = False;
2565                 goto fail;
2566         }
2567         
2568         printf("fifth delete on close test succeeded.\n");
2569         
2570         /* Test 6 ... */
2571         cli_setatr(&cli1, fname, 0, 0);
2572         cli_unlink(&cli1, fname);
2573         
2574         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2575                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2576                                    FILE_OVERWRITE_IF, 0);
2577         
2578         if (fnum1 == -1) {
2579                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2580                 correct = False;
2581                 goto fail;
2582         }
2583         
2584         /* This should fail - only allowed on NT opens with DELETE access. */
2585         
2586         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2587                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2588                 correct = False;
2589                 goto fail;
2590         }
2591
2592         if (!cli_close(&cli1, fnum1)) {
2593                 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2594                 correct = False;
2595                 goto fail;
2596         }
2597
2598         printf("sixth delete on close test succeeded.\n");
2599         
2600         /* Test 7 ... */
2601         cli_setatr(&cli1, fname, 0, 0);
2602         cli_unlink(&cli1, fname);
2603         
2604         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2605                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2606                                                                 
2607         if (fnum1 == -1) {
2608                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2609                 correct = False;
2610                 goto fail;
2611         }
2612
2613         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2614                 printf("[7] setting delete_on_close on file failed !\n");
2615                 correct = False;
2616                 goto fail;
2617         }
2618         
2619         if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2620                 printf("[7] unsetting delete_on_close on file failed !\n");
2621                 correct = False;
2622                 goto fail;
2623         }
2624
2625         if (!cli_close(&cli1, fnum1)) {
2626                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2627                 correct = False;
2628                 goto fail;
2629         }
2630         
2631         /* This next open should succeed - we reset the flag. */
2632         
2633         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2634         if (fnum1 == -1) {
2635                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2636                 correct = False;
2637                 goto fail;
2638         }
2639
2640         if (!cli_close(&cli1, fnum1)) {
2641                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2642                 correct = False;
2643                 goto fail;
2644         }
2645
2646         printf("seventh delete on close test succeeded.\n");
2647         
2648         /* Test 7 ... */
2649         cli_setatr(&cli1, fname, 0, 0);
2650         cli_unlink(&cli1, fname);
2651         
2652         if (!torture_open_connection(&cli2)) {
2653                 printf("[8] failed to open second connection.\n");
2654                 correct = False;
2655                 goto fail;
2656         }
2657
2658         cli_sockopt(&cli1, sockops);
2659         
2660         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2661                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2662         
2663         if (fnum1 == -1) {
2664                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2665                 correct = False;
2666                 goto fail;
2667         }
2668
2669         fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2670                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2671         
2672         if (fnum2 == -1) {
2673                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2674                 correct = False;
2675                 goto fail;
2676         }
2677
2678         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2679                 printf("[8] setting delete_on_close on file failed !\n");
2680                 correct = False;
2681                 goto fail;
2682         }
2683         
2684         if (!cli_close(&cli1, fnum1)) {
2685                 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2686                 correct = False;
2687                 goto fail;
2688         }
2689
2690         if (!cli_close(&cli2, fnum2)) {
2691                 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2692                 correct = False;
2693                 goto fail;
2694         }
2695
2696         /* This should fail.. */
2697         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2698         if (fnum1 != -1) {
2699                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2700                 goto fail;
2701                 correct = False;
2702         } else
2703                 printf("eighth delete on close test succeeded.\n");
2704
2705         /* This should fail - we need to set DELETE_ACCESS. */
2706         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2707                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2708         
2709         if (fnum1 != -1) {
2710                 printf("[9] open of %s succeeded should have failed!\n", fname);
2711                 correct = False;
2712                 goto fail;
2713         }
2714
2715         printf("ninth delete on close test succeeded.\n");
2716
2717         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2718                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2719         if (fnum1 == -1) {
2720                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2721                 correct = False;
2722                 goto fail;
2723         }
2724
2725         /* This should delete the file. */
2726         if (!cli_close(&cli1, fnum1)) {
2727                 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2728                 correct = False;
2729                 goto fail;
2730         }
2731
2732         /* This should fail.. */
2733         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2734         if (fnum1 != -1) {
2735                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2736                 goto fail;
2737                 correct = False;
2738         } else
2739                 printf("tenth delete on close test succeeded.\n");
2740         printf("finished delete test\n");
2741
2742   fail:
2743         
2744         cli_close(&cli1, fnum1);
2745         cli_close(&cli1, fnum2);
2746         cli_setatr(&cli1, fname, 0, 0);
2747         cli_unlink(&cli1, fname);
2748         
2749         if (!torture_close_connection(&cli1)) {
2750                 correct = False;
2751         }
2752         if (!torture_close_connection(&cli2)) {
2753                 correct = False;
2754         }
2755         return correct;
2756 }
2757
2758
2759 /*
2760   print out server properties
2761  */
2762 static BOOL run_properties(int dummy)
2763 {
2764         static struct cli_state cli;
2765         BOOL correct = True;
2766         
2767         printf("starting properties test\n");
2768         
2769         ZERO_STRUCT(cli);
2770
2771         if (!torture_open_connection(&cli)) {
2772                 return False;
2773         }
2774         
2775         cli_sockopt(&cli, sockops);
2776
2777         d_printf("Capabilities 0x%08x\n", cli.capabilities);
2778
2779         if (!torture_close_connection(&cli)) {
2780                 correct = False;
2781         }
2782
2783         return correct;
2784 }
2785
2786
2787
2788 /* FIRST_DESIRED_ACCESS   0xf019f */
2789 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2790                                FILE_READ_EA|                           /* 0xf */ \
2791                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
2792                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
2793                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
2794                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
2795 /* SECOND_DESIRED_ACCESS  0xe0080 */
2796 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2797                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2798                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
2799
2800 #if 0
2801 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2802                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2803                                FILE_READ_DATA|\
2804                                WRITE_OWNER_ACCESS                      /* */
2805 #endif
2806
2807 /*
2808   Test ntcreate calls made by xcopy
2809  */
2810 static BOOL run_xcopy(int dummy)
2811 {
2812         static struct cli_state cli1;
2813         char *fname = "\\test.txt";
2814         BOOL correct = True;
2815         int fnum1, fnum2;
2816
2817         printf("starting xcopy test\n");
2818         
2819         if (!torture_open_connection(&cli1)) {
2820                 return False;
2821         }
2822         
2823         fnum1 = cli_nt_create_full(&cli1, fname, 
2824                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2825                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
2826                                    0x4044);
2827
2828         if (fnum1 == -1) {
2829                 printf("First open failed - %s\n", cli_errstr(&cli1));
2830                 return False;
2831         }
2832
2833         fnum2 = cli_nt_create_full(&cli1, fname, 
2834                                    SECOND_DESIRED_ACCESS, 0,
2835                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
2836                                    0x200000);
2837         if (fnum2 == -1) {
2838                 printf("second open failed - %s\n", cli_errstr(&cli1));
2839                 return False;
2840         }
2841         
2842         if (!torture_close_connection(&cli1)) {
2843                 correct = False;
2844         }
2845         
2846         return correct;
2847 }
2848
2849 /*
2850   Test rename on files open with share delete and no share delete.
2851  */
2852 static BOOL run_rename(int dummy)
2853 {
2854         static struct cli_state cli1;
2855         char *fname = "\\test.txt";
2856         char *fname1 = "\\test1.txt";
2857         BOOL correct = True;
2858         int fnum1;
2859
2860         printf("starting rename test\n");
2861         
2862         if (!torture_open_connection(&cli1)) {
2863                 return False;
2864         }
2865         
2866         cli_unlink(&cli1, fname);
2867         cli_unlink(&cli1, fname1);
2868         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2869                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2870
2871         if (fnum1 == -1) {
2872                 printf("First open failed - %s\n", cli_errstr(&cli1));
2873                 return False;
2874         }
2875
2876         if (!cli_rename(&cli1, fname, fname1)) {
2877                 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
2878         } else {
2879                 printf("First rename succeeded - this should have failed !\n");
2880                 correct = False;
2881         }
2882
2883         if (!cli_close(&cli1, fnum1)) {
2884                 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
2885                 return False;
2886         }
2887
2888         cli_unlink(&cli1, fname);
2889         cli_unlink(&cli1, fname1);
2890         fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2891                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2892
2893         if (fnum1 == -1) {
2894                 printf("Second open failed - %s\n", cli_errstr(&cli1));
2895                 return False;
2896         }
2897
2898         if (!cli_rename(&cli1, fname, fname1)) {
2899                 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2900                 correct = False;
2901         } else {
2902                 printf("Second rename succeeded\n");
2903         }
2904
2905         if (!cli_close(&cli1, fnum1)) {
2906                 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
2907                 return False;
2908         }
2909
2910         cli_unlink(&cli1, fname);
2911         cli_unlink(&cli1, fname1);
2912
2913         if (!torture_close_connection(&cli1)) {
2914                 correct = False;
2915         }
2916         
2917         return correct;
2918 }
2919
2920
2921 /*
2922   Test open mode returns on read-only files.
2923  */
2924 static BOOL run_opentest(int dummy)
2925 {
2926         static struct cli_state cli1;
2927         char *fname = "\\readonly.file";
2928         int fnum1, fnum2;
2929         char buf[20];
2930         size_t fsize;
2931         BOOL correct = True;
2932         char *tmp_path;
2933
2934         printf("starting open test\n");
2935         
2936         if (!torture_open_connection(&cli1)) {
2937                 return False;
2938         }
2939         
2940         cli_setatr(&cli1, fname, 0, 0);
2941         cli_unlink(&cli1, fname);
2942         
2943         cli_sockopt(&cli1, sockops);
2944         
2945         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2946         if (fnum1 == -1) {
2947                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2948                 return False;
2949         }
2950
2951         if (!cli_close(&cli1, fnum1)) {
2952                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2953                 return False;
2954         }
2955         
2956         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2957                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2958                 return False;
2959         }
2960         
2961         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2962         if (fnum1 == -1) {
2963                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2964                 return False;
2965         }
2966         
2967         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2968         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2969         
2970         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
2971                         NT_STATUS_ACCESS_DENIED)) {
2972                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2973         }
2974         
2975         printf("finished open test 1\n");
2976         
2977         cli_close(&cli1, fnum1);
2978         
2979         /* Now try not readonly and ensure ERRbadshare is returned. */
2980         
2981         cli_setatr(&cli1, fname, 0, 0);
2982         
2983         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2984         if (fnum1 == -1) {
2985                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2986                 return False;
2987         }
2988         
2989         /* This will fail - but the error should be ERRshare. */
2990         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2991         
2992         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
2993                         NT_STATUS_SHARING_VIOLATION)) {
2994                 printf("correct error code ERRDOS/ERRbadshare returned\n");
2995         }
2996         
2997         if (!cli_close(&cli1, fnum1)) {
2998                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2999                 return False;
3000         }
3001         
3002         cli_unlink(&cli1, fname);
3003         
3004         printf("finished open test 2\n");
3005         
3006         /* Test truncate open disposition on file opened for read. */
3007         
3008         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3009         if (fnum1 == -1) {
3010                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3011                 return False;
3012         }
3013         
3014         /* write 20 bytes. */
3015         
3016         memset(buf, '\0', 20);
3017
3018         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3019                 printf("write failed (%s)\n", cli_errstr(&cli1));
3020                 correct = False;
3021         }
3022
3023         if (!cli_close(&cli1, fnum1)) {
3024                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3025                 return False;
3026         }
3027         
3028         /* Ensure size == 20. */
3029         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3030                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3031                 return False;
3032         }
3033         
3034         if (fsize != 20) {
3035                 printf("(3) file size != 20\n");
3036                 return False;
3037         }
3038
3039         /* Now test if we can truncate a file opened for readonly. */
3040         
3041         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3042         if (fnum1 == -1) {
3043                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3044                 return False;
3045         }
3046         
3047         if (!cli_close(&cli1, fnum1)) {
3048                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3049                 return False;
3050         }
3051
3052         /* Ensure size == 0. */
3053         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3054                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3055                 return False;
3056         }
3057
3058         if (fsize != 0) {
3059                 printf("(3) file size != 0\n");
3060                 return False;
3061         }
3062         printf("finished open test 3\n");
3063         
3064         cli_unlink(&cli1, fname);
3065
3066
3067         printf("testing ctemp\n");
3068         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3069         if (fnum1 == -1) {
3070                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3071                 return False;
3072         }
3073         printf("ctemp gave path %s\n", tmp_path);
3074         if (!cli_close(&cli1, fnum1)) {
3075                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3076         }
3077         if (!cli_unlink(&cli1, tmp_path)) {
3078                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3079         }
3080         
3081         if (!torture_close_connection(&cli1)) {
3082                 correct = False;
3083         }
3084         
3085         return correct;
3086 }
3087
3088 static void list_fn(file_info *finfo, const char *name, void *state)
3089 {
3090         
3091 }
3092
3093 /*
3094   test directory listing speed
3095  */
3096 static BOOL run_dirtest(int dummy)
3097 {
3098         int i;
3099         static struct cli_state cli;
3100         int fnum;
3101         double t1;
3102         BOOL correct = True;
3103
3104         printf("starting directory test\n");
3105
3106         if (!torture_open_connection(&cli)) {
3107                 return False;
3108         }
3109
3110         cli_sockopt(&cli, sockops);
3111
3112         srandom(0);
3113         for (i=0;i<numops;i++) {
3114                 fstring fname;
3115                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3116                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3117                 if (fnum == -1) {
3118                         fprintf(stderr,"Failed to open %s\n", fname);
3119                         return False;
3120                 }
3121                 cli_close(&cli, fnum);
3122         }
3123
3124         t1 = end_timer();
3125
3126         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3127         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3128         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3129
3130         printf("dirtest core %g seconds\n", end_timer() - t1);
3131
3132         srandom(0);
3133         for (i=0;i<numops;i++) {
3134                 fstring fname;
3135                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3136                 cli_unlink(&cli, fname);
3137         }
3138
3139         if (!torture_close_connection(&cli)) {
3140                 correct = False;
3141         }
3142
3143         printf("finished dirtest\n");
3144
3145         return correct;
3146 }
3147
3148 static BOOL run_error_map_extract(int dummy) {
3149         
3150         static struct cli_state c_dos;
3151         static struct cli_state c_nt;
3152
3153         uint32 error;
3154
3155         uint32 flgs2, errnum;
3156         uint8 errclass;
3157
3158         NTSTATUS nt_status;
3159
3160         fstring user;
3161
3162         /* NT-Error connection */
3163
3164         if (!open_nbt_connection(&c_nt)) {
3165                 return False;
3166         }
3167
3168         c_nt.use_spnego = False;
3169
3170         if (!cli_negprot(&c_nt)) {
3171                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3172                 cli_shutdown(&c_nt);
3173                 return False;
3174         }
3175
3176         if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3177                                workgroup)) {
3178                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3179                 return False;
3180         }
3181
3182         /* DOS-Error connection */
3183
3184         if (!open_nbt_connection(&c_dos)) {
3185                 return False;
3186         }
3187
3188         c_dos.use_spnego = False;
3189         c_dos.force_dos_errors = True;
3190
3191         if (!cli_negprot(&c_dos)) {
3192                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3193                 cli_shutdown(&c_dos);
3194                 return False;
3195         }
3196
3197         if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3198                                workgroup)) {
3199                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3200                 return False;
3201         }
3202
3203         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3204                 snprintf(user, sizeof(user), "%X", error);
3205
3206                 if (cli_session_setup(&c_nt, user, 
3207                                        password, strlen(password),
3208                                        password, strlen(password),
3209                                       workgroup)) {
3210                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3211                 }
3212                 
3213                 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3214                 
3215                 /* Case #1: 32-bit NT errors */
3216                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3217                         nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3218                 } else {
3219                         printf("/** Dos error on NT connection! (%s) */\n", 
3220                                cli_errstr(&c_nt));
3221                         nt_status = NT_STATUS(0xc0000000);
3222                 }
3223
3224                 if (cli_session_setup(&c_dos, user, 
3225                                        password, strlen(password),
3226                                        password, strlen(password),
3227                                        workgroup)) {
3228                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3229                 }
3230                 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3231                 
3232                 /* Case #1: 32-bit NT errors */
3233                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3234                         printf("/** NT error on DOS connection! (%s) */\n", 
3235                                cli_errstr(&c_nt));
3236                         errnum = errclass = 0;
3237                 } else {
3238                         cli_dos_error(&c_dos, &errclass, &errnum);
3239                 }
3240
3241                 if (NT_STATUS_V(nt_status) != error) { 
3242                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
3243                                get_nt_error_c_code(NT_STATUS(error)), 
3244                                get_nt_error_c_code(nt_status));
3245                 }
3246                 
3247                 printf("\t{%s,\t%s,\t%s},\n", 
3248                        smb_dos_err_class(errclass), 
3249                        smb_dos_err_name(errclass, errnum), 
3250                        get_nt_error_c_code(NT_STATUS(error)));
3251         }
3252         return True;
3253 }
3254
3255 static double create_procs(BOOL (*fn)(int), BOOL *result)
3256 {
3257         int i, status;
3258         volatile pid_t *child_status;
3259         volatile BOOL *child_status_out;
3260         int synccount;
3261         int tries = 8;
3262
3263         synccount = 0;
3264
3265         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3266         if (!child_status) {
3267                 printf("Failed to setup shared memory\n");
3268                 return -1;
3269         }
3270
3271         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3272         if (!child_status_out) {
3273                 printf("Failed to setup result status shared memory\n");
3274                 return -1;
3275         }
3276
3277         for (i = 0; i < nprocs; i++) {
3278                 child_status[i] = 0;
3279                 child_status_out[i] = True;
3280         }
3281
3282         start_timer();
3283
3284         for (i=0;i<nprocs;i++) {
3285                 procnum = i;
3286                 if (fork() == 0) {
3287                         pid_t mypid = getpid();
3288                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3289
3290                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
3291
3292                         while (1) {
3293                                 memset(&current_cli, 0, sizeof(current_cli));
3294                                 if (torture_open_connection(&current_cli)) break;
3295                                 if (tries-- == 0) {
3296                                         printf("pid %d failed to start\n", (int)getpid());
3297                                         _exit(1);
3298                                 }
3299                                 msleep(10);     
3300                         }
3301
3302                         child_status[i] = getpid();
3303
3304                         while (child_status[i]) msleep(2);
3305
3306                         child_status_out[i] = fn(i);
3307                         _exit(0);
3308                 }
3309         }
3310
3311         do {
3312                 synccount = 0;
3313                 for (i=0;i<nprocs;i++) {
3314                         if (child_status[i]) synccount++;
3315                 }
3316                 if (synccount == nprocs) break;
3317                 msleep(10);
3318         } while (end_timer() < 30);
3319
3320         if (synccount != nprocs) {
3321                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3322                 *result = False;
3323                 return end_timer();
3324         }
3325
3326         /* start the client load */
3327         start_timer();
3328
3329         for (i=0;i<nprocs;i++) {
3330                 child_status[i] = 0;
3331         }
3332
3333         printf("%d clients started\n", nprocs);
3334
3335         for (i=0;i<nprocs;i++) {
3336                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3337         }
3338
3339         printf("\n");
3340         
3341         for (i=0;i<nprocs;i++) {
3342                 if (!child_status_out[i]) {
3343                         *result = False;
3344                 }
3345         }
3346         return end_timer();
3347 }
3348
3349 #define FLAG_MULTIPROC 1
3350
3351 static struct {
3352         char *name;
3353         BOOL (*fn)(int);
3354         unsigned flags;
3355 } torture_ops[] = {
3356         {"FDPASS", run_fdpasstest, 0},
3357         {"LOCK1",  run_locktest1,  0},
3358         {"LOCK2",  run_locktest2,  0},
3359         {"LOCK3",  run_locktest3,  0},
3360         {"LOCK4",  run_locktest4,  0},
3361         {"LOCK5",  run_locktest5,  0},
3362         {"LOCK6",  run_locktest6,  0},
3363         {"UNLINK", run_unlinktest, 0},
3364         {"BROWSE", run_browsetest, 0},
3365         {"ATTR",   run_attrtest,   0},
3366         {"TRANS2", run_trans2test, 0},
3367         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3368         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3369         {"RANDOMIPC", run_randomipc, 0},
3370         {"NEGNOWAIT", run_negprot_nowait, 0},
3371         {"NBENCH",  run_nbench, 0},
3372         {"OPLOCK1",  run_oplock1, 0},
3373         {"OPLOCK2",  run_oplock2, 0},
3374         {"OPLOCK3",  run_oplock3, 0},
3375         {"DIR",  run_dirtest, 0},
3376         {"DENY1",  torture_denytest1, 0},
3377         {"DENY2",  torture_denytest2, 0},
3378         {"TCON",  run_tcon_test, 0},
3379         {"RW1",  run_readwritetest, 0},
3380         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3381         {"RW3",  run_readwritelarge, 0},
3382         {"OPEN", run_opentest, 0},
3383         {"XCOPY", run_xcopy, 0},
3384         {"RENAME", run_rename, 0},
3385         {"DELETE", run_deletetest, 0},
3386         {"PROPERTIES", run_properties, 0},
3387         {"W2K", run_w2ktest, 0},
3388         {"TRANS2SCAN", torture_trans2_scan, 0},
3389         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3390         {"UTABLE", torture_utable, 0},
3391         {"CASETABLE", torture_casetable, 0},
3392         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3393         {NULL, NULL, 0}};
3394
3395
3396
3397 /****************************************************************************
3398 run a specified test or "ALL"
3399 ****************************************************************************/
3400 static BOOL run_test(char *name)
3401 {
3402         BOOL ret = True;
3403         BOOL result = True;
3404         int i;
3405         double t;
3406         if (strequal(name,"ALL")) {
3407                 for (i=0;torture_ops[i].name;i++) {
3408                         run_test(torture_ops[i].name);
3409                 }
3410         }
3411         
3412         for (i=0;torture_ops[i].name;i++) {
3413                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
3414                          (unsigned)random());
3415
3416                 if (strequal(name, torture_ops[i].name)) {
3417                         printf("Running %s\n", name);
3418                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
3419                                 t = create_procs(torture_ops[i].fn, &result);
3420                                 if (!result) { 
3421                                         ret = False;
3422                                         printf("TEST %s FAILED!\n", name);
3423                                 }
3424                                          
3425                         } else {
3426                                 start_timer();
3427                                 if (!torture_ops[i].fn(0)) {
3428                                         ret = False;
3429                                         printf("TEST %s FAILED!\n", name);
3430                                 }
3431                                 t = end_timer();
3432                         }
3433                         printf("%s took %g secs\n\n", name, t);
3434                 }
3435         }
3436         return ret;
3437 }
3438
3439
3440 static void usage(void)
3441 {
3442         int i;
3443
3444         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3445
3446         printf("\t-d debuglevel\n");
3447         printf("\t-U user%%pass\n");
3448         printf("\t-k               use kerberos\n");
3449         printf("\t-N numprocs\n");
3450         printf("\t-n my_netbios_name\n");
3451         printf("\t-W workgroup\n");
3452         printf("\t-o num_operations\n");
3453         printf("\t-O socket_options\n");
3454         printf("\t-m maximum protocol\n");
3455         printf("\t-L use oplocks\n");
3456         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
3457         printf("\t-A showall\n");
3458         printf("\n\n");
3459
3460         printf("tests are:");
3461         for (i=0;torture_ops[i].name;i++) {
3462                 printf(" %s", torture_ops[i].name);
3463         }
3464         printf("\n");
3465
3466         printf("default test is ALL\n");
3467         
3468         exit(1);
3469 }
3470
3471
3472
3473
3474
3475 /****************************************************************************
3476   main program
3477 ****************************************************************************/
3478  int main(int argc,char *argv[])
3479 {
3480         int opt, i;
3481         char *p;
3482         int gotpass = 0;
3483         extern char *optarg;
3484         extern int optind;
3485         BOOL correct = True;
3486
3487         dbf = x_stdout;
3488
3489 #ifdef HAVE_SETBUFFER
3490         setbuffer(stdout, NULL, 0);
3491 #endif
3492
3493         lp_load(dyn_CONFIGFILE,True,False,False);
3494         load_interfaces();
3495
3496         if (argc < 2) {
3497                 usage();
3498         }
3499
3500         for(p = argv[1]; *p; p++)
3501           if(*p == '\\')
3502             *p = '/';
3503  
3504         if (strncmp(argv[1], "//", 2)) {
3505                 usage();
3506         }
3507
3508         fstrcpy(host, &argv[1][2]);
3509         p = strchr_m(&host[2],'/');
3510         if (!p) {
3511                 usage();
3512         }
3513         *p = 0;
3514         fstrcpy(share, p+1);
3515
3516         get_myname(myname);
3517
3518         if (*username == 0 && getenv("LOGNAME")) {
3519           pstrcpy(username,getenv("LOGNAME"));
3520         }
3521
3522         argc--;
3523         argv++;
3524
3525
3526         fstrcpy(workgroup, lp_workgroup());
3527
3528         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:k")) != EOF) {
3529                 switch (opt) {
3530                 case 'W':
3531                         fstrcpy(workgroup,optarg);
3532                         break;
3533                 case 'm':
3534                         max_protocol = interpret_protocol(optarg, max_protocol);
3535                         break;
3536                 case 'N':
3537                         nprocs = atoi(optarg);
3538                         break;
3539                 case 'o':
3540                         numops = atoi(optarg);
3541                         break;
3542                 case 'd':
3543                         DEBUGLEVEL = atoi(optarg);
3544                         break;
3545                 case 'O':
3546                         sockops = optarg;
3547                         break;
3548                 case 'L':
3549                         use_oplocks = True;
3550                         break;
3551                 case 'A':
3552                         torture_showall = True;
3553                         break;
3554                 case 'n':
3555                         fstrcpy(myname, optarg);
3556                         break;
3557                 case 'c':
3558                         client_txt = optarg;
3559                         break;
3560                 case 'k':
3561 #ifdef HAVE_KRB5
3562                         use_kerberos = True;
3563                         gotpass = True;
3564 #else
3565                         d_printf("No kerberos support compiled in\n");
3566                         exit(1);
3567 #endif
3568                         break;
3569                 case 'U':
3570                         pstrcpy(username,optarg);
3571                         p = strchr_m(username,'%');
3572                         if (p) {
3573                                 *p = 0;
3574                                 pstrcpy(password, p+1);
3575                                 gotpass = 1;
3576                         }
3577                         break;
3578                 default:
3579                         printf("Unknown option %c (%d)\n", (char)opt, opt);
3580                         usage();
3581                 }
3582         }
3583
3584
3585         while (!gotpass) {
3586                 p = getpass("Password:");
3587                 if (p) {
3588                         pstrcpy(password, p);
3589                         gotpass = 1;
3590                 }
3591         }
3592
3593         printf("host=%s share=%s user=%s myname=%s\n", 
3594                host, share, username, myname);
3595
3596         if (argc == 1) {
3597                 correct = run_test("ALL");
3598         } else {
3599                 for (i=1;i<argc;i++) {
3600                         if (!run_test(argv[i])) {
3601                                 correct = False;
3602                         }
3603                 }
3604         }
3605
3606         if (correct) {
3607                 return(0);
3608         } else {
3609                 return(1);
3610         }
3611 }