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