source: branches/samba-3.3.x/source/torture/torture.c

Last change on this file was 224, checked in by Herwig Bauernfeind, 16 years ago

Update Samba 3.3 branch to 3.3.4

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