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