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