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