This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[kai/samba.git] / source / 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 const 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 const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const char *fname = "\\trans2.tst";
1935         const char *dname = "\\trans2";
1936         const 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         const 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         const 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         const 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         const 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         const 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         const 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         const char *fname = "\\test.txt";
2889         const 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         const 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         const 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         uint16 attr;
3047
3048         printf("starting open test\n");
3049         
3050         if (!torture_open_connection(&cli1)) {
3051                 return False;
3052         }
3053         
3054         cli_setatr(&cli1, fname, 0, 0);
3055         cli_unlink(&cli1, fname);
3056         
3057         cli_sockopt(&cli1, sockops);
3058         
3059         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3060         if (fnum1 == -1) {
3061                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3062                 return False;
3063         }
3064
3065         if (!cli_close(&cli1, fnum1)) {
3066                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3067                 return False;
3068         }
3069         
3070         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3071                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3072                 return False;
3073         }
3074         
3075         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3076         if (fnum1 == -1) {
3077                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3078                 return False;
3079         }
3080         
3081         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3082         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3083         
3084         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
3085                         NT_STATUS_ACCESS_DENIED)) {
3086                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3087         }
3088         
3089         printf("finished open test 1\n");
3090         
3091         cli_close(&cli1, fnum1);
3092         
3093         /* Now try not readonly and ensure ERRbadshare is returned. */
3094         
3095         cli_setatr(&cli1, fname, 0, 0);
3096         
3097         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3098         if (fnum1 == -1) {
3099                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3100                 return False;
3101         }
3102         
3103         /* This will fail - but the error should be ERRshare. */
3104         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3105         
3106         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
3107                         NT_STATUS_SHARING_VIOLATION)) {
3108                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3109         }
3110         
3111         if (!cli_close(&cli1, fnum1)) {
3112                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3113                 return False;
3114         }
3115         
3116         cli_unlink(&cli1, fname);
3117         
3118         printf("finished open test 2\n");
3119         
3120         /* Test truncate open disposition on file opened for read. */
3121         
3122         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3123         if (fnum1 == -1) {
3124                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3125                 return False;
3126         }
3127         
3128         /* write 20 bytes. */
3129         
3130         memset(buf, '\0', 20);
3131
3132         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3133                 printf("write failed (%s)\n", cli_errstr(&cli1));
3134                 correct = False;
3135         }
3136
3137         if (!cli_close(&cli1, fnum1)) {
3138                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3139                 return False;
3140         }
3141         
3142         /* Ensure size == 20. */
3143         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3144                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3145                 return False;
3146         }
3147         
3148         if (fsize != 20) {
3149                 printf("(3) file size != 20\n");
3150                 return False;
3151         }
3152
3153         /* Now test if we can truncate a file opened for readonly. */
3154         
3155         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3156         if (fnum1 == -1) {
3157                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3158                 return False;
3159         }
3160         
3161         if (!cli_close(&cli1, fnum1)) {
3162                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3163                 return False;
3164         }
3165
3166         /* Ensure size == 0. */
3167         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3168                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3169                 return False;
3170         }
3171
3172         if (fsize != 0) {
3173                 printf("(3) file size != 0\n");
3174                 return False;
3175         }
3176         printf("finished open test 3\n");
3177         
3178         cli_unlink(&cli1, fname);
3179
3180
3181         printf("testing ctemp\n");
3182         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3183         if (fnum1 == -1) {
3184                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3185                 return False;
3186         }
3187         printf("ctemp gave path %s\n", tmp_path);
3188         if (!cli_close(&cli1, fnum1)) {
3189                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3190         }
3191         if (!cli_unlink(&cli1, tmp_path)) {
3192                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3193         }
3194         
3195         /* Test the non-io opens... */
3196
3197         if (!torture_open_connection(&cli2)) {
3198                 return False;
3199         }
3200         
3201         cli_setatr(&cli2, fname, 0, 0);
3202         cli_unlink(&cli2, fname);
3203         
3204         cli_sockopt(&cli2, sockops);
3205
3206         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3207         
3208         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3209                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3210
3211         if (fnum1 == -1) {
3212                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3213                 return False;
3214         }
3215
3216         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3217                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3218
3219         if (fnum2 == -1) {
3220                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3221                 return False;
3222         }
3223
3224         if (!cli_close(&cli1, fnum1)) {
3225                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3226                 return False;
3227         }
3228         if (!cli_close(&cli2, fnum2)) {
3229                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3230                 return False;
3231         }
3232
3233         printf("non-io open test #1 passed.\n");
3234
3235         cli_unlink(&cli1, fname);
3236
3237         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3238         
3239         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3240                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3241
3242         if (fnum1 == -1) {
3243                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3244                 return False;
3245         }
3246
3247         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3248                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3249
3250         if (fnum2 == -1) {
3251                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3252                 return False;
3253         }
3254
3255         if (!cli_close(&cli1, fnum1)) {
3256                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3257                 return False;
3258         }
3259         if (!cli_close(&cli2, fnum2)) {
3260                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3261                 return False;
3262         }
3263
3264         printf("non-io open test #2 passed.\n");
3265
3266         cli_unlink(&cli1, fname);
3267
3268         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3269         
3270         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3271                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3272
3273         if (fnum1 == -1) {
3274                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3275                 return False;
3276         }
3277
3278         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3279                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3280
3281         if (fnum2 == -1) {
3282                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3283                 return False;
3284         }
3285
3286         if (!cli_close(&cli1, fnum1)) {
3287                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3288                 return False;
3289         }
3290         if (!cli_close(&cli2, fnum2)) {
3291                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3292                 return False;
3293         }
3294
3295         printf("non-io open test #3 passed.\n");
3296
3297         cli_unlink(&cli1, fname);
3298
3299         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3300         
3301         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3302                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3303
3304         if (fnum1 == -1) {
3305                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3306                 return False;
3307         }
3308
3309         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3310                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3311
3312         if (fnum2 != -1) {
3313                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3314                 return False;
3315         }
3316
3317         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3318
3319         if (!cli_close(&cli1, fnum1)) {
3320                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3321                 return False;
3322         }
3323
3324         printf("non-io open test #4 passed.\n");
3325
3326         cli_unlink(&cli1, fname);
3327
3328         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3329         
3330         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3331                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3332
3333         if (fnum1 == -1) {
3334                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3335                 return False;
3336         }
3337
3338         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3339                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3340
3341         if (fnum2 == -1) {
3342                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3343                 return False;
3344         }
3345
3346         if (!cli_close(&cli1, fnum1)) {
3347                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3348                 return False;
3349         }
3350
3351         if (!cli_close(&cli2, fnum2)) {
3352                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3353                 return False;
3354         }
3355
3356         printf("non-io open test #5 passed.\n");
3357
3358         printf("TEST #6 testing 1 non-io open, one io open\n");
3359         
3360         cli_unlink(&cli1, fname);
3361
3362         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3363                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3364
3365         if (fnum1 == -1) {
3366                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3367                 return False;
3368         }
3369
3370         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3371                                    FILE_SHARE_READ, FILE_OPEN_IF, 0);
3372
3373         if (fnum2 == -1) {
3374                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3375                 return False;
3376         }
3377
3378         if (!cli_close(&cli1, fnum1)) {
3379                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3380                 return False;
3381         }
3382
3383         if (!cli_close(&cli2, fnum2)) {
3384                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3385                 return False;
3386         }
3387
3388         printf("non-io open test #6 passed.\n");
3389
3390         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3391
3392         cli_unlink(&cli1, fname);
3393
3394         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3395                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3396
3397         if (fnum1 == -1) {
3398                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3399                 return False;
3400         }
3401
3402         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3403                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3404
3405         if (fnum2 != -1) {
3406                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3407                 return False;
3408         }
3409
3410         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3411
3412         if (!cli_close(&cli1, fnum1)) {
3413                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3414                 return False;
3415         }
3416
3417         printf("non-io open test #7 passed.\n");
3418
3419         cli_unlink(&cli1, fname);
3420
3421         /* Test 8 - attributes test #1... */
3422         fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN,
3423                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3424
3425         if (fnum1 == -1) {
3426                 printf("test 8 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3427                 return False;
3428         }
3429
3430         if (!cli_close(&cli1, fnum1)) {
3431                 printf("test 8 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3432                 return False;
3433         }
3434
3435         /* FILE_SUPERSEDE && FILE_OVERWRITE_IF have the same effect here. */
3436         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL,
3437                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3438
3439         if (fnum1 == -1) {
3440                 printf("test 8 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3441                 return False;
3442         }
3443
3444         if (!cli_close(&cli1, fnum1)) {
3445                 printf("test 8 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3446                 return False;
3447         }
3448
3449         /* This open should fail with ACCESS_DENIED for FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF. */
3450         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3451                                    FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3452
3453         if (fnum1 != -1) {
3454                 printf("test 8 open 3 of %s succeeded - should have failed with (NT_STATUS_ACCESS_DENIED)\n", fname);
3455                 correct = False;
3456                 cli_close(&cli1, fnum1);
3457         } else {
3458                 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED)) {
3459                         printf("correct error code NT_STATUS_ACCESS_DENIED/ERRDOS:ERRnoaccess returned\n");
3460                 }
3461         }
3462
3463         printf("Attribute open test #8 %s.\n", correct ? "passed" : "failed");
3464
3465         cli_unlink(&cli1, fname);
3466
3467         /*
3468          * Test #9. Open with NORMAL, close, then re-open with attribute
3469          * HIDDEN and request to truncate.
3470          */
3471
3472         fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
3473                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3474
3475         if (fnum1 == -1) {
3476                 printf("test 9 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3477                 return False;
3478         }
3479
3480         if (!cli_close(&cli1, fnum1)) {
3481                 printf("test 9 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3482                 return False;
3483         }
3484
3485         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, FILE_ATTRIBUTE_HIDDEN,
3486                                    FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3487
3488         if (fnum1 == -1) {
3489                 printf("test 9 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3490                 return False;
3491         }
3492
3493         if (!cli_close(&cli1, fnum1)) {
3494                 printf("test 9 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3495                 return False;
3496         }
3497
3498         /* Ensure we have attr hidden. */
3499         if (!cli_getatr(&cli1, fname, &attr, NULL, NULL)) {
3500                 printf("test 9 getatr(2) failed (%s)\n", cli_errstr(&cli1));
3501                 return False;
3502         }
3503
3504         if (!(attr & FILE_ATTRIBUTE_HIDDEN)) {
3505                 printf("test 9 getatr didn't have HIDDEN attribute\n");
3506                 cli_unlink(&cli1, fname);
3507                 return False;
3508         }
3509
3510         printf("Attribute open test #9 %s.\n", correct ? "passed" : "failed");
3511
3512         cli_unlink(&cli1, fname);
3513
3514         if (!torture_close_connection(&cli1)) {
3515                 correct = False;
3516         }
3517         if (!torture_close_connection(&cli2)) {
3518                 correct = False;
3519         }
3520         
3521         return correct;
3522 }
3523
3524 static void list_fn(file_info *finfo, const char *name, void *state)
3525 {
3526         
3527 }
3528
3529 /*
3530   test directory listing speed
3531  */
3532 static BOOL run_dirtest(int dummy)
3533 {
3534         int i;
3535         static struct cli_state cli;
3536         int fnum;
3537         double t1;
3538         BOOL correct = True;
3539
3540         printf("starting directory test\n");
3541
3542         if (!torture_open_connection(&cli)) {
3543                 return False;
3544         }
3545
3546         cli_sockopt(&cli, sockops);
3547
3548         srandom(0);
3549         for (i=0;i<torture_numops;i++) {
3550                 fstring fname;
3551                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3552                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3553                 if (fnum == -1) {
3554                         fprintf(stderr,"Failed to open %s\n", fname);
3555                         return False;
3556                 }
3557                 cli_close(&cli, fnum);
3558         }
3559
3560         t1 = end_timer();
3561
3562         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3563         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3564         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3565
3566         printf("dirtest core %g seconds\n", end_timer() - t1);
3567
3568         srandom(0);
3569         for (i=0;i<torture_numops;i++) {
3570                 fstring fname;
3571                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3572                 cli_unlink(&cli, fname);
3573         }
3574
3575         if (!torture_close_connection(&cli)) {
3576                 correct = False;
3577         }
3578
3579         printf("finished dirtest\n");
3580
3581         return correct;
3582 }
3583
3584 static void del_fn(file_info *finfo, const char *mask, void *state)
3585 {
3586         struct cli_state *pcli = (struct cli_state *)state;
3587         fstring fname;
3588         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3589
3590         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3591                 return;
3592
3593         if (finfo->mode & aDIR) {
3594                 if (!cli_rmdir(pcli, fname))
3595                         printf("del_fn: failed to rmdir %s\n,", fname );
3596         } else {
3597                 if (!cli_unlink(pcli, fname))
3598                         printf("del_fn: failed to unlink %s\n,", fname );
3599         }
3600 }
3601
3602 static BOOL run_dirtest1(int dummy)
3603 {
3604         int i;
3605         static struct cli_state cli;
3606         int fnum, num_seen;
3607         BOOL correct = True;
3608
3609         printf("starting directory test\n");
3610
3611         if (!torture_open_connection(&cli)) {
3612                 return False;
3613         }
3614
3615         cli_sockopt(&cli, sockops);
3616
3617         cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3618         cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3619         cli_rmdir(&cli, "\\LISTDIR");
3620         cli_mkdir(&cli, "\\LISTDIR");
3621
3622         /* Create 1000 files and 1000 directories. */
3623         for (i=0;i<1000;i++) {
3624                 fstring fname;
3625                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
3626                 fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3627                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
3628                 if (fnum == -1) {
3629                         fprintf(stderr,"Failed to open %s\n", fname);
3630                         return False;
3631                 }
3632                 cli_close(&cli, fnum);
3633         }
3634         for (i=0;i<1000;i++) {
3635                 fstring fname;
3636                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
3637                 if (!cli_mkdir(&cli, fname)) {
3638                         fprintf(stderr,"Failed to open %s\n", fname);
3639                         return False;
3640                 }
3641         }
3642
3643         /* Now ensure that doing an old list sees both files and directories. */
3644         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
3645         printf("num_seen = %d\n", num_seen );
3646         /* We should see 100 files + 1000 directories + . and .. */
3647         if (num_seen != 2002)
3648                 correct = False;
3649
3650         /* Ensure if we have the "must have" bits we only see the
3651          * relevent entries.
3652          */
3653         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
3654         printf("num_seen = %d\n", num_seen );
3655         if (num_seen != 1002)
3656                 correct = False;
3657
3658         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
3659         printf("num_seen = %d\n", num_seen );
3660         if (num_seen != 1000)
3661                 correct = False;
3662
3663         /* Delete everything. */
3664         cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3665         cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3666         cli_rmdir(&cli, "\\LISTDIR");
3667
3668 #if 0
3669         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3670         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3671         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3672 #endif
3673
3674         if (!torture_close_connection(&cli)) {
3675                 correct = False;
3676         }
3677
3678         printf("finished dirtest1\n");
3679
3680         return correct;
3681 }
3682
3683 static BOOL run_error_map_extract(int dummy) {
3684         
3685         static struct cli_state c_dos;
3686         static struct cli_state c_nt;
3687
3688         uint32 error;
3689
3690         uint32 flgs2, errnum;
3691         uint8 errclass;
3692
3693         NTSTATUS nt_status;
3694
3695         fstring user;
3696
3697         /* NT-Error connection */
3698
3699         if (!open_nbt_connection(&c_nt)) {
3700                 return False;
3701         }
3702
3703         c_nt.use_spnego = False;
3704
3705         if (!cli_negprot(&c_nt)) {
3706                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3707                 cli_shutdown(&c_nt);
3708                 return False;
3709         }
3710
3711         if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3712                                workgroup)) {
3713                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3714                 return False;
3715         }
3716
3717         /* DOS-Error connection */
3718
3719         if (!open_nbt_connection(&c_dos)) {
3720                 return False;
3721         }
3722
3723         c_dos.use_spnego = False;
3724         c_dos.force_dos_errors = True;
3725
3726         if (!cli_negprot(&c_dos)) {
3727                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3728                 cli_shutdown(&c_dos);
3729                 return False;
3730         }
3731
3732         if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3733                                workgroup)) {
3734                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3735                 return False;
3736         }
3737
3738         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3739                 snprintf(user, sizeof(user), "%X", error);
3740
3741                 if (cli_session_setup(&c_nt, user, 
3742                                        password, strlen(password),
3743                                        password, strlen(password),
3744                                       workgroup)) {
3745                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3746                 }
3747                 
3748                 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3749                 
3750                 /* Case #1: 32-bit NT errors */
3751                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3752                         nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3753                 } else {
3754                         printf("/** Dos error on NT connection! (%s) */\n", 
3755                                cli_errstr(&c_nt));
3756                         nt_status = NT_STATUS(0xc0000000);
3757                 }
3758
3759                 if (cli_session_setup(&c_dos, user, 
3760                                        password, strlen(password),
3761                                        password, strlen(password),
3762                                        workgroup)) {
3763                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3764                 }
3765                 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3766                 
3767                 /* Case #1: 32-bit NT errors */
3768                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3769                         printf("/** NT error on DOS connection! (%s) */\n", 
3770                                cli_errstr(&c_nt));
3771                         errnum = errclass = 0;
3772                 } else {
3773                         cli_dos_error(&c_dos, &errclass, &errnum);
3774                 }
3775
3776                 if (NT_STATUS_V(nt_status) != error) { 
3777                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
3778                                get_nt_error_c_code(NT_STATUS(error)), 
3779                                get_nt_error_c_code(nt_status));
3780                 }
3781                 
3782                 printf("\t{%s,\t%s,\t%s},\n", 
3783                        smb_dos_err_class(errclass), 
3784                        smb_dos_err_name(errclass, errnum), 
3785                        get_nt_error_c_code(NT_STATUS(error)));
3786         }
3787         return True;
3788 }
3789
3790 static double create_procs(BOOL (*fn)(int), BOOL *result)
3791 {
3792         int i, status;
3793         volatile pid_t *child_status;
3794         volatile BOOL *child_status_out;
3795         int synccount;
3796         int tries = 8;
3797
3798         synccount = 0;
3799
3800         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3801         if (!child_status) {
3802                 printf("Failed to setup shared memory\n");
3803                 return -1;
3804         }
3805
3806         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3807         if (!child_status_out) {
3808                 printf("Failed to setup result status shared memory\n");
3809                 return -1;
3810         }
3811
3812         for (i = 0; i < nprocs; i++) {
3813                 child_status[i] = 0;
3814                 child_status_out[i] = True;
3815         }
3816
3817         start_timer();
3818
3819         for (i=0;i<nprocs;i++) {
3820                 procnum = i;
3821                 if (fork() == 0) {
3822                         pid_t mypid = getpid();
3823                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3824
3825                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
3826
3827                         while (1) {
3828                                 memset(&current_cli, 0, sizeof(current_cli));
3829                                 if (torture_open_connection(&current_cli)) break;
3830                                 if (tries-- == 0) {
3831                                         printf("pid %d failed to start\n", (int)getpid());
3832                                         _exit(1);
3833                                 }
3834                                 msleep(10);     
3835                         }
3836
3837                         child_status[i] = getpid();
3838
3839                         while (child_status[i] && end_timer() < 5) msleep(2);
3840
3841                         child_status_out[i] = fn(i);
3842                         _exit(0);
3843                 }
3844         }
3845
3846         do {
3847                 synccount = 0;
3848                 for (i=0;i<nprocs;i++) {
3849                         if (child_status[i]) synccount++;
3850                 }
3851                 if (synccount == nprocs) break;
3852                 msleep(10);
3853         } while (end_timer() < 30);
3854
3855         if (synccount != nprocs) {
3856                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3857                 *result = False;
3858                 return end_timer();
3859         }
3860
3861         /* start the client load */
3862         start_timer();
3863
3864         for (i=0;i<nprocs;i++) {
3865                 child_status[i] = 0;
3866         }
3867
3868         printf("%d clients started\n", nprocs);
3869
3870         for (i=0;i<nprocs;i++) {
3871                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3872         }
3873
3874         printf("\n");
3875         
3876         for (i=0;i<nprocs;i++) {
3877                 if (!child_status_out[i]) {
3878                         *result = False;
3879                 }
3880         }
3881         return end_timer();
3882 }
3883
3884 #define FLAG_MULTIPROC 1
3885
3886 static struct {
3887         const char *name;
3888         BOOL (*fn)(int);
3889         unsigned flags;
3890 } torture_ops[] = {
3891         {"FDPASS", run_fdpasstest, 0},
3892         {"LOCK1",  run_locktest1,  0},
3893         {"LOCK2",  run_locktest2,  0},
3894         {"LOCK3",  run_locktest3,  0},
3895         {"LOCK4",  run_locktest4,  0},
3896         {"LOCK5",  run_locktest5,  0},
3897         {"LOCK6",  run_locktest6,  0},
3898         {"UNLINK", run_unlinktest, 0},
3899         {"BROWSE", run_browsetest, 0},
3900         {"ATTR",   run_attrtest,   0},
3901         {"TRANS2", run_trans2test, 0},
3902         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3903         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3904         {"RANDOMIPC", run_randomipc, 0},
3905         {"NEGNOWAIT", run_negprot_nowait, 0},
3906         {"NBENCH",  run_nbench, 0},
3907         {"OPLOCK1",  run_oplock1, 0},
3908         {"OPLOCK2",  run_oplock2, 0},
3909         {"OPLOCK3",  run_oplock3, 0},
3910         {"DIR",  run_dirtest, 0},
3911         {"DIR1",  run_dirtest1, 0},
3912         {"DENY1",  torture_denytest1, 0},
3913         {"DENY2",  torture_denytest2, 0},
3914         {"TCON",  run_tcon_test, 0},
3915         {"RW1",  run_readwritetest, 0},
3916         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3917         {"RW3",  run_readwritelarge, 0},
3918         {"OPEN", run_opentest, 0},
3919         {"XCOPY", run_xcopy, 0},
3920         {"RENAME", run_rename, 0},
3921         {"DELETE", run_deletetest, 0},
3922         {"PROPERTIES", run_properties, 0},
3923         {"MANGLE", torture_mangle, 0},
3924         {"W2K", run_w2ktest, 0},
3925         {"TRANS2SCAN", torture_trans2_scan, 0},
3926         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3927         {"UTABLE", torture_utable, 0},
3928         {"CASETABLE", torture_casetable, 0},
3929         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3930         {"PIPE_NUMBER", run_pipe_number, 0},
3931         {NULL, NULL, 0}};
3932
3933
3934
3935 /****************************************************************************
3936 run a specified test or "ALL"
3937 ****************************************************************************/
3938 static BOOL run_test(const char *name)
3939 {
3940         BOOL ret = True;
3941         BOOL result = True;
3942         int i;
3943         double t;
3944         if (strequal(name,"ALL")) {
3945                 for (i=0;torture_ops[i].name;i++) {
3946                         run_test(torture_ops[i].name);
3947                 }
3948         }
3949         
3950         for (i=0;torture_ops[i].name;i++) {
3951                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
3952                          (unsigned)random());
3953
3954                 if (strequal(name, torture_ops[i].name)) {
3955                         printf("Running %s\n", name);
3956                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
3957                                 t = create_procs(torture_ops[i].fn, &result);
3958                                 if (!result) { 
3959                                         ret = False;
3960                                         printf("TEST %s FAILED!\n", name);
3961                                 }
3962                                          
3963                         } else {
3964                                 start_timer();
3965                                 if (!torture_ops[i].fn(0)) {
3966                                         ret = False;
3967                                         printf("TEST %s FAILED!\n", name);
3968                                 }
3969                                 t = end_timer();
3970                         }
3971                         printf("%s took %g secs\n\n", name, t);
3972                 }
3973         }
3974         return ret;
3975 }
3976
3977
3978 static void usage(void)
3979 {
3980         int i;
3981
3982         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3983
3984         printf("\t-d debuglevel\n");
3985         printf("\t-U user%%pass\n");
3986         printf("\t-k               use kerberos\n");
3987         printf("\t-N numprocs\n");
3988         printf("\t-n my_netbios_name\n");
3989         printf("\t-W workgroup\n");
3990         printf("\t-o num_operations\n");
3991         printf("\t-O socket_options\n");
3992         printf("\t-m maximum protocol\n");
3993         printf("\t-L use oplocks\n");
3994         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
3995         printf("\t-A showall\n");
3996         printf("\t-s seed\n");
3997         printf("\n\n");
3998
3999         printf("tests are:");
4000         for (i=0;torture_ops[i].name;i++) {
4001                 printf(" %s", torture_ops[i].name);
4002         }
4003         printf("\n");
4004
4005         printf("default test is ALL\n");
4006         
4007         exit(1);
4008 }
4009
4010
4011
4012
4013
4014 /****************************************************************************
4015   main program
4016 ****************************************************************************/
4017  int main(int argc,char *argv[])
4018 {
4019         int opt, i;
4020         char *p;
4021         int gotpass = 0;
4022         extern char *optarg;
4023         extern int optind;
4024         BOOL correct = True;
4025
4026         dbf = x_stdout;
4027
4028 #ifdef HAVE_SETBUFFER
4029         setbuffer(stdout, NULL, 0);
4030 #endif
4031
4032         lp_load(dyn_CONFIGFILE,True,False,False);
4033         load_interfaces();
4034
4035         if (argc < 2) {
4036                 usage();
4037         }
4038
4039         for(p = argv[1]; *p; p++)
4040           if(*p == '\\')
4041             *p = '/';
4042  
4043         if (strncmp(argv[1], "//", 2)) {
4044                 usage();
4045         }
4046
4047         fstrcpy(host, &argv[1][2]);
4048         p = strchr_m(&host[2],'/');
4049         if (!p) {
4050                 usage();
4051         }
4052         *p = 0;
4053         fstrcpy(share, p+1);
4054
4055         get_myname(myname);
4056
4057         if (*username == 0 && getenv("LOGNAME")) {
4058           fstrcpy(username,getenv("LOGNAME"));
4059         }
4060
4061         argc--;
4062         argv++;
4063
4064         srandom(time(NULL));
4065
4066         fstrcpy(workgroup, lp_workgroup());
4067
4068         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4069                 switch (opt) {
4070                 case 's':
4071                         srandom(atoi(optarg));
4072                         break;
4073                 case 'W':
4074                         fstrcpy(workgroup,optarg);
4075                         break;
4076                 case 'm':
4077                         max_protocol = interpret_protocol(optarg, max_protocol);
4078                         break;
4079                 case 'N':
4080                         nprocs = atoi(optarg);
4081                         break;
4082                 case 'o':
4083                         torture_numops = atoi(optarg);
4084                         break;
4085                 case 'd':
4086                         DEBUGLEVEL = atoi(optarg);
4087                         break;
4088                 case 'O':
4089                         sockops = optarg;
4090                         break;
4091                 case 'L':
4092                         use_oplocks = True;
4093                         break;
4094                 case 'A':
4095                         torture_showall = True;
4096                         break;
4097                 case 'n':
4098                         fstrcpy(myname, optarg);
4099                         break;
4100                 case 'c':
4101                         client_txt = optarg;
4102                         break;
4103                 case 'k':
4104 #ifdef HAVE_KRB5
4105                         use_kerberos = True;
4106                         gotpass = True;
4107 #else
4108                         d_printf("No kerberos support compiled in\n");
4109                         exit(1);
4110 #endif
4111                         break;
4112                 case 'U':
4113                         fstrcpy(username,optarg);
4114                         p = strchr_m(username,'%');
4115                         if (p) {
4116                                 *p = 0;
4117                                 fstrcpy(password, p+1);
4118                                 gotpass = 1;
4119                         }
4120                         break;
4121                 default:
4122                         printf("Unknown option %c (%d)\n", (char)opt, opt);
4123                         usage();
4124                 }
4125         }
4126
4127
4128         while (!gotpass) {
4129                 p = getpass("Password:");
4130                 if (p) {
4131                         fstrcpy(password, p);
4132                         gotpass = 1;
4133                 }
4134         }
4135
4136         printf("host=%s share=%s user=%s myname=%s\n", 
4137                host, share, username, myname);
4138
4139         if (argc == 1) {
4140                 correct = run_test("ALL");
4141         } else {
4142                 for (i=1;i<argc;i++) {
4143                         if (!run_test(argv[i])) {
4144                                 correct = False;
4145                         }
4146                 }
4147         }
4148
4149         if (correct) {
4150                 return(0);
4151         } else {
4152                 return(1);
4153         }
4154 }