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