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