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