806455ff18be975c9ab39bdc3e16abbc8e5d14b7
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    Copyright (C) Jeremy Allison 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27 #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
33 extern char *optarg;
34 extern int optind;
35
36 static fstring host, workgroup, share, password, username, myname;
37 static int max_protocol = PROTOCOL_NT1;
38 static const char *sockops="TCP_NODELAY";
39 static int nprocs=1;
40 static int port_to_use=0;
41 int torture_numops=100;
42 int torture_blocksize=1024*1024;
43 static int procnum; /* records process count number when forking */
44 static struct cli_state *current_cli;
45 static fstring randomfname;
46 static bool use_oplocks;
47 static bool use_level_II_oplocks;
48 static const char *client_txt = "client_oplocks.txt";
49 static bool use_kerberos;
50 static fstring multishare_conn_fname;
51 static bool use_multishare_conn = False;
52 static bool do_encrypt;
53 static const char *local_path = NULL;
54
55 bool torture_showall = False;
56
57 static double create_procs(bool (*fn)(int), bool *result);
58
59
60 /* return a pointer to a anonymous shared memory segment of size "size"
61    which will persist across fork() but will disappear when all processes
62    exit 
63
64    The memory is not zeroed 
65
66    This function uses system5 shared memory. It takes advantage of a property
67    that the memory is not destroyed if it is attached when the id is removed
68    */
69 void *shm_setup(int size)
70 {
71         int shmid;
72         void *ret;
73
74 #ifdef __QNXNTO__
75         shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
76         if (shmid == -1) {
77                 printf("can't get shared memory\n");
78                 exit(1);
79         }
80         shm_unlink("private");
81         if (ftruncate(shmid, size) == -1) {
82                 printf("can't set shared memory size\n");
83                 exit(1);
84         }
85         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
86         if (ret == MAP_FAILED) {
87                 printf("can't map shared memory\n");
88                 exit(1);
89         }
90 #else
91         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
92         if (shmid == -1) {
93                 printf("can't get shared memory\n");
94                 exit(1);
95         }
96         ret = (void *)shmat(shmid, 0, 0);
97         if (!ret || ret == (void *)-1) {
98                 printf("can't attach to shared memory\n");
99                 return NULL;
100         }
101         /* the following releases the ipc, but note that this process
102            and all its children will still have access to the memory, its
103            just that the shmid is no longer valid for other shm calls. This
104            means we don't leave behind lots of shm segments after we exit 
105
106            See Stevens "advanced programming in unix env" for details
107            */
108         shmctl(shmid, IPC_RMID, 0);
109 #endif
110
111         return ret;
112 }
113
114 /********************************************************************
115  Ensure a connection is encrypted.
116 ********************************************************************/
117
118 static bool force_cli_encryption(struct cli_state *c,
119                         const char *sharename)
120 {
121         uint16 major, minor;
122         uint32 caplow, caphigh;
123         NTSTATUS status;
124
125         if (!SERVER_HAS_UNIX_CIFS(c)) {
126                 d_printf("Encryption required and "
127                         "server that doesn't support "
128                         "UNIX extensions - failing connect\n");
129                         return false;
130         }
131
132         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
133                                              &caphigh);
134         if (!NT_STATUS_IS_OK(status)) {
135                 d_printf("Encryption required and "
136                         "can't get UNIX CIFS extensions "
137                         "version from server: %s\n", nt_errstr(status));
138                 return false;
139         }
140
141         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
142                 d_printf("Encryption required and "
143                         "share %s doesn't support "
144                         "encryption.\n", sharename);
145                 return false;
146         }
147
148         if (c->use_kerberos) {
149                 status = cli_gss_smb_encryption_start(c);
150         } else {
151                 status = cli_raw_ntlm_smb_encryption_start(c,
152                                                 username,
153                                                 password,
154                                                 workgroup);
155         }
156
157         if (!NT_STATUS_IS_OK(status)) {
158                 d_printf("Encryption required and "
159                         "setup failed with error %s.\n",
160                         nt_errstr(status));
161                 return false;
162         }
163
164         return true;
165 }
166
167
168 static struct cli_state *open_nbt_connection(void)
169 {
170         struct nmb_name called, calling;
171         struct sockaddr_storage ss;
172         struct cli_state *c;
173         NTSTATUS status;
174
175         make_nmb_name(&calling, myname, 0x0);
176         make_nmb_name(&called , host, 0x20);
177
178         zero_sockaddr(&ss);
179
180         if (!(c = cli_initialise())) {
181                 printf("Failed initialize cli_struct to connect with %s\n", host);
182                 return NULL;
183         }
184
185         c->port = port_to_use;
186
187         status = cli_connect(c, host, &ss);
188         if (!NT_STATUS_IS_OK(status)) {
189                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
190                 return NULL;
191         }
192
193         c->use_kerberos = use_kerberos;
194
195         c->timeout = 120000; /* set a really long timeout (2 minutes) */
196         if (use_oplocks) c->use_oplocks = True;
197         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
198
199         if (!cli_session_request(c, &calling, &called)) {
200                 /*
201                  * Well, that failed, try *SMBSERVER ...
202                  * However, we must reconnect as well ...
203                  */
204                 status = cli_connect(c, host, &ss);
205                 if (!NT_STATUS_IS_OK(status)) {
206                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
207                         return NULL;
208                 }
209
210                 make_nmb_name(&called, "*SMBSERVER", 0x20);
211                 if (!cli_session_request(c, &calling, &called)) {
212                         printf("%s rejected the session\n",host);
213                         printf("We tried with a called name of %s & %s\n",
214                                 host, "*SMBSERVER");
215                         cli_shutdown(c);
216                         return NULL;
217                 }
218         }
219
220         return c;
221 }
222
223 /* Insert a NULL at the first separator of the given path and return a pointer
224  * to the remainder of the string.
225  */
226 static char *
227 terminate_path_at_separator(char * path)
228 {
229         char * p;
230
231         if (!path) {
232                 return NULL;
233         }
234
235         if ((p = strchr_m(path, '/'))) {
236                 *p = '\0';
237                 return p + 1;
238         }
239
240         if ((p = strchr_m(path, '\\'))) {
241                 *p = '\0';
242                 return p + 1;
243         }
244
245         /* No separator. */
246         return NULL;
247 }
248
249 /*
250   parse a //server/share type UNC name
251 */
252 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
253                       char **hostname, char **sharename)
254 {
255         char *p;
256
257         *hostname = *sharename = NULL;
258
259         if (strncmp(unc_name, "\\\\", 2) &&
260             strncmp(unc_name, "//", 2)) {
261                 return False;
262         }
263
264         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
265         p = terminate_path_at_separator(*hostname);
266
267         if (p && *p) {
268                 *sharename = talloc_strdup(mem_ctx, p);
269                 terminate_path_at_separator(*sharename);
270         }
271
272         if (*hostname && *sharename) {
273                 return True;
274         }
275
276         TALLOC_FREE(*hostname);
277         TALLOC_FREE(*sharename);
278         return False;
279 }
280
281 static bool torture_open_connection_share(struct cli_state **c,
282                                    const char *hostname, 
283                                    const char *sharename)
284 {
285         bool retry;
286         int flags = 0;
287         NTSTATUS status;
288
289         if (use_kerberos)
290                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
291         if (use_oplocks)
292                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
293         if (use_level_II_oplocks)
294                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
295
296         status = cli_full_connection(c, myname,
297                                      hostname, NULL, port_to_use, 
298                                      sharename, "?????", 
299                                      username, workgroup, 
300                                      password, flags, Undefined, &retry);
301         if (!NT_STATUS_IS_OK(status)) {
302                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
303                         hostname, sharename, port_to_use, nt_errstr(status));
304                 return False;
305         }
306
307         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
308
309         if (do_encrypt) {
310                 return force_cli_encryption(*c,
311                                         sharename);
312         }
313         return True;
314 }
315
316 bool torture_open_connection(struct cli_state **c, int conn_index)
317 {
318         char **unc_list = NULL;
319         int num_unc_names = 0;
320         bool result;
321
322         if (use_multishare_conn==True) {
323                 char *h, *s;
324                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
325                 if (!unc_list || num_unc_names <= 0) {
326                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
327                         exit(1);
328                 }
329
330                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
331                                       NULL, &h, &s)) {
332                         printf("Failed to parse UNC name %s\n",
333                                unc_list[conn_index % num_unc_names]);
334                         TALLOC_FREE(unc_list);
335                         exit(1);
336                 }
337
338                 result = torture_open_connection_share(c, h, s);
339
340                 /* h, s were copied earlier */
341                 TALLOC_FREE(unc_list);
342                 return result;
343         }
344
345         return torture_open_connection_share(c, host, share);
346 }
347
348 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
349 {
350         uint16 old_vuid = cli->vuid;
351         fstring old_user_name;
352         size_t passlen = strlen(password);
353         NTSTATUS status;
354         bool ret;
355
356         fstrcpy(old_user_name, cli->user_name);
357         cli->vuid = 0;
358         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
359                                                 password, passlen,
360                                                 password, passlen,
361                                                 workgroup));
362         *new_vuid = cli->vuid;
363         cli->vuid = old_vuid;
364         status = cli_set_username(cli, old_user_name);
365         if (!NT_STATUS_IS_OK(status)) {
366                 return false;
367         }
368         return ret;
369 }
370
371
372 bool torture_close_connection(struct cli_state *c)
373 {
374         bool ret = True;
375         NTSTATUS status;
376
377         status = cli_tdis(c);
378         if (!NT_STATUS_IS_OK(status)) {
379                 printf("tdis failed (%s)\n", nt_errstr(status));
380                 ret = False;
381         }
382
383         cli_shutdown(c);
384
385         return ret;
386 }
387
388
389 /* check if the server produced the expected error code */
390 static bool check_error(int line, struct cli_state *c, 
391                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
392 {
393         if (cli_is_dos_error(c)) {
394                 uint8 cclass;
395                 uint32 num;
396
397                 /* Check DOS error */
398
399                 cli_dos_error(c, &cclass, &num);
400
401                 if (eclass != cclass || ecode != num) {
402                         printf("unexpected error code class=%d code=%d\n", 
403                                (int)cclass, (int)num);
404                         printf(" expected %d/%d %s (line=%d)\n", 
405                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
406                         return False;
407                 }
408
409         } else {
410                 NTSTATUS status;
411
412                 /* Check NT error */
413
414                 status = cli_nt_error(c);
415
416                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
417                         printf("unexpected error code %s\n", nt_errstr(status));
418                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
419                         return False;
420                 }
421         }
422
423         return True;
424 }
425
426
427 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
428 {
429         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
430                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
431         }
432         return True;
433 }
434
435
436 static bool rw_torture(struct cli_state *c)
437 {
438         const char *lockfname = "\\torture.lck";
439         fstring fname;
440         uint16_t fnum;
441         uint16_t fnum2;
442         pid_t pid2, pid = getpid();
443         int i, j;
444         char buf[1024];
445         bool correct = True;
446         NTSTATUS status;
447
448         memset(buf, '\0', sizeof(buf));
449
450         status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
451                          DENY_NONE, &fnum2);
452         if (!NT_STATUS_IS_OK(status)) {
453                 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
454         }
455         if (!NT_STATUS_IS_OK(status)) {
456                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
457                 return False;
458         }
459
460         for (i=0;i<torture_numops;i++) {
461                 unsigned n = (unsigned)sys_random()%10;
462                 if (i % 10 == 0) {
463                         printf("%d\r", i); fflush(stdout);
464                 }
465                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
466
467                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
468                         return False;
469                 }
470
471                 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
472                         printf("open failed (%s)\n", cli_errstr(c));
473                         correct = False;
474                         break;
475                 }
476
477                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
478                         printf("write failed (%s)\n", cli_errstr(c));
479                         correct = False;
480                 }
481
482                 for (j=0;j<50;j++) {
483                         if (cli_write(c, fnum, 0, (char *)buf, 
484                                       sizeof(pid)+(j*sizeof(buf)), 
485                                       sizeof(buf)) != sizeof(buf)) {
486                                 printf("write failed (%s)\n", cli_errstr(c));
487                                 correct = False;
488                         }
489                 }
490
491                 pid2 = 0;
492
493                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
494                         printf("read failed (%s)\n", cli_errstr(c));
495                         correct = False;
496                 }
497
498                 if (pid2 != pid) {
499                         printf("data corruption!\n");
500                         correct = False;
501                 }
502
503                 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
504                         printf("close failed (%s)\n", cli_errstr(c));
505                         correct = False;
506                 }
507
508                 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
509                         printf("unlink failed (%s)\n", cli_errstr(c));
510                         correct = False;
511                 }
512
513                 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
514                         printf("unlock failed (%s)\n", cli_errstr(c));
515                         correct = False;
516                 }
517         }
518
519         cli_close(c, fnum2);
520         cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
521
522         printf("%d\n", i);
523
524         return correct;
525 }
526
527 static bool run_torture(int dummy)
528 {
529         struct cli_state *cli;
530         bool ret;
531
532         cli = current_cli;
533
534         cli_sockopt(cli, sockops);
535
536         ret = rw_torture(cli);
537
538         if (!torture_close_connection(cli)) {
539                 ret = False;
540         }
541
542         return ret;
543 }
544
545 static bool rw_torture3(struct cli_state *c, char *lockfname)
546 {
547         uint16_t fnum = (uint16_t)-1;
548         unsigned int i = 0;
549         char buf[131072];
550         char buf_rd[131072];
551         unsigned count;
552         unsigned countprev = 0;
553         ssize_t sent = 0;
554         bool correct = True;
555         NTSTATUS status;
556
557         srandom(1);
558         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
559         {
560                 SIVAL(buf, i, sys_random());
561         }
562
563         if (procnum == 0)
564         {
565                 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
566                                  DENY_NONE, &fnum))) {
567                         printf("first open read/write of %s failed (%s)\n",
568                                         lockfname, cli_errstr(c));
569                         return False;
570                 }
571         }
572         else
573         {
574                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
575                 {
576                         status = cli_open(c, lockfname, O_RDONLY, 
577                                          DENY_NONE, &fnum);
578                         if (!NT_STATUS_IS_OK(status)) {
579                                 break;
580                         }
581                         smb_msleep(10);
582                 }
583                 if (!NT_STATUS_IS_OK(status)) {
584                         printf("second open read-only of %s failed (%s)\n",
585                                         lockfname, cli_errstr(c));
586                         return False;
587                 }
588         }
589
590         i = 0;
591         for (count = 0; count < sizeof(buf); count += sent)
592         {
593                 if (count >= countprev) {
594                         printf("%d %8d\r", i, count);
595                         fflush(stdout);
596                         i++;
597                         countprev += (sizeof(buf) / 20);
598                 }
599
600                 if (procnum == 0)
601                 {
602                         sent = ((unsigned)sys_random()%(20))+ 1;
603                         if (sent > sizeof(buf) - count)
604                         {
605                                 sent = sizeof(buf) - count;
606                         }
607
608                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
609                                 printf("write failed (%s)\n", cli_errstr(c));
610                                 correct = False;
611                         }
612                 }
613                 else
614                 {
615                         sent = cli_read(c, fnum, buf_rd+count, count,
616                                                   sizeof(buf)-count);
617                         if (sent < 0)
618                         {
619                                 printf("read failed offset:%d size:%ld (%s)\n",
620                                        count, (unsigned long)sizeof(buf)-count,
621                                        cli_errstr(c));
622                                 correct = False;
623                                 sent = 0;
624                         }
625                         if (sent > 0)
626                         {
627                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
628                                 {
629                                         printf("read/write compare failed\n");
630                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
631                                         correct = False;
632                                         break;
633                                 }
634                         }
635                 }
636
637         }
638
639         if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
640                 printf("close failed (%s)\n", cli_errstr(c));
641                 correct = False;
642         }
643
644         return correct;
645 }
646
647 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
648 {
649         const char *lockfname = "\\torture2.lck";
650         uint16_t fnum1;
651         uint16_t fnum2;
652         int i;
653         char buf[131072];
654         char buf_rd[131072];
655         bool correct = True;
656         ssize_t bytes_read;
657
658         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
659                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
660         }
661
662         if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
663                          DENY_NONE, &fnum1))) {
664                 printf("first open read/write of %s failed (%s)\n",
665                                 lockfname, cli_errstr(c1));
666                 return False;
667         }
668         if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY, 
669                          DENY_NONE, &fnum2))) {
670                 printf("second open read-only of %s failed (%s)\n",
671                                 lockfname, cli_errstr(c2));
672                 cli_close(c1, fnum1);
673                 return False;
674         }
675
676         for (i=0;i<torture_numops;i++)
677         {
678                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
679                 if (i % 10 == 0) {
680                         printf("%d\r", i); fflush(stdout);
681                 }
682
683                 generate_random_buffer((unsigned char *)buf, buf_size);
684
685                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
686                         printf("write failed (%s)\n", cli_errstr(c1));
687                         correct = False;
688                         break;
689                 }
690
691                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
692                         printf("read failed (%s)\n", cli_errstr(c2));
693                         printf("read %d, expected %ld\n", (int)bytes_read, 
694                                (unsigned long)buf_size); 
695                         correct = False;
696                         break;
697                 }
698
699                 if (memcmp(buf_rd, buf, buf_size) != 0)
700                 {
701                         printf("read/write compare failed\n");
702                         correct = False;
703                         break;
704                 }
705         }
706
707         if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
708                 printf("close failed (%s)\n", cli_errstr(c2));
709                 correct = False;
710         }
711         if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
712                 printf("close failed (%s)\n", cli_errstr(c1));
713                 correct = False;
714         }
715
716         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
717                 printf("unlink failed (%s)\n", cli_errstr(c1));
718                 correct = False;
719         }
720
721         return correct;
722 }
723
724 static bool run_readwritetest(int dummy)
725 {
726         struct cli_state *cli1, *cli2;
727         bool test1, test2 = False;
728
729         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
730                 return False;
731         }
732         cli_sockopt(cli1, sockops);
733         cli_sockopt(cli2, sockops);
734
735         printf("starting readwritetest\n");
736
737         test1 = rw_torture2(cli1, cli2);
738         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
739
740         if (test1) {
741                 test2 = rw_torture2(cli1, cli1);
742                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
743         }
744
745         if (!torture_close_connection(cli1)) {
746                 test1 = False;
747         }
748
749         if (!torture_close_connection(cli2)) {
750                 test2 = False;
751         }
752
753         return (test1 && test2);
754 }
755
756 static bool run_readwritemulti(int dummy)
757 {
758         struct cli_state *cli;
759         bool test;
760
761         cli = current_cli;
762
763         cli_sockopt(cli, sockops);
764
765         printf("run_readwritemulti: fname %s\n", randomfname);
766         test = rw_torture3(cli, randomfname);
767
768         if (!torture_close_connection(cli)) {
769                 test = False;
770         }
771
772         return test;
773 }
774
775 static bool run_readwritelarge(int dummy)
776 {
777         static struct cli_state *cli1;
778         uint16_t fnum1;
779         const char *lockfname = "\\large.dat";
780         SMB_OFF_T fsize;
781         char buf[126*1024];
782         bool correct = True;
783
784         if (!torture_open_connection(&cli1, 0)) {
785                 return False;
786         }
787         cli_sockopt(cli1, sockops);
788         memset(buf,'\0',sizeof(buf));
789
790         cli1->max_xmit = 128*1024;
791
792         printf("starting readwritelarge\n");
793
794         cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
795
796         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
797                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
798                 return False;
799         }
800
801         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
802
803         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
804                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
805                 correct = False;
806         }
807
808         if (fsize == sizeof(buf))
809                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
810                        (unsigned long)fsize);
811         else {
812                 printf("readwritelarge test 1 failed (size = %lx)\n", 
813                        (unsigned long)fsize);
814                 correct = False;
815         }
816
817         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
818                 printf("close failed (%s)\n", cli_errstr(cli1));
819                 correct = False;
820         }
821
822         if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
823                 printf("unlink failed (%s)\n", cli_errstr(cli1));
824                 correct = False;
825         }
826
827         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
828                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
829                 return False;
830         }
831
832         cli1->max_xmit = 4*1024;
833
834         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
835
836         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
837                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
838                 correct = False;
839         }
840
841         if (fsize == sizeof(buf))
842                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
843                        (unsigned long)fsize);
844         else {
845                 printf("readwritelarge test 2 failed (size = %lx)\n", 
846                        (unsigned long)fsize);
847                 correct = False;
848         }
849
850 #if 0
851         /* ToDo - set allocation. JRA */
852         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
853                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
854                 return False;
855         }
856         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
857                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
858                 correct = False;
859         }
860         if (fsize != 0)
861                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
862 #endif
863
864         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
865                 printf("close failed (%s)\n", cli_errstr(cli1));
866                 correct = False;
867         }
868
869         if (!torture_close_connection(cli1)) {
870                 correct = False;
871         }
872         return correct;
873 }
874
875 int line_count = 0;
876 int nbio_id;
877
878 #define ival(s) strtol(s, NULL, 0)
879
880 /* run a test that simulates an approximate netbench client load */
881 static bool run_netbench(int client)
882 {
883         struct cli_state *cli;
884         int i;
885         char line[1024];
886         char cname[20];
887         FILE *f;
888         const char *params[20];
889         bool correct = True;
890
891         cli = current_cli;
892
893         nbio_id = client;
894
895         cli_sockopt(cli, sockops);
896
897         nb_setup(cli);
898
899         slprintf(cname,sizeof(cname)-1, "client%d", client);
900
901         f = fopen(client_txt, "r");
902
903         if (!f) {
904                 perror(client_txt);
905                 return False;
906         }
907
908         while (fgets(line, sizeof(line)-1, f)) {
909                 char *saveptr;
910                 line_count++;
911
912                 line[strlen(line)-1] = 0;
913
914                 /* printf("[%d] %s\n", line_count, line); */
915
916                 all_string_sub(line,"client1", cname, sizeof(line));
917
918                 /* parse the command parameters */
919                 params[0] = strtok_r(line, " ", &saveptr);
920                 i = 0;
921                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
922
923                 params[i] = "";
924
925                 if (i < 2) continue;
926
927                 if (!strncmp(params[0],"SMB", 3)) {
928                         printf("ERROR: You are using a dbench 1 load file\n");
929                         exit(1);
930                 }
931
932                 if (!strcmp(params[0],"NTCreateX")) {
933                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
934                                    ival(params[4]));
935                 } else if (!strcmp(params[0],"Close")) {
936                         nb_close(ival(params[1]));
937                 } else if (!strcmp(params[0],"Rename")) {
938                         nb_rename(params[1], params[2]);
939                 } else if (!strcmp(params[0],"Unlink")) {
940                         nb_unlink(params[1]);
941                 } else if (!strcmp(params[0],"Deltree")) {
942                         nb_deltree(params[1]);
943                 } else if (!strcmp(params[0],"Rmdir")) {
944                         nb_rmdir(params[1]);
945                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
946                         nb_qpathinfo(params[1]);
947                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
948                         nb_qfileinfo(ival(params[1]));
949                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
950                         nb_qfsinfo(ival(params[1]));
951                 } else if (!strcmp(params[0],"FIND_FIRST")) {
952                         nb_findfirst(params[1]);
953                 } else if (!strcmp(params[0],"WriteX")) {
954                         nb_writex(ival(params[1]), 
955                                   ival(params[2]), ival(params[3]), ival(params[4]));
956                 } else if (!strcmp(params[0],"ReadX")) {
957                         nb_readx(ival(params[1]), 
958                                   ival(params[2]), ival(params[3]), ival(params[4]));
959                 } else if (!strcmp(params[0],"Flush")) {
960                         nb_flush(ival(params[1]));
961                 } else {
962                         printf("Unknown operation %s\n", params[0]);
963                         exit(1);
964                 }
965         }
966         fclose(f);
967
968         nb_cleanup();
969
970         if (!torture_close_connection(cli)) {
971                 correct = False;
972         }
973
974         return correct;
975 }
976
977
978 /* run a test that simulates an approximate netbench client load */
979 static bool run_nbench(int dummy)
980 {
981         double t;
982         bool correct = True;
983
984         nbio_shmem(nprocs);
985
986         nbio_id = -1;
987
988         signal(SIGALRM, nb_alarm);
989         alarm(1);
990         t = create_procs(run_netbench, &correct);
991         alarm(0);
992
993         printf("\nThroughput %g MB/sec\n", 
994                1.0e-6 * nbio_total() / t);
995         return correct;
996 }
997
998
999 /*
1000   This test checks for two things:
1001
1002   1) correct support for retaining locks over a close (ie. the server
1003      must not use posix semantics)
1004   2) support for lock timeouts
1005  */
1006 static bool run_locktest1(int dummy)
1007 {
1008         struct cli_state *cli1, *cli2;
1009         const char *fname = "\\lockt1.lck";
1010         uint16_t fnum1, fnum2, fnum3;
1011         time_t t1, t2;
1012         unsigned lock_timeout;
1013
1014         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1015                 return False;
1016         }
1017         cli_sockopt(cli1, sockops);
1018         cli_sockopt(cli2, sockops);
1019
1020         printf("starting locktest1\n");
1021
1022         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1023
1024         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1025                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1026                 return False;
1027         }
1028         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1029                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1030                 return False;
1031         }
1032         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1033                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1034                 return False;
1035         }
1036
1037         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1038                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1039                 return False;
1040         }
1041
1042
1043         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1044                 printf("lock2 succeeded! This is a locking bug\n");
1045                 return False;
1046         } else {
1047                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1048                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1049         }
1050
1051
1052         lock_timeout = (1 + (random() % 20));
1053         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1054         t1 = time(NULL);
1055         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1056                 printf("lock3 succeeded! This is a locking bug\n");
1057                 return False;
1058         } else {
1059                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1060                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1061         }
1062         t2 = time(NULL);
1063
1064         if (ABS(t2 - t1) < lock_timeout-1) {
1065                 printf("error: This server appears not to support timed lock requests\n");
1066         }
1067
1068         printf("server slept for %u seconds for a %u second timeout\n",
1069                (unsigned int)(t2-t1), lock_timeout);
1070
1071         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1072                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1073                 return False;
1074         }
1075
1076         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1077                 printf("lock4 succeeded! This is a locking bug\n");
1078                 return False;
1079         } else {
1080                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1081                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1082         }
1083
1084         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1085                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1086                 return False;
1087         }
1088
1089         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1090                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1091                 return False;
1092         }
1093
1094         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1095                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1096                 return False;
1097         }
1098
1099
1100         if (!torture_close_connection(cli1)) {
1101                 return False;
1102         }
1103
1104         if (!torture_close_connection(cli2)) {
1105                 return False;
1106         }
1107
1108         printf("Passed locktest1\n");
1109         return True;
1110 }
1111
1112 /*
1113   this checks to see if a secondary tconx can use open files from an
1114   earlier tconx
1115  */
1116 static bool run_tcon_test(int dummy)
1117 {
1118         static struct cli_state *cli;
1119         const char *fname = "\\tcontest.tmp";
1120         uint16 fnum1;
1121         uint16 cnum1, cnum2, cnum3;
1122         uint16 vuid1, vuid2;
1123         char buf[4];
1124         bool ret = True;
1125         NTSTATUS status;
1126
1127         memset(buf, '\0', sizeof(buf));
1128
1129         if (!torture_open_connection(&cli, 0)) {
1130                 return False;
1131         }
1132         cli_sockopt(cli, sockops);
1133
1134         printf("starting tcontest\n");
1135
1136         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1137
1138         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1139                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1140                 return False;
1141         }
1142
1143         cnum1 = cli->cnum;
1144         vuid1 = cli->vuid;
1145
1146         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1147                 printf("initial write failed (%s)", cli_errstr(cli));
1148                 return False;
1149         }
1150
1151         status = cli_tcon_andx(cli, share, "?????",
1152                                password, strlen(password)+1);
1153         if (!NT_STATUS_IS_OK(status)) {
1154                 printf("%s refused 2nd tree connect (%s)\n", host,
1155                        nt_errstr(status));
1156                 cli_shutdown(cli);
1157                 return False;
1158         }
1159
1160         cnum2 = cli->cnum;
1161         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1162         vuid2 = cli->vuid + 1;
1163
1164         /* try a write with the wrong tid */
1165         cli->cnum = cnum2;
1166
1167         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168                 printf("* server allows write with wrong TID\n");
1169                 ret = False;
1170         } else {
1171                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1172         }
1173
1174
1175         /* try a write with an invalid tid */
1176         cli->cnum = cnum3;
1177
1178         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1179                 printf("* server allows write with invalid TID\n");
1180                 ret = False;
1181         } else {
1182                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1183         }
1184
1185         /* try a write with an invalid vuid */
1186         cli->vuid = vuid2;
1187         cli->cnum = cnum1;
1188
1189         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1190                 printf("* server allows write with invalid VUID\n");
1191                 ret = False;
1192         } else {
1193                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1194         }
1195
1196         cli->cnum = cnum1;
1197         cli->vuid = vuid1;
1198
1199         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1200                 printf("close failed (%s)\n", cli_errstr(cli));
1201                 return False;
1202         }
1203
1204         cli->cnum = cnum2;
1205
1206         status = cli_tdis(cli);
1207         if (!NT_STATUS_IS_OK(status)) {
1208                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1209                 return False;
1210         }
1211
1212         cli->cnum = cnum1;
1213
1214         if (!torture_close_connection(cli)) {
1215                 return False;
1216         }
1217
1218         return ret;
1219 }
1220
1221
1222 /*
1223  checks for old style tcon support
1224  */
1225 static bool run_tcon2_test(int dummy)
1226 {
1227         static struct cli_state *cli;
1228         uint16 cnum, max_xmit;
1229         char *service;
1230         NTSTATUS status;
1231
1232         if (!torture_open_connection(&cli, 0)) {
1233                 return False;
1234         }
1235         cli_sockopt(cli, sockops);
1236
1237         printf("starting tcon2 test\n");
1238
1239         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1240                 return false;
1241         }
1242
1243         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1244
1245         if (!NT_STATUS_IS_OK(status)) {
1246                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1247         } else {
1248                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1249                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1250         }
1251
1252         if (!torture_close_connection(cli)) {
1253                 return False;
1254         }
1255
1256         printf("Passed tcon2 test\n");
1257         return True;
1258 }
1259
1260 static bool tcon_devtest(struct cli_state *cli,
1261                          const char *myshare, const char *devtype,
1262                          const char *return_devtype,
1263                          NTSTATUS expected_error)
1264 {
1265         NTSTATUS status;
1266         bool ret;
1267
1268         status = cli_tcon_andx(cli, myshare, devtype,
1269                                password, strlen(password)+1);
1270
1271         if (NT_STATUS_IS_OK(expected_error)) {
1272                 if (NT_STATUS_IS_OK(status)) {
1273                         if (strcmp(cli->dev, return_devtype) == 0) {
1274                                 ret = True;
1275                         } else { 
1276                                 printf("tconX to share %s with type %s "
1277                                        "succeeded but returned the wrong "
1278                                        "device type (got [%s] but should have got [%s])\n",
1279                                        myshare, devtype, cli->dev, return_devtype);
1280                                 ret = False;
1281                         }
1282                 } else {
1283                         printf("tconX to share %s with type %s "
1284                                "should have succeeded but failed\n",
1285                                myshare, devtype);
1286                         ret = False;
1287                 }
1288                 cli_tdis(cli);
1289         } else {
1290                 if (NT_STATUS_IS_OK(status)) {
1291                         printf("tconx to share %s with type %s "
1292                                "should have failed but succeeded\n",
1293                                myshare, devtype);
1294                         ret = False;
1295                 } else {
1296                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1297                                             expected_error)) {
1298                                 ret = True;
1299                         } else {
1300                                 printf("Returned unexpected error\n");
1301                                 ret = False;
1302                         }
1303                 }
1304         }
1305         return ret;
1306 }
1307
1308 /*
1309  checks for correct tconX support
1310  */
1311 static bool run_tcon_devtype_test(int dummy)
1312 {
1313         static struct cli_state *cli1 = NULL;
1314         bool retry;
1315         int flags = 0;
1316         NTSTATUS status;
1317         bool ret = True;
1318
1319         status = cli_full_connection(&cli1, myname,
1320                                      host, NULL, port_to_use,
1321                                      NULL, NULL,
1322                                      username, workgroup,
1323                                      password, flags, Undefined, &retry);
1324
1325         if (!NT_STATUS_IS_OK(status)) {
1326                 printf("could not open connection\n");
1327                 return False;
1328         }
1329
1330         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1331                 ret = False;
1332
1333         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1334                 ret = False;
1335
1336         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1337                 ret = False;
1338
1339         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1340                 ret = False;
1341
1342         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1343                 ret = False;
1344
1345         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1346                 ret = False;
1347
1348         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1349                 ret = False;
1350
1351         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1352                 ret = False;
1353
1354         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1355                 ret = False;
1356
1357         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1358                 ret = False;
1359
1360         cli_shutdown(cli1);
1361
1362         if (ret)
1363                 printf("Passed tcondevtest\n");
1364
1365         return ret;
1366 }
1367
1368
1369 /*
1370   This test checks that 
1371
1372   1) the server supports multiple locking contexts on the one SMB
1373   connection, distinguished by PID.  
1374
1375   2) the server correctly fails overlapping locks made by the same PID (this
1376      goes against POSIX behaviour, which is why it is tricky to implement)
1377
1378   3) the server denies unlock requests by an incorrect client PID
1379 */
1380 static bool run_locktest2(int dummy)
1381 {
1382         static struct cli_state *cli;
1383         const char *fname = "\\lockt2.lck";
1384         uint16_t fnum1, fnum2, fnum3;
1385         bool correct = True;
1386
1387         if (!torture_open_connection(&cli, 0)) {
1388                 return False;
1389         }
1390
1391         cli_sockopt(cli, sockops);
1392
1393         printf("starting locktest2\n");
1394
1395         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1396
1397         cli_setpid(cli, 1);
1398
1399         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1400                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1401                 return False;
1402         }
1403
1404         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1405                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1406                 return False;
1407         }
1408
1409         cli_setpid(cli, 2);
1410
1411         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1412                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1413                 return False;
1414         }
1415
1416         cli_setpid(cli, 1);
1417
1418         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1419                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1420                 return False;
1421         }
1422
1423         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1424                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1425                 correct = False;
1426         } else {
1427                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1428                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1429         }
1430
1431         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1432                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1433                 correct = False;
1434         } else {
1435                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1436                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1437         }
1438
1439         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1440                 printf("READ lock2 succeeded! This is a locking bug\n");
1441                 correct = False;
1442         } else {
1443                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1444                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1445         }
1446
1447         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1448                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1449         }
1450         cli_setpid(cli, 2);
1451         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1452                 printf("unlock at 100 succeeded! This is a locking bug\n");
1453                 correct = False;
1454         }
1455
1456         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1457                 printf("unlock1 succeeded! This is a locking bug\n");
1458                 correct = False;
1459         } else {
1460                 if (!check_error(__LINE__, cli, 
1461                                  ERRDOS, ERRlock, 
1462                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1463         }
1464
1465         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1466                 printf("unlock2 succeeded! This is a locking bug\n");
1467                 correct = False;
1468         } else {
1469                 if (!check_error(__LINE__, cli, 
1470                                  ERRDOS, ERRlock, 
1471                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1472         }
1473
1474         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1475                 printf("lock3 succeeded! This is a locking bug\n");
1476                 correct = False;
1477         } else {
1478                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1479         }
1480
1481         cli_setpid(cli, 1);
1482
1483         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1484                 printf("close1 failed (%s)\n", cli_errstr(cli));
1485                 return False;
1486         }
1487
1488         if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1489                 printf("close2 failed (%s)\n", cli_errstr(cli));
1490                 return False;
1491         }
1492
1493         if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1494                 printf("close3 failed (%s)\n", cli_errstr(cli));
1495                 return False;
1496         }
1497
1498         if (!torture_close_connection(cli)) {
1499                 correct = False;
1500         }
1501
1502         printf("locktest2 finished\n");
1503
1504         return correct;
1505 }
1506
1507
1508 /*
1509   This test checks that 
1510
1511   1) the server supports the full offset range in lock requests
1512 */
1513 static bool run_locktest3(int dummy)
1514 {
1515         static struct cli_state *cli1, *cli2;
1516         const char *fname = "\\lockt3.lck";
1517         uint16_t fnum1, fnum2;
1518         int i;
1519         uint32 offset;
1520         bool correct = True;
1521
1522 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1523
1524         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1525                 return False;
1526         }
1527         cli_sockopt(cli1, sockops);
1528         cli_sockopt(cli2, sockops);
1529
1530         printf("starting locktest3\n");
1531
1532         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1533
1534         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1535                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1536                 return False;
1537         }
1538         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1539                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1540                 return False;
1541         }
1542
1543         for (offset=i=0;i<torture_numops;i++) {
1544                 NEXT_OFFSET;
1545                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1546                         printf("lock1 %d failed (%s)\n", 
1547                                i,
1548                                cli_errstr(cli1));
1549                         return False;
1550                 }
1551
1552                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1553                         printf("lock2 %d failed (%s)\n", 
1554                                i,
1555                                cli_errstr(cli1));
1556                         return False;
1557                 }
1558         }
1559
1560         for (offset=i=0;i<torture_numops;i++) {
1561                 NEXT_OFFSET;
1562
1563                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1564                         printf("error: lock1 %d succeeded!\n", i);
1565                         return False;
1566                 }
1567
1568                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1569                         printf("error: lock2 %d succeeded!\n", i);
1570                         return False;
1571                 }
1572
1573                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1574                         printf("error: lock3 %d succeeded!\n", i);
1575                         return False;
1576                 }
1577
1578                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1579                         printf("error: lock4 %d succeeded!\n", i);
1580                         return False;
1581                 }
1582         }
1583
1584         for (offset=i=0;i<torture_numops;i++) {
1585                 NEXT_OFFSET;
1586
1587                 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1588                         printf("unlock1 %d failed (%s)\n", 
1589                                i,
1590                                cli_errstr(cli1));
1591                         return False;
1592                 }
1593
1594                 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1595                         printf("unlock2 %d failed (%s)\n", 
1596                                i,
1597                                cli_errstr(cli1));
1598                         return False;
1599                 }
1600         }
1601
1602         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1603                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1604                 return False;
1605         }
1606
1607         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1608                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1609                 return False;
1610         }
1611
1612         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1613                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1614                 return False;
1615         }
1616
1617         if (!torture_close_connection(cli1)) {
1618                 correct = False;
1619         }
1620
1621         if (!torture_close_connection(cli2)) {
1622                 correct = False;
1623         }
1624
1625         printf("finished locktest3\n");
1626
1627         return correct;
1628 }
1629
1630 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1631         printf("** "); correct = False; \
1632         }
1633
1634 /*
1635   looks at overlapping locks
1636 */
1637 static bool run_locktest4(int dummy)
1638 {
1639         static struct cli_state *cli1, *cli2;
1640         const char *fname = "\\lockt4.lck";
1641         uint16_t fnum1, fnum2, f;
1642         bool ret;
1643         char buf[1000];
1644         bool correct = True;
1645
1646         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1647                 return False;
1648         }
1649
1650         cli_sockopt(cli1, sockops);
1651         cli_sockopt(cli2, sockops);
1652
1653         printf("starting locktest4\n");
1654
1655         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1656
1657         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1658         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1659
1660         memset(buf, 0, sizeof(buf));
1661
1662         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1663                 printf("Failed to create file\n");
1664                 correct = False;
1665                 goto fail;
1666         }
1667
1668         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1669               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1670         EXPECTED(ret, False);
1671         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1672
1673         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1674               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1675         EXPECTED(ret, True);
1676         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1677
1678         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1679               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1680         EXPECTED(ret, False);
1681         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1682
1683         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1684               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1685         EXPECTED(ret, True);
1686         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1687
1688         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1689               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1690         EXPECTED(ret, False);
1691         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1692
1693         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1694               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1695         EXPECTED(ret, True);
1696         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1697
1698         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1699               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1700         EXPECTED(ret, True);
1701         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1702
1703         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1704               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1705         EXPECTED(ret, False);
1706         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1707
1708         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1709               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1710         EXPECTED(ret, False);
1711         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1712
1713         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1714               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1715         EXPECTED(ret, True);
1716         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1717
1718         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1719               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1720         EXPECTED(ret, False);
1721         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1722
1723         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1724               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1725               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1726         EXPECTED(ret, False);
1727         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1728
1729
1730         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1731               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1732         EXPECTED(ret, False);
1733         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1734
1735         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1736               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1737         EXPECTED(ret, False);
1738         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1739
1740
1741         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1742               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1743               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1744               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1745         EXPECTED(ret, True);
1746         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1747
1748
1749         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1750               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1751               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1752               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1753               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1754               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1755         EXPECTED(ret, True);
1756         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1757
1758         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1759               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1760               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1761               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1762         EXPECTED(ret, True);
1763         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1764
1765         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1766               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1767               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1768               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1769         EXPECTED(ret, True);
1770         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1771
1772         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1773               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1774               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1775               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1776               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1777         EXPECTED(ret, True);
1778         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1779
1780         cli_close(cli1, fnum1);
1781         cli_close(cli2, fnum2);
1782         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1783         cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1784         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1785               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1786               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1787               NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1788               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1789         cli_close(cli1, f);
1790         cli_close(cli1, fnum1);
1791         EXPECTED(ret, True);
1792         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1793
1794  fail:
1795         cli_close(cli1, fnum1);
1796         cli_close(cli2, fnum2);
1797         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1798         torture_close_connection(cli1);
1799         torture_close_connection(cli2);
1800
1801         printf("finished locktest4\n");
1802         return correct;
1803 }
1804
1805 /*
1806   looks at lock upgrade/downgrade.
1807 */
1808 static bool run_locktest5(int dummy)
1809 {
1810         static struct cli_state *cli1, *cli2;
1811         const char *fname = "\\lockt5.lck";
1812         uint16_t fnum1, fnum2, fnum3;
1813         bool ret;
1814         char buf[1000];
1815         bool correct = True;
1816
1817         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1818                 return False;
1819         }
1820
1821         cli_sockopt(cli1, sockops);
1822         cli_sockopt(cli2, sockops);
1823
1824         printf("starting locktest5\n");
1825
1826         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1827
1828         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1829         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1830         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1831
1832         memset(buf, 0, sizeof(buf));
1833
1834         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1835                 printf("Failed to create file\n");
1836                 correct = False;
1837                 goto fail;
1838         }
1839
1840         /* Check for NT bug... */
1841         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1842                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1843         cli_close(cli1, fnum1);
1844         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1845         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1846         EXPECTED(ret, True);
1847         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1848         cli_close(cli1, fnum1);
1849         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1850         cli_unlock(cli1, fnum3, 0, 1);
1851
1852         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1853               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1854         EXPECTED(ret, True);
1855         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1856
1857         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1858         EXPECTED(ret, False);
1859
1860         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1861
1862         /* Unlock the process 2 lock. */
1863         cli_unlock(cli2, fnum2, 0, 4);
1864
1865         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1866         EXPECTED(ret, False);
1867
1868         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1869
1870         /* Unlock the process 1 fnum3 lock. */
1871         cli_unlock(cli1, fnum3, 0, 4);
1872
1873         /* Stack 2 more locks here. */
1874         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1875                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1876
1877         EXPECTED(ret, True);
1878         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1879
1880         /* Unlock the first process lock, then check this was the WRITE lock that was
1881                 removed. */
1882
1883         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1884                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1885
1886         EXPECTED(ret, True);
1887         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1888
1889         /* Unlock the process 2 lock. */
1890         cli_unlock(cli2, fnum2, 0, 4);
1891
1892         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1893
1894         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1895                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1896                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1897
1898         EXPECTED(ret, True);
1899         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1900
1901         /* Ensure the next unlock fails. */
1902         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1903         EXPECTED(ret, False);
1904         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1905
1906         /* Ensure connection 2 can get a write lock. */
1907         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1908         EXPECTED(ret, True);
1909
1910         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1911
1912
1913  fail:
1914         cli_close(cli1, fnum1);
1915         cli_close(cli2, fnum2);
1916         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1917         if (!torture_close_connection(cli1)) {
1918                 correct = False;
1919         }
1920         if (!torture_close_connection(cli2)) {
1921                 correct = False;
1922         }
1923
1924         printf("finished locktest5\n");
1925
1926         return correct;
1927 }
1928
1929 /*
1930   tries the unusual lockingX locktype bits
1931 */
1932 static bool run_locktest6(int dummy)
1933 {
1934         static struct cli_state *cli;
1935         const char *fname[1] = { "\\lock6.txt" };
1936         int i;
1937         uint16_t fnum;
1938         NTSTATUS status;
1939
1940         if (!torture_open_connection(&cli, 0)) {
1941                 return False;
1942         }
1943
1944         cli_sockopt(cli, sockops);
1945
1946         printf("starting locktest6\n");
1947
1948         for (i=0;i<1;i++) {
1949                 printf("Testing %s\n", fname[i]);
1950
1951                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1952
1953                 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1954                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1955                 cli_close(cli, fnum);
1956                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1957
1958                 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1959                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1960                 cli_close(cli, fnum);
1961                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1962
1963                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1964         }
1965
1966         torture_close_connection(cli);
1967
1968         printf("finished locktest6\n");
1969         return True;
1970 }
1971
1972 static bool run_locktest7(int dummy)
1973 {
1974         struct cli_state *cli1;
1975         const char *fname = "\\lockt7.lck";
1976         uint16_t fnum1;
1977         char buf[200];
1978         bool correct = False;
1979
1980         if (!torture_open_connection(&cli1, 0)) {
1981                 return False;
1982         }
1983
1984         cli_sockopt(cli1, sockops);
1985
1986         printf("starting locktest7\n");
1987
1988         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1989
1990         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1991
1992         memset(buf, 0, sizeof(buf));
1993
1994         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1995                 printf("Failed to create file\n");
1996                 goto fail;
1997         }
1998
1999         cli_setpid(cli1, 1);
2000
2001         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2002                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2003                 goto fail;
2004         } else {
2005                 printf("pid1 successfully locked range 130:4 for READ\n");
2006         }
2007
2008         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2009                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2010                 goto fail;
2011         } else {
2012                 printf("pid1 successfully read the range 130:4\n");
2013         }
2014
2015         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2016                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2017                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2018                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2019                         goto fail;
2020                 }
2021         } else {
2022                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2023                 goto fail;
2024         }
2025
2026         cli_setpid(cli1, 2);
2027
2028         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2029                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2030         } else {
2031                 printf("pid2 successfully read the range 130:4\n");
2032         }
2033
2034         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2035                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2036                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2037                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2038                         goto fail;
2039                 }
2040         } else {
2041                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2042                 goto fail;
2043         }
2044
2045         cli_setpid(cli1, 1);
2046         cli_unlock(cli1, fnum1, 130, 4);
2047
2048         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2049                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2050                 goto fail;
2051         } else {
2052                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2053         }
2054
2055         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2056                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2057                 goto fail;
2058         } else {
2059                 printf("pid1 successfully read the range 130:4\n");
2060         }
2061
2062         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2063                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2064                 goto fail;
2065         } else {
2066                 printf("pid1 successfully wrote to the range 130:4\n");
2067         }
2068
2069         cli_setpid(cli1, 2);
2070
2071         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2072                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2073                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2074                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2075                         goto fail;
2076                 }
2077         } else {
2078                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2079                 goto fail;
2080         }
2081
2082         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2083                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2084                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2085                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2086                         goto fail;
2087                 }
2088         } else {
2089                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2090                 goto fail;
2091         }
2092
2093         cli_unlock(cli1, fnum1, 130, 0);
2094         correct = True;
2095
2096 fail:
2097         cli_close(cli1, fnum1);
2098         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2099         torture_close_connection(cli1);
2100
2101         printf("finished locktest7\n");
2102         return correct;
2103 }
2104
2105 /*
2106  * This demonstrates a problem with our use of GPFS share modes: A file
2107  * descriptor sitting in the pending close queue holding a GPFS share mode
2108  * blocks opening a file another time. Happens with Word 2007 temp files.
2109  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2110  * open is denied with NT_STATUS_SHARING_VIOLATION.
2111  */
2112
2113 static bool run_locktest8(int dummy)
2114 {
2115         struct cli_state *cli1;
2116         const char *fname = "\\lockt8.lck";
2117         uint16_t fnum1, fnum2;
2118         char buf[200];
2119         bool correct = False;
2120         NTSTATUS status;
2121
2122         if (!torture_open_connection(&cli1, 0)) {
2123                 return False;
2124         }
2125
2126         cli_sockopt(cli1, sockops);
2127
2128         printf("starting locktest8\n");
2129
2130         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2131
2132         status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2133                           &fnum1);
2134         if (!NT_STATUS_IS_OK(status)) {
2135                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2136                 return false;
2137         }
2138
2139         memset(buf, 0, sizeof(buf));
2140
2141         status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2142         if (!NT_STATUS_IS_OK(status)) {
2143                 d_fprintf(stderr, "cli_open second time returned %s\n",
2144                           cli_errstr(cli1));
2145                 goto fail;
2146         }
2147
2148         if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2149                 printf("Unable to apply read lock on range 1:1, error was "
2150                        "%s\n", cli_errstr(cli1));
2151                 goto fail;
2152         }
2153
2154         status = cli_close(cli1, fnum1);
2155         if (!NT_STATUS_IS_OK(status)) {
2156                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2157                 goto fail;
2158         }
2159
2160         status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2161         if (!NT_STATUS_IS_OK(status)) {
2162                 d_fprintf(stderr, "cli_open third time returned %s\n",
2163                           cli_errstr(cli1));
2164                 goto fail;
2165         }
2166
2167         correct = true;
2168
2169 fail:
2170         cli_close(cli1, fnum1);
2171         cli_close(cli1, fnum2);
2172         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2173         torture_close_connection(cli1);
2174
2175         printf("finished locktest8\n");
2176         return correct;
2177 }
2178
2179 /*
2180  * This test is designed to be run in conjunction with
2181  * external NFS or POSIX locks taken in the filesystem.
2182  * It checks that the smbd server will block until the
2183  * lock is released and then acquire it. JRA.
2184  */
2185
2186 static bool got_alarm;
2187 static int alarm_fd;
2188
2189 static void alarm_handler(int dummy)
2190 {
2191         got_alarm = True;
2192 }
2193
2194 static void alarm_handler_parent(int dummy)
2195 {
2196         close(alarm_fd);
2197 }
2198
2199 static void do_local_lock(int read_fd, int write_fd)
2200 {
2201         int fd;
2202         char c = '\0';
2203         struct flock lock;
2204         const char *local_pathname = NULL;
2205         int ret;
2206
2207         local_pathname = talloc_asprintf(talloc_tos(),
2208                         "%s/lockt9.lck", local_path);
2209         if (!local_pathname) {
2210                 printf("child: alloc fail\n");
2211                 exit(1);
2212         }
2213
2214         unlink(local_pathname);
2215         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2216         if (fd == -1) {
2217                 printf("child: open of %s failed %s.\n",
2218                         local_pathname, strerror(errno));
2219                 exit(1);
2220         }
2221
2222         /* Now take a fcntl lock. */
2223         lock.l_type = F_WRLCK;
2224         lock.l_whence = SEEK_SET;
2225         lock.l_start = 0;
2226         lock.l_len = 4;
2227         lock.l_pid = getpid();
2228
2229         ret = fcntl(fd,F_SETLK,&lock);
2230         if (ret == -1) {
2231                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2232                         local_pathname, strerror(errno));
2233                 exit(1);
2234         } else {
2235                 printf("child: got lock 0:4 on file %s.\n",
2236                         local_pathname );
2237                 fflush(stdout);
2238         }
2239
2240         CatchSignal(SIGALRM, alarm_handler);
2241         alarm(5);
2242         /* Signal the parent. */
2243         if (write(write_fd, &c, 1) != 1) {
2244                 printf("child: start signal fail %s.\n",
2245                         strerror(errno));
2246                 exit(1);
2247         }
2248         alarm(0);
2249
2250         alarm(10);
2251         /* Wait for the parent to be ready. */
2252         if (read(read_fd, &c, 1) != 1) {
2253                 printf("child: reply signal fail %s.\n",
2254                         strerror(errno));
2255                 exit(1);
2256         }
2257         alarm(0);
2258
2259         sleep(5);
2260         close(fd);
2261         printf("child: released lock 0:4 on file %s.\n",
2262                 local_pathname );
2263         fflush(stdout);
2264         exit(0);
2265 }
2266
2267 static bool run_locktest9(int dummy)
2268 {
2269         struct cli_state *cli1;
2270         const char *fname = "\\lockt9.lck";
2271         uint16_t fnum;
2272         bool correct = False;
2273         int pipe_in[2], pipe_out[2];
2274         pid_t child_pid;
2275         char c = '\0';
2276         int ret;
2277         struct timeval start;
2278         double seconds;
2279         NTSTATUS status;
2280
2281         printf("starting locktest9\n");
2282
2283         if (local_path == NULL) {
2284                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2285                 return false;
2286         }
2287
2288         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2289                 return false;
2290         }
2291
2292         child_pid = fork();
2293         if (child_pid == -1) {
2294                 return false;
2295         }
2296
2297         if (child_pid == 0) {
2298                 /* Child. */
2299                 do_local_lock(pipe_out[0], pipe_in[1]);
2300                 exit(0);
2301         }
2302
2303         close(pipe_out[0]);
2304         close(pipe_in[1]);
2305         pipe_out[0] = -1;
2306         pipe_in[1] = -1;
2307
2308         /* Parent. */
2309         ret = read(pipe_in[0], &c, 1);
2310         if (ret != 1) {
2311                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2312                         strerror(errno));
2313                 return false;
2314         }
2315
2316         if (!torture_open_connection(&cli1, 0)) {
2317                 return false;
2318         }
2319
2320         cli_sockopt(cli1, sockops);
2321
2322         status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2323                           &fnum);
2324         if (!NT_STATUS_IS_OK(status)) {
2325                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2326                 return false;
2327         }
2328
2329         /* Ensure the child has the lock. */
2330         if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2331                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2332                 goto fail;
2333         } else {
2334                 d_printf("Child has the lock.\n");
2335         }
2336
2337         /* Tell the child to wait 5 seconds then exit. */
2338         ret = write(pipe_out[1], &c, 1);
2339         if (ret != 1) {
2340                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2341                         strerror(errno));
2342                 goto fail;
2343         }
2344
2345         /* Wait 20 seconds for the lock. */
2346         alarm_fd = cli1->fd;
2347         CatchSignal(SIGALRM, alarm_handler_parent);
2348         alarm(20);
2349
2350         start = timeval_current();
2351
2352         if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2353                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2354                        "%s\n", cli_errstr(cli1));
2355                 goto fail_nofd;
2356         }
2357         alarm(0);
2358
2359         seconds = timeval_elapsed(&start);
2360
2361         printf("Parent got the lock after %.2f seconds.\n",
2362                 seconds);
2363
2364         status = cli_close(cli1, fnum);
2365         if (!NT_STATUS_IS_OK(status)) {
2366                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2367                 goto fail;
2368         }
2369
2370         correct = true;
2371
2372 fail:
2373         cli_close(cli1, fnum);
2374         torture_close_connection(cli1);
2375
2376 fail_nofd:
2377
2378         printf("finished locktest9\n");
2379         return correct;
2380 }
2381
2382 /*
2383 test whether fnums and tids open on one VC are available on another (a major
2384 security hole)
2385 */
2386 static bool run_fdpasstest(int dummy)
2387 {
2388         struct cli_state *cli1, *cli2;
2389         const char *fname = "\\fdpass.tst";
2390         uint16_t fnum1;
2391         char buf[1024];
2392
2393         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2394                 return False;
2395         }
2396         cli_sockopt(cli1, sockops);
2397         cli_sockopt(cli2, sockops);
2398
2399         printf("starting fdpasstest\n");
2400
2401         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2402
2403         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2404                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2405                 return False;
2406         }
2407
2408         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2409                 printf("write failed (%s)\n", cli_errstr(cli1));
2410                 return False;
2411         }
2412
2413         cli2->vuid = cli1->vuid;
2414         cli2->cnum = cli1->cnum;
2415         cli2->pid = cli1->pid;
2416
2417         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2418                 printf("read succeeded! nasty security hole [%s]\n",
2419                        buf);
2420                 return False;
2421         }
2422
2423         cli_close(cli1, fnum1);
2424         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2425
2426         torture_close_connection(cli1);
2427         torture_close_connection(cli2);
2428
2429         printf("finished fdpasstest\n");
2430         return True;
2431 }
2432
2433 static bool run_fdsesstest(int dummy)
2434 {
2435         struct cli_state *cli;
2436         uint16 new_vuid;
2437         uint16 saved_vuid;
2438         uint16 new_cnum;
2439         uint16 saved_cnum;
2440         const char *fname = "\\fdsess.tst";
2441         const char *fname1 = "\\fdsess1.tst";
2442         uint16_t fnum1;
2443         uint16_t fnum2;
2444         char buf[1024];
2445         bool ret = True;
2446
2447         if (!torture_open_connection(&cli, 0))
2448                 return False;
2449         cli_sockopt(cli, sockops);
2450
2451         if (!torture_cli_session_setup2(cli, &new_vuid))
2452                 return False;
2453
2454         saved_cnum = cli->cnum;
2455         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2456                 return False;
2457         new_cnum = cli->cnum;
2458         cli->cnum = saved_cnum;
2459
2460         printf("starting fdsesstest\n");
2461
2462         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2463         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2464
2465         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2466                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2467                 return False;
2468         }
2469
2470         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2471                 printf("write failed (%s)\n", cli_errstr(cli));
2472                 return False;
2473         }
2474
2475         saved_vuid = cli->vuid;
2476         cli->vuid = new_vuid;
2477
2478         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2479                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2480                        buf);
2481                 ret = False;
2482         }
2483         /* Try to open a file with different vuid, samba cnum. */
2484         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2485                 printf("create with different vuid, same cnum succeeded.\n");
2486                 cli_close(cli, fnum2);
2487                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2488         } else {
2489                 printf("create with different vuid, same cnum failed.\n");
2490                 printf("This will cause problems with service clients.\n");
2491                 ret = False;
2492         }
2493
2494         cli->vuid = saved_vuid;
2495
2496         /* Try with same vuid, different cnum. */
2497         cli->cnum = new_cnum;
2498
2499         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2500                 printf("read succeeded with different cnum![%s]\n",
2501                        buf);
2502                 ret = False;
2503         }
2504
2505         cli->cnum = saved_cnum;
2506         cli_close(cli, fnum1);
2507         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2508
2509         torture_close_connection(cli);
2510
2511         printf("finished fdsesstest\n");
2512         return ret;
2513 }
2514
2515 /*
2516   This test checks that 
2517
2518   1) the server does not allow an unlink on a file that is open
2519 */
2520 static bool run_unlinktest(int dummy)
2521 {
2522         struct cli_state *cli;
2523         const char *fname = "\\unlink.tst";
2524         uint16_t fnum;
2525         bool correct = True;
2526
2527         if (!torture_open_connection(&cli, 0)) {
2528                 return False;
2529         }
2530
2531         cli_sockopt(cli, sockops);
2532
2533         printf("starting unlink test\n");
2534
2535         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2536
2537         cli_setpid(cli, 1);
2538
2539         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2540                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2541                 return False;
2542         }
2543
2544         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2545                 printf("error: server allowed unlink on an open file\n");
2546                 correct = False;
2547         } else {
2548                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2549                                       NT_STATUS_SHARING_VIOLATION);
2550         }
2551
2552         cli_close(cli, fnum);
2553         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2554
2555         if (!torture_close_connection(cli)) {
2556                 correct = False;
2557         }
2558
2559         printf("unlink test finished\n");
2560
2561         return correct;
2562 }
2563
2564
2565 /*
2566 test how many open files this server supports on the one socket
2567 */
2568 static bool run_maxfidtest(int dummy)
2569 {
2570         struct cli_state *cli;
2571         const char *ftemplate = "\\maxfid.%d.%d";
2572         fstring fname;
2573         uint16_t fnums[0x11000];
2574         int i;
2575         int retries=4;
2576         bool correct = True;
2577
2578         cli = current_cli;
2579
2580         if (retries <= 0) {
2581                 printf("failed to connect\n");
2582                 return False;
2583         }
2584
2585         cli_sockopt(cli, sockops);
2586
2587         for (i=0; i<0x11000; i++) {
2588                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2589                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2590                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2591                         printf("open of %s failed (%s)\n", 
2592                                fname, cli_errstr(cli));
2593                         printf("maximum fnum is %d\n", i);
2594                         break;
2595                 }
2596                 printf("%6d\r", i);
2597         }
2598         printf("%6d\n", i);
2599         i--;
2600
2601         printf("cleaning up\n");
2602         for (;i>=0;i--) {
2603                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2604                 cli_close(cli, fnums[i]);
2605                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2606                         printf("unlink of %s failed (%s)\n", 
2607                                fname, cli_errstr(cli));
2608                         correct = False;
2609                 }
2610                 printf("%6d\r", i);
2611         }
2612         printf("%6d\n", 0);
2613
2614         printf("maxfid test finished\n");
2615         if (!torture_close_connection(cli)) {
2616                 correct = False;
2617         }
2618         return correct;
2619 }
2620
2621 /* generate a random buffer */
2622 static void rand_buf(char *buf, int len)
2623 {
2624         while (len--) {
2625                 *buf = (char)sys_random();
2626                 buf++;
2627         }
2628 }
2629
2630 /* send smb negprot commands, not reading the response */
2631 static bool run_negprot_nowait(int dummy)
2632 {
2633         int i;
2634         static struct cli_state *cli;
2635         bool correct = True;
2636
2637         printf("starting negprot nowait test\n");
2638
2639         if (!(cli = open_nbt_connection())) {
2640                 return False;
2641         }
2642
2643         for (i=0;i<50000;i++) {
2644                 cli_negprot_sendsync(cli);
2645         }
2646
2647         if (!torture_close_connection(cli)) {
2648                 correct = False;
2649         }
2650
2651         printf("finished negprot nowait test\n");
2652
2653         return correct;
2654 }
2655
2656
2657 /* send random IPC commands */
2658 static bool run_randomipc(int dummy)
2659 {
2660         char *rparam = NULL;
2661         char *rdata = NULL;
2662         unsigned int rdrcnt,rprcnt;
2663         char param[1024];
2664         int api, param_len, i;
2665         struct cli_state *cli;
2666         bool correct = True;
2667         int count = 50000;
2668
2669         printf("starting random ipc test\n");
2670
2671         if (!torture_open_connection(&cli, 0)) {
2672                 return False;
2673         }
2674
2675         for (i=0;i<count;i++) {
2676                 api = sys_random() % 500;
2677                 param_len = (sys_random() % 64);
2678
2679                 rand_buf(param, param_len);
2680
2681                 SSVAL(param,0,api); 
2682
2683                 cli_api(cli, 
2684                         param, param_len, 8,  
2685                         NULL, 0, BUFFER_SIZE, 
2686                         &rparam, &rprcnt,     
2687                         &rdata, &rdrcnt);
2688                 if (i % 100 == 0) {
2689                         printf("%d/%d\r", i,count);
2690                 }
2691         }
2692         printf("%d/%d\n", i, count);
2693
2694         if (!torture_close_connection(cli)) {
2695                 correct = False;
2696         }
2697
2698         printf("finished random ipc test\n");
2699
2700         return correct;
2701 }
2702
2703
2704
2705 static void browse_callback(const char *sname, uint32 stype, 
2706                             const char *comment, void *state)
2707 {
2708         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2709 }
2710
2711
2712
2713 /*
2714   This test checks the browse list code
2715
2716 */
2717 static bool run_browsetest(int dummy)
2718 {
2719         static struct cli_state *cli;
2720         bool correct = True;
2721
2722         printf("starting browse test\n");
2723
2724         if (!torture_open_connection(&cli, 0)) {
2725                 return False;
2726         }
2727
2728         printf("domain list:\n");
2729         cli_NetServerEnum(cli, cli->server_domain, 
2730                           SV_TYPE_DOMAIN_ENUM,
2731                           browse_callback, NULL);
2732
2733         printf("machine list:\n");
2734         cli_NetServerEnum(cli, cli->server_domain, 
2735                           SV_TYPE_ALL,
2736                           browse_callback, NULL);
2737
2738         if (!torture_close_connection(cli)) {
2739                 correct = False;
2740         }
2741
2742         printf("browse test finished\n");
2743
2744         return correct;
2745
2746 }
2747
2748
2749 /*
2750   This checks how the getatr calls works
2751 */
2752 static bool run_attrtest(int dummy)
2753 {
2754         struct cli_state *cli;
2755         uint16_t fnum;
2756         time_t t, t2;
2757         const char *fname = "\\attrib123456789.tst";
2758         bool correct = True;
2759
2760         printf("starting attrib test\n");
2761
2762         if (!torture_open_connection(&cli, 0)) {
2763                 return False;
2764         }
2765
2766         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2767         cli_open(cli, fname, 
2768                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2769         cli_close(cli, fnum);
2770         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2771                 printf("getatr failed (%s)\n", cli_errstr(cli));
2772                 correct = False;
2773         }
2774
2775         if (abs(t - time(NULL)) > 60*60*24*10) {
2776                 printf("ERROR: SMBgetatr bug. time is %s",
2777                        ctime(&t));
2778                 t = time(NULL);
2779                 correct = True;
2780         }
2781
2782         t2 = t-60*60*24; /* 1 day ago */
2783
2784         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2785                 printf("setatr failed (%s)\n", cli_errstr(cli));
2786                 correct = True;
2787         }
2788
2789         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2790                 printf("getatr failed (%s)\n", cli_errstr(cli));
2791                 correct = True;
2792         }
2793
2794         if (t != t2) {
2795                 printf("ERROR: getatr/setatr bug. times are\n%s",
2796                        ctime(&t));
2797                 printf("%s", ctime(&t2));
2798                 correct = True;
2799         }
2800
2801         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2802
2803         if (!torture_close_connection(cli)) {
2804                 correct = False;
2805         }
2806
2807         printf("attrib test finished\n");
2808
2809         return correct;
2810 }
2811
2812
2813 /*
2814   This checks a couple of trans2 calls
2815 */
2816 static bool run_trans2test(int dummy)
2817 {
2818         struct cli_state *cli;
2819         uint16_t fnum;
2820         SMB_OFF_T size;
2821         time_t c_time, a_time, m_time;
2822         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2823         const char *fname = "\\trans2.tst";
2824         const char *dname = "\\trans2";
2825         const char *fname2 = "\\trans2\\trans2.tst";
2826         char pname[1024];
2827         bool correct = True;
2828         NTSTATUS status;
2829         uint32_t fs_attr;
2830
2831         printf("starting trans2 test\n");
2832
2833         if (!torture_open_connection(&cli, 0)) {
2834                 return False;
2835         }
2836
2837         status = cli_get_fs_attr_info(cli, &fs_attr);
2838         if (!NT_STATUS_IS_OK(status)) {
2839                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2840                        nt_errstr(status));
2841                 correct = false;
2842         }
2843
2844         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2845         cli_open(cli, fname, 
2846                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2847         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2848                            &m_time_ts, NULL)) {
2849                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2850                 correct = False;
2851         }
2852
2853         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2854                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2855                 correct = False;
2856         }
2857
2858         if (strcmp(pname, fname)) {
2859                 printf("qfilename gave different name? [%s] [%s]\n",
2860                        fname, pname);
2861                 correct = False;
2862         }
2863
2864         cli_close(cli, fnum);
2865
2866         sleep(2);
2867
2868         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2869         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2870                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2871                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2872                 return False;
2873         }
2874         cli_close(cli, fnum);
2875
2876         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2877                                 NULL);
2878         if (!NT_STATUS_IS_OK(status)) {
2879                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2880                 correct = False;
2881         } else {
2882                 if (c_time != m_time) {
2883                         printf("create time=%s", ctime(&c_time));
2884                         printf("modify time=%s", ctime(&m_time));
2885                         printf("This system appears to have sticky create times\n");
2886                 }
2887                 if (a_time % (60*60) == 0) {
2888                         printf("access time=%s", ctime(&a_time));
2889                         printf("This system appears to set a midnight access time\n");
2890                         correct = False;
2891                 }
2892
2893                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2894                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2895                         correct = False;
2896                 }
2897         }
2898
2899
2900         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2901         cli_open(cli, fname, 
2902                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2903         cli_close(cli, fnum);
2904         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2905                                 &m_time_ts, &size, NULL, NULL);
2906         if (!NT_STATUS_IS_OK(status)) {
2907                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2908                 correct = False;
2909         } else {
2910                 if (w_time_ts.tv_sec < 60*60*24*2) {
2911                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2912                         printf("This system appears to set a initial 0 write time\n");
2913                         correct = False;
2914                 }
2915         }
2916
2917         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2918
2919
2920         /* check if the server updates the directory modification time
2921            when creating a new file */
2922         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2923                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2924                 correct = False;
2925         }
2926         sleep(3);
2927         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2928                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2929         if (!NT_STATUS_IS_OK(status)) {
2930                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2931                 correct = False;
2932         }
2933
2934         cli_open(cli, fname2, 
2935                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2936         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2937         cli_close(cli, fnum);
2938         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2939                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2940         if (!NT_STATUS_IS_OK(status)) {
2941                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2942                 correct = False;
2943         } else {
2944                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2945                     == 0) {
2946                         printf("This system does not update directory modification times\n");
2947                         correct = False;
2948                 }
2949         }
2950         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2951         cli_rmdir(cli, dname);
2952
2953         if (!torture_close_connection(cli)) {
2954                 correct = False;
2955         }
2956
2957         printf("trans2 test finished\n");
2958
2959         return correct;
2960 }
2961
2962 /*
2963   This checks new W2K calls.
2964 */
2965
2966 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2967 {
2968         char *buf = NULL;
2969         uint32 len;
2970         bool correct = True;
2971
2972         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2973                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2974                 correct = False;
2975         } else {
2976                 printf("qfileinfo: level %d, len = %u\n", level, len);
2977                 dump_data(0, (uint8 *)buf, len);
2978                 printf("\n");
2979         }
2980         SAFE_FREE(buf);
2981         return correct;
2982 }
2983
2984 static bool run_w2ktest(int dummy)
2985 {
2986         struct cli_state *cli;
2987         uint16_t fnum;
2988         const char *fname = "\\w2ktest\\w2k.tst";
2989         int level;
2990         bool correct = True;
2991
2992         printf("starting w2k test\n");
2993
2994         if (!torture_open_connection(&cli, 0)) {
2995                 return False;
2996         }
2997
2998         cli_open(cli, fname, 
2999                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
3000
3001         for (level = 1004; level < 1040; level++) {
3002                 new_trans(cli, fnum, level);
3003         }
3004
3005         cli_close(cli, fnum);
3006
3007         if (!torture_close_connection(cli)) {
3008                 correct = False;
3009         }
3010
3011         printf("w2k test finished\n");
3012
3013         return correct;
3014 }
3015
3016
3017 /*
3018   this is a harness for some oplock tests
3019  */
3020 static bool run_oplock1(int dummy)
3021 {
3022         struct cli_state *cli1;
3023         const char *fname = "\\lockt1.lck";
3024         uint16_t fnum1;
3025         bool correct = True;
3026
3027         printf("starting oplock test 1\n");
3028
3029         if (!torture_open_connection(&cli1, 0)) {
3030                 return False;
3031         }
3032
3033         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3034
3035         cli_sockopt(cli1, sockops);
3036
3037         cli1->use_oplocks = True;
3038
3039         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3040                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3041                 return False;
3042         }
3043
3044         cli1->use_oplocks = False;
3045
3046         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3047         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3048
3049         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3050                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3051                 return False;
3052         }
3053
3054         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3055                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3056                 return False;
3057         }
3058
3059         if (!torture_close_connection(cli1)) {
3060                 correct = False;
3061         }
3062
3063         printf("finished oplock test 1\n");
3064
3065         return correct;
3066 }
3067
3068 static bool run_oplock2(int dummy)
3069 {
3070         struct cli_state *cli1, *cli2;
3071         const char *fname = "\\lockt2.lck";
3072         uint16_t fnum1, fnum2;
3073         int saved_use_oplocks = use_oplocks;
3074         char buf[4];
3075         bool correct = True;
3076         volatile bool *shared_correct;
3077
3078         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3079         *shared_correct = True;
3080
3081         use_level_II_oplocks = True;
3082         use_oplocks = True;
3083
3084         printf("starting oplock test 2\n");
3085
3086         if (!torture_open_connection(&cli1, 0)) {
3087                 use_level_II_oplocks = False;
3088                 use_oplocks = saved_use_oplocks;
3089                 return False;
3090         }
3091
3092         cli1->use_oplocks = True;
3093         cli1->use_level_II_oplocks = True;
3094
3095         if (!torture_open_connection(&cli2, 1)) {
3096                 use_level_II_oplocks = False;
3097                 use_oplocks = saved_use_oplocks;
3098                 return False;
3099         }
3100
3101         cli2->use_oplocks = True;
3102         cli2->use_level_II_oplocks = True;
3103
3104         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3105
3106         cli_sockopt(cli1, sockops);
3107         cli_sockopt(cli2, sockops);
3108
3109         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3110                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3111                 return False;
3112         }
3113
3114         /* Don't need the globals any more. */
3115         use_level_II_oplocks = False;
3116         use_oplocks = saved_use_oplocks;
3117
3118         if (fork() == 0) {
3119                 /* Child code */
3120                 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3121                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3122                         *shared_correct = False;
3123                         exit(0);
3124                 }
3125
3126                 sleep(2);
3127
3128                 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3129                         printf("close2 failed (%s)\n", cli_errstr(cli1));
3130                         *shared_correct = False;
3131                 }
3132
3133                 exit(0);
3134         }
3135
3136         sleep(2);
3137
3138         /* Ensure cli1 processes the break. Empty file should always return 0
3139          * bytes.  */
3140
3141         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3142                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3143                 correct = False;
3144         }
3145
3146         /* Should now be at level II. */
3147         /* Test if sending a write locks causes a break to none. */
3148
3149         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3150                 printf("lock failed (%s)\n", cli_errstr(cli1));
3151                 correct = False;
3152         }
3153
3154         cli_unlock(cli1, fnum1, 0, 4);
3155
3156         sleep(2);
3157
3158         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3159                 printf("lock failed (%s)\n", cli_errstr(cli1));
3160                 correct = False;
3161         }
3162
3163         cli_unlock(cli1, fnum1, 0, 4);