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