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