source: branches/samba-3.5.x/source3/torture/torture.c

Last change on this file was 833, checked in by Herwig Bauernfeind, 12 years ago

Samba 3.5: Remove torture test change

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