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