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