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