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