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