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