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