use the auto-generated UUID, version and name rather than listing them
[bbaumbach/samba-autobuild/.git] / source4 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-2003
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 static int nprocs=4;
24 int torture_numops=100;
25 int torture_entries=1000;
26 int torture_failures=1;
27 static int procnum; /* records process count number when forking */
28 static struct cli_state *current_cli;
29 static char *randomfname;
30 static BOOL use_oplocks;
31 static BOOL use_level_II_oplocks;
32 static const char *client_txt = "client_oplocks.txt";
33 static BOOL use_kerberos;
34
35 BOOL torture_showall = False;
36
37 static double create_procs(BOOL (*fn)(int), BOOL *result);
38
39 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
40
41 static struct cli_state *open_nbt_connection(void)
42 {
43         struct nmb_name called, calling;
44         struct in_addr ip;
45         struct cli_state *cli;
46         char *host = lp_parm_string(-1, "torture", "host");
47
48         make_nmb_name(&calling, lp_netbios_name(), 0x0);
49         make_nmb_name(&called , host, 0x20);
50
51         zero_ip(&ip);
52
53         cli = cli_state_init();
54         if (!cli) {
55                 printf("Failed initialize cli_struct to connect with %s\n", host);
56                 return NULL;
57         }
58
59         if (!cli_socket_connect(cli, host, &ip)) {
60                 printf("Failed to connect with %s\n", host);
61                 return cli;
62         }
63
64         cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
65
66         if (!cli_transport_establish(cli, &calling, &called)) {
67                 /*
68                  * Well, that failed, try *SMBSERVER ... 
69                  * However, we must reconnect as well ...
70                  */
71                 if (!cli_socket_connect(cli, host, &ip)) {
72                         printf("Failed to connect with %s\n", host);
73                         return False;
74                 }
75
76                 make_nmb_name(&called, "*SMBSERVER", 0x20);
77                 if (!cli_transport_establish(cli, &calling, &called)) {
78                         printf("%s rejected the session\n",host);
79                         printf("We tried with a called name of %s & %s\n",
80                                 host, "*SMBSERVER");
81                         cli_shutdown(cli);
82                         return NULL;
83                 }
84         }
85
86         return cli;
87 }
88
89 BOOL torture_open_connection(struct cli_state **c)
90 {
91         BOOL retry;
92         int flags = 0;
93         NTSTATUS status;
94         char *host = lp_parm_string(-1, "torture", "host");
95         char *share = lp_parm_string(-1, "torture", "share");
96         char *username = lp_parm_string(-1, "torture", "username");
97         char *password = lp_parm_string(-1, "torture", "password");
98
99         if (use_kerberos)
100                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
101
102         status = cli_full_connection(c, lp_netbios_name(),
103                                      host, NULL, 
104                                      share, "?????", 
105                                      username, username[0]?lp_workgroup():"",
106                                      password, flags, &retry);
107         if (!NT_STATUS_IS_OK(status)) {
108                 printf("Failed to open connection - %s\n", nt_errstr(status));
109                 return False;
110         }
111
112         (*c)->transport->options.use_oplocks = use_oplocks;
113         (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
114         (*c)->transport->socket->timeout = 120000;
115
116         return True;
117 }
118
119 BOOL torture_close_connection(struct cli_state *c)
120 {
121         BOOL ret = True;
122         DEBUG(9,("torture_close_connection: cli_state@%p\n", c));
123         if (!c) return True;
124         if (!cli_tdis(c)) {
125                 printf("tdis failed (%s)\n", cli_errstr(c));
126                 ret = False;
127         }
128         DEBUG(9,("torture_close_connection: call cli_shutdown\n"));
129         cli_shutdown(c);
130         DEBUG(9,("torture_close_connection: exit\n"));
131         return ret;
132 }
133
134 /* open a rpc connection to a named pipe */
135 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p, 
136                                 const char *pipe_name,
137                                 const char *pipe_uuid, 
138                                 uint32 pipe_version)
139 {
140         struct cli_state *cli;
141         NTSTATUS status;
142
143         if (!torture_open_connection(&cli)) {
144                 return NT_STATUS_UNSUCCESSFUL;
145         }
146
147         if (!(*p = dcerpc_pipe_init(cli->tree))) {
148                 return NT_STATUS_NO_MEMORY;
149         }
150  
151         status = dcerpc_pipe_open_smb(*p, pipe_name, pipe_uuid, pipe_version);
152         if (!NT_STATUS_IS_OK(status)) {
153                 printf("Open of pipe '%s' failed with error (%s)\n",
154                        pipe_name, nt_errstr(status));
155                 return status;
156         }
157  
158         return status;
159 }
160
161 /* close a rpc connection to a named pipe */
162 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
163 {
164         union smb_close io;
165         NTSTATUS status;
166
167         io.close.level = RAW_CLOSE_CLOSE;
168         io.close.in.fnum = p->fnum;
169         io.close.in.write_time = 0;
170         status = smb_raw_close(p->tree, &io);
171
172         dcerpc_pipe_close(p);
173
174         return status;
175 }
176
177
178 /* check if the server produced the expected error code */
179 static BOOL check_error(int line, struct cli_state *c, 
180                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
181 {
182         if (cli_is_dos_error(c)) {
183                 uint8 class;
184                 uint32 num;
185
186                 /* Check DOS error */
187
188                 cli_dos_error(c, &class, &num);
189
190                 if (eclass != class || ecode != num) {
191                         printf("unexpected error code class=%d code=%d\n", 
192                                (int)class, (int)num);
193                         printf(" expected %d/%d %s (line=%d)\n", 
194                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
195                         return False;
196                 }
197
198         } else {
199                 NTSTATUS status;
200
201                 /* Check NT error */
202
203                 status = cli_nt_error(c);
204
205                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
206                         printf("unexpected error code %s\n", nt_errstr(status));
207                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
208                         return False;
209                 }
210         }
211
212         return True;
213 }
214
215
216 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
217 {
218         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
219                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
220         }
221         return True;
222 }
223
224
225 static BOOL rw_torture(struct cli_state *c)
226 {
227         const char *lockfname = "\\torture.lck";
228         char *fname;
229         int fnum;
230         int fnum2;
231         pid_t pid2, pid = getpid();
232         int i, j;
233         char buf[1024];
234         BOOL correct = True;
235
236         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
237                          DENY_NONE);
238         if (fnum2 == -1)
239                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
240         if (fnum2 == -1) {
241                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
242                 return False;
243         }
244
245
246         for (i=0;i<torture_numops;i++) {
247                 unsigned n = (unsigned)sys_random()%10;
248                 if (i % 10 == 0) {
249                         printf("%d\r", i); fflush(stdout);
250                 }
251                 asprintf(&fname, "\\torture.%u", n);
252
253                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
254                         return False;
255                 }
256
257                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
258                 if (fnum == -1) {
259                         printf("open failed (%s)\n", cli_errstr(c));
260                         correct = False;
261                         break;
262                 }
263
264                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
265                         printf("write failed (%s)\n", cli_errstr(c));
266                         correct = False;
267                 }
268
269                 for (j=0;j<50;j++) {
270                         if (cli_write(c, fnum, 0, (char *)buf, 
271                                       sizeof(pid)+(j*sizeof(buf)), 
272                                       sizeof(buf)) != sizeof(buf)) {
273                                 printf("write failed (%s)\n", cli_errstr(c));
274                                 correct = False;
275                         }
276                 }
277
278                 pid2 = 0;
279
280                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
281                         printf("read failed (%s)\n", cli_errstr(c));
282                         correct = False;
283                 }
284
285                 if (pid2 != pid) {
286                         printf("data corruption!\n");
287                         correct = False;
288                 }
289
290                 if (!cli_close(c, fnum)) {
291                         printf("close failed (%s)\n", cli_errstr(c));
292                         correct = False;
293                 }
294
295                 if (!cli_unlink(c, fname)) {
296                         printf("unlink failed (%s)\n", cli_errstr(c));
297                         correct = False;
298                 }
299
300                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
301                         printf("unlock failed (%s)\n", cli_errstr(c));
302                         correct = False;
303                 }
304                 free(fname);
305         }
306
307         cli_close(c, fnum2);
308         cli_unlink(c, lockfname);
309
310         printf("%d\n", i);
311
312         return correct;
313 }
314
315 static BOOL run_torture(int dummy)
316 {
317         struct cli_state *cli;
318         BOOL ret;
319
320         cli = current_cli;
321
322         ret = rw_torture(cli);
323         
324         if (!torture_close_connection(cli)) {
325                 ret = False;
326         }
327
328         return ret;
329 }
330
331 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
332 {
333         int fnum = -1;
334         unsigned int i = 0;
335         char buf[131072];
336         char buf_rd[131072];
337         unsigned count;
338         unsigned countprev = 0;
339         ssize_t sent = 0;
340         BOOL correct = True;
341
342         srandom(1);
343         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
344         {
345                 SIVAL(buf, i, sys_random());
346         }
347
348         if (procnum == 0)
349         {
350                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
351                                  DENY_NONE);
352                 if (fnum == -1) {
353                         printf("first open read/write of %s failed (%s)\n",
354                                         lockfname, cli_errstr(c));
355                         return False;
356                 }
357         }
358         else
359         {
360                 for (i = 0; i < 500 && fnum == -1; i++)
361                 {
362                         fnum = cli_open(c, lockfname, O_RDONLY, 
363                                          DENY_NONE);
364                         msleep(10);
365                 }
366                 if (fnum == -1) {
367                         printf("second open read-only of %s failed (%s)\n",
368                                         lockfname, cli_errstr(c));
369                         return False;
370                 }
371         }
372
373         i = 0;
374         for (count = 0; count < sizeof(buf); count += sent)
375         {
376                 if (count >= countprev) {
377                         printf("%d %8d\r", i, count);
378                         fflush(stdout);
379                         i++;
380                         countprev += (sizeof(buf) / 20);
381                 }
382
383                 if (procnum == 0)
384                 {
385                         sent = ((unsigned)sys_random()%(20))+ 1;
386                         if (sent > sizeof(buf) - count)
387                         {
388                                 sent = sizeof(buf) - count;
389                         }
390
391                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
392                                 printf("write failed (%s)\n", cli_errstr(c));
393                                 correct = False;
394                         }
395                 }
396                 else
397                 {
398                         sent = cli_read(c, fnum, buf_rd+count, count,
399                                                   sizeof(buf)-count);
400                         if (sent < 0)
401                         {
402                                 printf("read failed offset:%d size:%d (%s)\n",
403                                                 count, sizeof(buf)-count,
404                                                 cli_errstr(c));
405                                 correct = False;
406                                 sent = 0;
407                         }
408                         if (sent > 0)
409                         {
410                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
411                                 {
412                                         printf("read/write compare failed\n");
413                                         printf("offset: %d req %d recvd %d\n",
414                                                 count, sizeof(buf)-count, sent);
415                                         correct = False;
416                                         break;
417                                 }
418                         }
419                 }
420
421         }
422
423         if (!cli_close(c, fnum)) {
424                 printf("close failed (%s)\n", cli_errstr(c));
425                 correct = False;
426         }
427
428         return correct;
429 }
430
431 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
432 {
433         const char *lockfname = "\\torture2.lck";
434         int fnum1;
435         int fnum2;
436         int i;
437         uchar buf[131072];
438         uchar buf_rd[131072];
439         BOOL correct = True;
440         ssize_t bytes_read, bytes_written;
441
442         if (cli_deltree(c1, lockfname) == -1) {
443                 printf("unlink failed (%s)\n", cli_errstr(c1));
444         }
445
446         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
447                          DENY_NONE);
448         if (fnum1 == -1) {
449                 printf("first open read/write of %s failed (%s)\n",
450                                 lockfname, cli_errstr(c1));
451                 return False;
452         }
453         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
454                          DENY_NONE);
455         if (fnum2 == -1) {
456                 printf("second open read-only of %s failed (%s)\n",
457                                 lockfname, cli_errstr(c2));
458                 cli_close(c1, fnum1);
459                 return False;
460         }
461
462         printf("Checking data integrity over %d ops\n", torture_numops);
463
464         for (i=0;i<torture_numops;i++)
465         {
466                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
467                 if (i % 10 == 0) {
468                         printf("%d\r", i); fflush(stdout);
469                 }
470
471                 generate_random_buffer(buf, buf_size, False);
472
473                 if ((bytes_written = cli_write(c1, fnum1, 0, buf, 0, buf_size)) != buf_size) {
474                         printf("write failed (%s)\n", cli_errstr(c1));
475                         printf("wrote %d, expected %d\n", bytes_written, buf_size); 
476                         correct = False;
477                         break;
478                 }
479
480                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
481                         printf("read failed (%s)\n", cli_errstr(c2));
482                         printf("read %d, expected %d\n", bytes_read, buf_size); 
483                         correct = False;
484                         break;
485                 }
486
487                 if (memcmp(buf_rd, buf, buf_size) != 0)
488                 {
489                         printf("read/write compare failed\n");
490                         correct = False;
491                         break;
492                 }
493         }
494
495         if (!cli_close(c2, fnum2)) {
496                 printf("close failed (%s)\n", cli_errstr(c2));
497                 correct = False;
498         }
499         if (!cli_close(c1, fnum1)) {
500                 printf("close failed (%s)\n", cli_errstr(c1));
501                 correct = False;
502         }
503
504         if (!cli_unlink(c1, lockfname)) {
505                 printf("unlink failed (%s)\n", cli_errstr(c1));
506                 correct = False;
507         }
508
509         return correct;
510 }
511
512 static BOOL run_readwritetest(int dummy)
513 {
514         struct cli_state *cli1, *cli2;
515         BOOL test1, test2 = True;
516
517         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
518                 return False;
519         }
520
521         printf("starting readwritetest\n");
522
523         test1 = rw_torture2(cli1, cli2);
524         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
525
526         if (test1) {
527                 test2 = rw_torture2(cli1, cli1);
528                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
529         }
530
531         if (!torture_close_connection(cli1)) {
532                 test1 = False;
533         }
534
535         if (!torture_close_connection(cli2)) {
536                 test2 = False;
537         }
538
539         return (test1 && test2);
540 }
541
542 static BOOL run_readwritemulti(int dummy)
543 {
544         struct cli_state *cli;
545         BOOL test;
546
547         cli = current_cli;
548
549         printf("run_readwritemulti: fname %s\n", randomfname);
550         test = rw_torture3(cli, randomfname);
551
552         if (!torture_close_connection(cli)) {
553                 test = False;
554         }
555         
556         return test;
557 }
558
559
560 int line_count = 0;
561 int nbio_id;
562
563 #define ival(s) strtol(s, NULL, 0)
564
565 /* run a test that simulates an approximate netbench client load */
566 static BOOL run_netbench(int client)
567 {
568         struct cli_state *cli;
569         int i;
570         pstring line;
571         char *cname;
572         FILE *f;
573         const char *params[20];
574         BOOL correct = True;
575
576         cli = current_cli;
577
578         nbio_id = client;
579
580         nb_setup(cli);
581
582         asprintf(&cname, "client%d", client);
583
584         f = fopen(client_txt, "r");
585
586         if (!f) {
587                 perror(client_txt);
588                 return False;
589         }
590
591         while (fgets(line, sizeof(line)-1, f)) {
592                 line_count++;
593
594                 line[strlen(line)-1] = 0;
595
596                 /* printf("[%d] %s\n", line_count, line); */
597
598                 all_string_sub(line,"client1", cname, sizeof(line));
599                 
600                 /* parse the command parameters */
601                 params[0] = strtok(line," ");
602                 i = 0;
603                 while (params[i]) params[++i] = strtok(NULL," ");
604
605                 params[i] = "";
606
607                 if (i < 2) continue;
608
609                 if (!strncmp(params[0],"SMB", 3)) {
610                         printf("ERROR: You are using a dbench 1 load file\n");
611                         exit(1);
612                 }
613                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
614
615                 if (!strcmp(params[0],"NTCreateX")) {
616                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
617                                    ival(params[4]));
618                 } else if (!strcmp(params[0],"Close")) {
619                         nb_close(ival(params[1]));
620                 } else if (!strcmp(params[0],"Rename")) {
621                         nb_rename(params[1], params[2]);
622                 } else if (!strcmp(params[0],"Unlink")) {
623                         nb_unlink(params[1]);
624                 } else if (!strcmp(params[0],"Deltree")) {
625                         nb_deltree(params[1]);
626                 } else if (!strcmp(params[0],"Rmdir")) {
627                         nb_rmdir(params[1]);
628                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
629                         nb_qpathinfo(params[1]);
630                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
631                         nb_qfileinfo(ival(params[1]));
632                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
633                         nb_qfsinfo(ival(params[1]));
634                 } else if (!strcmp(params[0],"FIND_FIRST")) {
635                         nb_findfirst(params[1]);
636                 } else if (!strcmp(params[0],"WriteX")) {
637                         nb_writex(ival(params[1]), 
638                                 ival(params[2]), ival(params[3]), ival(params[4]));
639                 } else if (!strcmp(params[0],"ReadX")) {
640                         nb_readx(ival(params[1]), 
641                       ival(params[2]), ival(params[3]), ival(params[4]));
642                 } else if (!strcmp(params[0],"Flush")) {
643                         nb_flush(ival(params[1]));
644                 } else {
645                         printf("Unknown operation %s\n", params[0]);
646                         exit(1);
647                 }
648         }
649         fclose(f);
650
651         nb_cleanup();
652
653         if (!torture_close_connection(cli)) {
654                 correct = False;
655         }
656         
657         return correct;
658 }
659
660
661 /* run a test that simulates an approximate netbench client load */
662 static BOOL run_nbench(int dummy)
663 {
664         double t;
665         BOOL correct = True;
666
667         nbio_shmem(nprocs);
668
669         nbio_id = -1;
670
671         signal(SIGALRM, SIGNAL_CAST nb_alarm);
672         alarm(1);
673         t = create_procs(run_netbench, &correct);
674         alarm(0);
675
676         printf("\nThroughput %g MB/sec\n", 
677                1.0e-6 * nbio_total() / t);
678         return correct;
679 }
680
681
682 /*
683   This test checks for two things:
684
685   1) correct support for retaining locks over a close (ie. the server
686      must not use posix semantics)
687   2) support for lock timeouts
688  */
689 static BOOL run_locktest1(int dummy)
690 {
691         struct cli_state *cli1, *cli2;
692         const char *fname = "\\lockt1.lck";
693         int fnum1, fnum2, fnum3;
694         time_t t1, t2;
695         unsigned lock_timeout;
696
697         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
698                 return False;
699         }
700
701         printf("starting locktest1\n");
702
703         cli_unlink(cli1, fname);
704
705         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
706         if (fnum1 == -1) {
707                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
708                 return False;
709         }
710         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
711         if (fnum2 == -1) {
712                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
713                 return False;
714         }
715         fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
716         if (fnum3 == -1) {
717                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
718                 return False;
719         }
720
721         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
722                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
723                 return False;
724         }
725
726
727         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
728                 printf("lock2 succeeded! This is a locking bug\n");
729                 return False;
730         } else {
731                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
732                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
733         }
734
735
736         lock_timeout = (6 + (random() % 20));
737         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
738         t1 = time(NULL);
739         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
740                 printf("lock3 succeeded! This is a locking bug\n");
741                 return False;
742         } else {
743                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
744                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
745         }
746         t2 = time(NULL);
747
748         if (t2 - t1 < 5) {
749                 printf("error: This server appears not to support timed lock requests\n");
750         }
751         printf("server slept for %u seconds for a %u second timeout\n",
752                (unsigned int)(t2-t1), lock_timeout);
753
754         if (!cli_close(cli1, fnum2)) {
755                 printf("close1 failed (%s)\n", cli_errstr(cli1));
756                 return False;
757         }
758
759         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
760                 printf("lock4 succeeded! This is a locking bug\n");
761                 return False;
762         } else {
763                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
764                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
765         }
766
767         if (!cli_close(cli1, fnum1)) {
768                 printf("close2 failed (%s)\n", cli_errstr(cli1));
769                 return False;
770         }
771
772         if (!cli_close(cli2, fnum3)) {
773                 printf("close3 failed (%s)\n", cli_errstr(cli2));
774                 return False;
775         }
776
777         if (!cli_unlink(cli1, fname)) {
778                 printf("unlink failed (%s)\n", cli_errstr(cli1));
779                 return False;
780         }
781
782
783         if (!torture_close_connection(cli1)) {
784                 return False;
785         }
786
787         if (!torture_close_connection(cli2)) {
788                 return False;
789         }
790
791         printf("Passed locktest1\n");
792         return True;
793 }
794
795 /*
796   this checks to see if a secondary tconx can use open files from an
797   earlier tconx
798  */
799 static BOOL run_tcon_test(int dummy)
800 {
801         struct cli_state *cli;
802         const char *fname = "\\tcontest.tmp";
803         int fnum1;
804         uint16 cnum1, cnum2, cnum3;
805         uint16 vuid1, vuid2;
806         char buf[4];
807         BOOL ret = True;
808         struct cli_tree *tree1;
809         char *host = lp_parm_string(-1, "torture", "host");
810         char *share = lp_parm_string(-1, "torture", "share");
811         char *password = lp_parm_string(-1, "torture", "password");
812
813         if (!torture_open_connection(&cli)) {
814                 return False;
815         }
816
817         printf("starting tcontest\n");
818
819         if (cli_deltree(cli, fname) == -1) {
820                 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli));
821         }
822
823         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
824         if (fnum1 == -1) {
825                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
826                 return False;
827         }
828
829         cnum1 = cli->tree->tid;
830         vuid1 = cli->session->vuid;
831
832         memset(&buf, 0, 4); /* init buf so valgrind won't complain */
833         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
834                 printf("initial write failed (%s)\n", cli_errstr(cli));
835                 return False;
836         }
837
838         tree1 = cli->tree;      /* save old tree connection */
839         if (!cli_send_tconX(cli, share, "?????",
840                             password)) {
841                 printf("%s refused 2nd tree connect (%s)\n", host,
842                            cli_errstr(cli));
843                 cli_shutdown(cli);
844                 return False;
845         }
846
847         cnum2 = cli->tree->tid;
848         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
849         vuid2 = cli->session->vuid + 1;
850
851         /* try a write with the wrong tid */
852         cli->tree->tid = cnum2;
853
854         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
855                 printf("* server allows write with wrong TID\n");
856                 ret = False;
857         } else {
858                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
859         }
860
861
862         /* try a write with an invalid tid */
863         cli->tree->tid = cnum3;
864
865         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
866                 printf("* server allows write with invalid TID\n");
867                 ret = False;
868         } else {
869                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
870         }
871
872         /* try a write with an invalid vuid */
873         cli->session->vuid = vuid2;
874         cli->tree->tid = cnum1;
875
876         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
877                 printf("* server allows write with invalid VUID\n");
878                 ret = False;
879         } else {
880                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
881         }
882
883         cli->session->vuid = vuid1;
884         cli->tree->tid = cnum1;
885
886         if (!cli_close(cli, fnum1)) {
887                 printf("close failed (%s)\n", cli_errstr(cli));
888                 return False;
889         }
890
891         cli->tree->tid = cnum2;
892
893         if (!cli_tdis(cli)) {
894                 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
895                 return False;
896         }
897
898         cli->tree = tree1;  /* restore initial tree */
899         cli->tree->tid = cnum1;
900
901         if (!torture_close_connection(cli)) {
902                 return False;
903         }
904
905         return ret;
906 }
907
908
909
910 static BOOL tcon_devtest(struct cli_state *cli,
911                          const char *myshare, const char *devtype,
912                          NTSTATUS expected_error)
913 {
914         BOOL status;
915         BOOL ret;
916         char *password = lp_parm_string(-1, "torture", "password");
917
918         status = cli_send_tconX(cli, myshare, devtype,
919                                 password);
920
921         printf("Trying share %s with devtype %s\n", myshare, devtype);
922
923         if (NT_STATUS_IS_OK(expected_error)) {
924                 if (status) {
925                         ret = True;
926                 } else {
927                         printf("tconX to share %s with type %s "
928                                "should have succeeded but failed\n",
929                                myshare, devtype);
930                         ret = False;
931                 }
932                 cli_tdis(cli);
933         } else {
934                 if (status) {
935                         printf("tconx to share %s with type %s "
936                                "should have failed but succeeded\n",
937                                myshare, devtype);
938                         ret = False;
939                 } else {
940                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
941                                             expected_error)) {
942                                 ret = True;
943                         } else {
944                                 printf("Returned unexpected error\n");
945                                 ret = False;
946                         }
947                 }
948         }
949         return ret;
950 }
951
952 /*
953  checks for correct tconX support
954  */
955 static BOOL run_tcon_devtype_test(int dummy)
956 {
957         struct cli_state *cli1 = NULL;
958         BOOL retry;
959         int flags = 0;
960         NTSTATUS status;
961         BOOL ret = True;
962         char *host = lp_parm_string(-1, "torture", "host");
963         char *share = lp_parm_string(-1, "torture", "share");
964         char *username = lp_parm_string(-1, "torture", "username");
965         char *password = lp_parm_string(-1, "torture", "password");
966         
967         status = cli_full_connection(&cli1, lp_netbios_name(),
968                                      host, NULL, 
969                                      share, "?????",
970                                      username, lp_workgroup(),
971                                      password, flags, &retry);
972
973         if (!NT_STATUS_IS_OK(status)) {
974                 printf("could not open connection\n");
975                 return False;
976         }
977
978         if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
979                 ret = False;
980
981         if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
982                 ret = False;
983
984         if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
985                 ret = False;
986
987         if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
988                 ret = False;
989                         
990         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
991                 ret = False;
992
993         if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
994                 ret = False;
995
996         if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
997                 ret = False;
998
999         if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1000                 ret = False;
1001
1002         if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
1003                 ret = False;
1004                         
1005         if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1006                 ret = False;
1007
1008         cli_shutdown(cli1);
1009
1010         if (ret)
1011                 printf("Passed tcondevtest\n");
1012
1013         return ret;
1014 }
1015
1016
1017 /*
1018   This test checks that 
1019
1020   1) the server supports multiple locking contexts on the one SMB
1021   connection, distinguished by PID.  
1022
1023   2) the server correctly fails overlapping locks made by the same PID (this
1024      goes against POSIX behaviour, which is why it is tricky to implement)
1025
1026   3) the server denies unlock requests by an incorrect client PID
1027 */
1028 static BOOL run_locktest2(int dummy)
1029 {
1030         struct cli_state *cli;
1031         const char *fname = "\\lockt2.lck";
1032         int fnum1, fnum2, fnum3;
1033         BOOL correct = True;
1034
1035         if (!torture_open_connection(&cli)) {
1036                 return False;
1037         }
1038
1039         printf("starting locktest2\n");
1040
1041         cli_unlink(cli, fname);
1042
1043         printf("Testing pid context\n");
1044         
1045         cli->session->pid = 1;
1046
1047         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1048         if (fnum1 == -1) {
1049                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1050                 return False;
1051         }
1052
1053         fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1054         if (fnum2 == -1) {
1055                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1056                 return False;
1057         }
1058
1059         cli->session->pid = 2;
1060
1061         fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1062         if (fnum3 == -1) {
1063                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1064                 return False;
1065         }
1066
1067         cli->session->pid = 1;
1068
1069         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1070                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1071                 return False;
1072         }
1073
1074         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1075                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1076                 correct = False;
1077         } else {
1078                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1079                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1080         }
1081
1082         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1083                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1084                 correct = False;
1085         } else {
1086                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1087                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1088         }
1089
1090         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1091                 printf("READ lock2 succeeded! This is a locking bug\n");
1092                 correct = False;
1093         } else {
1094                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1095                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1096         }
1097
1098         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1099                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1100         }
1101
1102         cli->session->pid = 2;
1103
1104         if (cli_unlock(cli, fnum1, 100, 4)) {
1105                 printf("unlock at 100 succeeded! This is a locking bug\n");
1106                 correct = False;
1107         }
1108
1109         if (cli_unlock(cli, fnum1, 0, 4)) {
1110                 printf("unlock1 succeeded! This is a locking bug\n");
1111                 correct = False;
1112         } else {
1113                 if (!check_error(__LINE__, cli, 
1114                                  ERRDOS, ERRlock, 
1115                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1116         }
1117
1118         if (cli_unlock(cli, fnum1, 0, 8)) {
1119                 printf("unlock2 succeeded! This is a locking bug\n");
1120                 correct = False;
1121         } else {
1122                 if (!check_error(__LINE__, cli, 
1123                                  ERRDOS, ERRlock, 
1124                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1125         }
1126
1127         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1128                 printf("lock3 succeeded! This is a locking bug\n");
1129                 correct = False;
1130         } else {
1131                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1132         }
1133
1134         cli->session->pid = 1;
1135
1136         if (!cli_close(cli, fnum1)) {
1137                 printf("close1 failed (%s)\n", cli_errstr(cli));
1138                 return False;
1139         }
1140
1141         if (!cli_close(cli, fnum2)) {
1142                 printf("close2 failed (%s)\n", cli_errstr(cli));
1143                 return False;
1144         }
1145
1146         if (!cli_close(cli, fnum3)) {
1147                 printf("close3 failed (%s)\n", cli_errstr(cli));
1148                 return False;
1149         }
1150
1151         if (!torture_close_connection(cli)) {
1152                 correct = False;
1153         }
1154
1155         printf("locktest2 finished\n");
1156
1157         return correct;
1158 }
1159
1160
1161 /*
1162   This test checks that 
1163
1164   1) the server supports the full offset range in lock requests
1165 */
1166 static BOOL run_locktest3(int dummy)
1167 {
1168         struct cli_state *cli1, *cli2;
1169         const char *fname = "\\lockt3.lck";
1170         int fnum1, fnum2, i;
1171         uint32 offset;
1172         BOOL correct = True;
1173
1174 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1175
1176         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1177                 return False;
1178         }
1179
1180         printf("starting locktest3\n");
1181
1182         printf("Testing 32 bit offset ranges\n");
1183
1184         cli_unlink(cli1, fname);
1185
1186         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1187         if (fnum1 == -1) {
1188                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1189                 return False;
1190         }
1191         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1192         if (fnum2 == -1) {
1193                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1194                 return False;
1195         }
1196
1197         printf("Establishing %d locks\n", torture_numops);
1198
1199         for (offset=i=0;i<torture_numops;i++) {
1200                 NEXT_OFFSET;
1201                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1202                         printf("lock1 %d failed (%s)\n", 
1203                                i,
1204                                cli_errstr(cli1));
1205                         return False;
1206                 }
1207
1208                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1209                         printf("lock2 %d failed (%s)\n", 
1210                                i,
1211                                cli_errstr(cli1));
1212                         return False;
1213                 }
1214         }
1215
1216         printf("Testing %d locks\n", torture_numops);
1217
1218         for (offset=i=0;i<torture_numops;i++) {
1219                 NEXT_OFFSET;
1220
1221                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1222                         printf("error: lock1 %d succeeded!\n", i);
1223                         return False;
1224                 }
1225
1226                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1227                         printf("error: lock2 %d succeeded!\n", i);
1228                         return False;
1229                 }
1230
1231                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1232                         printf("error: lock3 %d succeeded!\n", i);
1233                         return False;
1234                 }
1235
1236                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1237                         printf("error: lock4 %d succeeded!\n", i);
1238                         return False;
1239                 }
1240         }
1241
1242         printf("Removing %d locks\n", torture_numops);
1243
1244         for (offset=i=0;i<torture_numops;i++) {
1245                 NEXT_OFFSET;
1246
1247                 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1248                         printf("unlock1 %d failed (%s)\n", 
1249                                i,
1250                                cli_errstr(cli1));
1251                         return False;
1252                 }
1253
1254                 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1255                         printf("unlock2 %d failed (%s)\n", 
1256                                i,
1257                                cli_errstr(cli1));
1258                         return False;
1259                 }
1260         }
1261
1262         if (!cli_close(cli1, fnum1)) {
1263                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1264                 return False;
1265         }
1266
1267         if (!cli_close(cli2, fnum2)) {
1268                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1269                 return False;
1270         }
1271
1272         if (!cli_unlink(cli1, fname)) {
1273                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1274                 return False;
1275         }
1276
1277         if (!torture_close_connection(cli1)) {
1278                 correct = False;
1279         }
1280         
1281         if (!torture_close_connection(cli2)) {
1282                 correct = False;
1283         }
1284
1285         printf("finished locktest3\n");
1286
1287         return correct;
1288 }
1289
1290 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1291         printf("** "); correct = False; \
1292         }
1293
1294 /*
1295   looks at overlapping locks
1296 */
1297 static BOOL run_locktest4(int dummy)
1298 {
1299         struct cli_state *cli1, *cli2;
1300         const char *fname = "\\lockt4.lck";
1301         int fnum1, fnum2, f;
1302         BOOL ret;
1303         char buf[1000];
1304         BOOL correct = True;
1305
1306         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1307                 return False;
1308         }
1309
1310         printf("starting locktest4\n");
1311
1312         cli_unlink(cli1, fname);
1313
1314         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1315         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1316
1317         memset(buf, 0, sizeof(buf));
1318
1319         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1320                 printf("Failed to create file\n");
1321                 correct = False;
1322                 goto fail;
1323         }
1324
1325         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1326               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1327         EXPECTED(ret, False);
1328         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1329             
1330         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1331               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1332         EXPECTED(ret, True);
1333         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1334
1335         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1336               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1337         EXPECTED(ret, False);
1338         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1339             
1340         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1341               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1342         EXPECTED(ret, True);
1343         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1344         
1345         ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1346               (cli1->session->pid = 2, cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1347         EXPECTED(ret, False);
1348         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1349             
1350         ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1351               (cli1->session->pid = 2, cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1352         EXPECTED(ret, True);
1353         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1354
1355         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1356               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1357         EXPECTED(ret, True);
1358         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1359
1360         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1361               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1362         EXPECTED(ret, False);
1363         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1364
1365         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1366               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1367         EXPECTED(ret, False);
1368         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1369
1370         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1371               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1372         EXPECTED(ret, True);
1373         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1374
1375         ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1376               (cli1->session->pid = 2, cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1377         EXPECTED(ret, False);
1378         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1379
1380         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1381               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1382               cli_unlock(cli1, fnum1, 110, 6);
1383         EXPECTED(ret, False);
1384         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1385
1386
1387         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1388               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1389         EXPECTED(ret, False);
1390         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1391
1392         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1393               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1394         EXPECTED(ret, False);
1395         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1396
1397
1398         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1399               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1400               cli_unlock(cli1, fnum1, 140, 4) &&
1401               cli_unlock(cli1, fnum1, 140, 4);
1402         EXPECTED(ret, True);
1403         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1404
1405
1406         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1407               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1408               cli_unlock(cli1, fnum1, 150, 4) &&
1409               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1410               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1411               cli_unlock(cli1, fnum1, 150, 4);
1412         EXPECTED(ret, True);
1413         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1414
1415         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1416               cli_unlock(cli1, fnum1, 160, 4) &&
1417               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1418               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1419         EXPECTED(ret, True);
1420         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1421
1422         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1423               cli_unlock(cli1, fnum1, 170, 4) &&
1424               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1425               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1426         EXPECTED(ret, True);
1427         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1428
1429         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1430               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1431               cli_unlock(cli1, fnum1, 190, 4) &&
1432               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1433               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1434         EXPECTED(ret, True);
1435         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1436
1437         cli_close(cli1, fnum1);
1438         cli_close(cli2, fnum2);
1439         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1440         f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1441         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1442               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1443               cli_close(cli1, fnum1) &&
1444               ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1445               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1446         cli_close(cli1, f);
1447         cli_close(cli1, fnum1);
1448         EXPECTED(ret, True);
1449         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1450
1451  fail:
1452         cli_close(cli1, fnum1);
1453         cli_close(cli2, fnum2);
1454         cli_unlink(cli1, fname);
1455         torture_close_connection(cli1);
1456         torture_close_connection(cli2);
1457
1458         printf("finished locktest4\n");
1459         return correct;
1460 }
1461
1462 /*
1463   looks at lock upgrade/downgrade.
1464 */
1465 static BOOL run_locktest5(int dummy)
1466 {
1467         struct cli_state *cli1, *cli2;
1468         const char *fname = "\\lockt5.lck";
1469         int fnum1, fnum2, fnum3;
1470         BOOL ret;
1471         char buf[1000];
1472         BOOL correct = True;
1473
1474         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1475                 return False;
1476         }
1477
1478         printf("starting locktest5\n");
1479
1480         cli_unlink(cli1, fname);
1481
1482         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1483         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1484         fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1485
1486         memset(buf, 0, sizeof(buf));
1487
1488         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1489                 printf("Failed to create file\n");
1490                 correct = False;
1491                 goto fail;
1492         }
1493
1494         /* Check for NT bug... */
1495         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1496                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1497         cli_close(cli1, fnum1);
1498         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1499         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1500         EXPECTED(ret, True);
1501         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1502         cli_close(cli1, fnum1);
1503         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1504         cli_unlock(cli1, fnum3, 0, 1);
1505
1506         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1507               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1508         EXPECTED(ret, True);
1509         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1510
1511         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1512         EXPECTED(ret, False);
1513
1514         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1515
1516         /* Unlock the process 2 lock. */
1517         cli_unlock(cli2, fnum2, 0, 4);
1518
1519         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1520         EXPECTED(ret, False);
1521
1522         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1523
1524         /* Unlock the process 1 fnum3 lock. */
1525         cli_unlock(cli1, fnum3, 0, 4);
1526
1527         /* Stack 2 more locks here. */
1528         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1529                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1530
1531         EXPECTED(ret, True);
1532         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1533
1534         /* Unlock the first process lock, then check this was the WRITE lock that was
1535                 removed. */
1536
1537         ret = cli_unlock(cli1, fnum1, 0, 4) &&
1538                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1539
1540         EXPECTED(ret, True);
1541         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1542
1543         /* Unlock the process 2 lock. */
1544         cli_unlock(cli2, fnum2, 0, 4);
1545
1546         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1547
1548         ret = cli_unlock(cli1, fnum1, 1, 1) &&
1549                   cli_unlock(cli1, fnum1, 0, 4) &&
1550                   cli_unlock(cli1, fnum1, 0, 4);
1551
1552         EXPECTED(ret, True);
1553         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1554
1555         /* Ensure the next unlock fails. */
1556         ret = cli_unlock(cli1, fnum1, 0, 4);
1557         EXPECTED(ret, False);
1558         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1559
1560         /* Ensure connection 2 can get a write lock. */
1561         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1562         EXPECTED(ret, True);
1563
1564         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1565
1566
1567  fail:
1568         cli_close(cli1, fnum1);
1569         cli_close(cli2, fnum2);
1570         cli_unlink(cli1, fname);
1571         if (!torture_close_connection(cli1)) {
1572                 correct = False;
1573         }
1574         if (!torture_close_connection(cli2)) {
1575                 correct = False;
1576         }
1577
1578         printf("finished locktest5\n");
1579        
1580         return correct;
1581 }
1582
1583 /*
1584   tries the unusual lockingX locktype bits
1585 */
1586 static BOOL run_locktest6(int dummy)
1587 {
1588         struct cli_state *cli;
1589         const char *fname[1] = { "\\lock6.txt" };
1590         int i;
1591         int fnum;
1592         NTSTATUS status;
1593
1594         if (!torture_open_connection(&cli)) {
1595                 return False;
1596         }
1597
1598         printf("starting locktest6\n");
1599
1600         for (i=0;i<1;i++) {
1601                 printf("Testing %s\n", fname[i]);
1602
1603                 cli_unlink(cli, fname[i]);
1604
1605                 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1606                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1607                 cli_close(cli, fnum);
1608                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1609
1610                 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1611                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1612                 cli_close(cli, fnum);
1613                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1614
1615                 cli_unlink(cli, fname[i]);
1616         }
1617
1618         torture_close_connection(cli);
1619
1620         printf("finished locktest6\n");
1621         return True;
1622 }
1623
1624 static BOOL run_locktest7(int dummy)
1625 {
1626         struct cli_state *cli1;
1627         const char *fname = "\\lockt7.lck";
1628         int fnum1;
1629         char buf[200];
1630         BOOL correct = False;
1631
1632         if (!torture_open_connection(&cli1)) {
1633                 return False;
1634         }
1635
1636         printf("starting locktest7\n");
1637
1638         cli_unlink(cli1, fname);
1639
1640         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1641
1642         memset(buf, 0, sizeof(buf));
1643
1644         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1645                 printf("Failed to create file\n");
1646                 goto fail;
1647         }
1648
1649         cli1->session->pid = 1;
1650
1651         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1652                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1653                 goto fail;
1654         } else {
1655                 printf("pid1 successfully locked range 130:4 for READ\n");
1656         }
1657
1658         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1659                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1660                 goto fail;
1661         } else {
1662                 printf("pid1 successfully read the range 130:4\n");
1663         }
1664
1665         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1666                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1667                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1668                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1669                         goto fail;
1670                 }
1671         } else {
1672                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1673                 goto fail;
1674         }
1675
1676         cli1->session->pid = 2;
1677
1678         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1679                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1680         } else {
1681                 printf("pid2 successfully read the range 130:4\n");
1682         }
1683
1684         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1685                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1686                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1687                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1688                         goto fail;
1689                 }
1690         } else {
1691                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1692                 goto fail;
1693         }
1694
1695         cli1->session->pid = 1;
1696         cli_unlock(cli1, fnum1, 130, 4);
1697
1698         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1699                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1700                 goto fail;
1701         } else {
1702                 printf("pid1 successfully locked range 130:4 for WRITE\n");
1703         }
1704
1705         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1706                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1707                 goto fail;
1708         } else {
1709                 printf("pid1 successfully read the range 130:4\n");
1710         }
1711
1712         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1713                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1714                 goto fail;
1715         } else {
1716                 printf("pid1 successfully wrote to the range 130:4\n");
1717         }
1718
1719         cli1->session->pid = 2;
1720
1721         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1722                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1723                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1724                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1725                         goto fail;
1726                 }
1727         } else {
1728                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1729                 goto fail;
1730         }
1731
1732         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1733                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1734                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1735                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1736                         goto fail;
1737                 }
1738         } else {
1739                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1740                 goto fail;
1741         }
1742
1743         cli_unlock(cli1, fnum1, 130, 0);
1744         correct = True;
1745
1746 fail:
1747         cli_close(cli1, fnum1);
1748         cli_unlink(cli1, fname);
1749         torture_close_connection(cli1);
1750
1751         printf("finished locktest7\n");
1752         return correct;
1753 }
1754
1755 /*
1756 test whether fnums and tids open on one VC are available on another (a major
1757 security hole)
1758 */
1759 static BOOL run_fdpasstest(int dummy)
1760 {
1761         struct cli_state *cli1, *cli2;
1762         const char *fname = "\\fdpass.tst";
1763         int fnum1, oldtid;
1764         pstring buf;
1765
1766         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1767                 return False;
1768         }
1769
1770         printf("starting fdpasstest\n");
1771
1772         cli_unlink(cli1, fname);
1773
1774         printf("Opening a file on connection 1\n");
1775
1776         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1777         if (fnum1 == -1) {
1778                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1779                 return False;
1780         }
1781
1782         printf("writing to file on connection 1\n");
1783
1784         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1785                 printf("write failed (%s)\n", cli_errstr(cli1));
1786                 return False;
1787         }
1788
1789         oldtid = cli2->tree->tid;
1790         cli2->session->vuid = cli1->session->vuid;
1791         cli2->tree->tid = cli1->tree->tid;
1792         cli2->session->pid = cli1->session->pid;
1793
1794         printf("reading from file on connection 2\n");
1795
1796         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
1797                 printf("read succeeded! nasty security hole [%s]\n",
1798                        buf);
1799                 return False;
1800         }
1801
1802         cli_close(cli1, fnum1);
1803         cli_unlink(cli1, fname);
1804
1805         cli2->tree->tid = oldtid;
1806
1807         torture_close_connection(cli1);
1808         torture_close_connection(cli2);
1809
1810         printf("finished fdpasstest\n");
1811         return True;
1812 }
1813
1814
1815 /*
1816   This test checks that 
1817
1818   1) the server does not allow an unlink on a file that is open
1819 */
1820 static BOOL run_unlinktest(int dummy)
1821 {
1822         struct cli_state *cli;
1823         const char *fname = "\\unlink.tst";
1824         int fnum;
1825         BOOL correct = True;
1826
1827         if (!torture_open_connection(&cli)) {
1828                 return False;
1829         }
1830
1831         printf("starting unlink test\n");
1832
1833         cli_unlink(cli, fname);
1834
1835         cli->session->pid = 1;
1836
1837         printf("Opening a file\n");
1838
1839         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1840         if (fnum == -1) {
1841                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1842                 return False;
1843         }
1844
1845         printf("Unlinking a open file\n");
1846
1847         if (cli_unlink(cli, fname)) {
1848                 printf("error: server allowed unlink on an open file\n");
1849                 correct = False;
1850         } else {
1851                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
1852                                       NT_STATUS_SHARING_VIOLATION);
1853         }
1854
1855         cli_close(cli, fnum);
1856         cli_unlink(cli, fname);
1857
1858         if (!torture_close_connection(cli)) {
1859                 correct = False;
1860         }
1861
1862         printf("unlink test finished\n");
1863         
1864         return correct;
1865 }
1866
1867
1868 /*
1869 test how many open files this server supports on the one socket
1870 */
1871 static BOOL run_maxfidtest(int dummy)
1872 {
1873         struct cli_state *cli;
1874         const char *template = "\\maxfid.%d.%d";
1875         char *fname;
1876         int fnums[0x11000], i;
1877         int retries=4;
1878         BOOL correct = True;
1879
1880         cli = current_cli;
1881
1882         if (retries <= 0) {
1883                 printf("failed to connect\n");
1884                 return False;
1885         }
1886
1887         printf("Testing maximum number of open files\n");
1888
1889         for (i=0; i<0x11000; i++) {
1890                 asprintf(&fname, template, i,(int)getpid());
1891                 if ((fnums[i] = cli_open(cli, fname, 
1892                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1893                     -1) {
1894                         printf("open of %s failed (%s)\n", 
1895                                fname, cli_errstr(cli));
1896                         printf("maximum fnum is %d\n", i);
1897                         break;
1898                 }
1899                 free(fname);
1900                 printf("%6d\r", i);
1901         }
1902         printf("%6d\n", i);
1903         i--;
1904
1905         printf("cleaning up\n");
1906         for (;i>=0;i--) {
1907                 asprintf(&fname, template, i,(int)getpid());
1908                 if (!cli_close(cli, fnums[i])) {
1909                         printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli));
1910                 }
1911                 if (!cli_unlink(cli, fname)) {
1912                         printf("unlink of %s failed (%s)\n", 
1913                                fname, cli_errstr(cli));
1914                         correct = False;
1915                 }
1916                 free(fname);
1917                 printf("%6d\r", i);
1918         }
1919         printf("%6d\n", 0);
1920
1921         printf("maxfid test finished\n");
1922         if (!torture_close_connection(cli)) {
1923                 correct = False;
1924         }
1925         return correct;
1926 }
1927
1928 /* send smb negprot commands, not reading the response */
1929 static BOOL run_negprot_nowait(int dummy)
1930 {
1931         int i;
1932         struct cli_state *cli;
1933         BOOL correct = True;
1934
1935         printf("starting negprot nowait test\n");
1936
1937         cli = open_nbt_connection();
1938         if (!cli) {
1939                 return False;
1940         }
1941
1942         printf("Establishing protocol negotiations - connect with another client\n");
1943
1944         for (i=0;i<50000;i++) {
1945                 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1946         }
1947
1948         if (!torture_close_connection(cli)) {
1949                 correct = False;
1950         }
1951
1952         printf("finished negprot nowait test\n");
1953
1954         return correct;
1955 }
1956
1957
1958 /*
1959   This checks how the getatr calls works
1960 */
1961 static BOOL run_attrtest(int dummy)
1962 {
1963         struct cli_state *cli;
1964         int fnum;
1965         time_t t, t2;
1966         const char *fname = "\\attrib123456789.tst";
1967         BOOL correct = True;
1968
1969         printf("starting attrib test\n");
1970
1971         if (!torture_open_connection(&cli)) {
1972                 return False;
1973         }
1974
1975         cli_unlink(cli, fname);
1976         fnum = cli_open(cli, fname, 
1977                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1978         cli_close(cli, fnum);
1979
1980         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
1981                 printf("getatr failed (%s)\n", cli_errstr(cli));
1982                 correct = False;
1983         }
1984
1985         printf("New file time is %s", ctime(&t));
1986
1987         if (abs(t - time(NULL)) > 60*60*24*10) {
1988                 printf("ERROR: SMBgetatr bug. time is %s",
1989                        ctime(&t));
1990                 t = time(NULL);
1991                 correct = False;
1992         }
1993
1994         t2 = t-60*60*24; /* 1 day ago */
1995
1996         printf("Setting file time to %s", ctime(&t2));
1997
1998         if (!cli_setatr(cli, fname, 0, t2)) {
1999                 printf("setatr failed (%s)\n", cli_errstr(cli));
2000                 correct = True;
2001         }
2002
2003         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2004                 printf("getatr failed (%s)\n", cli_errstr(cli));
2005                 correct = True;
2006         }
2007
2008         printf("Retrieved file time as %s", ctime(&t));
2009
2010         if (t != t2) {
2011                 printf("ERROR: getatr/setatr bug. times are\n%s",
2012                        ctime(&t));
2013                 printf("%s", ctime(&t2));
2014                 correct = True;
2015         }
2016
2017         cli_unlink(cli, fname);
2018
2019         if (!torture_close_connection(cli)) {
2020                 correct = False;
2021         }
2022
2023         printf("attrib test finished\n");
2024
2025         return correct;
2026 }
2027
2028
2029 /*
2030   This checks a couple of trans2 calls
2031 */
2032 static BOOL run_trans2test(int dummy)
2033 {
2034         struct cli_state *cli;
2035         int fnum;
2036         size_t size;
2037         time_t c_time, a_time, m_time, w_time, m_time2;
2038         const char *fname = "\\trans2.tst";
2039         const char *dname = "\\trans2";
2040         const char *fname2 = "\\trans2\\trans2.tst";
2041         const char *pname;
2042         BOOL correct = True;
2043
2044         printf("starting trans2 test\n");
2045
2046         if (!torture_open_connection(&cli)) {
2047                 return False;
2048         }
2049
2050         cli_unlink(cli, fname);
2051
2052         printf("Testing qfileinfo\n");
2053         
2054         fnum = cli_open(cli, fname, 
2055                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2056         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2057                            NULL, NULL)) {
2058                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2059                 correct = False;
2060         }
2061
2062         printf("Testing NAME_INFO\n");
2063
2064         if (!cli_qfilename(cli, fnum, &pname)) {
2065                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2066                 correct = False;
2067         }
2068
2069         if (!pname || strcmp(pname, fname)) {
2070                 printf("qfilename gave different name? [%s] [%s]\n",
2071                        fname, pname);
2072                 correct = False;
2073         }
2074
2075         cli_close(cli, fnum);
2076         cli_unlink(cli, fname);
2077
2078         fnum = cli_open(cli, fname, 
2079                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2080         if (fnum == -1) {
2081                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2082                 return False;
2083         }
2084         cli_close(cli, fnum);
2085
2086         printf("Checking for sticky create times\n");
2087
2088         if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2089                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2090                 correct = False;
2091         } else {
2092                 if (c_time != m_time) {
2093                         printf("create time=%s", ctime(&c_time));
2094                         printf("modify time=%s", ctime(&m_time));
2095                         printf("This system appears to have sticky create times\n");
2096                 }
2097                 if (a_time % (60*60) == 0) {
2098                         printf("access time=%s", ctime(&a_time));
2099                         printf("This system appears to set a midnight access time\n");
2100                         correct = False;
2101                 }
2102
2103                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2104                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2105                         correct = False;
2106                 }
2107         }
2108
2109
2110         cli_unlink(cli, fname);
2111         fnum = cli_open(cli, fname, 
2112                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2113         cli_close(cli, fnum);
2114         if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time, 
2115                             &w_time, &size, NULL, NULL)) {
2116                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2117                 correct = False;
2118         } else {
2119                 if (w_time < 60*60*24*2) {
2120                         printf("write time=%s", ctime(&w_time));
2121                         printf("This system appears to set a initial 0 write time\n");
2122                         correct = False;
2123                 }
2124         }
2125
2126         cli_unlink(cli, fname);
2127
2128
2129         /* check if the server updates the directory modification time
2130            when creating a new file */
2131         if (!cli_mkdir(cli, dname)) {
2132                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2133                 correct = False;
2134         }
2135         sleep(3);
2136         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time, 
2137                             &w_time, &size, NULL, NULL)) {
2138                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2139                 correct = False;
2140         }
2141
2142         fnum = cli_open(cli, fname2, 
2143                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2144         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2145         cli_close(cli, fnum);
2146         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
2147                             &w_time, &size, NULL, NULL)) {
2148                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2149                 correct = False;
2150         } else {
2151                 if (m_time2 == m_time) {
2152                         printf("This system does not update directory modification times\n");
2153                         correct = False;
2154                 }
2155         }
2156         cli_unlink(cli, fname2);
2157         cli_rmdir(cli, dname);
2158
2159         if (!torture_close_connection(cli)) {
2160                 correct = False;
2161         }
2162
2163         printf("trans2 test finished\n");
2164
2165         return correct;
2166 }
2167
2168 /*
2169   Test delete on close semantics.
2170  */
2171 static BOOL run_deletetest(int dummy)
2172 {
2173         struct cli_state *cli1;
2174         struct cli_state *cli2 = NULL;
2175         const char *fname = "\\delete.file";
2176         int fnum1 = -1;
2177         int fnum2 = -1;
2178         BOOL correct = True;
2179         
2180         printf("starting delete test\n");
2181         
2182         if (!torture_open_connection(&cli1)) {
2183                 return False;
2184         }
2185         
2186         /* Test 1 - this should delete the file on close. */
2187         
2188         cli_setatr(cli1, fname, 0, 0);
2189         cli_unlink(cli1, fname);
2190         
2191         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2192                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 
2193                                    NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2194         
2195         if (fnum1 == -1) {
2196                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2197                 correct = False;
2198                 goto fail;
2199         }
2200         
2201         if (!cli_close(cli1, fnum1)) {
2202                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2203                 correct = False;
2204                 goto fail;
2205         }
2206
2207         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2208         if (fnum1 != -1) {
2209                 printf("[1] open of %s succeeded (should fail)\n", fname);
2210                 correct = False;
2211                 goto fail;
2212         }
2213         
2214         printf("first delete on close test succeeded.\n");
2215         
2216         /* Test 2 - this should delete the file on close. */
2217         
2218         cli_setatr(cli1, fname, 0, 0);
2219         cli_unlink(cli1, fname);
2220         
2221         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2222                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, 
2223                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2224         
2225         if (fnum1 == -1) {
2226                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2227                 correct = False;
2228                 goto fail;
2229         }
2230         
2231         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2232                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2233                 correct = False;
2234                 goto fail;
2235         }
2236         
2237         if (!cli_close(cli1, fnum1)) {
2238                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2239                 correct = False;
2240                 goto fail;
2241         }
2242         
2243         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2244         if (fnum1 != -1) {
2245                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2246                 if (!cli_close(cli1, fnum1)) {
2247                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
2248                         correct = False;
2249                         goto fail;
2250                 }
2251                 cli_unlink(cli1, fname);
2252         } else
2253                 printf("second delete on close test succeeded.\n");
2254         
2255         /* Test 3 - ... */
2256         cli_setatr(cli1, fname, 0, 0);
2257         cli_unlink(cli1, fname);
2258
2259         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2260                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2261
2262         if (fnum1 == -1) {
2263                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
2264                 correct = False;
2265                 goto fail;
2266         }
2267
2268         /* This should fail with a sharing violation - open for delete is only compatible
2269            with SHARE_DELETE. */
2270
2271         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2272                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
2273                                    NTCREATEX_DISP_OPEN, 0, 0);
2274
2275         if (fnum2 != -1) {
2276                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2277                 correct = False;
2278                 goto fail;
2279         }
2280
2281         /* This should succeed. */
2282
2283         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2284                         NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2285
2286         if (fnum2 == -1) {
2287                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2288                 correct = False;
2289                 goto fail;
2290         }
2291
2292         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2293                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2294                 correct = False;
2295                 goto fail;
2296         }
2297         
2298         if (!cli_close(cli1, fnum1)) {
2299                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
2300                 correct = False;
2301                 goto fail;
2302         }
2303         
2304         if (!cli_close(cli1, fnum2)) {
2305                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
2306                 correct = False;
2307                 goto fail;
2308         }
2309         
2310         /* This should fail - file should no longer be there. */
2311
2312         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2313         if (fnum1 != -1) {
2314                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2315                 if (!cli_close(cli1, fnum1)) {
2316                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
2317                 }
2318                 cli_unlink(cli1, fname);
2319                 correct = False;
2320                 goto fail;
2321         } else
2322                 printf("third delete on close test succeeded.\n");
2323
2324         /* Test 4 ... */
2325         cli_setatr(cli1, fname, 0, 0);
2326         cli_unlink(cli1, fname);
2327
2328         fnum1 = cli_nt_create_full(cli1, fname, 0, 
2329                                    SA_RIGHT_FILE_READ_DATA  | 
2330                                    SA_RIGHT_FILE_WRITE_DATA |
2331                                    STD_RIGHT_DELETE_ACCESS,
2332                                    FILE_ATTRIBUTE_NORMAL, 
2333                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
2334                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2335                                                                 
2336         if (fnum1 == -1) {
2337                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2338                 correct = False;
2339                 goto fail;
2340         }
2341
2342         /* This should succeed. */
2343         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2344                                    FILE_ATTRIBUTE_NORMAL, 
2345                                    NTCREATEX_SHARE_ACCESS_READ  | 
2346                                    NTCREATEX_SHARE_ACCESS_WRITE |
2347                                    NTCREATEX_SHARE_ACCESS_DELETE, 
2348                                    NTCREATEX_DISP_OPEN, 0, 0);
2349         if (fnum2 == -1) {
2350                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2351                 correct = False;
2352                 goto fail;
2353         }
2354         
2355         if (!cli_close(cli1, fnum2)) {
2356                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
2357                 correct = False;
2358                 goto fail;
2359         }
2360         
2361         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2362                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2363                 correct = False;
2364                 goto fail;
2365         }
2366         
2367         /* This should fail - no more opens once delete on close set. */
2368         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2369                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2370                                    NTCREATEX_DISP_OPEN, 0, 0);
2371         if (fnum2 != -1) {
2372                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2373                 correct = False;
2374                 goto fail;
2375         } else
2376                 printf("fourth delete on close test succeeded.\n");
2377         
2378         if (!cli_close(cli1, fnum1)) {
2379                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
2380                 correct = False;
2381                 goto fail;
2382         }
2383         
2384         /* Test 5 ... */
2385         cli_setatr(cli1, fname, 0, 0);
2386         cli_unlink(cli1, fname);
2387         
2388         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2389         if (fnum1 == -1) {
2390                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2391                 correct = False;
2392                 goto fail;
2393         }
2394
2395         /* This should fail - only allowed on NT opens with DELETE access. */
2396
2397         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2398                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2399                 correct = False;
2400                 goto fail;
2401         }
2402
2403         if (!cli_close(cli1, fnum1)) {
2404                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
2405                 correct = False;
2406                 goto fail;
2407         }
2408         
2409         printf("fifth delete on close test succeeded.\n");
2410         
2411         /* Test 6 ... */
2412         cli_setatr(cli1, fname, 0, 0);
2413         cli_unlink(cli1, fname);
2414         
2415         fnum1 = cli_nt_create_full(cli1, fname, 0, 
2416                                    SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2417                                    FILE_ATTRIBUTE_NORMAL, 
2418                                    NTCREATEX_SHARE_ACCESS_READ  |
2419                                    NTCREATEX_SHARE_ACCESS_WRITE |
2420                                    NTCREATEX_SHARE_ACCESS_DELETE,
2421                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2422         
2423         if (fnum1 == -1) {
2424                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2425                 correct = False;
2426                 goto fail;
2427         }
2428         
2429         /* This should fail - only allowed on NT opens with DELETE access. */
2430         
2431         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2432                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2433                 correct = False;
2434                 goto fail;
2435         }
2436
2437         if (!cli_close(cli1, fnum1)) {
2438                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
2439                 correct = False;
2440                 goto fail;
2441         }
2442
2443         printf("sixth delete on close test succeeded.\n");
2444         
2445         /* Test 7 ... */
2446         cli_setatr(cli1, fname, 0, 0);
2447         cli_unlink(cli1, fname);
2448         
2449         fnum1 = cli_nt_create_full(cli1, fname, 0, 
2450                                    SA_RIGHT_FILE_READ_DATA  | 
2451                                    SA_RIGHT_FILE_WRITE_DATA |
2452                                    STD_RIGHT_DELETE_ACCESS,
2453                                    FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2454                                                                 
2455         if (fnum1 == -1) {
2456                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2457                 correct = False;
2458                 goto fail;
2459         }
2460
2461         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2462                 printf("[7] setting delete_on_close on file failed !\n");
2463                 correct = False;
2464                 goto fail;
2465         }
2466         
2467         if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
2468                 printf("[7] unsetting delete_on_close on file failed !\n");
2469                 correct = False;
2470                 goto fail;
2471         }
2472
2473         if (!cli_close(cli1, fnum1)) {
2474                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2475                 correct = False;
2476                 goto fail;
2477         }
2478         
2479         /* This next open should succeed - we reset the flag. */
2480         
2481         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2482         if (fnum1 == -1) {
2483                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2484                 correct = False;
2485                 goto fail;
2486         }
2487
2488         if (!cli_close(cli1, fnum1)) {
2489                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2490                 correct = False;
2491                 goto fail;
2492         }
2493
2494         printf("seventh delete on close test succeeded.\n");
2495         
2496         /* Test 7 ... */
2497         cli_setatr(cli1, fname, 0, 0);
2498         cli_unlink(cli1, fname);
2499         
2500         if (!torture_open_connection(&cli2)) {
2501                 printf("[8] failed to open second connection.\n");
2502                 correct = False;
2503                 goto fail;
2504         }
2505
2506         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2507                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2508                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2509         
2510         if (fnum1 == -1) {
2511                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2512                 correct = False;
2513                 goto fail;
2514         }
2515
2516         fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2517                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2518                                    NTCREATEX_DISP_OPEN, 0, 0);
2519         
2520         if (fnum2 == -1) {
2521                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2522                 correct = False;
2523                 goto fail;
2524         }
2525
2526         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2527                 printf("[8] setting delete_on_close on file failed !\n");
2528                 correct = False;
2529                 goto fail;
2530         }
2531         
2532         if (!cli_close(cli1, fnum1)) {
2533                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
2534                 correct = False;
2535                 goto fail;
2536         }
2537
2538         if (!cli_close(cli2, fnum2)) {
2539                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
2540                 correct = False;
2541                 goto fail;
2542         }
2543
2544         /* This should fail.. */
2545         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2546         if (fnum1 != -1) {
2547                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2548                 goto fail;
2549                 correct = False;
2550         } else
2551                 printf("eighth delete on close test succeeded.\n");
2552
2553         /* This should fail - we need to set DELETE_ACCESS. */
2554         fnum1 = cli_nt_create_full(cli1, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2555                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2556         
2557         if (fnum1 != -1) {
2558                 printf("[9] open of %s succeeded should have failed!\n", fname);
2559                 correct = False;
2560                 goto fail;
2561         }
2562
2563         printf("ninth delete on close test succeeded.\n");
2564
2565         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2566                                    FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2567         if (fnum1 == -1) {
2568                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2569                 correct = False;
2570                 goto fail;
2571         }
2572
2573         /* This should delete the file. */
2574         if (!cli_close(cli1, fnum1)) {
2575                 printf("[10] close failed (%s)\n", cli_errstr(cli1));
2576                 correct = False;
2577                 goto fail;
2578         }
2579
2580         /* This should fail.. */
2581         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2582         if (fnum1 != -1) {
2583                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2584                 goto fail;
2585                 correct = False;
2586         } else
2587                 printf("tenth delete on close test succeeded.\n");
2588         printf("finished delete test\n");
2589
2590   fail:
2591         /* FIXME: This will crash if we aborted before cli2 got
2592          * intialized, because these functions don't handle
2593          * uninitialized connections. */
2594                 
2595         cli_close(cli1, fnum1);
2596         cli_close(cli1, fnum2);
2597         cli_setatr(cli1, fname, 0, 0);
2598         cli_unlink(cli1, fname);
2599
2600         if (!torture_close_connection(cli1)) {
2601                 correct = False;
2602         }
2603         if (!torture_close_connection(cli2)) {
2604                 correct = False;
2605         }
2606         return correct;
2607 }
2608
2609
2610 /*
2611   print out server properties
2612  */
2613 static BOOL run_properties(int dummy)
2614 {
2615         struct cli_state *cli;
2616         BOOL correct = True;
2617         
2618         printf("starting properties test\n");
2619         
2620         ZERO_STRUCT(cli);
2621
2622         if (!torture_open_connection(&cli)) {
2623                 return False;
2624         }
2625         
2626         d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2627
2628         if (!torture_close_connection(cli)) {
2629                 correct = False;
2630         }
2631
2632         return correct;
2633 }
2634
2635
2636
2637 /* FIRST_DESIRED_ACCESS   0xf019f */
2638 #define FIRST_DESIRED_ACCESS   SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2639                                SA_RIGHT_FILE_READ_EA|                           /* 0xf */ \
2640                                SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES|     /* 0x90 */ \
2641                                SA_RIGHT_FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
2642                                STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2643                                STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS     /* 0xf0000 */
2644 /* SECOND_DESIRED_ACCESS  0xe0080 */
2645 #define SECOND_DESIRED_ACCESS  SA_RIGHT_FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2646                                STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2647                                STD_RIGHT_WRITE_OWNER_ACCESS                      /* 0xe0000 */
2648
2649 #if 0
2650 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2651                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2652                                SA_RIGHT_FILE_READ_DATA|\
2653                                WRITE_OWNER_ACCESS                      /* */
2654 #endif
2655
2656 /*
2657   Test ntcreate calls made by xcopy
2658  */
2659 static BOOL run_xcopy(int dummy)
2660 {
2661         struct cli_state *cli1;
2662         const char *fname = "\\test.txt";
2663         BOOL correct = True;
2664         int fnum1, fnum2;
2665
2666         printf("starting xcopy test\n");
2667         
2668         if (!torture_open_connection(&cli1)) {
2669                 return False;
2670         }
2671         
2672         fnum1 = cli_nt_create_full(cli1, fname, 0,
2673                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2674                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 
2675                                    0x4044, 0);
2676
2677         if (fnum1 == -1) {
2678                 printf("First open failed - %s\n", cli_errstr(cli1));
2679                 return False;
2680         }
2681
2682         fnum2 = cli_nt_create_full(cli1, fname, 0,
2683                                    SECOND_DESIRED_ACCESS, 0,
2684                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 
2685                                    0x200000, 0);
2686         if (fnum2 == -1) {
2687                 printf("second open failed - %s\n", cli_errstr(cli1));
2688                 return False;
2689         }
2690         
2691         if (!torture_close_connection(cli1)) {
2692                 correct = False;
2693         }
2694         
2695         return correct;
2696 }
2697
2698 /*
2699   Test rename on files open with share delete and no share delete.
2700  */
2701 static BOOL run_rename(int dummy)
2702 {
2703         struct cli_state *cli1;
2704         const char *fname = "\\test.txt";
2705         const char *fname1 = "\\test1.txt";
2706         BOOL correct = True;
2707         int fnum1;
2708
2709         printf("starting rename test\n");
2710         
2711         if (!torture_open_connection(&cli1)) {
2712                 return False;
2713         }
2714         
2715         cli_unlink(cli1, fname);
2716         cli_unlink(cli1, fname1);
2717         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2718                                    NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2719
2720         if (fnum1 == -1) {
2721                 printf("First open failed - %s\n", cli_errstr(cli1));
2722                 return False;
2723         }
2724
2725         if (!cli_rename(cli1, fname, fname1)) {
2726                 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
2727         } else {
2728                 printf("First rename succeeded - this should have failed !\n");
2729                 correct = False;
2730         }
2731
2732         if (!cli_close(cli1, fnum1)) {
2733                 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
2734                 return False;
2735         }
2736
2737         cli_unlink(cli1, fname);
2738         cli_unlink(cli1, fname1);
2739         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2740 #if 0
2741                                    NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2742 #else
2743                                    NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2744 #endif
2745
2746         if (fnum1 == -1) {
2747                 printf("Second open failed - %s\n", cli_errstr(cli1));
2748                 return False;
2749         }
2750
2751         if (!cli_rename(cli1, fname, fname1)) {
2752                 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2753                 correct = False;
2754         } else {
2755                 printf("Second rename succeeded\n");
2756         }
2757
2758         if (!cli_close(cli1, fnum1)) {
2759                 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
2760                 return False;
2761         }
2762
2763         cli_unlink(cli1, fname);
2764         cli_unlink(cli1, fname1);
2765
2766         fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2767                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2768
2769         if (fnum1 == -1) {
2770                 printf("Third open failed - %s\n", cli_errstr(cli1));
2771                 return False;
2772         }
2773
2774
2775 #if 0
2776   {
2777   int fnum2;
2778
2779         fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2780                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2781
2782         if (fnum2 == -1) {
2783                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
2784                 return False;
2785         }
2786         if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
2787                 printf("[8] setting delete_on_close on file failed !\n");
2788                 return False;
2789         }
2790         
2791         if (!cli_close(cli1, fnum2)) {
2792                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
2793                 return False;
2794         }
2795   }
2796 #endif
2797
2798         if (!cli_rename(cli1, fname, fname1)) {
2799                 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2800                 correct = False;
2801         } else {
2802                 printf("Third rename succeeded\n");
2803         }
2804
2805         if (!cli_close(cli1, fnum1)) {
2806                 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
2807                 return False;
2808         }
2809
2810         cli_unlink(cli1, fname);
2811         cli_unlink(cli1, fname1);
2812
2813         if (!torture_close_connection(cli1)) {
2814                 correct = False;
2815         }
2816         
2817         return correct;
2818 }
2819
2820 static BOOL run_pipe_number(int dummy)
2821 {
2822         struct cli_state *cli1;
2823         const char *pipe_name = "\\WKSSVC";
2824         int fnum;
2825         int num_pipes = 0;
2826
2827         printf("starting pipenumber test\n");
2828         if (!torture_open_connection(&cli1)) {
2829                 return False;
2830         }
2831
2832         while(1) {
2833                 fnum = cli_nt_create_full(cli1, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2834                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2835
2836                 if (fnum == -1) {
2837                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
2838                         break;
2839                 }
2840                 num_pipes++;
2841         }
2842
2843         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2844         torture_close_connection(cli1);
2845         return True;
2846 }
2847
2848
2849 /*
2850   Test open mode returns on read-only files.
2851  */
2852  static BOOL run_opentest(int dummy)
2853 {
2854         static struct cli_state *cli1;
2855         static struct cli_state *cli2;
2856         const char *fname = "\\readonly.file";
2857         int fnum1, fnum2;
2858         char buf[20];
2859         size_t fsize;
2860         BOOL correct = True;
2861         char *tmp_path;
2862         int failures = 0;
2863
2864         printf("starting open test\n");
2865         
2866         if (!torture_open_connection(&cli1)) {
2867                 return False;
2868         }
2869         
2870         cli_setatr(cli1, fname, 0, 0);
2871         cli_unlink(cli1, fname);
2872         
2873         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2874         if (fnum1 == -1) {
2875                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2876                 return False;
2877         }
2878
2879         if (!cli_close(cli1, fnum1)) {
2880                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2881                 return False;
2882         }
2883         
2884         if (!cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0)) {
2885                 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
2886                 CHECK_MAX_FAILURES(error_test1);
2887                 return False;
2888         }
2889         
2890         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2891         if (fnum1 == -1) {
2892                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2893                 CHECK_MAX_FAILURES(error_test1);
2894                 return False;
2895         }
2896         
2897         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2898         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2899         
2900         if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
2901                         NT_STATUS_ACCESS_DENIED)) {
2902                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2903         }
2904         
2905         printf("finished open test 1\n");
2906 error_test1:
2907         cli_close(cli1, fnum1);
2908         
2909         /* Now try not readonly and ensure ERRbadshare is returned. */
2910         
2911         cli_setatr(cli1, fname, 0, 0);
2912         
2913         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2914         if (fnum1 == -1) {
2915                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2916                 return False;
2917         }
2918         
2919         /* This will fail - but the error should be ERRshare. */
2920         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2921         
2922         if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
2923                         NT_STATUS_SHARING_VIOLATION)) {
2924                 printf("correct error code ERRDOS/ERRbadshare returned\n");
2925         }
2926         
2927         if (!cli_close(cli1, fnum1)) {
2928                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2929                 return False;
2930         }
2931         
2932         cli_unlink(cli1, fname);
2933         
2934         printf("finished open test 2\n");
2935         
2936         /* Test truncate open disposition on file opened for read. */
2937         
2938         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2939         if (fnum1 == -1) {
2940                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
2941                 return False;
2942         }
2943         
2944         /* write 20 bytes. */
2945         
2946         memset(buf, '\0', 20);
2947
2948         if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
2949                 printf("write failed (%s)\n", cli_errstr(cli1));
2950                 correct = False;
2951         }
2952
2953         if (!cli_close(cli1, fnum1)) {
2954                 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
2955                 return False;
2956         }
2957         
2958         /* Ensure size == 20. */
2959         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
2960                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
2961                 CHECK_MAX_FAILURES(error_test3);
2962                 return False;
2963         }
2964         
2965         if (fsize != 20) {
2966                 printf("(3) file size != 20\n");
2967                 CHECK_MAX_FAILURES(error_test3);
2968                 return False;
2969         }
2970
2971         /* Now test if we can truncate a file opened for readonly. */
2972         
2973         fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2974         if (fnum1 == -1) {
2975                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
2976                 CHECK_MAX_FAILURES(error_test3);
2977                 return False;
2978         }
2979         
2980         if (!cli_close(cli1, fnum1)) {
2981                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2982                 return False;
2983         }
2984
2985         /* Ensure size == 0. */
2986         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
2987                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
2988                 CHECK_MAX_FAILURES(error_test3);
2989                 return False;
2990         }
2991
2992         if (fsize != 0) {
2993                 printf("(3) file size != 0\n");
2994                 CHECK_MAX_FAILURES(error_test3);
2995                 return False;
2996         }
2997         printf("finished open test 3\n");
2998 error_test3:    
2999         cli_unlink(cli1, fname);
3000
3001
3002         printf("testing ctemp\n");
3003         fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3004         if (fnum1 == -1) {
3005                 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3006                 CHECK_MAX_FAILURES(error_test4);
3007                 return False;
3008         }
3009         printf("ctemp gave path %s\n", tmp_path);
3010         if (!cli_close(cli1, fnum1)) {
3011                 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3012         }
3013         if (!cli_unlink(cli1, tmp_path)) {
3014                 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3015         }
3016 error_test4:    
3017         /* Test the non-io opens... */
3018
3019         if (!torture_open_connection(&cli2)) {
3020                 return False;
3021         }
3022         
3023         cli_setatr(cli2, fname, 0, 0);
3024         cli_unlink(cli2, fname);
3025         
3026         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3027         
3028         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3029                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3030
3031         if (fnum1 == -1) {
3032                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3033                 CHECK_MAX_FAILURES(error_test10);
3034                 return False;
3035         }
3036
3037         fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3038                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3039         if (fnum2 == -1) {
3040                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3041                 CHECK_MAX_FAILURES(error_test10);
3042                 return False;
3043         }
3044
3045         if (!cli_close(cli1, fnum1)) {
3046                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3047                 return False;
3048         }
3049         if (!cli_close(cli2, fnum2)) {
3050                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3051                 return False;
3052         }
3053
3054         printf("non-io open test #1 passed.\n");
3055 error_test10:
3056         cli_unlink(cli1, fname);
3057
3058         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3059         
3060         fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3061                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3062
3063         if (fnum1 == -1) {
3064                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3065                 CHECK_MAX_FAILURES(error_test20);
3066                 return False;
3067         }
3068
3069         fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3070                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3071
3072         if (fnum2 == -1) {
3073                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3074                 CHECK_MAX_FAILURES(error_test20);
3075                 return False;
3076         }
3077
3078         if (!cli_close(cli1, fnum1)) {
3079                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3080                 return False;
3081         }
3082         if (!cli_close(cli2, fnum2)) {
3083                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3084                 return False;
3085         }
3086
3087         printf("non-io open test #2 passed.\n");
3088 error_test20:
3089         cli_unlink(cli1, fname);
3090
3091         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3092         
3093         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3094                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3095
3096         if (fnum1 == -1) {
3097                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3098                 CHECK_MAX_FAILURES(error_test30);
3099                 return False;
3100         }
3101
3102         fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3103                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3104
3105         if (fnum2 == -1) {
3106                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3107                 CHECK_MAX_FAILURES(error_test30);
3108                 return False;
3109         }
3110
3111         if (!cli_close(cli1, fnum1)) {
3112                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3113                 return False;
3114         }
3115         if (!cli_close(cli2, fnum2)) {
3116                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3117                 return False;
3118         }
3119
3120         printf("non-io open test #3 passed.\n");
3121 error_test30:
3122         cli_unlink(cli1, fname);
3123
3124         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3125         
3126         fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3127                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3128
3129         if (fnum1 == -1) {
3130                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3131                 CHECK_MAX_FAILURES(error_test40);
3132                 return False;
3133         }
3134
3135         fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3136                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3137
3138         if (fnum2 != -1) {
3139                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3140                 CHECK_MAX_FAILURES(error_test40);
3141                 return False;
3142         }
3143
3144         printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3145
3146         if (!cli_close(cli1, fnum1)) {
3147                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3148                 return False;
3149         }
3150
3151         printf("non-io open test #4 passed.\n");
3152 error_test40:
3153         cli_unlink(cli1, fname);
3154
3155         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3156         
3157         fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3158                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3159
3160         if (fnum1 == -1) {
3161                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3162                 CHECK_MAX_FAILURES(error_test50);
3163                 return False;
3164         }
3165
3166         fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3167                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3168
3169         if (fnum2 == -1) {
3170                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3171                 CHECK_MAX_FAILURES(error_test50);
3172                 return False;
3173         }
3174
3175         if (!cli_close(cli1, fnum1)) {
3176                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3177                 return False;
3178         }
3179
3180         if (!cli_close(cli2, fnum2)) {
3181                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3182                 return False;
3183         }
3184
3185         printf("non-io open test #5 passed.\n");
3186 error_test50:
3187         printf("TEST #6 testing 1 non-io open, one io open\n");
3188         
3189         cli_unlink(cli1, fname);
3190
3191         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3192                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3193
3194         if (fnum1 == -1) {
3195                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3196                 CHECK_MAX_FAILURES(error_test60);
3197                 return False;
3198         }
3199
3200         fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3201                                    NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3202
3203         if (fnum2 == -1) {
3204                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3205                 CHECK_MAX_FAILURES(error_test60);
3206                 return False;
3207         }
3208
3209         if (!cli_close(cli1, fnum1)) {
3210                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3211                 return False;
3212         }
3213
3214         if (!cli_close(cli2, fnum2)) {
3215                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3216                 return False;
3217         }
3218
3219         printf("non-io open test #6 passed.\n");
3220 error_test60:
3221         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3222
3223         cli_unlink(cli1, fname);
3224
3225         fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3226                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3227
3228         if (fnum1 == -1) {
3229                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3230                 CHECK_MAX_FAILURES(error_test70);
3231                 return False;
3232         }
3233
3234         fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3235                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3236
3237         if (fnum2 != -1) {
3238                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3239                 CHECK_MAX_FAILURES(error_test70);
3240                 return False;
3241         }
3242
3243         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3244
3245         if (!cli_close(cli1, fnum1)) {
3246                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3247                 return False;
3248         }
3249
3250         printf("non-io open test #7 passed.\n");
3251 error_test70:
3252         cli_unlink(cli1, fname);
3253
3254         if (!torture_close_connection(cli1)) {
3255                 correct = False;
3256         }
3257         if (!torture_close_connection(cli2)) {
3258                 correct = False;
3259         }
3260         
3261         return correct;
3262 }
3263
3264
3265 static uint32 open_attrs_table[] = {
3266                 FILE_ATTRIBUTE_NORMAL,
3267                 FILE_ATTRIBUTE_ARCHIVE,
3268                 FILE_ATTRIBUTE_READONLY,
3269                 FILE_ATTRIBUTE_HIDDEN,
3270                 FILE_ATTRIBUTE_SYSTEM,
3271
3272                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3273                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3274                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3275                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3276                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3277                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3278
3279                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3280                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3281                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3282                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3283 };
3284
3285 struct trunc_open_results {
3286         unsigned int num;
3287         uint32 init_attr;
3288         uint32 trunc_attr;
3289         uint32 result_attr;
3290 };
3291
3292 static struct trunc_open_results attr_results[] = {
3293         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3294         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3295         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3296         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3297         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3298         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3299         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3300         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3301         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3302         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3303         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3304         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3305         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3306         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3307         { 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 },
3308         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3309         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3310         { 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 },
3311         { 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 },
3312         { 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 },
3313         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3314         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3315         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3316         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3317         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3318         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3319 };
3320
3321 static BOOL run_openattrtest(int dummy)
3322 {
3323         struct cli_state *cli1;
3324         const char *fname = "\\openattr.file";
3325         int fnum1;
3326         BOOL correct = True;
3327         uint16 attr;
3328         unsigned int i, j, k, l;
3329         int failures = 0;
3330
3331         printf("starting open attr test\n");
3332         
3333         if (!torture_open_connection(&cli1)) {
3334                 return False;
3335         }
3336         
3337         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3338                 cli_setatr(cli1, fname, 0, 0);
3339                 cli_unlink(cli1, fname);
3340                 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3341                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3342
3343                 if (fnum1 == -1) {
3344                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3345                         return False;
3346                 }
3347
3348                 if (!cli_close(cli1, fnum1)) {
3349                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3350                         return False;
3351                 }
3352
3353                 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3354                         fnum1 = cli_nt_create_full(cli1, fname, 0, 
3355                                                    SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA, 
3356                                                    open_attrs_table[j],
3357                                                    NTCREATEX_SHARE_ACCESS_NONE, 
3358                                                    NTCREATEX_DISP_OVERWRITE, 0, 0);
3359
3360                         if (fnum1 == -1) {
3361                                 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3362                                         if (attr_results[l].num == k) {
3363                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3364                                                                 k, open_attrs_table[i],
3365                                                                 open_attrs_table[j],
3366                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
3367                                                 correct = False;
3368                                                 CHECK_MAX_FAILURES(error_exit);
3369                                         }
3370                                 }
3371                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3372                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3373                                                         k, open_attrs_table[i], open_attrs_table[j],
3374                                                         cli_errstr(cli1));
3375                                         correct = False;
3376                                         CHECK_MAX_FAILURES(error_exit);
3377                                 }
3378 #if 0
3379                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3380 #endif
3381                                 k++;
3382                                 continue;
3383                         }
3384
3385                         if (!cli_close(cli1, fnum1)) {
3386                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
3387                                 return False;
3388                         }
3389
3390                         if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
3391                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
3392                                 return False;
3393                         }
3394
3395 #if 0
3396                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3397                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
3398 #endif
3399
3400                         for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3401                                 if (attr_results[l].num == k) {
3402                                         if (attr != attr_results[l].result_attr ||
3403                                                         open_attrs_table[i] != attr_results[l].init_attr ||
3404                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
3405                                                 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3406                                                         k, open_attrs_table[i],
3407                                                         open_attrs_table[j],
3408                                                         (unsigned int)attr,
3409                                                         attr_results[l].result_attr);
3410                                                 correct = False;
3411                                                 CHECK_MAX_FAILURES(error_exit);
3412                                         }
3413                                         break;
3414                                 }
3415                         }
3416                         k++;
3417                 }
3418         }
3419 error_exit:
3420         cli_setatr(cli1, fname, 0, 0);
3421         cli_unlink(cli1, fname);
3422
3423         printf("open attr test %s.\n", correct ? "passed" : "failed");
3424
3425         if (!torture_close_connection(cli1)) {
3426                 correct = False;
3427         }
3428         return correct;
3429 }
3430
3431 static void list_fn(file_info *finfo, const char *name, void *state)
3432 {
3433         
3434 }
3435
3436 /*
3437   test directory listing speed
3438  */
3439 static BOOL run_dirtest(int dummy)
3440 {
3441         int i;
3442         struct cli_state *cli;
3443         int fnum;
3444         double t1;
3445         BOOL correct = True;
3446
3447         printf("starting directory test\n");
3448
3449         if (!torture_open_connection(&cli)) {
3450                 return False;
3451         }
3452
3453         printf("Creating %d random filenames\n", torture_numops);
3454
3455         srandom(0);
3456         for (i=0;i<torture_numops;i++) {
3457                 char *fname;
3458                 asprintf(&fname, "\\%x", (int)random());
3459                 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3460                 if (fnum == -1) {
3461                         fprintf(stderr,"Failed to open %s\n", fname);
3462                         return False;
3463                 }
3464                 cli_close(cli, fnum);
3465                 free(fname);
3466         }
3467
3468         t1 = end_timer();
3469
3470         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3471         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3472         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3473
3474         printf("dirtest core %g seconds\n", end_timer() - t1);
3475
3476         srandom(0);
3477         for (i=0;i<torture_numops;i++) {
3478                 char *fname;
3479                 asprintf(&fname, "\\%x", (int)random());
3480                 cli_unlink(cli, fname);
3481                 free(fname);
3482         }
3483
3484         if (!torture_close_connection(cli)) {
3485                 correct = False;
3486         }
3487
3488         printf("finished dirtest\n");
3489
3490         return correct;
3491 }
3492
3493 static void del_fn(file_info *finfo, const char *mask, void *state)
3494 {
3495         struct cli_state *pcli = (struct cli_state *)state;
3496         char *fname;
3497         asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3498
3499         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3500                 return;
3501
3502         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3503                 if (!cli_rmdir(pcli, fname))
3504                         printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli) );
3505         } else {
3506                 if (!cli_unlink(pcli, fname))
3507                         printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli) );
3508         }
3509         free(fname);
3510 }
3511
3512
3513 /*
3514   sees what IOCTLs are supported
3515  */
3516 BOOL torture_ioctl_test(int dummy)
3517 {
3518         struct cli_state *cli;
3519         uint16 device, function;
3520         int fnum;
3521         const char *fname = "\\ioctl.dat";
3522         DATA_BLOB blob;
3523         NTSTATUS status;
3524         struct smb_ioctl parms;
3525         TALLOC_CTX *mem_ctx;
3526
3527         if (!torture_open_connection(&cli)) {
3528                 return False;
3529         }
3530
3531         mem_ctx = talloc_init("ioctl_test");
3532
3533         printf("starting ioctl test\n");
3534
3535         cli_unlink(cli, fname);
3536
3537         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3538         if (fnum == -1) {
3539                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3540                 return False;
3541         }
3542
3543         parms.in.request = IOCTL_QUERY_JOB_INFO;
3544         status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3545         printf("ioctl job info: %s\n", cli_errstr(cli));
3546
3547         for (device=0;device<0x100;device++) {
3548                 printf("testing device=0x%x\n", device);
3549                 for (function=0;function<0x100;function++) {
3550                         parms.in.request = (device << 16) | function;
3551                         status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3552
3553                         if (NT_STATUS_IS_OK(status)) {
3554                                 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n", 
3555                                         device, function, blob.length);
3556                                 data_blob_free(&parms.out.blob);
3557                         }
3558                 }
3559         }
3560
3561         if (!torture_close_connection(cli)) {
3562                 return False;
3563         }
3564
3565         return True;
3566 }
3567
3568
3569 /*
3570   tries variants of chkpath
3571  */
3572 BOOL torture_chkpath_test(int dummy)
3573 {
3574         struct cli_state *cli;
3575         int fnum;
3576         BOOL ret;
3577
3578         if (!torture_open_connection(&cli)) {
3579                 return False;
3580         }
3581
3582         printf("starting chkpath test\n");
3583
3584         printf("Testing valid and invalid paths\n");
3585
3586         /* cleanup from an old run */
3587         cli_rmdir(cli, "\\chkpath.dir\\dir2");
3588         cli_unlink(cli, "\\chkpath.dir\\*");
3589         cli_rmdir(cli, "\\chkpath.dir");
3590
3591         if (!cli_mkdir(cli, "\\chkpath.dir")) {
3592                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
3593                 return False;
3594         }
3595
3596         if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
3597                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
3598                 return False;
3599         }
3600
3601         fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3602         if (fnum == -1) {
3603                 printf("open1 failed (%s)\n", cli_errstr(cli));
3604                 return False;
3605         }
3606         cli_close(cli, fnum);
3607
3608         if (!cli_chkpath(cli, "\\chkpath.dir")) {
3609                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
3610                 ret = False;
3611         }
3612
3613         if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
3614                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
3615                 ret = False;
3616         }
3617
3618         if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
3619                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
3620                                   NT_STATUS_NOT_A_DIRECTORY);
3621         } else {
3622                 printf("* chkpath on a file should fail\n");
3623                 ret = False;
3624         }
3625
3626         if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
3627                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
3628                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
3629         } else {
3630                 printf("* chkpath on a non existent file should fail\n");
3631                 ret = False;
3632         }
3633
3634         if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
3635                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
3636                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
3637         } else {
3638                 printf("* chkpath on a non existent component should fail\n");
3639                 ret = False;
3640         }
3641
3642         cli_rmdir(cli, "\\chkpath.dir\\dir2");
3643         cli_unlink(cli, "\\chkpath.dir\\*");
3644         cli_rmdir(cli, "\\chkpath.dir");
3645
3646         if (!torture_close_connection(cli)) {
3647                 return False;
3648         }
3649
3650         return ret;
3651 }
3652
3653 static BOOL run_dirtest1(int dummy)
3654 {
3655         int i;
3656         struct cli_state *cli;
3657         int fnum, num_seen;
3658         BOOL correct = True;
3659
3660         printf("starting directory test\n");
3661
3662         if (!torture_open_connection(&cli)) {
3663                 return False;
3664         }
3665
3666         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3667         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3668         if (cli_deltree(cli, "\\LISTDIR") == -1) {
3669                 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3670                 return False;
3671         }
3672         if (!cli_mkdir(cli, "\\LISTDIR")) {
3673                 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3674                 return False;
3675         }
3676
3677         printf("Creating %d files\n", torture_entries);
3678
3679         /* Create torture_entries files and torture_entries directories. */
3680         for (i=0;i<torture_entries;i++) {
3681                 char *fname;
3682                 asprintf(&fname, "\\LISTDIR\\f%d", i);
3683                 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3684                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3685                 if (fnum == -1) {
3686                         fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3687                         return False;
3688                 }
3689                 free(fname);
3690                 cli_close(cli, fnum);
3691         }
3692         for (i=0;i<torture_entries;i++) {
3693                 char *fname;
3694                 asprintf(&fname, "\\LISTDIR\\d%d", i);
3695                 if (!cli_mkdir(cli, fname)) {
3696                         fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3697                         return False;
3698                 }
3699                 free(fname);
3700         }
3701
3702         /* Now ensure that doing an old list sees both files and directories. */
3703         num_seen = cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3704         printf("num_seen = %d\n", num_seen );
3705         /* We should see (torture_entries) each of files & directories + . and .. */
3706         if (num_seen != (2*torture_entries)+2) {
3707                 correct = False;
3708                 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3709                         (2*torture_entries)+2, num_seen);
3710         }
3711                 
3712
3713         /* Ensure if we have the "must have" bits we only see the
3714          * relevant entries.
3715          */
3716         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3717         printf("num_seen = %d\n", num_seen );
3718         if (num_seen != torture_entries+2) {
3719                 correct = False;
3720                 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3721                         torture_entries+2, num_seen);
3722         }
3723
3724         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3725         printf("num_seen = %d\n", num_seen );
3726         if (num_seen != torture_entries) {
3727                 correct = False;
3728                 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3729                         torture_entries, num_seen);
3730         }
3731
3732         /* Delete everything. */
3733         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3734         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3735         cli_rmdir(cli, "\\LISTDIR");
3736
3737 #if 0
3738         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3739         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3740         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3741 #endif
3742
3743         if (!torture_close_connection(cli)) {
3744                 correct = False;
3745         }
3746
3747         printf("finished dirtest1\n");
3748
3749         return correct;
3750 }
3751
3752
3753 /*
3754    simple test harness for playing with deny modes
3755  */
3756 static BOOL run_deny3test(int dummy)
3757 {
3758         struct cli_state *cli1, *cli2;
3759         int fnum1, fnum2;
3760         const char *fname;
3761
3762         printf("starting deny3 test\n");
3763
3764         printf("Testing simple deny modes\n");
3765         
3766         if (!torture_open_connection(&cli1)) {
3767                 return False;
3768         }
3769         if (!torture_open_connection(&cli2)) {
3770                 return False;
3771         }
3772
3773         fname = "\\deny_dos1.dat";
3774
3775         cli_unlink(cli1, fname);
3776         fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3777         fnum2 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3778         if (fnum1 != -1) cli_close(cli1, fnum1);
3779         if (fnum2 != -1) cli_close(cli1, fnum2);
3780         cli_unlink(cli1, fname);
3781         printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3782
3783
3784         fname = "\\deny_dos2.dat";
3785
3786         cli_unlink(cli1, fname);
3787         fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3788         fnum2 = cli_open(cli2, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3789         if (fnum1 != -1) cli_close(cli1, fnum1);
3790         if (fnum2 != -1) cli_close(cli2, fnum2);
3791         cli_unlink(cli1, fname);
3792         printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3793
3794
3795         torture_close_connection(cli1);
3796         torture_close_connection(cli2);
3797
3798         return True;
3799 }
3800
3801 static void sigcont(void)
3802 {
3803 }
3804
3805 static double create_procs(BOOL (*fn)(int), BOOL *result)
3806 {
3807         int i, status;
3808         volatile pid_t *child_status;
3809         volatile BOOL *child_status_out;
3810         int synccount;
3811         int tries = 8;
3812         double start_time_limit = 10 + (nprocs * 1.5);
3813
3814         synccount = 0;
3815
3816         signal(SIGCONT, sigcont);
3817
3818         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3819         if (!child_status) {
3820                 printf("Failed to setup shared memory\n");
3821                 return -1;
3822         }
3823
3824         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3825         if (!child_status_out) {
3826                 printf("Failed to setup result status shared memory\n");
3827                 return -1;
3828         }
3829
3830         for (i = 0; i < nprocs; i++) {
3831                 child_status[i] = 0;
3832                 child_status_out[i] = True;
3833         }
3834
3835         start_timer();
3836
3837         for (i=0;i<nprocs;i++) {
3838                 procnum = i;
3839                 if (fork() == 0) {
3840                         char *myname;
3841                         pid_t mypid = getpid();
3842                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3843
3844                         asprintf(&myname, "CLIENT%d", i);
3845                         lp_set_cmdline("netbios name", myname);
3846                         free(myname);
3847
3848                         while (1) {
3849                                 if (torture_open_connection(&current_cli)) break;
3850                                 if (tries-- == 0) {
3851                                         printf("pid %d failed to start\n", (int)getpid());
3852                                         _exit(1);
3853                                 }
3854                                 msleep(100);    
3855                         }
3856
3857                         child_status[i] = getpid();
3858
3859                         pause();
3860
3861                         if (child_status[i]) {
3862                                 printf("Child %d failed to start!\n", i);
3863                                 child_status_out[i] = 1;
3864                                 _exit(1);
3865                         }
3866
3867                         child_status_out[i] = fn(i);
3868                         _exit(0);
3869                 }
3870         }
3871
3872         do {
3873                 synccount = 0;
3874                 for (i=0;i<nprocs;i++) {
3875                         if (child_status[i]) synccount++;
3876                 }
3877                 if (synccount == nprocs) break;
3878                 msleep(100);
3879         } while (end_timer() < start_time_limit);
3880
3881         if (synccount != nprocs) {
3882                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3883                 *result = False;
3884                 return end_timer();
3885         }
3886
3887         printf("Starting %d clients\n", nprocs);
3888
3889         /* start the client load */
3890         start_timer();
3891         for (i=0;i<nprocs;i++) {
3892                 child_status[i] = 0;
3893         }
3894         kill(0, SIGCONT);
3895
3896         printf("%d clients started\n", nprocs);
3897
3898         for (i=0;i<nprocs;i++) {
3899                 int ret;
3900                 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
3901                 if (ret == -1 || WEXITSTATUS(status) != 0) {
3902                         *result = False;
3903                 }
3904         }
3905
3906         printf("\n");
3907         
3908         for (i=0;i<nprocs;i++) {
3909                 if (!child_status_out[i]) {
3910                         *result = False;
3911                 }
3912         }
3913         return end_timer();
3914 }
3915
3916 #define FLAG_MULTIPROC 1
3917
3918 static struct {
3919         const char *name;
3920         BOOL (*fn)(int);
3921         unsigned flags;
3922 } torture_ops[] = {
3923         {"FDPASS", run_fdpasstest, 0},
3924         {"LOCK1",  run_locktest1,  0},
3925         {"LOCK2",  run_locktest2,  0},
3926         {"LOCK3",  run_locktest3,  0},
3927         {"LOCK4",  run_locktest4,  0},
3928         {"LOCK5",  run_locktest5,  0},
3929         {"LOCK6",  run_locktest6,  0},
3930         {"LOCK7",  run_locktest7,  0},
3931         {"UNLINK", run_unlinktest, 0},
3932         {"ATTR",   run_attrtest,   0},
3933         {"TRANS2", run_trans2test, 0},
3934         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3935         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3936         {"NEGNOWAIT", run_negprot_nowait, 0},
3937         {"NBENCH",  run_nbench, 0},
3938         {"DIR",  run_dirtest, 0},
3939         {"DIR1",  run_dirtest1, 0},
3940         {"DENY1",  torture_denytest1, 0},
3941         {"DENY2",  torture_denytest2, 0},
3942         {"TCON",  run_tcon_test, 0},
3943         {"TCONDEV",  run_tcon_devtype_test, 0},
3944 #if 0
3945         {"DFSBASIC", torture_dfs_basic, 0},
3946         {"DFSRENAME", torture_dfs_rename, 0},
3947         {"DFSRANDOM", torture_dfs_random, 0},
3948 #endif
3949         {"RW1",  run_readwritetest, 0},
3950         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3951         {"OPEN", run_opentest, 0},
3952         {"DENY3", run_deny3test, 0},
3953 #if 1
3954         {"OPENATTR", run_openattrtest, 0},
3955 #endif
3956         {"XCOPY", run_xcopy, 0},
3957         {"RENAME", run_rename, 0},
3958         {"DELETE", run_deletetest, 0},
3959         {"PROPERTIES", run_properties, 0},
3960         {"MANGLE", torture_mangle, 0},
3961         {"UTABLE", torture_utable, 0},
3962         {"CASETABLE", torture_casetable, 0},
3963         {"PIPE_NUMBER", run_pipe_number, 0},
3964         {"IOCTL",  torture_ioctl_test, 0},
3965         {"CHKPATH",  torture_chkpath_test, 0},
3966         {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
3967         {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
3968         {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
3969         {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
3970         {"RAW-SEARCH", torture_raw_search, 0},
3971         {"RAW-CLOSE", torture_raw_close, 0},
3972         {"RAW-OPEN", torture_raw_open, 0},
3973         {"RAW-MKDIR", torture_raw_mkdir, 0},
3974         {"RAW-OPLOCK", torture_raw_oplock, 0},
3975         {"RAW-NOTIFY", torture_raw_notify, 0},
3976         {"RAW-MUX", torture_raw_mux, 0},
3977         {"RAW-IOCTL", torture_raw_ioctl, 0},
3978         {"RAW-CHKPATH", torture_raw_chkpath, 0},
3979         {"RAW-UNLINK", torture_raw_unlink, 0},
3980         {"RAW-READ", torture_raw_read, 0},
3981         {"RAW-WRITE", torture_raw_write, 0},
3982         {"RAW-LOCK", torture_raw_lock, 0},
3983         {"RAW-CONTEXT", torture_raw_context, 0},
3984         {"RAW-RENAME", torture_raw_rename, 0},
3985         {"RAW-SEEK", torture_raw_seek, 0},
3986         {"SCAN-TRANS2", torture_trans2_scan, 0},
3987         {"SCAN-NTTRANS", torture_nttrans_scan, 0},
3988         {"SCAN-ALIASES", torture_trans2_aliases, 0},
3989         {"SCAN-SMB", torture_smb_scan, 0},
3990         {"RPC-LSA", torture_rpc_lsa, 0},
3991         {"RPC-ECHO", torture_rpc_echo, 0},
3992         {"RPC-DFS", torture_rpc_dfs, 0},
3993         {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
3994         {"RPC-SAMR", torture_rpc_samr, 0},
3995         {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
3996         {NULL, NULL, 0}};
3997
3998
3999
4000 /****************************************************************************
4001 run a specified test or "ALL"
4002 ****************************************************************************/
4003 static BOOL run_test(const char *name)
4004 {
4005         BOOL ret = True;
4006         int i;
4007         BOOL matched = False;
4008
4009         if (strequal(name,"ALL")) {
4010                 for (i=0;torture_ops[i].name;i++) {
4011                         if (!run_test(torture_ops[i].name)) {
4012                                 ret = False;
4013                         }
4014                 }
4015                 return ret;
4016         }
4017
4018         for (i=0;torture_ops[i].name;i++) {
4019                 asprintf(&randomfname, "\\XX%x", 
4020                          (unsigned)random());
4021
4022                 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4023                         double t;
4024                         matched = True;
4025                         printf("Running %s\n", torture_ops[i].name);
4026                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
4027                                 BOOL result;
4028                                 t = create_procs(torture_ops[i].fn, &result);
4029                                 if (!result) { 
4030                                         ret = False;
4031                                         printf("TEST %s FAILED!\n", torture_ops[i].name);
4032                                 }
4033                                          
4034                         } else {
4035                                 start_timer();
4036                                 if (!torture_ops[i].fn(0)) {
4037                                         ret = False;
4038                                         printf("TEST %s FAILED!\n", torture_ops[i].name);
4039                                 }
4040                                 t = end_timer();
4041                         }
4042                         printf("%s took %g secs\n\n", torture_ops[i].name, t);
4043                 }
4044         }
4045
4046         if (!matched) {
4047                 printf("Unknown torture operation '%s'\n", name);
4048         }
4049
4050         return ret;
4051 }
4052
4053
4054 /*
4055   parse a username%password
4056 */
4057 static void parse_user(const char *user)
4058 {
4059         char *username, *password, *p;
4060
4061         username = strdup(user);
4062         p = strchr_m(username,'%');
4063         if (p) {
4064                 *p = 0;
4065                 password = strdup(p+1);
4066         }
4067
4068         lp_set_cmdline("torture:username", username);
4069         lp_set_cmdline("torture:password", password);
4070 }
4071
4072
4073 static void usage(void)
4074 {
4075         int i;
4076
4077         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4078
4079         printf("\t-d debuglevel\n");
4080         printf("\t-U user%%pass\n");
4081         printf("\t-k use kerberos\n");
4082         printf("\t-N numprocs\n");
4083         printf("\t-n my_netbios_name\n");
4084         printf("\t-W workgroup\n");
4085         printf("\t-o num_operations\n");
4086         printf("\t-e num files(entries)\n");
4087         printf("\t-O socket_options\n");
4088         printf("\t-m maximum protocol\n");
4089         printf("\t-L use oplocks\n");
4090         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
4091         printf("\t-A showall\n");
4092         printf("\t-p port\n");
4093         printf("\t-s seed\n");
4094         printf("\t-f max failures\n");
4095         printf("\t-b bypass I/O (NBENCH)\n");
4096         printf("\n\n");
4097
4098         printf("tests are:");
4099         for (i=0;torture_ops[i].name;i++) {
4100                 printf(" %s", torture_ops[i].name);
4101         }
4102         printf("\n");
4103
4104         printf("default test is ALL\n");
4105         
4106         exit(1);
4107 }
4108
4109 /****************************************************************************
4110   main program
4111 ****************************************************************************/
4112  int main(int argc,char *argv[])
4113 {
4114         int opt, i;
4115         char *p;
4116         BOOL correct = True;
4117         char *host, *share, *username;
4118
4119         setup_logging("smbtorture", DEBUG_STDOUT);
4120
4121 #ifdef HAVE_SETBUFFER
4122         setbuffer(stdout, NULL, 0);
4123 #endif
4124
4125         lp_load(dyn_CONFIGFILE,True,False,False);
4126         load_interfaces();
4127
4128         if (argc < 2) {
4129                 usage();
4130         }
4131
4132         for(p = argv[1]; *p; p++)
4133           if(*p == '\\')
4134             *p = '/';
4135  
4136         if (strncmp(argv[1], "//", 2)) {
4137                 usage();
4138         }
4139
4140         host = strdup(&argv[1][2]);
4141         p = strchr_m(&host[2],'/');
4142         if (!p) {
4143                 usage();
4144         }
4145         *p = 0;
4146         share = strdup(p+1);
4147
4148         if (getenv("LOGNAME")) {
4149                 username = strdup(getenv("LOGNAME"));
4150         }
4151
4152         lp_set_cmdline("torture:host", host);
4153         lp_set_cmdline("torture:share", share);
4154         lp_set_cmdline("torture:username", username);
4155         lp_set_cmdline("torture:password", "");
4156
4157         argc--;
4158         argv++;
4159
4160         srandom(time(NULL));
4161
4162         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:")) != EOF) {
4163                 switch (opt) {
4164                 case 'p':
4165                         lp_set_cmdline("smb ports", optarg);
4166                         break;
4167                 case 'W':
4168                         lp_set_cmdline("workgroup", optarg);
4169                         break;
4170                 case 'm':
4171                         lp_set_cmdline("protocol", optarg);
4172                         break;
4173                 case 'n':
4174                         lp_set_cmdline("netbios name", optarg);
4175                         break;
4176                 case 'd':
4177                         lp_set_cmdline("debug level", optarg);
4178                         setup_logging(NULL, DEBUG_STDOUT);
4179                         break;
4180                 case 'O':
4181                         lp_set_cmdline("socket options", optarg);
4182                         break;
4183                 case 's':
4184                         srandom(atoi(optarg));
4185                         break;
4186                 case 'N':
4187                         nprocs = atoi(optarg);
4188                         break;
4189                 case 'o':
4190                         torture_numops = atoi(optarg);
4191                         break;
4192                 case 'e':
4193                         torture_entries = atoi(optarg);
4194                         break;
4195                 case 'L':
4196                         use_oplocks = True;
4197                         break;
4198                 case 'A':
4199                         torture_showall = True;
4200                         break;
4201                 case 'c':
4202                         client_txt = optarg;
4203                         break;
4204                 case 'k':
4205 #ifdef HAVE_KRB5
4206                         use_kerberos = True;
4207 #else
4208                         d_printf("No kerberos support compiled in\n");
4209                         exit(1);
4210 #endif
4211                         break;
4212                 case 'U':
4213                         parse_user(optarg);
4214                         break;
4215                 case 'f':
4216                         torture_failures = atoi(optarg);
4217                         break;
4218
4219                 default:
4220                         printf("Unknown option %c (%d)\n", (char)opt, opt);
4221                         usage();
4222                 }
4223         }
4224
4225         printf("host=%s share=%s user=%s myname=%s\n", 
4226                host, share, lp_parm_string(-1, "torture", "username"), 
4227                lp_netbios_name());
4228
4229         if (argc == optind) {
4230                 printf("You must specify a test to run, or 'ALL'\n");
4231         } else {
4232                 for (i=optind;i<argc;i++) {
4233                         if (!run_test(argv[i])) {
4234                                 correct = False;
4235                         }
4236                 }
4237         }
4238
4239         if (correct) {
4240                 return(0);
4241         } else {
4242                 return(1);
4243         }
4244 }