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