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