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