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