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