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