s3: Add talloc_dict.[ch]
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "nsswitch/libwbclient/wbc_async.h"
22
23 extern char *optarg;
24 extern int optind;
25
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static const char *sockops="TCP_NODELAY";
29 static int nprocs=1;
30 static int port_to_use=0;
31 int torture_numops=100;
32 int torture_blocksize=1024*1024;
33 static int procnum; /* records process count number when forking */
34 static struct cli_state *current_cli;
35 static fstring randomfname;
36 static bool use_oplocks;
37 static bool use_level_II_oplocks;
38 static const char *client_txt = "client_oplocks.txt";
39 static bool use_kerberos;
40 static fstring multishare_conn_fname;
41 static bool use_multishare_conn = False;
42 static bool do_encrypt;
43
44 bool torture_showall = False;
45
46 static double create_procs(bool (*fn)(int), bool *result);
47
48
49 static struct timeval tp1,tp2;
50
51
52 void start_timer(void)
53 {
54         GetTimeOfDay(&tp1);
55 }
56
57 double end_timer(void)
58 {
59         GetTimeOfDay(&tp2);
60         return((tp2.tv_sec - tp1.tv_sec) + 
61                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
62 }
63
64
65 /* return a pointer to a anonymous shared memory segment of size "size"
66    which will persist across fork() but will disappear when all processes
67    exit 
68
69    The memory is not zeroed 
70
71    This function uses system5 shared memory. It takes advantage of a property
72    that the memory is not destroyed if it is attached when the id is removed
73    */
74 void *shm_setup(int size)
75 {
76         int shmid;
77         void *ret;
78
79         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 (!NT_STATUS_IS_OK(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         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 (NT_STATUS_IS_OK(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 (NT_STATUS_IS_OK(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 (NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1725               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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               NT_STATUS_IS_OK(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 = NT_STATUS_IS_OK(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 = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1876                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1877                   NT_STATUS_IS_OK(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 = NT_STATUS_IS_OK(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  * This demonstrates a problem with our use of GPFS share modes: A file
2088  * descriptor sitting in the pending close queue holding a GPFS share mode
2089  * blocks opening a file another time. Happens with Word 2007 temp files.
2090  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2091  * open is denied with NT_STATUS_SHARING_VIOLATION.
2092  */
2093
2094 static bool run_locktest8(int dummy)
2095 {
2096         struct cli_state *cli1;
2097         const char *fname = "\\lockt8.lck";
2098         uint16_t fnum1, fnum2;
2099         char buf[200];
2100         bool correct = False;
2101         NTSTATUS status;
2102
2103         if (!torture_open_connection(&cli1, 0)) {
2104                 return False;
2105         }
2106
2107         cli_sockopt(cli1, sockops);
2108
2109         printf("starting locktest8\n");
2110
2111         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2112
2113         status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2114                           &fnum1);
2115         if (!NT_STATUS_IS_OK(status)) {
2116                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2117                 return false;
2118         }
2119
2120         memset(buf, 0, sizeof(buf));
2121
2122         status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2123         if (!NT_STATUS_IS_OK(status)) {
2124                 d_fprintf(stderr, "cli_open second time returned %s\n",
2125                           cli_errstr(cli1));
2126                 goto fail;
2127         }
2128
2129         if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2130                 printf("Unable to apply read lock on range 1:1, error was "
2131                        "%s\n", cli_errstr(cli1));
2132                 goto fail;
2133         }
2134
2135         status = cli_close(cli1, fnum1);
2136         if (!NT_STATUS_IS_OK(status)) {
2137                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2138                 goto fail;
2139         }
2140
2141         status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2142         if (!NT_STATUS_IS_OK(status)) {
2143                 d_fprintf(stderr, "cli_open third time returned %s\n",
2144                           cli_errstr(cli1));
2145                 goto fail;
2146         }
2147
2148         correct = true;
2149
2150 fail:
2151         cli_close(cli1, fnum1);
2152         cli_close(cli1, fnum2);
2153         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2154         torture_close_connection(cli1);
2155
2156         printf("finished locktest8\n");
2157         return correct;
2158 }
2159
2160 /*
2161 test whether fnums and tids open on one VC are available on another (a major
2162 security hole)
2163 */
2164 static bool run_fdpasstest(int dummy)
2165 {
2166         struct cli_state *cli1, *cli2;
2167         const char *fname = "\\fdpass.tst";
2168         uint16_t fnum1;
2169         char buf[1024];
2170
2171         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2172                 return False;
2173         }
2174         cli_sockopt(cli1, sockops);
2175         cli_sockopt(cli2, sockops);
2176
2177         printf("starting fdpasstest\n");
2178
2179         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2180
2181         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2182                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2183                 return False;
2184         }
2185
2186         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2187                 printf("write failed (%s)\n", cli_errstr(cli1));
2188                 return False;
2189         }
2190
2191         cli2->vuid = cli1->vuid;
2192         cli2->cnum = cli1->cnum;
2193         cli2->pid = cli1->pid;
2194
2195         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2196                 printf("read succeeded! nasty security hole [%s]\n",
2197                        buf);
2198                 return False;
2199         }
2200
2201         cli_close(cli1, fnum1);
2202         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2203
2204         torture_close_connection(cli1);
2205         torture_close_connection(cli2);
2206
2207         printf("finished fdpasstest\n");
2208         return True;
2209 }
2210
2211 static bool run_fdsesstest(int dummy)
2212 {
2213         struct cli_state *cli;
2214         uint16 new_vuid;
2215         uint16 saved_vuid;
2216         uint16 new_cnum;
2217         uint16 saved_cnum;
2218         const char *fname = "\\fdsess.tst";
2219         const char *fname1 = "\\fdsess1.tst";
2220         uint16_t fnum1;
2221         uint16_t fnum2;
2222         char buf[1024];
2223         bool ret = True;
2224
2225         if (!torture_open_connection(&cli, 0))
2226                 return False;
2227         cli_sockopt(cli, sockops);
2228
2229         if (!torture_cli_session_setup2(cli, &new_vuid))
2230                 return False;
2231
2232         saved_cnum = cli->cnum;
2233         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2234                 return False;
2235         new_cnum = cli->cnum;
2236         cli->cnum = saved_cnum;
2237
2238         printf("starting fdsesstest\n");
2239
2240         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2241         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2242
2243         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2244                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2245                 return False;
2246         }
2247
2248         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2249                 printf("write failed (%s)\n", cli_errstr(cli));
2250                 return False;
2251         }
2252
2253         saved_vuid = cli->vuid;
2254         cli->vuid = new_vuid;
2255
2256         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2257                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2258                        buf);
2259                 ret = False;
2260         }
2261         /* Try to open a file with different vuid, samba cnum. */
2262         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2263                 printf("create with different vuid, same cnum succeeded.\n");
2264                 cli_close(cli, fnum2);
2265                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2266         } else {
2267                 printf("create with different vuid, same cnum failed.\n");
2268                 printf("This will cause problems with service clients.\n");
2269                 ret = False;
2270         }
2271
2272         cli->vuid = saved_vuid;
2273
2274         /* Try with same vuid, different cnum. */
2275         cli->cnum = new_cnum;
2276
2277         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2278                 printf("read succeeded with different cnum![%s]\n",
2279                        buf);
2280                 ret = False;
2281         }
2282
2283         cli->cnum = saved_cnum;
2284         cli_close(cli, fnum1);
2285         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2286
2287         torture_close_connection(cli);
2288
2289         printf("finished fdsesstest\n");
2290         return ret;
2291 }
2292
2293 /*
2294   This test checks that 
2295
2296   1) the server does not allow an unlink on a file that is open
2297 */
2298 static bool run_unlinktest(int dummy)
2299 {
2300         struct cli_state *cli;
2301         const char *fname = "\\unlink.tst";
2302         uint16_t fnum;
2303         bool correct = True;
2304
2305         if (!torture_open_connection(&cli, 0)) {
2306                 return False;
2307         }
2308
2309         cli_sockopt(cli, sockops);
2310
2311         printf("starting unlink test\n");
2312
2313         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2314
2315         cli_setpid(cli, 1);
2316
2317         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2318                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2319                 return False;
2320         }
2321
2322         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2323                 printf("error: server allowed unlink on an open file\n");
2324                 correct = False;
2325         } else {
2326                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2327                                       NT_STATUS_SHARING_VIOLATION);
2328         }
2329
2330         cli_close(cli, fnum);
2331         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2332
2333         if (!torture_close_connection(cli)) {
2334                 correct = False;
2335         }
2336
2337         printf("unlink test finished\n");
2338
2339         return correct;
2340 }
2341
2342
2343 /*
2344 test how many open files this server supports on the one socket
2345 */
2346 static bool run_maxfidtest(int dummy)
2347 {
2348         struct cli_state *cli;
2349         const char *ftemplate = "\\maxfid.%d.%d";
2350         fstring fname;
2351         uint16_t fnums[0x11000];
2352         int i;
2353         int retries=4;
2354         bool correct = True;
2355
2356         cli = current_cli;
2357
2358         if (retries <= 0) {
2359                 printf("failed to connect\n");
2360                 return False;
2361         }
2362
2363         cli_sockopt(cli, sockops);
2364
2365         for (i=0; i<0x11000; i++) {
2366                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2367                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2368                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2369                         printf("open of %s failed (%s)\n", 
2370                                fname, cli_errstr(cli));
2371                         printf("maximum fnum is %d\n", i);
2372                         break;
2373                 }
2374                 printf("%6d\r", i);
2375         }
2376         printf("%6d\n", i);
2377         i--;
2378
2379         printf("cleaning up\n");
2380         for (;i>=0;i--) {
2381                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2382                 cli_close(cli, fnums[i]);
2383                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2384                         printf("unlink of %s failed (%s)\n", 
2385                                fname, cli_errstr(cli));
2386                         correct = False;
2387                 }
2388                 printf("%6d\r", i);
2389         }
2390         printf("%6d\n", 0);
2391
2392         printf("maxfid test finished\n");
2393         if (!torture_close_connection(cli)) {
2394                 correct = False;
2395         }
2396         return correct;
2397 }
2398
2399 /* generate a random buffer */
2400 static void rand_buf(char *buf, int len)
2401 {
2402         while (len--) {
2403                 *buf = (char)sys_random();
2404                 buf++;
2405         }
2406 }
2407
2408 /* send smb negprot commands, not reading the response */
2409 static bool run_negprot_nowait(int dummy)
2410 {
2411         int i;
2412         static struct cli_state *cli;
2413         bool correct = True;
2414
2415         printf("starting negprot nowait test\n");
2416
2417         if (!(cli = open_nbt_connection())) {
2418                 return False;
2419         }
2420
2421         for (i=0;i<50000;i++) {
2422                 cli_negprot_sendsync(cli);
2423         }
2424
2425         if (!torture_close_connection(cli)) {
2426                 correct = False;
2427         }
2428
2429         printf("finished negprot nowait test\n");
2430
2431         return correct;
2432 }
2433
2434
2435 /* send random IPC commands */
2436 static bool run_randomipc(int dummy)
2437 {
2438         char *rparam = NULL;
2439         char *rdata = NULL;
2440         unsigned int rdrcnt,rprcnt;
2441         char param[1024];
2442         int api, param_len, i;
2443         struct cli_state *cli;
2444         bool correct = True;
2445         int count = 50000;
2446
2447         printf("starting random ipc test\n");
2448
2449         if (!torture_open_connection(&cli, 0)) {
2450                 return False;
2451         }
2452
2453         for (i=0;i<count;i++) {
2454                 api = sys_random() % 500;
2455                 param_len = (sys_random() % 64);
2456
2457                 rand_buf(param, param_len);
2458
2459                 SSVAL(param,0,api); 
2460
2461                 cli_api(cli, 
2462                         param, param_len, 8,  
2463                         NULL, 0, BUFFER_SIZE, 
2464                         &rparam, &rprcnt,     
2465                         &rdata, &rdrcnt);
2466                 if (i % 100 == 0) {
2467                         printf("%d/%d\r", i,count);
2468                 }
2469         }
2470         printf("%d/%d\n", i, count);
2471
2472         if (!torture_close_connection(cli)) {
2473                 correct = False;
2474         }
2475
2476         printf("finished random ipc test\n");
2477
2478         return correct;
2479 }
2480
2481
2482
2483 static void browse_callback(const char *sname, uint32 stype, 
2484                             const char *comment, void *state)
2485 {
2486         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2487 }
2488
2489
2490
2491 /*
2492   This test checks the browse list code
2493
2494 */
2495 static bool run_browsetest(int dummy)
2496 {
2497         static struct cli_state *cli;
2498         bool correct = True;
2499
2500         printf("starting browse test\n");
2501
2502         if (!torture_open_connection(&cli, 0)) {
2503                 return False;
2504         }
2505
2506         printf("domain list:\n");
2507         cli_NetServerEnum(cli, cli->server_domain, 
2508                           SV_TYPE_DOMAIN_ENUM,
2509                           browse_callback, NULL);
2510
2511         printf("machine list:\n");
2512         cli_NetServerEnum(cli, cli->server_domain, 
2513                           SV_TYPE_ALL,
2514                           browse_callback, NULL);
2515
2516         if (!torture_close_connection(cli)) {
2517                 correct = False;
2518         }
2519
2520         printf("browse test finished\n");
2521
2522         return correct;
2523
2524 }
2525
2526
2527 /*
2528   This checks how the getatr calls works
2529 */
2530 static bool run_attrtest(int dummy)
2531 {
2532         struct cli_state *cli;
2533         uint16_t fnum;
2534         time_t t, t2;
2535         const char *fname = "\\attrib123456789.tst";
2536         bool correct = True;
2537
2538         printf("starting attrib test\n");
2539
2540         if (!torture_open_connection(&cli, 0)) {
2541                 return False;
2542         }
2543
2544         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2545         cli_open(cli, fname, 
2546                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2547         cli_close(cli, fnum);
2548         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2549                 printf("getatr failed (%s)\n", cli_errstr(cli));
2550                 correct = False;
2551         }
2552
2553         if (abs(t - time(NULL)) > 60*60*24*10) {
2554                 printf("ERROR: SMBgetatr bug. time is %s",
2555                        ctime(&t));
2556                 t = time(NULL);
2557                 correct = True;
2558         }
2559
2560         t2 = t-60*60*24; /* 1 day ago */
2561
2562         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2563                 printf("setatr failed (%s)\n", cli_errstr(cli));
2564                 correct = True;
2565         }
2566
2567         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2568                 printf("getatr failed (%s)\n", cli_errstr(cli));
2569                 correct = True;
2570         }
2571
2572         if (t != t2) {
2573                 printf("ERROR: getatr/setatr bug. times are\n%s",
2574                        ctime(&t));
2575                 printf("%s", ctime(&t2));
2576                 correct = True;
2577         }
2578
2579         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2580
2581         if (!torture_close_connection(cli)) {
2582                 correct = False;
2583         }
2584
2585         printf("attrib test finished\n");
2586
2587         return correct;
2588 }
2589
2590
2591 /*
2592   This checks a couple of trans2 calls
2593 */
2594 static bool run_trans2test(int dummy)
2595 {
2596         struct cli_state *cli;
2597         uint16_t fnum;
2598         SMB_OFF_T size;
2599         time_t c_time, a_time, m_time;
2600         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2601         const char *fname = "\\trans2.tst";
2602         const char *dname = "\\trans2";
2603         const char *fname2 = "\\trans2\\trans2.tst";
2604         char pname[1024];
2605         bool correct = True;
2606
2607         printf("starting trans2 test\n");
2608
2609         if (!torture_open_connection(&cli, 0)) {
2610                 return False;
2611         }
2612
2613         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2614         cli_open(cli, fname, 
2615                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2616         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2617                            &m_time_ts, NULL)) {
2618                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2619                 correct = False;
2620         }
2621
2622         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2623                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2624                 correct = False;
2625         }
2626
2627         if (strcmp(pname, fname)) {
2628                 printf("qfilename gave different name? [%s] [%s]\n",
2629                        fname, pname);
2630                 correct = False;
2631         }
2632
2633         cli_close(cli, fnum);
2634
2635         sleep(2);
2636
2637         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2638         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2639                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2640                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2641                 return False;
2642         }
2643         cli_close(cli, fnum);
2644
2645         if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2646                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2647                 correct = False;
2648         } else {
2649                 if (c_time != m_time) {
2650                         printf("create time=%s", ctime(&c_time));
2651                         printf("modify time=%s", ctime(&m_time));
2652                         printf("This system appears to have sticky create times\n");
2653                 }
2654                 if (a_time % (60*60) == 0) {
2655                         printf("access time=%s", ctime(&a_time));
2656                         printf("This system appears to set a midnight access time\n");
2657                         correct = False;
2658                 }
2659
2660                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2661                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2662                         correct = False;
2663                 }
2664         }
2665
2666
2667         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2668         cli_open(cli, fname, 
2669                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2670         cli_close(cli, fnum);
2671         if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, 
2672                             &m_time_ts, &size, NULL, NULL)) {
2673                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2674                 correct = False;
2675         } else {
2676                 if (w_time_ts.tv_sec < 60*60*24*2) {
2677                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2678                         printf("This system appears to set a initial 0 write time\n");
2679                         correct = False;
2680                 }
2681         }
2682
2683         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2684
2685
2686         /* check if the server updates the directory modification time
2687            when creating a new file */
2688         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2689                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2690                 correct = False;
2691         }
2692         sleep(3);
2693         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2694                             &m_time_ts, &size, NULL, NULL)) {
2695                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2696                 correct = False;
2697         }
2698
2699         cli_open(cli, fname2, 
2700                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2701         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2702         cli_close(cli, fnum);
2703         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2704                             &m_time2_ts, &size, NULL, NULL)) {
2705                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2706                 correct = False;
2707         } else {
2708                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2709                     == 0) {
2710                         printf("This system does not update directory modification times\n");
2711                         correct = False;
2712                 }
2713         }
2714         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2715         cli_rmdir(cli, dname);
2716
2717         if (!torture_close_connection(cli)) {
2718                 correct = False;
2719         }
2720
2721         printf("trans2 test finished\n");
2722
2723         return correct;
2724 }
2725
2726 /*
2727   This checks new W2K calls.
2728 */
2729
2730 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2731 {
2732         char *buf = NULL;
2733         uint32 len;
2734         bool correct = True;
2735
2736         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2737                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2738                 correct = False;
2739         } else {
2740                 printf("qfileinfo: level %d, len = %u\n", level, len);
2741                 dump_data(0, (uint8 *)buf, len);
2742                 printf("\n");
2743         }
2744         SAFE_FREE(buf);
2745         return correct;
2746 }
2747
2748 static bool run_w2ktest(int dummy)
2749 {
2750         struct cli_state *cli;
2751         uint16_t fnum;
2752         const char *fname = "\\w2ktest\\w2k.tst";
2753         int level;
2754         bool correct = True;
2755
2756         printf("starting w2k test\n");
2757
2758         if (!torture_open_connection(&cli, 0)) {
2759                 return False;
2760         }
2761
2762         cli_open(cli, fname, 
2763                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
2764
2765         for (level = 1004; level < 1040; level++) {
2766                 new_trans(cli, fnum, level);
2767         }
2768
2769         cli_close(cli, fnum);
2770
2771         if (!torture_close_connection(cli)) {
2772                 correct = False;
2773         }
2774
2775         printf("w2k test finished\n");
2776
2777         return correct;
2778 }
2779
2780
2781 /*
2782   this is a harness for some oplock tests
2783  */
2784 static bool run_oplock1(int dummy)
2785 {
2786         struct cli_state *cli1;
2787         const char *fname = "\\lockt1.lck";
2788         uint16_t fnum1;
2789         bool correct = True;
2790
2791         printf("starting oplock test 1\n");
2792
2793         if (!torture_open_connection(&cli1, 0)) {
2794                 return False;
2795         }
2796
2797         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2798
2799         cli_sockopt(cli1, sockops);
2800
2801         cli1->use_oplocks = True;
2802
2803         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2804                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2805                 return False;
2806         }
2807
2808         cli1->use_oplocks = False;
2809
2810         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2811         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2812
2813         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
2814                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2815                 return False;
2816         }
2817
2818         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
2819                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2820                 return False;
2821         }
2822
2823         if (!torture_close_connection(cli1)) {
2824                 correct = False;
2825         }
2826
2827         printf("finished oplock test 1\n");
2828
2829         return correct;
2830 }
2831
2832 static bool run_oplock2(int dummy)
2833 {
2834         struct cli_state *cli1, *cli2;
2835         const char *fname = "\\lockt2.lck";
2836         uint16_t fnum1, fnum2;
2837         int saved_use_oplocks = use_oplocks;
2838         char buf[4];
2839         bool correct = True;
2840         volatile bool *shared_correct;
2841
2842         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2843         *shared_correct = True;
2844
2845         use_level_II_oplocks = True;
2846         use_oplocks = True;
2847
2848         printf("starting oplock test 2\n");
2849
2850         if (!torture_open_connection(&cli1, 0)) {
2851                 use_level_II_oplocks = False;
2852                 use_oplocks = saved_use_oplocks;
2853                 return False;
2854         }
2855
2856         cli1->use_oplocks = True;
2857         cli1->use_level_II_oplocks = True;
2858
2859         if (!torture_open_connection(&cli2, 1)) {
2860                 use_level_II_oplocks = False;
2861                 use_oplocks = saved_use_oplocks;
2862                 return False;
2863         }
2864
2865         cli2->use_oplocks = True;
2866         cli2->use_level_II_oplocks = True;
2867
2868         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2869
2870         cli_sockopt(cli1, sockops);
2871         cli_sockopt(cli2, sockops);
2872
2873         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2874                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2875                 return False;
2876         }
2877
2878         /* Don't need the globals any more. */
2879         use_level_II_oplocks = False;
2880         use_oplocks = saved_use_oplocks;
2881
2882         if (fork() == 0) {
2883                 /* Child code */
2884                 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
2885                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2886                         *shared_correct = False;
2887                         exit(0);
2888                 }
2889
2890                 sleep(2);
2891
2892                 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
2893                         printf("close2 failed (%s)\n", cli_errstr(cli1));
2894                         *shared_correct = False;
2895                 }
2896
2897                 exit(0);
2898         }
2899
2900         sleep(2);
2901
2902         /* Ensure cli1 processes the break. Empty file should always return 0
2903          * bytes.  */
2904
2905         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2906                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2907                 correct = False;
2908         }
2909
2910         /* Should now be at level II. */
2911         /* Test if sending a write locks causes a break to none. */
2912
2913         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2914                 printf("lock failed (%s)\n", cli_errstr(cli1));
2915                 correct = False;
2916         }
2917
2918         cli_unlock(cli1, fnum1, 0, 4);
2919
2920         sleep(2);
2921
2922         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2923                 printf("lock failed (%s)\n", cli_errstr(cli1));
2924                 correct = False;
2925         }
2926
2927         cli_unlock(cli1, fnum1, 0, 4);
2928
2929         sleep(2);
2930
2931         cli_read(cli1, fnum1, buf, 0, 4);
2932
2933 #if 0
2934         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2935                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2936                 correct = False;
2937         }
2938 #endif
2939
2940         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
2941                 printf("close1 failed (%s)\n", cli_errstr(cli1));
2942                 correct = False;
2943         }
2944
2945         sleep(4);
2946
2947         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
2948                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2949                 correct = False;
2950         }
2951
2952         if (!torture_close_connection(cli1)) {
2953                 correct = False;
2954         }
2955
2956         if (!*shared_correct) {
2957                 correct = False;
2958         }
2959
2960         printf("finished oplock test 2\n");
2961
2962         return correct;
2963 }
2964
2965 /* handler for oplock 3 tests */
2966 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
2967 {
2968         printf("got oplock break fnum=%d level=%d\n",
2969                fnum, level);
2970         return cli_oplock_ack(cli, fnum, level);
2971 }
2972
2973 static bool run_oplock3(int dummy)
2974 {
2975         struct cli_state *cli;
2976         const char *fname = "\\oplockt3.dat";
2977         uint16_t fnum;
2978         char buf[4] = "abcd";
2979         bool correct = True;
2980         volatile bool *shared_correct;
2981
2982         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2983         *shared_correct = True;
2984
2985         printf("starting oplock test 3\n");
2986
2987         if (fork() == 0) {
2988                 /* Child code */
2989                 use_oplocks = True;
2990                 use_level_II_oplocks = True;
2991                 if (!torture_open_connection(&cli, 0)) {
2992                         *shared_correct = False;
2993                         exit(0);
2994                 } 
2995                 sleep(2);
2996                 /* try to trigger a oplock break in parent */
2997                 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
2998                 cli_write(cli, fnum, 0, buf, 0, 4);
2999                 exit(0);
3000         }
3001
3002         /* parent code */
3003         use_oplocks = True;
3004         use_level_II_oplocks = True;
3005         if (!torture_open_connection(&cli, 1)) { /* other is forked */
3006                 return False;
3007         }
3008         cli_oplock_handler(cli, oplock3_handler);
3009         cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3010         cli_write(cli, fnum, 0, buf, 0, 4);
3011         cli_close(cli, fnum);
3012         cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3013         cli->timeout = 20000;
3014         cli_receive_smb(cli);
3015         printf("finished oplock test 3\n");
3016
3017         return (correct && *shared_correct);
3018
3019 /* What are we looking for here?  What's sucess and what's FAILURE? */
3020 }
3021
3022
3023
3024 /*
3025   Test delete on close semantics.
3026  */
3027 static bool run_deletetest(int dummy)
3028 {
3029         struct cli_state *cli1 = NULL;
3030         struct cli_state *cli2 = NULL;
3031         const char *fname = "\\delete.file";
3032         uint16_t fnum1 = (uint16_t)-1;
3033         uint16_t fnum2 = (uint16_t)-1;
3034         bool correct = True;
3035
3036         printf("starting delete test\n");
3037
3038         if (!torture_open_connection(&cli1, 0)) {
3039                 return False;
3040         }
3041
3042         cli_sockopt(cli1, sockops);
3043
3044         /* Test 1 - this should delete the file on close. */
3045
3046         cli_setatr(cli1, fname, 0, 0);
3047         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3048
3049         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3050                                    0, FILE_OVERWRITE_IF, 
3051                                    FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3052                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3053                 correct = False;
3054                 goto fail;
3055         }
3056
3057 #if 0 /* JRATEST */
3058         {
3059                 uint32 *accinfo = NULL;
3060                 uint32 len;
3061                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3062                 if (accinfo)
3063                         printf("access mode = 0x%lx\n", *accinfo);
3064                 SAFE_FREE(accinfo);
3065         }
3066 #endif
3067
3068         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3069                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3070                 correct = False;
3071                 goto fail;
3072         }
3073
3074         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3075                 printf("[1] open of %s succeeded (should fail)\n", fname);
3076                 correct = False;
3077                 goto fail;
3078         }
3079
3080         printf("first delete on close test succeeded.\n");
3081
3082         /* Test 2 - this should delete the file on close. */
3083
3084         cli_setatr(cli1, fname, 0, 0);
3085         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3086
3087         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3088                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3089                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3090                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3091                 correct = False;
3092                 goto fail;
3093         }
3094
3095         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3096                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3097                 correct = False;
3098                 goto fail;
3099         }
3100
3101         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3102                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3103                 correct = False;
3104                 goto fail;
3105         }
3106
3107         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3108                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3109                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3110                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3111                         correct = False;
3112                         goto fail;
3113                 }
3114                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3115         } else
3116                 printf("second delete on close test succeeded.\n");
3117
3118         /* Test 3 - ... */
3119         cli_setatr(cli1, fname, 0, 0);
3120         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3121
3122         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3123                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3124                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3125                 correct = False;
3126                 goto fail;
3127         }
3128
3129         /* This should fail with a sharing violation - open for delete is only compatible
3130            with SHARE_DELETE. */
3131
3132         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3133                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3134                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3135                 correct = False;
3136                 goto fail;
3137         }
3138
3139         /* This should succeed. */
3140
3141         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3142                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3143                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3144                 correct = False;
3145                 goto fail;
3146         }
3147
3148         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3149                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3150                 correct = False;
3151                 goto fail;
3152         }
3153
3154         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3155                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3156                 correct = False;
3157                 goto fail;
3158         }
3159
3160         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3161                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3162                 correct = False;
3163                 goto fail;
3164         }
3165
3166         /* This should fail - file should no longer be there. */
3167
3168         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3169                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3170                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3171                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3172                 }
3173                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3174                 correct = False;
3175                 goto fail;
3176         } else
3177                 printf("third delete on close test succeeded.\n");
3178
3179         /* Test 4 ... */
3180         cli_setatr(cli1, fname, 0, 0);
3181         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3182
3183         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3184                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3185                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3186                 correct = False;
3187                 goto fail;
3188         }
3189
3190         /* This should succeed. */
3191         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3192                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3193                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3194                 correct = False;
3195                 goto fail;
3196         }
3197
3198         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3199                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3200                 correct = False;
3201                 goto fail;
3202         }
3203
3204         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3205                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3206                 correct = False;
3207                 goto fail;
3208         }
3209
3210         /* This should fail - no more opens once delete on close set. */
3211         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3212                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3213                                    FILE_OPEN, 0, 0, &fnum2))) {
3214                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3215                 correct = False;
3216                 goto fail;
3217         } else
3218                 printf("fourth delete on close test succeeded.\n");
3219
3220         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3221                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3222                 correct = False;
3223                 goto fail;
3224         }
3225
3226         /* Test 5 ... */
3227         cli_setatr(cli1, fname, 0, 0);
3228         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3229
3230         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3231                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3232                 correct = False;
3233                 goto fail;
3234         }
3235
3236         /* This should fail - only allowed on NT opens with DELETE access. */
3237
3238         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3239                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3240                 correct = False;
3241                 goto fail;
3242         }
3243
3244         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3245                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3246                 correct = False;
3247                 goto fail;
3248         }
3249
3250         printf("fifth delete on close test succeeded.\n");
3251
3252         /* Test 6 ... */
3253         cli_setatr(cli1, fname, 0, 0);
3254         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3255
3256         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3257                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3258                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3259                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3260                 correct = False;
3261                 goto fail;
3262         }
3263
3264         /* This should fail - only allowed on NT opens with DELETE access. */
3265
3266         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3267                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3268                 correct = False;
3269                 goto fail;
3270         }
3271
3272         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3273                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3274                 correct = False;
3275                 goto fail;
3276         }
3277
3278         printf("sixth delete on close test succeeded.\n");
3279
3280         /* Test 7 ... */
3281         cli_setatr(cli1, fname, 0, 0);
3282         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3283
3284         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3285                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3286                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3287                 correct = False;
3288                 goto fail;
3289         }
3290
3291         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3292                 printf("[7] setting delete_on_close on file failed !\n");
3293                 correct = False;
3294                 goto fail;
3295         }
3296
3297         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3298                 printf("[7] unsetting delete_on_close on file failed !\n");
3299                 correct = False;
3300                 goto fail;
3301         }
3302
3303         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3304                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3305                 correct = False;
3306                 goto fail;
3307         }
3308
3309         /* This next open should succeed - we reset the flag. */
3310
3311         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3312                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3313                 correct = False;
3314                 goto fail;
3315         }
3316
3317         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3318                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3319                 correct = False;
3320                 goto fail;
3321         }
3322
3323         printf("seventh delete on close test succeeded.\n");
3324
3325         /* Test 7 ... */
3326         cli_setatr(cli1, fname, 0, 0);
3327         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3328
3329         if (!torture_open_connection(&cli2, 1)) {
3330                 printf("[8] failed to open second connection.\n");
3331                 correct = False;
3332                 goto fail;
3333         }
3334
3335         cli_sockopt(cli1, sockops);
3336
3337         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3338                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3339                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3340                 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3341                 correct = False;
3342                 goto fail;
3343         }
3344
3345         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3346                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3347                                    FILE_OPEN, 0, 0, &fnum2))) {
3348                 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3349                 correct = False;
3350                 goto fail;
3351         }
3352
3353         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3354                 printf("[8] setting delete_on_close on file failed !\n");
3355                 correct = False;
3356                 goto fail;
3357         }
3358
3359         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3360                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3361                 correct = False;
3362                 goto fail;
3363         }
3364
3365         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3366                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3367                 correct = False;
3368                 goto fail;
3369         }
3370
3371         /* This should fail.. */
3372         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3373                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3374                 goto fail;
3375                 correct = False;
3376         } else
3377                 printf("eighth delete on close test succeeded.\n");
3378
3379         /* This should fail - we need to set DELETE_ACCESS. */
3380         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3381                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3382                 printf("[9] open of %s succeeded should have failed!\n", fname);
3383                 correct = False;
3384                 goto fail;
3385         }
3386
3387         printf("ninth delete on close test succeeded.\n");
3388
3389         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3390                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3391                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3392                 correct = False;
3393                 goto fail;
3394         }
3395
3396         /* This should delete the file. */
3397         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3398                 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3399                 correct = False;
3400                 goto fail;
3401         }
3402
3403         /* This should fail.. */
3404         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3405                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3406                 goto fail;
3407                 correct = False;
3408         } else
3409                 printf("tenth delete on close test succeeded.\n");
3410
3411         cli_setatr(cli1, fname, 0, 0);
3412         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3413
3414         /* What error do we get when attempting to open a read-only file with
3415            delete access ? */
3416
3417         /* Create a readonly file. */
3418         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3419                                    FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3420                 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3421                 correct = False;
3422                 goto fail;
3423         }
3424
3425         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3426                 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3427                 correct = False;
3428                 goto fail;
3429         }
3430
3431         /* Now try open for delete access. */
3432         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3433                                    0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3434                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3435                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3436                 cli_close(cli1, fnum1);
3437                 goto fail;
3438                 correct = False;
3439         } else {
3440                 NTSTATUS nterr = cli_nt_error(cli1);
3441                 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3442                         printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3443                         goto fail;
3444                         correct = False;
3445                 } else {
3446                         printf("eleventh delete on close test succeeded.\n");
3447                 }
3448         }
3449
3450         printf("finished delete test\n");
3451
3452   fail:
3453         /* FIXME: This will crash if we aborted before cli2 got
3454          * intialized, because these functions don't handle
3455          * uninitialized connections. */
3456
3457         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3458         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3459         cli_setatr(cli1, fname, 0, 0);
3460         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3461
3462         if (cli1 && !torture_close_connection(cli1)) {
3463                 correct = False;
3464         }
3465         if (cli2 && !torture_close_connection(cli2)) {
3466                 correct = False;
3467         }
3468         return correct;
3469 }
3470
3471
3472 /*
3473   print out server properties
3474  */
3475 static bool run_properties(int dummy)
3476 {
3477         struct cli_state *cli;
3478         bool correct = True;
3479
3480         printf("starting properties test\n");
3481
3482         ZERO_STRUCT(cli);
3483
3484         if (!torture_open_connection(&cli, 0)) {
3485                 return False;
3486         }
3487
3488         cli_sockopt(cli, sockops);
3489
3490         d_printf("Capabilities 0x%08x\n", cli->capabilities);
3491
3492         if (!torture_close_connection(cli)) {
3493                 correct = False;
3494         }
3495
3496         return correct;
3497 }
3498
3499
3500
3501 /* FIRST_DESIRED_ACCESS   0xf019f */
3502 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3503                                FILE_READ_EA|                           /* 0xf */ \
3504                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
3505                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
3506                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
3507                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
3508 /* SECOND_DESIRED_ACCESS  0xe0080 */
3509 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3510                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3511                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
3512
3513 #if 0
3514 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3515                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3516                                FILE_READ_DATA|\
3517                                WRITE_OWNER_ACCESS                      /* */
3518 #endif
3519
3520 /*
3521   Test ntcreate calls made by xcopy
3522  */
3523 static bool run_xcopy(int dummy)
3524 {
3525         static struct cli_state *cli1;
3526         const char *fname = "\\test.txt";
3527         bool correct = True;
3528         uint16_t fnum1, fnum2;
3529
3530         printf("starting xcopy test\n");
3531
3532         if (!torture_open_connection(&cli1, 0)) {
3533                 return False;
3534         }
3535
3536         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3537                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3538                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
3539                                    0x4044, 0, &fnum1))) {
3540                 printf("First open failed - %s\n", cli_errstr(cli1));
3541                 return False;
3542         }
3543
3544         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3545                                    SECOND_DESIRED_ACCESS, 0,
3546                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
3547                                    0x200000, 0, &fnum2))) {
3548                 printf("second open failed - %s\n", cli_errstr(cli1));
3549                 return False;
3550         }
3551
3552         if (!torture_close_connection(cli1)) {
3553                 correct = False;
3554         }
3555
3556         return correct;
3557 }
3558
3559 /*
3560   Test rename on files open with share delete and no share delete.
3561  */
3562 static bool run_rename(int dummy)
3563 {
3564         static struct cli_state *cli1;
3565         const char *fname = "\\test.txt";
3566         const char *fname1 = "\\test1.txt";
3567         bool correct = True;
3568         uint16_t fnum1;
3569         NTSTATUS status;
3570
3571         printf("starting rename test\n");
3572
3573         if (!torture_open_connection(&cli1, 0)) {
3574                 return False;
3575         }
3576
3577         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3578         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3579         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3580                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3581                 printf("First open failed - %s\n", cli_errstr(cli1));
3582                 return False;
3583         }
3584
3585         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3586                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3587         } else {
3588                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3589                 correct = False;
3590         }
3591
3592         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3593                 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3594                 return False;
3595         }
3596
3597         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3598         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3599         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3600 #if 0
3601                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
3602 #else
3603                               FILE_SHARE_DELETE|FILE_SHARE_READ,
3604 #endif
3605                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3606         if (!NT_STATUS_IS_OK(status)) {
3607                 printf("Second open failed - %s\n", cli_errstr(cli1));
3608                 return False;
3609         }
3610
3611         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3612                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3613                 correct = False;
3614         } else {
3615                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3616         }
3617
3618         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3619                 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3620                 return False;
3621         }
3622
3623         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3624         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3625
3626         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3627                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3628                 printf("Third open failed - %s\n", cli_errstr(cli1));
3629                 return False;
3630         }
3631
3632
3633 #if 0
3634   {
3635         uint16_t fnum2;
3636
3637         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3638                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3639                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3640                 return False;
3641         }
3642         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3643                 printf("[8] setting delete_on_close on file failed !\n");
3644                 return False;
3645         }
3646
3647         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3648                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3649                 return False;
3650         }
3651   }
3652 #endif
3653
3654         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3655                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3656                 correct = False;
3657         } else {
3658                 printf("Third rename succeeded (SHARE_NONE)\n");
3659         }
3660
3661         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3662                 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3663                 return False;
3664         }
3665
3666         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3667         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3668
3669         /*----*/
3670
3671         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3672                                    FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3673                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3674                 return False;
3675         }
3676
3677         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3678                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3679         } else {
3680                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3681                 correct = False;
3682         }
3683
3684         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3685                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3686                 return False;
3687         }
3688
3689         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3690         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3691
3692         /*--*/
3693
3694         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3695                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3696                 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3697                 return False;
3698         }
3699
3700         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3701                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3702                         cli_errstr(cli1));
3703                 correct = False;
3704         } else {
3705                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3706         }
3707
3708         /*
3709          * Now check if the first name still exists ...
3710          */
3711
3712         /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3713                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3714           printf("Opening original file after rename of open file fails: %s\n",
3715               cli_errstr(cli1));
3716         }
3717         else {
3718           printf("Opening original file after rename of open file works ...\n");
3719           (void)cli_close(cli1, fnum2);
3720           } */
3721
3722         /*--*/
3723
3724
3725         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3726                 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3727                 return False;
3728         }
3729
3730         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3731         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3732
3733         if (!torture_close_connection(cli1)) {
3734                 correct = False;
3735         }
3736
3737         return correct;
3738 }
3739
3740 static bool run_pipe_number(int dummy)
3741 {
3742         struct cli_state *cli1;
3743         const char *pipe_name = "\\SPOOLSS";
3744         uint16_t fnum;
3745         int num_pipes = 0;
3746
3747         printf("starting pipenumber test\n");
3748         if (!torture_open_connection(&cli1, 0)) {
3749                 return False;
3750         }
3751
3752         cli_sockopt(cli1, sockops);
3753         while(1) {
3754                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3755                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
3756                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3757                         break;
3758                 }
3759                 num_pipes++;
3760                 printf("\r%6d", num_pipes);
3761         }
3762
3763         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3764         torture_close_connection(cli1);
3765         return True;
3766 }
3767
3768 /*
3769   Test open mode returns on read-only files.
3770  */
3771 static bool run_opentest(int dummy)
3772 {
3773         static struct cli_state *cli1;
3774         static struct cli_state *cli2;
3775         const char *fname = "\\readonly.file";
3776         uint16_t fnum1, fnum2;
3777         char buf[20];
3778         SMB_OFF_T fsize;
3779         bool correct = True;
3780         char *tmp_path;
3781
3782         printf("starting open test\n");
3783
3784         if (!torture_open_connection(&cli1, 0)) {
3785                 return False;
3786         }
3787
3788         cli_setatr(cli1, fname, 0, 0);
3789         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3790
3791         cli_sockopt(cli1, sockops);
3792
3793         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3794                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3795                 return False;
3796         }
3797
3798         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3799                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3800                 return False;
3801         }
3802
3803         if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
3804                 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3805                 return False;
3806         }
3807
3808         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
3809                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3810                 return False;
3811         }
3812
3813         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3814         cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
3815
3816         if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
3817                         NT_STATUS_ACCESS_DENIED)) {
3818                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3819         }
3820
3821         printf("finished open test 1\n");
3822
3823         cli_close(cli1, fnum1);
3824
3825         /* Now try not readonly and ensure ERRbadshare is returned. */
3826
3827         cli_setatr(cli1, fname, 0, 0);
3828
3829         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
3830                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3831                 return False;
3832         }
3833
3834         /* This will fail - but the error should be ERRshare. */
3835         cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
3836
3837         if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
3838                         NT_STATUS_SHARING_VIOLATION)) {
3839                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3840         }
3841
3842         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3843                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3844                 return False;
3845         }
3846
3847         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3848
3849         printf("finished open test 2\n");
3850
3851         /* Test truncate open disposition on file opened for read. */
3852
3853         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3854                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3855                 return False;
3856         }
3857
3858         /* write 20 bytes. */
3859
3860         memset(buf, '\0', 20);
3861
3862         if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3863                 printf("write failed (%s)\n", cli_errstr(cli1));
3864                 correct = False;
3865         }
3866
3867         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3868                 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3869                 return False;
3870         }
3871
3872         /* Ensure size == 20. */
3873         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
3874                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3875                 return False;
3876         }
3877
3878         if (fsize != 20) {
3879                 printf("(3) file size != 20\n");
3880                 return False;
3881         }
3882
3883         /* Now test if we can truncate a file opened for readonly. */
3884
3885         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
3886                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3887                 return False;
3888         }
3889
3890         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3891                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3892                 return False;
3893         }
3894
3895         /* Ensure size == 0. */
3896         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
3897                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3898                 return False;
3899         }
3900
3901         if (fsize != 0) {
3902                 printf("(3) file size != 0\n");
3903                 return False;
3904         }
3905         printf("finished open test 3\n");
3906
3907         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3908
3909
3910         printf("testing ctemp\n");
3911         if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
3912                 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3913                 return False;
3914         }
3915         printf("ctemp gave path %s\n", tmp_path);
3916         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3917                 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3918         }
3919         if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
3920                 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3921         }
3922
3923         /* Test the non-io opens... */
3924
3925         if (!torture_open_connection(&cli2, 1)) {
3926                 return False;
3927         }
3928
3929         cli_setatr(cli2, fname, 0, 0);
3930         cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
3931
3932         cli_sockopt(cli2, sockops);
3933
3934         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3935
3936         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3937                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3938                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3939                 return False;
3940         }
3941
3942         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3943                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
3944                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3945                 return False;
3946         }
3947
3948         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3949                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3950                 return False;
3951         }
3952         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3953                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3954                 return False;
3955         }
3956
3957         printf("non-io open test #1 passed.\n");
3958
3959         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3960
3961         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3962
3963         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3964                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3965                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3966                 return False;
3967         }
3968
3969         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3970                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
3971                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3972                 return False;
3973         }
3974
3975         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3976                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3977                 return False;
3978         }
3979         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3980                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3981                 return False;
3982         }
3983
3984         printf("non-io open test #2 passed.\n");
3985
3986         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3987
3988         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3989
3990         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3991                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3992                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3993                 return False;
3994         }
3995
3996         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3997                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
3998                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3999                 return False;
4000         }
4001
4002         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4003                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4004                 return False;
4005         }
4006         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4007                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4008                 return False;
4009         }
4010
4011         printf("non-io open test #3 passed.\n");
4012
4013         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4014
4015         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4016
4017         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4018                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4019                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4020                 return False;
4021         }
4022
4023         if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4024                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4025                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4026                 return False;
4027         }
4028
4029         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4030
4031         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4032                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4033                 return False;
4034         }
4035
4036         printf("non-io open test #4 passed.\n");
4037
4038         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4039
4040         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4041
4042         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4043                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4044                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4045                 return False;
4046         }
4047
4048         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4049                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4050                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4051                 return False;
4052         }
4053
4054         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4055                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4056                 return False;
4057         }
4058
4059         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4060                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4061                 return False;
4062         }
4063
4064         printf("non-io open test #5 passed.\n");
4065
4066         printf("TEST #6 testing 1 non-io open, one io open\n");
4067
4068         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4069
4070         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4071                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4072                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4073                 return False;
4074         }
4075
4076         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4077                                    FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4078                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4079                 return False;
4080         }
4081
4082         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4083                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4084                 return False;
4085         }
4086
4087         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4088                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4089                 return False;
4090         }
4091
4092         printf("non-io open test #6 passed.\n");
4093
4094         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4095
4096         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4097
4098         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4099                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4100                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4101                 return False;
4102         }
4103
4104         if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4105                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4106                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4107                 return False;
4108         }
4109
4110         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4111
4112         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4113                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4114                 return False;
4115         }
4116
4117         printf("non-io open test #7 passed.\n");
4118
4119         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4120
4121         if (!torture_close_connection(cli1)) {
4122                 correct = False;
4123         }
4124         if (!torture_close_connection(cli2)) {
4125                 correct = False;
4126         }
4127
4128         return correct;
4129 }
4130
4131 /*
4132   Test POSIX open /mkdir calls.
4133  */
4134 static bool run_simple_posix_open_test(int dummy)
4135 {
4136         static struct cli_state *cli1;
4137         const char *fname = "posix:file";
4138         const char *hname = "posix:hlink";
4139         const char *sname = "posix:symlink";
4140         const char *dname = "posix:dir";
4141         char buf[10];
4142         char namebuf[11];
4143         uint16 major, minor;
4144         uint32 caplow, caphigh;
4145         uint16_t fnum1 = (uint16_t)-1;
4146         SMB_STRUCT_STAT sbuf;
4147         bool correct = false;
4148
4149         printf("Starting simple POSIX open test\n");
4150
4151         if (!torture_open_connection(&cli1, 0)) {
4152                 return false;
4153         }
4154
4155         cli_sockopt(cli1, sockops);
4156
4157         if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4158                 printf("Server doesn't support UNIX CIFS extensions.\n");
4159                 return false;
4160         }
4161
4162         if (!cli_unix_extensions_version(cli1, &major,
4163                         &minor, &caplow, &caphigh)) {
4164                 printf("Server didn't return UNIX CIFS extensions.\n");
4165                 return false;
4166         }
4167
4168         if (!cli_set_unix_extensions_capabilities(cli1,
4169                         major, minor, caplow, caphigh)) {
4170                 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4171                 return false;
4172         }
4173
4174         cli_setatr(cli1, fname, 0, 0);
4175         cli_posix_unlink(cli1, fname);
4176         cli_setatr(cli1, dname, 0, 0);
4177         cli_posix_rmdir(cli1, dname);
4178         cli_setatr(cli1, hname, 0, 0);
4179         cli_posix_unlink(cli1, hname);
4180         cli_setatr(cli1, sname, 0, 0);
4181         cli_posix_unlink(cli1, sname);
4182
4183         /* Create a directory. */
4184         if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4185                 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4186                 goto out;
4187         }
4188
4189         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4190                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4191                 goto out;
4192         }
4193
4194         /* Test ftruncate - set file size. */
4195         if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4196                 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4197                 goto out;
4198         }
4199
4200         /* Ensure st_size == 1000 */
4201         if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4202                 printf("stat failed (%s)\n", cli_errstr(cli1));
4203                 goto out;
4204         }
4205
4206         if (sbuf.st_ex_size != 1000) {
4207                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4208                 goto out;
4209         }
4210
4211         /* Test ftruncate - set file size back to zero. */
4212         if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4213                 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4214                 goto out;
4215         }
4216
4217         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4218                 printf("close failed (%s)\n", cli_errstr(cli1));
4219                 goto out;
4220         }
4221
4222         /* Now open the file again for read only. */
4223         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4224                 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4225                 goto out;
4226         }
4227
4228         /* Now unlink while open. */
4229         if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4230                 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4231                 goto out;
4232         }
4233
4234         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4235                 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4236                 goto out;
4237         }
4238
4239         /* Ensure the file has gone. */
4240         if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4241                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4242                 goto out;
4243         }
4244
4245         /* What happens when we try and POSIX open a directory ? */
4246         if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4247                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4248                 goto out;
4249         } else {
4250                 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4251                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4252                         goto out;
4253                 }
4254         }
4255
4256         /* Create the file. */
4257         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4258                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4259                 goto out;
4260         }
4261
4262         /* Write some data into it. */
4263         if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4264                 printf("cli_write failed: %s\n", cli_errstr(cli1));
4265                 goto out;
4266         }
4267
4268         cli_close(cli1, fnum1);
4269
4270         /* Now create a hardlink. */
4271         if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4272                 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4273                 goto out;
4274         }
4275
4276         /* Now create a symlink. */
4277         if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4278                 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4279                 goto out;
4280         }
4281
4282         /* Open the hardlink for read. */
4283         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4284                 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4285                 goto out;
4286         }
4287
4288         if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4289                 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4290                 goto out;
4291         }
4292
4293         if (memcmp(buf, "TEST DATA\n", 10)) {
4294                 printf("invalid data read from hardlink\n");
4295                 goto out;
4296         }
4297
4298         /* Do a POSIX lock/unlock. */
4299         if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4300                 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4301                 goto out;
4302         }
4303
4304         /* Punch a hole in the locked area. */
4305         if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4306                 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4307                 goto out;
4308         }
4309
4310         cli_close(cli1, fnum1);
4311
4312         /* Open the symlink for read - this should fail. A POSIX
4313            client should not be doing opens on a symlink. */
4314         if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4315                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4316                 goto out;
4317         } else {
4318                 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4319                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4320                         printf("POSIX open of %s should have failed "
4321                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4322                                 "failed with %s instead.\n",
4323                                 sname, cli_errstr(cli1));
4324                         goto out;
4325                 }
4326         }
4327
4328         if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4329                 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4330                 goto out;
4331         }
4332
4333         if (strcmp(namebuf, fname) != 0) {
4334                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4335                         sname, fname, namebuf);
4336                 goto out;
4337         }
4338
4339         if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4340                 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4341                 goto out;
4342         }
4343
4344         printf("Simple POSIX open test passed\n");
4345         correct = true;
4346
4347   out:
4348
4349         if (fnum1 != (uint16_t)-1) {
4350                 cli_close(cli1, fnum1);
4351                 fnum1 = (uint16_t)-1;
4352         }
4353
4354         cli_setatr(cli1, sname, 0, 0);
4355         cli_posix_unlink(cli1, sname);
4356         cli_setatr(cli1, hname, 0, 0);
4357         cli_posix_unlink(cli1, hname);
4358         cli_setatr(cli1, fname, 0, 0);
4359         cli_posix_unlink(cli1, fname);
4360         cli_setatr(cli1, dname, 0, 0);
4361         cli_posix_rmdir(cli1, dname);
4362
4363         if (!torture_close_connection(cli1)) {
4364                 correct = false;
4365         }
4366
4367         return correct;
4368 }
4369
4370
4371 static uint32 open_attrs_table[] = {
4372                 FILE_ATTRIBUTE_NORMAL,
4373                 FILE_ATTRIBUTE_ARCHIVE,
4374                 FILE_ATTRIBUTE_READONLY,
4375                 FILE_ATTRIBUTE_HIDDEN,
4376                 FILE_ATTRIBUTE_SYSTEM,
4377
4378                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4379                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4380                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4381                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4382                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4383                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4384
4385                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4386                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4387                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4388                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4389 };
4390
4391 struct trunc_open_results {
4392         unsigned int num;
4393         uint32 init_attr;
4394         uint32 trunc_attr;
4395         uint32 result_attr;
4396 };
4397
4398 static struct trunc_open_results attr_results[] = {
4399         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4400         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4401         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4402         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4403         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4404         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4405         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4406         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4407         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4408         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4409         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4410         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4411         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4412         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4413         { 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 },
4414         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4415         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4416         { 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 },
4417         { 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 },
4418         { 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 },
4419         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4420         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4421         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4422         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4423         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4424         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4425 };
4426
4427 static bool run_openattrtest(int dummy)
4428 {
4429         static struct cli_state *cli1;
4430         const char *fname = "\\openattr.file";
4431         uint16_t fnum1;
4432         bool correct = True;
4433         uint16 attr;
4434         unsigned int i, j, k, l;
4435
4436         printf("starting open attr test\n");
4437
4438         if (!torture_open_connection(&cli1, 0)) {
4439                 return False;
4440         }
4441
4442         cli_sockopt(cli1, sockops);
4443
4444         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4445                 cli_setatr(cli1, fname, 0, 0);
4446                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4447                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4448                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4449                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4450                         return False;
4451                 }
4452
4453                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4454                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4455                         return False;
4456                 }
4457
4458                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4459                         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4460                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4461                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4462                                         if (attr_results[l].num == k) {
4463                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4464                                                                 k, open_attrs_table[i],
4465                                                                 open_attrs_table[j],
4466                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4467                                                 correct = False;
4468                                         }
4469                                 }
4470                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4471                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4472                                                         k, open_attrs_table[i], open_attrs_table[j],
4473                                                         cli_errstr(cli1));
4474                                         correct = False;
4475                                 }
4476 #if 0
4477                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4478 #endif
4479                                 k++;
4480                                 continue;
4481                         }
4482
4483                         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4484                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4485                                 return False;
4486                         }
4487
4488                         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4489                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4490                                 return False;
4491                         }
4492
4493 #if 0
4494                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4495                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
4496 #endif
4497
4498                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4499                                 if (attr_results[l].num == k) {
4500                                         if (attr != attr_results[l].result_attr ||
4501                                                         open_attrs_table[i] != attr_results[l].init_attr ||
4502                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
4503                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4504                                                 open_attrs_table[i],
4505                                                 open_attrs_table[j],
4506                                                 (unsigned int)attr,
4507                                                 attr_results[l].result_attr);
4508                                                 correct = False;
4509                                         }
4510                                         break;
4511                                 }
4512                         }
4513                         k++;
4514                 }
4515         }
4516
4517         cli_setatr(cli1, fname, 0, 0);
4518         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4519
4520         printf("open attr test %s.\n", correct ? "passed" : "failed");
4521
4522         if (!torture_close_connection(cli1)) {
4523                 correct = False;
4524         }
4525         return correct;
4526 }
4527
4528 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4529 {
4530
4531 }
4532
4533 /*
4534   test directory listing speed
4535  */
4536 static bool run_dirtest(int dummy)
4537 {
4538         int i;
4539         static struct cli_state *cli;
4540         uint16_t fnum;
4541         double t1;
4542         bool correct = True;
4543
4544         printf("starting directory test\n");
4545
4546         if (!torture_open_connection(&cli, 0)) {
4547                 return False;
4548         }
4549
4550         cli_sockopt(cli, sockops);
4551
4552         srandom(0);
4553         for (i=0;i<torture_numops;i++) {
4554                 fstring fname;
4555                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4556                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4557                         fprintf(stderr,"Failed to open %s\n", fname);
4558                         return False;
4559                 }
4560                 cli_close(cli, fnum);
4561         }
4562
4563         t1 = end_timer();
4564
4565         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4566         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4567         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4568
4569         printf("dirtest core %g seconds\n", end_timer() - t1);
4570
4571         srandom(0);
4572         for (i=0;i<torture_numops;i++) {
4573                 fstring fname;
4574                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4575                 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4576         }
4577
4578         if (!torture_close_connection(cli)) {
4579                 correct = False;
4580         }
4581
4582         printf("finished dirtest\n");
4583
4584         return correct;
4585 }
4586
4587 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4588 {
4589         struct cli_state *pcli = (struct cli_state *)state;
4590         fstring fname;
4591         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4592
4593         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4594                 return;
4595
4596         if (finfo->mode & aDIR) {
4597                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4598                         printf("del_fn: failed to rmdir %s\n,", fname );
4599         } else {
4600                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4601                         printf("del_fn: failed to unlink %s\n,", fname );
4602         }
4603 }
4604
4605
4606 /*
4607   sees what IOCTLs are supported
4608  */
4609 bool torture_ioctl_test(int dummy)
4610 {
4611         static struct cli_state *cli;
4612         uint16_t device, function;
4613         uint16_t fnum;
4614         const char *fname = "\\ioctl.dat";
4615         DATA_BLOB blob;
4616         NTSTATUS status;
4617
4618         if (!torture_open_connection(&cli, 0)) {
4619                 return False;
4620         }
4621
4622         printf("starting ioctl test\n");
4623
4624         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4625
4626         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4627                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4628                 return False;
4629         }
4630
4631         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4632         printf("ioctl device info: %s\n", cli_errstr(cli));
4633
4634         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4635         printf("ioctl job info: %s\n", cli_errstr(cli));
4636
4637         for (device=0;device<0x100;device++) {
4638                 printf("testing device=0x%x\n", device);
4639                 for (function=0;function<0x100;function++) {
4640                         uint32 code = (device<<16) | function;
4641
4642                         status = cli_raw_ioctl(cli, fnum, code, &blob);
4643
4644                         if (NT_STATUS_IS_OK(status)) {
4645                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4646                                        (int)blob.length);
4647                                 data_blob_free(&blob);
4648                         }
4649                 }
4650         }
4651
4652         if (!torture_close_connection(cli)) {
4653                 return False;
4654         }
4655
4656         return True;
4657 }
4658
4659
4660 /*
4661   tries varients of chkpath
4662  */
4663 bool torture_chkpath_test(int dummy)
4664 {
4665         static struct cli_state *cli;
4666         uint16_t fnum;
4667         bool ret;
4668
4669         if (!torture_open_connection(&cli, 0)) {
4670                 return False;
4671         }
4672
4673         printf("starting chkpath test\n");
4674
4675         /* cleanup from an old run */
4676         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4677         cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4678         cli_rmdir(cli, "\\chkpath.dir");
4679
4680         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4681                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4682                 return False;
4683         }
4684
4685         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4686                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4687                 return False;
4688         }
4689
4690         if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4691                 printf("open1 failed (%s)\n", cli_errstr(cli));
4692                 return False;
4693         }
4694         cli_close(cli, fnum);
4695
4696         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4697                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4698                 ret = False;
4699         }
4700
4701         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4702                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4703                 ret = False;
4704         }
4705
4706         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4707                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4708                                   NT_STATUS_NOT_A_DIRECTORY);
4709         } else {
4710                 printf("* chkpath on a file should fail\n");
4711                 ret = False;
4712         }
4713
4714         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4715                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
4716                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
4717         } else {
4718                 printf("* chkpath on a non existant file should fail\n");
4719                 ret = False;
4720         }
4721
4722         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4723                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4724                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
4725         } else {
4726                 printf("* chkpath on a non existent component should fail\n");
4727                 ret = False;
4728         }
4729
4730         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4731         cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4732         cli_rmdir(cli, "\\chkpath.dir");
4733
4734         if (!torture_close_connection(cli)) {
4735                 return False;
4736         }
4737
4738         return ret;
4739 }
4740
4741 static bool run_eatest(int dummy)
4742 {
4743         static struct cli_state *cli;
4744         const char *fname = "\\eatest.txt";
4745         bool correct = True;
4746         uint16_t fnum;
4747         int i;
4748         size_t num_eas;
4749         struct ea_struct *ea_list = NULL;
4750         TALLOC_CTX *mem_ctx = talloc_init("eatest");
4751
4752         printf("starting eatest\n");
4753
4754         if (!torture_open_connection(&cli, 0)) {
4755                 talloc_destroy(mem_ctx);
4756                 return False;
4757         }
4758
4759         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4760         if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
4761                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4762                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
4763                                    0x4044, 0, &fnum))) {
4764                 printf("open failed - %s\n", cli_errstr(cli));
4765                 talloc_destroy(mem_ctx);
4766                 return False;
4767         }
4768
4769         for (i = 0; i < 10; i++) {
4770                 fstring ea_name, ea_val;
4771
4772                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4773                 memset(ea_val, (char)i+1, i+1);
4774                 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4775                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4776                         talloc_destroy(mem_ctx);
4777                         return False;
4778                 }
4779         }
4780
4781         cli_close(cli, fnum);
4782         for (i = 0; i < 10; i++) {
4783                 fstring ea_name, ea_val;
4784
4785                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4786                 memset(ea_val, (char)i+1, i+1);
4787                 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4788                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4789                         talloc_destroy(mem_ctx);
4790                         return False;
4791                 }
4792         }
4793
4794         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4795                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4796                 correct = False;
4797         }
4798
4799         printf("num_eas = %d\n", (int)num_eas);
4800
4801         if (num_eas != 20) {
4802                 printf("Should be 20 EA's stored... failing.\n");
4803                 correct = False;
4804         }
4805
4806         for (i = 0; i < num_eas; i++) {
4807                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4808                 dump_data(0, ea_list[i].value.data,
4809                           ea_list[i].value.length);
4810         }
4811
4812         /* Setting EA's to zero length deletes them. Test this */
4813         printf("Now deleting all EA's - case indepenent....\n");
4814
4815 #if 1
4816         cli_set_ea_path(cli, fname, "", "", 0);
4817 #else
4818         for (i = 0; i < 20; i++) {
4819                 fstring ea_name;
4820                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4821                 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4822                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4823                         talloc_destroy(mem_ctx);
4824                         return False;
4825                 }
4826         }
4827 #endif
4828
4829         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4830                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4831                 correct = False;
4832         }
4833
4834         printf("num_eas = %d\n", (int)num_eas);
4835         for (i = 0; i < num_eas; i++) {
4836                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4837                 dump_data(0, ea_list[i].value.data,
4838                           ea_list[i].value.length);
4839         }
4840
4841         if (num_eas != 0) {
4842                 printf("deleting EA's failed.\n");
4843                 correct = False;
4844         }
4845
4846         /* Try and delete a non existant EA. */
4847         if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4848                 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4849                 correct = False;
4850         }
4851
4852         talloc_destroy(mem_ctx);
4853         if (!torture_close_connection(cli)) {
4854                 correct = False;
4855         }
4856
4857         return correct;
4858 }
4859
4860 static bool run_dirtest1(int dummy)
4861 {
4862         int i;
4863         static struct cli_state *cli;
4864         uint16_t fnum;
4865         int num_seen;
4866         bool correct = True;
4867
4868         printf("starting directory test\n");
4869
4870         if (!torture_open_connection(&cli, 0)) {
4871                 return False;
4872         }
4873
4874         cli_sockopt(cli, sockops);
4875
4876         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4877         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4878         cli_rmdir(cli, "\\LISTDIR");
4879         cli_mkdir(cli, "\\LISTDIR");
4880
4881         /* Create 1000 files and 1000 directories. */
4882         for (i=0;i<1000;i++) {
4883                 fstring fname;
4884                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4885                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4886                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
4887                         fprintf(stderr,"Failed to open %s\n", fname);
4888                         return False;
4889                 }
4890                 cli_close(cli, fnum);
4891         }
4892         for (i=0;i<1000;i++) {
4893                 fstring fname;
4894                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4895                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
4896                         fprintf(stderr,"Failed to open %s\n", fname);
4897                         return False;
4898                 }
4899         }
4900
4901         /* Now ensure that doing an old list sees both files and directories. */
4902         num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4903         printf("num_seen = %d\n", num_seen );
4904         /* We should see 100 files + 1000 directories + . and .. */
4905         if (num_seen != 2002)
4906                 correct = False;
4907
4908         /* Ensure if we have the "must have" bits we only see the
4909          * relevent entries.
4910          */
4911         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4912         printf("num_seen = %d\n", num_seen );
4913         if (num_seen != 1002)
4914                 correct = False;
4915
4916         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4917         printf("num_seen = %d\n", num_seen );
4918         if (num_seen != 1000)
4919                 correct = False;
4920
4921         /* Delete everything. */
4922         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4923         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4924         cli_rmdir(cli, "\\LISTDIR");
4925
4926 #if 0
4927         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4928         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4929         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4930 #endif
4931
4932         if (!torture_close_connection(cli)) {
4933                 correct = False;
4934         }
4935
4936         printf("finished dirtest1\n");
4937
4938         return correct;
4939 }
4940
4941 static bool run_error_map_extract(int dummy) {
4942
4943         static struct cli_state *c_dos;
4944         static struct cli_state *c_nt;
4945         NTSTATUS status;
4946
4947         uint32 error;
4948
4949         uint32 flgs2, errnum;
4950         uint8 errclass;
4951
4952         NTSTATUS nt_status;
4953
4954         fstring user;
4955
4956         /* NT-Error connection */
4957
4958         if (!(c_nt = open_nbt_connection())) {
4959                 return False;
4960         }
4961
4962         c_nt->use_spnego = False;
4963
4964         status = cli_negprot(c_nt);
4965
4966         if (!NT_STATUS_IS_OK(status)) {
4967                 printf("%s rejected the NT-error negprot (%s)\n", host,
4968                        nt_errstr(status));
4969                 cli_shutdown(c_nt);
4970                 return False;
4971         }
4972
4973         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4974                                                workgroup))) {
4975                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4976                 return False;
4977         }
4978
4979         /* DOS-Error connection */
4980
4981         if (!(c_dos = open_nbt_connection())) {
4982                 return False;
4983         }
4984
4985         c_dos->use_spnego = False;
4986         c_dos->force_dos_errors = True;
4987
4988         status = cli_negprot(c_dos);
4989         if (!NT_STATUS_IS_OK(status)) {
4990                 printf("%s rejected the DOS-error negprot (%s)\n", host,
4991                        nt_errstr(status));
4992                 cli_shutdown(c_dos);
4993                 return False;
4994         }
4995
4996         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4997                                                workgroup))) {
4998                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4999                 return False;
5000         }
5001
5002         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5003                 fstr_sprintf(user, "%X", error);
5004
5005                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
5006                                                       password, strlen(password),
5007                                                       password, strlen(password),
5008                                                       workgroup))) {
5009                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5010                 }
5011
5012                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5013
5014                 /* Case #1: 32-bit NT errors */
5015                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5016                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5017                 } else {
5018                         printf("/** Dos error on NT connection! (%s) */\n", 
5019                                cli_errstr(c_nt));
5020                         nt_status = NT_STATUS(0xc0000000);
5021                 }
5022
5023                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
5024                                                       password, strlen(password),
5025                                                       password, strlen(password),
5026                                                       workgroup))) {
5027                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5028                 }
5029                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5030
5031                 /* Case #1: 32-bit NT errors */
5032                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5033                         printf("/** NT error on DOS connection! (%s) */\n", 
5034                                cli_errstr(c_nt));
5035                         errnum = errclass = 0;
5036                 } else {
5037                         cli_dos_error(c_dos, &errclass, &errnum);
5038                 }
5039
5040                 if (NT_STATUS_V(nt_status) != error) { 
5041                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
5042                                get_nt_error_c_code(NT_STATUS(error)), 
5043                                get_nt_error_c_code(nt_status));
5044                 }
5045
5046                 printf("\t{%s,\t%s,\t%s},\n", 
5047                        smb_dos_err_class(errclass), 
5048                        smb_dos_err_name(errclass, errnum), 
5049                        get_nt_error_c_code(NT_STATUS(error)));
5050         }
5051         return True;
5052 }
5053
5054 static bool run_sesssetup_bench(int dummy)
5055 {
5056         static struct cli_state *c;
5057         const char *fname = "\\file.dat";
5058         uint16_t fnum;
5059         NTSTATUS status;
5060         int i;
5061
5062         if (!torture_open_connection(&c, 0)) {
5063                 return false;
5064         }
5065
5066         if (!NT_STATUS_IS_OK(cli_ntcreate(
5067                         c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5068                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5069                         FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5070                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5071                 return false;
5072         }
5073
5074         for (i=0; i<torture_numops; i++) {
5075                 status = cli_session_setup(
5076                         c, username,
5077                         password, strlen(password),
5078                         password, strlen(password),
5079                         workgroup);
5080                 if (!NT_STATUS_IS_OK(status)) {
5081                         d_printf("(%s) cli_session_setup failed: %s\n",
5082                                  __location__, nt_errstr(status));
5083                         return false;
5084                 }
5085
5086                 d_printf("\r%d   ", (int)c->vuid);
5087
5088                 if (!cli_ulogoff(c)) {
5089                         d_printf("(%s) cli_ulogoff failed: %s\n",
5090                                  __location__, cli_errstr(c));
5091                         return false;
5092                 }
5093                 c->vuid = 0;
5094         }
5095
5096         return true;
5097 }
5098
5099 static bool subst_test(const char *str, const char *user, const char *domain,
5100                        uid_t uid, gid_t gid, const char *expected)
5101 {
5102         char *subst;
5103         bool result = true;
5104
5105         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5106
5107         if (strcmp(subst, expected) != 0) {
5108                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5109                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5110                        expected);
5111                 result = false;
5112         }
5113
5114         TALLOC_FREE(subst);
5115         return result;
5116 }
5117
5118 static void chain1_open_completion(struct tevent_req *req)
5119 {
5120         uint16_t fnum;
5121         NTSTATUS status;
5122         status = cli_open_recv(req, &fnum);
5123         TALLOC_FREE(req);
5124
5125         d_printf("cli_open_recv returned %s: %d\n",
5126                  nt_errstr(status),
5127                  NT_STATUS_IS_OK(status) ? fnum : -1);
5128 }
5129
5130 static void chain1_write_completion(struct tevent_req *req)
5131 {
5132         size_t written;
5133         NTSTATUS status;
5134         status = cli_write_andx_recv(req, &written);
5135         TALLOC_FREE(req);
5136
5137         d_printf("cli_write_andx_recv returned %s: %d\n",
5138                  nt_errstr(status),
5139                  NT_STATUS_IS_OK(status) ? (int)written : -1);
5140 }
5141
5142 static void chain1_close_completion(struct tevent_req *req)
5143 {
5144         NTSTATUS status;
5145         bool *done = (bool *)tevent_req_callback_data_void(req);
5146
5147         status = cli_close_recv(req);
5148         *done = true;
5149
5150         TALLOC_FREE(req);
5151
5152         d_printf("cli_close returned %s\n", nt_errstr(status));
5153 }
5154
5155 static bool run_chain1(int dummy)
5156 {
5157         struct cli_state *cli1;
5158         struct event_context *evt = event_context_init(NULL);
5159         struct tevent_req *reqs[3], *smbreqs[3];
5160         bool done = false;
5161         const char *str = "foobar";
5162         NTSTATUS status;
5163
5164         printf("starting chain1 test\n");
5165         if (!torture_open_connection(&cli1, 0)) {
5166                 return False;
5167         }
5168
5169         cli_sockopt(cli1, sockops);
5170
5171         reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5172                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
5173         if (reqs[0] == NULL) return false;
5174         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5175
5176
5177         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5178                                         (uint8_t *)str, 0, strlen(str)+1,
5179                                         smbreqs, 1, &smbreqs[1]);
5180         if (reqs[1] == NULL) return false;
5181         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5182
5183         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5184         if (reqs[2] == NULL) return false;
5185         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5186
5187         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5188         if (!NT_STATUS_IS_OK(status)) {
5189                 return false;
5190         }
5191
5192         while (!done) {
5193                 event_loop_once(evt);
5194         }
5195
5196         torture_close_connection(cli1);
5197         return True;
5198 }
5199
5200 static void chain2_sesssetup_completion(struct tevent_req *req)
5201 {
5202         NTSTATUS status;
5203         status = cli_session_setup_guest_recv(req);
5204         d_printf("sesssetup returned %s\n", nt_errstr(status));
5205 }
5206
5207 static void chain2_tcon_completion(struct tevent_req *req)
5208 {
5209         bool *done = (bool *)tevent_req_callback_data_void(req);
5210         NTSTATUS status;
5211         status = cli_tcon_andx_recv(req);
5212         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5213         *done = true;
5214 }
5215
5216 static bool run_chain2(int dummy)
5217 {
5218         struct cli_state *cli1;
5219         struct event_context *evt = event_context_init(NULL);
5220         struct tevent_req *reqs[2], *smbreqs[2];
5221         bool done = false;
5222         NTSTATUS status;
5223
5224         printf("starting chain2 test\n");
5225         status = cli_start_connection(&cli1, global_myname(), host, NULL,
5226                                       port_to_use, Undefined, 0, NULL);
5227         if (!NT_STATUS_IS_OK(status)) {
5228                 return False;
5229         }
5230
5231         cli_sockopt(cli1, sockops);
5232
5233         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5234                                                  &smbreqs[0]);
5235         if (reqs[0] == NULL) return false;
5236         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5237
5238         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5239                                        "?????", NULL, 0, &smbreqs[1]);
5240         if (reqs[1] == NULL) return false;
5241         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5242
5243         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5244         if (!NT_STATUS_IS_OK(status)) {
5245                 return false;
5246         }
5247
5248         while (!done) {
5249                 event_loop_once(evt);
5250         }
5251
5252         torture_close_connection(cli1);
5253         return True;
5254 }
5255
5256 static bool run_mangle1(int dummy)
5257 {
5258         struct cli_state *cli;
5259         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5260         uint16_t fnum;
5261         fstring alt_name;
5262         NTSTATUS status;
5263         time_t change_time, access_time, write_time;
5264         SMB_OFF_T size;
5265         uint16_t mode;
5266
5267         printf("starting mangle1 test\n");
5268         if (!torture_open_connection(&cli, 0)) {
5269                 return False;
5270         }
5271
5272         cli_sockopt(cli, sockops);
5273
5274         if (!NT_STATUS_IS_OK(cli_ntcreate(
5275                         cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5276                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5277                 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5278                 return false;
5279         }
5280         cli_close(cli, fnum);
5281
5282         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5283         if (!NT_STATUS_IS_OK(status)) {
5284                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5285                          nt_errstr(status));
5286                 return false;
5287         }
5288         d_printf("alt_name: %s\n", alt_name);
5289
5290         if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5291                 d_printf("cli_open(%s) failed: %s\n", alt_name,
5292                          cli_errstr(cli));
5293                 return false;
5294         }
5295         cli_close(cli, fnum);
5296
5297         if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5298                            &write_time, &size, &mode)) {
5299                 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5300                          cli_errstr(cli));
5301                 return false;
5302         }
5303
5304         return true;
5305 }
5306
5307 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5308 {
5309         size_t *to_pull = (size_t *)priv;
5310         size_t thistime = *to_pull;
5311
5312         thistime = MIN(thistime, n);
5313         if (thistime == 0) {
5314                 return 0;
5315         }
5316
5317         memset(buf, 0, thistime);
5318         *to_pull -= thistime;
5319         return thistime;
5320 }
5321
5322 static bool run_windows_write(int dummy)
5323 {
5324         struct cli_state *cli1;
5325         uint16_t fnum;
5326         int i;
5327         bool ret = false;
5328         const char *fname = "\\writetest.txt";
5329         double seconds;
5330         double kbytes;
5331
5332         printf("starting windows_write test\n");
5333         if (!torture_open_connection(&cli1, 0)) {
5334                 return False;
5335         }
5336
5337         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5338                 printf("open failed (%s)\n", cli_errstr(cli1));
5339                 return False;
5340         }
5341
5342         cli_sockopt(cli1, sockops);
5343
5344         start_timer();
5345
5346         for (i=0; i<torture_numops; i++) {
5347                 char c = 0;
5348                 off_t start = i * torture_blocksize;
5349                 NTSTATUS status;
5350                 size_t to_pull = torture_blocksize - 1;
5351
5352                 if (cli_write(cli1, fnum, 0, &c,
5353                               start + torture_blocksize - 1, 1) != 1) {
5354                         printf("cli_write failed: %s\n", cli_errstr(cli1));
5355                         goto fail;
5356                 }
5357
5358                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5359                                   null_source, &to_pull);
5360                 if (!NT_STATUS_IS_OK(status)) {
5361                         printf("cli_push returned: %s\n", nt_errstr(status));
5362                         goto fail;
5363                 }
5364         }
5365
5366         seconds = end_timer();
5367         kbytes = (double)torture_blocksize * torture_numops;
5368         kbytes /= 1024;
5369
5370         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5371                (double)seconds, (int)(kbytes/seconds));
5372
5373         ret = true;
5374  fail:
5375         cli_close(cli1, fnum);
5376         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5377         torture_close_connection(cli1);
5378         return ret;
5379 }
5380
5381 static bool run_cli_echo(int dummy)
5382 {
5383         struct cli_state *cli;
5384         NTSTATUS status;
5385
5386         printf("starting cli_echo test\n");
5387         if (!torture_open_connection(&cli, 0)) {
5388                 return false;
5389         }
5390         cli_sockopt(cli, sockops);
5391
5392         status = cli_echo(cli, 5, data_blob_const("hello", 5));
5393
5394         d_printf("cli_echo returned %s\n", nt_errstr(status));
5395
5396         torture_close_connection(cli);
5397         return NT_STATUS_IS_OK(status);
5398 }
5399
5400 static bool run_uid_regression_test(int dummy)
5401 {
5402         static struct cli_state *cli;
5403         int16_t old_vuid;
5404         int16_t old_cnum;
5405         bool correct = True;
5406
5407         printf("starting uid regression test\n");
5408
5409         if (!torture_open_connection(&cli, 0)) {
5410                 return False;
5411         }
5412
5413         cli_sockopt(cli, sockops);
5414
5415         /* Ok - now save then logoff our current user. */
5416         old_vuid = cli->vuid;
5417
5418         if (!cli_ulogoff(cli)) {
5419                 d_printf("(%s) cli_ulogoff failed: %s\n",
5420                         __location__, cli_errstr(cli));
5421                 correct = false;
5422                 goto out;
5423         }
5424
5425         cli->vuid = old_vuid;
5426
5427         /* Try an operation. */
5428         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
5429                 /* We expect bad uid. */
5430                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5431                                 NT_STATUS_NO_SUCH_USER)) {
5432                         return False;
5433                 }
5434         }
5435
5436         old_cnum = cli->cnum;
5437
5438         /* Now try a SMBtdis with the invald vuid set to zero. */
5439         cli->vuid = 0;
5440
5441         /* This should succeed. */
5442         if (cli_tdis(cli)) {
5443                 printf("First tdis with invalid vuid should succeed.\n");
5444         } else {
5445                 printf("First tdis failed (%s)\n", cli_errstr(cli));
5446         }
5447
5448         cli->vuid = old_vuid;
5449         cli->cnum = old_cnum;
5450
5451         /* This should fail. */
5452         if (cli_tdis(cli)) {
5453                 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
5454         } else {
5455                 /* Should be bad tid. */
5456                 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
5457                                 NT_STATUS_NETWORK_NAME_DELETED)) {
5458                         return False;
5459                 }
5460         }
5461
5462         cli_rmdir(cli, "\\uid_reg_test");
5463
5464   out:
5465
5466         cli_shutdown(cli);
5467         return correct;
5468 }
5469
5470
5471 static const char *illegal_chars = "*\\/?<>|\":";
5472 static char force_shortname_chars[] = " +,.[];=\177";
5473
5474 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
5475 {
5476         struct cli_state *pcli = (struct cli_state *)state;
5477         fstring fname;
5478         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
5479
5480         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5481                 return;
5482
5483         if (finfo->mode & aDIR) {
5484                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5485                         printf("del_fn: failed to rmdir %s\n,", fname );
5486         } else {
5487                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5488                         printf("del_fn: failed to unlink %s\n,", fname );
5489         }
5490 }
5491
5492 struct sn_state {
5493         int i;
5494         bool val;
5495 };
5496
5497 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
5498 {
5499         struct sn_state *s = (struct sn_state  *)state;
5500         int i = s->i;
5501
5502 #if 0
5503         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
5504                 i, finfo->name, finfo->short_name);
5505 #endif
5506
5507         if (strchr(force_shortname_chars, i)) {
5508                 if (!finfo->short_name[0]) {
5509                         /* Shortname not created when it should be. */
5510                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
5511                                 __location__, finfo->name, i);
5512                         s->val = true;
5513                 }
5514         } else if (finfo->short_name[0]){
5515                 /* Shortname created when it should not be. */
5516                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
5517                         __location__, finfo->short_name, finfo->name);
5518                 s->val = true;
5519         }
5520 }
5521
5522 static bool run_shortname_test(int dummy)
5523 {
5524         static struct cli_state *cli;
5525         bool correct = True;
5526         int i;
5527         struct sn_state s;
5528         char fname[20];
5529
5530         printf("starting shortname test\n");
5531
5532         if (!torture_open_connection(&cli, 0)) {
5533                 return False;
5534         }
5535
5536         cli_sockopt(cli, sockops);
5537
5538         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5539         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5540         cli_rmdir(cli, "\\shortname");
5541
5542         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
5543                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
5544                         __location__, cli_errstr(cli));
5545                 correct = false;
5546                 goto out;
5547         }
5548
5549         strlcpy(fname, "\\shortname\\", sizeof(fname));
5550         strlcat(fname, "test .txt", sizeof(fname));
5551
5552         s.val = false;
5553
5554         for (i = 32; i < 128; i++) {
5555                 NTSTATUS status;
5556                 uint16_t fnum = (uint16_t)-1;
5557
5558                 s.i = i;
5559
5560                 if (strchr(illegal_chars, i)) {
5561                         continue;
5562                 }
5563                 fname[15] = i;
5564
5565                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
5566                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
5567                 if (!NT_STATUS_IS_OK(status)) {
5568                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
5569                                 __location__, fname, cli_errstr(cli));
5570                         correct = false;
5571                         goto out;
5572                 }
5573                 cli_close(cli, fnum);
5574                 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
5575                         d_printf("(%s) failed to list %s: %s\n",
5576                                 __location__, fname, cli_errstr(cli));
5577                         correct = false;
5578                         goto out;
5579                 }
5580                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
5581                         d_printf("(%s) failed to delete %s: %s\n",
5582                                 __location__, fname, cli_errstr(cli));
5583                         correct = false;
5584                         goto out;
5585                 }
5586
5587                 if (s.val) {
5588                         correct = false;
5589                         goto out;
5590                 }
5591         }
5592
5593   out:
5594
5595         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5596         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5597         cli_rmdir(cli, "\\shortname");
5598         torture_close_connection(cli);
5599         return correct;
5600 }
5601
5602 static void pagedsearch_cb(struct tevent_req *req)
5603 {
5604         int rc;
5605         struct tldap_message *msg;
5606         char *dn;
5607
5608         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
5609         if (rc != TLDAP_SUCCESS) {
5610                 d_printf("tldap_search_paged_recv failed: %s\n",
5611                          tldap_err2string(rc));
5612                 return;
5613         }
5614         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
5615                 TALLOC_FREE(msg);
5616                 return;
5617         }
5618         if (!tldap_entry_dn(msg, &dn)) {
5619                 d_printf("tldap_entry_dn failed\n");
5620                 return;
5621         }
5622         d_printf("%s\n", dn);
5623         TALLOC_FREE(msg);
5624 }
5625
5626 static bool run_tldap(int dummy)
5627 {
5628         struct tldap_context *ld;
5629         int fd, rc;
5630         NTSTATUS status;
5631         struct sockaddr_storage addr;
5632         struct tevent_context *ev;
5633         struct tevent_req *req;
5634         char *basedn;
5635
5636         if (!resolve_name(host, &addr, 0, false)) {
5637                 d_printf("could not find host %s\n", host);
5638                 return false;
5639         }
5640         status = open_socket_out(&addr, 389, 9999, &fd);
5641         if (!NT_STATUS_IS_OK(status)) {
5642                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
5643                 return false;
5644         }
5645
5646         ld = tldap_context_create(talloc_tos(), fd);
5647         if (ld == NULL) {
5648                 close(fd);
5649                 d_printf("tldap_context_create failed\n");
5650                 return false;
5651         }
5652
5653         rc = tldap_fetch_rootdse(ld);
5654         if (rc != TLDAP_SUCCESS) {
5655                 d_printf("tldap_fetch_rootdse failed: %s\n",
5656                          tldap_errstr(talloc_tos(), ld, rc));
5657                 return false;
5658         }
5659
5660         basedn = tldap_talloc_single_attribute(
5661                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
5662         if (basedn == NULL) {
5663                 d_printf("no defaultNamingContext\n");
5664                 return false;
5665         }
5666         d_printf("defaultNamingContext: %s\n", basedn);
5667
5668         ev = tevent_context_init(talloc_tos());
5669         if (ev == NULL) {
5670                 d_printf("tevent_context_init failed\n");
5671                 return false;
5672         }
5673
5674         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
5675                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
5676                                       NULL, 0, 0,
5677                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
5678         if (req == NULL) {
5679                 d_printf("tldap_search_paged_send failed\n");
5680                 return false;
5681         }
5682         tevent_req_set_callback(req, pagedsearch_cb, NULL);
5683
5684         tevent_req_poll(req, ev);
5685
5686         TALLOC_FREE(req);
5687
5688         TALLOC_FREE(ld);
5689         return true;
5690 }
5691
5692 static bool run_streamerror(int dummy)
5693 {
5694         struct cli_state *cli;
5695         const char *dname = "\\testdir";
5696         const char *streamname =
5697                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
5698         NTSTATUS status;
5699         time_t change_time, access_time, write_time;
5700         SMB_OFF_T size;
5701         uint16_t mode, fnum;
5702         bool ret = true;
5703
5704         if (!torture_open_connection(&cli, 0)) {
5705                 return false;
5706         }
5707
5708         cli_rmdir(cli, dname);
5709
5710         status = cli_mkdir(cli, dname);
5711         if (!NT_STATUS_IS_OK(status)) {
5712                 printf("mkdir failed: %s\n", nt_errstr(status));
5713                 return false;
5714         }
5715
5716         cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
5717                       &size, &mode);
5718         status = cli_nt_error(cli);
5719
5720         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5721                 printf("pathinfo returned %s, expected "
5722                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5723                        nt_errstr(status));
5724                 ret = false;
5725         }
5726
5727         status = cli_ntcreate(cli, streamname, 0x16,
5728                               FILE_READ_DATA|FILE_READ_EA|
5729                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
5730                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5731                               FILE_OPEN, 0, 0, &fnum);
5732
5733         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5734                 printf("ntcreate returned %s, expected "
5735                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5736                        nt_errstr(status));
5737                 ret = false;
5738         }
5739
5740
5741         cli_rmdir(cli, dname);
5742         return ret;
5743 }
5744
5745 static bool run_local_substitute(int dummy)
5746 {
5747         bool ok = true;
5748
5749         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5750         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5751         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5752         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5753         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5754         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5755         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5756         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5757
5758         /* Different captialization rules in sub_basic... */
5759
5760         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5761                        "blaDOM") == 0);
5762
5763         return ok;
5764 }
5765
5766 static bool run_local_base64(int dummy)
5767 {
5768         int i;
5769         bool ret = true;
5770
5771         for (i=1; i<2000; i++) {
5772                 DATA_BLOB blob1, blob2;
5773                 char *b64;
5774
5775                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
5776                 blob1.length = i;
5777                 generate_random_buffer(blob1.data, blob1.length);
5778
5779                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
5780                 if (b64 == NULL) {
5781                         d_fprintf(stderr, "base64_encode_data_blob failed "
5782                                   "for %d bytes\n", i);
5783                         ret = false;
5784                 }
5785                 blob2 = base64_decode_data_blob(b64);
5786                 TALLOC_FREE(b64);
5787
5788                 if (data_blob_cmp(&blob1, &blob2)) {
5789                         d_fprintf(stderr, "data_blob_cmp failed for %d "
5790                                   "bytes\n", i);
5791                         ret = false;
5792                 }
5793                 TALLOC_FREE(blob1.data);
5794                 data_blob_free(&blob2);
5795         }
5796         return ret;
5797 }
5798
5799 static bool run_local_gencache(int dummy)
5800 {
5801         char *val;
5802         time_t tm;
5803         DATA_BLOB blob;
5804
5805         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5806                 d_printf("%s: gencache_set() failed\n", __location__);
5807                 return False;
5808         }
5809
5810         if (!gencache_get("foo", &val, &tm)) {
5811                 d_printf("%s: gencache_get() failed\n", __location__);
5812                 return False;
5813         }
5814
5815         if (strcmp(val, "bar") != 0) {
5816                 d_printf("%s: gencache_get() returned %s, expected %s\n",
5817                          __location__, val, "bar");
5818                 SAFE_FREE(val);
5819                 return False;
5820         }
5821
5822         SAFE_FREE(val);
5823
5824         if (!gencache_del("foo")) {
5825                 d_printf("%s: gencache_del() failed\n", __location__);
5826                 return False;
5827         }
5828         if (gencache_del("foo")) {
5829                 d_printf("%s: second gencache_del() succeeded\n",
5830                          __location__);
5831                 return False;
5832         }
5833
5834         if (gencache_get("foo", &val, &tm)) {
5835                 d_printf("%s: gencache_get() on deleted entry "
5836                          "succeeded\n", __location__);
5837                 return False;
5838         }
5839
5840         blob = data_blob_string_const_null("bar");
5841         tm = time(NULL) + 60;
5842
5843         if (!gencache_set_data_blob("foo", &blob, tm)) {
5844                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5845                 return False;
5846         }
5847
5848         if (!gencache_get_data_blob("foo", &blob, NULL)) {
5849                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5850                 return False;
5851         }
5852
5853         if (strcmp((const char *)blob.data, "bar") != 0) {
5854                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5855                          __location__, (const char *)blob.data, "bar");
5856                 data_blob_free(&blob);
5857                 return False;
5858         }
5859
5860         data_blob_free(&blob);
5861
5862         if (!gencache_del("foo")) {
5863                 d_printf("%s: gencache_del() failed\n", __location__);
5864                 return False;
5865         }
5866         if (gencache_del("foo")) {
5867                 d_printf("%s: second gencache_del() succeeded\n",
5868                          __location__);
5869                 return False;
5870         }
5871
5872         if (gencache_get_data_blob("foo", &blob, NULL)) {
5873                 d_printf("%s: gencache_get_data_blob() on deleted entry "
5874                          "succeeded\n", __location__);
5875                 return False;
5876         }
5877
5878         return True;
5879 }
5880
5881 static bool rbt_testval(struct db_context *db, const char *key,
5882                         const char *value)
5883 {
5884         struct db_record *rec;
5885         TDB_DATA data = string_tdb_data(value);
5886         bool ret = false;
5887         NTSTATUS status;
5888
5889         rec = db->fetch_locked(db, db, string_tdb_data(key));
5890         if (rec == NULL) {
5891                 d_fprintf(stderr, "fetch_locked failed\n");
5892                 goto done;
5893         }
5894         status = rec->store(rec, data, 0);
5895         if (!NT_STATUS_IS_OK(status)) {
5896                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5897                 goto done;
5898         }
5899         TALLOC_FREE(rec);
5900
5901         rec = db->fetch_locked(db, db, string_tdb_data(key));
5902         if (rec == NULL) {
5903                 d_fprintf(stderr, "second fetch_locked failed\n");
5904                 goto done;
5905         }
5906         if ((rec->value.dsize != data.dsize)
5907             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5908                 d_fprintf(stderr, "Got wrong data back\n");
5909                 goto done;
5910         }
5911
5912         ret = true;
5913  done:
5914         TALLOC_FREE(rec);
5915         return ret;
5916 }
5917
5918 static bool run_local_rbtree(int dummy)
5919 {
5920         struct db_context *db;
5921         bool ret = false;
5922         int i;
5923
5924         db = db_open_rbt(NULL);
5925
5926         if (db == NULL) {
5927                 d_fprintf(stderr, "db_open_rbt failed\n");
5928                 return false;
5929         }
5930
5931         for (i=0; i<1000; i++) {
5932                 char *key, *value;
5933
5934                 if (asprintf(&key, "key%ld", random()) == -1) {
5935                         goto done;
5936                 }
5937                 if (asprintf(&value, "value%ld", random()) == -1) {
5938                         SAFE_FREE(key);
5939                         goto done;
5940                 }
5941
5942                 if (!rbt_testval(db, key, value)) {
5943                         SAFE_FREE(key);
5944                         SAFE_FREE(value);
5945                         goto done;
5946                 }
5947
5948                 SAFE_FREE(value);
5949                 if (asprintf(&value, "value%ld", random()) == -1) {
5950                         SAFE_FREE(key);
5951                         goto done;
5952                 }
5953
5954                 if (!rbt_testval(db, key, value)) {
5955                         SAFE_FREE(key);
5956                         SAFE_FREE(value);
5957                         goto done;
5958                 }
5959
5960                 SAFE_FREE(key);
5961                 SAFE_FREE(value);
5962         }
5963
5964         ret = true;
5965
5966  done:
5967         TALLOC_FREE(db);
5968         return ret;
5969 }
5970
5971 struct talloc_dict_test {
5972         int content;
5973 };
5974
5975 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
5976 {
5977         int *count = (int *)priv;
5978         *count += 1;
5979         return 0;
5980 }
5981
5982 static bool run_local_talloc_dict(int dummy)
5983 {
5984         struct talloc_dict *dict;
5985         struct talloc_dict_test *t;
5986         int key, count;
5987
5988         dict = talloc_dict_init(talloc_tos());
5989         if (dict == NULL) {
5990                 return false;
5991         }
5992
5993         t = talloc(talloc_tos(), struct talloc_dict_test);
5994         if (t == NULL) {
5995                 return false;
5996         }
5997
5998         key = 1;
5999         t->content = 1;
6000         if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6001                 return false;
6002         }
6003
6004         count = 0;
6005         if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6006                 return false;
6007         }
6008
6009         if (count != 1) {
6010                 return false;
6011         }
6012
6013         TALLOC_FREE(dict);
6014
6015         return true;
6016 }
6017
6018 /* Split a path name into filename and stream name components. Canonicalise
6019  * such that an implicit $DATA token is always explicit.
6020  *
6021  * The "specification" of this function can be found in the
6022  * run_local_stream_name() function in torture.c, I've tried those
6023  * combinations against a W2k3 server.
6024  */
6025
6026 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6027                                        char **pbase, char **pstream)
6028 {
6029         char *base = NULL;
6030         char *stream = NULL;
6031         char *sname; /* stream name */
6032         const char *stype; /* stream type */
6033
6034         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6035
6036         sname = strchr_m(fname, ':');
6037
6038         if (lp_posix_pathnames() || (sname == NULL)) {
6039                 if (pbase != NULL) {
6040                         base = talloc_strdup(mem_ctx, fname);
6041                         NT_STATUS_HAVE_NO_MEMORY(base);
6042                 }
6043                 goto done;
6044         }
6045
6046         if (pbase != NULL) {
6047                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6048                 NT_STATUS_HAVE_NO_MEMORY(base);
6049         }
6050
6051         sname += 1;
6052
6053         stype = strchr_m(sname, ':');
6054
6055         if (stype == NULL) {
6056                 sname = talloc_strdup(mem_ctx, sname);
6057                 stype = "$DATA";
6058         }
6059         else {
6060                 if (StrCaseCmp(stype, ":$DATA") != 0) {
6061                         /*
6062                          * If there is an explicit stream type, so far we only
6063                          * allow $DATA. Is there anything else allowed? -- vl
6064                          */
6065                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6066                         TALLOC_FREE(base);
6067                         return NT_STATUS_OBJECT_NAME_INVALID;
6068                 }
6069                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6070                 stype += 1;
6071         }
6072
6073         if (sname == NULL) {
6074                 TALLOC_FREE(base);
6075                 return NT_STATUS_NO_MEMORY;
6076         }
6077
6078         if (sname[0] == '\0') {
6079                 /*
6080                  * no stream name, so no stream
6081                  */
6082                 goto done;
6083         }
6084
6085         if (pstream != NULL) {
6086                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6087                 if (stream == NULL) {
6088                         TALLOC_FREE(sname);
6089                         TALLOC_FREE(base);
6090                         return NT_STATUS_NO_MEMORY;
6091                 }
6092                 /*
6093                  * upper-case the type field
6094                  */
6095                 strupper_m(strchr_m(stream, ':')+1);
6096         }
6097
6098  done:
6099         if (pbase != NULL) {
6100                 *pbase = base;
6101         }
6102         if (pstream != NULL) {
6103                 *pstream = stream;
6104         }
6105         return NT_STATUS_OK;
6106 }
6107
6108 static bool test_stream_name(const char *fname, const char *expected_base,
6109                              const char *expected_stream,
6110                              NTSTATUS expected_status)
6111 {
6112         NTSTATUS status;
6113         char *base = NULL;
6114         char *stream = NULL;
6115
6116         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6117         if (!NT_STATUS_EQUAL(status, expected_status)) {
6118                 goto error;
6119         }
6120
6121         if (!NT_STATUS_IS_OK(status)) {
6122                 return true;
6123         }
6124
6125         if (base == NULL) goto error;
6126
6127         if (strcmp(expected_base, base) != 0) goto error;
6128
6129         if ((expected_stream != NULL) && (stream == NULL)) goto error;
6130         if ((expected_stream == NULL) && (stream != NULL)) goto error;
6131
6132         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6133                 goto error;
6134
6135         TALLOC_FREE(base);
6136         TALLOC_FREE(stream);
6137         return true;
6138
6139  error:
6140         d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6141                   fname, expected_base ? expected_base : "<NULL>",
6142                   expected_stream ? expected_stream : "<NULL>",
6143                   nt_errstr(expected_status));
6144         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6145                   base ? base : "<NULL>", stream ? stream : "<NULL>",
6146                   nt_errstr(status));
6147         TALLOC_FREE(base);
6148         TALLOC_FREE(stream);
6149         return false;
6150 }
6151
6152 static bool run_local_stream_name(int dummy)
6153 {
6154         bool ret = true;
6155
6156         ret &= test_stream_name(
6157                 "bla", "bla", NULL, NT_STATUS_OK);
6158         ret &= test_stream_name(
6159                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6160         ret &= test_stream_name(
6161                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6162         ret &= test_stream_name(
6163                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6164         ret &= test_stream_name(
6165                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6166         ret &= test_stream_name(
6167                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6168         ret &= test_stream_name(
6169                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6170         ret &= test_stream_name(
6171                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6172
6173         return ret;
6174 }
6175
6176 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6177 {
6178         if (a.length != b.length) {
6179                 printf("a.length=%d != b.length=%d\n",
6180                        (int)a.length, (int)b.length);
6181                 return false;
6182         }
6183         if (memcmp(a.data, b.data, a.length) != 0) {
6184                 printf("a.data and b.data differ\n");
6185                 return false;
6186         }
6187         return true;
6188 }
6189
6190 static bool run_local_memcache(int dummy)
6191 {
6192         struct memcache *cache;
6193         DATA_BLOB k1, k2;
6194         DATA_BLOB d1, d2, d3;
6195         DATA_BLOB v1, v2, v3;
6196
6197         TALLOC_CTX *mem_ctx;
6198         char *str1, *str2;
6199         size_t size1, size2;
6200         bool ret = false;
6201
6202         cache = memcache_init(NULL, 100);
6203
6204         if (cache == NULL) {
6205                 printf("memcache_init failed\n");
6206                 return false;
6207         }
6208
6209         d1 = data_blob_const("d1", 2);
6210         d2 = data_blob_const("d2", 2);
6211         d3 = data_blob_const("d3", 2);
6212
6213         k1 = data_blob_const("d1", 2);
6214         k2 = data_blob_const("d2", 2);
6215
6216         memcache_add(cache, STAT_CACHE, k1, d1);
6217         memcache_add(cache, GETWD_CACHE, k2, d2);
6218
6219         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6220                 printf("could not find k1\n");
6221                 return false;
6222         }
6223         if (!data_blob_equal(d1, v1)) {
6224                 return false;
6225         }
6226
6227         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6228                 printf("could not find k2\n");
6229                 return false;
6230         }
6231         if (!data_blob_equal(d2, v2)) {
6232                 return false;
6233         }
6234
6235         memcache_add(cache, STAT_CACHE, k1, d3);
6236
6237         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
6238                 printf("could not find replaced k1\n");
6239                 return false;
6240         }
6241         if (!data_blob_equal(d3, v3)) {
6242                 return false;
6243         }
6244
6245         memcache_add(cache, GETWD_CACHE, k1, d1);
6246
6247         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6248                 printf("Did find k2, should have been purged\n");
6249                 return false;
6250         }
6251
6252         TALLOC_FREE(cache);
6253
6254         cache = memcache_init(NULL, 0);
6255
6256         mem_ctx = talloc_init("foo");
6257
6258         str1 = talloc_strdup(mem_ctx, "string1");
6259         str2 = talloc_strdup(mem_ctx, "string2");
6260
6261         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6262                             data_blob_string_const("torture"), &str1);
6263         size1 = talloc_total_size(cache);
6264
6265         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6266                             data_blob_string_const("torture"), &str2);
6267         size2 = talloc_total_size(cache);
6268
6269         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
6270
6271         if (size2 > size1) {
6272                 printf("memcache leaks memory!\n");
6273                 goto fail;
6274         }
6275
6276         ret = true;
6277  fail:
6278         TALLOC_FREE(cache);
6279         return ret;
6280 }
6281
6282 static void wbclient_done(struct tevent_req *req)
6283 {
6284         wbcErr wbc_err;
6285         struct winbindd_response *wb_resp;
6286         int *i = (int *)tevent_req_callback_data_void(req);
6287
6288         wbc_err = wb_trans_recv(req, req, &wb_resp);
6289         TALLOC_FREE(req);
6290         *i += 1;
6291         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
6292 }
6293
6294 static bool run_local_wbclient(int dummy)
6295 {
6296         struct event_context *ev;
6297         struct wb_context **wb_ctx;
6298         struct winbindd_request wb_req;
6299         bool result = false;
6300         int i, j;
6301
6302         BlockSignals(True, SIGPIPE);
6303
6304         ev = tevent_context_init_byname(talloc_tos(), "epoll");
6305         if (ev == NULL) {
6306                 goto fail;
6307         }
6308
6309         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
6310         if (wb_ctx == NULL) {
6311                 goto fail;
6312         }
6313
6314         ZERO_STRUCT(wb_req);
6315         wb_req.cmd = WINBINDD_PING;
6316
6317         d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
6318
6319         for (i=0; i<nprocs; i++) {
6320                 wb_ctx[i] = wb_context_init(ev, NULL);
6321                 if (wb_ctx[i] == NULL) {
6322                         goto fail;
6323                 }
6324                 for (j=0; j<torture_numops; j++) {
6325                         struct tevent_req *req;
6326                         req = wb_trans_send(ev, ev, wb_ctx[i],
6327                                             (j % 2) == 0, &wb_req);
6328                         if (req == NULL) {
6329                                 goto fail;
6330                         }
6331                         tevent_req_set_callback(req, wbclient_done, &i);
6332                 }
6333         }
6334
6335         i = 0;
6336
6337         while (i < nprocs * torture_numops) {
6338                 event_loop_once(ev);
6339         }
6340
6341         result = true;
6342  fail:
6343         TALLOC_FREE(ev);
6344         return result;
6345 }
6346
6347 static void getaddrinfo_finished(struct tevent_req *req)
6348 {
6349         char *name = (char *)tevent_req_callback_data_void(req);
6350         struct addrinfo *ainfo;
6351         int res;
6352
6353         res = getaddrinfo_recv(req, &ainfo);
6354         if (res != 0) {
6355                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
6356                 return;
6357         }
6358         d_printf("gai(%s) succeeded\n", name);
6359         freeaddrinfo(ainfo);
6360 }
6361
6362 static bool run_getaddrinfo_send(int dummy)
6363 {
6364         TALLOC_CTX *frame = talloc_stackframe();
6365         struct fncall_context *ctx;
6366         struct tevent_context *ev;
6367         bool result = false;
6368         const char *names[4] = { "www.samba.org", "notfound.samba.org",
6369                                  "www.slashdot.org", "heise.de" };
6370         struct tevent_req *reqs[4];
6371         int i;
6372
6373         ev = event_context_init(frame);
6374         if (ev == NULL) {
6375                 goto fail;
6376         }
6377
6378         ctx = fncall_context_init(frame, 4);
6379
6380         for (i=0; i<ARRAY_SIZE(names); i++) {
6381                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
6382                                            NULL);
6383                 if (reqs[i] == NULL) {
6384                         goto fail;
6385                 }
6386                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
6387                                         (void *)names[i]);
6388         }
6389
6390         for (i=0; i<ARRAY_SIZE(reqs); i++) {
6391                 tevent_loop_once(ev);
6392         }
6393
6394         result = true;
6395 fail:
6396         TALLOC_FREE(frame);
6397         return result;
6398 }
6399
6400
6401 static double create_procs(bool (*fn)(int), bool *result)
6402 {
6403         int i, status;
6404         volatile pid_t *child_status;
6405         volatile bool *child_status_out;
6406         int synccount;
6407         int tries = 8;
6408
6409         synccount = 0;
6410
6411         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
6412         if (!child_status) {
6413                 printf("Failed to setup shared memory\n");
6414                 return -1;
6415         }
6416
6417         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
6418         if (!child_status_out) {
6419                 printf("Failed to setup result status shared memory\n");
6420                 return -1;
6421         }
6422
6423         for (i = 0; i < nprocs; i++) {
6424                 child_status[i] = 0;
6425                 child_status_out[i] = True;
6426         }
6427
6428         start_timer();
6429
6430         for (i=0;i<nprocs;i++) {
6431                 procnum = i;
6432                 if (fork() == 0) {
6433                         pid_t mypid = getpid();
6434                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
6435
6436                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
6437
6438                         while (1) {
6439                                 if (torture_open_connection(&current_cli, i)) break;
6440                                 if (tries-- == 0) {
6441                                         printf("pid %d failed to start\n", (int)getpid());
6442                                         _exit(1);
6443                                 }
6444                                 smb_msleep(10); 
6445                         }
6446
6447                         child_status[i] = getpid();
6448
6449                         while (child_status[i] && end_timer() < 5) smb_msleep(2);
6450
6451                         child_status_out[i] = fn(i);
6452                         _exit(0);
6453                 }
6454         }
6455
6456         do {
6457                 synccount = 0;
6458                 for (i=0;i<nprocs;i++) {
6459                         if (child_status[i]) synccount++;
6460                 }
6461                 if (synccount == nprocs) break;
6462                 smb_msleep(10);
6463         } while (end_timer() < 30);
6464
6465         if (synccount != nprocs) {
6466                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
6467                 *result = False;
6468                 return end_timer();
6469         }
6470
6471         /* start the client load */
6472         start_timer();
6473
6474         for (i=0;i<nprocs;i++) {
6475                 child_status[i] = 0;
6476         }
6477
6478         printf("%d clients started\n", nprocs);
6479
6480         for (i=0;i<nprocs;i++) {
6481                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
6482         }
6483
6484         printf("\n");
6485
6486         for (i=0;i<nprocs;i++) {
6487                 if (!child_status_out[i]) {
6488                         *result = False;
6489                 }
6490         }
6491         return end_timer();
6492 }
6493
6494 #define FLAG_MULTIPROC 1
6495
6496 static struct {
6497         const char *name;
6498         bool (*fn)(int);
6499         unsigned flags;
6500 } torture_ops[] = {
6501         {"FDPASS", run_fdpasstest, 0},
6502         {"LOCK1",  run_locktest1,  0},
6503         {"LOCK2",  run_locktest2,  0},
6504         {"LOCK3",  run_locktest3,  0},
6505         {"LOCK4",  run_locktest4,  0},
6506         {"LOCK5",  run_locktest5,  0},
6507         {"LOCK6",  run_locktest6,  0},
6508         {"LOCK7",  run_locktest7,  0},
6509         {"LOCK8",  run_locktest8,  0},
6510         {"UNLINK", run_unlinktest, 0},
6511         {"BROWSE", run_browsetest, 0},
6512         {"ATTR",   run_attrtest,   0},
6513         {"TRANS2", run_trans2test, 0},
6514         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
6515         {"TORTURE",run_torture,    FLAG_MULTIPROC},
6516         {"RANDOMIPC", run_randomipc, 0},
6517         {"NEGNOWAIT", run_negprot_nowait, 0},
6518         {"NBENCH",  run_nbench, 0},
6519         {"OPLOCK1",  run_oplock1, 0},
6520         {"OPLOCK2",  run_oplock2, 0},
6521         {"OPLOCK3",  run_oplock3, 0},
6522         {"DIR",  run_dirtest, 0},
6523         {"DIR1",  run_dirtest1, 0},
6524         {"DENY1",  torture_denytest1, 0},
6525         {"DENY2",  torture_denytest2, 0},
6526         {"TCON",  run_tcon_test, 0},
6527         {"TCONDEV",  run_tcon_devtype_test, 0},
6528         {"RW1",  run_readwritetest, 0},
6529         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
6530         {"RW3",  run_readwritelarge, 0},
6531         {"OPEN", run_opentest, 0},
6532         {"POSIX", run_simple_posix_open_test, 0},
6533         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
6534         { "SHORTNAME-TEST", run_shortname_test, 0},
6535 #if 1
6536         {"OPENATTR", run_openattrtest, 0},
6537 #endif
6538         {"XCOPY", run_xcopy, 0},
6539         {"RENAME", run_rename, 0},
6540         {"DELETE", run_deletetest, 0},
6541         {"PROPERTIES", run_properties, 0},
6542         {"MANGLE", torture_mangle, 0},
6543         {"MANGLE1", run_mangle1, 0},
6544         {"W2K", run_w2ktest, 0},
6545         {"TRANS2SCAN", torture_trans2_scan, 0},
6546         {"NTTRANSSCAN", torture_nttrans_scan, 0},
6547         {"UTABLE", torture_utable, 0},
6548         {"CASETABLE", torture_casetable, 0},
6549         {"ERRMAPEXTRACT", run_error_map_extract, 0},
6550         {"PIPE_NUMBER", run_pipe_number, 0},
6551         {"TCON2",  run_tcon2_test, 0},
6552         {"IOCTL",  torture_ioctl_test, 0},
6553         {"CHKPATH",  torture_chkpath_test, 0},
6554         {"FDSESS", run_fdsesstest, 0},
6555         { "EATEST", run_eatest, 0},
6556         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
6557         { "CHAIN1", run_chain1, 0},
6558         { "CHAIN2", run_chain2, 0},
6559         { "WINDOWS-WRITE", run_windows_write, 0},
6560         { "CLI_ECHO", run_cli_echo, 0},
6561         { "GETADDRINFO", run_getaddrinfo_send, 0},
6562         { "TLDAP", run_tldap },
6563         { "STREAMERROR", run_streamerror },
6564         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
6565         { "LOCAL-GENCACHE", run_local_gencache, 0},
6566         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
6567         { "LOCAL-BASE64", run_local_base64, 0},
6568         { "LOCAL-RBTREE", run_local_rbtree, 0},
6569         { "LOCAL-MEMCACHE", run_local_memcache, 0},
6570         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
6571         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
6572         {NULL, NULL, 0}};
6573
6574
6575
6576 /****************************************************************************
6577 run a specified test or "ALL"
6578 ****************************************************************************/
6579 static bool run_test(const char *name)
6580 {
6581         bool ret = True;
6582         bool result = True;
6583         bool found = False;
6584         int i;
6585         double t;
6586         if (strequal(name,"ALL")) {
6587                 for (i=0;torture_ops[i].name;i++) {
6588                         run_test(torture_ops[i].name);
6589                 }
6590                 found = True;
6591         }
6592
6593         for (i=0;torture_ops[i].name;i++) {
6594                 fstr_sprintf(randomfname, "\\XX%x", 
6595                          (unsigned)random());
6596
6597                 if (strequal(name, torture_ops[i].name)) {
6598                         found = True;
6599                         printf("Running %s\n", name);
6600                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
6601                                 t = create_procs(torture_ops[i].fn, &result);
6602                                 if (!result) { 
6603                                         ret = False;
6604                                         printf("TEST %s FAILED!\n", name);
6605                                 }
6606                         } else {
6607                                 start_timer();
6608                                 if (!torture_ops[i].fn(0)) {
6609                                         ret = False;
6610                                         printf("TEST %s FAILED!\n", name);
6611                                 }
6612                                 t = end_timer();
6613                         }
6614                         printf("%s took %g secs\n\n", name, t);
6615                 }
6616         }
6617
6618         if (!found) {
6619                 printf("Did not find a test named %s\n", name);
6620                 ret = False;
6621         }
6622
6623         return ret;
6624 }
6625
6626
6627 static void usage(void)
6628 {
6629         int i;
6630
6631         printf("WARNING samba4 test suite is much more complete nowadays.\n");
6632         printf("Please use samba4 torture.\n\n");
6633
6634         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
6635
6636         printf("\t-d debuglevel\n");
6637         printf("\t-U user%%pass\n");
6638         printf("\t-k               use kerberos\n");
6639         printf("\t-N numprocs\n");
6640         printf("\t-n my_netbios_name\n");
6641         printf("\t-W workgroup\n");
6642         printf("\t-o num_operations\n");
6643         printf("\t-O socket_options\n");
6644         printf("\t-m maximum protocol\n");
6645         printf("\t-L use oplocks\n");
6646         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
6647         printf("\t-A showall\n");
6648         printf("\t-p port\n");
6649         printf("\t-s seed\n");
6650         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
6651         printf("\n\n");
6652
6653         printf("tests are:");
6654         for (i=0;torture_ops[i].name;i++) {
6655                 printf(" %s", torture_ops[i].name);
6656         }
6657         printf("\n");
6658
6659         printf("default test is ALL\n");
6660
6661         exit(1);
6662 }
6663
6664 /****************************************************************************
6665   main program
6666 ****************************************************************************/
6667  int main(int argc,char *argv[])
6668 {
6669         int opt, i;
6670         char *p;
6671         int gotuser = 0;
6672         int gotpass = 0;
6673         bool correct = True;
6674         TALLOC_CTX *frame = talloc_stackframe();
6675         int seed = time(NULL);
6676
6677         dbf = x_stdout;
6678
6679 #ifdef HAVE_SETBUFFER
6680         setbuffer(stdout, NULL, 0);
6681 #endif
6682
6683         load_case_tables();
6684
6685         if (is_default_dyn_CONFIGFILE()) {
6686                 if(getenv("SMB_CONF_PATH")) {
6687                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6688                 }
6689         }
6690         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6691         load_interfaces();
6692
6693         if (argc < 2) {
6694                 usage();
6695         }
6696
6697         for(p = argv[1]; *p; p++)
6698           if(*p == '\\')
6699             *p = '/';
6700
6701         if (strncmp(argv[1], "//", 2)) {
6702                 usage();
6703         }
6704
6705         fstrcpy(host, &argv[1][2]);
6706         p = strchr_m(&host[2],'/');
6707         if (!p) {
6708                 usage();
6709         }
6710         *p = 0;
6711         fstrcpy(share, p+1);
6712
6713         fstrcpy(myname, get_myname(talloc_tos()));
6714         if (!*myname) {
6715                 fprintf(stderr, "Failed to get my hostname.\n");
6716                 return 1;
6717         }
6718
6719         if (*username == 0 && getenv("LOGNAME")) {
6720           fstrcpy(username,getenv("LOGNAME"));
6721         }
6722
6723         argc--;
6724         argv++;
6725
6726         fstrcpy(workgroup, lp_workgroup());
6727
6728         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6729                 switch (opt) {
6730                 case 'p':
6731                         port_to_use = atoi(optarg);
6732                         break;
6733                 case 's':
6734                         seed = atoi(optarg);
6735                         break;
6736                 case 'W':
6737                         fstrcpy(workgroup,optarg);
6738                         break;
6739                 case 'm':
6740                         max_protocol = interpret_protocol(optarg, max_protocol);
6741                         break;
6742                 case 'N':
6743                         nprocs = atoi(optarg);
6744                         break;
6745                 case 'o':
6746                         torture_numops = atoi(optarg);
6747                         break;
6748                 case 'd':
6749                         DEBUGLEVEL = atoi(optarg);
6750                         break;
6751                 case 'O':
6752                         sockops = optarg;
6753                         break;
6754                 case 'L':
6755                         use_oplocks = True;
6756                         break;
6757                 case 'A':
6758                         torture_showall = True;
6759                         break;
6760                 case 'n':
6761                         fstrcpy(myname, optarg);
6762                         break;
6763                 case 'c':
6764                         client_txt = optarg;
6765                         break;
6766                 case 'e':
6767                         do_encrypt = true;
6768                         break;
6769                 case 'k':
6770 #ifdef HAVE_KRB5
6771                         use_kerberos = True;
6772 #else
6773                         d_printf("No kerberos support compiled in\n");
6774                         exit(1);
6775 #endif
6776                         break;
6777                 case 'U':
6778                         gotuser = 1;
6779                         fstrcpy(username,optarg);
6780                         p = strchr_m(username,'%');
6781                         if (p) {
6782                                 *p = 0;
6783                                 fstrcpy(password, p+1);
6784                                 gotpass = 1;
6785                         }
6786                         break;
6787                 case 'b':
6788                         fstrcpy(multishare_conn_fname, optarg);
6789                         use_multishare_conn = True;
6790                         break;
6791                 case 'B':
6792                         torture_blocksize = atoi(optarg);
6793                         break;
6794                 default:
6795                         printf("Unknown option %c (%d)\n", (char)opt, opt);
6796                         usage();
6797                 }
6798         }
6799
6800         d_printf("using seed %d\n", seed);
6801
6802         srandom(seed);
6803
6804         if(use_kerberos && !gotuser) gotpass = True;
6805
6806         while (!gotpass) {
6807                 p = getpass("Password:");
6808                 if (p) {
6809                         fstrcpy(password, p);
6810                         gotpass = 1;
6811                 }
6812         }
6813
6814         printf("host=%s share=%s user=%s myname=%s\n", 
6815                host, share, username, myname);
6816
6817         if (argc == optind) {
6818                 correct = run_test("ALL");
6819         } else {
6820                 for (i=optind;i<argc;i++) {
6821                         if (!run_test(argv[i])) {
6822                                 correct = False;
6823                         }
6824                 }
6825         }
6826
6827         TALLOC_FREE(frame);
6828
6829         if (correct) {
6830                 return(0);
6831         } else {
6832                 return(1);
6833         }
6834 }