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