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