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