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