source: branches/samba-3.0/source/torture/torture.c

Last change on this file was 124, checked in by Paul Smedley, 17 years ago

Update source to 3.0.28a

File size: 135.3 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "includes.h"
22
23extern char *optarg;
24extern int optind;
25
26static fstring host, workgroup, share, password, username, myname;
27static int max_protocol = PROTOCOL_NT1;
28static const char *sockops="TCP_NODELAY";
29static int nprocs=1;
30static int port_to_use=0;
31int torture_numops=100;
32static int procnum; /* records process count number when forking */
33static struct cli_state *current_cli;
34static fstring randomfname;
35static BOOL use_oplocks;
36static BOOL use_level_II_oplocks;
37static const char *client_txt = "client_oplocks.txt";
38static BOOL use_kerberos;
39static fstring multishare_conn_fname;
40static BOOL use_multishare_conn = False;
41
42BOOL torture_showall = False;
43
44static double create_procs(BOOL (*fn)(int), BOOL *result);
45
46
47static struct timeval tp1,tp2;
48
49
50void start_timer(void)
51{
52 GetTimeOfDay(&tp1);
53}
54
55double end_timer(void)
56{
57 GetTimeOfDay(&tp2);
58 return((tp2.tv_sec - tp1.tv_sec) +
59 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
60}
61
62
63/* return a pointer to a anonymous shared memory segment of size "size"
64 which will persist across fork() but will disappear when all processes
65 exit
66
67 The memory is not zeroed
68
69 This function uses system5 shared memory. It takes advantage of a property
70 that the memory is not destroyed if it is attached when the id is removed
71 */
72void *shm_setup(int size)
73{
74 int shmid;
75 void *ret;
76
77 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
78 if (shmid == -1) {
79 printf("can't get shared memory\n");
80 exit(1);
81 }
82 ret = (void *)shmat(shmid, 0, 0);
83 if (!ret || ret == (void *)-1) {
84 printf("can't attach to shared memory\n");
85 return NULL;
86 }
87 /* the following releases the ipc, but note that this process
88 and all its children will still have access to the memory, its
89 just that the shmid is no longer valid for other shm calls. This
90 means we don't leave behind lots of shm segments after we exit
91
92 See Stevens "advanced programming in unix env" for details
93 */
94 shmctl(shmid, IPC_RMID, 0);
95
96 return ret;
97}
98
99
100static struct cli_state *open_nbt_connection(void)
101{
102 struct nmb_name called, calling;
103 struct in_addr ip;
104 struct cli_state *c;
105 NTSTATUS status;
106
107 make_nmb_name(&calling, myname, 0x0);
108 make_nmb_name(&called , host, 0x20);
109
110 zero_ip(&ip);
111
112 if (!(c = cli_initialise())) {
113 printf("Failed initialize cli_struct to connect with %s\n", host);
114 return NULL;
115 }
116
117 c->port = port_to_use;
118
119 status = cli_connect(c, host, &ip);
120 if (!NT_STATUS_IS_OK(status)) {
121 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
122 return NULL;
123 }
124
125 c->use_kerberos = use_kerberos;
126
127 c->timeout = 120000; /* set a really long timeout (2 minutes) */
128 if (use_oplocks) c->use_oplocks = True;
129 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
130
131 if (!cli_session_request(c, &calling, &called)) {
132 /*
133 * Well, that failed, try *SMBSERVER ...
134 * However, we must reconnect as well ...
135 */
136 status = cli_connect(c, host, &ip);
137 if (!NT_STATUS_IS_OK(status)) {
138 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
139 return NULL;
140 }
141
142 make_nmb_name(&called, "*SMBSERVER", 0x20);
143 if (!cli_session_request(c, &calling, &called)) {
144 printf("%s rejected the session\n",host);
145 printf("We tried with a called name of %s & %s\n",
146 host, "*SMBSERVER");
147 cli_shutdown(c);
148 return NULL;
149 }
150 }
151
152 return c;
153}
154
155/* Insert a NULL at the first separator of the given path and return a pointer
156 * to the remainder of the string.
157 */
158static char *
159terminate_path_at_separator(char * path)
160{
161 char * p;
162
163 if (!path) {
164 return NULL;
165 }
166
167 if ((p = strchr_m(path, '/'))) {
168 *p = '\0';
169 return p + 1;
170 }
171
172 if ((p = strchr_m(path, '\\'))) {
173 *p = '\0';
174 return p + 1;
175 }
176
177 /* No separator. */
178 return NULL;
179}
180
181/*
182 parse a //server/share type UNC name
183*/
184BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
185 char **hostname, char **sharename)
186{
187 char *p;
188
189 *hostname = *sharename = NULL;
190
191 if (strncmp(unc_name, "\\\\", 2) &&
192 strncmp(unc_name, "//", 2)) {
193 return False;
194 }
195
196 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
197 p = terminate_path_at_separator(*hostname);
198
199 if (p && *p) {
200 *sharename = talloc_strdup(mem_ctx, p);
201 terminate_path_at_separator(*sharename);
202 }
203
204 if (*hostname && *sharename) {
205 return True;
206 }
207
208 TALLOC_FREE(*hostname);
209 TALLOC_FREE(*sharename);
210 return False;
211}
212
213static BOOL torture_open_connection_share(struct cli_state **c,
214 const char *hostname,
215 const char *sharename)
216{
217 BOOL retry;
218 int flags = 0;
219 NTSTATUS status;
220
221 if (use_kerberos)
222 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
223
224 status = cli_full_connection(c, myname,
225 hostname, NULL, port_to_use,
226 sharename, "?????",
227 username, workgroup,
228 password, flags, Undefined, &retry);
229 if (!NT_STATUS_IS_OK(status)) {
230 printf("failed to open share connection: //%s/%s port:%d - %s\n",
231 hostname, sharename, port_to_use, nt_errstr(status));
232 return False;
233 }
234
235 if (use_oplocks) (*c)->use_oplocks = True;
236 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
237 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
238
239 return True;
240}
241
242void torture_open_connection_free_unclist(char **unc_list)
243{
244 if (unc_list!=NULL)
245 {
246 SAFE_FREE(unc_list[0]);
247 SAFE_FREE(unc_list);
248 }
249}
250
251BOOL torture_open_connection(struct cli_state **c, int conn_index)
252{
253 char **unc_list = NULL;
254 int num_unc_names = 0;
255 BOOL result;
256
257 if (use_multishare_conn==True) {
258 char *h, *s;
259 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
260 if (!unc_list || num_unc_names <= 0) {
261 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
262 exit(1);
263 }
264
265 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
266 NULL, &h, &s)) {
267 printf("Failed to parse UNC name %s\n",
268 unc_list[conn_index % num_unc_names]);
269 torture_open_connection_free_unclist(unc_list);
270 exit(1);
271 }
272
273 result = torture_open_connection_share(c, h, s);
274
275 /* h, s were copied earlier */
276 torture_open_connection_free_unclist(unc_list);
277 return result;
278 }
279
280 return torture_open_connection_share(c, host, share);
281}
282
283BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
284{
285 uint16 old_vuid = cli->vuid;
286 fstring old_user_name;
287 size_t passlen = strlen(password);
288 BOOL ret;
289
290 fstrcpy(old_user_name, cli->user_name);
291 cli->vuid = 0;
292 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
293 password, passlen,
294 password, passlen,
295 workgroup));
296 *new_vuid = cli->vuid;
297 cli->vuid = old_vuid;
298 fstrcpy(cli->user_name, old_user_name);
299 return ret;
300}
301
302
303BOOL torture_close_connection(struct cli_state *c)
304{
305 BOOL ret = True;
306 if (!cli_tdis(c)) {
307 printf("tdis failed (%s)\n", cli_errstr(c));
308 ret = False;
309 }
310
311 cli_shutdown(c);
312
313 return ret;
314}
315
316
317/* check if the server produced the expected error code */
318static BOOL check_error(int line, struct cli_state *c,
319 uint8 eclass, uint32 ecode, NTSTATUS nterr)
320{
321 if (cli_is_dos_error(c)) {
322 uint8 cclass;
323 uint32 num;
324
325 /* Check DOS error */
326
327 cli_dos_error(c, &cclass, &num);
328
329 if (eclass != cclass || ecode != num) {
330 printf("unexpected error code class=%d code=%d\n",
331 (int)cclass, (int)num);
332 printf(" expected %d/%d %s (line=%d)\n",
333 (int)eclass, (int)ecode, nt_errstr(nterr), line);
334 return False;
335 }
336
337 } else {
338 NTSTATUS status;
339
340 /* Check NT error */
341
342 status = cli_nt_error(c);
343
344 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
345 printf("unexpected error code %s\n", nt_errstr(status));
346 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
347 return False;
348 }
349 }
350
351 return True;
352}
353
354
355static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
356{
357 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
358 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
359 }
360 return True;
361}
362
363
364static BOOL rw_torture(struct cli_state *c)
365{
366 const char *lockfname = "\\torture.lck";
367 fstring fname;
368 int fnum;
369 int fnum2;
370 pid_t pid2, pid = getpid();
371 int i, j;
372 char buf[1024];
373 BOOL correct = True;
374
375 memset(buf, '\0', sizeof(buf));
376
377 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
378 DENY_NONE);
379 if (fnum2 == -1)
380 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
381 if (fnum2 == -1) {
382 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
383 return False;
384 }
385
386
387 for (i=0;i<torture_numops;i++) {
388 unsigned n = (unsigned)sys_random()%10;
389 if (i % 10 == 0) {
390 printf("%d\r", i); fflush(stdout);
391 }
392 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
393
394 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
395 return False;
396 }
397
398 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
399 if (fnum == -1) {
400 printf("open failed (%s)\n", cli_errstr(c));
401 correct = False;
402 break;
403 }
404
405 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
406 printf("write failed (%s)\n", cli_errstr(c));
407 correct = False;
408 }
409
410 for (j=0;j<50;j++) {
411 if (cli_write(c, fnum, 0, (char *)buf,
412 sizeof(pid)+(j*sizeof(buf)),
413 sizeof(buf)) != sizeof(buf)) {
414 printf("write failed (%s)\n", cli_errstr(c));
415 correct = False;
416 }
417 }
418
419 pid2 = 0;
420
421 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
422 printf("read failed (%s)\n", cli_errstr(c));
423 correct = False;
424 }
425
426 if (pid2 != pid) {
427 printf("data corruption!\n");
428 correct = False;
429 }
430
431 if (!cli_close(c, fnum)) {
432 printf("close failed (%s)\n", cli_errstr(c));
433 correct = False;
434 }
435
436 if (!cli_unlink(c, fname)) {
437 printf("unlink failed (%s)\n", cli_errstr(c));
438 correct = False;
439 }
440
441 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
442 printf("unlock failed (%s)\n", cli_errstr(c));
443 correct = False;
444 }
445 }
446
447 cli_close(c, fnum2);
448 cli_unlink(c, lockfname);
449
450 printf("%d\n", i);
451
452 return correct;
453}
454
455static BOOL run_torture(int dummy)
456{
457 struct cli_state *cli;
458 BOOL ret;
459
460 cli = current_cli;
461
462 cli_sockopt(cli, sockops);
463
464 ret = rw_torture(cli);
465
466 if (!torture_close_connection(cli)) {
467 ret = False;
468 }
469
470 return ret;
471}
472
473static BOOL rw_torture3(struct cli_state *c, char *lockfname)
474{
475 int fnum = -1;
476 unsigned int i = 0;
477 char buf[131072];
478 char buf_rd[131072];
479 unsigned count;
480 unsigned countprev = 0;
481 ssize_t sent = 0;
482 BOOL correct = True;
483
484 srandom(1);
485 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
486 {
487 SIVAL(buf, i, sys_random());
488 }
489
490 if (procnum == 0)
491 {
492 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
493 DENY_NONE);
494 if (fnum == -1) {
495 printf("first open read/write of %s failed (%s)\n",
496 lockfname, cli_errstr(c));
497 return False;
498 }
499 }
500 else
501 {
502 for (i = 0; i < 500 && fnum == -1; i++)
503 {
504 fnum = cli_open(c, lockfname, O_RDONLY,
505 DENY_NONE);
506 smb_msleep(10);
507 }
508 if (fnum == -1) {
509 printf("second open read-only of %s failed (%s)\n",
510 lockfname, cli_errstr(c));
511 return False;
512 }
513 }
514
515 i = 0;
516 for (count = 0; count < sizeof(buf); count += sent)
517 {
518 if (count >= countprev) {
519 printf("%d %8d\r", i, count);
520 fflush(stdout);
521 i++;
522 countprev += (sizeof(buf) / 20);
523 }
524
525 if (procnum == 0)
526 {
527 sent = ((unsigned)sys_random()%(20))+ 1;
528 if (sent > sizeof(buf) - count)
529 {
530 sent = sizeof(buf) - count;
531 }
532
533 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
534 printf("write failed (%s)\n", cli_errstr(c));
535 correct = False;
536 }
537 }
538 else
539 {
540 sent = cli_read(c, fnum, buf_rd+count, count,
541 sizeof(buf)-count);
542 if (sent < 0)
543 {
544 printf("read failed offset:%d size:%ld (%s)\n",
545 count, (unsigned long)sizeof(buf)-count,
546 cli_errstr(c));
547 correct = False;
548 sent = 0;
549 }
550 if (sent > 0)
551 {
552 if (memcmp(buf_rd+count, buf+count, sent) != 0)
553 {
554 printf("read/write compare failed\n");
555 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
556 correct = False;
557 break;
558 }
559 }
560 }
561
562 }
563
564 if (!cli_close(c, fnum)) {
565 printf("close failed (%s)\n", cli_errstr(c));
566 correct = False;
567 }
568
569 return correct;
570}
571
572static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
573{
574 const char *lockfname = "\\torture2.lck";
575 int fnum1;
576 int fnum2;
577 int i;
578 char buf[131072];
579 char buf_rd[131072];
580 BOOL correct = True;
581 ssize_t bytes_read;
582
583 if (!cli_unlink(c1, lockfname)) {
584 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
585 }
586
587 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
588 DENY_NONE);
589 if (fnum1 == -1) {
590 printf("first open read/write of %s failed (%s)\n",
591 lockfname, cli_errstr(c1));
592 return False;
593 }
594 fnum2 = cli_open(c2, lockfname, O_RDONLY,
595 DENY_NONE);
596 if (fnum2 == -1) {
597 printf("second open read-only of %s failed (%s)\n",
598 lockfname, cli_errstr(c2));
599 cli_close(c1, fnum1);
600 return False;
601 }
602
603 for (i=0;i<torture_numops;i++)
604 {
605 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
606 if (i % 10 == 0) {
607 printf("%d\r", i); fflush(stdout);
608 }
609
610 generate_random_buffer((unsigned char *)buf, buf_size);
611
612 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
613 printf("write failed (%s)\n", cli_errstr(c1));
614 correct = False;
615 break;
616 }
617
618 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
619 printf("read failed (%s)\n", cli_errstr(c2));
620 printf("read %d, expected %ld\n", (int)bytes_read,
621 (unsigned long)buf_size);
622 correct = False;
623 break;
624 }
625
626 if (memcmp(buf_rd, buf, buf_size) != 0)
627 {
628 printf("read/write compare failed\n");
629 correct = False;
630 break;
631 }
632 }
633
634 if (!cli_close(c2, fnum2)) {
635 printf("close failed (%s)\n", cli_errstr(c2));
636 correct = False;
637 }
638 if (!cli_close(c1, fnum1)) {
639 printf("close failed (%s)\n", cli_errstr(c1));
640 correct = False;
641 }
642
643 if (!cli_unlink(c1, lockfname)) {
644 printf("unlink failed (%s)\n", cli_errstr(c1));
645 correct = False;
646 }
647
648 return correct;
649}
650
651static BOOL run_readwritetest(int dummy)
652{
653 static struct cli_state *cli1, *cli2;
654 BOOL test1, test2 = False;
655
656 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
657 return False;
658 }
659 cli_sockopt(cli1, sockops);
660 cli_sockopt(cli2, sockops);
661
662 printf("starting readwritetest\n");
663
664 test1 = rw_torture2(cli1, cli2);
665 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
666
667 if (test1) {
668 test2 = rw_torture2(cli1, cli1);
669 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
670 }
671
672 if (!torture_close_connection(cli1)) {
673 test1 = False;
674 }
675
676 if (!torture_close_connection(cli2)) {
677 test2 = False;
678 }
679
680 return (test1 && test2);
681}
682
683static BOOL run_readwritemulti(int dummy)
684{
685 struct cli_state *cli;
686 BOOL test;
687
688 cli = current_cli;
689
690 cli_sockopt(cli, sockops);
691
692 printf("run_readwritemulti: fname %s\n", randomfname);
693 test = rw_torture3(cli, randomfname);
694
695 if (!torture_close_connection(cli)) {
696 test = False;
697 }
698
699 return test;
700}
701
702static BOOL run_readwritelarge(int dummy)
703{
704 static struct cli_state *cli1;
705 int fnum1;
706 const char *lockfname = "\\large.dat";
707 SMB_OFF_T fsize;
708 char buf[126*1024];
709 BOOL correct = True;
710
711 if (!torture_open_connection(&cli1, 0)) {
712 return False;
713 }
714 cli_sockopt(cli1, sockops);
715 memset(buf,'\0',sizeof(buf));
716
717 cli1->max_xmit = 128*1024;
718
719 printf("starting readwritelarge\n");
720
721 cli_unlink(cli1, lockfname);
722
723 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
724 if (fnum1 == -1) {
725 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
726 return False;
727 }
728
729 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
730
731 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
732 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
733 correct = False;
734 }
735
736 if (fsize == sizeof(buf))
737 printf("readwritelarge test 1 succeeded (size = %lx)\n",
738 (unsigned long)fsize);
739 else {
740 printf("readwritelarge test 1 failed (size = %lx)\n",
741 (unsigned long)fsize);
742 correct = False;
743 }
744
745 if (!cli_close(cli1, fnum1)) {
746 printf("close failed (%s)\n", cli_errstr(cli1));
747 correct = False;
748 }
749
750 if (!cli_unlink(cli1, lockfname)) {
751 printf("unlink failed (%s)\n", cli_errstr(cli1));
752 correct = False;
753 }
754
755 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
756 if (fnum1 == -1) {
757 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
758 return False;
759 }
760
761 cli1->max_xmit = 4*1024;
762
763 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
764
765 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
766 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
767 correct = False;
768 }
769
770 if (fsize == sizeof(buf))
771 printf("readwritelarge test 2 succeeded (size = %lx)\n",
772 (unsigned long)fsize);
773 else {
774 printf("readwritelarge test 2 failed (size = %lx)\n",
775 (unsigned long)fsize);
776 correct = False;
777 }
778
779#if 0
780 /* ToDo - set allocation. JRA */
781 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
782 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
783 return False;
784 }
785 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
786 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
787 correct = False;
788 }
789 if (fsize != 0)
790 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
791#endif
792
793 if (!cli_close(cli1, fnum1)) {
794 printf("close failed (%s)\n", cli_errstr(cli1));
795 correct = False;
796 }
797
798 if (!torture_close_connection(cli1)) {
799 correct = False;
800 }
801 return correct;
802}
803
804int line_count = 0;
805int nbio_id;
806
807#define ival(s) strtol(s, NULL, 0)
808
809/* run a test that simulates an approximate netbench client load */
810static BOOL run_netbench(int client)
811{
812 struct cli_state *cli;
813 int i;
814 pstring line;
815 char cname[20];
816 FILE *f;
817 const char *params[20];
818 BOOL correct = True;
819
820 cli = current_cli;
821
822 nbio_id = client;
823
824 cli_sockopt(cli, sockops);
825
826 nb_setup(cli);
827
828 slprintf(cname,sizeof(cname)-1, "client%d", client);
829
830 f = fopen(client_txt, "r");
831
832 if (!f) {
833 perror(client_txt);
834 return False;
835 }
836
837 while (fgets(line, sizeof(line)-1, f)) {
838 line_count++;
839
840 line[strlen(line)-1] = 0;
841
842 /* printf("[%d] %s\n", line_count, line); */
843
844 all_string_sub(line,"client1", cname, sizeof(line));
845
846 /* parse the command parameters */
847 params[0] = strtok(line," ");
848 i = 0;
849 while (params[i]) params[++i] = strtok(NULL," ");
850
851 params[i] = "";
852
853 if (i < 2) continue;
854
855 if (!strncmp(params[0],"SMB", 3)) {
856 printf("ERROR: You are using a dbench 1 load file\n");
857 exit(1);
858 }
859
860 if (!strcmp(params[0],"NTCreateX")) {
861 nb_createx(params[1], ival(params[2]), ival(params[3]),
862 ival(params[4]));
863 } else if (!strcmp(params[0],"Close")) {
864 nb_close(ival(params[1]));
865 } else if (!strcmp(params[0],"Rename")) {
866 nb_rename(params[1], params[2]);
867 } else if (!strcmp(params[0],"Unlink")) {
868 nb_unlink(params[1]);
869 } else if (!strcmp(params[0],"Deltree")) {
870 nb_deltree(params[1]);
871 } else if (!strcmp(params[0],"Rmdir")) {
872 nb_rmdir(params[1]);
873 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
874 nb_qpathinfo(params[1]);
875 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
876 nb_qfileinfo(ival(params[1]));
877 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
878 nb_qfsinfo(ival(params[1]));
879 } else if (!strcmp(params[0],"FIND_FIRST")) {
880 nb_findfirst(params[1]);
881 } else if (!strcmp(params[0],"WriteX")) {
882 nb_writex(ival(params[1]),
883 ival(params[2]), ival(params[3]), ival(params[4]));
884 } else if (!strcmp(params[0],"ReadX")) {
885 nb_readx(ival(params[1]),
886 ival(params[2]), ival(params[3]), ival(params[4]));
887 } else if (!strcmp(params[0],"Flush")) {
888 nb_flush(ival(params[1]));
889 } else {
890 printf("Unknown operation %s\n", params[0]);
891 exit(1);
892 }
893 }
894 fclose(f);
895
896 nb_cleanup();
897
898 if (!torture_close_connection(cli)) {
899 correct = False;
900 }
901
902 return correct;
903}
904
905
906/* run a test that simulates an approximate netbench client load */
907static BOOL run_nbench(int dummy)
908{
909 double t;
910 BOOL correct = True;
911
912 nbio_shmem(nprocs);
913
914 nbio_id = -1;
915
916 signal(SIGALRM, nb_alarm);
917 alarm(1);
918 t = create_procs(run_netbench, &correct);
919 alarm(0);
920
921 printf("\nThroughput %g MB/sec\n",
922 1.0e-6 * nbio_total() / t);
923 return correct;
924}
925
926
927/*
928 This test checks for two things:
929
930 1) correct support for retaining locks over a close (ie. the server
931 must not use posix semantics)
932 2) support for lock timeouts
933 */
934static BOOL run_locktest1(int dummy)
935{
936 struct cli_state *cli1, *cli2;
937 const char *fname = "\\lockt1.lck";
938 int fnum1, fnum2, fnum3;
939 time_t t1, t2;
940 unsigned lock_timeout;
941
942 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
943 return False;
944 }
945 cli_sockopt(cli1, sockops);
946 cli_sockopt(cli2, sockops);
947
948 printf("starting locktest1\n");
949
950 cli_unlink(cli1, fname);
951
952 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
953 if (fnum1 == -1) {
954 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
955 return False;
956 }
957 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
958 if (fnum2 == -1) {
959 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
960 return False;
961 }
962 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
963 if (fnum3 == -1) {
964 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
965 return False;
966 }
967
968 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
969 printf("lock1 failed (%s)\n", cli_errstr(cli1));
970 return False;
971 }
972
973
974 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
975 printf("lock2 succeeded! This is a locking bug\n");
976 return False;
977 } else {
978 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
979 NT_STATUS_LOCK_NOT_GRANTED)) return False;
980 }
981
982
983 lock_timeout = (1 + (random() % 20));
984 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
985 t1 = time(NULL);
986 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
987 printf("lock3 succeeded! This is a locking bug\n");
988 return False;
989 } else {
990 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
991 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
992 }
993 t2 = time(NULL);
994
995 if (ABS(t2 - t1) < lock_timeout-1) {
996 printf("error: This server appears not to support timed lock requests\n");
997 }
998
999 printf("server slept for %u seconds for a %u second timeout\n",
1000 (unsigned int)(t2-t1), lock_timeout);
1001
1002 if (!cli_close(cli1, fnum2)) {
1003 printf("close1 failed (%s)\n", cli_errstr(cli1));
1004 return False;
1005 }
1006
1007 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1008 printf("lock4 succeeded! This is a locking bug\n");
1009 return False;
1010 } else {
1011 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1012 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1013 }
1014
1015 if (!cli_close(cli1, fnum1)) {
1016 printf("close2 failed (%s)\n", cli_errstr(cli1));
1017 return False;
1018 }
1019
1020 if (!cli_close(cli2, fnum3)) {
1021 printf("close3 failed (%s)\n", cli_errstr(cli2));
1022 return False;
1023 }
1024
1025 if (!cli_unlink(cli1, fname)) {
1026 printf("unlink failed (%s)\n", cli_errstr(cli1));
1027 return False;
1028 }
1029
1030
1031 if (!torture_close_connection(cli1)) {
1032 return False;
1033 }
1034
1035 if (!torture_close_connection(cli2)) {
1036 return False;
1037 }
1038
1039 printf("Passed locktest1\n");
1040 return True;
1041}
1042
1043/*
1044 this checks to see if a secondary tconx can use open files from an
1045 earlier tconx
1046 */
1047static BOOL run_tcon_test(int dummy)
1048{
1049 static struct cli_state *cli;
1050 const char *fname = "\\tcontest.tmp";
1051 int fnum1;
1052 uint16 cnum1, cnum2, cnum3;
1053 uint16 vuid1, vuid2;
1054 char buf[4];
1055 BOOL ret = True;
1056
1057 memset(buf, '\0', sizeof(buf));
1058
1059 if (!torture_open_connection(&cli, 0)) {
1060 return False;
1061 }
1062 cli_sockopt(cli, sockops);
1063
1064 printf("starting tcontest\n");
1065
1066 cli_unlink(cli, fname);
1067
1068 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1069 if (fnum1 == -1) {
1070 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1071 return False;
1072 }
1073
1074 cnum1 = cli->cnum;
1075 vuid1 = cli->vuid;
1076
1077 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1078 printf("initial write failed (%s)", cli_errstr(cli));
1079 return False;
1080 }
1081
1082 if (!cli_send_tconX(cli, share, "?????",
1083 password, strlen(password)+1)) {
1084 printf("%s refused 2nd tree connect (%s)\n", host,
1085 cli_errstr(cli));
1086 cli_shutdown(cli);
1087 return False;
1088 }
1089
1090 cnum2 = cli->cnum;
1091 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1092 vuid2 = cli->vuid + 1;
1093
1094 /* try a write with the wrong tid */
1095 cli->cnum = cnum2;
1096
1097 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1098 printf("* server allows write with wrong TID\n");
1099 ret = False;
1100 } else {
1101 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1102 }
1103
1104
1105 /* try a write with an invalid tid */
1106 cli->cnum = cnum3;
1107
1108 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1109 printf("* server allows write with invalid TID\n");
1110 ret = False;
1111 } else {
1112 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1113 }
1114
1115 /* try a write with an invalid vuid */
1116 cli->vuid = vuid2;
1117 cli->cnum = cnum1;
1118
1119 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1120 printf("* server allows write with invalid VUID\n");
1121 ret = False;
1122 } else {
1123 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1124 }
1125
1126 cli->cnum = cnum1;
1127 cli->vuid = vuid1;
1128
1129 if (!cli_close(cli, fnum1)) {
1130 printf("close failed (%s)\n", cli_errstr(cli));
1131 return False;
1132 }
1133
1134 cli->cnum = cnum2;
1135
1136 if (!cli_tdis(cli)) {
1137 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1138 return False;
1139 }
1140
1141 cli->cnum = cnum1;
1142
1143 if (!torture_close_connection(cli)) {
1144 return False;
1145 }
1146
1147 return ret;
1148}
1149
1150
1151/*
1152 checks for old style tcon support
1153 */
1154static BOOL run_tcon2_test(int dummy)
1155{
1156 static struct cli_state *cli;
1157 uint16 cnum, max_xmit;
1158 char *service;
1159 NTSTATUS status;
1160
1161 if (!torture_open_connection(&cli, 0)) {
1162 return False;
1163 }
1164 cli_sockopt(cli, sockops);
1165
1166 printf("starting tcon2 test\n");
1167
1168 asprintf(&service, "\\\\%s\\%s", host, share);
1169
1170 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1171
1172 if (!NT_STATUS_IS_OK(status)) {
1173 printf("tcon2 failed : %s\n", cli_errstr(cli));
1174 } else {
1175 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1176 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1177 }
1178
1179 if (!torture_close_connection(cli)) {
1180 return False;
1181 }
1182
1183 printf("Passed tcon2 test\n");
1184 return True;
1185}
1186
1187static BOOL tcon_devtest(struct cli_state *cli,
1188 const char *myshare, const char *devtype,
1189 const char *return_devtype,
1190 NTSTATUS expected_error)
1191{
1192 BOOL status;
1193 BOOL ret;
1194
1195 status = cli_send_tconX(cli, myshare, devtype,
1196 password, strlen(password)+1);
1197
1198 if (NT_STATUS_IS_OK(expected_error)) {
1199 if (status) {
1200 if (strcmp(cli->dev, return_devtype) == 0) {
1201 ret = True;
1202 } else {
1203 printf("tconX to share %s with type %s "
1204 "succeeded but returned the wrong "
1205 "device type (got [%s] but should have got [%s])\n",
1206 myshare, devtype, cli->dev, return_devtype);
1207 ret = False;
1208 }
1209 } else {
1210 printf("tconX to share %s with type %s "
1211 "should have succeeded but failed\n",
1212 myshare, devtype);
1213 ret = False;
1214 }
1215 cli_tdis(cli);
1216 } else {
1217 if (status) {
1218 printf("tconx to share %s with type %s "
1219 "should have failed but succeeded\n",
1220 myshare, devtype);
1221 ret = False;
1222 } else {
1223 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1224 expected_error)) {
1225 ret = True;
1226 } else {
1227 printf("Returned unexpected error\n");
1228 ret = False;
1229 }
1230 }
1231 }
1232 return ret;
1233}
1234
1235/*
1236 checks for correct tconX support
1237 */
1238static BOOL run_tcon_devtype_test(int dummy)
1239{
1240 static struct cli_state *cli1 = NULL;
1241 BOOL retry;
1242 int flags = 0;
1243 NTSTATUS status;
1244 BOOL ret = True;
1245
1246 status = cli_full_connection(&cli1, myname,
1247 host, NULL, port_to_use,
1248 NULL, NULL,
1249 username, workgroup,
1250 password, flags, Undefined, &retry);
1251
1252 if (!NT_STATUS_IS_OK(status)) {
1253 printf("could not open connection\n");
1254 return False;
1255 }
1256
1257 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1258 ret = False;
1259
1260 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1261 ret = False;
1262
1263 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1264 ret = False;
1265
1266 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1267 ret = False;
1268
1269 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1270 ret = False;
1271
1272 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1273 ret = False;
1274
1275 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1276 ret = False;
1277
1278 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1279 ret = False;
1280
1281 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1282 ret = False;
1283
1284 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1285 ret = False;
1286
1287 cli_shutdown(cli1);
1288
1289 if (ret)
1290 printf("Passed tcondevtest\n");
1291
1292 return ret;
1293}
1294
1295
1296/*
1297 This test checks that
1298
1299 1) the server supports multiple locking contexts on the one SMB
1300 connection, distinguished by PID.
1301
1302 2) the server correctly fails overlapping locks made by the same PID (this
1303 goes against POSIX behaviour, which is why it is tricky to implement)
1304
1305 3) the server denies unlock requests by an incorrect client PID
1306*/
1307static BOOL run_locktest2(int dummy)
1308{
1309 static struct cli_state *cli;
1310 const char *fname = "\\lockt2.lck";
1311 int fnum1, fnum2, fnum3;
1312 BOOL correct = True;
1313
1314 if (!torture_open_connection(&cli, 0)) {
1315 return False;
1316 }
1317
1318 cli_sockopt(cli, sockops);
1319
1320 printf("starting locktest2\n");
1321
1322 cli_unlink(cli, fname);
1323
1324 cli_setpid(cli, 1);
1325
1326 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1327 if (fnum1 == -1) {
1328 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1329 return False;
1330 }
1331
1332 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1333 if (fnum2 == -1) {
1334 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1335 return False;
1336 }
1337
1338 cli_setpid(cli, 2);
1339
1340 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1341 if (fnum3 == -1) {
1342 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1343 return False;
1344 }
1345
1346 cli_setpid(cli, 1);
1347
1348 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1349 printf("lock1 failed (%s)\n", cli_errstr(cli));
1350 return False;
1351 }
1352
1353 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1354 printf("WRITE lock1 succeeded! This is a locking bug\n");
1355 correct = False;
1356 } else {
1357 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1358 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1359 }
1360
1361 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1362 printf("WRITE lock2 succeeded! This is a locking bug\n");
1363 correct = False;
1364 } else {
1365 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1366 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1367 }
1368
1369 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1370 printf("READ lock2 succeeded! This is a locking bug\n");
1371 correct = False;
1372 } else {
1373 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1374 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1375 }
1376
1377 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1378 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1379 }
1380 cli_setpid(cli, 2);
1381 if (cli_unlock(cli, fnum1, 100, 4)) {
1382 printf("unlock at 100 succeeded! This is a locking bug\n");
1383 correct = False;
1384 }
1385
1386 if (cli_unlock(cli, fnum1, 0, 4)) {
1387 printf("unlock1 succeeded! This is a locking bug\n");
1388 correct = False;
1389 } else {
1390 if (!check_error(__LINE__, cli,
1391 ERRDOS, ERRlock,
1392 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1393 }
1394
1395 if (cli_unlock(cli, fnum1, 0, 8)) {
1396 printf("unlock2 succeeded! This is a locking bug\n");
1397 correct = False;
1398 } else {
1399 if (!check_error(__LINE__, cli,
1400 ERRDOS, ERRlock,
1401 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1402 }
1403
1404 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1405 printf("lock3 succeeded! This is a locking bug\n");
1406 correct = False;
1407 } else {
1408 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1409 }
1410
1411 cli_setpid(cli, 1);
1412
1413 if (!cli_close(cli, fnum1)) {
1414 printf("close1 failed (%s)\n", cli_errstr(cli));
1415 return False;
1416 }
1417
1418 if (!cli_close(cli, fnum2)) {
1419 printf("close2 failed (%s)\n", cli_errstr(cli));
1420 return False;
1421 }
1422
1423 if (!cli_close(cli, fnum3)) {
1424 printf("close3 failed (%s)\n", cli_errstr(cli));
1425 return False;
1426 }
1427
1428 if (!torture_close_connection(cli)) {
1429 correct = False;
1430 }
1431
1432 printf("locktest2 finished\n");
1433
1434 return correct;
1435}
1436
1437
1438/*
1439 This test checks that
1440
1441 1) the server supports the full offset range in lock requests
1442*/
1443static BOOL run_locktest3(int dummy)
1444{
1445 static struct cli_state *cli1, *cli2;
1446 const char *fname = "\\lockt3.lck";
1447 int fnum1, fnum2, i;
1448 uint32 offset;
1449 BOOL correct = True;
1450
1451#define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1452
1453 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1454 return False;
1455 }
1456 cli_sockopt(cli1, sockops);
1457 cli_sockopt(cli2, sockops);
1458
1459 printf("starting locktest3\n");
1460
1461 cli_unlink(cli1, fname);
1462
1463 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1464 if (fnum1 == -1) {
1465 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1466 return False;
1467 }
1468 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1469 if (fnum2 == -1) {
1470 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1471 return False;
1472 }
1473
1474 for (offset=i=0;i<torture_numops;i++) {
1475 NEXT_OFFSET;
1476 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1477 printf("lock1 %d failed (%s)\n",
1478 i,
1479 cli_errstr(cli1));
1480 return False;
1481 }
1482
1483 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1484 printf("lock2 %d failed (%s)\n",
1485 i,
1486 cli_errstr(cli1));
1487 return False;
1488 }
1489 }
1490
1491 for (offset=i=0;i<torture_numops;i++) {
1492 NEXT_OFFSET;
1493
1494 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1495 printf("error: lock1 %d succeeded!\n", i);
1496 return False;
1497 }
1498
1499 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1500 printf("error: lock2 %d succeeded!\n", i);
1501 return False;
1502 }
1503
1504 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1505 printf("error: lock3 %d succeeded!\n", i);
1506 return False;
1507 }
1508
1509 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1510 printf("error: lock4 %d succeeded!\n", i);
1511 return False;
1512 }
1513 }
1514
1515 for (offset=i=0;i<torture_numops;i++) {
1516 NEXT_OFFSET;
1517
1518 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1519 printf("unlock1 %d failed (%s)\n",
1520 i,
1521 cli_errstr(cli1));
1522 return False;
1523 }
1524
1525 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1526 printf("unlock2 %d failed (%s)\n",
1527 i,
1528 cli_errstr(cli1));
1529 return False;
1530 }
1531 }
1532
1533 if (!cli_close(cli1, fnum1)) {
1534 printf("close1 failed (%s)\n", cli_errstr(cli1));
1535 return False;
1536 }
1537
1538 if (!cli_close(cli2, fnum2)) {
1539 printf("close2 failed (%s)\n", cli_errstr(cli2));
1540 return False;
1541 }
1542
1543 if (!cli_unlink(cli1, fname)) {
1544 printf("unlink failed (%s)\n", cli_errstr(cli1));
1545 return False;
1546 }
1547
1548 if (!torture_close_connection(cli1)) {
1549 correct = False;
1550 }
1551
1552 if (!torture_close_connection(cli2)) {
1553 correct = False;
1554 }
1555
1556 printf("finished locktest3\n");
1557
1558 return correct;
1559}
1560
1561#define EXPECTED(ret, v) if ((ret) != (v)) { \
1562 printf("** "); correct = False; \
1563 }
1564
1565/*
1566 looks at overlapping locks
1567*/
1568static BOOL run_locktest4(int dummy)
1569{
1570 static struct cli_state *cli1, *cli2;
1571 const char *fname = "\\lockt4.lck";
1572 int fnum1, fnum2, f;
1573 BOOL ret;
1574 char buf[1000];
1575 BOOL correct = True;
1576
1577 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1578 return False;
1579 }
1580
1581 cli_sockopt(cli1, sockops);
1582 cli_sockopt(cli2, sockops);
1583
1584 printf("starting locktest4\n");
1585
1586 cli_unlink(cli1, fname);
1587
1588 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1589 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1590
1591 memset(buf, 0, sizeof(buf));
1592
1593 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1594 printf("Failed to create file\n");
1595 correct = False;
1596 goto fail;
1597 }
1598
1599 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1600 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1601 EXPECTED(ret, False);
1602 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1603
1604 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1605 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1606 EXPECTED(ret, True);
1607 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1608
1609 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1610 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1611 EXPECTED(ret, False);
1612 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1613
1614 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1615 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1616 EXPECTED(ret, True);
1617 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1618
1619 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1620 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1621 EXPECTED(ret, False);
1622 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1623
1624 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1625 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1626 EXPECTED(ret, True);
1627 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1628
1629 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1630 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1631 EXPECTED(ret, True);
1632 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1633
1634 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1635 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1636 EXPECTED(ret, False);
1637 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1638
1639 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1640 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1641 EXPECTED(ret, False);
1642 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1643
1644 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1645 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1646 EXPECTED(ret, True);
1647 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1648
1649 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1650 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1651 EXPECTED(ret, False);
1652 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1653
1654 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1655 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1656 cli_unlock(cli1, fnum1, 110, 6);
1657 EXPECTED(ret, False);
1658 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1659
1660
1661 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1662 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1663 EXPECTED(ret, False);
1664 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1665
1666 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1667 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1668 EXPECTED(ret, False);
1669 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1670
1671
1672 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1673 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1674 cli_unlock(cli1, fnum1, 140, 4) &&
1675 cli_unlock(cli1, fnum1, 140, 4);
1676 EXPECTED(ret, True);
1677 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1678
1679
1680 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1681 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1682 cli_unlock(cli1, fnum1, 150, 4) &&
1683 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1684 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1685 cli_unlock(cli1, fnum1, 150, 4);
1686 EXPECTED(ret, True);
1687 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1688
1689 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1690 cli_unlock(cli1, fnum1, 160, 4) &&
1691 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1692 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1693 EXPECTED(ret, True);
1694 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1695
1696 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1697 cli_unlock(cli1, fnum1, 170, 4) &&
1698 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1699 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1700 EXPECTED(ret, True);
1701 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1702
1703 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1704 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1705 cli_unlock(cli1, fnum1, 190, 4) &&
1706 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1707 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1708 EXPECTED(ret, True);
1709 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1710
1711 cli_close(cli1, fnum1);
1712 cli_close(cli2, fnum2);
1713 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1714 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1715 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1716 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1717 cli_close(cli1, fnum1) &&
1718 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1719 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1720 cli_close(cli1, f);
1721 cli_close(cli1, fnum1);
1722 EXPECTED(ret, True);
1723 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1724
1725 fail:
1726 cli_close(cli1, fnum1);
1727 cli_close(cli2, fnum2);
1728 cli_unlink(cli1, fname);
1729 torture_close_connection(cli1);
1730 torture_close_connection(cli2);
1731
1732 printf("finished locktest4\n");
1733 return correct;
1734}
1735
1736/*
1737 looks at lock upgrade/downgrade.
1738*/
1739static BOOL run_locktest5(int dummy)
1740{
1741 static struct cli_state *cli1, *cli2;
1742 const char *fname = "\\lockt5.lck";
1743 int fnum1, fnum2, fnum3;
1744 BOOL ret;
1745 char buf[1000];
1746 BOOL correct = True;
1747
1748 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1749 return False;
1750 }
1751
1752 cli_sockopt(cli1, sockops);
1753 cli_sockopt(cli2, sockops);
1754
1755 printf("starting locktest5\n");
1756
1757 cli_unlink(cli1, fname);
1758
1759 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1760 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1761 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1762
1763 memset(buf, 0, sizeof(buf));
1764
1765 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1766 printf("Failed to create file\n");
1767 correct = False;
1768 goto fail;
1769 }
1770
1771 /* Check for NT bug... */
1772 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1773 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1774 cli_close(cli1, fnum1);
1775 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1776 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1777 EXPECTED(ret, True);
1778 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1779 cli_close(cli1, fnum1);
1780 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1781 cli_unlock(cli1, fnum3, 0, 1);
1782
1783 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1784 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1785 EXPECTED(ret, True);
1786 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1787
1788 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1789 EXPECTED(ret, False);
1790
1791 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1792
1793 /* Unlock the process 2 lock. */
1794 cli_unlock(cli2, fnum2, 0, 4);
1795
1796 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1797 EXPECTED(ret, False);
1798
1799 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1800
1801 /* Unlock the process 1 fnum3 lock. */
1802 cli_unlock(cli1, fnum3, 0, 4);
1803
1804 /* Stack 2 more locks here. */
1805 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1806 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1807
1808 EXPECTED(ret, True);
1809 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1810
1811 /* Unlock the first process lock, then check this was the WRITE lock that was
1812 removed. */
1813
1814 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1815 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1816
1817 EXPECTED(ret, True);
1818 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1819
1820 /* Unlock the process 2 lock. */
1821 cli_unlock(cli2, fnum2, 0, 4);
1822
1823 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1824
1825 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1826 cli_unlock(cli1, fnum1, 0, 4) &&
1827 cli_unlock(cli1, fnum1, 0, 4);
1828
1829 EXPECTED(ret, True);
1830 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1831
1832 /* Ensure the next unlock fails. */
1833 ret = cli_unlock(cli1, fnum1, 0, 4);
1834 EXPECTED(ret, False);
1835 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1836
1837 /* Ensure connection 2 can get a write lock. */
1838 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1839 EXPECTED(ret, True);
1840
1841 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1842
1843
1844 fail:
1845 cli_close(cli1, fnum1);
1846 cli_close(cli2, fnum2);
1847 cli_unlink(cli1, fname);
1848 if (!torture_close_connection(cli1)) {
1849 correct = False;
1850 }
1851 if (!torture_close_connection(cli2)) {
1852 correct = False;
1853 }
1854
1855 printf("finished locktest5\n");
1856
1857 return correct;
1858}
1859
1860/*
1861 tries the unusual lockingX locktype bits
1862*/
1863static BOOL run_locktest6(int dummy)
1864{
1865 static struct cli_state *cli;
1866 const char *fname[1] = { "\\lock6.txt" };
1867 int i;
1868 int fnum;
1869 NTSTATUS status;
1870
1871 if (!torture_open_connection(&cli, 0)) {
1872 return False;
1873 }
1874
1875 cli_sockopt(cli, sockops);
1876
1877 printf("starting locktest6\n");
1878
1879 for (i=0;i<1;i++) {
1880 printf("Testing %s\n", fname[i]);
1881
1882 cli_unlink(cli, fname[i]);
1883
1884 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1885 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1886 cli_close(cli, fnum);
1887 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1888
1889 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1890 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1891 cli_close(cli, fnum);
1892 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1893
1894 cli_unlink(cli, fname[i]);
1895 }
1896
1897 torture_close_connection(cli);
1898
1899 printf("finished locktest6\n");
1900 return True;
1901}
1902
1903static BOOL run_locktest7(int dummy)
1904{
1905 struct cli_state *cli1;
1906 const char *fname = "\\lockt7.lck";
1907 int fnum1;
1908 char buf[200];
1909 BOOL correct = False;
1910
1911 if (!torture_open_connection(&cli1, 0)) {
1912 return False;
1913 }
1914
1915 cli_sockopt(cli1, sockops);
1916
1917 printf("starting locktest7\n");
1918
1919 cli_unlink(cli1, fname);
1920
1921 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1922
1923 memset(buf, 0, sizeof(buf));
1924
1925 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1926 printf("Failed to create file\n");
1927 goto fail;
1928 }
1929
1930 cli_setpid(cli1, 1);
1931
1932 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1933 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1934 goto fail;
1935 } else {
1936 printf("pid1 successfully locked range 130:4 for READ\n");
1937 }
1938
1939 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1940 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1941 goto fail;
1942 } else {
1943 printf("pid1 successfully read the range 130:4\n");
1944 }
1945
1946 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1947 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1948 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1949 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1950 goto fail;
1951 }
1952 } else {
1953 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1954 goto fail;
1955 }
1956
1957 cli_setpid(cli1, 2);
1958
1959 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1960 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1961 } else {
1962 printf("pid2 successfully read the range 130:4\n");
1963 }
1964
1965 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1966 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1967 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1968 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1969 goto fail;
1970 }
1971 } else {
1972 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1973 goto fail;
1974 }
1975
1976 cli_setpid(cli1, 1);
1977 cli_unlock(cli1, fnum1, 130, 4);
1978
1979 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1980 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1981 goto fail;
1982 } else {
1983 printf("pid1 successfully locked range 130:4 for WRITE\n");
1984 }
1985
1986 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1987 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1988 goto fail;
1989 } else {
1990 printf("pid1 successfully read the range 130:4\n");
1991 }
1992
1993 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1994 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1995 goto fail;
1996 } else {
1997 printf("pid1 successfully wrote to the range 130:4\n");
1998 }
1999
2000 cli_setpid(cli1, 2);
2001
2002 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2003 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2004 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2005 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2006 goto fail;
2007 }
2008 } else {
2009 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2010 goto fail;
2011 }
2012
2013 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2014 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2015 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2016 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2017 goto fail;
2018 }
2019 } else {
2020 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2021 goto fail;
2022 }
2023
2024 cli_unlock(cli1, fnum1, 130, 0);
2025 correct = True;
2026
2027fail:
2028 cli_close(cli1, fnum1);
2029 cli_unlink(cli1, fname);
2030 torture_close_connection(cli1);
2031
2032 printf("finished locktest7\n");
2033 return correct;
2034}
2035
2036/*
2037test whether fnums and tids open on one VC are available on another (a major
2038security hole)
2039*/
2040static BOOL run_fdpasstest(int dummy)
2041{
2042 struct cli_state *cli1, *cli2;
2043 const char *fname = "\\fdpass.tst";
2044 int fnum1;
2045 pstring buf;
2046
2047 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2048 return False;
2049 }
2050 cli_sockopt(cli1, sockops);
2051 cli_sockopt(cli2, sockops);
2052
2053 printf("starting fdpasstest\n");
2054
2055 cli_unlink(cli1, fname);
2056
2057 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2058 if (fnum1 == -1) {
2059 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2060 return False;
2061 }
2062
2063 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2064 printf("write failed (%s)\n", cli_errstr(cli1));
2065 return False;
2066 }
2067
2068 cli2->vuid = cli1->vuid;
2069 cli2->cnum = cli1->cnum;
2070 cli2->pid = cli1->pid;
2071
2072 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2073 printf("read succeeded! nasty security hole [%s]\n",
2074 buf);
2075 return False;
2076 }
2077
2078 cli_close(cli1, fnum1);
2079 cli_unlink(cli1, fname);
2080
2081 torture_close_connection(cli1);
2082 torture_close_connection(cli2);
2083
2084 printf("finished fdpasstest\n");
2085 return True;
2086}
2087
2088static BOOL run_fdsesstest(int dummy)
2089{
2090 struct cli_state *cli;
2091 uint16 new_vuid;
2092 uint16 saved_vuid;
2093 uint16 new_cnum;
2094 uint16 saved_cnum;
2095 const char *fname = "\\fdsess.tst";
2096 const char *fname1 = "\\fdsess1.tst";
2097 int fnum1;
2098 int fnum2;
2099 pstring buf;
2100 BOOL ret = True;
2101
2102 if (!torture_open_connection(&cli, 0))
2103 return False;
2104 cli_sockopt(cli, sockops);
2105
2106 if (!torture_cli_session_setup2(cli, &new_vuid))
2107 return False;
2108
2109 saved_cnum = cli->cnum;
2110 if (!cli_send_tconX(cli, share, "?????", "", 1))
2111 return False;
2112 new_cnum = cli->cnum;
2113 cli->cnum = saved_cnum;
2114
2115 printf("starting fdsesstest\n");
2116
2117 cli_unlink(cli, fname);
2118 cli_unlink(cli, fname1);
2119
2120 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2121 if (fnum1 == -1) {
2122 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2123 return False;
2124 }
2125
2126 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2127 printf("write failed (%s)\n", cli_errstr(cli));
2128 return False;
2129 }
2130
2131 saved_vuid = cli->vuid;
2132 cli->vuid = new_vuid;
2133
2134 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2135 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2136 buf);
2137 ret = False;
2138 }
2139 /* Try to open a file with different vuid, samba cnum. */
2140 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2141 if (fnum2 != -1) {
2142 printf("create with different vuid, same cnum succeeded.\n");
2143 cli_close(cli, fnum2);
2144 cli_unlink(cli, fname1);
2145 } else {
2146 printf("create with different vuid, same cnum failed.\n");
2147 printf("This will cause problems with service clients.\n");
2148 ret = False;
2149 }
2150
2151 cli->vuid = saved_vuid;
2152
2153 /* Try with same vuid, different cnum. */
2154 cli->cnum = new_cnum;
2155
2156 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2157 printf("read succeeded with different cnum![%s]\n",
2158 buf);
2159 ret = False;
2160 }
2161
2162 cli->cnum = saved_cnum;
2163 cli_close(cli, fnum1);
2164 cli_unlink(cli, fname);
2165
2166 torture_close_connection(cli);
2167
2168 printf("finished fdsesstest\n");
2169 return ret;
2170}
2171
2172/*
2173 This test checks that
2174
2175 1) the server does not allow an unlink on a file that is open
2176*/
2177static BOOL run_unlinktest(int dummy)
2178{
2179 struct cli_state *cli;
2180 const char *fname = "\\unlink.tst";
2181 int fnum;
2182 BOOL correct = True;
2183
2184 if (!torture_open_connection(&cli, 0)) {
2185 return False;
2186 }
2187
2188 cli_sockopt(cli, sockops);
2189
2190 printf("starting unlink test\n");
2191
2192 cli_unlink(cli, fname);
2193
2194 cli_setpid(cli, 1);
2195
2196 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2197 if (fnum == -1) {
2198 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2199 return False;
2200 }
2201
2202 if (cli_unlink(cli, fname)) {
2203 printf("error: server allowed unlink on an open file\n");
2204 correct = False;
2205 } else {
2206 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2207 NT_STATUS_SHARING_VIOLATION);
2208 }
2209
2210 cli_close(cli, fnum);
2211 cli_unlink(cli, fname);
2212
2213 if (!torture_close_connection(cli)) {
2214 correct = False;
2215 }
2216
2217 printf("unlink test finished\n");
2218
2219 return correct;
2220}
2221
2222
2223/*
2224test how many open files this server supports on the one socket
2225*/
2226static BOOL run_maxfidtest(int dummy)
2227{
2228 struct cli_state *cli;
2229 const char *ftemplate = "\\maxfid.%d.%d";
2230 fstring fname;
2231 int fnums[0x11000], i;
2232 int retries=4;
2233 BOOL correct = True;
2234
2235 cli = current_cli;
2236
2237 if (retries <= 0) {
2238 printf("failed to connect\n");
2239 return False;
2240 }
2241
2242 cli_sockopt(cli, sockops);
2243
2244 for (i=0; i<0x11000; i++) {
2245 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2246 if ((fnums[i] = cli_open(cli, fname,
2247 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2248 -1) {
2249 printf("open of %s failed (%s)\n",
2250 fname, cli_errstr(cli));
2251 printf("maximum fnum is %d\n", i);
2252 break;
2253 }
2254 printf("%6d\r", i);
2255 }
2256 printf("%6d\n", i);
2257 i--;
2258
2259 printf("cleaning up\n");
2260 for (;i>=0;i--) {
2261 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2262 cli_close(cli, fnums[i]);
2263 if (!cli_unlink(cli, fname)) {
2264 printf("unlink of %s failed (%s)\n",
2265 fname, cli_errstr(cli));
2266 correct = False;
2267 }
2268 printf("%6d\r", i);
2269 }
2270 printf("%6d\n", 0);
2271
2272 printf("maxfid test finished\n");
2273 if (!torture_close_connection(cli)) {
2274 correct = False;
2275 }
2276 return correct;
2277}
2278
2279/* generate a random buffer */
2280static void rand_buf(char *buf, int len)
2281{
2282 while (len--) {
2283 *buf = (char)sys_random();
2284 buf++;
2285 }
2286}
2287
2288/* send smb negprot commands, not reading the response */
2289static BOOL run_negprot_nowait(int dummy)
2290{
2291 int i;
2292 static struct cli_state *cli;
2293 BOOL correct = True;
2294
2295 printf("starting negprot nowait test\n");
2296
2297 if (!(cli = open_nbt_connection())) {
2298 return False;
2299 }
2300
2301 for (i=0;i<50000;i++) {
2302 cli_negprot_send(cli);
2303 }
2304
2305 if (!torture_close_connection(cli)) {
2306 correct = False;
2307 }
2308
2309 printf("finished negprot nowait test\n");
2310
2311 return correct;
2312}
2313
2314
2315/* send random IPC commands */
2316static BOOL run_randomipc(int dummy)
2317{
2318 char *rparam = NULL;
2319 char *rdata = NULL;
2320 unsigned int rdrcnt,rprcnt;
2321 pstring param;
2322 int api, param_len, i;
2323 struct cli_state *cli;
2324 BOOL correct = True;
2325 int count = 50000;
2326
2327 printf("starting random ipc test\n");
2328
2329 if (!torture_open_connection(&cli, 0)) {
2330 return False;
2331 }
2332
2333 for (i=0;i<count;i++) {
2334 api = sys_random() % 500;
2335 param_len = (sys_random() % 64);
2336
2337 rand_buf(param, param_len);
2338
2339 SSVAL(param,0,api);
2340
2341 cli_api(cli,
2342 param, param_len, 8,
2343 NULL, 0, BUFFER_SIZE,
2344 &rparam, &rprcnt,
2345 &rdata, &rdrcnt);
2346 if (i % 100 == 0) {
2347 printf("%d/%d\r", i,count);
2348 }
2349 }
2350 printf("%d/%d\n", i, count);
2351
2352 if (!torture_close_connection(cli)) {
2353 correct = False;
2354 }
2355
2356 printf("finished random ipc test\n");
2357
2358 return correct;
2359}
2360
2361
2362
2363static void browse_callback(const char *sname, uint32 stype,
2364 const char *comment, void *state)
2365{
2366 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2367}
2368
2369
2370
2371/*
2372 This test checks the browse list code
2373
2374*/
2375static BOOL run_browsetest(int dummy)
2376{
2377 static struct cli_state *cli;
2378 BOOL correct = True;
2379
2380 printf("starting browse test\n");
2381
2382 if (!torture_open_connection(&cli, 0)) {
2383 return False;
2384 }
2385
2386 printf("domain list:\n");
2387 cli_NetServerEnum(cli, cli->server_domain,
2388 SV_TYPE_DOMAIN_ENUM,
2389 browse_callback, NULL);
2390
2391 printf("machine list:\n");
2392 cli_NetServerEnum(cli, cli->server_domain,
2393 SV_TYPE_ALL,
2394 browse_callback, NULL);
2395
2396 if (!torture_close_connection(cli)) {
2397 correct = False;
2398 }
2399
2400 printf("browse test finished\n");
2401
2402 return correct;
2403
2404}
2405
2406
2407/*
2408 This checks how the getatr calls works
2409*/
2410static BOOL run_attrtest(int dummy)
2411{
2412 struct cli_state *cli;
2413 int fnum;
2414 time_t t, t2;
2415 const char *fname = "\\attrib123456789.tst";
2416 BOOL correct = True;
2417
2418 printf("starting attrib test\n");
2419
2420 if (!torture_open_connection(&cli, 0)) {
2421 return False;
2422 }
2423
2424 cli_unlink(cli, fname);
2425 fnum = cli_open(cli, fname,
2426 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2427 cli_close(cli, fnum);
2428 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2429 printf("getatr failed (%s)\n", cli_errstr(cli));
2430 correct = False;
2431 }
2432
2433 if (abs(t - time(NULL)) > 60*60*24*10) {
2434 printf("ERROR: SMBgetatr bug. time is %s",
2435 ctime(&t));
2436 t = time(NULL);
2437 correct = True;
2438 }
2439
2440 t2 = t-60*60*24; /* 1 day ago */
2441
2442 if (!cli_setatr(cli, fname, 0, t2)) {
2443 printf("setatr failed (%s)\n", cli_errstr(cli));
2444 correct = True;
2445 }
2446
2447 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2448 printf("getatr failed (%s)\n", cli_errstr(cli));
2449 correct = True;
2450 }
2451
2452 if (t != t2) {
2453 printf("ERROR: getatr/setatr bug. times are\n%s",
2454 ctime(&t));
2455 printf("%s", ctime(&t2));
2456 correct = True;
2457 }
2458
2459 cli_unlink(cli, fname);
2460
2461 if (!torture_close_connection(cli)) {
2462 correct = False;
2463 }
2464
2465 printf("attrib test finished\n");
2466
2467 return correct;
2468}
2469
2470
2471/*
2472 This checks a couple of trans2 calls
2473*/
2474static BOOL run_trans2test(int dummy)
2475{
2476 struct cli_state *cli;
2477 int fnum;
2478 SMB_OFF_T size;
2479 time_t c_time, a_time, m_time;
2480 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2481 const char *fname = "\\trans2.tst";
2482 const char *dname = "\\trans2";
2483 const char *fname2 = "\\trans2\\trans2.tst";
2484 pstring pname;
2485 BOOL correct = True;
2486
2487 printf("starting trans2 test\n");
2488
2489 if (!torture_open_connection(&cli, 0)) {
2490 return False;
2491 }
2492
2493 cli_unlink(cli, fname);
2494 fnum = cli_open(cli, fname,
2495 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2496 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2497 &m_time_ts, NULL)) {
2498 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2499 correct = False;
2500 }
2501
2502 if (!cli_qfilename(cli, fnum, pname)) {
2503 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2504 correct = False;
2505 }
2506
2507 if (strcmp(pname, fname)) {
2508 printf("qfilename gave different name? [%s] [%s]\n",
2509 fname, pname);
2510 correct = False;
2511 }
2512
2513 cli_close(cli, fnum);
2514
2515 sleep(2);
2516
2517 cli_unlink(cli, fname);
2518 fnum = cli_open(cli, fname,
2519 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2520 if (fnum == -1) {
2521 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2522 return False;
2523 }
2524 cli_close(cli, fnum);
2525
2526 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2527 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2528 correct = False;
2529 } else {
2530 if (c_time != m_time) {
2531 printf("create time=%s", ctime(&c_time));
2532 printf("modify time=%s", ctime(&m_time));
2533 printf("This system appears to have sticky create times\n");
2534 }
2535 if (a_time % (60*60) == 0) {
2536 printf("access time=%s", ctime(&a_time));
2537 printf("This system appears to set a midnight access time\n");
2538 correct = False;
2539 }
2540
2541 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2542 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2543 correct = False;
2544 }
2545 }
2546
2547
2548 cli_unlink(cli, fname);
2549 fnum = cli_open(cli, fname,
2550 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2551 cli_close(cli, fnum);
2552 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2553 &m_time_ts, &size, NULL, NULL)) {
2554 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2555 correct = False;
2556 } else {
2557 if (w_time_ts.tv_sec < 60*60*24*2) {
2558 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2559 printf("This system appears to set a initial 0 write time\n");
2560 correct = False;
2561 }
2562 }
2563
2564 cli_unlink(cli, fname);
2565
2566
2567 /* check if the server updates the directory modification time
2568 when creating a new file */
2569 if (!cli_mkdir(cli, dname)) {
2570 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2571 correct = False;
2572 }
2573 sleep(3);
2574 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2575 &m_time_ts, &size, NULL, NULL)) {
2576 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2577 correct = False;
2578 }
2579
2580 fnum = cli_open(cli, fname2,
2581 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2582 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2583 cli_close(cli, fnum);
2584 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2585 &m_time2_ts, &size, NULL, NULL)) {
2586 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2587 correct = False;
2588 } else {
2589 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2590 == 0) {
2591 printf("This system does not update directory modification times\n");
2592 correct = False;
2593 }
2594 }
2595 cli_unlink(cli, fname2);
2596 cli_rmdir(cli, dname);
2597
2598 if (!torture_close_connection(cli)) {
2599 correct = False;
2600 }
2601
2602 printf("trans2 test finished\n");
2603
2604 return correct;
2605}
2606
2607/*
2608 This checks new W2K calls.
2609*/
2610
2611static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2612{
2613 char *buf = NULL;
2614 uint32 len;
2615 BOOL correct = True;
2616
2617 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2618 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2619 correct = False;
2620 } else {
2621 printf("qfileinfo: level %d, len = %u\n", level, len);
2622 dump_data(0, buf, len);
2623 printf("\n");
2624 }
2625 SAFE_FREE(buf);
2626 return correct;
2627}
2628
2629static BOOL run_w2ktest(int dummy)
2630{
2631 struct cli_state *cli;
2632 int fnum;
2633 const char *fname = "\\w2ktest\\w2k.tst";
2634 int level;
2635 BOOL correct = True;
2636
2637 printf("starting w2k test\n");
2638
2639 if (!torture_open_connection(&cli, 0)) {
2640 return False;
2641 }
2642
2643 fnum = cli_open(cli, fname,
2644 O_RDWR | O_CREAT , DENY_NONE);
2645
2646 for (level = 1004; level < 1040; level++) {
2647 new_trans(cli, fnum, level);
2648 }
2649
2650 cli_close(cli, fnum);
2651
2652 if (!torture_close_connection(cli)) {
2653 correct = False;
2654 }
2655
2656 printf("w2k test finished\n");
2657
2658 return correct;
2659}
2660
2661
2662/*
2663 this is a harness for some oplock tests
2664 */
2665static BOOL run_oplock1(int dummy)
2666{
2667 struct cli_state *cli1;
2668 const char *fname = "\\lockt1.lck";
2669 int fnum1;
2670 BOOL correct = True;
2671
2672 printf("starting oplock test 1\n");
2673
2674 if (!torture_open_connection(&cli1, 0)) {
2675 return False;
2676 }
2677
2678 cli_unlink(cli1, fname);
2679
2680 cli_sockopt(cli1, sockops);
2681
2682 cli1->use_oplocks = True;
2683
2684 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2685 if (fnum1 == -1) {
2686 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2687 return False;
2688 }
2689
2690 cli1->use_oplocks = False;
2691
2692 cli_unlink(cli1, fname);
2693 cli_unlink(cli1, fname);
2694
2695 if (!cli_close(cli1, fnum1)) {
2696 printf("close2 failed (%s)\n", cli_errstr(cli1));
2697 return False;
2698 }
2699
2700 if (!cli_unlink(cli1, fname)) {
2701 printf("unlink failed (%s)\n", cli_errstr(cli1));
2702 return False;
2703 }
2704
2705 if (!torture_close_connection(cli1)) {
2706 correct = False;
2707 }
2708
2709 printf("finished oplock test 1\n");
2710
2711 return correct;
2712}
2713
2714static BOOL run_oplock2(int dummy)
2715{
2716 struct cli_state *cli1, *cli2;
2717 const char *fname = "\\lockt2.lck";
2718 int fnum1, fnum2;
2719 int saved_use_oplocks = use_oplocks;
2720 char buf[4];
2721 BOOL correct = True;
2722 volatile BOOL *shared_correct;
2723
2724 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2725 *shared_correct = True;
2726
2727 use_level_II_oplocks = True;
2728 use_oplocks = True;
2729
2730 printf("starting oplock test 2\n");
2731
2732 if (!torture_open_connection(&cli1, 0)) {
2733 use_level_II_oplocks = False;
2734 use_oplocks = saved_use_oplocks;
2735 return False;
2736 }
2737
2738 cli1->use_oplocks = True;
2739 cli1->use_level_II_oplocks = True;
2740
2741 if (!torture_open_connection(&cli2, 1)) {
2742 use_level_II_oplocks = False;
2743 use_oplocks = saved_use_oplocks;
2744 return False;
2745 }
2746
2747 cli2->use_oplocks = True;
2748 cli2->use_level_II_oplocks = True;
2749
2750 cli_unlink(cli1, fname);
2751
2752 cli_sockopt(cli1, sockops);
2753 cli_sockopt(cli2, sockops);
2754
2755 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2756 if (fnum1 == -1) {
2757 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2758 return False;
2759 }
2760
2761 /* Don't need the globals any more. */
2762 use_level_II_oplocks = False;
2763 use_oplocks = saved_use_oplocks;
2764
2765 if (fork() == 0) {
2766 /* Child code */
2767 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2768 if (fnum2 == -1) {
2769 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2770 *shared_correct = False;
2771 exit(0);
2772 }
2773
2774 sleep(2);
2775
2776 if (!cli_close(cli2, fnum2)) {
2777 printf("close2 failed (%s)\n", cli_errstr(cli1));
2778 *shared_correct = False;
2779 }
2780
2781 exit(0);
2782 }
2783
2784 sleep(2);
2785
2786 /* Ensure cli1 processes the break. Empty file should always return 0
2787 * bytes. */
2788
2789 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2790 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2791 correct = False;
2792 }
2793
2794 /* Should now be at level II. */
2795 /* Test if sending a write locks causes a break to none. */
2796
2797 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2798 printf("lock failed (%s)\n", cli_errstr(cli1));
2799 correct = False;
2800 }
2801
2802 cli_unlock(cli1, fnum1, 0, 4);
2803
2804 sleep(2);
2805
2806 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2807 printf("lock failed (%s)\n", cli_errstr(cli1));
2808 correct = False;
2809 }
2810
2811 cli_unlock(cli1, fnum1, 0, 4);
2812
2813 sleep(2);
2814
2815 cli_read(cli1, fnum1, buf, 0, 4);
2816
2817#if 0
2818 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2819 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2820 correct = False;
2821 }
2822#endif
2823
2824 if (!cli_close(cli1, fnum1)) {
2825 printf("close1 failed (%s)\n", cli_errstr(cli1));
2826 correct = False;
2827 }
2828
2829 sleep(4);
2830
2831 if (!cli_unlink(cli1, fname)) {
2832 printf("unlink failed (%s)\n", cli_errstr(cli1));
2833 correct = False;
2834 }
2835
2836 if (!torture_close_connection(cli1)) {
2837 correct = False;
2838 }
2839
2840 if (!*shared_correct) {
2841 correct = False;
2842 }
2843
2844 printf("finished oplock test 2\n");
2845
2846 return correct;
2847}
2848
2849/* handler for oplock 3 tests */
2850static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2851{
2852 printf("got oplock break fnum=%d level=%d\n",
2853 fnum, level);
2854 return cli_oplock_ack(cli, fnum, level);
2855}
2856
2857static BOOL run_oplock3(int dummy)
2858{
2859 struct cli_state *cli;
2860 const char *fname = "\\oplockt3.dat";
2861 int fnum;
2862 char buf[4] = "abcd";
2863 BOOL correct = True;
2864 volatile BOOL *shared_correct;
2865
2866 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2867 *shared_correct = True;
2868
2869 printf("starting oplock test 3\n");
2870
2871 if (fork() == 0) {
2872 /* Child code */
2873 use_oplocks = True;
2874 use_level_II_oplocks = True;
2875 if (!torture_open_connection(&cli, 0)) {
2876 *shared_correct = False;
2877 exit(0);
2878 }
2879 sleep(2);
2880 /* try to trigger a oplock break in parent */
2881 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2882 cli_write(cli, fnum, 0, buf, 0, 4);
2883 exit(0);
2884 }
2885
2886 /* parent code */
2887 use_oplocks = True;
2888 use_level_II_oplocks = True;
2889 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2890 return False;
2891 }
2892 cli_oplock_handler(cli, oplock3_handler);
2893 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2894 cli_write(cli, fnum, 0, buf, 0, 4);
2895 cli_close(cli, fnum);
2896 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2897 cli->timeout = 20000;
2898 cli_receive_smb(cli);
2899 printf("finished oplock test 3\n");
2900
2901 return (correct && *shared_correct);
2902
2903/* What are we looking for here? What's sucess and what's FAILURE? */
2904}
2905
2906
2907
2908/*
2909 Test delete on close semantics.
2910 */
2911static BOOL run_deletetest(int dummy)
2912{
2913 struct cli_state *cli1 = NULL;
2914 struct cli_state *cli2 = NULL;
2915 const char *fname = "\\delete.file";
2916 int fnum1 = -1;
2917 int fnum2 = -1;
2918 BOOL correct = True;
2919
2920 printf("starting delete test\n");
2921
2922 if (!torture_open_connection(&cli1, 0)) {
2923 return False;
2924 }
2925
2926 cli_sockopt(cli1, sockops);
2927
2928 /* Test 1 - this should delete the file on close. */
2929
2930 cli_setatr(cli1, fname, 0, 0);
2931 cli_unlink(cli1, fname);
2932
2933 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2934 0, FILE_OVERWRITE_IF,
2935 FILE_DELETE_ON_CLOSE, 0);
2936
2937 if (fnum1 == -1) {
2938 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2939 correct = False;
2940 goto fail;
2941 }
2942
2943#if 0 /* JRATEST */
2944 {
2945 uint32 *accinfo = NULL;
2946 uint32 len;
2947 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2948 if (accinfo)
2949 printf("access mode = 0x%lx\n", *accinfo);
2950 SAFE_FREE(accinfo);
2951 }
2952#endif
2953
2954 if (!cli_close(cli1, fnum1)) {
2955 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2956 correct = False;
2957 goto fail;
2958 }
2959
2960 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2961 if (fnum1 != -1) {
2962 printf("[1] open of %s succeeded (should fail)\n", fname);
2963 correct = False;
2964 goto fail;
2965 }
2966
2967 printf("first delete on close test succeeded.\n");
2968
2969 /* Test 2 - this should delete the file on close. */
2970
2971 cli_setatr(cli1, fname, 0, 0);
2972 cli_unlink(cli1, fname);
2973
2974 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
2975 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2976 FILE_OVERWRITE_IF, 0, 0);
2977
2978 if (fnum1 == -1) {
2979 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2980 correct = False;
2981 goto fail;
2982 }
2983
2984 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2985 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2986 correct = False;
2987 goto fail;
2988 }
2989
2990 if (!cli_close(cli1, fnum1)) {
2991 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2992 correct = False;
2993 goto fail;
2994 }
2995
2996 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2997 if (fnum1 != -1) {
2998 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2999 if (!cli_close(cli1, fnum1)) {
3000 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3001 correct = False;
3002 goto fail;
3003 }
3004 cli_unlink(cli1, fname);
3005 } else
3006 printf("second delete on close test succeeded.\n");
3007
3008 /* Test 3 - ... */
3009 cli_setatr(cli1, fname, 0, 0);
3010 cli_unlink(cli1, fname);
3011
3012 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3013 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3014
3015 if (fnum1 == -1) {
3016 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3017 correct = False;
3018 goto fail;
3019 }
3020
3021 /* This should fail with a sharing violation - open for delete is only compatible
3022 with SHARE_DELETE. */
3023
3024 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3025 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3026
3027 if (fnum2 != -1) {
3028 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3029 correct = False;
3030 goto fail;
3031 }
3032
3033 /* This should succeed. */
3034
3035 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3036 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3037
3038 if (fnum2 == -1) {
3039 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3040 correct = False;
3041 goto fail;
3042 }
3043
3044 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3045 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3046 correct = False;
3047 goto fail;
3048 }
3049
3050 if (!cli_close(cli1, fnum1)) {
3051 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3052 correct = False;
3053 goto fail;
3054 }
3055
3056 if (!cli_close(cli1, fnum2)) {
3057 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3058 correct = False;
3059 goto fail;
3060 }
3061
3062 /* This should fail - file should no longer be there. */
3063
3064 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3065 if (fnum1 != -1) {
3066 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3067 if (!cli_close(cli1, fnum1)) {
3068 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3069 }
3070 cli_unlink(cli1, fname);
3071 correct = False;
3072 goto fail;
3073 } else
3074 printf("third delete on close test succeeded.\n");
3075
3076 /* Test 4 ... */
3077 cli_setatr(cli1, fname, 0, 0);
3078 cli_unlink(cli1, fname);
3079
3080 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3081 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3082
3083 if (fnum1 == -1) {
3084 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3085 correct = False;
3086 goto fail;
3087 }
3088
3089 /* This should succeed. */
3090 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3091 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3092 if (fnum2 == -1) {
3093 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3094 correct = False;
3095 goto fail;
3096 }
3097
3098 if (!cli_close(cli1, fnum2)) {
3099 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3100 correct = False;
3101 goto fail;
3102 }
3103
3104 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3105 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3106 correct = False;
3107 goto fail;
3108 }
3109
3110 /* This should fail - no more opens once delete on close set. */
3111 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3112 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3113 FILE_OPEN, 0, 0);
3114 if (fnum2 != -1) {
3115 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3116 correct = False;
3117 goto fail;
3118 } else
3119 printf("fourth delete on close test succeeded.\n");
3120
3121 if (!cli_close(cli1, fnum1)) {
3122 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3123 correct = False;
3124 goto fail;
3125 }
3126
3127 /* Test 5 ... */
3128 cli_setatr(cli1, fname, 0, 0);
3129 cli_unlink(cli1, fname);
3130
3131 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3132 if (fnum1 == -1) {
3133 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3134 correct = False;
3135 goto fail;
3136 }
3137
3138 /* This should fail - only allowed on NT opens with DELETE access. */
3139
3140 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3141 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3142 correct = False;
3143 goto fail;
3144 }
3145
3146 if (!cli_close(cli1, fnum1)) {
3147 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3148 correct = False;
3149 goto fail;
3150 }
3151
3152 printf("fifth delete on close test succeeded.\n");
3153
3154 /* Test 6 ... */
3155 cli_setatr(cli1, fname, 0, 0);
3156 cli_unlink(cli1, fname);
3157
3158 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3159 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3160 FILE_OVERWRITE_IF, 0, 0);
3161
3162 if (fnum1 == -1) {
3163 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3164 correct = False;
3165 goto fail;
3166 }
3167
3168 /* This should fail - only allowed on NT opens with DELETE access. */
3169
3170 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3171 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3172 correct = False;
3173 goto fail;
3174 }
3175
3176 if (!cli_close(cli1, fnum1)) {
3177 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3178 correct = False;
3179 goto fail;
3180 }
3181
3182 printf("sixth delete on close test succeeded.\n");
3183
3184 /* Test 7 ... */
3185 cli_setatr(cli1, fname, 0, 0);
3186 cli_unlink(cli1, fname);
3187
3188 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3189 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3190
3191 if (fnum1 == -1) {
3192 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3193 correct = False;
3194 goto fail;
3195 }
3196
3197 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3198 printf("[7] setting delete_on_close on file failed !\n");
3199 correct = False;
3200 goto fail;
3201 }
3202
3203 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3204 printf("[7] unsetting delete_on_close on file failed !\n");
3205 correct = False;
3206 goto fail;
3207 }
3208
3209 if (!cli_close(cli1, fnum1)) {
3210 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3211 correct = False;
3212 goto fail;
3213 }
3214
3215 /* This next open should succeed - we reset the flag. */
3216
3217 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3218 if (fnum1 == -1) {
3219 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3220 correct = False;
3221 goto fail;
3222 }
3223
3224 if (!cli_close(cli1, fnum1)) {
3225 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3226 correct = False;
3227 goto fail;
3228 }
3229
3230 printf("seventh delete on close test succeeded.\n");
3231
3232 /* Test 7 ... */
3233 cli_setatr(cli1, fname, 0, 0);
3234 cli_unlink(cli1, fname);
3235
3236 if (!torture_open_connection(&cli2, 1)) {
3237 printf("[8] failed to open second connection.\n");
3238 correct = False;
3239 goto fail;
3240 }
3241
3242 cli_sockopt(cli1, sockops);
3243
3244 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3245 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3246 FILE_OVERWRITE_IF, 0, 0);
3247
3248 if (fnum1 == -1) {
3249 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3250 correct = False;
3251 goto fail;
3252 }
3253
3254 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3255 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3256 FILE_OPEN, 0, 0);
3257
3258 if (fnum2 == -1) {
3259 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3260 correct = False;
3261 goto fail;
3262 }
3263
3264 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3265 printf("[8] setting delete_on_close on file failed !\n");
3266 correct = False;
3267 goto fail;
3268 }
3269
3270 if (!cli_close(cli1, fnum1)) {
3271 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3272 correct = False;
3273 goto fail;
3274 }
3275
3276 if (!cli_close(cli2, fnum2)) {
3277 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3278 correct = False;
3279 goto fail;
3280 }
3281
3282 /* This should fail.. */
3283 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3284 if (fnum1 != -1) {
3285 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3286 goto fail;
3287 correct = False;
3288 } else
3289 printf("eighth delete on close test succeeded.\n");
3290
3291 /* This should fail - we need to set DELETE_ACCESS. */
3292 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3293 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3294
3295 if (fnum1 != -1) {
3296 printf("[9] open of %s succeeded should have failed!\n", fname);
3297 correct = False;
3298 goto fail;
3299 }
3300
3301 printf("ninth delete on close test succeeded.\n");
3302
3303 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3304 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3305 if (fnum1 == -1) {
3306 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3307 correct = False;
3308 goto fail;
3309 }
3310
3311 /* This should delete the file. */
3312 if (!cli_close(cli1, fnum1)) {
3313 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3314 correct = False;
3315 goto fail;
3316 }
3317
3318 /* This should fail.. */
3319 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3320 if (fnum1 != -1) {
3321 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3322 goto fail;
3323 correct = False;
3324 } else
3325 printf("tenth delete on close test succeeded.\n");
3326
3327 cli_setatr(cli1, fname, 0, 0);
3328 cli_unlink(cli1, fname);
3329
3330 /* What error do we get when attempting to open a read-only file with
3331 delete access ? */
3332
3333 /* Create a readonly file. */
3334 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3335 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3336 if (fnum1 == -1) {
3337 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3338 correct = False;
3339 goto fail;
3340 }
3341
3342 if (!cli_close(cli1, fnum1)) {
3343 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3344 correct = False;
3345 goto fail;
3346 }
3347
3348 /* Now try open for delete access. */
3349 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3350 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3351 FILE_OVERWRITE_IF, 0, 0);
3352
3353 if (fnum1 != -1) {
3354 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3355 cli_close(cli1, fnum1);
3356 goto fail;
3357 correct = False;
3358 } else {
3359 NTSTATUS nterr = cli_nt_error(cli1);
3360 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3361 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3362 goto fail;
3363 correct = False;
3364 } else {
3365 printf("eleventh delete on close test succeeded.\n");
3366 }
3367 }
3368
3369 printf("finished delete test\n");
3370
3371 fail:
3372 /* FIXME: This will crash if we aborted before cli2 got
3373 * intialized, because these functions don't handle
3374 * uninitialized connections. */
3375
3376 if (fnum1 != -1) cli_close(cli1, fnum1);
3377 if (fnum2 != -1) cli_close(cli1, fnum2);
3378 cli_setatr(cli1, fname, 0, 0);
3379 cli_unlink(cli1, fname);
3380
3381 if (cli1 && !torture_close_connection(cli1)) {
3382 correct = False;
3383 }
3384 if (cli2 && !torture_close_connection(cli2)) {
3385 correct = False;
3386 }
3387 return correct;
3388}
3389
3390
3391/*
3392 print out server properties
3393 */
3394static BOOL run_properties(int dummy)
3395{
3396 static struct cli_state *cli;
3397 BOOL correct = True;
3398
3399 printf("starting properties test\n");
3400
3401 ZERO_STRUCT(cli);
3402
3403 if (!torture_open_connection(&cli, 0)) {
3404 return False;
3405 }
3406
3407 cli_sockopt(cli, sockops);
3408
3409 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3410
3411 if (!torture_close_connection(cli)) {
3412 correct = False;
3413 }
3414
3415 return correct;
3416}
3417
3418
3419
3420/* FIRST_DESIRED_ACCESS 0xf019f */
3421#define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3422 FILE_READ_EA| /* 0xf */ \
3423 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3424 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3425 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3426 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3427/* SECOND_DESIRED_ACCESS 0xe0080 */
3428#define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3429 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3430 WRITE_OWNER_ACCESS /* 0xe0000 */
3431
3432#if 0
3433#define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3434 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3435 FILE_READ_DATA|\
3436 WRITE_OWNER_ACCESS /* */
3437#endif
3438
3439/*
3440 Test ntcreate calls made by xcopy
3441 */
3442static BOOL run_xcopy(int dummy)
3443{
3444 static struct cli_state *cli1;
3445 const char *fname = "\\test.txt";
3446 BOOL correct = True;
3447 int fnum1, fnum2;
3448
3449 printf("starting xcopy test\n");
3450
3451 if (!torture_open_connection(&cli1, 0)) {
3452 return False;
3453 }
3454
3455 fnum1 = cli_nt_create_full(cli1, fname, 0,
3456 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3457 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3458 0x4044, 0);
3459
3460 if (fnum1 == -1) {
3461 printf("First open failed - %s\n", cli_errstr(cli1));
3462 return False;
3463 }
3464
3465 fnum2 = cli_nt_create_full(cli1, fname, 0,
3466 SECOND_DESIRED_ACCESS, 0,
3467 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3468 0x200000, 0);
3469 if (fnum2 == -1) {
3470 printf("second open failed - %s\n", cli_errstr(cli1));
3471 return False;
3472 }
3473
3474 if (!torture_close_connection(cli1)) {
3475 correct = False;
3476 }
3477
3478 return correct;
3479}
3480
3481/*
3482 Test rename on files open with share delete and no share delete.
3483 */
3484static BOOL run_rename(int dummy)
3485{
3486 static struct cli_state *cli1;
3487 const char *fname = "\\test.txt";
3488 const char *fname1 = "\\test1.txt";
3489 BOOL correct = True;
3490 int fnum1;
3491
3492 printf("starting rename test\n");
3493
3494 if (!torture_open_connection(&cli1, 0)) {
3495 return False;
3496 }
3497
3498 cli_unlink(cli1, fname);
3499 cli_unlink(cli1, fname1);
3500 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3501 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3502
3503 if (fnum1 == -1) {
3504 printf("First open failed - %s\n", cli_errstr(cli1));
3505 return False;
3506 }
3507
3508 if (!cli_rename(cli1, fname, fname1)) {
3509 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3510 } else {
3511 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3512 correct = False;
3513 }
3514
3515 if (!cli_close(cli1, fnum1)) {
3516 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3517 return False;
3518 }
3519
3520 cli_unlink(cli1, fname);
3521 cli_unlink(cli1, fname1);
3522 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3523#if 0
3524 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3525#else
3526 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3527#endif
3528
3529 if (fnum1 == -1) {
3530 printf("Second open failed - %s\n", cli_errstr(cli1));
3531 return False;
3532 }
3533
3534 if (!cli_rename(cli1, fname, fname1)) {
3535 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3536 correct = False;
3537 } else {
3538 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3539 }
3540
3541 if (!cli_close(cli1, fnum1)) {
3542 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3543 return False;
3544 }
3545
3546 cli_unlink(cli1, fname);
3547 cli_unlink(cli1, fname1);
3548
3549 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3550 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3551
3552 if (fnum1 == -1) {
3553 printf("Third open failed - %s\n", cli_errstr(cli1));
3554 return False;
3555 }
3556
3557
3558#if 0
3559 {
3560 int fnum2;
3561
3562 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3563 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3564
3565 if (fnum2 == -1) {
3566 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3567 return False;
3568 }
3569 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3570 printf("[8] setting delete_on_close on file failed !\n");
3571 return False;
3572 }
3573
3574 if (!cli_close(cli1, fnum2)) {
3575 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3576 return False;
3577 }
3578 }
3579#endif
3580
3581 if (!cli_rename(cli1, fname, fname1)) {
3582 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3583 correct = False;
3584 } else {
3585 printf("Third rename succeeded (SHARE_NONE)\n");
3586 }
3587
3588 if (!cli_close(cli1, fnum1)) {
3589 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3590 return False;
3591 }
3592
3593 cli_unlink(cli1, fname);
3594 cli_unlink(cli1, fname1);
3595
3596 /*----*/
3597
3598 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3599 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3600
3601 if (fnum1 == -1) {
3602 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3603 return False;
3604 }
3605
3606 if (!cli_rename(cli1, fname, fname1)) {
3607 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3608 } else {
3609 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3610 correct = False;
3611 }
3612
3613 if (!cli_close(cli1, fnum1)) {
3614 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3615 return False;
3616 }
3617
3618 cli_unlink(cli1, fname);
3619 cli_unlink(cli1, fname1);
3620
3621 /*--*/
3622
3623 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3624 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3625
3626 if (fnum1 == -1) {
3627 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3628 return False;
3629 }
3630
3631 if (!cli_rename(cli1, fname, fname1)) {
3632 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
3633 correct = False;
3634 } else {
3635 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3636 }
3637
3638 /*
3639 * Now check if the first name still exists ...
3640 */
3641
3642 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3643 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3644
3645 if (fnum2 == -1) {
3646 printf("Opening original file after rename of open file fails: %s\n",
3647 cli_errstr(cli1));
3648 }
3649 else {
3650 printf("Opening original file after rename of open file works ...\n");
3651 (void)cli_close(cli1, fnum2);
3652 } */
3653
3654 /*--*/
3655
3656
3657 if (!cli_close(cli1, fnum1)) {
3658 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3659 return False;
3660 }
3661
3662 cli_unlink(cli1, fname);
3663 cli_unlink(cli1, fname1);
3664
3665 if (!torture_close_connection(cli1)) {
3666 correct = False;
3667 }
3668
3669 return correct;
3670}
3671
3672static BOOL run_pipe_number(int dummy)
3673{
3674 struct cli_state *cli1;
3675 const char *pipe_name = "\\SPOOLSS";
3676 int fnum;
3677 int num_pipes = 0;
3678
3679 printf("starting pipenumber test\n");
3680 if (!torture_open_connection(&cli1, 0)) {
3681 return False;
3682 }
3683
3684 cli_sockopt(cli1, sockops);
3685 while(1) {
3686 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3687 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3688
3689 if (fnum == -1) {
3690 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3691 break;
3692 }
3693 num_pipes++;
3694 printf("\r%6d", num_pipes);
3695 }
3696
3697 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3698 torture_close_connection(cli1);
3699 return True;
3700}
3701
3702/*
3703 Test open mode returns on read-only files.
3704 */
3705static BOOL run_opentest(int dummy)
3706{
3707 static struct cli_state *cli1;
3708 static struct cli_state *cli2;
3709 const char *fname = "\\readonly.file";
3710 int fnum1, fnum2;
3711 char buf[20];
3712 SMB_OFF_T fsize;
3713 BOOL correct = True;
3714 char *tmp_path;
3715
3716 printf("starting open test\n");
3717
3718 if (!torture_open_connection(&cli1, 0)) {
3719 return False;
3720 }
3721
3722 cli_setatr(cli1, fname, 0, 0);
3723 cli_unlink(cli1, fname);
3724
3725 cli_sockopt(cli1, sockops);
3726
3727 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3728 if (fnum1 == -1) {
3729 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3730 return False;
3731 }
3732
3733 if (!cli_close(cli1, fnum1)) {
3734 printf("close2 failed (%s)\n", cli_errstr(cli1));
3735 return False;
3736 }
3737
3738 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3739 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3740 return False;
3741 }
3742
3743 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3744 if (fnum1 == -1) {
3745 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3746 return False;
3747 }
3748
3749 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3750 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3751
3752 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3753 NT_STATUS_ACCESS_DENIED)) {
3754 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3755 }
3756
3757 printf("finished open test 1\n");
3758
3759 cli_close(cli1, fnum1);
3760
3761 /* Now try not readonly and ensure ERRbadshare is returned. */
3762
3763 cli_setatr(cli1, fname, 0, 0);
3764
3765 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3766 if (fnum1 == -1) {
3767 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3768 return False;
3769 }
3770
3771 /* This will fail - but the error should be ERRshare. */
3772 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3773
3774 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3775 NT_STATUS_SHARING_VIOLATION)) {
3776 printf("correct error code ERRDOS/ERRbadshare returned\n");
3777 }
3778
3779 if (!cli_close(cli1, fnum1)) {
3780 printf("close2 failed (%s)\n", cli_errstr(cli1));
3781 return False;
3782 }
3783
3784 cli_unlink(cli1, fname);
3785
3786 printf("finished open test 2\n");
3787
3788 /* Test truncate open disposition on file opened for read. */
3789
3790 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3791 if (fnum1 == -1) {
3792 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3793 return False;
3794 }
3795
3796 /* write 20 bytes. */
3797
3798 memset(buf, '\0', 20);
3799
3800 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3801 printf("write failed (%s)\n", cli_errstr(cli1));
3802 correct = False;
3803 }
3804
3805 if (!cli_close(cli1, fnum1)) {
3806 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3807 return False;
3808 }
3809
3810 /* Ensure size == 20. */
3811 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3812 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3813 return False;
3814 }
3815
3816 if (fsize != 20) {
3817 printf("(3) file size != 20\n");
3818 return False;
3819 }
3820
3821 /* Now test if we can truncate a file opened for readonly. */
3822
3823 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3824 if (fnum1 == -1) {
3825 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3826 return False;
3827 }
3828
3829 if (!cli_close(cli1, fnum1)) {
3830 printf("close2 failed (%s)\n", cli_errstr(cli1));
3831 return False;
3832 }
3833
3834 /* Ensure size == 0. */
3835 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3836 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3837 return False;
3838 }
3839
3840 if (fsize != 0) {
3841 printf("(3) file size != 0\n");
3842 return False;
3843 }
3844 printf("finished open test 3\n");
3845
3846 cli_unlink(cli1, fname);
3847
3848
3849 printf("testing ctemp\n");
3850 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3851 if (fnum1 == -1) {
3852 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3853 return False;
3854 }
3855 printf("ctemp gave path %s\n", tmp_path);
3856 if (!cli_close(cli1, fnum1)) {
3857 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3858 }
3859 if (!cli_unlink(cli1, tmp_path)) {
3860 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3861 }
3862
3863 /* Test the non-io opens... */
3864
3865 if (!torture_open_connection(&cli2, 1)) {
3866 return False;
3867 }
3868
3869 cli_setatr(cli2, fname, 0, 0);
3870 cli_unlink(cli2, fname);
3871
3872 cli_sockopt(cli2, sockops);
3873
3874 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3875
3876 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3877 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3878
3879 if (fnum1 == -1) {
3880 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3881 return False;
3882 }
3883
3884 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3885 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3886
3887 if (fnum2 == -1) {
3888 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3889 return False;
3890 }
3891
3892 if (!cli_close(cli1, fnum1)) {
3893 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3894 return False;
3895 }
3896 if (!cli_close(cli2, fnum2)) {
3897 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3898 return False;
3899 }
3900
3901 printf("non-io open test #1 passed.\n");
3902
3903 cli_unlink(cli1, fname);
3904
3905 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3906
3907 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3908 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3909
3910 if (fnum1 == -1) {
3911 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3912 return False;
3913 }
3914
3915 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3916 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3917
3918 if (fnum2 == -1) {
3919 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3920 return False;
3921 }
3922
3923 if (!cli_close(cli1, fnum1)) {
3924 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3925 return False;
3926 }
3927 if (!cli_close(cli2, fnum2)) {
3928 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3929 return False;
3930 }
3931
3932 printf("non-io open test #2 passed.\n");
3933
3934 cli_unlink(cli1, fname);
3935
3936 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3937
3938 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3939 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3940
3941 if (fnum1 == -1) {
3942 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3943 return False;
3944 }
3945
3946 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3947 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3948
3949 if (fnum2 == -1) {
3950 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3951 return False;
3952 }
3953
3954 if (!cli_close(cli1, fnum1)) {
3955 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3956 return False;
3957 }
3958 if (!cli_close(cli2, fnum2)) {
3959 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3960 return False;
3961 }
3962
3963 printf("non-io open test #3 passed.\n");
3964
3965 cli_unlink(cli1, fname);
3966
3967 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3968
3969 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3970 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3971
3972 if (fnum1 == -1) {
3973 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3974 return False;
3975 }
3976
3977 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3978 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3979
3980 if (fnum2 != -1) {
3981 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3982 return False;
3983 }
3984
3985 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3986
3987 if (!cli_close(cli1, fnum1)) {
3988 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3989 return False;
3990 }
3991
3992 printf("non-io open test #4 passed.\n");
3993
3994 cli_unlink(cli1, fname);
3995
3996 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3997
3998 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3999 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4000
4001 if (fnum1 == -1) {
4002 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4003 return False;
4004 }
4005
4006 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4007 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4008
4009 if (fnum2 == -1) {
4010 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4011 return False;
4012 }
4013
4014 if (!cli_close(cli1, fnum1)) {
4015 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4016 return False;
4017 }
4018
4019 if (!cli_close(cli2, fnum2)) {
4020 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4021 return False;
4022 }
4023
4024 printf("non-io open test #5 passed.\n");
4025
4026 printf("TEST #6 testing 1 non-io open, one io open\n");
4027
4028 cli_unlink(cli1, fname);
4029
4030 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4031 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4032
4033 if (fnum1 == -1) {
4034 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4035 return False;
4036 }
4037
4038 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4039 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4040
4041 if (fnum2 == -1) {
4042 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4043 return False;
4044 }
4045
4046 if (!cli_close(cli1, fnum1)) {
4047 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4048 return False;
4049 }
4050
4051 if (!cli_close(cli2, fnum2)) {
4052 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4053 return False;
4054 }
4055
4056 printf("non-io open test #6 passed.\n");
4057
4058 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4059
4060 cli_unlink(cli1, fname);
4061
4062 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4063 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4064
4065 if (fnum1 == -1) {
4066 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4067 return False;
4068 }
4069
4070 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4071 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4072
4073 if (fnum2 != -1) {
4074 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4075 return False;
4076 }
4077
4078 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4079
4080 if (!cli_close(cli1, fnum1)) {
4081 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4082 return False;
4083 }
4084
4085 printf("non-io open test #7 passed.\n");
4086
4087 cli_unlink(cli1, fname);
4088
4089 if (!torture_close_connection(cli1)) {
4090 correct = False;
4091 }
4092 if (!torture_close_connection(cli2)) {
4093 correct = False;
4094 }
4095
4096 return correct;
4097}
4098
4099static uint32 open_attrs_table[] = {
4100 FILE_ATTRIBUTE_NORMAL,
4101 FILE_ATTRIBUTE_ARCHIVE,
4102 FILE_ATTRIBUTE_READONLY,
4103 FILE_ATTRIBUTE_HIDDEN,
4104 FILE_ATTRIBUTE_SYSTEM,
4105
4106 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4109 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4110 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4111 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4112
4113 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4114 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4115 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4116 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4117};
4118
4119struct trunc_open_results {
4120 unsigned int num;
4121 uint32 init_attr;
4122 uint32 trunc_attr;
4123 uint32 result_attr;
4124};
4125
4126static struct trunc_open_results attr_results[] = {
4127 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4128 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4129 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4130 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4131 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4132 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4133 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4134 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4135 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4136 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4137 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4138 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4139 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4140 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4141 { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4142 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4143 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4144 { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4145 { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
4146 { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
4147 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4148 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4149 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4150 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4151 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4152 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4153};
4154
4155static BOOL run_openattrtest(int dummy)
4156{
4157 static struct cli_state *cli1;
4158 const char *fname = "\\openattr.file";
4159 int fnum1;
4160 BOOL correct = True;
4161 uint16 attr;
4162 unsigned int i, j, k, l;
4163
4164 printf("starting open attr test\n");
4165
4166 if (!torture_open_connection(&cli1, 0)) {
4167 return False;
4168 }
4169
4170 cli_sockopt(cli1, sockops);
4171
4172 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4173 cli_setatr(cli1, fname, 0, 0);
4174 cli_unlink(cli1, fname);
4175 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4176 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4177
4178 if (fnum1 == -1) {
4179 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4180 return False;
4181 }
4182
4183 if (!cli_close(cli1, fnum1)) {
4184 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4185 return False;
4186 }
4187
4188 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4189 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4190 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4191
4192 if (fnum1 == -1) {
4193 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4194 if (attr_results[l].num == k) {
4195 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4196 k, open_attrs_table[i],
4197 open_attrs_table[j],
4198 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4199 correct = False;
4200 }
4201 }
4202 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4203 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4204 k, open_attrs_table[i], open_attrs_table[j],
4205 cli_errstr(cli1));
4206 correct = False;
4207 }
4208#if 0
4209 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4210#endif
4211 k++;
4212 continue;
4213 }
4214
4215 if (!cli_close(cli1, fnum1)) {
4216 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4217 return False;
4218 }
4219
4220 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4221 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4222 return False;
4223 }
4224
4225#if 0
4226 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4227 k, open_attrs_table[i], open_attrs_table[j], attr );
4228#endif
4229
4230 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4231 if (attr_results[l].num == k) {
4232 if (attr != attr_results[l].result_attr ||
4233 open_attrs_table[i] != attr_results[l].init_attr ||
4234 open_attrs_table[j] != attr_results[l].trunc_attr) {
4235 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4236 open_attrs_table[i],
4237 open_attrs_table[j],
4238 (unsigned int)attr,
4239 attr_results[l].result_attr);
4240 correct = False;
4241 }
4242 break;
4243 }
4244 }
4245 k++;
4246 }
4247 }
4248
4249 cli_setatr(cli1, fname, 0, 0);
4250 cli_unlink(cli1, fname);
4251
4252 printf("open attr test %s.\n", correct ? "passed" : "failed");
4253
4254 if (!torture_close_connection(cli1)) {
4255 correct = False;
4256 }
4257 return correct;
4258}
4259
4260static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4261{
4262
4263}
4264
4265/*
4266 test directory listing speed
4267 */
4268static BOOL run_dirtest(int dummy)
4269{
4270 int i;
4271 static struct cli_state *cli;
4272 int fnum;
4273 double t1;
4274 BOOL correct = True;
4275
4276 printf("starting directory test\n");
4277
4278 if (!torture_open_connection(&cli, 0)) {
4279 return False;
4280 }
4281
4282 cli_sockopt(cli, sockops);
4283
4284 srandom(0);
4285 for (i=0;i<torture_numops;i++) {
4286 fstring fname;
4287 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4288 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4289 if (fnum == -1) {
4290 fprintf(stderr,"Failed to open %s\n", fname);
4291 return False;
4292 }
4293 cli_close(cli, fnum);
4294 }
4295
4296 t1 = end_timer();
4297
4298 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4299 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4300 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4301
4302 printf("dirtest core %g seconds\n", end_timer() - t1);
4303
4304 srandom(0);
4305 for (i=0;i<torture_numops;i++) {
4306 fstring fname;
4307 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4308 cli_unlink(cli, fname);
4309 }
4310
4311 if (!torture_close_connection(cli)) {
4312 correct = False;
4313 }
4314
4315 printf("finished dirtest\n");
4316
4317 return correct;
4318}
4319
4320static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4321{
4322 struct cli_state *pcli = (struct cli_state *)state;
4323 fstring fname;
4324 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4325
4326 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4327 return;
4328
4329 if (finfo->mode & aDIR) {
4330 if (!cli_rmdir(pcli, fname))
4331 printf("del_fn: failed to rmdir %s\n,", fname );
4332 } else {
4333 if (!cli_unlink(pcli, fname))
4334 printf("del_fn: failed to unlink %s\n,", fname );
4335 }
4336}
4337
4338
4339/*
4340 sees what IOCTLs are supported
4341 */
4342BOOL torture_ioctl_test(int dummy)
4343{
4344 static struct cli_state *cli;
4345 uint16 device, function;
4346 int fnum;
4347 const char *fname = "\\ioctl.dat";
4348 DATA_BLOB blob;
4349 NTSTATUS status;
4350
4351 if (!torture_open_connection(&cli, 0)) {
4352 return False;
4353 }
4354
4355 printf("starting ioctl test\n");
4356
4357 cli_unlink(cli, fname);
4358
4359 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4360 if (fnum == -1) {
4361 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4362 return False;
4363 }
4364
4365 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4366 printf("ioctl device info: %s\n", cli_errstr(cli));
4367
4368 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4369 printf("ioctl job info: %s\n", cli_errstr(cli));
4370
4371 for (device=0;device<0x100;device++) {
4372 printf("testing device=0x%x\n", device);
4373 for (function=0;function<0x100;function++) {
4374 uint32 code = (device<<16) | function;
4375
4376 status = cli_raw_ioctl(cli, fnum, code, &blob);
4377
4378 if (NT_STATUS_IS_OK(status)) {
4379 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4380 (int)blob.length);
4381 data_blob_free(&blob);
4382 }
4383 }
4384 }
4385
4386 if (!torture_close_connection(cli)) {
4387 return False;
4388 }
4389
4390 return True;
4391}
4392
4393
4394/*
4395 tries varients of chkpath
4396 */
4397BOOL torture_chkpath_test(int dummy)
4398{
4399 static struct cli_state *cli;
4400 int fnum;
4401 BOOL ret;
4402
4403 if (!torture_open_connection(&cli, 0)) {
4404 return False;
4405 }
4406
4407 printf("starting chkpath test\n");
4408
4409 /* cleanup from an old run */
4410 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4411 cli_unlink(cli, "\\chkpath.dir\\*");
4412 cli_rmdir(cli, "\\chkpath.dir");
4413
4414 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4415 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4416 return False;
4417 }
4418
4419 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4420 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4421 return False;
4422 }
4423
4424 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4425 if (fnum == -1) {
4426 printf("open1 failed (%s)\n", cli_errstr(cli));
4427 return False;
4428 }
4429 cli_close(cli, fnum);
4430
4431 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4432 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4433 ret = False;
4434 }
4435
4436 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4437 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4438 ret = False;
4439 }
4440
4441 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4442 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4443 NT_STATUS_NOT_A_DIRECTORY);
4444 } else {
4445 printf("* chkpath on a file should fail\n");
4446 ret = False;
4447 }
4448
4449 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4450 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4451 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4452 } else {
4453 printf("* chkpath on a non existant file should fail\n");
4454 ret = False;
4455 }
4456
4457 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4458 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4459 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4460 } else {
4461 printf("* chkpath on a non existent component should fail\n");
4462 ret = False;
4463 }
4464
4465 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4466 cli_unlink(cli, "\\chkpath.dir\\*");
4467 cli_rmdir(cli, "\\chkpath.dir");
4468
4469 if (!torture_close_connection(cli)) {
4470 return False;
4471 }
4472
4473 return ret;
4474}
4475
4476static BOOL run_eatest(int dummy)
4477{
4478 static struct cli_state *cli;
4479 const char *fname = "\\eatest.txt";
4480 BOOL correct = True;
4481 int fnum, i;
4482 size_t num_eas;
4483 struct ea_struct *ea_list = NULL;
4484 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4485
4486 printf("starting eatest\n");
4487
4488 if (!torture_open_connection(&cli, 0)) {
4489 talloc_destroy(mem_ctx);
4490 return False;
4491 }
4492
4493 cli_unlink(cli, fname);
4494 fnum = cli_nt_create_full(cli, fname, 0,
4495 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4496 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4497 0x4044, 0);
4498
4499 if (fnum == -1) {
4500 printf("open failed - %s\n", cli_errstr(cli));
4501 talloc_destroy(mem_ctx);
4502 return False;
4503 }
4504
4505 for (i = 0; i < 10; i++) {
4506 fstring ea_name, ea_val;
4507
4508 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4509 memset(ea_val, (char)i+1, i+1);
4510 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4511 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4512 talloc_destroy(mem_ctx);
4513 return False;
4514 }
4515 }
4516
4517 cli_close(cli, fnum);
4518 for (i = 0; i < 10; i++) {
4519 fstring ea_name, ea_val;
4520
4521 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4522 memset(ea_val, (char)i+1, i+1);
4523 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4524 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4525 talloc_destroy(mem_ctx);
4526 return False;
4527 }
4528 }
4529
4530 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4531 printf("ea_get list failed - %s\n", cli_errstr(cli));
4532 correct = False;
4533 }
4534
4535 printf("num_eas = %d\n", (int)num_eas);
4536
4537#ifdef __OS2__ // add libc UNIX emulation EAs
4538 if (num_eas != 27) {
4539#else
4540 if (num_eas != 20) {
4541#endif
4542 printf("Should be 20 EA's stored... failing.\n");
4543 correct = False;
4544 }
4545
4546 for (i = 0; i < num_eas; i++) {
4547 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4548 dump_data(0, (char *)ea_list[i].value.data,
4549 ea_list[i].value.length);
4550 }
4551
4552 /* Setting EA's to zero length deletes them. Test this */
4553 printf("\nNow deleting all EA's - case indepenent....\n");
4554
4555#if 0 // YD see bug#3212, smb_info_set_ea(), this is a NOP now!
4556 cli_set_ea_path(cli, fname, "", "", 0);
4557#else
4558 for (i = 0; i < 20; i++) {
4559 fstring ea_name;
4560 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4561 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4562 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4563 talloc_destroy(mem_ctx);
4564 return False;
4565 }
4566 }
4567#endif
4568
4569 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4570 printf("ea_get list failed - %s\n", cli_errstr(cli));
4571 correct = False;
4572 }
4573
4574 printf("num_eas = %d\n", (int)num_eas);
4575 for (i = 0; i < num_eas; i++) {
4576 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4577 dump_data(0, (char *)ea_list[i].value.data,
4578 ea_list[i].value.length);
4579 }
4580
4581 if (num_eas != 0) {
4582 printf("\ndeleting EA's failed.\n");
4583 correct = False;
4584 }
4585
4586 /* Try and delete a non existant EA. */
4587 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4588 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4589 correct = False;
4590 }
4591
4592 talloc_destroy(mem_ctx);
4593 if (!torture_close_connection(cli)) {
4594 correct = False;
4595 }
4596
4597 return correct;
4598}
4599
4600static BOOL run_dirtest1(int dummy)
4601{
4602 int i;
4603 static struct cli_state *cli;
4604 int fnum, num_seen;
4605 BOOL correct = True;
4606
4607 printf("starting directory test\n");
4608
4609 if (!torture_open_connection(&cli, 0)) {
4610 return False;
4611 }
4612
4613 cli_sockopt(cli, sockops);
4614
4615 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4616 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4617 cli_rmdir(cli, "\\LISTDIR");
4618 cli_mkdir(cli, "\\LISTDIR");
4619
4620 /* Create 1000 files and 1000 directories. */
4621 for (i=0;i<1000;i++) {
4622 fstring fname;
4623 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4624 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4625 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4626 if (fnum == -1) {
4627 fprintf(stderr,"Failed to open %s\n", fname);
4628 return False;
4629 }
4630 cli_close(cli, fnum);
4631 }
4632 for (i=0;i<1000;i++) {
4633 fstring fname;
4634 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4635 if (!cli_mkdir(cli, fname)) {
4636 fprintf(stderr,"Failed to open %s\n", fname);
4637 return False;
4638 }
4639 }
4640
4641 /* Now ensure that doing an old list sees both files and directories. */
4642 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4643 printf("num_seen = %d\n", num_seen );
4644 /* We should see 100 files + 1000 directories + . and .. */
4645 if (num_seen != 2002)
4646 correct = False;
4647
4648 /* Ensure if we have the "must have" bits we only see the
4649 * relevent entries.
4650 */
4651 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4652 printf("num_seen = %d\n", num_seen );
4653 if (num_seen != 1002)
4654 correct = False;
4655
4656 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4657 printf("num_seen = %d\n", num_seen );
4658 if (num_seen != 1000)
4659 correct = False;
4660
4661 /* Delete everything. */
4662 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4663 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4664 cli_rmdir(cli, "\\LISTDIR");
4665
4666#if 0
4667 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4668 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4669 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4670#endif
4671
4672 if (!torture_close_connection(cli)) {
4673 correct = False;
4674 }
4675
4676 printf("finished dirtest1\n");
4677
4678 return correct;
4679}
4680
4681static BOOL run_error_map_extract(int dummy) {
4682
4683 static struct cli_state *c_dos;
4684 static struct cli_state *c_nt;
4685
4686 uint32 error;
4687
4688 uint32 flgs2, errnum;
4689 uint8 errclass;
4690
4691 NTSTATUS nt_status;
4692
4693 fstring user;
4694
4695 /* NT-Error connection */
4696
4697 if (!(c_nt = open_nbt_connection())) {
4698 return False;
4699 }
4700
4701 c_nt->use_spnego = False;
4702
4703 if (!cli_negprot(c_nt)) {
4704 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
4705 cli_shutdown(c_nt);
4706 return False;
4707 }
4708
4709 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4710 workgroup))) {
4711 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4712 return False;
4713 }
4714
4715 /* DOS-Error connection */
4716
4717 if (!(c_dos = open_nbt_connection())) {
4718 return False;
4719 }
4720
4721 c_dos->use_spnego = False;
4722 c_dos->force_dos_errors = True;
4723
4724 if (!cli_negprot(c_dos)) {
4725 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
4726 cli_shutdown(c_dos);
4727 return False;
4728 }
4729
4730 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4731 workgroup))) {
4732 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4733 return False;
4734 }
4735
4736 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4737 fstr_sprintf(user, "%X", error);
4738
4739 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4740 password, strlen(password),
4741 password, strlen(password),
4742 workgroup))) {
4743 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4744 }
4745
4746 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4747
4748 /* Case #1: 32-bit NT errors */
4749 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4750 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4751 } else {
4752 printf("/** Dos error on NT connection! (%s) */\n",
4753 cli_errstr(c_nt));
4754 nt_status = NT_STATUS(0xc0000000);
4755 }
4756
4757 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4758 password, strlen(password),
4759 password, strlen(password),
4760 workgroup))) {
4761 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4762 }
4763 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4764
4765 /* Case #1: 32-bit NT errors */
4766 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4767 printf("/** NT error on DOS connection! (%s) */\n",
4768 cli_errstr(c_nt));
4769 errnum = errclass = 0;
4770 } else {
4771 cli_dos_error(c_dos, &errclass, &errnum);
4772 }
4773
4774 if (NT_STATUS_V(nt_status) != error) {
4775 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4776 get_nt_error_c_code(NT_STATUS(error)),
4777 get_nt_error_c_code(nt_status));
4778 }
4779
4780 printf("\t{%s,\t%s,\t%s},\n",
4781 smb_dos_err_class(errclass),
4782 smb_dos_err_name(errclass, errnum),
4783 get_nt_error_c_code(NT_STATUS(error)));
4784 }
4785 return True;
4786}
4787
4788static BOOL run_sesssetup_bench(int dummy)
4789{
4790 static struct cli_state *c;
4791 NTSTATUS status;
4792 int i;
4793
4794 if (!(c = open_nbt_connection())) {
4795 return false;
4796 }
4797
4798 if (!cli_negprot(c)) {
4799 printf("%s rejected the NT-error negprot (%s)\n", host,
4800 cli_errstr(c));
4801 cli_shutdown(c);
4802 return false;
4803 }
4804
4805 for (i=0; i<torture_numops; i++) {
4806 status = cli_session_setup(
4807 c, username,
4808 password, strlen(password),
4809 password, strlen(password),
4810 workgroup);
4811 if (!NT_STATUS_IS_OK(status)) {
4812 d_printf("(%s) cli_session_setup failed: %s\n",
4813 __location__, nt_errstr(status));
4814 return false;
4815 }
4816
4817 if (!cli_ulogoff(c)) {
4818 d_printf("(%s) cli_ulogoff failed: %s\n",
4819 __location__, cli_errstr(c));
4820 return false;
4821 }
4822
4823 c->vuid = 0;
4824 }
4825
4826 return True;
4827}
4828
4829static BOOL run_local_substitute(int dummy)
4830{
4831 TALLOC_CTX *mem_ctx;
4832 int diff = 0;
4833
4834 if ((mem_ctx = talloc_init("run_local_subst")) == NULL) {
4835 printf("talloc_init failed\n");
4836 return False;
4837 }
4838
4839 diff |= strcmp(talloc_sub_specified(mem_ctx, "%U", "bla", "", -1, -1),
4840 "bla");
4841 diff |= strcmp(talloc_sub_specified(mem_ctx, "%u%U", "bla", "", -1, -1),
4842 "blabla");
4843 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, -1),
4844 "NO_GROUP");
4845 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, -1),
4846 "NO_GROUP");
4847 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, 0),
4848 gidtoname(0));
4849 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, 0),
4850 gidtoname(0));
4851 diff |= strcmp(talloc_sub_specified(mem_ctx, "%D%u", "u", "dom", -1, 0),
4852 "domu");
4853 diff |= strcmp(talloc_sub_specified(mem_ctx, "%i %I", "", "", -1, -1),
4854 "0.0.0.0 0.0.0.0");
4855
4856 /* Different captialization rules in sub_basic... */
4857
4858 diff |= strcmp(talloc_sub_basic(mem_ctx, "BLA", "dom", "%U%D"),
4859 "blaDOM");
4860
4861 TALLOC_FREE(mem_ctx);
4862 return (diff == 0);
4863}
4864
4865static BOOL run_local_gencache(int dummy)
4866{
4867 char *val;
4868 time_t tm;
4869
4870 if (!gencache_init()) {
4871 d_printf("%s: gencache_init() failed\n", __location__);
4872 return False;
4873 }
4874
4875 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
4876 d_printf("%s: gencache_set() failed\n", __location__);
4877 return False;
4878 }
4879
4880 if (!gencache_get("foo", &val, &tm)) {
4881 d_printf("%s: gencache_get() failed\n", __location__);
4882 return False;
4883 }
4884
4885 if (strcmp(val, "bar") != 0) {
4886 d_printf("%s: gencache_get() returned %s, expected %s\n",
4887 __location__, val, "bar");
4888 SAFE_FREE(val);
4889 return False;
4890 }
4891
4892 SAFE_FREE(val);
4893
4894 if (!gencache_del("foo")) {
4895 d_printf("%s: gencache_del() failed\n", __location__);
4896 return False;
4897 }
4898 if (gencache_del("foo")) {
4899 d_printf("%s: second gencache_del() succeeded\n",
4900 __location__);
4901 return False;
4902 }
4903
4904 if (gencache_get("foo", &val, &tm)) {
4905 d_printf("%s: gencache_get() on deleted entry "
4906 "succeeded\n", __location__);
4907 return False;
4908 }
4909
4910 if (!gencache_shutdown()) {
4911 d_printf("%s: gencache_shutdown() failed\n", __location__);
4912 return False;
4913 }
4914
4915 if (gencache_shutdown()) {
4916 d_printf("%s: second gencache_shutdown() succeeded\n",
4917 __location__);
4918 return False;
4919 }
4920
4921 return True;
4922}
4923
4924static double create_procs(BOOL (*fn)(int), BOOL *result)
4925{
4926 int i, status;
4927 volatile pid_t *child_status;
4928 volatile BOOL *child_status_out;
4929 int synccount;
4930 int tries = 8;
4931
4932 synccount = 0;
4933
4934 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4935 if (!child_status) {
4936 printf("Failed to setup shared memory\n");
4937 return -1;
4938 }
4939
4940 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4941 if (!child_status_out) {
4942 printf("Failed to setup result status shared memory\n");
4943 return -1;
4944 }
4945
4946 for (i = 0; i < nprocs; i++) {
4947 child_status[i] = 0;
4948 child_status_out[i] = True;
4949 }
4950
4951 start_timer();
4952
4953 for (i=0;i<nprocs;i++) {
4954 procnum = i;
4955 if (fork() == 0) {
4956 pid_t mypid = getpid();
4957 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4958
4959 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4960
4961 while (1) {
4962 if (torture_open_connection(&current_cli, i)) break;
4963 if (tries-- == 0) {
4964 printf("pid %d failed to start\n", (int)getpid());
4965 _exit(1);
4966 }
4967 smb_msleep(10);
4968 }
4969
4970 child_status[i] = getpid();
4971
4972 while (child_status[i] && end_timer() < 5) smb_msleep(2);
4973
4974 child_status_out[i] = fn(i);
4975 _exit(0);
4976 }
4977 }
4978
4979 do {
4980 synccount = 0;
4981 for (i=0;i<nprocs;i++) {
4982 if (child_status[i]) synccount++;
4983 }
4984 if (synccount == nprocs) break;
4985 smb_msleep(10);
4986 } while (end_timer() < 30);
4987
4988 if (synccount != nprocs) {
4989 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4990 *result = False;
4991 return end_timer();
4992 }
4993
4994 /* start the client load */
4995 start_timer();
4996
4997 for (i=0;i<nprocs;i++) {
4998 child_status[i] = 0;
4999 }
5000
5001 printf("%d clients started\n", nprocs);
5002
5003 for (i=0;i<nprocs;i++) {
5004 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5005 }
5006
5007 printf("\n");
5008
5009 for (i=0;i<nprocs;i++) {
5010 if (!child_status_out[i]) {
5011 *result = False;
5012 }
5013 }
5014 return end_timer();
5015}
5016
5017#define FLAG_MULTIPROC 1
5018
5019static struct {
5020 const char *name;
5021 BOOL (*fn)(int);
5022 unsigned flags;
5023} torture_ops[] = {
5024 {"FDPASS", run_fdpasstest, 0},
5025 {"LOCK1", run_locktest1, 0},
5026 {"LOCK2", run_locktest2, 0},
5027 {"LOCK3", run_locktest3, 0},
5028 {"LOCK4", run_locktest4, 0},
5029 {"LOCK5", run_locktest5, 0},
5030 {"LOCK6", run_locktest6, 0},
5031 {"LOCK7", run_locktest7, 0},
5032 {"UNLINK", run_unlinktest, 0},
5033 {"BROWSE", run_browsetest, 0},
5034 {"ATTR", run_attrtest, 0},
5035 {"TRANS2", run_trans2test, 0},
5036 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5037 {"TORTURE",run_torture, FLAG_MULTIPROC},
5038 {"RANDOMIPC", run_randomipc, 0},
5039 {"NEGNOWAIT", run_negprot_nowait, 0},
5040 {"NBENCH", run_nbench, 0},
5041 {"OPLOCK1", run_oplock1, 0},
5042 {"OPLOCK2", run_oplock2, 0},
5043 {"OPLOCK3", run_oplock3, 0},
5044 {"DIR", run_dirtest, 0},
5045 {"DIR1", run_dirtest1, 0},
5046 {"DENY1", torture_denytest1, 0},
5047 {"DENY2", torture_denytest2, 0},
5048 {"TCON", run_tcon_test, 0},
5049 {"TCONDEV", run_tcon_devtype_test, 0},
5050 {"RW1", run_readwritetest, 0},
5051 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5052 {"RW3", run_readwritelarge, 0},
5053 {"OPEN", run_opentest, 0},
5054#if 1
5055 {"OPENATTR", run_openattrtest, 0},
5056#endif
5057 {"XCOPY", run_xcopy, 0},
5058 {"RENAME", run_rename, 0},
5059 {"DELETE", run_deletetest, 0},
5060 {"PROPERTIES", run_properties, 0},
5061 {"MANGLE", torture_mangle, 0},
5062 {"W2K", run_w2ktest, 0},
5063 {"TRANS2SCAN", torture_trans2_scan, 0},
5064 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5065 {"UTABLE", torture_utable, 0},
5066 {"CASETABLE", torture_casetable, 0},
5067 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5068 {"PIPE_NUMBER", run_pipe_number, 0},
5069 {"TCON2", run_tcon2_test, 0},
5070 {"IOCTL", torture_ioctl_test, 0},
5071 {"CHKPATH", torture_chkpath_test, 0},
5072 {"FDSESS", run_fdsesstest, 0},
5073 { "EATEST", run_eatest, 0},
5074 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5075 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5076 { "LOCAL-GENCACHE", run_local_gencache, 0},
5077 {NULL, NULL, 0}};
5078
5079
5080
5081/****************************************************************************
5082run a specified test or "ALL"
5083****************************************************************************/
5084static BOOL run_test(const char *name)
5085{
5086 BOOL ret = True;
5087 BOOL result = True;
5088 BOOL found = False;
5089 int i;
5090 double t;
5091 if (strequal(name,"ALL")) {
5092 for (i=0;torture_ops[i].name;i++) {
5093 run_test(torture_ops[i].name);
5094 }
5095 found = True;
5096 }
5097
5098 for (i=0;torture_ops[i].name;i++) {
5099 fstr_sprintf(randomfname, "\\XX%x",
5100 (unsigned)random());
5101
5102 if (strequal(name, torture_ops[i].name)) {
5103 found = True;
5104 printf("Running %s\n", name);
5105 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5106 t = create_procs(torture_ops[i].fn, &result);
5107 if (!result) {
5108 ret = False;
5109 printf("TEST %s FAILED!\n", name);
5110 }
5111
5112 } else {
5113 start_timer();
5114 if (!torture_ops[i].fn(0)) {
5115 ret = False;
5116 printf("TEST %s FAILED!\n", name);
5117 }
5118 t = end_timer();
5119 }
5120 printf("%s took %g secs\n\n", name, t);
5121 }
5122 }
5123
5124 if (!found) {
5125 printf("Did not find a test named %s\n", name);
5126 ret = False;
5127 }
5128
5129 return ret;
5130}
5131
5132
5133static void usage(void)
5134{
5135 int i;
5136
5137 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5138 printf("Please use samba4 torture.\n\n");
5139
5140 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5141
5142 printf("\t-d debuglevel\n");
5143 printf("\t-U user%%pass\n");
5144 printf("\t-k use kerberos\n");
5145 printf("\t-N numprocs\n");
5146 printf("\t-n my_netbios_name\n");
5147 printf("\t-W workgroup\n");
5148 printf("\t-o num_operations\n");
5149 printf("\t-O socket_options\n");
5150 printf("\t-m maximum protocol\n");
5151 printf("\t-L use oplocks\n");
5152 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5153 printf("\t-A showall\n");
5154 printf("\t-p port\n");
5155 printf("\t-s seed\n");
5156 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5157 printf("\n\n");
5158
5159 printf("tests are:");
5160 for (i=0;torture_ops[i].name;i++) {
5161 printf(" %s", torture_ops[i].name);
5162 }
5163 printf("\n");
5164
5165 printf("default test is ALL\n");
5166
5167 exit(1);
5168}
5169
5170/****************************************************************************
5171 main program
5172****************************************************************************/
5173 int main(int argc,char *argv[])
5174{
5175 int opt, i;
5176 char *p;
5177 int gotuser = 0;
5178 int gotpass = 0;
5179 BOOL correct = True;
5180
5181 dbf = x_stdout;
5182
5183#ifdef HAVE_SETBUFFER
5184 setbuffer(stdout, NULL, 0);
5185#endif
5186
5187 load_case_tables();
5188
5189 lp_load(dyn_CONFIGFILE,True,False,False,True);
5190 load_interfaces();
5191
5192 if (argc < 2) {
5193 usage();
5194 }
5195
5196 for(p = argv[1]; *p; p++)
5197 if(*p == '\\')
5198 *p = '/';
5199
5200 if (strncmp(argv[1], "//", 2)) {
5201 usage();
5202 }
5203
5204 fstrcpy(host, &argv[1][2]);
5205 p = strchr_m(&host[2],'/');
5206 if (!p) {
5207 usage();
5208 }
5209 *p = 0;
5210 fstrcpy(share, p+1);
5211
5212 get_myname(myname);
5213
5214 if (*username == 0 && getenv("LOGNAME")) {
5215 fstrcpy(username,getenv("LOGNAME"));
5216 }
5217
5218 argc--;
5219 argv++;
5220
5221 srandom(time(NULL));
5222
5223 fstrcpy(workgroup, lp_workgroup());
5224
5225 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
5226 switch (opt) {
5227 case 'p':
5228 port_to_use = atoi(optarg);
5229 break;
5230 case 's':
5231 srandom(atoi(optarg));
5232 break;
5233 case 'W':
5234 fstrcpy(workgroup,optarg);
5235 break;
5236 case 'm':
5237 max_protocol = interpret_protocol(optarg, max_protocol);
5238 break;
5239 case 'N':
5240 nprocs = atoi(optarg);
5241 break;
5242 case 'o':
5243 torture_numops = atoi(optarg);
5244 break;
5245 case 'd':
5246 DEBUGLEVEL = atoi(optarg);
5247 break;
5248 case 'O':
5249 sockops = optarg;
5250 break;
5251 case 'L':
5252 use_oplocks = True;
5253 break;
5254 case 'A':
5255 torture_showall = True;
5256 break;
5257 case 'n':
5258 fstrcpy(myname, optarg);
5259 break;
5260 case 'c':
5261 client_txt = optarg;
5262 break;
5263 case 'k':
5264#ifdef HAVE_KRB5
5265 use_kerberos = True;
5266#else
5267 d_printf("No kerberos support compiled in\n");
5268 exit(1);
5269#endif
5270 break;
5271 case 'U':
5272 gotuser = 1;
5273 fstrcpy(username,optarg);
5274 p = strchr_m(username,'%');
5275 if (p) {
5276 *p = 0;
5277 fstrcpy(password, p+1);
5278 gotpass = 1;
5279 }
5280 break;
5281 case 'b':
5282 fstrcpy(multishare_conn_fname, optarg);
5283 use_multishare_conn = True;
5284 break;
5285 default:
5286 printf("Unknown option %c (%d)\n", (char)opt, opt);
5287 usage();
5288 }
5289 }
5290
5291 if(use_kerberos && !gotuser) gotpass = True;
5292
5293 while (!gotpass) {
5294 p = getpass("Password:");
5295 if (p) {
5296 fstrcpy(password, p);
5297 gotpass = 1;
5298 }
5299 }
5300
5301 printf("host=%s share=%s user=%s myname=%s\n",
5302 host, share, username, myname);
5303
5304 if (argc == optind) {
5305 correct = run_test("ALL");
5306 } else {
5307 for (i=optind;i<argc;i++) {
5308 if (!run_test(argv[i])) {
5309 correct = False;
5310 }
5311 }
5312 }
5313
5314 if (correct) {
5315 return(0);
5316 } else {
5317 return(1);
5318 }
5319}
Note: See TracBrowser for help on using the repository browser.