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