This changes our handling of invalid service types that the
[Samba/gebeck_regimport.git] / source / torture / torture.c
blobd6ae58c522c0231cb9d27d82a747fe9c8774eef5
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #define NO_SYSLOG
23 #include "includes.h"
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 static int port_to_use=0;
30 int torture_numops=100;
31 static int procnum; /* records process count number when forking */
32 static struct cli_state *current_cli;
33 static fstring randomfname;
34 static BOOL use_oplocks;
35 static BOOL use_level_II_oplocks;
36 static const char *client_txt = "client_oplocks.txt";
37 static BOOL use_kerberos;
39 BOOL torture_showall = False;
41 static double create_procs(BOOL (*fn)(int), BOOL *result);
44 static struct timeval tp1,tp2;
46 void start_timer(void)
48 gettimeofday(&tp1,NULL);
51 double end_timer(void)
53 gettimeofday(&tp2,NULL);
54 return((tp2.tv_sec - tp1.tv_sec) +
55 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
59 /* return a pointer to a anonymous shared memory segment of size "size"
60 which will persist across fork() but will disappear when all processes
61 exit
63 The memory is not zeroed
65 This function uses system5 shared memory. It takes advantage of a property
66 that the memory is not destroyed if it is attached when the id is removed
68 void *shm_setup(int size)
70 int shmid;
71 void *ret;
73 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
74 if (shmid == -1) {
75 printf("can't get shared memory\n");
76 exit(1);
78 ret = (void *)shmat(shmid, 0, 0);
79 if (!ret || ret == (void *)-1) {
80 printf("can't attach to shared memory\n");
81 return NULL;
83 /* the following releases the ipc, but note that this process
84 and all its children will still have access to the memory, its
85 just that the shmid is no longer valid for other shm calls. This
86 means we don't leave behind lots of shm segments after we exit
88 See Stevens "advanced programming in unix env" for details
90 shmctl(shmid, IPC_RMID, 0);
92 return ret;
96 static BOOL open_nbt_connection(struct cli_state *c)
98 struct nmb_name called, calling;
99 struct in_addr ip;
101 ZERO_STRUCTP(c);
103 make_nmb_name(&calling, myname, 0x0);
104 make_nmb_name(&called , host, 0x20);
106 zero_ip(&ip);
108 if (!cli_initialise(c)) {
109 printf("Failed initialize cli_struct to connect with %s\n", host);
110 return False;
113 c->port = port_to_use;
115 if (!cli_connect(c, host, &ip)) {
116 printf("Failed to connect with %s\n", host);
117 return False;
120 c->use_kerberos = use_kerberos;
122 c->timeout = 120000; /* set a really long timeout (2 minutes) */
123 if (use_oplocks) c->use_oplocks = True;
124 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
126 if (!cli_session_request(c, &calling, &called)) {
128 * Well, that failed, try *SMBSERVER ...
129 * However, we must reconnect as well ...
131 if (!cli_connect(c, host, &ip)) {
132 printf("Failed to connect with %s\n", host);
133 return False;
136 make_nmb_name(&called, "*SMBSERVER", 0x20);
137 if (!cli_session_request(c, &calling, &called)) {
138 printf("%s rejected the session\n",host);
139 printf("We tried with a called name of %s & %s\n",
140 host, "*SMBSERVER");
141 cli_shutdown(c);
142 return False;
146 return True;
149 BOOL torture_open_connection(struct cli_state **c)
151 BOOL retry;
152 int flags = 0;
153 NTSTATUS status;
155 if (use_kerberos)
156 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
158 status = cli_full_connection(c, myname,
159 host, NULL, port_to_use,
160 share, "?????",
161 username, workgroup,
162 password, flags, &retry);
163 if (!NT_STATUS_IS_OK(status)) {
164 return False;
167 if (use_oplocks) (*c)->use_oplocks = True;
168 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
169 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
171 return True;
175 BOOL torture_close_connection(struct cli_state *c)
177 BOOL ret = True;
178 if (!cli_tdis(c)) {
179 printf("tdis failed (%s)\n", cli_errstr(c));
180 ret = False;
183 cli_shutdown(c);
185 return ret;
189 /* check if the server produced the expected error code */
190 static BOOL check_error(int line, struct cli_state *c,
191 uint8 eclass, uint32 ecode, NTSTATUS nterr)
193 if (cli_is_dos_error(c)) {
194 uint8 class;
195 uint32 num;
197 /* Check DOS error */
199 cli_dos_error(c, &class, &num);
201 if (eclass != class || ecode != num) {
202 printf("unexpected error code class=%d code=%d\n",
203 (int)class, (int)num);
204 printf(" expected %d/%d %s (line=%d)\n",
205 (int)eclass, (int)ecode, nt_errstr(nterr), line);
206 return False;
209 } else {
210 NTSTATUS status;
212 /* Check NT error */
214 status = cli_nt_error(c);
216 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
217 printf("unexpected error code %s\n", nt_errstr(status));
218 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
219 return False;
223 return True;
227 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
229 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
230 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
232 return True;
236 static BOOL rw_torture(struct cli_state *c)
238 const char *lockfname = "\\torture.lck";
239 fstring fname;
240 int fnum;
241 int fnum2;
242 pid_t pid2, pid = getpid();
243 int i, j;
244 char buf[1024];
245 BOOL correct = True;
247 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
248 DENY_NONE);
249 if (fnum2 == -1)
250 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
251 if (fnum2 == -1) {
252 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
253 return False;
257 for (i=0;i<torture_numops;i++) {
258 unsigned n = (unsigned)sys_random()%10;
259 if (i % 10 == 0) {
260 printf("%d\r", i); fflush(stdout);
262 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
264 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
265 return False;
268 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
269 if (fnum == -1) {
270 printf("open failed (%s)\n", cli_errstr(c));
271 correct = False;
272 break;
275 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
276 printf("write failed (%s)\n", cli_errstr(c));
277 correct = False;
280 for (j=0;j<50;j++) {
281 if (cli_write(c, fnum, 0, (char *)buf,
282 sizeof(pid)+(j*sizeof(buf)),
283 sizeof(buf)) != sizeof(buf)) {
284 printf("write failed (%s)\n", cli_errstr(c));
285 correct = False;
289 pid2 = 0;
291 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
292 printf("read failed (%s)\n", cli_errstr(c));
293 correct = False;
296 if (pid2 != pid) {
297 printf("data corruption!\n");
298 correct = False;
301 if (!cli_close(c, fnum)) {
302 printf("close failed (%s)\n", cli_errstr(c));
303 correct = False;
306 if (!cli_unlink(c, fname)) {
307 printf("unlink failed (%s)\n", cli_errstr(c));
308 correct = False;
311 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
312 printf("unlock failed (%s)\n", cli_errstr(c));
313 correct = False;
317 cli_close(c, fnum2);
318 cli_unlink(c, lockfname);
320 printf("%d\n", i);
322 return correct;
325 static BOOL run_torture(int dummy)
327 struct cli_state *cli;
328 BOOL ret;
330 cli = current_cli;
332 cli_sockopt(cli, sockops);
334 ret = rw_torture(cli);
336 if (!torture_close_connection(cli)) {
337 ret = False;
340 return ret;
343 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
345 int fnum = -1;
346 unsigned int i = 0;
347 char buf[131072];
348 char buf_rd[131072];
349 unsigned count;
350 unsigned countprev = 0;
351 ssize_t sent = 0;
352 BOOL correct = True;
354 srandom(1);
355 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
357 SIVAL(buf, i, sys_random());
360 if (procnum == 0)
362 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
363 DENY_NONE);
364 if (fnum == -1) {
365 printf("first open read/write of %s failed (%s)\n",
366 lockfname, cli_errstr(c));
367 return False;
370 else
372 for (i = 0; i < 500 && fnum == -1; i++)
374 fnum = cli_open(c, lockfname, O_RDONLY,
375 DENY_NONE);
376 msleep(10);
378 if (fnum == -1) {
379 printf("second open read-only of %s failed (%s)\n",
380 lockfname, cli_errstr(c));
381 return False;
385 i = 0;
386 for (count = 0; count < sizeof(buf); count += sent)
388 if (count >= countprev) {
389 printf("%d %8d\r", i, count);
390 fflush(stdout);
391 i++;
392 countprev += (sizeof(buf) / 20);
395 if (procnum == 0)
397 sent = ((unsigned)sys_random()%(20))+ 1;
398 if (sent > sizeof(buf) - count)
400 sent = sizeof(buf) - count;
403 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
404 printf("write failed (%s)\n", cli_errstr(c));
405 correct = False;
408 else
410 sent = cli_read(c, fnum, buf_rd+count, count,
411 sizeof(buf)-count);
412 if (sent < 0)
414 printf("read failed offset:%d size:%d (%s)\n",
415 count, sizeof(buf)-count,
416 cli_errstr(c));
417 correct = False;
418 sent = 0;
420 if (sent > 0)
422 if (memcmp(buf_rd+count, buf+count, sent) != 0)
424 printf("read/write compare failed\n");
425 printf("offset: %d req %d recvd %d\n",
426 count, sizeof(buf)-count, sent);
427 correct = False;
428 break;
435 if (!cli_close(c, fnum)) {
436 printf("close failed (%s)\n", cli_errstr(c));
437 correct = False;
440 return correct;
443 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
445 const char *lockfname = "\\torture2.lck";
446 int fnum1;
447 int fnum2;
448 int i;
449 uchar buf[131072];
450 uchar buf_rd[131072];
451 BOOL correct = True;
452 ssize_t bytes_read;
454 if (!cli_unlink(c1, lockfname)) {
455 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
458 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
459 DENY_NONE);
460 if (fnum1 == -1) {
461 printf("first open read/write of %s failed (%s)\n",
462 lockfname, cli_errstr(c1));
463 return False;
465 fnum2 = cli_open(c2, lockfname, O_RDONLY,
466 DENY_NONE);
467 if (fnum2 == -1) {
468 printf("second open read-only of %s failed (%s)\n",
469 lockfname, cli_errstr(c2));
470 cli_close(c1, fnum1);
471 return False;
474 for (i=0;i<torture_numops;i++)
476 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
477 if (i % 10 == 0) {
478 printf("%d\r", i); fflush(stdout);
481 generate_random_buffer(buf, buf_size, False);
483 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
484 printf("write failed (%s)\n", cli_errstr(c1));
485 correct = False;
488 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
489 printf("read failed (%s)\n", cli_errstr(c2));
490 printf("read %d, expected %d\n", bytes_read, buf_size);
491 correct = False;
494 if (memcmp(buf_rd, buf, buf_size) != 0)
496 printf("read/write compare failed\n");
497 correct = False;
501 if (!cli_close(c2, fnum2)) {
502 printf("close failed (%s)\n", cli_errstr(c2));
503 correct = False;
505 if (!cli_close(c1, fnum1)) {
506 printf("close failed (%s)\n", cli_errstr(c1));
507 correct = False;
510 if (!cli_unlink(c1, lockfname)) {
511 printf("unlink failed (%s)\n", cli_errstr(c1));
512 correct = False;
515 return correct;
518 static BOOL run_readwritetest(int dummy)
520 static struct cli_state *cli1, *cli2;
521 BOOL test1, test2;
523 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
524 return False;
526 cli_sockopt(cli1, sockops);
527 cli_sockopt(cli2, sockops);
529 printf("starting readwritetest\n");
531 test1 = rw_torture2(cli1, cli2);
532 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
534 test2 = rw_torture2(cli1, cli1);
535 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
537 if (!torture_close_connection(cli1)) {
538 test1 = False;
541 if (!torture_close_connection(cli2)) {
542 test2 = False;
545 return (test1 && test2);
548 static BOOL run_readwritemulti(int dummy)
550 struct cli_state *cli;
551 BOOL test;
553 cli = current_cli;
555 cli_sockopt(&cli, sockops);
557 printf("run_readwritemulti: fname %s\n", randomfname);
558 test = rw_torture3(&cli, randomfname);
560 if (!torture_close_connection(&cli)) {
561 test = False;
564 return test;
567 static BOOL run_readwritelarge(int dummy)
569 static struct cli_state *cli1;
570 int fnum1;
571 const char *lockfname = "\\large.dat";
572 size_t fsize;
573 char buf[126*1024];
574 BOOL correct = True;
576 if (!torture_open_connection(&cli1)) {
577 return False;
579 cli_sockopt(cli1, sockops);
580 memset(buf,'\0',sizeof(buf));
582 cli1->max_xmit = 128*1024;
584 printf("starting readwritelarge\n");
586 cli_unlink(cli1, lockfname);
588 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
589 if (fnum1 == -1) {
590 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
591 return False;
594 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
596 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
597 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
598 correct = False;
601 if (fsize == sizeof(buf))
602 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
603 else {
604 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
605 correct = False;
608 if (!cli_close(cli1, fnum1)) {
609 printf("close failed (%s)\n", cli_errstr(cli1));
610 correct = False;
613 if (!cli_unlink(cli1, lockfname)) {
614 printf("unlink failed (%s)\n", cli_errstr(cli1));
615 correct = False;
618 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
619 if (fnum1 == -1) {
620 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
621 return False;
624 cli1->max_xmit = 4*1024;
626 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
628 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
629 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
630 correct = False;
633 if (fsize == sizeof(buf))
634 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
635 else {
636 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
637 correct = False;
640 #if 0
641 /* ToDo - set allocation. JRA */
642 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
643 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
644 return False;
646 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
647 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
648 correct = False;
650 if (fsize != 0)
651 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
652 #endif
654 if (!cli_close(cli1, fnum1)) {
655 printf("close failed (%s)\n", cli_errstr(cli1));
656 correct = False;
659 if (!torture_close_connection(cli1)) {
660 correct = False;
662 return correct;
665 int line_count = 0;
666 int nbio_id;
668 #define ival(s) strtol(s, NULL, 0)
670 /* run a test that simulates an approximate netbench client load */
671 static BOOL run_netbench(int client)
673 struct cli_state *cli;
674 int i;
675 fstring fname;
676 pstring line;
677 char cname[20];
678 FILE *f;
679 char *params[20];
680 BOOL correct = True;
682 cli = current_cli;
684 nbio_id = client;
686 cli_sockopt(cli, sockops);
688 nb_setup(cli);
690 slprintf(cname,sizeof(fname), "client%d", client);
692 f = fopen(client_txt, "r");
694 if (!f) {
695 perror(client_txt);
696 return False;
699 while (fgets(line, sizeof(line)-1, f)) {
700 line_count++;
702 line[strlen(line)-1] = 0;
704 /* printf("[%d] %s\n", line_count, line); */
706 all_string_sub(line,"client1", cname, sizeof(line));
708 /* parse the command parameters */
709 params[0] = strtok(line," ");
710 i = 0;
711 while (params[i]) params[++i] = strtok(NULL," ");
713 params[i] = "";
715 if (i < 2) continue;
717 if (!strncmp(params[0],"SMB", 3)) {
718 printf("ERROR: You are using a dbench 1 load file\n");
719 exit(1);
722 if (!strcmp(params[0],"NTCreateX")) {
723 nb_createx(params[1], ival(params[2]), ival(params[3]),
724 ival(params[4]));
725 } else if (!strcmp(params[0],"Close")) {
726 nb_close(ival(params[1]));
727 } else if (!strcmp(params[0],"Rename")) {
728 nb_rename(params[1], params[2]);
729 } else if (!strcmp(params[0],"Unlink")) {
730 nb_unlink(params[1]);
731 } else if (!strcmp(params[0],"Deltree")) {
732 nb_deltree(params[1]);
733 } else if (!strcmp(params[0],"Rmdir")) {
734 nb_rmdir(params[1]);
735 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
736 nb_qpathinfo(params[1]);
737 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
738 nb_qfileinfo(ival(params[1]));
739 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
740 nb_qfsinfo(ival(params[1]));
741 } else if (!strcmp(params[0],"FIND_FIRST")) {
742 nb_findfirst(params[1]);
743 } else if (!strcmp(params[0],"WriteX")) {
744 nb_writex(ival(params[1]),
745 ival(params[2]), ival(params[3]), ival(params[4]));
746 } else if (!strcmp(params[0],"ReadX")) {
747 nb_readx(ival(params[1]),
748 ival(params[2]), ival(params[3]), ival(params[4]));
749 } else if (!strcmp(params[0],"Flush")) {
750 nb_flush(ival(params[1]));
751 } else {
752 printf("Unknown operation %s\n", params[0]);
753 exit(1);
756 fclose(f);
758 nb_cleanup();
760 if (!torture_close_connection(cli)) {
761 correct = False;
764 return correct;
768 /* run a test that simulates an approximate netbench client load */
769 static BOOL run_nbench(int dummy)
771 double t;
772 BOOL correct = True;
774 nbio_shmem(nprocs);
776 nbio_id = -1;
778 signal(SIGALRM, nb_alarm);
779 alarm(1);
780 t = create_procs(run_netbench, &correct);
781 alarm(0);
783 printf("\nThroughput %g MB/sec\n",
784 1.0e-6 * nbio_total() / t);
785 return correct;
790 This test checks for two things:
792 1) correct support for retaining locks over a close (ie. the server
793 must not use posix semantics)
794 2) support for lock timeouts
796 static BOOL run_locktest1(int dummy)
798 struct cli_state *cli1, *cli2;
799 const char *fname = "\\lockt1.lck";
800 int fnum1, fnum2, fnum3;
801 time_t t1, t2;
802 unsigned lock_timeout;
804 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
805 return False;
807 cli_sockopt(cli1, sockops);
808 cli_sockopt(cli2, sockops);
810 printf("starting locktest1\n");
812 cli_unlink(cli1, fname);
814 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
815 if (fnum1 == -1) {
816 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
817 return False;
819 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
820 if (fnum2 == -1) {
821 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
822 return False;
824 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
825 if (fnum3 == -1) {
826 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
827 return False;
830 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
831 printf("lock1 failed (%s)\n", cli_errstr(cli1));
832 return False;
836 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
837 printf("lock2 succeeded! This is a locking bug\n");
838 return False;
839 } else {
840 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
841 NT_STATUS_LOCK_NOT_GRANTED)) return False;
845 lock_timeout = (1 + (random() % 20));
846 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
847 t1 = time(NULL);
848 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
849 printf("lock3 succeeded! This is a locking bug\n");
850 return False;
851 } else {
852 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
853 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
855 t2 = time(NULL);
857 if (t2 - t1 < 5) {
858 printf("error: This server appears not to support timed lock requests\n");
860 printf("server slept for %u seconds for a %u second timeout\n",
861 (unsigned int)(t2-t1), lock_timeout);
863 if (!cli_close(cli1, fnum2)) {
864 printf("close1 failed (%s)\n", cli_errstr(cli1));
865 return False;
868 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
869 printf("lock4 succeeded! This is a locking bug\n");
870 return False;
871 } else {
872 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
873 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
876 if (!cli_close(cli1, fnum1)) {
877 printf("close2 failed (%s)\n", cli_errstr(cli1));
878 return False;
881 if (!cli_close(cli2, fnum3)) {
882 printf("close3 failed (%s)\n", cli_errstr(cli2));
883 return False;
886 if (!cli_unlink(cli1, fname)) {
887 printf("unlink failed (%s)\n", cli_errstr(cli1));
888 return False;
892 if (!torture_close_connection(cli1)) {
893 return False;
896 if (!torture_close_connection(cli2)) {
897 return False;
900 printf("Passed locktest1\n");
901 return True;
905 this checks to see if a secondary tconx can use open files from an
906 earlier tconx
908 static BOOL run_tcon_test(int dummy)
910 static struct cli_state *cli;
911 const char *fname = "\\tcontest.tmp";
912 int fnum1;
913 uint16 cnum1, cnum2, cnum3;
914 uint16 vuid1, vuid2;
915 char buf[4];
916 BOOL ret = True;
918 if (!torture_open_connection(&cli)) {
919 return False;
921 cli_sockopt(cli, sockops);
923 printf("starting tcontest\n");
925 cli_unlink(cli, fname);
927 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
928 if (fnum1 == -1) {
929 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
930 return False;
933 cnum1 = cli->cnum;
934 vuid1 = cli->vuid;
936 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
937 printf("initial write failed (%s)", cli_errstr(cli));
938 return False;
941 if (!cli_send_tconX(cli, share, "?????",
942 password, strlen(password)+1)) {
943 printf("%s refused 2nd tree connect (%s)\n", host,
944 cli_errstr(cli));
945 cli_shutdown(cli);
946 return False;
949 cnum2 = cli->cnum;
950 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
951 vuid2 = cli->vuid + 1;
953 /* try a write with the wrong tid */
954 cli->cnum = cnum2;
956 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
957 printf("server allows write with wrong TID\n");
958 } else {
959 printf("* server fails write with wrong TID : %s\n", cli_errstr(cli));
960 ret = False;
964 /* try a write with an invalid tid */
965 cli->cnum = cnum3;
967 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
968 printf("server allows write with invalid TID\n");
969 } else {
970 printf("* server fails write with invalid TID : %s\n", cli_errstr(cli));
971 ret = False;
974 /* try a write with an invalid vuid */
975 cli->vuid = vuid2;
976 cli->cnum = cnum1;
978 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
979 printf("server allows write with invalid VUID\n");
980 } else {
981 printf("* server fails write with invalid VUID : %s\n", cli_errstr(cli));
982 ret = False;
985 cli->cnum = cnum1;
986 cli->vuid = vuid1;
988 if (!cli_close(cli, fnum1)) {
989 printf("close failed (%s)\n", cli_errstr(cli));
990 return False;
993 cli->cnum = cnum2;
995 if (!cli_tdis(cli)) {
996 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
997 return False;
1000 cli->cnum = cnum1;
1002 if (!torture_close_connection(cli)) {
1003 return False;
1006 return ret;
1011 checks for old style tcon support
1013 static BOOL run_tcon2_test(int dummy)
1015 static struct cli_state *cli;
1016 uint16 cnum, max_xmit;
1017 char *service;
1018 NTSTATUS status;
1020 if (!torture_open_connection(&cli)) {
1021 return False;
1023 cli_sockopt(cli, sockops);
1025 printf("starting tcon2 test\n");
1027 asprintf(&service, "\\\\%s\\%s", host, share);
1029 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 printf("tcon2 failed : %s\n", cli_errstr(cli));
1033 } else {
1034 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1035 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1038 if (!torture_close_connection(cli)) {
1039 return False;
1042 printf("Passed tcon2 test\n");
1043 return True;
1046 static BOOL tcon_devtest(struct cli_state *cli,
1047 const char *myshare, const char *devtype,
1048 NTSTATUS expected_error)
1050 BOOL status;
1051 BOOL ret;
1053 status = cli_send_tconX(cli, myshare, devtype,
1054 password, strlen(password)+1);
1056 if (NT_STATUS_IS_OK(expected_error)) {
1057 if (status) {
1058 ret = True;
1059 } else {
1060 printf("tconX to share %s with type %s "
1061 "should have succeeded but failed\n",
1062 myshare, devtype);
1063 ret = False;
1065 cli_tdis(cli);
1066 } else {
1067 if (status) {
1068 printf("tconx to share %s with type %s "
1069 "should have failed but succeeded\n",
1070 myshare, devtype);
1071 ret = False;
1072 } else {
1073 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1074 expected_error)) {
1075 ret = True;
1076 } else {
1077 printf("Returned unexpected error\n");
1078 ret = False;
1082 return ret;
1086 checks for correct tconX support
1088 static BOOL run_tcon_devtype_test(int dummy)
1090 static struct cli_state *cli1 = NULL;
1091 BOOL retry;
1092 int flags = 0;
1093 NTSTATUS status;
1094 BOOL ret;
1096 status = cli_full_connection(&cli1, myname,
1097 host, NULL, port_to_use,
1098 NULL, NULL,
1099 username, workgroup,
1100 password, flags, &retry);
1102 if (!NT_STATUS_IS_OK(status)) {
1103 printf("could not open connection\n");
1104 return False;
1107 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
1108 ret = False;
1110 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
1111 ret = False;
1113 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1114 ret = False;
1116 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
1117 ret = False;
1119 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1120 ret = False;
1122 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
1123 ret = False;
1125 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
1126 ret = False;
1128 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1129 ret = False;
1131 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
1132 ret = False;
1134 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1135 ret = False;
1137 cli_shutdown(cli1);
1139 if (ret)
1140 printf("Passed tcondevtest\n");
1142 return ret;
1147 This test checks that
1149 1) the server supports multiple locking contexts on the one SMB
1150 connection, distinguished by PID.
1152 2) the server correctly fails overlapping locks made by the same PID (this
1153 goes against POSIX behaviour, which is why it is tricky to implement)
1155 3) the server denies unlock requests by an incorrect client PID
1157 static BOOL run_locktest2(int dummy)
1159 static struct cli_state *cli;
1160 const char *fname = "\\lockt2.lck";
1161 int fnum1, fnum2, fnum3;
1162 BOOL correct = True;
1164 if (!torture_open_connection(&cli)) {
1165 return False;
1168 cli_sockopt(cli, sockops);
1170 printf("starting locktest2\n");
1172 cli_unlink(cli, fname);
1174 cli_setpid(cli, 1);
1176 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1177 if (fnum1 == -1) {
1178 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1179 return False;
1182 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1183 if (fnum2 == -1) {
1184 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1185 return False;
1188 cli_setpid(cli, 2);
1190 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1191 if (fnum3 == -1) {
1192 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1193 return False;
1196 cli_setpid(cli, 1);
1198 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1199 printf("lock1 failed (%s)\n", cli_errstr(cli));
1200 return False;
1203 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1204 printf("WRITE lock1 succeeded! This is a locking bug\n");
1205 correct = False;
1206 } else {
1207 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1208 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1211 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1212 printf("WRITE lock2 succeeded! This is a locking bug\n");
1213 correct = False;
1214 } else {
1215 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1216 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1219 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1220 printf("READ lock2 succeeded! This is a locking bug\n");
1221 correct = False;
1222 } else {
1223 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1224 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1227 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1228 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1230 cli_setpid(cli, 2);
1231 if (cli_unlock(cli, fnum1, 100, 4)) {
1232 printf("unlock at 100 succeeded! This is a locking bug\n");
1233 correct = False;
1236 if (cli_unlock(cli, fnum1, 0, 4)) {
1237 printf("unlock1 succeeded! This is a locking bug\n");
1238 correct = False;
1239 } else {
1240 if (!check_error(__LINE__, cli,
1241 ERRDOS, ERRlock,
1242 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1245 if (cli_unlock(cli, fnum1, 0, 8)) {
1246 printf("unlock2 succeeded! This is a locking bug\n");
1247 correct = False;
1248 } else {
1249 if (!check_error(__LINE__, cli,
1250 ERRDOS, ERRlock,
1251 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1254 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1255 printf("lock3 succeeded! This is a locking bug\n");
1256 correct = False;
1257 } else {
1258 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1261 cli_setpid(cli, 1);
1263 if (!cli_close(cli, fnum1)) {
1264 printf("close1 failed (%s)\n", cli_errstr(cli));
1265 return False;
1268 if (!cli_close(cli, fnum2)) {
1269 printf("close2 failed (%s)\n", cli_errstr(cli));
1270 return False;
1273 if (!cli_close(cli, fnum3)) {
1274 printf("close3 failed (%s)\n", cli_errstr(cli));
1275 return False;
1278 if (!torture_close_connection(cli)) {
1279 correct = False;
1282 printf("locktest2 finished\n");
1284 return correct;
1289 This test checks that
1291 1) the server supports the full offset range in lock requests
1293 static BOOL run_locktest3(int dummy)
1295 static struct cli_state *cli1, *cli2;
1296 const char *fname = "\\lockt3.lck";
1297 int fnum1, fnum2, i;
1298 uint32 offset;
1299 BOOL correct = True;
1301 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1303 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1304 return False;
1306 cli_sockopt(cli1, sockops);
1307 cli_sockopt(cli2, sockops);
1309 printf("starting locktest3\n");
1311 cli_unlink(cli1, fname);
1313 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1314 if (fnum1 == -1) {
1315 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1316 return False;
1318 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1319 if (fnum2 == -1) {
1320 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1321 return False;
1324 for (offset=i=0;i<torture_numops;i++) {
1325 NEXT_OFFSET;
1326 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1327 printf("lock1 %d failed (%s)\n",
1329 cli_errstr(cli1));
1330 return False;
1333 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1334 printf("lock2 %d failed (%s)\n",
1336 cli_errstr(cli1));
1337 return False;
1341 for (offset=i=0;i<torture_numops;i++) {
1342 NEXT_OFFSET;
1344 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1345 printf("error: lock1 %d succeeded!\n", i);
1346 return False;
1349 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1350 printf("error: lock2 %d succeeded!\n", i);
1351 return False;
1354 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1355 printf("error: lock3 %d succeeded!\n", i);
1356 return False;
1359 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1360 printf("error: lock4 %d succeeded!\n", i);
1361 return False;
1365 for (offset=i=0;i<torture_numops;i++) {
1366 NEXT_OFFSET;
1368 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1369 printf("unlock1 %d failed (%s)\n",
1371 cli_errstr(cli1));
1372 return False;
1375 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1376 printf("unlock2 %d failed (%s)\n",
1378 cli_errstr(cli1));
1379 return False;
1383 if (!cli_close(cli1, fnum1)) {
1384 printf("close1 failed (%s)\n", cli_errstr(cli1));
1385 return False;
1388 if (!cli_close(cli2, fnum2)) {
1389 printf("close2 failed (%s)\n", cli_errstr(cli2));
1390 return False;
1393 if (!cli_unlink(cli1, fname)) {
1394 printf("unlink failed (%s)\n", cli_errstr(cli1));
1395 return False;
1398 if (!torture_close_connection(cli1)) {
1399 correct = False;
1402 if (!torture_close_connection(cli2)) {
1403 correct = False;
1406 printf("finished locktest3\n");
1408 return correct;
1411 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1412 printf("** "); correct = False; \
1416 looks at overlapping locks
1418 static BOOL run_locktest4(int dummy)
1420 static struct cli_state *cli1, *cli2;
1421 const char *fname = "\\lockt4.lck";
1422 int fnum1, fnum2, f;
1423 BOOL ret;
1424 char buf[1000];
1425 BOOL correct = True;
1427 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1428 return False;
1431 cli_sockopt(cli1, sockops);
1432 cli_sockopt(cli2, sockops);
1434 printf("starting locktest4\n");
1436 cli_unlink(cli1, fname);
1438 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1439 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1441 memset(buf, 0, sizeof(buf));
1443 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1444 printf("Failed to create file\n");
1445 correct = False;
1446 goto fail;
1449 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1450 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1451 EXPECTED(ret, False);
1452 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1454 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1455 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1456 EXPECTED(ret, True);
1457 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1459 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1460 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1461 EXPECTED(ret, False);
1462 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1464 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1465 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1466 EXPECTED(ret, True);
1467 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1469 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1470 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1471 EXPECTED(ret, False);
1472 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1474 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1475 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1476 EXPECTED(ret, True);
1477 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1479 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1480 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1481 EXPECTED(ret, True);
1482 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1484 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1485 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1486 EXPECTED(ret, False);
1487 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1489 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1490 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1491 EXPECTED(ret, False);
1492 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1494 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1495 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1496 EXPECTED(ret, True);
1497 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1499 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1500 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1501 EXPECTED(ret, False);
1502 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1504 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1505 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1506 cli_unlock(cli1, fnum1, 110, 6);
1507 EXPECTED(ret, False);
1508 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1511 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1512 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1513 EXPECTED(ret, False);
1514 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1516 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1517 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1518 EXPECTED(ret, False);
1519 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1522 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1523 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1524 cli_unlock(cli1, fnum1, 140, 4) &&
1525 cli_unlock(cli1, fnum1, 140, 4);
1526 EXPECTED(ret, True);
1527 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1530 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1531 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1532 cli_unlock(cli1, fnum1, 150, 4) &&
1533 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1534 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1535 cli_unlock(cli1, fnum1, 150, 4);
1536 EXPECTED(ret, True);
1537 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1539 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1540 cli_unlock(cli1, fnum1, 160, 4) &&
1541 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1542 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1543 EXPECTED(ret, True);
1544 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1546 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1547 cli_unlock(cli1, fnum1, 170, 4) &&
1548 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1549 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1550 EXPECTED(ret, True);
1551 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1553 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1554 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1555 cli_unlock(cli1, fnum1, 190, 4) &&
1556 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1557 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1558 EXPECTED(ret, True);
1559 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1561 cli_close(cli1, fnum1);
1562 cli_close(cli2, fnum2);
1563 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1564 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1565 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1566 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1567 cli_close(cli1, fnum1) &&
1568 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1569 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1570 cli_close(cli1, f);
1571 cli_close(cli1, fnum1);
1572 EXPECTED(ret, True);
1573 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1575 fail:
1576 cli_close(cli1, fnum1);
1577 cli_close(cli2, fnum2);
1578 cli_unlink(cli1, fname);
1579 torture_close_connection(cli1);
1580 torture_close_connection(cli2);
1582 printf("finished locktest4\n");
1583 return correct;
1587 looks at lock upgrade/downgrade.
1589 static BOOL run_locktest5(int dummy)
1591 static struct cli_state *cli1, *cli2;
1592 const char *fname = "\\lockt5.lck";
1593 int fnum1, fnum2, fnum3;
1594 BOOL ret;
1595 char buf[1000];
1596 BOOL correct = True;
1598 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1599 return False;
1602 cli_sockopt(cli1, sockops);
1603 cli_sockopt(cli2, sockops);
1605 printf("starting locktest5\n");
1607 cli_unlink(cli1, fname);
1609 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1610 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1611 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1613 memset(buf, 0, sizeof(buf));
1615 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1616 printf("Failed to create file\n");
1617 correct = False;
1618 goto fail;
1621 /* Check for NT bug... */
1622 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1623 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1624 cli_close(cli1, fnum1);
1625 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1626 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1627 EXPECTED(ret, True);
1628 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1629 cli_close(cli1, fnum1);
1630 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1631 cli_unlock(cli1, fnum3, 0, 1);
1633 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1634 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1635 EXPECTED(ret, True);
1636 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1638 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1639 EXPECTED(ret, False);
1641 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1643 /* Unlock the process 2 lock. */
1644 cli_unlock(cli2, fnum2, 0, 4);
1646 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1647 EXPECTED(ret, False);
1649 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1651 /* Unlock the process 1 fnum3 lock. */
1652 cli_unlock(cli1, fnum3, 0, 4);
1654 /* Stack 2 more locks here. */
1655 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1656 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1658 EXPECTED(ret, True);
1659 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1661 /* Unlock the first process lock, then check this was the WRITE lock that was
1662 removed. */
1664 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1665 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1667 EXPECTED(ret, True);
1668 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1670 /* Unlock the process 2 lock. */
1671 cli_unlock(cli2, fnum2, 0, 4);
1673 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1675 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1676 cli_unlock(cli1, fnum1, 0, 4) &&
1677 cli_unlock(cli1, fnum1, 0, 4);
1679 EXPECTED(ret, True);
1680 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1682 /* Ensure the next unlock fails. */
1683 ret = cli_unlock(cli1, fnum1, 0, 4);
1684 EXPECTED(ret, False);
1685 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1687 /* Ensure connection 2 can get a write lock. */
1688 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1689 EXPECTED(ret, True);
1691 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1694 fail:
1695 cli_close(cli1, fnum1);
1696 cli_close(cli2, fnum2);
1697 cli_unlink(cli1, fname);
1698 if (!torture_close_connection(cli1)) {
1699 correct = False;
1701 if (!torture_close_connection(cli2)) {
1702 correct = False;
1705 printf("finished locktest5\n");
1707 return correct;
1711 tries the unusual lockingX locktype bits
1713 static BOOL run_locktest6(int dummy)
1715 static struct cli_state *cli;
1716 const char *fname[1] = { "\\lock6.txt" };
1717 int i;
1718 int fnum;
1719 NTSTATUS status;
1721 if (!torture_open_connection(&cli)) {
1722 return False;
1725 cli_sockopt(cli, sockops);
1727 printf("starting locktest6\n");
1729 for (i=0;i<1;i++) {
1730 printf("Testing %s\n", fname[i]);
1732 cli_unlink(cli, fname[i]);
1734 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1735 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1736 cli_close(cli, fnum);
1737 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1739 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1740 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1741 cli_close(cli, fnum);
1742 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1744 cli_unlink(cli, fname[i]);
1747 torture_close_connection(cli);
1749 printf("finished locktest6\n");
1750 return True;
1753 static BOOL run_locktest7(int dummy)
1755 struct cli_state *cli1;
1756 const char *fname = "\\lockt7.lck";
1757 int fnum1;
1758 char buf[200];
1759 BOOL correct = False;
1761 if (!torture_open_connection(&cli1)) {
1762 return False;
1765 cli_sockopt(cli1, sockops);
1767 printf("starting locktest7\n");
1769 cli_unlink(cli1, fname);
1771 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1773 memset(buf, 0, sizeof(buf));
1775 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1776 printf("Failed to create file\n");
1777 goto fail;
1780 cli_setpid(cli1, 1);
1782 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1783 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1784 goto fail;
1785 } else {
1786 printf("pid1 successfully locked range 130:4 for READ\n");
1789 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1790 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1791 goto fail;
1792 } else {
1793 printf("pid1 successfully read the range 130:4\n");
1796 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1797 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1798 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1799 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1800 goto fail;
1802 } else {
1803 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1804 goto fail;
1807 cli_setpid(cli1, 2);
1809 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1810 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1811 } else {
1812 printf("pid2 successfully read the range 130:4\n");
1815 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1816 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1817 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1818 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1819 goto fail;
1821 } else {
1822 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1823 goto fail;
1826 cli_setpid(cli1, 1);
1827 cli_unlock(cli1, fnum1, 130, 4);
1829 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1830 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1831 goto fail;
1832 } else {
1833 printf("pid1 successfully locked range 130:4 for WRITE\n");
1836 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1837 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1838 goto fail;
1839 } else {
1840 printf("pid1 successfully read the range 130:4\n");
1843 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1844 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1845 goto fail;
1846 } else {
1847 printf("pid1 successfully wrote to the range 130:4\n");
1850 cli_setpid(cli1, 2);
1852 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1853 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1854 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1855 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1856 goto fail;
1858 } else {
1859 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1860 goto fail;
1863 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1864 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1865 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1866 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1867 goto fail;
1869 } else {
1870 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1871 goto fail;
1874 cli_unlock(cli1, fnum1, 130, 0);
1875 correct = True;
1877 fail:
1878 cli_close(cli1, fnum1);
1879 cli_unlink(cli1, fname);
1880 torture_close_connection(cli1);
1882 printf("finished locktest7\n");
1883 return correct;
1887 test whether fnums and tids open on one VC are available on another (a major
1888 security hole)
1890 static BOOL run_fdpasstest(int dummy)
1892 struct cli_state *cli1, *cli2;
1893 const char *fname = "\\fdpass.tst";
1894 int fnum1;
1895 pstring buf;
1897 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1898 return False;
1900 cli_sockopt(cli1, sockops);
1901 cli_sockopt(cli2, sockops);
1903 printf("starting fdpasstest\n");
1905 cli_unlink(cli1, fname);
1907 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1908 if (fnum1 == -1) {
1909 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1910 return False;
1913 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1914 printf("write failed (%s)\n", cli_errstr(cli1));
1915 return False;
1918 cli2->vuid = cli1->vuid;
1919 cli2->cnum = cli1->cnum;
1920 cli2->pid = cli1->pid;
1922 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
1923 printf("read succeeded! nasty security hole [%s]\n",
1924 buf);
1925 return False;
1928 cli_close(cli1, fnum1);
1929 cli_unlink(cli1, fname);
1931 torture_close_connection(cli1);
1932 torture_close_connection(cli2);
1934 printf("finished fdpasstest\n");
1935 return True;
1940 This test checks that
1942 1) the server does not allow an unlink on a file that is open
1944 static BOOL run_unlinktest(int dummy)
1946 struct cli_state *cli;
1947 const char *fname = "\\unlink.tst";
1948 int fnum;
1949 BOOL correct = True;
1951 if (!torture_open_connection(&cli)) {
1952 return False;
1955 cli_sockopt(cli, sockops);
1957 printf("starting unlink test\n");
1959 cli_unlink(cli, fname);
1961 cli_setpid(cli, 1);
1963 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1964 if (fnum == -1) {
1965 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1966 return False;
1969 if (cli_unlink(cli, fname)) {
1970 printf("error: server allowed unlink on an open file\n");
1971 correct = False;
1972 } else {
1973 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1974 NT_STATUS_SHARING_VIOLATION);
1977 cli_close(cli, fnum);
1978 cli_unlink(cli, fname);
1980 if (!torture_close_connection(cli)) {
1981 correct = False;
1984 printf("unlink test finished\n");
1986 return correct;
1991 test how many open files this server supports on the one socket
1993 static BOOL run_maxfidtest(int dummy)
1995 struct cli_state *cli;
1996 const char *template = "\\maxfid.%d.%d";
1997 fstring fname;
1998 int fnums[0x11000], i;
1999 int retries=4;
2000 BOOL correct = True;
2002 cli = current_cli;
2004 if (retries <= 0) {
2005 printf("failed to connect\n");
2006 return False;
2009 cli_sockopt(cli, sockops);
2011 for (i=0; i<0x11000; i++) {
2012 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
2013 if ((fnums[i] = cli_open(cli, fname,
2014 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2015 -1) {
2016 printf("open of %s failed (%s)\n",
2017 fname, cli_errstr(cli));
2018 printf("maximum fnum is %d\n", i);
2019 break;
2021 printf("%6d\r", i);
2023 printf("%6d\n", i);
2024 i--;
2026 printf("cleaning up\n");
2027 for (;i>=0;i--) {
2028 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
2029 cli_close(cli, fnums[i]);
2030 if (!cli_unlink(cli, fname)) {
2031 printf("unlink of %s failed (%s)\n",
2032 fname, cli_errstr(cli));
2033 correct = False;
2035 printf("%6d\r", i);
2037 printf("%6d\n", 0);
2039 printf("maxfid test finished\n");
2040 if (!torture_close_connection(cli)) {
2041 correct = False;
2043 return correct;
2046 /* generate a random buffer */
2047 static void rand_buf(char *buf, int len)
2049 while (len--) {
2050 *buf = (char)sys_random();
2051 buf++;
2055 /* send smb negprot commands, not reading the response */
2056 static BOOL run_negprot_nowait(int dummy)
2058 int i;
2059 static struct cli_state cli;
2060 BOOL correct = True;
2062 printf("starting negprot nowait test\n");
2064 if (!open_nbt_connection(&cli)) {
2065 return False;
2068 for (i=0;i<50000;i++) {
2069 cli_negprot_send(&cli);
2072 if (!torture_close_connection(&cli)) {
2073 correct = False;
2076 printf("finished negprot nowait test\n");
2078 return correct;
2082 /* send random IPC commands */
2083 static BOOL run_randomipc(int dummy)
2085 char *rparam = NULL;
2086 char *rdata = NULL;
2087 int rdrcnt,rprcnt;
2088 pstring param;
2089 int api, param_len, i;
2090 struct cli_state *cli;
2091 BOOL correct = True;
2092 int count = 50000;
2094 printf("starting random ipc test\n");
2096 if (!torture_open_connection(&cli)) {
2097 return False;
2100 for (i=0;i<count;i++) {
2101 api = sys_random() % 500;
2102 param_len = (sys_random() % 64);
2104 rand_buf(param, param_len);
2106 SSVAL(param,0,api);
2108 cli_api(cli,
2109 param, param_len, 8,
2110 NULL, 0, BUFFER_SIZE,
2111 &rparam, &rprcnt,
2112 &rdata, &rdrcnt);
2113 if (i % 100 == 0) {
2114 printf("%d/%d\r", i,count);
2117 printf("%d/%d\n", i, count);
2119 if (!torture_close_connection(cli)) {
2120 correct = False;
2123 printf("finished random ipc test\n");
2125 return correct;
2130 static void browse_callback(const char *sname, uint32 stype,
2131 const char *comment, void *state)
2133 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2139 This test checks the browse list code
2142 static BOOL run_browsetest(int dummy)
2144 static struct cli_state *cli;
2145 BOOL correct = True;
2147 printf("starting browse test\n");
2149 if (!torture_open_connection(&cli)) {
2150 return False;
2153 printf("domain list:\n");
2154 cli_NetServerEnum(cli, cli->server_domain,
2155 SV_TYPE_DOMAIN_ENUM,
2156 browse_callback, NULL);
2158 printf("machine list:\n");
2159 cli_NetServerEnum(cli, cli->server_domain,
2160 SV_TYPE_ALL,
2161 browse_callback, NULL);
2163 if (!torture_close_connection(cli)) {
2164 correct = False;
2167 printf("browse test finished\n");
2169 return correct;
2175 This checks how the getatr calls works
2177 static BOOL run_attrtest(int dummy)
2179 struct cli_state *cli;
2180 int fnum;
2181 time_t t, t2;
2182 const char *fname = "\\attrib.tst";
2183 BOOL correct = True;
2185 printf("starting attrib test\n");
2187 if (!torture_open_connection(&cli)) {
2188 return False;
2191 cli_unlink(cli, fname);
2192 fnum = cli_open(cli, fname,
2193 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2194 cli_close(cli, fnum);
2195 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2196 printf("getatr failed (%s)\n", cli_errstr(cli));
2197 correct = False;
2200 if (abs(t - time(NULL)) > 60*60*24*10) {
2201 printf("ERROR: SMBgetatr bug. time is %s",
2202 ctime(&t));
2203 t = time(NULL);
2204 correct = True;
2207 t2 = t-60*60*24; /* 1 day ago */
2209 if (!cli_setatr(cli, fname, 0, t2)) {
2210 printf("setatr failed (%s)\n", cli_errstr(cli));
2211 correct = True;
2214 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2215 printf("getatr failed (%s)\n", cli_errstr(cli));
2216 correct = True;
2219 if (t != t2) {
2220 printf("ERROR: getatr/setatr bug. times are\n%s",
2221 ctime(&t));
2222 printf("%s", ctime(&t2));
2223 correct = True;
2226 cli_unlink(cli, fname);
2228 if (!torture_close_connection(cli)) {
2229 correct = False;
2232 printf("attrib test finished\n");
2234 return correct;
2239 This checks a couple of trans2 calls
2241 static BOOL run_trans2test(int dummy)
2243 struct cli_state *cli;
2244 int fnum;
2245 size_t size;
2246 time_t c_time, a_time, m_time, w_time, m_time2;
2247 const char *fname = "\\trans2.tst";
2248 const char *dname = "\\trans2";
2249 const char *fname2 = "\\trans2\\trans2.tst";
2250 pstring pname;
2251 BOOL correct = True;
2253 printf("starting trans2 test\n");
2255 if (!torture_open_connection(&cli)) {
2256 return False;
2259 cli_unlink(cli, fname);
2260 fnum = cli_open(cli, fname,
2261 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2262 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2263 NULL, NULL)) {
2264 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2265 correct = False;
2268 if (!cli_qfilename(cli, fnum, pname)) {
2269 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2270 correct = False;
2273 if (strcmp(pname, fname)) {
2274 printf("qfilename gave different name? [%s] [%s]\n",
2275 fname, pname);
2276 correct = False;
2279 cli_close(cli, fnum);
2281 sleep(2);
2283 cli_unlink(cli, fname);
2284 fnum = cli_open(cli, fname,
2285 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2286 if (fnum == -1) {
2287 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2288 return False;
2290 cli_close(cli, fnum);
2292 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2293 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2294 correct = False;
2295 } else {
2296 if (c_time != m_time) {
2297 printf("create time=%s", ctime(&c_time));
2298 printf("modify time=%s", ctime(&m_time));
2299 printf("This system appears to have sticky create times\n");
2301 if (a_time % (60*60) == 0) {
2302 printf("access time=%s", ctime(&a_time));
2303 printf("This system appears to set a midnight access time\n");
2304 correct = False;
2307 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2308 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2309 correct = False;
2314 cli_unlink(cli, fname);
2315 fnum = cli_open(cli, fname,
2316 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2317 cli_close(cli, fnum);
2318 if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time,
2319 &w_time, &size, NULL, NULL)) {
2320 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2321 correct = False;
2322 } else {
2323 if (w_time < 60*60*24*2) {
2324 printf("write time=%s", ctime(&w_time));
2325 printf("This system appears to set a initial 0 write time\n");
2326 correct = False;
2330 cli_unlink(cli, fname);
2333 /* check if the server updates the directory modification time
2334 when creating a new file */
2335 if (!cli_mkdir(cli, dname)) {
2336 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2337 correct = False;
2339 sleep(3);
2340 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time,
2341 &w_time, &size, NULL, NULL)) {
2342 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2343 correct = False;
2346 fnum = cli_open(cli, fname2,
2347 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2348 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2349 cli_close(cli, fnum);
2350 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2351 &w_time, &size, NULL, NULL)) {
2352 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2353 correct = False;
2354 } else {
2355 if (m_time2 == m_time) {
2356 printf("This system does not update directory modification times\n");
2357 correct = False;
2360 cli_unlink(cli, fname2);
2361 cli_rmdir(cli, dname);
2363 if (!torture_close_connection(cli)) {
2364 correct = False;
2367 printf("trans2 test finished\n");
2369 return correct;
2373 This checks new W2K calls.
2376 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2378 char buf[4096];
2379 BOOL correct = True;
2381 memset(buf, 0xff, sizeof(buf));
2383 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2384 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2385 correct = False;
2386 } else {
2387 printf("qfileinfo: level %d\n", level);
2388 dump_data(0, buf, 256);
2389 printf("\n");
2391 return correct;
2394 static BOOL run_w2ktest(int dummy)
2396 struct cli_state *cli;
2397 int fnum;
2398 const char *fname = "\\w2ktest\\w2k.tst";
2399 int level;
2400 BOOL correct = True;
2402 printf("starting w2k test\n");
2404 if (!torture_open_connection(&cli)) {
2405 return False;
2408 fnum = cli_open(cli, fname,
2409 O_RDWR | O_CREAT , DENY_NONE);
2411 for (level = 1004; level < 1040; level++) {
2412 new_trans(cli, fnum, level);
2415 cli_close(cli, fnum);
2417 if (!torture_close_connection(cli)) {
2418 correct = False;
2421 printf("w2k test finished\n");
2423 return correct;
2428 this is a harness for some oplock tests
2430 static BOOL run_oplock1(int dummy)
2432 struct cli_state *cli1;
2433 const char *fname = "\\lockt1.lck";
2434 int fnum1;
2435 BOOL correct = True;
2437 printf("starting oplock test 1\n");
2439 if (!torture_open_connection(&cli1)) {
2440 return False;
2443 cli_unlink(cli1, fname);
2445 cli_sockopt(cli1, sockops);
2447 cli1->use_oplocks = True;
2449 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2450 if (fnum1 == -1) {
2451 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2452 return False;
2455 cli1->use_oplocks = False;
2457 cli_unlink(cli1, fname);
2458 cli_unlink(cli1, fname);
2460 if (!cli_close(cli1, fnum1)) {
2461 printf("close2 failed (%s)\n", cli_errstr(cli1));
2462 return False;
2465 if (!cli_unlink(cli1, fname)) {
2466 printf("unlink failed (%s)\n", cli_errstr(cli1));
2467 return False;
2470 if (!torture_close_connection(cli1)) {
2471 correct = False;
2474 printf("finished oplock test 1\n");
2476 return correct;
2479 static BOOL run_oplock2(int dummy)
2481 struct cli_state *cli1, *cli2;
2482 const char *fname = "\\lockt2.lck";
2483 int fnum1, fnum2;
2484 int saved_use_oplocks = use_oplocks;
2485 char buf[4];
2486 BOOL correct = True;
2487 volatile BOOL *shared_correct;
2489 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2490 *shared_correct = True;
2492 use_level_II_oplocks = True;
2493 use_oplocks = True;
2495 printf("starting oplock test 2\n");
2497 if (!torture_open_connection(&cli1)) {
2498 use_level_II_oplocks = False;
2499 use_oplocks = saved_use_oplocks;
2500 return False;
2503 cli1->use_oplocks = True;
2504 cli1->use_level_II_oplocks = True;
2506 if (!torture_open_connection(&cli2)) {
2507 use_level_II_oplocks = False;
2508 use_oplocks = saved_use_oplocks;
2509 return False;
2512 cli2->use_oplocks = True;
2513 cli2->use_level_II_oplocks = True;
2515 cli_unlink(cli1, fname);
2517 cli_sockopt(cli1, sockops);
2518 cli_sockopt(cli2, sockops);
2520 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2521 if (fnum1 == -1) {
2522 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2523 return False;
2526 /* Don't need the globals any more. */
2527 use_level_II_oplocks = False;
2528 use_oplocks = saved_use_oplocks;
2530 if (fork() == 0) {
2531 /* Child code */
2532 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2533 if (fnum2 == -1) {
2534 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2535 *shared_correct = False;
2536 exit(0);
2539 sleep(2);
2541 if (!cli_close(cli2, fnum2)) {
2542 printf("close2 failed (%s)\n", cli_errstr(cli1));
2543 *shared_correct = False;
2546 exit(0);
2549 sleep(2);
2551 /* Ensure cli1 processes the break. */
2553 if (cli_read(cli1, fnum1, buf, 0, 4) != 4) {
2554 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2555 correct = False;
2558 /* Should now be at level II. */
2559 /* Test if sending a write locks causes a break to none. */
2561 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2562 printf("lock failed (%s)\n", cli_errstr(cli1));
2563 correct = False;
2566 cli_unlock(cli1, fnum1, 0, 4);
2568 sleep(2);
2570 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2571 printf("lock failed (%s)\n", cli_errstr(cli1));
2572 correct = False;
2575 cli_unlock(cli1, fnum1, 0, 4);
2577 sleep(2);
2579 cli_read(cli1, fnum1, buf, 0, 4);
2581 #if 0
2582 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2583 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2584 correct = False;
2586 #endif
2588 if (!cli_close(cli1, fnum1)) {
2589 printf("close1 failed (%s)\n", cli_errstr(cli1));
2590 correct = False;
2593 sleep(4);
2595 if (!cli_unlink(cli1, fname)) {
2596 printf("unlink failed (%s)\n", cli_errstr(cli1));
2597 correct = False;
2600 if (!torture_close_connection(cli1)) {
2601 correct = False;
2604 if (!*shared_correct) {
2605 correct = False;
2608 printf("finished oplock test 2\n");
2610 return correct;
2613 /* handler for oplock 3 tests */
2614 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2616 printf("got oplock break fnum=%d level=%d\n",
2617 fnum, level);
2618 return cli_oplock_ack(cli, fnum, level);
2621 static BOOL run_oplock3(int dummy)
2623 struct cli_state *cli;
2624 const char *fname = "\\oplockt3.dat";
2625 int fnum;
2626 char buf[4] = "abcd";
2627 BOOL correct = True;
2628 volatile BOOL *shared_correct;
2630 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2631 *shared_correct = True;
2633 printf("starting oplock test 3\n");
2635 if (fork() == 0) {
2636 /* Child code */
2637 use_oplocks = True;
2638 use_level_II_oplocks = True;
2639 if (!torture_open_connection(&cli)) {
2640 *shared_correct = False;
2641 exit(0);
2643 sleep(2);
2644 /* try to trigger a oplock break in parent */
2645 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2646 cli_write(cli, fnum, 0, buf, 0, 4);
2647 exit(0);
2650 /* parent code */
2651 use_oplocks = True;
2652 use_level_II_oplocks = True;
2653 if (!torture_open_connection(&cli)) {
2654 return False;
2656 cli_oplock_handler(cli, oplock3_handler);
2657 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2658 cli_write(cli, fnum, 0, buf, 0, 4);
2659 cli_close(cli, fnum);
2660 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2661 cli->timeout = 20000;
2662 cli_receive_smb(cli);
2663 printf("finished oplock test 3\n");
2665 return (correct && *shared_correct);
2667 /* What are we looking for here? What's sucess and what's FAILURE? */
2673 Test delete on close semantics.
2675 static BOOL run_deletetest(int dummy)
2677 struct cli_state *cli1;
2678 struct cli_state *cli2;
2679 const char *fname = "\\delete.file";
2680 int fnum1 = -1;
2681 int fnum2 = -1;
2682 BOOL correct = True;
2684 printf("starting delete test\n");
2686 if (!torture_open_connection(&cli1)) {
2687 return False;
2690 cli_sockopt(cli1, sockops);
2692 /* Test 1 - this should delete the file on close. */
2694 cli_setatr(cli1, fname, 0, 0);
2695 cli_unlink(cli1, fname);
2697 fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2698 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2699 FILE_DELETE_ON_CLOSE);
2701 if (fnum1 == -1) {
2702 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2703 correct = False;
2704 goto fail;
2707 if (!cli_close(cli1, fnum1)) {
2708 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2709 correct = False;
2710 goto fail;
2713 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2714 if (fnum1 != -1) {
2715 printf("[1] open of %s succeeded (should fail)\n", fname);
2716 correct = False;
2717 goto fail;
2720 printf("first delete on close test succeeded.\n");
2722 /* Test 2 - this should delete the file on close. */
2724 cli_setatr(cli1, fname, 0, 0);
2725 cli_unlink(cli1, fname);
2727 fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS,
2728 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2729 FILE_OVERWRITE_IF, 0);
2731 if (fnum1 == -1) {
2732 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2733 correct = False;
2734 goto fail;
2737 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2738 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2739 correct = False;
2740 goto fail;
2743 if (!cli_close(cli1, fnum1)) {
2744 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2745 correct = False;
2746 goto fail;
2749 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2750 if (fnum1 != -1) {
2751 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2752 if (!cli_close(cli1, fnum1)) {
2753 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2754 correct = False;
2755 goto fail;
2757 cli_unlink(cli1, fname);
2758 } else
2759 printf("second delete on close test succeeded.\n");
2761 /* Test 3 - ... */
2762 cli_setatr(cli1, fname, 0, 0);
2763 cli_unlink(cli1, fname);
2765 fnum1 = cli_nt_create_full(cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2766 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2768 if (fnum1 == -1) {
2769 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
2770 correct = False;
2771 goto fail;
2774 /* This should fail with a sharing violation - open for delete is only compatible
2775 with SHARE_DELETE. */
2777 fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2778 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2780 if (fnum2 != -1) {
2781 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2782 correct = False;
2783 goto fail;
2786 /* This should succeed. */
2788 fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2789 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2791 if (fnum2 == -1) {
2792 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2793 correct = False;
2794 goto fail;
2797 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2798 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2799 correct = False;
2800 goto fail;
2803 if (!cli_close(cli1, fnum1)) {
2804 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
2805 correct = False;
2806 goto fail;
2809 if (!cli_close(cli1, fnum2)) {
2810 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
2811 correct = False;
2812 goto fail;
2815 /* This should fail - file should no longer be there. */
2817 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2818 if (fnum1 != -1) {
2819 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2820 if (!cli_close(cli1, fnum1)) {
2821 printf("[3] close failed (%s)\n", cli_errstr(cli1));
2823 cli_unlink(cli1, fname);
2824 correct = False;
2825 goto fail;
2826 } else
2827 printf("third delete on close test succeeded.\n");
2829 /* Test 4 ... */
2830 cli_setatr(cli1, fname, 0, 0);
2831 cli_unlink(cli1, fname);
2833 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2834 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2836 if (fnum1 == -1) {
2837 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2838 correct = False;
2839 goto fail;
2842 /* This should succeed. */
2843 fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS,
2844 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2845 if (fnum2 == -1) {
2846 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2847 correct = False;
2848 goto fail;
2851 if (!cli_close(cli1, fnum2)) {
2852 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
2853 correct = False;
2854 goto fail;
2857 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2858 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2859 correct = False;
2860 goto fail;
2863 /* This should fail - no more opens once delete on close set. */
2864 fnum2 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS,
2865 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2866 if (fnum2 != -1) {
2867 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2868 correct = False;
2869 goto fail;
2870 } else
2871 printf("fourth delete on close test succeeded.\n");
2873 if (!cli_close(cli1, fnum1)) {
2874 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
2875 correct = False;
2876 goto fail;
2879 /* Test 5 ... */
2880 cli_setatr(cli1, fname, 0, 0);
2881 cli_unlink(cli1, fname);
2883 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2884 if (fnum1 == -1) {
2885 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2886 correct = False;
2887 goto fail;
2890 /* This should fail - only allowed on NT opens with DELETE access. */
2892 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2893 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2894 correct = False;
2895 goto fail;
2898 if (!cli_close(cli1, fnum1)) {
2899 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
2900 correct = False;
2901 goto fail;
2904 printf("fifth delete on close test succeeded.\n");
2906 /* Test 6 ... */
2907 cli_setatr(cli1, fname, 0, 0);
2908 cli_unlink(cli1, fname);
2910 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2911 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2912 FILE_OVERWRITE_IF, 0);
2914 if (fnum1 == -1) {
2915 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2916 correct = False;
2917 goto fail;
2920 /* This should fail - only allowed on NT opens with DELETE access. */
2922 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2923 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2924 correct = False;
2925 goto fail;
2928 if (!cli_close(cli1, fnum1)) {
2929 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
2930 correct = False;
2931 goto fail;
2934 printf("sixth delete on close test succeeded.\n");
2936 /* Test 7 ... */
2937 cli_setatr(cli1, fname, 0, 0);
2938 cli_unlink(cli1, fname);
2940 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2941 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2943 if (fnum1 == -1) {
2944 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2945 correct = False;
2946 goto fail;
2949 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2950 printf("[7] setting delete_on_close on file failed !\n");
2951 correct = False;
2952 goto fail;
2955 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
2956 printf("[7] unsetting delete_on_close on file failed !\n");
2957 correct = False;
2958 goto fail;
2961 if (!cli_close(cli1, fnum1)) {
2962 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2963 correct = False;
2964 goto fail;
2967 /* This next open should succeed - we reset the flag. */
2969 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2970 if (fnum1 == -1) {
2971 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2972 correct = False;
2973 goto fail;
2976 if (!cli_close(cli1, fnum1)) {
2977 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2978 correct = False;
2979 goto fail;
2982 printf("seventh delete on close test succeeded.\n");
2984 /* Test 7 ... */
2985 cli_setatr(cli1, fname, 0, 0);
2986 cli_unlink(cli1, fname);
2988 if (!torture_open_connection(&cli2)) {
2989 printf("[8] failed to open second connection.\n");
2990 correct = False;
2991 goto fail;
2994 cli_sockopt(cli1, sockops);
2996 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2997 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2999 if (fnum1 == -1) {
3000 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3001 correct = False;
3002 goto fail;
3005 fnum2 = cli_nt_create_full(cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3006 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
3008 if (fnum2 == -1) {
3009 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3010 correct = False;
3011 goto fail;
3014 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3015 printf("[8] setting delete_on_close on file failed !\n");
3016 correct = False;
3017 goto fail;
3020 if (!cli_close(cli1, fnum1)) {
3021 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3022 correct = False;
3023 goto fail;
3026 if (!cli_close(cli2, fnum2)) {
3027 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3028 correct = False;
3029 goto fail;
3032 /* This should fail.. */
3033 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3034 if (fnum1 != -1) {
3035 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3036 goto fail;
3037 correct = False;
3038 } else
3039 printf("eighth delete on close test succeeded.\n");
3041 /* This should fail - we need to set DELETE_ACCESS. */
3042 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
3043 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
3045 if (fnum1 != -1) {
3046 printf("[9] open of %s succeeded should have failed!\n", fname);
3047 correct = False;
3048 goto fail;
3051 printf("ninth delete on close test succeeded.\n");
3053 fnum1 = cli_nt_create_full(cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3054 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
3055 if (fnum1 == -1) {
3056 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3057 correct = False;
3058 goto fail;
3061 /* This should delete the file. */
3062 if (!cli_close(cli1, fnum1)) {
3063 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3064 correct = False;
3065 goto fail;
3068 /* This should fail.. */
3069 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3070 if (fnum1 != -1) {
3071 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3072 goto fail;
3073 correct = False;
3074 } else
3075 printf("tenth delete on close test succeeded.\n");
3076 printf("finished delete test\n");
3078 fail:
3079 /* FIXME: This will crash if we aborted before cli2 got
3080 * intialized, because these functions don't handle
3081 * uninitialized connections. */
3083 cli_close(cli1, fnum1);
3084 cli_close(cli1, fnum2);
3085 cli_setatr(cli1, fname, 0, 0);
3086 cli_unlink(cli1, fname);
3088 if (!torture_close_connection(cli1)) {
3089 correct = False;
3091 if (!torture_close_connection(cli2)) {
3092 correct = False;
3094 return correct;
3099 print out server properties
3101 static BOOL run_properties(int dummy)
3103 static struct cli_state *cli;
3104 BOOL correct = True;
3106 printf("starting properties test\n");
3108 ZERO_STRUCT(cli);
3110 if (!torture_open_connection(&cli)) {
3111 return False;
3114 cli_sockopt(cli, sockops);
3116 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3118 if (!torture_close_connection(cli)) {
3119 correct = False;
3122 return correct;
3127 /* FIRST_DESIRED_ACCESS 0xf019f */
3128 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3129 FILE_READ_EA| /* 0xf */ \
3130 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3131 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3132 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3133 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3134 /* SECOND_DESIRED_ACCESS 0xe0080 */
3135 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3136 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3137 WRITE_OWNER_ACCESS /* 0xe0000 */
3139 #if 0
3140 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3141 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3142 FILE_READ_DATA|\
3143 WRITE_OWNER_ACCESS /* */
3144 #endif
3147 Test ntcreate calls made by xcopy
3149 static BOOL run_xcopy(int dummy)
3151 static struct cli_state *cli1;
3152 const char *fname = "\\test.txt";
3153 BOOL correct = True;
3154 int fnum1, fnum2;
3156 printf("starting xcopy test\n");
3158 if (!torture_open_connection(&cli1)) {
3159 return False;
3162 fnum1 = cli_nt_create_full(cli1, fname,
3163 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3164 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3165 0x4044);
3167 if (fnum1 == -1) {
3168 printf("First open failed - %s\n", cli_errstr(cli1));
3169 return False;
3172 fnum2 = cli_nt_create_full(cli1, fname,
3173 SECOND_DESIRED_ACCESS, 0,
3174 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3175 0x200000);
3176 if (fnum2 == -1) {
3177 printf("second open failed - %s\n", cli_errstr(cli1));
3178 return False;
3181 if (!torture_close_connection(cli1)) {
3182 correct = False;
3185 return correct;
3189 Test rename on files open with share delete and no share delete.
3191 static BOOL run_rename(int dummy)
3193 static struct cli_state *cli1;
3194 const char *fname = "\\test.txt";
3195 const char *fname1 = "\\test1.txt";
3196 BOOL correct = True;
3197 int fnum1;
3199 printf("starting rename test\n");
3201 if (!torture_open_connection(&cli1)) {
3202 return False;
3205 cli_unlink(cli1, fname);
3206 cli_unlink(cli1, fname1);
3207 fnum1 = cli_nt_create_full(cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3208 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3210 if (fnum1 == -1) {
3211 printf("First open failed - %s\n", cli_errstr(cli1));
3212 return False;
3215 if (!cli_rename(cli1, fname, fname1)) {
3216 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
3217 } else {
3218 printf("First rename succeeded - this should have failed !\n");
3219 correct = False;
3222 if (!cli_close(cli1, fnum1)) {
3223 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3224 return False;
3227 cli_unlink(cli1, fname);
3228 cli_unlink(cli1, fname1);
3229 fnum1 = cli_nt_create_full(cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3230 #if 0
3231 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3232 #else
3233 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3234 #endif
3236 if (fnum1 == -1) {
3237 printf("Second open failed - %s\n", cli_errstr(cli1));
3238 return False;
3241 if (!cli_rename(cli1, fname, fname1)) {
3242 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
3243 correct = False;
3244 } else {
3245 printf("Second rename succeeded\n");
3248 if (!cli_close(cli1, fnum1)) {
3249 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3250 return False;
3253 cli_unlink(cli1, fname);
3254 cli_unlink(cli1, fname1);
3256 fnum1 = cli_nt_create_full(cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3257 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3259 if (fnum1 == -1) {
3260 printf("Third open failed - %s\n", cli_errstr(cli1));
3261 return False;
3265 #if 0
3267 int fnum2;
3269 fnum2 = cli_nt_create_full(cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3270 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3272 if (fnum2 == -1) {
3273 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3274 return False;
3276 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3277 printf("[8] setting delete_on_close on file failed !\n");
3278 return False;
3281 if (!cli_close(cli1, fnum2)) {
3282 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3283 return False;
3286 #endif
3288 if (!cli_rename(cli1, fname, fname1)) {
3289 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
3290 correct = False;
3291 } else {
3292 printf("Third rename succeeded\n");
3295 if (!cli_close(cli1, fnum1)) {
3296 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3297 return False;
3300 cli_unlink(cli1, fname);
3301 cli_unlink(cli1, fname1);
3303 if (!torture_close_connection(cli1)) {
3304 correct = False;
3307 return correct;
3310 static BOOL run_pipe_number(int dummy)
3312 struct cli_state *cli1;
3313 const char *pipe_name = "\\SPOOLSS";
3314 int fnum;
3315 int num_pipes = 0;
3317 printf("starting pipenumber test\n");
3318 if (!torture_open_connection(&cli1)) {
3319 return False;
3322 cli_sockopt(cli1, sockops);
3323 while(1) {
3324 fnum = cli_nt_create_full(cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3325 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
3327 if (fnum == -1) {
3328 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3329 break;
3331 num_pipes++;
3334 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3335 torture_close_connection(cli1);
3336 return True;
3340 Test open mode returns on read-only files.
3342 static BOOL run_opentest(int dummy)
3344 static struct cli_state *cli1;
3345 static struct cli_state *cli2;
3346 const char *fname = "\\readonly.file";
3347 int fnum1, fnum2;
3348 char buf[20];
3349 size_t fsize;
3350 BOOL correct = True;
3351 char *tmp_path;
3353 printf("starting open test\n");
3355 if (!torture_open_connection(&cli1)) {
3356 return False;
3359 cli_setatr(cli1, fname, 0, 0);
3360 cli_unlink(cli1, fname);
3362 cli_sockopt(cli1, sockops);
3364 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3365 if (fnum1 == -1) {
3366 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3367 return False;
3370 if (!cli_close(cli1, fnum1)) {
3371 printf("close2 failed (%s)\n", cli_errstr(cli1));
3372 return False;
3375 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3376 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3377 return False;
3380 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3381 if (fnum1 == -1) {
3382 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3383 return False;
3386 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3387 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3389 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3390 NT_STATUS_ACCESS_DENIED)) {
3391 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3394 printf("finished open test 1\n");
3396 cli_close(cli1, fnum1);
3398 /* Now try not readonly and ensure ERRbadshare is returned. */
3400 cli_setatr(cli1, fname, 0, 0);
3402 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3403 if (fnum1 == -1) {
3404 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3405 return False;
3408 /* This will fail - but the error should be ERRshare. */
3409 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3411 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3412 NT_STATUS_SHARING_VIOLATION)) {
3413 printf("correct error code ERRDOS/ERRbadshare returned\n");
3416 if (!cli_close(cli1, fnum1)) {
3417 printf("close2 failed (%s)\n", cli_errstr(cli1));
3418 return False;
3421 cli_unlink(cli1, fname);
3423 printf("finished open test 2\n");
3425 /* Test truncate open disposition on file opened for read. */
3427 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3428 if (fnum1 == -1) {
3429 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3430 return False;
3433 /* write 20 bytes. */
3435 memset(buf, '\0', 20);
3437 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3438 printf("write failed (%s)\n", cli_errstr(cli1));
3439 correct = False;
3442 if (!cli_close(cli1, fnum1)) {
3443 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3444 return False;
3447 /* Ensure size == 20. */
3448 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3449 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3450 return False;
3453 if (fsize != 20) {
3454 printf("(3) file size != 20\n");
3455 return False;
3458 /* Now test if we can truncate a file opened for readonly. */
3460 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3461 if (fnum1 == -1) {
3462 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3463 return False;
3466 if (!cli_close(cli1, fnum1)) {
3467 printf("close2 failed (%s)\n", cli_errstr(cli1));
3468 return False;
3471 /* Ensure size == 0. */
3472 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3473 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3474 return False;
3477 if (fsize != 0) {
3478 printf("(3) file size != 0\n");
3479 return False;
3481 printf("finished open test 3\n");
3483 cli_unlink(cli1, fname);
3486 printf("testing ctemp\n");
3487 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3488 if (fnum1 == -1) {
3489 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3490 return False;
3492 printf("ctemp gave path %s\n", tmp_path);
3493 if (!cli_close(cli1, fnum1)) {
3494 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3496 if (!cli_unlink(cli1, tmp_path)) {
3497 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3500 /* Test the non-io opens... */
3502 if (!torture_open_connection(&cli2)) {
3503 return False;
3506 cli_setatr(cli2, fname, 0, 0);
3507 cli_unlink(cli2, fname);
3509 cli_sockopt(cli2, sockops);
3511 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3513 fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3514 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3516 if (fnum1 == -1) {
3517 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3518 return False;
3521 fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3522 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3524 if (fnum2 == -1) {
3525 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3526 return False;
3529 if (!cli_close(cli1, fnum1)) {
3530 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3531 return False;
3533 if (!cli_close(cli2, fnum2)) {
3534 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3535 return False;
3538 printf("non-io open test #1 passed.\n");
3540 cli_unlink(cli1, fname);
3542 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3544 fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3545 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3547 if (fnum1 == -1) {
3548 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3549 return False;
3552 fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3553 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3555 if (fnum2 == -1) {
3556 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3557 return False;
3560 if (!cli_close(cli1, fnum1)) {
3561 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3562 return False;
3564 if (!cli_close(cli2, fnum2)) {
3565 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3566 return False;
3569 printf("non-io open test #2 passed.\n");
3571 cli_unlink(cli1, fname);
3573 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3575 fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3576 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3578 if (fnum1 == -1) {
3579 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3580 return False;
3583 fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3584 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3586 if (fnum2 == -1) {
3587 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3588 return False;
3591 if (!cli_close(cli1, fnum1)) {
3592 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3593 return False;
3595 if (!cli_close(cli2, fnum2)) {
3596 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3597 return False;
3600 printf("non-io open test #3 passed.\n");
3602 cli_unlink(cli1, fname);
3604 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3606 fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3607 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3609 if (fnum1 == -1) {
3610 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3611 return False;
3614 fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3615 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3617 if (fnum2 != -1) {
3618 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3619 return False;
3622 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3624 if (!cli_close(cli1, fnum1)) {
3625 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3626 return False;
3629 printf("non-io open test #4 passed.\n");
3631 cli_unlink(cli1, fname);
3633 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3635 fnum1 = cli_nt_create_full(cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3636 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3638 if (fnum1 == -1) {
3639 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3640 return False;
3643 fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3644 FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3646 if (fnum2 == -1) {
3647 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3648 return False;
3651 if (!cli_close(cli1, fnum1)) {
3652 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3653 return False;
3656 if (!cli_close(cli2, fnum2)) {
3657 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3658 return False;
3661 printf("non-io open test #5 passed.\n");
3663 printf("TEST #6 testing 1 non-io open, one io open\n");
3665 cli_unlink(cli1, fname);
3667 fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3668 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3670 if (fnum1 == -1) {
3671 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3672 return False;
3675 fnum2 = cli_nt_create_full(cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3676 FILE_SHARE_READ, FILE_OPEN_IF, 0);
3678 if (fnum2 == -1) {
3679 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3680 return False;
3683 if (!cli_close(cli1, fnum1)) {
3684 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3685 return False;
3688 if (!cli_close(cli2, fnum2)) {
3689 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3690 return False;
3693 printf("non-io open test #6 passed.\n");
3695 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3697 cli_unlink(cli1, fname);
3699 fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3700 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3702 if (fnum1 == -1) {
3703 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3704 return False;
3707 fnum2 = cli_nt_create_full(cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3708 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3710 if (fnum2 != -1) {
3711 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3712 return False;
3715 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3717 if (!cli_close(cli1, fnum1)) {
3718 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3719 return False;
3722 printf("non-io open test #7 passed.\n");
3724 cli_unlink(cli1, fname);
3726 if (!torture_close_connection(cli1)) {
3727 correct = False;
3729 if (!torture_close_connection(cli2)) {
3730 correct = False;
3733 return correct;
3736 static uint32 open_attrs_table[] = {
3737 FILE_ATTRIBUTE_NORMAL,
3738 FILE_ATTRIBUTE_ARCHIVE,
3739 FILE_ATTRIBUTE_READONLY,
3740 FILE_ATTRIBUTE_HIDDEN,
3741 FILE_ATTRIBUTE_SYSTEM,
3743 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3744 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3745 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3746 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3747 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3748 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3750 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3751 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3752 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3753 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3756 struct trunc_open_results {
3757 unsigned int num;
3758 uint32 init_attr;
3759 uint32 trunc_attr;
3760 uint32 result_attr;
3763 static struct trunc_open_results attr_results[] = {
3764 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3765 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3766 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3767 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3768 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3769 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3770 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3771 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3772 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3773 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3774 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3775 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3776 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3777 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3778 { 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 },
3779 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3780 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3781 { 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 },
3782 { 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 },
3783 { 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 },
3784 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3785 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3786 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3787 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3788 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3789 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3792 static BOOL run_openattrtest(int dummy)
3794 static struct cli_state *cli1;
3795 const char *fname = "\\openattr.file";
3796 int fnum1;
3797 BOOL correct = True;
3798 uint16 attr;
3799 unsigned int i, j, k, l;
3801 printf("starting open attr test\n");
3803 if (!torture_open_connection(&cli1)) {
3804 return False;
3807 cli_sockopt(cli1, sockops);
3809 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3810 cli_setatr(cli1, fname, 0, 0);
3811 cli_unlink(cli1, fname);
3812 fnum1 = cli_nt_create_full(cli1, fname,FILE_WRITE_DATA, open_attrs_table[i],
3813 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3815 if (fnum1 == -1) {
3816 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3817 return False;
3820 if (!cli_close(cli1, fnum1)) {
3821 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3822 return False;
3825 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
3826 fnum1 = cli_nt_create_full(cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
3827 FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3829 if (fnum1 == -1) {
3830 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3831 if (attr_results[l].num == k) {
3832 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3833 k, open_attrs_table[i],
3834 open_attrs_table[j],
3835 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
3836 correct = False;
3839 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3840 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3841 k, open_attrs_table[i], open_attrs_table[j],
3842 cli_errstr(cli1));
3843 correct = False;
3845 #if 0
3846 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3847 #endif
3848 k++;
3849 continue;
3852 if (!cli_close(cli1, fnum1)) {
3853 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
3854 return False;
3857 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
3858 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
3859 return False;
3862 #if 0
3863 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3864 k, open_attrs_table[i], open_attrs_table[j], attr );
3865 #endif
3867 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3868 if (attr_results[l].num == k) {
3869 if (attr != attr_results[l].result_attr ||
3870 open_attrs_table[i] != attr_results[l].init_attr ||
3871 open_attrs_table[j] != attr_results[l].trunc_attr) {
3872 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3873 open_attrs_table[i],
3874 open_attrs_table[j],
3875 (unsigned int)attr,
3876 attr_results[l].result_attr);
3877 correct = False;
3879 break;
3882 k++;
3886 cli_setatr(cli1, fname, 0, 0);
3887 cli_unlink(cli1, fname);
3889 printf("open attr test %s.\n", correct ? "passed" : "failed");
3891 if (!torture_close_connection(cli1)) {
3892 correct = False;
3894 return correct;
3897 static void list_fn(file_info *finfo, const char *name, void *state)
3903 test directory listing speed
3905 static BOOL run_dirtest(int dummy)
3907 int i;
3908 static struct cli_state *cli;
3909 int fnum;
3910 double t1;
3911 BOOL correct = True;
3913 printf("starting directory test\n");
3915 if (!torture_open_connection(&cli)) {
3916 return False;
3919 cli_sockopt(cli, sockops);
3921 srandom(0);
3922 for (i=0;i<torture_numops;i++) {
3923 fstring fname;
3924 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3925 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3926 if (fnum == -1) {
3927 fprintf(stderr,"Failed to open %s\n", fname);
3928 return False;
3930 cli_close(cli, fnum);
3933 t1 = end_timer();
3935 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3936 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3937 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3939 printf("dirtest core %g seconds\n", end_timer() - t1);
3941 srandom(0);
3942 for (i=0;i<torture_numops;i++) {
3943 fstring fname;
3944 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3945 cli_unlink(cli, fname);
3948 if (!torture_close_connection(cli)) {
3949 correct = False;
3952 printf("finished dirtest\n");
3954 return correct;
3957 static void del_fn(file_info *finfo, const char *mask, void *state)
3959 struct cli_state *pcli = (struct cli_state *)state;
3960 fstring fname;
3961 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3963 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3964 return;
3966 if (finfo->mode & aDIR) {
3967 if (!cli_rmdir(pcli, fname))
3968 printf("del_fn: failed to rmdir %s\n,", fname );
3969 } else {
3970 if (!cli_unlink(pcli, fname))
3971 printf("del_fn: failed to unlink %s\n,", fname );
3977 sees what IOCTLs are supported
3979 BOOL torture_ioctl_test(int dummy)
3981 static struct cli_state *cli;
3982 uint16 device, function;
3983 int fnum;
3984 const char *fname = "\\ioctl.dat";
3985 DATA_BLOB blob;
3986 NTSTATUS status;
3988 if (!torture_open_connection(&cli)) {
3989 return False;
3992 printf("starting ioctl test\n");
3994 cli_unlink(cli, fname);
3996 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3997 if (fnum == -1) {
3998 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3999 return False;
4002 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4003 printf("ioctl device info: %s\n", cli_errstr(cli));
4005 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4006 printf("ioctl job info: %s\n", cli_errstr(cli));
4008 for (device=0;device<0x100;device++) {
4009 printf("testing device=0x%x\n", device);
4010 for (function=0;function<0x100;function++) {
4011 uint32 code = (device<<16) | function;
4013 status = cli_raw_ioctl(cli, fnum, code, &blob);
4015 if (NT_STATUS_IS_OK(status)) {
4016 printf("ioctl 0x%x OK : %d bytes\n", code, blob.length);
4017 data_blob_free(&blob);
4022 if (!torture_close_connection(cli)) {
4023 return False;
4026 return True;
4031 tries varients of chkpath
4033 BOOL torture_chkpath_test(int dummy)
4035 static struct cli_state *cli;
4036 int fnum;
4037 BOOL ret;
4039 if (!torture_open_connection(&cli)) {
4040 return False;
4043 printf("starting chkpath test\n");
4045 /* cleanup from an old run */
4046 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4047 cli_unlink(cli, "\\chkpath.dir\\*");
4048 cli_rmdir(cli, "\\chkpath.dir");
4050 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4051 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4052 return False;
4055 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4056 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4057 return False;
4060 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4061 if (fnum == -1) {
4062 printf("open1 failed (%s)\n", cli_errstr(cli));
4063 return False;
4065 cli_close(cli, fnum);
4067 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4068 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4069 ret = False;
4072 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4073 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4074 ret = False;
4077 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4078 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4079 NT_STATUS_NOT_A_DIRECTORY);
4080 } else {
4081 printf("* chkpath on a file should fail\n");
4082 ret = False;
4085 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4086 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4087 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4088 } else {
4089 printf("* chkpath on a non existant file should fail\n");
4090 ret = False;
4093 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4094 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4095 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4096 } else {
4097 printf("* chkpath on a non existent component should fail\n");
4098 ret = False;
4101 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4102 cli_unlink(cli, "\\chkpath.dir\\*");
4103 cli_rmdir(cli, "\\chkpath.dir");
4105 if (!torture_close_connection(cli)) {
4106 return False;
4109 return ret;
4115 static BOOL run_dirtest1(int dummy)
4117 int i;
4118 static struct cli_state *cli;
4119 int fnum, num_seen;
4120 BOOL correct = True;
4122 printf("starting directory test\n");
4124 if (!torture_open_connection(&cli)) {
4125 return False;
4128 cli_sockopt(cli, sockops);
4130 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4131 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4132 cli_rmdir(cli, "\\LISTDIR");
4133 cli_mkdir(cli, "\\LISTDIR");
4135 /* Create 1000 files and 1000 directories. */
4136 for (i=0;i<1000;i++) {
4137 fstring fname;
4138 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4139 fnum = cli_nt_create_full(cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4140 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
4141 if (fnum == -1) {
4142 fprintf(stderr,"Failed to open %s\n", fname);
4143 return False;
4145 cli_close(cli, fnum);
4147 for (i=0;i<1000;i++) {
4148 fstring fname;
4149 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4150 if (!cli_mkdir(cli, fname)) {
4151 fprintf(stderr,"Failed to open %s\n", fname);
4152 return False;
4156 /* Now ensure that doing an old list sees both files and directories. */
4157 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4158 printf("num_seen = %d\n", num_seen );
4159 /* We should see 100 files + 1000 directories + . and .. */
4160 if (num_seen != 2002)
4161 correct = False;
4163 /* Ensure if we have the "must have" bits we only see the
4164 * relevent entries.
4166 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4167 printf("num_seen = %d\n", num_seen );
4168 if (num_seen != 1002)
4169 correct = False;
4171 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4172 printf("num_seen = %d\n", num_seen );
4173 if (num_seen != 1000)
4174 correct = False;
4176 /* Delete everything. */
4177 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4178 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4179 cli_rmdir(cli, "\\LISTDIR");
4181 #if 0
4182 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4183 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4184 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4185 #endif
4187 if (!torture_close_connection(cli)) {
4188 correct = False;
4191 printf("finished dirtest1\n");
4193 return correct;
4196 static BOOL run_error_map_extract(int dummy) {
4198 static struct cli_state c_dos;
4199 static struct cli_state c_nt;
4201 uint32 error;
4203 uint32 flgs2, errnum;
4204 uint8 errclass;
4206 NTSTATUS nt_status;
4208 fstring user;
4210 /* NT-Error connection */
4212 if (!open_nbt_connection(&c_nt)) {
4213 return False;
4216 c_nt.use_spnego = False;
4218 if (!cli_negprot(&c_nt)) {
4219 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
4220 cli_shutdown(&c_nt);
4221 return False;
4224 if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
4225 workgroup)) {
4226 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
4227 return False;
4230 /* DOS-Error connection */
4232 if (!open_nbt_connection(&c_dos)) {
4233 return False;
4236 c_dos.use_spnego = False;
4237 c_dos.force_dos_errors = True;
4239 if (!cli_negprot(&c_dos)) {
4240 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
4241 cli_shutdown(&c_dos);
4242 return False;
4245 if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
4246 workgroup)) {
4247 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
4248 return False;
4251 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4252 snprintf(user, sizeof(user), "%X", error);
4254 if (cli_session_setup(&c_nt, user,
4255 password, strlen(password),
4256 password, strlen(password),
4257 workgroup)) {
4258 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4261 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
4263 /* Case #1: 32-bit NT errors */
4264 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4265 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
4266 } else {
4267 printf("/** Dos error on NT connection! (%s) */\n",
4268 cli_errstr(&c_nt));
4269 nt_status = NT_STATUS(0xc0000000);
4272 if (cli_session_setup(&c_dos, user,
4273 password, strlen(password),
4274 password, strlen(password),
4275 workgroup)) {
4276 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4278 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
4280 /* Case #1: 32-bit NT errors */
4281 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4282 printf("/** NT error on DOS connection! (%s) */\n",
4283 cli_errstr(&c_nt));
4284 errnum = errclass = 0;
4285 } else {
4286 cli_dos_error(&c_dos, &errclass, &errnum);
4289 if (NT_STATUS_V(nt_status) != error) {
4290 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4291 get_nt_error_c_code(NT_STATUS(error)),
4292 get_nt_error_c_code(nt_status));
4295 printf("\t{%s,\t%s,\t%s},\n",
4296 smb_dos_err_class(errclass),
4297 smb_dos_err_name(errclass, errnum),
4298 get_nt_error_c_code(NT_STATUS(error)));
4300 return True;
4303 static double create_procs(BOOL (*fn)(int), BOOL *result)
4305 int i, status;
4306 volatile pid_t *child_status;
4307 volatile BOOL *child_status_out;
4308 int synccount;
4309 int tries = 8;
4311 synccount = 0;
4313 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4314 if (!child_status) {
4315 printf("Failed to setup shared memory\n");
4316 return -1;
4319 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4320 if (!child_status_out) {
4321 printf("Failed to setup result status shared memory\n");
4322 return -1;
4325 for (i = 0; i < nprocs; i++) {
4326 child_status[i] = 0;
4327 child_status_out[i] = True;
4330 start_timer();
4332 for (i=0;i<nprocs;i++) {
4333 procnum = i;
4334 if (fork() == 0) {
4335 pid_t mypid = getpid();
4336 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4338 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4340 while (1) {
4341 if (torture_open_connection(&current_cli)) break;
4342 if (tries-- == 0) {
4343 printf("pid %d failed to start\n", (int)getpid());
4344 _exit(1);
4346 msleep(10);
4349 child_status[i] = getpid();
4351 while (child_status[i] && end_timer() < 5) msleep(2);
4353 child_status_out[i] = fn(i);
4354 _exit(0);
4358 do {
4359 synccount = 0;
4360 for (i=0;i<nprocs;i++) {
4361 if (child_status[i]) synccount++;
4363 if (synccount == nprocs) break;
4364 msleep(10);
4365 } while (end_timer() < 30);
4367 if (synccount != nprocs) {
4368 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4369 *result = False;
4370 return end_timer();
4373 /* start the client load */
4374 start_timer();
4376 for (i=0;i<nprocs;i++) {
4377 child_status[i] = 0;
4380 printf("%d clients started\n", nprocs);
4382 for (i=0;i<nprocs;i++) {
4383 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
4386 printf("\n");
4388 for (i=0;i<nprocs;i++) {
4389 if (!child_status_out[i]) {
4390 *result = False;
4393 return end_timer();
4396 #define FLAG_MULTIPROC 1
4398 static struct {
4399 const char *name;
4400 BOOL (*fn)(int);
4401 unsigned flags;
4402 } torture_ops[] = {
4403 {"FDPASS", run_fdpasstest, 0},
4404 {"LOCK1", run_locktest1, 0},
4405 {"LOCK2", run_locktest2, 0},
4406 {"LOCK3", run_locktest3, 0},
4407 {"LOCK4", run_locktest4, 0},
4408 {"LOCK5", run_locktest5, 0},
4409 {"LOCK6", run_locktest6, 0},
4410 {"LOCK7", run_locktest7, 0},
4411 {"UNLINK", run_unlinktest, 0},
4412 {"BROWSE", run_browsetest, 0},
4413 {"ATTR", run_attrtest, 0},
4414 {"TRANS2", run_trans2test, 0},
4415 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4416 {"TORTURE",run_torture, FLAG_MULTIPROC},
4417 {"RANDOMIPC", run_randomipc, 0},
4418 {"NEGNOWAIT", run_negprot_nowait, 0},
4419 {"NBENCH", run_nbench, 0},
4420 {"OPLOCK1", run_oplock1, 0},
4421 {"OPLOCK2", run_oplock2, 0},
4422 {"OPLOCK3", run_oplock3, 0},
4423 {"DIR", run_dirtest, 0},
4424 {"DIR1", run_dirtest1, 0},
4425 {"DENY1", torture_denytest1, 0},
4426 {"DENY2", torture_denytest2, 0},
4427 {"TCON", run_tcon_test, 0},
4428 {"TCONDEV", run_tcon_devtype_test, 0},
4429 {"RW1", run_readwritetest, 0},
4430 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4431 {"RW3", run_readwritelarge, 0},
4432 {"OPEN", run_opentest, 0},
4433 #if 1
4434 {"OPENATTR", run_openattrtest, 0},
4435 #endif
4436 {"XCOPY", run_xcopy, 0},
4437 {"RENAME", run_rename, 0},
4438 {"DELETE", run_deletetest, 0},
4439 {"PROPERTIES", run_properties, 0},
4440 {"MANGLE", torture_mangle, 0},
4441 {"W2K", run_w2ktest, 0},
4442 {"TRANS2SCAN", torture_trans2_scan, 0},
4443 {"NTTRANSSCAN", torture_nttrans_scan, 0},
4444 {"UTABLE", torture_utable, 0},
4445 {"CASETABLE", torture_casetable, 0},
4446 {"ERRMAPEXTRACT", run_error_map_extract, 0},
4447 {"PIPE_NUMBER", run_pipe_number, 0},
4448 {"TCON2", run_tcon2_test, 0},
4449 {"IOCTL", torture_ioctl_test, 0},
4450 {"CHKPATH", torture_chkpath_test, 0},
4451 {NULL, NULL, 0}};
4455 /****************************************************************************
4456 run a specified test or "ALL"
4457 ****************************************************************************/
4458 static BOOL run_test(const char *name)
4460 BOOL ret = True;
4461 BOOL result = True;
4462 int i;
4463 double t;
4464 if (strequal(name,"ALL")) {
4465 for (i=0;torture_ops[i].name;i++) {
4466 run_test(torture_ops[i].name);
4470 for (i=0;torture_ops[i].name;i++) {
4471 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
4472 (unsigned)random());
4474 if (strequal(name, torture_ops[i].name)) {
4475 printf("Running %s\n", name);
4476 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4477 t = create_procs(torture_ops[i].fn, &result);
4478 if (!result) {
4479 ret = False;
4480 printf("TEST %s FAILED!\n", name);
4483 } else {
4484 start_timer();
4485 if (!torture_ops[i].fn(0)) {
4486 ret = False;
4487 printf("TEST %s FAILED!\n", name);
4489 t = end_timer();
4491 printf("%s took %g secs\n\n", name, t);
4494 return ret;
4498 static void usage(void)
4500 int i;
4502 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4504 printf("\t-d debuglevel\n");
4505 printf("\t-U user%%pass\n");
4506 printf("\t-k use kerberos\n");
4507 printf("\t-N numprocs\n");
4508 printf("\t-n my_netbios_name\n");
4509 printf("\t-W workgroup\n");
4510 printf("\t-o num_operations\n");
4511 printf("\t-O socket_options\n");
4512 printf("\t-m maximum protocol\n");
4513 printf("\t-L use oplocks\n");
4514 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4515 printf("\t-A showall\n");
4516 printf("\t-p port\n");
4517 printf("\t-s seed\n");
4518 printf("\n\n");
4520 printf("tests are:");
4521 for (i=0;torture_ops[i].name;i++) {
4522 printf(" %s", torture_ops[i].name);
4524 printf("\n");
4526 printf("default test is ALL\n");
4528 exit(1);
4531 /****************************************************************************
4532 main program
4533 ****************************************************************************/
4534 int main(int argc,char *argv[])
4536 int opt, i;
4537 char *p;
4538 int gotuser = 0;
4539 int gotpass = 0;
4540 extern char *optarg;
4541 extern int optind;
4542 BOOL correct = True;
4544 dbf = x_stdout;
4546 #ifdef HAVE_SETBUFFER
4547 setbuffer(stdout, NULL, 0);
4548 #endif
4550 lp_load(dyn_CONFIGFILE,True,False,False);
4551 load_interfaces();
4553 if (argc < 2) {
4554 usage();
4557 for(p = argv[1]; *p; p++)
4558 if(*p == '\\')
4559 *p = '/';
4561 if (strncmp(argv[1], "//", 2)) {
4562 usage();
4565 fstrcpy(host, &argv[1][2]);
4566 p = strchr_m(&host[2],'/');
4567 if (!p) {
4568 usage();
4570 *p = 0;
4571 fstrcpy(share, p+1);
4573 get_myname(myname);
4575 if (*username == 0 && getenv("LOGNAME")) {
4576 fstrcpy(username,getenv("LOGNAME"));
4579 argc--;
4580 argv++;
4582 srandom(time(NULL));
4584 fstrcpy(workgroup, lp_workgroup());
4586 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4587 switch (opt) {
4588 case 'p':
4589 port_to_use = atoi(optarg);
4590 break;
4591 case 's':
4592 srandom(atoi(optarg));
4593 break;
4594 case 'W':
4595 fstrcpy(workgroup,optarg);
4596 break;
4597 case 'm':
4598 max_protocol = interpret_protocol(optarg, max_protocol);
4599 break;
4600 case 'N':
4601 nprocs = atoi(optarg);
4602 break;
4603 case 'o':
4604 torture_numops = atoi(optarg);
4605 break;
4606 case 'd':
4607 DEBUGLEVEL = atoi(optarg);
4608 break;
4609 case 'O':
4610 sockops = optarg;
4611 break;
4612 case 'L':
4613 use_oplocks = True;
4614 break;
4615 case 'A':
4616 torture_showall = True;
4617 break;
4618 case 'n':
4619 fstrcpy(myname, optarg);
4620 break;
4621 case 'c':
4622 client_txt = optarg;
4623 break;
4624 case 'k':
4625 #ifdef HAVE_KRB5
4626 use_kerberos = True;
4627 #else
4628 d_printf("No kerberos support compiled in\n");
4629 exit(1);
4630 #endif
4631 break;
4632 case 'U':
4633 gotuser = 1;
4634 fstrcpy(username,optarg);
4635 p = strchr_m(username,'%');
4636 if (p) {
4637 *p = 0;
4638 fstrcpy(password, p+1);
4639 gotpass = 1;
4641 break;
4642 default:
4643 printf("Unknown option %c (%d)\n", (char)opt, opt);
4644 usage();
4648 if(use_kerberos && !gotuser) gotpass = True;
4650 while (!gotpass) {
4651 p = getpass("Password:");
4652 if (p) {
4653 fstrcpy(password, p);
4654 gotpass = 1;
4658 printf("host=%s share=%s user=%s myname=%s\n",
4659 host, share, username, myname);
4661 if (argc == 1) {
4662 correct = run_test("ALL");
4663 } else {
4664 for (i=1;i<argc;i++) {
4665 if (!run_test(argv[i])) {
4666 correct = False;
4671 if (correct) {
4672 return(0);
4673 } else {
4674 return(1);