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