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