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