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