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