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