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