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