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