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