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