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