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