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