source: trunk/server/source3/torture/torture.c@ 690

Last change on this file since 690 was 454, checked in by Silvan Scherrer, 16 years ago

Samba Server 3.5: merged changes from 3.3

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