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