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