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