s3: async cli_list
[ddiss/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 = 0;
5187         cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5188         printf("num_seen = %d\n", num_seen );
5189         /* We should see 100 files + 1000 directories + . and .. */
5190         if (num_seen != 2002)
5191                 correct = False;
5192
5193         /* Ensure if we have the "must have" bits we only see the
5194          * relevent entries.
5195          */
5196         num_seen = 0;
5197         cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5198         printf("num_seen = %d\n", num_seen );
5199         if (num_seen != 1002)
5200                 correct = False;
5201
5202         num_seen = 0;
5203         cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5204         printf("num_seen = %d\n", num_seen );
5205         if (num_seen != 1000)
5206                 correct = False;
5207
5208         /* Delete everything. */
5209         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5210         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5211         cli_rmdir(cli, "\\LISTDIR");
5212
5213 #if 0
5214         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5215         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5216         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5217 #endif
5218
5219         if (!torture_close_connection(cli)) {
5220                 correct = False;
5221         }
5222
5223         printf("finished dirtest1\n");
5224
5225         return correct;
5226 }
5227
5228 static bool run_error_map_extract(int dummy) {
5229
5230         static struct cli_state *c_dos;
5231         static struct cli_state *c_nt;
5232         NTSTATUS status;
5233
5234         uint32 error;
5235
5236         uint32 flgs2, errnum;
5237         uint8 errclass;
5238
5239         NTSTATUS nt_status;
5240
5241         fstring user;
5242
5243         /* NT-Error connection */
5244
5245         if (!(c_nt = open_nbt_connection())) {
5246                 return False;
5247         }
5248
5249         c_nt->use_spnego = False;
5250
5251         status = cli_negprot(c_nt);
5252
5253         if (!NT_STATUS_IS_OK(status)) {
5254                 printf("%s rejected the NT-error negprot (%s)\n", host,
5255                        nt_errstr(status));
5256                 cli_shutdown(c_nt);
5257                 return False;
5258         }
5259
5260         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5261                                                workgroup))) {
5262                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5263                 return False;
5264         }
5265
5266         /* DOS-Error connection */
5267
5268         if (!(c_dos = open_nbt_connection())) {
5269                 return False;
5270         }
5271
5272         c_dos->use_spnego = False;
5273         c_dos->force_dos_errors = True;
5274
5275         status = cli_negprot(c_dos);
5276         if (!NT_STATUS_IS_OK(status)) {
5277                 printf("%s rejected the DOS-error negprot (%s)\n", host,
5278                        nt_errstr(status));
5279                 cli_shutdown(c_dos);
5280                 return False;
5281         }
5282
5283         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5284                                                workgroup))) {
5285                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5286                 return False;
5287         }
5288
5289         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5290                 fstr_sprintf(user, "%X", error);
5291
5292                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
5293                                                       password, strlen(password),
5294                                                       password, strlen(password),
5295                                                       workgroup))) {
5296                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5297                 }
5298
5299                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5300
5301                 /* Case #1: 32-bit NT errors */
5302                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5303                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5304                 } else {
5305                         printf("/** Dos error on NT connection! (%s) */\n", 
5306                                cli_errstr(c_nt));
5307                         nt_status = NT_STATUS(0xc0000000);
5308                 }
5309
5310                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
5311                                                       password, strlen(password),
5312                                                       password, strlen(password),
5313                                                       workgroup))) {
5314                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5315                 }
5316                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5317
5318                 /* Case #1: 32-bit NT errors */
5319                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5320                         printf("/** NT error on DOS connection! (%s) */\n", 
5321                                cli_errstr(c_nt));
5322                         errnum = errclass = 0;
5323                 } else {
5324                         cli_dos_error(c_dos, &errclass, &errnum);
5325                 }
5326
5327                 if (NT_STATUS_V(nt_status) != error) { 
5328                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
5329                                get_nt_error_c_code(NT_STATUS(error)), 
5330                                get_nt_error_c_code(nt_status));
5331                 }
5332
5333                 printf("\t{%s,\t%s,\t%s},\n", 
5334                        smb_dos_err_class(errclass), 
5335                        smb_dos_err_name(errclass, errnum), 
5336                        get_nt_error_c_code(NT_STATUS(error)));
5337         }
5338         return True;
5339 }
5340
5341 static bool run_sesssetup_bench(int dummy)
5342 {
5343         static struct cli_state *c;
5344         const char *fname = "\\file.dat";
5345         uint16_t fnum;
5346         NTSTATUS status;
5347         int i;
5348
5349         if (!torture_open_connection(&c, 0)) {
5350                 return false;
5351         }
5352
5353         if (!NT_STATUS_IS_OK(cli_ntcreate(
5354                         c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5355                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5356                         FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5357                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5358                 return false;
5359         }
5360
5361         for (i=0; i<torture_numops; i++) {
5362                 status = cli_session_setup(
5363                         c, username,
5364                         password, strlen(password),
5365                         password, strlen(password),
5366                         workgroup);
5367                 if (!NT_STATUS_IS_OK(status)) {
5368                         d_printf("(%s) cli_session_setup failed: %s\n",
5369                                  __location__, nt_errstr(status));
5370                         return false;
5371                 }
5372
5373                 d_printf("\r%d   ", (int)c->vuid);
5374
5375                 status = cli_ulogoff(c);
5376                 if (!NT_STATUS_IS_OK(status)) {
5377                         d_printf("(%s) cli_ulogoff failed: %s\n",
5378                                  __location__, nt_errstr(status));
5379                         return false;
5380                 }
5381                 c->vuid = 0;
5382         }
5383
5384         return true;
5385 }
5386
5387 static bool subst_test(const char *str, const char *user, const char *domain,
5388                        uid_t uid, gid_t gid, const char *expected)
5389 {
5390         char *subst;
5391         bool result = true;
5392
5393         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5394
5395         if (strcmp(subst, expected) != 0) {
5396                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5397                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5398                        expected);
5399                 result = false;
5400         }
5401
5402         TALLOC_FREE(subst);
5403         return result;
5404 }
5405
5406 static void chain1_open_completion(struct tevent_req *req)
5407 {
5408         uint16_t fnum;
5409         NTSTATUS status;
5410         status = cli_open_recv(req, &fnum);
5411         TALLOC_FREE(req);
5412
5413         d_printf("cli_open_recv returned %s: %d\n",
5414                  nt_errstr(status),
5415                  NT_STATUS_IS_OK(status) ? fnum : -1);
5416 }
5417
5418 static void chain1_write_completion(struct tevent_req *req)
5419 {
5420         size_t written;
5421         NTSTATUS status;
5422         status = cli_write_andx_recv(req, &written);
5423         TALLOC_FREE(req);
5424
5425         d_printf("cli_write_andx_recv returned %s: %d\n",
5426                  nt_errstr(status),
5427                  NT_STATUS_IS_OK(status) ? (int)written : -1);
5428 }
5429
5430 static void chain1_close_completion(struct tevent_req *req)
5431 {
5432         NTSTATUS status;
5433         bool *done = (bool *)tevent_req_callback_data_void(req);
5434
5435         status = cli_close_recv(req);
5436         *done = true;
5437
5438         TALLOC_FREE(req);
5439
5440         d_printf("cli_close returned %s\n", nt_errstr(status));
5441 }
5442
5443 static bool run_chain1(int dummy)
5444 {
5445         struct cli_state *cli1;
5446         struct event_context *evt = event_context_init(NULL);
5447         struct tevent_req *reqs[3], *smbreqs[3];
5448         bool done = false;
5449         const char *str = "foobar";
5450         NTSTATUS status;
5451
5452         printf("starting chain1 test\n");
5453         if (!torture_open_connection(&cli1, 0)) {
5454                 return False;
5455         }
5456
5457         cli_sockopt(cli1, sockops);
5458
5459         reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5460                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
5461         if (reqs[0] == NULL) return false;
5462         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5463
5464
5465         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5466                                         (uint8_t *)str, 0, strlen(str)+1,
5467                                         smbreqs, 1, &smbreqs[1]);
5468         if (reqs[1] == NULL) return false;
5469         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5470
5471         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5472         if (reqs[2] == NULL) return false;
5473         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5474
5475         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5476         if (!NT_STATUS_IS_OK(status)) {
5477                 return false;
5478         }
5479
5480         while (!done) {
5481                 event_loop_once(evt);
5482         }
5483
5484         torture_close_connection(cli1);
5485         return True;
5486 }
5487
5488 static void chain2_sesssetup_completion(struct tevent_req *req)
5489 {
5490         NTSTATUS status;
5491         status = cli_session_setup_guest_recv(req);
5492         d_printf("sesssetup returned %s\n", nt_errstr(status));
5493 }
5494
5495 static void chain2_tcon_completion(struct tevent_req *req)
5496 {
5497         bool *done = (bool *)tevent_req_callback_data_void(req);
5498         NTSTATUS status;
5499         status = cli_tcon_andx_recv(req);
5500         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5501         *done = true;
5502 }
5503
5504 static bool run_chain2(int dummy)
5505 {
5506         struct cli_state *cli1;
5507         struct event_context *evt = event_context_init(NULL);
5508         struct tevent_req *reqs[2], *smbreqs[2];
5509         bool done = false;
5510         NTSTATUS status;
5511
5512         printf("starting chain2 test\n");
5513         status = cli_start_connection(&cli1, global_myname(), host, NULL,
5514                                       port_to_use, Undefined, 0, NULL);
5515         if (!NT_STATUS_IS_OK(status)) {
5516                 return False;
5517         }
5518
5519         cli_sockopt(cli1, sockops);
5520
5521         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5522                                                  &smbreqs[0]);
5523         if (reqs[0] == NULL) return false;
5524         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5525
5526         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5527                                        "?????", NULL, 0, &smbreqs[1]);
5528         if (reqs[1] == NULL) return false;
5529         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5530
5531         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5532         if (!NT_STATUS_IS_OK(status)) {
5533                 return false;
5534         }
5535
5536         while (!done) {
5537                 event_loop_once(evt);
5538         }
5539
5540         torture_close_connection(cli1);
5541         return True;
5542 }
5543
5544
5545 struct torture_createdel_state {
5546         struct tevent_context *ev;
5547         struct cli_state *cli;
5548 };
5549
5550 static void torture_createdel_created(struct tevent_req *subreq);
5551 static void torture_createdel_closed(struct tevent_req *subreq);
5552
5553 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5554                                                  struct tevent_context *ev,
5555                                                  struct cli_state *cli,
5556                                                  const char *name)
5557 {
5558         struct tevent_req *req, *subreq;
5559         struct torture_createdel_state *state;
5560
5561         req = tevent_req_create(mem_ctx, &state,
5562                                 struct torture_createdel_state);
5563         if (req == NULL) {
5564                 return NULL;
5565         }
5566         state->ev = ev;
5567         state->cli = cli;
5568
5569         subreq = cli_ntcreate_send(
5570                 state, ev, cli, name, 0,
5571                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5572                 FILE_ATTRIBUTE_NORMAL,
5573                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5574                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5575
5576         if (tevent_req_nomem(subreq, req)) {
5577                 return tevent_req_post(req, ev);
5578         }
5579         tevent_req_set_callback(subreq, torture_createdel_created, req);
5580         return req;
5581 }
5582
5583 static void torture_createdel_created(struct tevent_req *subreq)
5584 {
5585         struct tevent_req *req = tevent_req_callback_data(
5586                 subreq, struct tevent_req);
5587         struct torture_createdel_state *state = tevent_req_data(
5588                 req, struct torture_createdel_state);
5589         NTSTATUS status;
5590         uint16_t fnum;
5591
5592         status = cli_ntcreate_recv(subreq, &fnum);
5593         TALLOC_FREE(subreq);
5594         if (!NT_STATUS_IS_OK(status)) {
5595                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5596                            nt_errstr(status)));
5597                 tevent_req_nterror(req, status);
5598                 return;
5599         }
5600
5601         subreq = cli_close_send(state, state->ev, state->cli, fnum);
5602         if (tevent_req_nomem(subreq, req)) {
5603                 return;
5604         }
5605         tevent_req_set_callback(subreq, torture_createdel_closed, req);
5606 }
5607
5608 static void torture_createdel_closed(struct tevent_req *subreq)
5609 {
5610         struct tevent_req *req = tevent_req_callback_data(
5611                 subreq, struct tevent_req);
5612         NTSTATUS status;
5613
5614         status = cli_close_recv(subreq);
5615         if (!NT_STATUS_IS_OK(status)) {
5616                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5617                 tevent_req_nterror(req, status);
5618                 return;
5619         }
5620         tevent_req_done(req);
5621 }
5622
5623 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5624 {
5625         return tevent_req_simple_recv_ntstatus(req);
5626 }
5627
5628 struct torture_createdels_state {
5629         struct tevent_context *ev;
5630         struct cli_state *cli;
5631         const char *base_name;
5632         int sent;
5633         int received;
5634         int num_files;
5635         struct tevent_req **reqs;
5636 };
5637
5638 static void torture_createdels_done(struct tevent_req *subreq);
5639
5640 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5641                                                   struct tevent_context *ev,
5642                                                   struct cli_state *cli,
5643                                                   const char *base_name,
5644                                                   int num_parallel,
5645                                                   int num_files)
5646 {
5647         struct tevent_req *req;
5648         struct torture_createdels_state *state;
5649         int i;
5650
5651         req = tevent_req_create(mem_ctx, &state,
5652                                 struct torture_createdels_state);
5653         if (req == NULL) {
5654                 return NULL;
5655         }
5656         state->ev = ev;
5657         state->cli = cli;
5658         state->base_name = talloc_strdup(state, base_name);
5659         if (tevent_req_nomem(state->base_name, req)) {
5660                 return tevent_req_post(req, ev);
5661         }
5662         state->num_files = MAX(num_parallel, num_files);
5663         state->sent = 0;
5664         state->received = 0;
5665
5666         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5667         if (tevent_req_nomem(state->reqs, req)) {
5668                 return tevent_req_post(req, ev);
5669         }
5670
5671         for (i=0; i<num_parallel; i++) {
5672                 char *name;
5673
5674                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5675                                        state->sent);
5676                 if (tevent_req_nomem(name, req)) {
5677                         return tevent_req_post(req, ev);
5678                 }
5679                 state->reqs[i] = torture_createdel_send(
5680                         state->reqs, state->ev, state->cli, name);
5681                 if (tevent_req_nomem(state->reqs[i], req)) {
5682                         return tevent_req_post(req, ev);
5683                 }
5684                 name = talloc_move(state->reqs[i], &name);
5685                 tevent_req_set_callback(state->reqs[i],
5686                                         torture_createdels_done, req);
5687                 state->sent += 1;
5688         }
5689         return req;
5690 }
5691
5692 static void torture_createdels_done(struct tevent_req *subreq)
5693 {
5694         struct tevent_req *req = tevent_req_callback_data(
5695                 subreq, struct tevent_req);
5696         struct torture_createdels_state *state = tevent_req_data(
5697                 req, struct torture_createdels_state);
5698         size_t num_parallel = talloc_array_length(state->reqs);
5699         NTSTATUS status;
5700         char *name;
5701         int i;
5702
5703         status = torture_createdel_recv(subreq);
5704         if (!NT_STATUS_IS_OK(status)){
5705                 DEBUG(10, ("torture_createdel_recv returned %s\n",
5706                            nt_errstr(status)));
5707                 TALLOC_FREE(subreq);
5708                 tevent_req_nterror(req, status);
5709                 return;
5710         }
5711
5712         for (i=0; i<num_parallel; i++) {
5713                 if (subreq == state->reqs[i]) {
5714                         break;
5715                 }
5716         }
5717         if (i == num_parallel) {
5718                 DEBUG(10, ("received something we did not send\n"));
5719                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5720                 return;
5721         }
5722         TALLOC_FREE(state->reqs[i]);
5723
5724         if (state->sent >= state->num_files) {
5725                 tevent_req_done(req);
5726                 return;
5727         }
5728
5729         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5730                                state->sent);
5731         if (tevent_req_nomem(name, req)) {
5732                 return;
5733         }
5734         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5735                                                 state->cli, name);
5736         if (tevent_req_nomem(state->reqs[i], req)) {
5737                 return;
5738         }
5739         name = talloc_move(state->reqs[i], &name);
5740         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5741         state->sent += 1;
5742 }
5743
5744 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5745 {
5746         return tevent_req_simple_recv_ntstatus(req);
5747 }
5748
5749 struct swallow_notify_state {
5750         struct tevent_context *ev;
5751         struct cli_state *cli;
5752         uint16_t fnum;
5753         uint32_t completion_filter;
5754         bool recursive;
5755         bool (*fn)(uint32_t action, const char *name, void *priv);
5756         void *priv;
5757 };
5758
5759 static void swallow_notify_done(struct tevent_req *subreq);
5760
5761 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5762                                               struct tevent_context *ev,
5763                                               struct cli_state *cli,
5764                                               uint16_t fnum,
5765                                               uint32_t completion_filter,
5766                                               bool recursive,
5767                                               bool (*fn)(uint32_t action,
5768                                                          const char *name,
5769                                                          void *priv),
5770                                               void *priv)
5771 {
5772         struct tevent_req *req, *subreq;
5773         struct swallow_notify_state *state;
5774
5775         req = tevent_req_create(mem_ctx, &state,
5776                                 struct swallow_notify_state);
5777         if (req == NULL) {
5778                 return NULL;
5779         }
5780         state->ev = ev;
5781         state->cli = cli;
5782         state->fnum = fnum;
5783         state->completion_filter = completion_filter;
5784         state->recursive = recursive;
5785         state->fn = fn;
5786         state->priv = priv;
5787
5788         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5789                                  0xffff, state->completion_filter,
5790                                  state->recursive);
5791         if (tevent_req_nomem(subreq, req)) {
5792                 return tevent_req_post(req, ev);
5793         }
5794         tevent_req_set_callback(subreq, swallow_notify_done, req);
5795         return req;
5796 }
5797
5798 static void swallow_notify_done(struct tevent_req *subreq)
5799 {
5800         struct tevent_req *req = tevent_req_callback_data(
5801                 subreq, struct tevent_req);
5802         struct swallow_notify_state *state = tevent_req_data(
5803                 req, struct swallow_notify_state);
5804         NTSTATUS status;
5805         uint32_t i, num_changes;
5806         struct notify_change *changes;
5807
5808         status = cli_notify_recv(subreq, state, &num_changes, &changes);
5809         TALLOC_FREE(subreq);
5810         if (!NT_STATUS_IS_OK(status)) {
5811                 DEBUG(10, ("cli_notify_recv returned %s\n",
5812                            nt_errstr(status)));
5813                 tevent_req_nterror(req, status);
5814                 return;
5815         }
5816
5817         for (i=0; i<num_changes; i++) {
5818                 state->fn(changes[i].action, changes[i].name, state->priv);
5819         }
5820         TALLOC_FREE(changes);
5821
5822         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5823                                  0xffff, state->completion_filter,
5824                                  state->recursive);
5825         if (tevent_req_nomem(subreq, req)) {
5826                 return;
5827         }
5828         tevent_req_set_callback(subreq, swallow_notify_done, req);
5829 }
5830
5831 static bool print_notifies(uint32_t action, const char *name, void *priv)
5832 {
5833         if (DEBUGLEVEL > 5) {
5834                 d_printf("%d %s\n", (int)action, name);
5835         }
5836         return true;
5837 }
5838
5839 static void notify_bench_done(struct tevent_req *req)
5840 {
5841         int *num_finished = (int *)tevent_req_callback_data_void(req);
5842         *num_finished += 1;
5843 }
5844
5845 static bool run_notify_bench(int dummy)
5846 {
5847         const char *dname = "\\notify-bench";
5848         struct tevent_context *ev;
5849         NTSTATUS status;
5850         uint16_t dnum;
5851         struct tevent_req *req1;
5852         struct tevent_req *req2 = NULL;
5853         int i, num_unc_names;
5854         int num_finished = 0;
5855
5856         printf("starting notify-bench test\n");
5857
5858         if (use_multishare_conn) {
5859                 char **unc_list;
5860                 unc_list = file_lines_load(multishare_conn_fname,
5861                                            &num_unc_names, 0, NULL);
5862                 if (!unc_list || num_unc_names <= 0) {
5863                         d_printf("Failed to load unc names list from '%s'\n",
5864                                  multishare_conn_fname);
5865                         return false;
5866                 }
5867                 TALLOC_FREE(unc_list);
5868         } else {
5869                 num_unc_names = 1;
5870         }
5871
5872         ev = tevent_context_init(talloc_tos());
5873         if (ev == NULL) {
5874                 d_printf("tevent_context_init failed\n");
5875                 return false;
5876         }
5877
5878         for (i=0; i<num_unc_names; i++) {
5879                 struct cli_state *cli;
5880                 char *base_fname;
5881
5882                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5883                                              dname, i);
5884                 if (base_fname == NULL) {
5885                         return false;
5886                 }
5887
5888                 if (!torture_open_connection(&cli, i)) {
5889                         return false;
5890                 }
5891
5892                 status = cli_ntcreate(cli, dname, 0,
5893                                       MAXIMUM_ALLOWED_ACCESS,
5894                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5895                                       FILE_SHARE_DELETE,
5896                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5897                                       &dnum);
5898
5899                 if (!NT_STATUS_IS_OK(status)) {
5900                         d_printf("Could not create %s: %s\n", dname,
5901                                  nt_errstr(status));
5902                         return false;
5903                 }
5904
5905                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5906                                            FILE_NOTIFY_CHANGE_FILE_NAME |
5907                                            FILE_NOTIFY_CHANGE_DIR_NAME |
5908                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
5909                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
5910                                            false, print_notifies, NULL);
5911                 if (req1 == NULL) {
5912                         d_printf("Could not create notify request\n");
5913                         return false;
5914                 }
5915
5916                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5917                                                base_fname, 10, torture_numops);
5918                 if (req2 == NULL) {
5919                         d_printf("Could not create createdels request\n");
5920                         return false;
5921                 }
5922                 TALLOC_FREE(base_fname);
5923
5924                 tevent_req_set_callback(req2, notify_bench_done,
5925                                         &num_finished);
5926         }
5927
5928         while (num_finished < num_unc_names) {
5929                 int ret;
5930                 ret = tevent_loop_once(ev);
5931                 if (ret != 0) {
5932                         d_printf("tevent_loop_once failed\n");
5933                         return false;
5934                 }
5935         }
5936
5937         if (!tevent_req_poll(req2, ev)) {
5938                 d_printf("tevent_req_poll failed\n");
5939         }
5940
5941         status = torture_createdels_recv(req2);
5942         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5943
5944         return true;
5945 }
5946
5947 static bool run_mangle1(int dummy)
5948 {
5949         struct cli_state *cli;
5950         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5951         uint16_t fnum;
5952         fstring alt_name;
5953         NTSTATUS status;
5954         time_t change_time, access_time, write_time;
5955         SMB_OFF_T size;
5956         uint16_t mode;
5957
5958         printf("starting mangle1 test\n");
5959         if (!torture_open_connection(&cli, 0)) {
5960                 return False;
5961         }
5962
5963         cli_sockopt(cli, sockops);
5964
5965         if (!NT_STATUS_IS_OK(cli_ntcreate(
5966                         cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5967                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5968                 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5969                 return false;
5970         }
5971         cli_close(cli, fnum);
5972
5973         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5974         if (!NT_STATUS_IS_OK(status)) {
5975                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5976                          nt_errstr(status));
5977                 return false;
5978         }
5979         d_printf("alt_name: %s\n", alt_name);
5980
5981         if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5982                 d_printf("cli_open(%s) failed: %s\n", alt_name,
5983                          cli_errstr(cli));
5984                 return false;
5985         }
5986         cli_close(cli, fnum);
5987
5988         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
5989                                 &write_time, &size, &mode);
5990         if (!NT_STATUS_IS_OK(status)) {
5991                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
5992                          nt_errstr(status));
5993                 return false;
5994         }
5995
5996         return true;
5997 }
5998
5999 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6000 {
6001         size_t *to_pull = (size_t *)priv;
6002         size_t thistime = *to_pull;
6003
6004         thistime = MIN(thistime, n);
6005         if (thistime == 0) {
6006                 return 0;
6007         }
6008
6009         memset(buf, 0, thistime);
6010         *to_pull -= thistime;
6011         return thistime;
6012 }
6013
6014 static bool run_windows_write(int dummy)
6015 {
6016         struct cli_state *cli1;
6017         uint16_t fnum;
6018         int i;
6019         bool ret = false;
6020         const char *fname = "\\writetest.txt";
6021         struct timeval start_time;
6022         double seconds;
6023         double kbytes;
6024
6025         printf("starting windows_write test\n");
6026         if (!torture_open_connection(&cli1, 0)) {
6027                 return False;
6028         }
6029
6030         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6031                 printf("open failed (%s)\n", cli_errstr(cli1));
6032                 return False;
6033         }
6034
6035         cli_sockopt(cli1, sockops);
6036
6037         start_time = timeval_current();
6038
6039         for (i=0; i<torture_numops; i++) {
6040                 char c = 0;
6041                 off_t start = i * torture_blocksize;
6042                 NTSTATUS status;
6043                 size_t to_pull = torture_blocksize - 1;
6044
6045                 if (cli_write(cli1, fnum, 0, &c,
6046                               start + torture_blocksize - 1, 1) != 1) {
6047                         printf("cli_write failed: %s\n", cli_errstr(cli1));
6048                         goto fail;
6049                 }
6050
6051                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6052                                   null_source, &to_pull);
6053                 if (!NT_STATUS_IS_OK(status)) {
6054                         printf("cli_push returned: %s\n", nt_errstr(status));
6055                         goto fail;
6056                 }
6057         }
6058
6059         seconds = timeval_elapsed(&start_time);
6060         kbytes = (double)torture_blocksize * torture_numops;
6061         kbytes /= 1024;
6062
6063         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6064                (double)seconds, (int)(kbytes/seconds));
6065
6066         ret = true;
6067  fail:
6068         cli_close(cli1, fnum);
6069         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6070         torture_close_connection(cli1);
6071         return ret;
6072 }
6073
6074 static bool run_cli_echo(int dummy)
6075 {
6076         struct cli_state *cli;
6077         NTSTATUS status;
6078
6079         printf("starting cli_echo test\n");
6080         if (!torture_open_connection(&cli, 0)) {
6081                 return false;
6082         }
6083         cli_sockopt(cli, sockops);
6084
6085         status = cli_echo(cli, 5, data_blob_const("hello", 5));
6086
6087         d_printf("cli_echo returned %s\n", nt_errstr(status));
6088
6089         torture_close_connection(cli);
6090         return NT_STATUS_IS_OK(status);
6091 }
6092
6093 static bool run_uid_regression_test(int dummy)
6094 {
6095         static struct cli_state *cli;
6096         int16_t old_vuid;
6097         int16_t old_cnum;
6098         bool correct = True;
6099         NTSTATUS status;
6100
6101         printf("starting uid regression test\n");
6102
6103         if (!torture_open_connection(&cli, 0)) {
6104                 return False;
6105         }
6106
6107         cli_sockopt(cli, sockops);
6108
6109         /* Ok - now save then logoff our current user. */
6110         old_vuid = cli->vuid;
6111
6112         status = cli_ulogoff(cli);
6113         if (!NT_STATUS_IS_OK(status)) {
6114                 d_printf("(%s) cli_ulogoff failed: %s\n",
6115                          __location__, nt_errstr(status));
6116                 correct = false;
6117                 goto out;
6118         }
6119
6120         cli->vuid = old_vuid;
6121
6122         /* Try an operation. */
6123         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6124                 /* We expect bad uid. */
6125                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6126                                 NT_STATUS_NO_SUCH_USER)) {
6127                         return False;
6128                 }
6129         }
6130
6131         old_cnum = cli->cnum;
6132
6133         /* Now try a SMBtdis with the invald vuid set to zero. */
6134         cli->vuid = 0;
6135
6136         /* This should succeed. */
6137         status = cli_tdis(cli);
6138
6139         if (NT_STATUS_IS_OK(status)) {
6140                 printf("First tdis with invalid vuid should succeed.\n");
6141         } else {
6142                 printf("First tdis failed (%s)\n", nt_errstr(status));
6143         }
6144
6145         cli->vuid = old_vuid;
6146         cli->cnum = old_cnum;
6147
6148         /* This should fail. */
6149         status = cli_tdis(cli);
6150         if (NT_STATUS_IS_OK(status)) {
6151                 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6152         } else {
6153                 /* Should be bad tid. */
6154                 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6155                                 NT_STATUS_NETWORK_NAME_DELETED)) {
6156                         return False;
6157                 }
6158         }
6159
6160         cli_rmdir(cli, "\\uid_reg_test");
6161
6162   out:
6163
6164         cli_shutdown(cli);
6165         return correct;
6166 }
6167
6168
6169 static const char *illegal_chars = "*\\/?<>|\":";
6170 static char force_shortname_chars[] = " +,.[];=\177";
6171
6172 static void shortname_del_fn(const char *mnt, struct file_info *finfo,
6173                              const char *mask, void *state)
6174 {
6175         struct cli_state *pcli = (struct cli_state *)state;
6176         fstring fname;
6177         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6178
6179         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6180                 return;
6181
6182         if (finfo->mode & aDIR) {
6183                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6184                         printf("del_fn: failed to rmdir %s\n,", fname );
6185         } else {
6186                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6187                         printf("del_fn: failed to unlink %s\n,", fname );
6188         }
6189 }
6190
6191 struct sn_state {
6192         int matched;
6193         int i;
6194         bool val;
6195 };
6196
6197 static void shortname_list_fn(const char *mnt, struct file_info *finfo,
6198                               const char *name, void *state)
6199 {
6200         struct sn_state *s = (struct sn_state  *)state;
6201         int i = s->i;
6202
6203 #if 0
6204         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6205                 i, finfo->name, finfo->short_name);
6206 #endif
6207
6208         if (strchr(force_shortname_chars, i)) {
6209                 if (!finfo->short_name[0]) {
6210                         /* Shortname not created when it should be. */
6211                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6212                                 __location__, finfo->name, i);
6213                         s->val = true;
6214                 }
6215         } else if (finfo->short_name[0]){
6216                 /* Shortname created when it should not be. */
6217                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6218                         __location__, finfo->short_name, finfo->name);
6219                 s->val = true;
6220         }
6221         s->matched += 1;
6222 }
6223
6224 static bool run_shortname_test(int dummy)
6225 {
6226         static struct cli_state *cli;
6227         bool correct = True;
6228         int i;
6229         struct sn_state s;
6230         char fname[20];
6231
6232         printf("starting shortname test\n");
6233
6234         if (!torture_open_connection(&cli, 0)) {
6235                 return False;
6236         }
6237
6238         cli_sockopt(cli, sockops);
6239
6240         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6241         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6242         cli_rmdir(cli, "\\shortname");
6243
6244         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6245                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6246                         __location__, cli_errstr(cli));
6247                 correct = false;
6248                 goto out;
6249         }
6250
6251         strlcpy(fname, "\\shortname\\", sizeof(fname));
6252         strlcat(fname, "test .txt", sizeof(fname));
6253
6254         s.val = false;
6255
6256         for (i = 32; i < 128; i++) {
6257                 NTSTATUS status;
6258                 uint16_t fnum = (uint16_t)-1;
6259
6260                 s.i = i;
6261
6262                 if (strchr(illegal_chars, i)) {
6263                         continue;
6264                 }
6265                 fname[15] = i;
6266
6267                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6268                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6269                 if (!NT_STATUS_IS_OK(status)) {
6270                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
6271                                 __location__, fname, cli_errstr(cli));
6272                         correct = false;
6273                         goto out;
6274                 }
6275                 cli_close(cli, fnum);
6276
6277                 s.matched = 0;
6278                 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6279                          &s);
6280                 if (s.matched != 1) {
6281                         d_printf("(%s) failed to list %s: %s\n",
6282                                 __location__, fname, cli_errstr(cli));
6283                         correct = false;
6284                         goto out;
6285                 }
6286                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6287                         d_printf("(%s) failed to delete %s: %s\n",
6288                                 __location__, fname, cli_errstr(cli));
6289                         correct = false;
6290                         goto out;
6291                 }
6292
6293                 if (s.val) {
6294                         correct = false;
6295                         goto out;
6296                 }
6297         }
6298
6299   out:
6300
6301         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6302         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6303         cli_rmdir(cli, "\\shortname");
6304         torture_close_connection(cli);
6305         return correct;
6306 }
6307
6308 static void pagedsearch_cb(struct tevent_req *req)
6309 {
6310         int rc;
6311         struct tldap_message *msg;
6312         char *dn;
6313
6314         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6315         if (rc != TLDAP_SUCCESS) {
6316                 d_printf("tldap_search_paged_recv failed: %s\n",
6317                          tldap_err2string(rc));
6318                 return;
6319         }
6320         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6321                 TALLOC_FREE(msg);
6322                 return;
6323         }
6324         if (!tldap_entry_dn(msg, &dn)) {
6325                 d_printf("tldap_entry_dn failed\n");
6326                 return;
6327         }
6328         d_printf("%s\n", dn);
6329         TALLOC_FREE(msg);
6330 }
6331
6332 static bool run_tldap(int dummy)
6333 {
6334         struct tldap_context *ld;
6335         int fd, rc;
6336         NTSTATUS status;
6337         struct sockaddr_storage addr;
6338         struct tevent_context *ev;
6339         struct tevent_req *req;
6340         char *basedn;
6341         const char *filter;
6342
6343         if (!resolve_name(host, &addr, 0, false)) {
6344                 d_printf("could not find host %s\n", host);
6345                 return false;
6346         }
6347         status = open_socket_out(&addr, 389, 9999, &fd);
6348         if (!NT_STATUS_IS_OK(status)) {
6349                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6350                 return false;
6351         }
6352
6353         ld = tldap_context_create(talloc_tos(), fd);
6354         if (ld == NULL) {
6355                 close(fd);
6356                 d_printf("tldap_context_create failed\n");
6357                 return false;
6358         }
6359
6360         rc = tldap_fetch_rootdse(ld);
6361         if (rc != TLDAP_SUCCESS) {
6362                 d_printf("tldap_fetch_rootdse failed: %s\n",
6363                          tldap_errstr(talloc_tos(), ld, rc));
6364                 return false;
6365         }
6366
6367         basedn = tldap_talloc_single_attribute(
6368                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6369         if (basedn == NULL) {
6370                 d_printf("no defaultNamingContext\n");
6371                 return false;
6372         }
6373         d_printf("defaultNamingContext: %s\n", basedn);
6374
6375         ev = tevent_context_init(talloc_tos());
6376         if (ev == NULL) {
6377                 d_printf("tevent_context_init failed\n");
6378                 return false;
6379         }
6380
6381         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6382                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
6383                                       NULL, 0, 0,
6384                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
6385         if (req == NULL) {
6386                 d_printf("tldap_search_paged_send failed\n");
6387                 return false;
6388         }
6389         tevent_req_set_callback(req, pagedsearch_cb, NULL);
6390
6391         tevent_req_poll(req, ev);
6392
6393         TALLOC_FREE(req);
6394
6395         /* test search filters against rootDSE */
6396         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6397                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6398
6399         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6400                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6401                           talloc_tos(), NULL, NULL);
6402         if (rc != TLDAP_SUCCESS) {
6403                 d_printf("tldap_search with complex filter failed: %s\n",
6404                          tldap_errstr(talloc_tos(), ld, rc));
6405                 return false;
6406         }
6407
6408         TALLOC_FREE(ld);
6409         return true;
6410 }
6411
6412 /* Torture test to ensure no regression of :
6413 https://bugzilla.samba.org/show_bug.cgi?id=7084
6414 */
6415
6416 static bool run_dir_createtime(int dummy)
6417 {
6418         struct cli_state *cli;
6419         const char *dname = "\\testdir";
6420         const char *fname = "\\testdir\\testfile";
6421         NTSTATUS status;
6422         struct timespec create_time;
6423         struct timespec create_time1;
6424         uint16_t fnum;
6425         bool ret = false;
6426
6427         if (!torture_open_connection(&cli, 0)) {
6428                 return false;
6429         }
6430
6431         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6432         cli_rmdir(cli, dname);
6433
6434         status = cli_mkdir(cli, dname);
6435         if (!NT_STATUS_IS_OK(status)) {
6436                 printf("mkdir failed: %s\n", nt_errstr(status));
6437                 goto out;
6438         }
6439
6440         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6441                                 NULL, NULL, NULL);
6442         if (!NT_STATUS_IS_OK(status)) {
6443                 printf("cli_qpathinfo2 returned %s\n",
6444                        nt_errstr(status));
6445                 goto out;
6446         }
6447
6448         /* Sleep 3 seconds, then create a file. */
6449         sleep(3);
6450
6451         status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6452                          DENY_NONE, &fnum);
6453         if (!NT_STATUS_IS_OK(status)) {
6454                 printf("cli_open failed: %s\n", nt_errstr(status));
6455                 goto out;
6456         }
6457
6458         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6459                                 NULL, NULL, NULL);
6460         if (!NT_STATUS_IS_OK(status)) {
6461                 printf("cli_qpathinfo2 (2) returned %s\n",
6462                        nt_errstr(status));
6463                 goto out;
6464         }
6465
6466         if (timespec_compare(&create_time1, &create_time)) {
6467                 printf("run_dir_createtime: create time was updated (error)\n");
6468         } else {
6469                 printf("run_dir_createtime: create time was not updated (correct)\n");
6470                 ret = true;
6471         }
6472
6473   out:
6474
6475         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6476         cli_rmdir(cli, dname);
6477         if (!torture_close_connection(cli)) {
6478                 ret = false;
6479         }
6480         return ret;
6481 }
6482
6483
6484 static bool run_streamerror(int dummy)
6485 {
6486         struct cli_state *cli;
6487         const char *dname = "\\testdir";
6488         const char *streamname =
6489                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6490         NTSTATUS status;
6491         time_t change_time, access_time, write_time;
6492         SMB_OFF_T size;
6493         uint16_t mode, fnum;
6494         bool ret = true;
6495
6496         if (!torture_open_connection(&cli, 0)) {
6497                 return false;
6498         }
6499
6500         cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6501         cli_rmdir(cli, dname);
6502
6503         status = cli_mkdir(cli, dname);
6504         if (!NT_STATUS_IS_OK(status)) {
6505                 printf("mkdir failed: %s\n", nt_errstr(status));
6506                 return false;
6507         }
6508
6509         cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6510                       &size, &mode);
6511         status = cli_nt_error(cli);
6512
6513         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6514                 printf("pathinfo returned %s, expected "
6515                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6516                        nt_errstr(status));
6517                 ret = false;
6518         }
6519
6520         status = cli_ntcreate(cli, streamname, 0x16,
6521                               FILE_READ_DATA|FILE_READ_EA|
6522                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6523                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6524                               FILE_OPEN, 0, 0, &fnum);
6525
6526         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6527                 printf("ntcreate returned %s, expected "
6528                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6529                        nt_errstr(status));
6530                 ret = false;
6531         }
6532
6533
6534         cli_rmdir(cli, dname);
6535         return ret;
6536 }
6537
6538 static bool run_local_substitute(int dummy)
6539 {
6540         bool ok = true;
6541
6542         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6543         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6544         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6545         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6546         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6547         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6548         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6549         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6550
6551         /* Different captialization rules in sub_basic... */
6552
6553         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6554                        "blaDOM") == 0);
6555
6556         return ok;
6557 }
6558
6559 static bool run_local_base64(int dummy)
6560 {
6561         int i;
6562         bool ret = true;
6563
6564         for (i=1; i<2000; i++) {
6565                 DATA_BLOB blob1, blob2;
6566                 char *b64;
6567
6568                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6569                 blob1.length = i;
6570                 generate_random_buffer(blob1.data, blob1.length);
6571
6572                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6573                 if (b64 == NULL) {
6574                         d_fprintf(stderr, "base64_encode_data_blob failed "
6575                                   "for %d bytes\n", i);
6576                         ret = false;
6577                 }
6578                 blob2 = base64_decode_data_blob(b64);
6579                 TALLOC_FREE(b64);
6580
6581                 if (data_blob_cmp(&blob1, &blob2)) {
6582                         d_fprintf(stderr, "data_blob_cmp failed for %d "
6583                                   "bytes\n", i);
6584                         ret = false;
6585                 }
6586                 TALLOC_FREE(blob1.data);
6587                 data_blob_free(&blob2);
6588         }
6589         return ret;
6590 }
6591
6592 static bool run_local_gencache(int dummy)
6593 {
6594         char *val;
6595         time_t tm;
6596         DATA_BLOB blob;
6597
6598         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6599                 d_printf("%s: gencache_set() failed\n", __location__);
6600                 return False;
6601         }
6602
6603         if (!gencache_get("foo", NULL, NULL)) {
6604                 d_printf("%s: gencache_get() failed\n", __location__);
6605                 return False;
6606         }
6607
6608         if (!gencache_get("foo", &val, &tm)) {
6609                 d_printf("%s: gencache_get() failed\n", __location__);
6610                 return False;
6611         }
6612
6613         if (strcmp(val, "bar") != 0) {
6614                 d_printf("%s: gencache_get() returned %s, expected %s\n",
6615                          __location__, val, "bar");
6616                 SAFE_FREE(val);
6617                 return False;
6618         }
6619
6620         SAFE_FREE(val);
6621
6622         if (!gencache_del("foo")) {
6623                 d_printf("%s: gencache_del() failed\n", __location__);
6624                 return False;
6625         }
6626         if (gencache_del("foo")) {
6627                 d_printf("%s: second gencache_del() succeeded\n",
6628                          __location__);
6629                 return False;
6630         }
6631
6632         if (gencache_get("foo", &val, &tm)) {
6633                 d_printf("%s: gencache_get() on deleted entry "
6634                          "succeeded\n", __location__);
6635                 return False;
6636         }
6637
6638         blob = data_blob_string_const_null("bar");
6639         tm = time(NULL) + 60;
6640
6641         if (!gencache_set_data_blob("foo", &blob, tm)) {
6642                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6643                 return False;
6644         }
6645
6646         if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6647                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6648                 return False;
6649         }
6650
6651         if (strcmp((const char *)blob.data, "bar") != 0) {
6652                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6653                          __location__, (const char *)blob.data, "bar");
6654                 data_blob_free(&blob);
6655                 return False;
6656         }
6657
6658         data_blob_free(&blob);
6659
6660         if (!gencache_del("foo")) {
6661                 d_printf("%s: gencache_del() failed\n", __location__);
6662                 return False;
6663         }
6664         if (gencache_del("foo")) {
6665                 d_printf("%s: second gencache_del() succeeded\n",
6666                          __location__);
6667                 return False;
6668         }
6669
6670         if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6671                 d_printf("%s: gencache_get_data_blob() on deleted entry "
6672                          "succeeded\n", __location__);
6673                 return False;
6674         }
6675
6676         return True;
6677 }
6678
6679 static bool rbt_testval(struct db_context *db, const char *key,
6680                         const char *value)
6681 {
6682         struct db_record *rec;
6683         TDB_DATA data = string_tdb_data(value);
6684         bool ret = false;
6685         NTSTATUS status;
6686
6687         rec = db->fetch_locked(db, db, string_tdb_data(key));
6688         if (rec == NULL) {
6689                 d_fprintf(stderr, "fetch_locked failed\n");
6690                 goto done;
6691         }
6692         status = rec->store(rec, data, 0);
6693         if (!NT_STATUS_IS_OK(status)) {
6694                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6695                 goto done;
6696         }
6697         TALLOC_FREE(rec);
6698
6699         rec = db->fetch_locked(db, db, string_tdb_data(key));
6700         if (rec == NULL) {
6701                 d_fprintf(stderr, "second fetch_locked failed\n");
6702                 goto done;
6703         }
6704         if ((rec->value.dsize != data.dsize)
6705             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6706                 d_fprintf(stderr, "Got wrong data back\n");
6707                 goto done;
6708         }
6709
6710         ret = true;
6711  done:
6712         TALLOC_FREE(rec);
6713         return ret;
6714 }
6715
6716 static bool run_local_rbtree(int dummy)
6717 {
6718         struct db_context *db;
6719         bool ret = false;
6720         int i;
6721
6722         db = db_open_rbt(NULL);
6723
6724         if (db == NULL) {
6725                 d_fprintf(stderr, "db_open_rbt failed\n");
6726                 return false;
6727         }
6728
6729         for (i=0; i<1000; i++) {
6730                 char *key, *value;
6731
6732                 if (asprintf(&key, "key%ld", random()) == -1) {
6733                         goto done;
6734                 }
6735                 if (asprintf(&value, "value%ld", random()) == -1) {
6736                         SAFE_FREE(key);
6737                         goto done;
6738                 }
6739
6740                 if (!rbt_testval(db, key, value)) {
6741                         SAFE_FREE(key);
6742                         SAFE_FREE(value);
6743                         goto done;
6744                 }
6745
6746                 SAFE_FREE(value);
6747                 if (asprintf(&value, "value%ld", random()) == -1) {
6748                         SAFE_FREE(key);
6749                         goto done;
6750                 }
6751
6752                 if (!rbt_testval(db, key, value)) {
6753                         SAFE_FREE(key);
6754                         SAFE_FREE(value);
6755                         goto done;
6756                 }
6757
6758                 SAFE_FREE(key);
6759                 SAFE_FREE(value);
6760         }
6761
6762         ret = true;
6763
6764  done:
6765         TALLOC_FREE(db);
6766         return ret;
6767 }
6768
6769 struct talloc_dict_test {
6770         int content;
6771 };
6772
6773 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6774 {
6775         int *count = (int *)priv;
6776         *count += 1;
6777         return 0;
6778 }
6779
6780 static bool run_local_talloc_dict(int dummy)
6781 {
6782         struct talloc_dict *dict;
6783         struct talloc_dict_test *t;
6784         int key, count;
6785
6786         dict = talloc_dict_init(talloc_tos());
6787         if (dict == NULL) {
6788                 return false;
6789         }
6790
6791         t = talloc(talloc_tos(), struct talloc_dict_test);
6792         if (t == NULL) {
6793                 return false;
6794         }
6795
6796         key = 1;
6797         t->content = 1;
6798         if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6799                 return false;
6800         }
6801
6802         count = 0;
6803         if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6804                 return false;
6805         }
6806
6807         if (count != 1) {
6808                 return false;
6809         }
6810
6811         TALLOC_FREE(dict);
6812
6813         return true;
6814 }
6815
6816 static bool run_local_string_to_sid(int dummy) {
6817         struct dom_sid sid;
6818
6819         if (string_to_sid(&sid, "S--1-5-32-545")) {
6820                 printf("allowing S--1-5-32-545\n");
6821                 return false;
6822         }
6823         if (string_to_sid(&sid, "S-1-5-32-+545")) {
6824                 printf("allowing S-1-5-32-+545\n");
6825                 return false;
6826         }
6827         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")) {
6828                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6829                 return false;
6830         }
6831         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6832                 printf("allowing S-1-5-32-545-abc\n");
6833                 return false;
6834         }
6835         if (!string_to_sid(&sid, "S-1-5-32-545")) {
6836                 printf("could not parse S-1-5-32-545\n");
6837                 return false;
6838         }
6839         if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6840                 printf("mis-parsed S-1-5-32-545 as %s\n",
6841                        sid_string_tos(&sid));
6842                 return false;
6843         }
6844         return true;
6845 }
6846
6847 /* Split a path name into filename and stream name components. Canonicalise
6848  * such that an implicit $DATA token is always explicit.
6849  *
6850  * The "specification" of this function can be found in the
6851  * run_local_stream_name() function in torture.c, I've tried those
6852  * combinations against a W2k3 server.
6853  */
6854
6855 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6856                                        char **pbase, char **pstream)
6857 {
6858         char *base = NULL;
6859         char *stream = NULL;
6860         char *sname; /* stream name */
6861         const char *stype; /* stream type */
6862
6863         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6864
6865         sname = strchr_m(fname, ':');
6866
6867         if (lp_posix_pathnames() || (sname == NULL)) {
6868                 if (pbase != NULL) {
6869                         base = talloc_strdup(mem_ctx, fname);
6870                         NT_STATUS_HAVE_NO_MEMORY(base);
6871                 }
6872                 goto done;
6873         }
6874
6875         if (pbase != NULL) {
6876                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6877                 NT_STATUS_HAVE_NO_MEMORY(base);
6878         }
6879
6880         sname += 1;
6881
6882         stype = strchr_m(sname, ':');
6883
6884         if (stype == NULL) {
6885                 sname = talloc_strdup(mem_ctx, sname);
6886                 stype = "$DATA";
6887         }
6888         else {
6889                 if (StrCaseCmp(stype, ":$DATA") != 0) {
6890                         /*
6891                          * If there is an explicit stream type, so far we only
6892                          * allow $DATA. Is there anything else allowed? -- vl
6893                          */
6894                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6895                         TALLOC_FREE(base);
6896                         return NT_STATUS_OBJECT_NAME_INVALID;
6897                 }
6898                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6899                 stype += 1;
6900         }
6901
6902         if (sname == NULL) {
6903                 TALLOC_FREE(base);
6904                 return NT_STATUS_NO_MEMORY;
6905         }
6906
6907         if (sname[0] == '\0') {
6908                 /*
6909                  * no stream name, so no stream
6910                  */
6911                 goto done;
6912         }
6913
6914         if (pstream != NULL) {
6915                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6916                 if (stream == NULL) {
6917                         TALLOC_FREE(sname);
6918                         TALLOC_FREE(base);
6919                         return NT_STATUS_NO_MEMORY;
6920                 }
6921                 /*
6922                  * upper-case the type field
6923                  */
6924                 strupper_m(strchr_m(stream, ':')+1);
6925         }
6926
6927  done:
6928         if (pbase != NULL) {
6929                 *pbase = base;
6930         }
6931         if (pstream != NULL) {
6932                 *pstream = stream;
6933         }
6934         return NT_STATUS_OK;
6935 }
6936
6937 static bool test_stream_name(const char *fname, const char *expected_base,
6938                              const char *expected_stream,
6939                              NTSTATUS expected_status)
6940 {
6941         NTSTATUS status;
6942         char *base = NULL;
6943         char *stream = NULL;
6944
6945         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6946         if (!NT_STATUS_EQUAL(status, expected_status)) {
6947                 goto error;
6948         }
6949
6950         if (!NT_STATUS_IS_OK(status)) {
6951                 return true;
6952         }
6953
6954         if (base == NULL) goto error;
6955
6956         if (strcmp(expected_base, base) != 0) goto error;
6957
6958         if ((expected_stream != NULL) && (stream == NULL)) goto error;
6959         if ((expected_stream == NULL) && (stream != NULL)) goto error;
6960
6961         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6962                 goto error;
6963
6964         TALLOC_FREE(base);
6965         TALLOC_FREE(stream);
6966         return true;
6967
6968  error:
6969         d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6970                   fname, expected_base ? expected_base : "<NULL>",
6971                   expected_stream ? expected_stream : "<NULL>",
6972                   nt_errstr(expected_status));
6973         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6974                   base ? base : "<NULL>", stream ? stream : "<NULL>",
6975                   nt_errstr(status));
6976         TALLOC_FREE(base);
6977         TALLOC_FREE(stream);
6978         return false;
6979 }
6980
6981 static bool run_local_stream_name(int dummy)
6982 {
6983         bool ret = true;
6984
6985         ret &= test_stream_name(
6986                 "bla", "bla", NULL, NT_STATUS_OK);
6987         ret &= test_stream_name(
6988                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6989         ret &= test_stream_name(
6990                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6991         ret &= test_stream_name(
6992                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6993         ret &= test_stream_name(
6994                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6995         ret &= test_stream_name(
6996                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6997         ret &= test_stream_name(
6998                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6999         ret &= test_stream_name(
7000                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7001
7002         return ret;
7003 }
7004
7005 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7006 {
7007         if (a.length != b.length) {
7008                 printf("a.length=%d != b.length=%d\n",
7009                        (int)a.length, (int)b.length);
7010                 return false;
7011         }
7012         if (memcmp(a.data, b.data, a.length) != 0) {
7013                 printf("a.data and b.data differ\n");
7014                 return false;
7015         }
7016         return true;
7017 }
7018
7019 static bool run_local_memcache(int dummy)
7020 {
7021         struct memcache *cache;
7022         DATA_BLOB k1, k2;
7023         DATA_BLOB d1, d2, d3;
7024         DATA_BLOB v1, v2, v3;
7025
7026         TALLOC_CTX *mem_ctx;
7027         char *str1, *str2;
7028         size_t size1, size2;
7029         bool ret = false;
7030
7031         cache = memcache_init(NULL, 100);
7032
7033         if (cache == NULL) {
7034                 printf("memcache_init failed\n");
7035                 return false;
7036         }
7037
7038         d1 = data_blob_const("d1", 2);
7039         d2 = data_blob_const("d2", 2);
7040         d3 = data_blob_const("d3", 2);
7041
7042         k1 = data_blob_const("d1", 2);
7043         k2 = data_blob_const("d2", 2);
7044
7045         memcache_add(cache, STAT_CACHE, k1, d1);
7046         memcache_add(cache, GETWD_CACHE, k2, d2);
7047
7048         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7049                 printf("could not find k1\n");
7050                 return false;
7051         }
7052         if (!data_blob_equal(d1, v1)) {
7053                 return false;
7054         }
7055
7056         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7057                 printf("could not find k2\n");
7058                 return false;
7059         }
7060         if (!data_blob_equal(d2, v2)) {
7061                 return false;
7062         }
7063
7064         memcache_add(cache, STAT_CACHE, k1, d3);
7065
7066         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7067                 printf("could not find replaced k1\n");
7068                 return false;
7069         }
7070         if (!data_blob_equal(d3, v3)) {
7071                 return false;
7072         }
7073
7074         memcache_add(cache, GETWD_CACHE, k1, d1);
7075
7076         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7077                 printf("Did find k2, should have been purged\n");
7078                 return false;
7079         }
7080
7081         TALLOC_FREE(cache);
7082
7083         cache = memcache_init(NULL, 0);
7084
7085         mem_ctx = talloc_init("foo");
7086
7087         str1 = talloc_strdup(mem_ctx, "string1");
7088         str2 = talloc_strdup(mem_ctx, "string2");
7089
7090         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7091                             data_blob_string_const("torture"), &str1);
7092         size1 = talloc_total_size(cache);
7093
7094         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7095                             data_blob_string_const("torture"), &str2);
7096         size2 = talloc_total_size(cache);
7097
7098         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7099
7100         if (size2 > size1) {
7101                 printf("memcache leaks memory!\n");
7102                 goto fail;
7103         }
7104
7105         ret = true;
7106  fail:
7107         TALLOC_FREE(cache);
7108         return ret;
7109 }
7110
7111 static void wbclient_done(struct tevent_req *req)
7112 {
7113         wbcErr wbc_err;
7114         struct winbindd_response *wb_resp;
7115         int *i = (int *)tevent_req_callback_data_void(req);
7116
7117         wbc_err = wb_trans_recv(req, req, &wb_resp);
7118         TALLOC_FREE(req);
7119         *i += 1;
7120         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7121 }
7122
7123 static bool run_local_wbclient(int dummy)
7124 {
7125         struct event_context *ev;
7126         struct wb_context **wb_ctx;
7127         struct winbindd_request wb_req;
7128         bool result = false;
7129         int i, j;
7130
7131         BlockSignals(True, SIGPIPE);
7132
7133         ev = tevent_context_init_byname(talloc_tos(), "epoll");
7134         if (ev == NULL) {
7135                 goto fail;
7136         }
7137
7138         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7139         if (wb_ctx == NULL) {
7140                 goto fail;
7141         }
7142
7143         ZERO_STRUCT(wb_req);
7144         wb_req.cmd = WINBINDD_PING;
7145
7146         d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7147
7148         for (i=0; i<nprocs; i++) {
7149                 wb_ctx[i] = wb_context_init(ev, NULL);
7150                 if (wb_ctx[i] == NULL) {
7151                         goto fail;
7152                 }
7153                 for (j=0; j<torture_numops; j++) {
7154                         struct tevent_req *req;
7155                         req = wb_trans_send(ev, ev, wb_ctx[i],
7156                                             (j % 2) == 0, &wb_req);
7157                         if (req == NULL) {
7158                                 goto fail;
7159                         }
7160                         tevent_req_set_callback(req, wbclient_done, &i);
7161                 }
7162         }
7163
7164         i = 0;
7165
7166         while (i < nprocs * torture_numops) {
7167                 event_loop_once(ev);
7168         }
7169
7170         result = true;
7171  fail:
7172         TALLOC_FREE(ev);
7173         return result;
7174 }
7175
7176 static void getaddrinfo_finished(struct tevent_req *req)
7177 {
7178         char *name = (char *)tevent_req_callback_data_void(req);
7179         struct addrinfo *ainfo;
7180         int res;
7181
7182         res = getaddrinfo_recv(req, &ainfo);
7183         if (res != 0) {
7184                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7185                 return;
7186         }
7187         d_printf("gai(%s) succeeded\n", name);
7188         freeaddrinfo(ainfo);
7189 }
7190
7191 static bool run_getaddrinfo_send(int dummy)
7192 {
7193         TALLOC_CTX *frame = talloc_stackframe();
7194         struct fncall_context *ctx;
7195         struct tevent_context *ev;
7196         bool result = false;
7197         const char *names[4] = { "www.samba.org", "notfound.samba.org",
7198                                  "www.slashdot.org", "heise.de" };
7199         struct tevent_req *reqs[4];
7200         int i;
7201
7202         ev = event_context_init(frame);
7203         if (ev == NULL) {
7204                 goto fail;
7205         }
7206
7207         ctx = fncall_context_init(frame, 4);
7208
7209         for (i=0; i<ARRAY_SIZE(names); i++) {
7210                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7211                                            NULL);
7212                 if (reqs[i] == NULL) {
7213                         goto fail;
7214                 }
7215                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7216                                         (void *)names[i]);
7217         }
7218
7219         for (i=0; i<ARRAY_SIZE(reqs); i++) {
7220                 tevent_loop_once(ev);
7221         }
7222
7223         result = true;
7224 fail:
7225         TALLOC_FREE(frame);
7226         return result;
7227 }
7228
7229 static bool dbtrans_inc(struct db_context *db)
7230 {
7231         struct db_record *rec;
7232         uint32_t *val;
7233         bool ret = false;
7234         NTSTATUS status;
7235
7236         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7237         if (rec == NULL) {
7238                 printf(__location__ "fetch_lock failed\n");
7239                 return false;
7240         }
7241
7242         if (rec->value.dsize != sizeof(uint32_t)) {
7243                 printf(__location__ "value.dsize = %d\n",
7244                        (int)rec->value.dsize);
7245                 goto fail;
7246         }
7247
7248         val = (uint32_t *)rec->value.dptr;
7249         *val += 1;
7250
7251         status = rec->store(rec, make_tdb_data((uint8_t *)val,
7252                                                sizeof(uint32_t)),
7253                             0);
7254         if (!NT_STATUS_IS_OK(status)) {
7255                 printf(__location__ "store failed: %s\n",
7256                        nt_errstr(status));
7257                 goto fail;
7258         }
7259
7260         ret = true;
7261 fail:
7262         TALLOC_FREE(rec);
7263         return ret;
7264 }
7265
7266 static bool run_local_dbtrans(int dummy)
7267 {
7268         struct db_context *db;
7269         struct db_record *rec;
7270         NTSTATUS status;
7271         uint32_t initial;
7272         int res;
7273
7274         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7275                      O_RDWR|O_CREAT, 0600);
7276         if (db == NULL) {
7277                 printf("Could not open transtest.db\n");
7278                 return false;
7279         }
7280
7281         res = db->transaction_start(db);
7282         if (res == -1) {
7283                 printf(__location__ "transaction_start failed\n");
7284                 return false;
7285         }
7286
7287         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7288         if (rec == NULL) {
7289                 printf(__location__ "fetch_lock failed\n");
7290                 return false;
7291         }
7292
7293         if (rec->value.dptr == NULL) {
7294                 initial = 0;
7295                 status = rec->store(
7296                         rec, make_tdb_data((uint8_t *)&initial,
7297                                            sizeof(initial)),
7298                         0);
7299                 if (!NT_STATUS_IS_OK(status)) {
7300                         printf(__location__ "store returned %s\n",
7301                                nt_errstr(status));
7302                         return false;
7303                 }
7304         }
7305
7306         TALLOC_FREE(rec);
7307
7308         res = db->transaction_commit(db);
7309         if (res == -1) {
7310                 printf(__location__ "transaction_commit failed\n");
7311                 return false;
7312         }
7313
7314         while (true) {
7315                 uint32_t val, val2;
7316                 int i;
7317
7318                 res = db->transaction_start(db);
7319                 if (res == -1) {
7320                         printf(__location__ "transaction_start failed\n");
7321                         break;
7322                 }
7323
7324                 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7325                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
7326                         break;
7327                 }
7328
7329                 for (i=0; i<10; i++) {
7330                         if (!dbtrans_inc(db)) {
7331                                 return false;
7332                         }
7333                 }
7334
7335                 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7336                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
7337                         break;
7338                 }
7339
7340                 if (val2 != val + 10) {
7341                         printf(__location__ "val=%d, val2=%d\n",
7342                                (int)val, (int)val2);
7343                         break;
7344                 }
7345
7346                 printf("val2=%d\r", val2);
7347
7348                 res = db->transaction_commit(db);
7349                 if (res == -1) {
7350                         printf(__location__ "transaction_commit failed\n");
7351                         break;
7352                 }
7353         }
7354
7355         TALLOC_FREE(db);
7356         return true;
7357 }
7358
7359 /*
7360  * Just a dummy test to be run under a debugger. There's no real way
7361  * to inspect the tevent_select specific function from outside of
7362  * tevent_select.c.
7363  */
7364
7365 static bool run_local_tevent_select(int dummy)
7366 {
7367         struct tevent_context *ev;
7368         struct tevent_fd *fd1, *fd2;
7369         bool result = false;
7370
7371         ev = tevent_context_init_byname(NULL, "select");
7372         if (ev == NULL) {
7373                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7374                 goto fail;
7375         }
7376
7377         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7378         if (fd1 == NULL) {
7379                 d_fprintf(stderr, "tevent_add_fd failed\n");
7380                 goto fail;
7381         }
7382         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7383         if (fd2 == NULL) {
7384                 d_fprintf(stderr, "tevent_add_fd failed\n");
7385                 goto fail;
7386         }
7387         TALLOC_FREE(fd2);
7388
7389         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7390         if (fd2 == NULL) {
7391                 d_fprintf(stderr, "tevent_add_fd failed\n");
7392                 goto fail;
7393         }
7394
7395         result = true;
7396 fail:
7397         TALLOC_FREE(ev);
7398         return result;
7399 }
7400
7401 static double create_procs(bool (*fn)(int), bool *result)
7402 {
7403         int i, status;
7404         volatile pid_t *child_status;
7405         volatile bool *child_status_out;
7406         int synccount;
7407         int tries = 8;
7408         struct timeval start;
7409
7410         synccount = 0;
7411
7412         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7413         if (!child_status) {
7414                 printf("Failed to setup shared memory\n");
7415                 return -1;
7416         }
7417
7418         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7419         if (!child_status_out) {
7420                 printf("Failed to setup result status shared memory\n");
7421                 return -1;
7422         }
7423
7424         for (i = 0; i < nprocs; i++) {
7425                 child_status[i] = 0;
7426                 child_status_out[i] = True;
7427         }
7428
7429         start = timeval_current();
7430
7431         for (i=0;i<nprocs;i++) {
7432                 procnum = i;
7433                 if (fork() == 0) {
7434                         pid_t mypid = getpid();
7435                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7436
7437                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
7438
7439                         while (1) {
7440                                 if (torture_open_connection(&current_cli, i)) break;
7441                                 if (tries-- == 0) {
7442                                         printf("pid %d failed to start\n", (int)getpid());
7443                                         _exit(1);
7444                                 }
7445                                 smb_msleep(10); 
7446                         }
7447
7448                         child_status[i] = getpid();
7449
7450                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7451
7452                         child_status_out[i] = fn(i);
7453                         _exit(0);
7454                 }
7455         }
7456
7457         do {
7458                 synccount = 0;
7459                 for (i=0;i<nprocs;i++) {
7460                         if (child_status[i]) synccount++;
7461                 }
7462                 if (synccount == nprocs) break;
7463                 smb_msleep(10);
7464         } while (timeval_elapsed(&start) < 30);
7465
7466         if (synccount != nprocs) {
7467                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7468                 *result = False;
7469                 return timeval_elapsed(&start);
7470         }
7471
7472         /* start the client load */
7473         start = timeval_current();
7474
7475         for (i=0;i<nprocs;i++) {
7476                 child_status[i] = 0;
7477         }
7478
7479         printf("%d clients started\n", nprocs);
7480
7481         for (i=0;i<nprocs;i++) {
7482                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7483         }
7484
7485         printf("\n");
7486
7487         for (i=0;i<nprocs;i++) {
7488                 if (!child_status_out[i]) {
7489                         *result = False;
7490                 }
7491         }
7492         return timeval_elapsed(&start);
7493 }
7494
7495 #define FLAG_MULTIPROC 1
7496
7497 static struct {
7498         const char *name;
7499         bool (*fn)(int);
7500         unsigned flags;
7501 } torture_ops[] = {
7502         {"FDPASS", run_fdpasstest, 0},
7503         {"LOCK1",  run_locktest1,  0},
7504         {"LOCK2",  run_locktest2,  0},
7505         {"LOCK3",  run_locktest3,  0},
7506         {"LOCK4",  run_locktest4,  0},
7507         {"LOCK5",  run_locktest5,  0},
7508         {"LOCK6",  run_locktest6,  0},
7509         {"LOCK7",  run_locktest7,  0},
7510         {"LOCK8",  run_locktest8,  0},
7511         {"LOCK9",  run_locktest9,  0},
7512         {"UNLINK", run_unlinktest, 0},
7513         {"BROWSE", run_browsetest, 0},
7514         {"ATTR",   run_attrtest,   0},
7515         {"TRANS2", run_trans2test, 0},
7516         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7517         {"TORTURE",run_torture,    FLAG_MULTIPROC},
7518         {"RANDOMIPC", run_randomipc, 0},
7519         {"NEGNOWAIT", run_negprot_nowait, 0},
7520         {"NBENCH",  run_nbench, 0},
7521         {"NBENCH2", run_nbench2, 0},
7522         {"OPLOCK1",  run_oplock1, 0},
7523         {"OPLOCK2",  run_oplock2, 0},
7524         {"OPLOCK3",  run_oplock3, 0},
7525         {"DIR",  run_dirtest, 0},
7526         {"DIR1",  run_dirtest1, 0},
7527         {"DIR-CREATETIME",  run_dir_createtime, 0},
7528         {"DENY1",  torture_denytest1, 0},
7529         {"DENY2",  torture_denytest2, 0},
7530         {"TCON",  run_tcon_test, 0},
7531         {"TCONDEV",  run_tcon_devtype_test, 0},
7532         {"RW1",  run_readwritetest, 0},
7533         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
7534         {"RW3",  run_readwritelarge, 0},
7535         {"OPEN", run_opentest, 0},
7536         {"POSIX", run_simple_posix_open_test, 0},
7537         {"POSIX-APPEND", run_posix_append, 0},
7538         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7539         { "SHORTNAME-TEST", run_shortname_test, 0},
7540 #if 1
7541         {"OPENATTR", run_openattrtest, 0},
7542 #endif
7543         {"XCOPY", run_xcopy, 0},
7544         {"RENAME", run_rename, 0},
7545         {"DELETE", run_deletetest, 0},
7546         {"PROPERTIES", run_properties, 0},
7547         {"MANGLE", torture_mangle, 0},
7548         {"MANGLE1", run_mangle1, 0},
7549         {"W2K", run_w2ktest, 0},
7550         {"TRANS2SCAN", torture_trans2_scan, 0},
7551         {"NTTRANSSCAN", torture_nttrans_scan, 0},
7552         {"UTABLE", torture_utable, 0},
7553         {"CASETABLE", torture_casetable, 0},
7554         {"ERRMAPEXTRACT", run_error_map_extract, 0},
7555         {"PIPE_NUMBER", run_pipe_number, 0},
7556         {"TCON2",  run_tcon2_test, 0},
7557         {"IOCTL",  torture_ioctl_test, 0},
7558         {"CHKPATH",  torture_chkpath_test, 0},
7559         {"FDSESS", run_fdsesstest, 0},
7560         { "EATEST", run_eatest, 0},
7561         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7562         { "CHAIN1", run_chain1, 0},
7563         { "CHAIN2", run_chain2, 0},
7564         { "WINDOWS-WRITE", run_windows_write, 0},
7565         { "CLI_ECHO", run_cli_echo, 0},
7566         { "GETADDRINFO", run_getaddrinfo_send, 0},
7567         { "TLDAP", run_tldap },
7568         { "STREAMERROR", run_streamerror },
7569         { "NOTIFY-BENCH", run_notify_bench },
7570         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7571         { "LOCAL-GENCACHE", run_local_gencache, 0},
7572         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7573         { "LOCAL-BASE64", run_local_base64, 0},
7574         { "LOCAL-RBTREE", run_local_rbtree, 0},
7575         { "LOCAL-MEMCACHE", run_local_memcache, 0},
7576         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7577         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7578         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7579         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7580         { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7581         {NULL, NULL, 0}};
7582
7583
7584
7585 /****************************************************************************
7586 run a specified test or "ALL"
7587 ****************************************************************************/
7588 static bool run_test(const char *name)
7589 {
7590         bool ret = True;
7591         bool result = True;
7592         bool found = False;
7593         int i;
7594         double t;
7595         if (strequal(name,"ALL")) {
7596                 for (i=0;torture_ops[i].name;i++) {
7597                         run_test(torture_ops[i].name);
7598                 }
7599                 found = True;
7600         }
7601
7602         for (i=0;torture_ops[i].name;i++) {
7603                 fstr_sprintf(randomfname, "\\XX%x", 
7604                          (unsigned)random());
7605
7606                 if (strequal(name, torture_ops[i].name)) {
7607                         found = True;
7608                         printf("Running %s\n", name);
7609                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
7610                                 t = create_procs(torture_ops[i].fn, &result);
7611                                 if (!result) { 
7612                                         ret = False;
7613                                         printf("TEST %s FAILED!\n", name);
7614                                 }
7615                         } else {
7616                                 struct timeval start;
7617                                 start = timeval_current();
7618                                 if (!torture_ops[i].fn(0)) {
7619                                         ret = False;
7620                                         printf("TEST %s FAILED!\n", name);
7621                                 }
7622                                 t = timeval_elapsed(&start);
7623                         }
7624                         printf("%s took %g secs\n\n", name, t);
7625                 }
7626         }
7627
7628         if (!found) {
7629                 printf("Did not find a test named %s\n", name);
7630                 ret = False;
7631         }
7632
7633         return ret;
7634 }
7635
7636
7637 static void usage(void)
7638 {
7639         int i;
7640
7641         printf("WARNING samba4 test suite is much more complete nowadays.\n");
7642         printf("Please use samba4 torture.\n\n");
7643
7644         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7645
7646         printf("\t-d debuglevel\n");
7647         printf("\t-U user%%pass\n");
7648         printf("\t-k               use kerberos\n");
7649         printf("\t-N numprocs\n");
7650         printf("\t-n my_netbios_name\n");
7651         printf("\t-W workgroup\n");
7652         printf("\t-o num_operations\n");
7653         printf("\t-O socket_options\n");
7654         printf("\t-m maximum protocol\n");
7655         printf("\t-L use oplocks\n");
7656         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
7657         printf("\t-A showall\n");
7658         printf("\t-p port\n");
7659         printf("\t-s seed\n");
7660         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
7661         printf("\n\n");
7662
7663         printf("tests are:");
7664         for (i=0;torture_ops[i].name;i++) {
7665                 printf(" %s", torture_ops[i].name);
7666         }
7667         printf("\n");
7668
7669         printf("default test is ALL\n");
7670
7671         exit(1);
7672 }
7673
7674 /****************************************************************************
7675   main program
7676 ****************************************************************************/
7677  int main(int argc,char *argv[])
7678 {
7679         int opt, i;
7680         char *p;
7681         int gotuser = 0;
7682         int gotpass = 0;
7683         bool correct = True;
7684         TALLOC_CTX *frame = talloc_stackframe();
7685         int seed = time(NULL);
7686
7687         dbf = x_stdout;
7688
7689 #ifdef HAVE_SETBUFFER
7690         setbuffer(stdout, NULL, 0);
7691 #endif
7692
7693         load_case_tables();
7694
7695         setup_logging("smbtorture", true);
7696
7697         if (is_default_dyn_CONFIGFILE()) {
7698                 if(getenv("SMB_CONF_PATH")) {
7699                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7700                 }
7701         }
7702         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7703         load_interfaces();
7704
7705         if (argc < 2) {
7706                 usage();
7707         }
7708
7709         for(p = argv[1]; *p; p++)
7710           if(*p == '\\')
7711             *p = '/';
7712
7713         if (strncmp(argv[1], "//", 2)) {
7714                 usage();
7715         }
7716
7717         fstrcpy(host, &argv[1][2]);
7718         p = strchr_m(&host[2],'/');
7719         if (!p) {
7720                 usage();
7721         }
7722         *p = 0;
7723         fstrcpy(share, p+1);
7724
7725         fstrcpy(myname, get_myname(talloc_tos()));
7726         if (!*myname) {
7727                 fprintf(stderr, "Failed to get my hostname.\n");
7728                 return 1;
7729         }
7730
7731         if (*username == 0 && getenv("LOGNAME")) {
7732           fstrcpy(username,getenv("LOGNAME"));
7733         }
7734
7735         argc--;
7736         argv++;
7737
7738         fstrcpy(workgroup, lp_workgroup());
7739
7740         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7741                 switch (opt) {
7742                 case 'p':
7743                         port_to_use = atoi(optarg);
7744                         break;
7745                 case 's':
7746                         seed = atoi(optarg);
7747                         break;
7748                 case 'W':
7749                         fstrcpy(workgroup,optarg);
7750                         break;
7751                 case 'm':
7752                         max_protocol = interpret_protocol(optarg, max_protocol);
7753                         break;
7754                 case 'N':
7755                         nprocs = atoi(optarg);
7756                         break;
7757                 case 'o':
7758                         torture_numops = atoi(optarg);
7759                         break;
7760                 case 'd':
7761                         DEBUGLEVEL = atoi(optarg);
7762                         break;
7763                 case 'O':
7764                         sockops = optarg;
7765                         break;
7766                 case 'L':
7767                         use_oplocks = True;
7768                         break;
7769                 case 'l':
7770                         local_path = optarg;
7771                         break;
7772                 case 'A':
7773                         torture_showall = True;
7774                         break;
7775                 case 'n':
7776                         fstrcpy(myname, optarg);
7777                         break;
7778                 case 'c':
7779                         client_txt = optarg;
7780                         break;
7781                 case 'e':
7782                         do_encrypt = true;
7783                         break;
7784                 case 'k':
7785 #ifdef HAVE_KRB5
7786                         use_kerberos = True;
7787 #else
7788                         d_printf("No kerberos support compiled in\n");
7789                         exit(1);
7790 #endif
7791                         break;
7792                 case 'U':
7793                         gotuser = 1;
7794                         fstrcpy(username,optarg);
7795                         p = strchr_m(username,'%');
7796                         if (p) {
7797                                 *p = 0;
7798                                 fstrcpy(password, p+1);
7799                                 gotpass = 1;
7800                         }
7801                         break;
7802                 case 'b':
7803                         fstrcpy(multishare_conn_fname, optarg);
7804                         use_multishare_conn = True;
7805                         break;
7806                 case 'B':
7807                         torture_blocksize = atoi(optarg);
7808                         break;
7809                 default:
7810                         printf("Unknown option %c (%d)\n", (char)opt, opt);
7811                         usage();
7812                 }
7813         }
7814
7815         d_printf("using seed %d\n", seed);
7816
7817         srandom(seed);
7818
7819         if(use_kerberos && !gotuser) gotpass = True;
7820
7821         while (!gotpass) {
7822                 p = getpass("Password:");
7823                 if (p) {
7824                         fstrcpy(password, p);
7825                         gotpass = 1;
7826                 }
7827         }
7828
7829         printf("host=%s share=%s user=%s myname=%s\n", 
7830                host, share, username, myname);
7831
7832         if (argc == optind) {
7833                 correct = run_test("ALL");
7834         } else {
7835                 for (i=optind;i<argc;i++) {
7836                         if (!run_test(argv[i])) {
7837                                 correct = False;
7838                         }
7839                 }
7840         }
7841
7842         TALLOC_FREE(frame);
7843
7844         if (correct) {
7845                 return(0);
7846         } else {
7847                 return(1);
7848         }
7849 }