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