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