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