[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / torture / torture.c
blob8ca2eb58981938cd91b7624e9541d39ec38faf8d
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 #include "includes.h"
23 extern char *optarg;
24 extern int optind;
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static const char *sockops="TCP_NODELAY";
29 static int nprocs=1;
30 static int port_to_use=0;
31 int torture_numops=100;
32 static int procnum; /* records process count number when forking */
33 static struct cli_state *current_cli;
34 static fstring randomfname;
35 static BOOL use_oplocks;
36 static BOOL use_level_II_oplocks;
37 static const char *client_txt = "client_oplocks.txt";
38 static BOOL use_kerberos;
39 static fstring multishare_conn_fname;
40 static BOOL use_multishare_conn = False;
42 BOOL torture_showall = False;
44 static double create_procs(BOOL (*fn)(int), BOOL *result);
47 static struct timeval tp1,tp2;
50 void start_timer(void)
52 GetTimeOfDay(&tp1);
55 double end_timer(void)
57 GetTimeOfDay(&tp2);
58 return((tp2.tv_sec - tp1.tv_sec) +
59 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
63 /* return a pointer to a anonymous shared memory segment of size "size"
64 which will persist across fork() but will disappear when all processes
65 exit
67 The memory is not zeroed
69 This function uses system5 shared memory. It takes advantage of a property
70 that the memory is not destroyed if it is attached when the id is removed
72 void *shm_setup(int size)
74 int shmid;
75 void *ret;
77 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
78 if (shmid == -1) {
79 printf("can't get shared memory\n");
80 exit(1);
82 ret = (void *)shmat(shmid, 0, 0);
83 if (!ret || ret == (void *)-1) {
84 printf("can't attach to shared memory\n");
85 return NULL;
87 /* the following releases the ipc, but note that this process
88 and all its children will still have access to the memory, its
89 just that the shmid is no longer valid for other shm calls. This
90 means we don't leave behind lots of shm segments after we exit
92 See Stevens "advanced programming in unix env" for details
94 shmctl(shmid, IPC_RMID, 0);
96 return ret;
100 static struct cli_state *open_nbt_connection(void)
102 struct nmb_name called, calling;
103 struct in_addr ip;
104 struct cli_state *c;
105 NTSTATUS status;
107 make_nmb_name(&calling, myname, 0x0);
108 make_nmb_name(&called , host, 0x20);
110 zero_ip(&ip);
112 if (!(c = cli_initialise())) {
113 printf("Failed initialize cli_struct to connect with %s\n", host);
114 return NULL;
117 c->port = port_to_use;
119 status = cli_connect(c, host, &ip);
120 if (!NT_STATUS_IS_OK(status)) {
121 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
122 return NULL;
125 c->use_kerberos = use_kerberos;
127 c->timeout = 120000; /* set a really long timeout (2 minutes) */
128 if (use_oplocks) c->use_oplocks = True;
129 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
131 if (!cli_session_request(c, &calling, &called)) {
133 * Well, that failed, try *SMBSERVER ...
134 * However, we must reconnect as well ...
136 status = cli_connect(c, host, &ip);
137 if (!NT_STATUS_IS_OK(status)) {
138 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
139 return NULL;
142 make_nmb_name(&called, "*SMBSERVER", 0x20);
143 if (!cli_session_request(c, &calling, &called)) {
144 printf("%s rejected the session\n",host);
145 printf("We tried with a called name of %s & %s\n",
146 host, "*SMBSERVER");
147 cli_shutdown(c);
148 return NULL;
152 return c;
155 /* Insert a NULL at the first separator of the given path and return a pointer
156 * to the remainder of the string.
158 static char *
159 terminate_path_at_separator(char * path)
161 char * p;
163 if (!path) {
164 return NULL;
167 if ((p = strchr_m(path, '/'))) {
168 *p = '\0';
169 return p + 1;
172 if ((p = strchr_m(path, '\\'))) {
173 *p = '\0';
174 return p + 1;
177 /* No separator. */
178 return NULL;
182 parse a //server/share type UNC name
184 BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
185 char **hostname, char **sharename)
187 char *p;
189 *hostname = *sharename = NULL;
191 if (strncmp(unc_name, "\\\\", 2) &&
192 strncmp(unc_name, "//", 2)) {
193 return False;
196 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
197 p = terminate_path_at_separator(*hostname);
199 if (p && *p) {
200 *sharename = talloc_strdup(mem_ctx, p);
201 terminate_path_at_separator(*sharename);
204 if (*hostname && *sharename) {
205 return True;
208 TALLOC_FREE(*hostname);
209 TALLOC_FREE(*sharename);
210 return False;
213 static BOOL torture_open_connection_share(struct cli_state **c,
214 const char *hostname,
215 const char *sharename)
217 BOOL retry;
218 int flags = 0;
219 NTSTATUS status;
221 if (use_kerberos)
222 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
224 status = cli_full_connection(c, myname,
225 hostname, NULL, port_to_use,
226 sharename, "?????",
227 username, workgroup,
228 password, flags, Undefined, &retry);
229 if (!NT_STATUS_IS_OK(status)) {
230 printf("failed to open share connection: //%s/%s port:%d - %s\n",
231 hostname, sharename, port_to_use, nt_errstr(status));
232 return False;
235 if (use_oplocks) (*c)->use_oplocks = True;
236 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
237 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
239 return True;
242 void torture_open_connection_free_unclist(char **unc_list)
244 if (unc_list!=NULL)
246 SAFE_FREE(unc_list[0]);
247 SAFE_FREE(unc_list);
251 BOOL torture_open_connection(struct cli_state **c, int conn_index)
253 char **unc_list = NULL;
254 int num_unc_names = 0;
255 BOOL result;
257 if (use_multishare_conn==True) {
258 char *h, *s;
259 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
260 if (!unc_list || num_unc_names <= 0) {
261 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
262 exit(1);
265 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
266 NULL, &h, &s)) {
267 printf("Failed to parse UNC name %s\n",
268 unc_list[conn_index % num_unc_names]);
269 torture_open_connection_free_unclist(unc_list);
270 exit(1);
273 result = torture_open_connection_share(c, h, s);
275 /* h, s were copied earlier */
276 torture_open_connection_free_unclist(unc_list);
277 return result;
280 return torture_open_connection_share(c, host, share);
283 BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
285 uint16 old_vuid = cli->vuid;
286 fstring old_user_name;
287 size_t passlen = strlen(password);
288 BOOL ret;
290 fstrcpy(old_user_name, cli->user_name);
291 cli->vuid = 0;
292 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
293 password, passlen,
294 password, passlen,
295 workgroup));
296 *new_vuid = cli->vuid;
297 cli->vuid = old_vuid;
298 fstrcpy(cli->user_name, old_user_name);
299 return ret;
303 BOOL torture_close_connection(struct cli_state *c)
305 BOOL ret = True;
306 if (!cli_tdis(c)) {
307 printf("tdis failed (%s)\n", cli_errstr(c));
308 ret = False;
311 cli_shutdown(c);
313 return ret;
317 /* check if the server produced the expected error code */
318 static BOOL check_error(int line, struct cli_state *c,
319 uint8 eclass, uint32 ecode, NTSTATUS nterr)
321 if (cli_is_dos_error(c)) {
322 uint8 cclass;
323 uint32 num;
325 /* Check DOS error */
327 cli_dos_error(c, &cclass, &num);
329 if (eclass != cclass || ecode != num) {
330 printf("unexpected error code class=%d code=%d\n",
331 (int)cclass, (int)num);
332 printf(" expected %d/%d %s (line=%d)\n",
333 (int)eclass, (int)ecode, nt_errstr(nterr), line);
334 return False;
337 } else {
338 NTSTATUS status;
340 /* Check NT error */
342 status = cli_nt_error(c);
344 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
345 printf("unexpected error code %s\n", nt_errstr(status));
346 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
347 return False;
351 return True;
355 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
357 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
358 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
360 return True;
364 static BOOL rw_torture(struct cli_state *c)
366 const char *lockfname = "\\torture.lck";
367 fstring fname;
368 int fnum;
369 int fnum2;
370 pid_t pid2, pid = getpid();
371 int i, j;
372 char buf[1024];
373 BOOL correct = True;
375 memset(buf, '\0', sizeof(buf));
377 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
378 DENY_NONE);
379 if (fnum2 == -1)
380 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
381 if (fnum2 == -1) {
382 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
383 return False;
387 for (i=0;i<torture_numops;i++) {
388 unsigned n = (unsigned)sys_random()%10;
389 if (i % 10 == 0) {
390 printf("%d\r", i); fflush(stdout);
392 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
394 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
395 return False;
398 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
399 if (fnum == -1) {
400 printf("open failed (%s)\n", cli_errstr(c));
401 correct = False;
402 break;
405 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
406 printf("write failed (%s)\n", cli_errstr(c));
407 correct = False;
410 for (j=0;j<50;j++) {
411 if (cli_write(c, fnum, 0, (char *)buf,
412 sizeof(pid)+(j*sizeof(buf)),
413 sizeof(buf)) != sizeof(buf)) {
414 printf("write failed (%s)\n", cli_errstr(c));
415 correct = False;
419 pid2 = 0;
421 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
422 printf("read failed (%s)\n", cli_errstr(c));
423 correct = False;
426 if (pid2 != pid) {
427 printf("data corruption!\n");
428 correct = False;
431 if (!cli_close(c, fnum)) {
432 printf("close failed (%s)\n", cli_errstr(c));
433 correct = False;
436 if (!cli_unlink(c, fname)) {
437 printf("unlink failed (%s)\n", cli_errstr(c));
438 correct = False;
441 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
442 printf("unlock failed (%s)\n", cli_errstr(c));
443 correct = False;
447 cli_close(c, fnum2);
448 cli_unlink(c, lockfname);
450 printf("%d\n", i);
452 return correct;
455 static BOOL run_torture(int dummy)
457 struct cli_state *cli;
458 BOOL ret;
460 cli = current_cli;
462 cli_sockopt(cli, sockops);
464 ret = rw_torture(cli);
466 if (!torture_close_connection(cli)) {
467 ret = False;
470 return ret;
473 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
475 int fnum = -1;
476 unsigned int i = 0;
477 char buf[131072];
478 char buf_rd[131072];
479 unsigned count;
480 unsigned countprev = 0;
481 ssize_t sent = 0;
482 BOOL correct = True;
484 srandom(1);
485 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
487 SIVAL(buf, i, sys_random());
490 if (procnum == 0)
492 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
493 DENY_NONE);
494 if (fnum == -1) {
495 printf("first open read/write of %s failed (%s)\n",
496 lockfname, cli_errstr(c));
497 return False;
500 else
502 for (i = 0; i < 500 && fnum == -1; i++)
504 fnum = cli_open(c, lockfname, O_RDONLY,
505 DENY_NONE);
506 smb_msleep(10);
508 if (fnum == -1) {
509 printf("second open read-only of %s failed (%s)\n",
510 lockfname, cli_errstr(c));
511 return False;
515 i = 0;
516 for (count = 0; count < sizeof(buf); count += sent)
518 if (count >= countprev) {
519 printf("%d %8d\r", i, count);
520 fflush(stdout);
521 i++;
522 countprev += (sizeof(buf) / 20);
525 if (procnum == 0)
527 sent = ((unsigned)sys_random()%(20))+ 1;
528 if (sent > sizeof(buf) - count)
530 sent = sizeof(buf) - count;
533 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
534 printf("write failed (%s)\n", cli_errstr(c));
535 correct = False;
538 else
540 sent = cli_read(c, fnum, buf_rd+count, count,
541 sizeof(buf)-count);
542 if (sent < 0)
544 printf("read failed offset:%d size:%ld (%s)\n",
545 count, (unsigned long)sizeof(buf)-count,
546 cli_errstr(c));
547 correct = False;
548 sent = 0;
550 if (sent > 0)
552 if (memcmp(buf_rd+count, buf+count, sent) != 0)
554 printf("read/write compare failed\n");
555 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
556 correct = False;
557 break;
564 if (!cli_close(c, fnum)) {
565 printf("close failed (%s)\n", cli_errstr(c));
566 correct = False;
569 return correct;
572 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
574 const char *lockfname = "\\torture2.lck";
575 int fnum1;
576 int fnum2;
577 int i;
578 char buf[131072];
579 char buf_rd[131072];
580 BOOL correct = True;
581 ssize_t bytes_read;
583 if (!cli_unlink(c1, lockfname)) {
584 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
587 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
588 DENY_NONE);
589 if (fnum1 == -1) {
590 printf("first open read/write of %s failed (%s)\n",
591 lockfname, cli_errstr(c1));
592 return False;
594 fnum2 = cli_open(c2, lockfname, O_RDONLY,
595 DENY_NONE);
596 if (fnum2 == -1) {
597 printf("second open read-only of %s failed (%s)\n",
598 lockfname, cli_errstr(c2));
599 cli_close(c1, fnum1);
600 return False;
603 for (i=0;i<torture_numops;i++)
605 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
606 if (i % 10 == 0) {
607 printf("%d\r", i); fflush(stdout);
610 generate_random_buffer((unsigned char *)buf, buf_size);
612 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
613 printf("write failed (%s)\n", cli_errstr(c1));
614 correct = False;
615 break;
618 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
619 printf("read failed (%s)\n", cli_errstr(c2));
620 printf("read %d, expected %ld\n", (int)bytes_read,
621 (unsigned long)buf_size);
622 correct = False;
623 break;
626 if (memcmp(buf_rd, buf, buf_size) != 0)
628 printf("read/write compare failed\n");
629 correct = False;
630 break;
634 if (!cli_close(c2, fnum2)) {
635 printf("close failed (%s)\n", cli_errstr(c2));
636 correct = False;
638 if (!cli_close(c1, fnum1)) {
639 printf("close failed (%s)\n", cli_errstr(c1));
640 correct = False;
643 if (!cli_unlink(c1, lockfname)) {
644 printf("unlink failed (%s)\n", cli_errstr(c1));
645 correct = False;
648 return correct;
651 static BOOL run_readwritetest(int dummy)
653 static struct cli_state *cli1, *cli2;
654 BOOL test1, test2 = False;
656 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
657 return False;
659 cli_sockopt(cli1, sockops);
660 cli_sockopt(cli2, sockops);
662 printf("starting readwritetest\n");
664 test1 = rw_torture2(cli1, cli2);
665 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
667 if (test1) {
668 test2 = rw_torture2(cli1, cli1);
669 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
672 if (!torture_close_connection(cli1)) {
673 test1 = False;
676 if (!torture_close_connection(cli2)) {
677 test2 = False;
680 return (test1 && test2);
683 static BOOL run_readwritemulti(int dummy)
685 struct cli_state *cli;
686 BOOL test;
688 cli = current_cli;
690 cli_sockopt(cli, sockops);
692 printf("run_readwritemulti: fname %s\n", randomfname);
693 test = rw_torture3(cli, randomfname);
695 if (!torture_close_connection(cli)) {
696 test = False;
699 return test;
702 static BOOL run_readwritelarge(int dummy)
704 static struct cli_state *cli1;
705 int fnum1;
706 const char *lockfname = "\\large.dat";
707 SMB_OFF_T fsize;
708 char buf[126*1024];
709 BOOL correct = True;
711 if (!torture_open_connection(&cli1, 0)) {
712 return False;
714 cli_sockopt(cli1, sockops);
715 memset(buf,'\0',sizeof(buf));
717 cli1->max_xmit = 128*1024;
719 printf("starting readwritelarge\n");
721 cli_unlink(cli1, lockfname);
723 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
724 if (fnum1 == -1) {
725 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
726 return False;
729 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
731 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
732 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
733 correct = False;
736 if (fsize == sizeof(buf))
737 printf("readwritelarge test 1 succeeded (size = %lx)\n",
738 (unsigned long)fsize);
739 else {
740 printf("readwritelarge test 1 failed (size = %lx)\n",
741 (unsigned long)fsize);
742 correct = False;
745 if (!cli_close(cli1, fnum1)) {
746 printf("close failed (%s)\n", cli_errstr(cli1));
747 correct = False;
750 if (!cli_unlink(cli1, lockfname)) {
751 printf("unlink failed (%s)\n", cli_errstr(cli1));
752 correct = False;
755 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
756 if (fnum1 == -1) {
757 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
758 return False;
761 cli1->max_xmit = 4*1024;
763 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
765 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
766 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
767 correct = False;
770 if (fsize == sizeof(buf))
771 printf("readwritelarge test 2 succeeded (size = %lx)\n",
772 (unsigned long)fsize);
773 else {
774 printf("readwritelarge test 2 failed (size = %lx)\n",
775 (unsigned long)fsize);
776 correct = False;
779 #if 0
780 /* ToDo - set allocation. JRA */
781 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
782 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
783 return False;
785 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
786 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
787 correct = False;
789 if (fsize != 0)
790 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
791 #endif
793 if (!cli_close(cli1, fnum1)) {
794 printf("close failed (%s)\n", cli_errstr(cli1));
795 correct = False;
798 if (!torture_close_connection(cli1)) {
799 correct = False;
801 return correct;
804 int line_count = 0;
805 int nbio_id;
807 #define ival(s) strtol(s, NULL, 0)
809 /* run a test that simulates an approximate netbench client load */
810 static BOOL run_netbench(int client)
812 struct cli_state *cli;
813 int i;
814 pstring line;
815 char cname[20];
816 FILE *f;
817 const char *params[20];
818 BOOL correct = True;
820 cli = current_cli;
822 nbio_id = client;
824 cli_sockopt(cli, sockops);
826 nb_setup(cli);
828 slprintf(cname,sizeof(cname)-1, "client%d", client);
830 f = fopen(client_txt, "r");
832 if (!f) {
833 perror(client_txt);
834 return False;
837 while (fgets(line, sizeof(line)-1, f)) {
838 line_count++;
840 line[strlen(line)-1] = 0;
842 /* printf("[%d] %s\n", line_count, line); */
844 all_string_sub(line,"client1", cname, sizeof(line));
846 /* parse the command parameters */
847 params[0] = strtok(line," ");
848 i = 0;
849 while (params[i]) params[++i] = strtok(NULL," ");
851 params[i] = "";
853 if (i < 2) continue;
855 if (!strncmp(params[0],"SMB", 3)) {
856 printf("ERROR: You are using a dbench 1 load file\n");
857 exit(1);
860 if (!strcmp(params[0],"NTCreateX")) {
861 nb_createx(params[1], ival(params[2]), ival(params[3]),
862 ival(params[4]));
863 } else if (!strcmp(params[0],"Close")) {
864 nb_close(ival(params[1]));
865 } else if (!strcmp(params[0],"Rename")) {
866 nb_rename(params[1], params[2]);
867 } else if (!strcmp(params[0],"Unlink")) {
868 nb_unlink(params[1]);
869 } else if (!strcmp(params[0],"Deltree")) {
870 nb_deltree(params[1]);
871 } else if (!strcmp(params[0],"Rmdir")) {
872 nb_rmdir(params[1]);
873 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
874 nb_qpathinfo(params[1]);
875 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
876 nb_qfileinfo(ival(params[1]));
877 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
878 nb_qfsinfo(ival(params[1]));
879 } else if (!strcmp(params[0],"FIND_FIRST")) {
880 nb_findfirst(params[1]);
881 } else if (!strcmp(params[0],"WriteX")) {
882 nb_writex(ival(params[1]),
883 ival(params[2]), ival(params[3]), ival(params[4]));
884 } else if (!strcmp(params[0],"ReadX")) {
885 nb_readx(ival(params[1]),
886 ival(params[2]), ival(params[3]), ival(params[4]));
887 } else if (!strcmp(params[0],"Flush")) {
888 nb_flush(ival(params[1]));
889 } else {
890 printf("Unknown operation %s\n", params[0]);
891 exit(1);
894 fclose(f);
896 nb_cleanup();
898 if (!torture_close_connection(cli)) {
899 correct = False;
902 return correct;
906 /* run a test that simulates an approximate netbench client load */
907 static BOOL run_nbench(int dummy)
909 double t;
910 BOOL correct = True;
912 nbio_shmem(nprocs);
914 nbio_id = -1;
916 signal(SIGALRM, nb_alarm);
917 alarm(1);
918 t = create_procs(run_netbench, &correct);
919 alarm(0);
921 printf("\nThroughput %g MB/sec\n",
922 1.0e-6 * nbio_total() / t);
923 return correct;
928 This test checks for two things:
930 1) correct support for retaining locks over a close (ie. the server
931 must not use posix semantics)
932 2) support for lock timeouts
934 static BOOL run_locktest1(int dummy)
936 struct cli_state *cli1, *cli2;
937 const char *fname = "\\lockt1.lck";
938 int fnum1, fnum2, fnum3;
939 time_t t1, t2;
940 unsigned lock_timeout;
942 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
943 return False;
945 cli_sockopt(cli1, sockops);
946 cli_sockopt(cli2, sockops);
948 printf("starting locktest1\n");
950 cli_unlink(cli1, fname);
952 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
953 if (fnum1 == -1) {
954 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
955 return False;
957 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
958 if (fnum2 == -1) {
959 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
960 return False;
962 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
963 if (fnum3 == -1) {
964 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
965 return False;
968 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
969 printf("lock1 failed (%s)\n", cli_errstr(cli1));
970 return False;
974 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
975 printf("lock2 succeeded! This is a locking bug\n");
976 return False;
977 } else {
978 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
979 NT_STATUS_LOCK_NOT_GRANTED)) return False;
983 lock_timeout = (1 + (random() % 20));
984 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
985 t1 = time(NULL);
986 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
987 printf("lock3 succeeded! This is a locking bug\n");
988 return False;
989 } else {
990 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
991 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
993 t2 = time(NULL);
995 if (ABS(t2 - t1) < lock_timeout-1) {
996 printf("error: This server appears not to support timed lock requests\n");
999 printf("server slept for %u seconds for a %u second timeout\n",
1000 (unsigned int)(t2-t1), lock_timeout);
1002 if (!cli_close(cli1, fnum2)) {
1003 printf("close1 failed (%s)\n", cli_errstr(cli1));
1004 return False;
1007 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1008 printf("lock4 succeeded! This is a locking bug\n");
1009 return False;
1010 } else {
1011 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1012 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1015 if (!cli_close(cli1, fnum1)) {
1016 printf("close2 failed (%s)\n", cli_errstr(cli1));
1017 return False;
1020 if (!cli_close(cli2, fnum3)) {
1021 printf("close3 failed (%s)\n", cli_errstr(cli2));
1022 return False;
1025 if (!cli_unlink(cli1, fname)) {
1026 printf("unlink failed (%s)\n", cli_errstr(cli1));
1027 return False;
1031 if (!torture_close_connection(cli1)) {
1032 return False;
1035 if (!torture_close_connection(cli2)) {
1036 return False;
1039 printf("Passed locktest1\n");
1040 return True;
1044 this checks to see if a secondary tconx can use open files from an
1045 earlier tconx
1047 static BOOL run_tcon_test(int dummy)
1049 static struct cli_state *cli;
1050 const char *fname = "\\tcontest.tmp";
1051 int fnum1;
1052 uint16 cnum1, cnum2, cnum3;
1053 uint16 vuid1, vuid2;
1054 char buf[4];
1055 BOOL ret = True;
1057 memset(buf, '\0', sizeof(buf));
1059 if (!torture_open_connection(&cli, 0)) {
1060 return False;
1062 cli_sockopt(cli, sockops);
1064 printf("starting tcontest\n");
1066 cli_unlink(cli, fname);
1068 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1069 if (fnum1 == -1) {
1070 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1071 return False;
1074 cnum1 = cli->cnum;
1075 vuid1 = cli->vuid;
1077 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1078 printf("initial write failed (%s)", cli_errstr(cli));
1079 return False;
1082 if (!cli_send_tconX(cli, share, "?????",
1083 password, strlen(password)+1)) {
1084 printf("%s refused 2nd tree connect (%s)\n", host,
1085 cli_errstr(cli));
1086 cli_shutdown(cli);
1087 return False;
1090 cnum2 = cli->cnum;
1091 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1092 vuid2 = cli->vuid + 1;
1094 /* try a write with the wrong tid */
1095 cli->cnum = cnum2;
1097 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1098 printf("* server allows write with wrong TID\n");
1099 ret = False;
1100 } else {
1101 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1105 /* try a write with an invalid tid */
1106 cli->cnum = cnum3;
1108 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1109 printf("* server allows write with invalid TID\n");
1110 ret = False;
1111 } else {
1112 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1115 /* try a write with an invalid vuid */
1116 cli->vuid = vuid2;
1117 cli->cnum = cnum1;
1119 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1120 printf("* server allows write with invalid VUID\n");
1121 ret = False;
1122 } else {
1123 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1126 cli->cnum = cnum1;
1127 cli->vuid = vuid1;
1129 if (!cli_close(cli, fnum1)) {
1130 printf("close failed (%s)\n", cli_errstr(cli));
1131 return False;
1134 cli->cnum = cnum2;
1136 if (!cli_tdis(cli)) {
1137 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1138 return False;
1141 cli->cnum = cnum1;
1143 if (!torture_close_connection(cli)) {
1144 return False;
1147 return ret;
1152 checks for old style tcon support
1154 static BOOL run_tcon2_test(int dummy)
1156 static struct cli_state *cli;
1157 uint16 cnum, max_xmit;
1158 char *service;
1159 NTSTATUS status;
1161 if (!torture_open_connection(&cli, 0)) {
1162 return False;
1164 cli_sockopt(cli, sockops);
1166 printf("starting tcon2 test\n");
1168 asprintf(&service, "\\\\%s\\%s", host, share);
1170 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1172 if (!NT_STATUS_IS_OK(status)) {
1173 printf("tcon2 failed : %s\n", cli_errstr(cli));
1174 } else {
1175 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1176 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1179 if (!torture_close_connection(cli)) {
1180 return False;
1183 printf("Passed tcon2 test\n");
1184 return True;
1187 static BOOL tcon_devtest(struct cli_state *cli,
1188 const char *myshare, const char *devtype,
1189 const char *return_devtype,
1190 NTSTATUS expected_error)
1192 BOOL status;
1193 BOOL ret;
1195 status = cli_send_tconX(cli, myshare, devtype,
1196 password, strlen(password)+1);
1198 if (NT_STATUS_IS_OK(expected_error)) {
1199 if (status) {
1200 if (strcmp(cli->dev, return_devtype) == 0) {
1201 ret = True;
1202 } else {
1203 printf("tconX to share %s with type %s "
1204 "succeeded but returned the wrong "
1205 "device type (got [%s] but should have got [%s])\n",
1206 myshare, devtype, cli->dev, return_devtype);
1207 ret = False;
1209 } else {
1210 printf("tconX to share %s with type %s "
1211 "should have succeeded but failed\n",
1212 myshare, devtype);
1213 ret = False;
1215 cli_tdis(cli);
1216 } else {
1217 if (status) {
1218 printf("tconx to share %s with type %s "
1219 "should have failed but succeeded\n",
1220 myshare, devtype);
1221 ret = False;
1222 } else {
1223 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1224 expected_error)) {
1225 ret = True;
1226 } else {
1227 printf("Returned unexpected error\n");
1228 ret = False;
1232 return ret;
1236 checks for correct tconX support
1238 static BOOL run_tcon_devtype_test(int dummy)
1240 static struct cli_state *cli1 = NULL;
1241 BOOL retry;
1242 int flags = 0;
1243 NTSTATUS status;
1244 BOOL ret = True;
1246 status = cli_full_connection(&cli1, myname,
1247 host, NULL, port_to_use,
1248 NULL, NULL,
1249 username, workgroup,
1250 password, flags, Undefined, &retry);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 printf("could not open connection\n");
1254 return False;
1257 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1258 ret = False;
1260 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1261 ret = False;
1263 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1264 ret = False;
1266 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1267 ret = False;
1269 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1270 ret = False;
1272 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1273 ret = False;
1275 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1276 ret = False;
1278 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1279 ret = False;
1281 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1282 ret = False;
1284 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1285 ret = False;
1287 cli_shutdown(cli1);
1289 if (ret)
1290 printf("Passed tcondevtest\n");
1292 return ret;
1297 This test checks that
1299 1) the server supports multiple locking contexts on the one SMB
1300 connection, distinguished by PID.
1302 2) the server correctly fails overlapping locks made by the same PID (this
1303 goes against POSIX behaviour, which is why it is tricky to implement)
1305 3) the server denies unlock requests by an incorrect client PID
1307 static BOOL run_locktest2(int dummy)
1309 static struct cli_state *cli;
1310 const char *fname = "\\lockt2.lck";
1311 int fnum1, fnum2, fnum3;
1312 BOOL correct = True;
1314 if (!torture_open_connection(&cli, 0)) {
1315 return False;
1318 cli_sockopt(cli, sockops);
1320 printf("starting locktest2\n");
1322 cli_unlink(cli, fname);
1324 cli_setpid(cli, 1);
1326 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1327 if (fnum1 == -1) {
1328 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1329 return False;
1332 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1333 if (fnum2 == -1) {
1334 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1335 return False;
1338 cli_setpid(cli, 2);
1340 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1341 if (fnum3 == -1) {
1342 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1343 return False;
1346 cli_setpid(cli, 1);
1348 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1349 printf("lock1 failed (%s)\n", cli_errstr(cli));
1350 return False;
1353 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1354 printf("WRITE lock1 succeeded! This is a locking bug\n");
1355 correct = False;
1356 } else {
1357 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1358 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1361 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1362 printf("WRITE lock2 succeeded! This is a locking bug\n");
1363 correct = False;
1364 } else {
1365 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1366 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1369 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1370 printf("READ lock2 succeeded! This is a locking bug\n");
1371 correct = False;
1372 } else {
1373 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1374 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1377 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1378 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1380 cli_setpid(cli, 2);
1381 if (cli_unlock(cli, fnum1, 100, 4)) {
1382 printf("unlock at 100 succeeded! This is a locking bug\n");
1383 correct = False;
1386 if (cli_unlock(cli, fnum1, 0, 4)) {
1387 printf("unlock1 succeeded! This is a locking bug\n");
1388 correct = False;
1389 } else {
1390 if (!check_error(__LINE__, cli,
1391 ERRDOS, ERRlock,
1392 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1395 if (cli_unlock(cli, fnum1, 0, 8)) {
1396 printf("unlock2 succeeded! This is a locking bug\n");
1397 correct = False;
1398 } else {
1399 if (!check_error(__LINE__, cli,
1400 ERRDOS, ERRlock,
1401 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1404 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1405 printf("lock3 succeeded! This is a locking bug\n");
1406 correct = False;
1407 } else {
1408 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1411 cli_setpid(cli, 1);
1413 if (!cli_close(cli, fnum1)) {
1414 printf("close1 failed (%s)\n", cli_errstr(cli));
1415 return False;
1418 if (!cli_close(cli, fnum2)) {
1419 printf("close2 failed (%s)\n", cli_errstr(cli));
1420 return False;
1423 if (!cli_close(cli, fnum3)) {
1424 printf("close3 failed (%s)\n", cli_errstr(cli));
1425 return False;
1428 if (!torture_close_connection(cli)) {
1429 correct = False;
1432 printf("locktest2 finished\n");
1434 return correct;
1439 This test checks that
1441 1) the server supports the full offset range in lock requests
1443 static BOOL run_locktest3(int dummy)
1445 static struct cli_state *cli1, *cli2;
1446 const char *fname = "\\lockt3.lck";
1447 int fnum1, fnum2, i;
1448 uint32 offset;
1449 BOOL correct = True;
1451 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1453 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1454 return False;
1456 cli_sockopt(cli1, sockops);
1457 cli_sockopt(cli2, sockops);
1459 printf("starting locktest3\n");
1461 cli_unlink(cli1, fname);
1463 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1464 if (fnum1 == -1) {
1465 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1466 return False;
1468 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1469 if (fnum2 == -1) {
1470 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1471 return False;
1474 for (offset=i=0;i<torture_numops;i++) {
1475 NEXT_OFFSET;
1476 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1477 printf("lock1 %d failed (%s)\n",
1479 cli_errstr(cli1));
1480 return False;
1483 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1484 printf("lock2 %d failed (%s)\n",
1486 cli_errstr(cli1));
1487 return False;
1491 for (offset=i=0;i<torture_numops;i++) {
1492 NEXT_OFFSET;
1494 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1495 printf("error: lock1 %d succeeded!\n", i);
1496 return False;
1499 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1500 printf("error: lock2 %d succeeded!\n", i);
1501 return False;
1504 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1505 printf("error: lock3 %d succeeded!\n", i);
1506 return False;
1509 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1510 printf("error: lock4 %d succeeded!\n", i);
1511 return False;
1515 for (offset=i=0;i<torture_numops;i++) {
1516 NEXT_OFFSET;
1518 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1519 printf("unlock1 %d failed (%s)\n",
1521 cli_errstr(cli1));
1522 return False;
1525 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1526 printf("unlock2 %d failed (%s)\n",
1528 cli_errstr(cli1));
1529 return False;
1533 if (!cli_close(cli1, fnum1)) {
1534 printf("close1 failed (%s)\n", cli_errstr(cli1));
1535 return False;
1538 if (!cli_close(cli2, fnum2)) {
1539 printf("close2 failed (%s)\n", cli_errstr(cli2));
1540 return False;
1543 if (!cli_unlink(cli1, fname)) {
1544 printf("unlink failed (%s)\n", cli_errstr(cli1));
1545 return False;
1548 if (!torture_close_connection(cli1)) {
1549 correct = False;
1552 if (!torture_close_connection(cli2)) {
1553 correct = False;
1556 printf("finished locktest3\n");
1558 return correct;
1561 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1562 printf("** "); correct = False; \
1566 looks at overlapping locks
1568 static BOOL run_locktest4(int dummy)
1570 static struct cli_state *cli1, *cli2;
1571 const char *fname = "\\lockt4.lck";
1572 int fnum1, fnum2, f;
1573 BOOL ret;
1574 char buf[1000];
1575 BOOL correct = True;
1577 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1578 return False;
1581 cli_sockopt(cli1, sockops);
1582 cli_sockopt(cli2, sockops);
1584 printf("starting locktest4\n");
1586 cli_unlink(cli1, fname);
1588 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1589 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1591 memset(buf, 0, sizeof(buf));
1593 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1594 printf("Failed to create file\n");
1595 correct = False;
1596 goto fail;
1599 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1600 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1601 EXPECTED(ret, False);
1602 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1604 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1605 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1606 EXPECTED(ret, True);
1607 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1609 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1610 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1611 EXPECTED(ret, False);
1612 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1614 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1615 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1616 EXPECTED(ret, True);
1617 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1619 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1620 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1621 EXPECTED(ret, False);
1622 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1624 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1625 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1626 EXPECTED(ret, True);
1627 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1629 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1630 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1631 EXPECTED(ret, True);
1632 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1634 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1635 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1636 EXPECTED(ret, False);
1637 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1639 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1640 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1641 EXPECTED(ret, False);
1642 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1644 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1645 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1646 EXPECTED(ret, True);
1647 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1649 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1650 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1651 EXPECTED(ret, False);
1652 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1654 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1655 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1656 cli_unlock(cli1, fnum1, 110, 6);
1657 EXPECTED(ret, False);
1658 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1661 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1662 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1663 EXPECTED(ret, False);
1664 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1666 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1667 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1668 EXPECTED(ret, False);
1669 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1672 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1673 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1674 cli_unlock(cli1, fnum1, 140, 4) &&
1675 cli_unlock(cli1, fnum1, 140, 4);
1676 EXPECTED(ret, True);
1677 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1680 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1681 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1682 cli_unlock(cli1, fnum1, 150, 4) &&
1683 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1684 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1685 cli_unlock(cli1, fnum1, 150, 4);
1686 EXPECTED(ret, True);
1687 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1689 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1690 cli_unlock(cli1, fnum1, 160, 4) &&
1691 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1692 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1693 EXPECTED(ret, True);
1694 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1696 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1697 cli_unlock(cli1, fnum1, 170, 4) &&
1698 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1699 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1700 EXPECTED(ret, True);
1701 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1703 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1704 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1705 cli_unlock(cli1, fnum1, 190, 4) &&
1706 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1707 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1708 EXPECTED(ret, True);
1709 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1711 cli_close(cli1, fnum1);
1712 cli_close(cli2, fnum2);
1713 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1714 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1715 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1716 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1717 cli_close(cli1, fnum1) &&
1718 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1719 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1720 cli_close(cli1, f);
1721 cli_close(cli1, fnum1);
1722 EXPECTED(ret, True);
1723 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1725 fail:
1726 cli_close(cli1, fnum1);
1727 cli_close(cli2, fnum2);
1728 cli_unlink(cli1, fname);
1729 torture_close_connection(cli1);
1730 torture_close_connection(cli2);
1732 printf("finished locktest4\n");
1733 return correct;
1737 looks at lock upgrade/downgrade.
1739 static BOOL run_locktest5(int dummy)
1741 static struct cli_state *cli1, *cli2;
1742 const char *fname = "\\lockt5.lck";
1743 int fnum1, fnum2, fnum3;
1744 BOOL ret;
1745 char buf[1000];
1746 BOOL correct = True;
1748 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1749 return False;
1752 cli_sockopt(cli1, sockops);
1753 cli_sockopt(cli2, sockops);
1755 printf("starting locktest5\n");
1757 cli_unlink(cli1, fname);
1759 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1760 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1761 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1763 memset(buf, 0, sizeof(buf));
1765 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1766 printf("Failed to create file\n");
1767 correct = False;
1768 goto fail;
1771 /* Check for NT bug... */
1772 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1773 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1774 cli_close(cli1, fnum1);
1775 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1776 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1777 EXPECTED(ret, True);
1778 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1779 cli_close(cli1, fnum1);
1780 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1781 cli_unlock(cli1, fnum3, 0, 1);
1783 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1784 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1785 EXPECTED(ret, True);
1786 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1788 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1789 EXPECTED(ret, False);
1791 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1793 /* Unlock the process 2 lock. */
1794 cli_unlock(cli2, fnum2, 0, 4);
1796 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1797 EXPECTED(ret, False);
1799 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1801 /* Unlock the process 1 fnum3 lock. */
1802 cli_unlock(cli1, fnum3, 0, 4);
1804 /* Stack 2 more locks here. */
1805 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1806 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1808 EXPECTED(ret, True);
1809 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1811 /* Unlock the first process lock, then check this was the WRITE lock that was
1812 removed. */
1814 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1815 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1817 EXPECTED(ret, True);
1818 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1820 /* Unlock the process 2 lock. */
1821 cli_unlock(cli2, fnum2, 0, 4);
1823 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1825 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1826 cli_unlock(cli1, fnum1, 0, 4) &&
1827 cli_unlock(cli1, fnum1, 0, 4);
1829 EXPECTED(ret, True);
1830 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1832 /* Ensure the next unlock fails. */
1833 ret = cli_unlock(cli1, fnum1, 0, 4);
1834 EXPECTED(ret, False);
1835 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1837 /* Ensure connection 2 can get a write lock. */
1838 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1839 EXPECTED(ret, True);
1841 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1844 fail:
1845 cli_close(cli1, fnum1);
1846 cli_close(cli2, fnum2);
1847 cli_unlink(cli1, fname);
1848 if (!torture_close_connection(cli1)) {
1849 correct = False;
1851 if (!torture_close_connection(cli2)) {
1852 correct = False;
1855 printf("finished locktest5\n");
1857 return correct;
1861 tries the unusual lockingX locktype bits
1863 static BOOL run_locktest6(int dummy)
1865 static struct cli_state *cli;
1866 const char *fname[1] = { "\\lock6.txt" };
1867 int i;
1868 int fnum;
1869 NTSTATUS status;
1871 if (!torture_open_connection(&cli, 0)) {
1872 return False;
1875 cli_sockopt(cli, sockops);
1877 printf("starting locktest6\n");
1879 for (i=0;i<1;i++) {
1880 printf("Testing %s\n", fname[i]);
1882 cli_unlink(cli, fname[i]);
1884 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1885 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1886 cli_close(cli, fnum);
1887 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1889 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1890 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1891 cli_close(cli, fnum);
1892 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1894 cli_unlink(cli, fname[i]);
1897 torture_close_connection(cli);
1899 printf("finished locktest6\n");
1900 return True;
1903 static BOOL run_locktest7(int dummy)
1905 struct cli_state *cli1;
1906 const char *fname = "\\lockt7.lck";
1907 int fnum1;
1908 char buf[200];
1909 BOOL correct = False;
1911 if (!torture_open_connection(&cli1, 0)) {
1912 return False;
1915 cli_sockopt(cli1, sockops);
1917 printf("starting locktest7\n");
1919 cli_unlink(cli1, fname);
1921 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1923 memset(buf, 0, sizeof(buf));
1925 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1926 printf("Failed to create file\n");
1927 goto fail;
1930 cli_setpid(cli1, 1);
1932 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1933 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1934 goto fail;
1935 } else {
1936 printf("pid1 successfully locked range 130:4 for READ\n");
1939 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1940 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1941 goto fail;
1942 } else {
1943 printf("pid1 successfully read the range 130:4\n");
1946 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1947 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1948 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1949 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1950 goto fail;
1952 } else {
1953 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1954 goto fail;
1957 cli_setpid(cli1, 2);
1959 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1960 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1961 } else {
1962 printf("pid2 successfully read the range 130:4\n");
1965 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1966 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1967 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1968 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1969 goto fail;
1971 } else {
1972 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1973 goto fail;
1976 cli_setpid(cli1, 1);
1977 cli_unlock(cli1, fnum1, 130, 4);
1979 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1980 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1981 goto fail;
1982 } else {
1983 printf("pid1 successfully locked range 130:4 for WRITE\n");
1986 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1987 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1988 goto fail;
1989 } else {
1990 printf("pid1 successfully read the range 130:4\n");
1993 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1994 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1995 goto fail;
1996 } else {
1997 printf("pid1 successfully wrote to the range 130:4\n");
2000 cli_setpid(cli1, 2);
2002 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2003 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2004 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2005 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2006 goto fail;
2008 } else {
2009 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2010 goto fail;
2013 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2014 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2015 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2016 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2017 goto fail;
2019 } else {
2020 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2021 goto fail;
2024 cli_unlock(cli1, fnum1, 130, 0);
2025 correct = True;
2027 fail:
2028 cli_close(cli1, fnum1);
2029 cli_unlink(cli1, fname);
2030 torture_close_connection(cli1);
2032 printf("finished locktest7\n");
2033 return correct;
2037 test whether fnums and tids open on one VC are available on another (a major
2038 security hole)
2040 static BOOL run_fdpasstest(int dummy)
2042 struct cli_state *cli1, *cli2;
2043 const char *fname = "\\fdpass.tst";
2044 int fnum1;
2045 pstring buf;
2047 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2048 return False;
2050 cli_sockopt(cli1, sockops);
2051 cli_sockopt(cli2, sockops);
2053 printf("starting fdpasstest\n");
2055 cli_unlink(cli1, fname);
2057 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2058 if (fnum1 == -1) {
2059 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2060 return False;
2063 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2064 printf("write failed (%s)\n", cli_errstr(cli1));
2065 return False;
2068 cli2->vuid = cli1->vuid;
2069 cli2->cnum = cli1->cnum;
2070 cli2->pid = cli1->pid;
2072 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2073 printf("read succeeded! nasty security hole [%s]\n",
2074 buf);
2075 return False;
2078 cli_close(cli1, fnum1);
2079 cli_unlink(cli1, fname);
2081 torture_close_connection(cli1);
2082 torture_close_connection(cli2);
2084 printf("finished fdpasstest\n");
2085 return True;
2088 static BOOL run_fdsesstest(int dummy)
2090 struct cli_state *cli;
2091 uint16 new_vuid;
2092 uint16 saved_vuid;
2093 uint16 new_cnum;
2094 uint16 saved_cnum;
2095 const char *fname = "\\fdsess.tst";
2096 const char *fname1 = "\\fdsess1.tst";
2097 int fnum1;
2098 int fnum2;
2099 pstring buf;
2100 BOOL ret = True;
2102 if (!torture_open_connection(&cli, 0))
2103 return False;
2104 cli_sockopt(cli, sockops);
2106 if (!torture_cli_session_setup2(cli, &new_vuid))
2107 return False;
2109 saved_cnum = cli->cnum;
2110 if (!cli_send_tconX(cli, share, "?????", "", 1))
2111 return False;
2112 new_cnum = cli->cnum;
2113 cli->cnum = saved_cnum;
2115 printf("starting fdsesstest\n");
2117 cli_unlink(cli, fname);
2118 cli_unlink(cli, fname1);
2120 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2121 if (fnum1 == -1) {
2122 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2123 return False;
2126 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2127 printf("write failed (%s)\n", cli_errstr(cli));
2128 return False;
2131 saved_vuid = cli->vuid;
2132 cli->vuid = new_vuid;
2134 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2135 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2136 buf);
2137 ret = False;
2139 /* Try to open a file with different vuid, samba cnum. */
2140 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2141 if (fnum2 != -1) {
2142 printf("create with different vuid, same cnum succeeded.\n");
2143 cli_close(cli, fnum2);
2144 cli_unlink(cli, fname1);
2145 } else {
2146 printf("create with different vuid, same cnum failed.\n");
2147 printf("This will cause problems with service clients.\n");
2148 ret = False;
2151 cli->vuid = saved_vuid;
2153 /* Try with same vuid, different cnum. */
2154 cli->cnum = new_cnum;
2156 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2157 printf("read succeeded with different cnum![%s]\n",
2158 buf);
2159 ret = False;
2162 cli->cnum = saved_cnum;
2163 cli_close(cli, fnum1);
2164 cli_unlink(cli, fname);
2166 torture_close_connection(cli);
2168 printf("finished fdsesstest\n");
2169 return ret;
2173 This test checks that
2175 1) the server does not allow an unlink on a file that is open
2177 static BOOL run_unlinktest(int dummy)
2179 struct cli_state *cli;
2180 const char *fname = "\\unlink.tst";
2181 int fnum;
2182 BOOL correct = True;
2184 if (!torture_open_connection(&cli, 0)) {
2185 return False;
2188 cli_sockopt(cli, sockops);
2190 printf("starting unlink test\n");
2192 cli_unlink(cli, fname);
2194 cli_setpid(cli, 1);
2196 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2197 if (fnum == -1) {
2198 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2199 return False;
2202 if (cli_unlink(cli, fname)) {
2203 printf("error: server allowed unlink on an open file\n");
2204 correct = False;
2205 } else {
2206 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2207 NT_STATUS_SHARING_VIOLATION);
2210 cli_close(cli, fnum);
2211 cli_unlink(cli, fname);
2213 if (!torture_close_connection(cli)) {
2214 correct = False;
2217 printf("unlink test finished\n");
2219 return correct;
2224 test how many open files this server supports on the one socket
2226 static BOOL run_maxfidtest(int dummy)
2228 struct cli_state *cli;
2229 const char *ftemplate = "\\maxfid.%d.%d";
2230 fstring fname;
2231 int fnums[0x11000], i;
2232 int retries=4;
2233 BOOL correct = True;
2235 cli = current_cli;
2237 if (retries <= 0) {
2238 printf("failed to connect\n");
2239 return False;
2242 cli_sockopt(cli, sockops);
2244 for (i=0; i<0x11000; i++) {
2245 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2246 if ((fnums[i] = cli_open(cli, fname,
2247 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2248 -1) {
2249 printf("open of %s failed (%s)\n",
2250 fname, cli_errstr(cli));
2251 printf("maximum fnum is %d\n", i);
2252 break;
2254 printf("%6d\r", i);
2256 printf("%6d\n", i);
2257 i--;
2259 printf("cleaning up\n");
2260 for (;i>=0;i--) {
2261 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2262 cli_close(cli, fnums[i]);
2263 if (!cli_unlink(cli, fname)) {
2264 printf("unlink of %s failed (%s)\n",
2265 fname, cli_errstr(cli));
2266 correct = False;
2268 printf("%6d\r", i);
2270 printf("%6d\n", 0);
2272 printf("maxfid test finished\n");
2273 if (!torture_close_connection(cli)) {
2274 correct = False;
2276 return correct;
2279 /* generate a random buffer */
2280 static void rand_buf(char *buf, int len)
2282 while (len--) {
2283 *buf = (char)sys_random();
2284 buf++;
2288 /* send smb negprot commands, not reading the response */
2289 static BOOL run_negprot_nowait(int dummy)
2291 int i;
2292 static struct cli_state *cli;
2293 BOOL correct = True;
2295 printf("starting negprot nowait test\n");
2297 if (!(cli = open_nbt_connection())) {
2298 return False;
2301 for (i=0;i<50000;i++) {
2302 cli_negprot_send(cli);
2305 if (!torture_close_connection(cli)) {
2306 correct = False;
2309 printf("finished negprot nowait test\n");
2311 return correct;
2315 /* send random IPC commands */
2316 static BOOL run_randomipc(int dummy)
2318 char *rparam = NULL;
2319 char *rdata = NULL;
2320 unsigned int rdrcnt,rprcnt;
2321 pstring param;
2322 int api, param_len, i;
2323 struct cli_state *cli;
2324 BOOL correct = True;
2325 int count = 50000;
2327 printf("starting random ipc test\n");
2329 if (!torture_open_connection(&cli, 0)) {
2330 return False;
2333 for (i=0;i<count;i++) {
2334 api = sys_random() % 500;
2335 param_len = (sys_random() % 64);
2337 rand_buf(param, param_len);
2339 SSVAL(param,0,api);
2341 cli_api(cli,
2342 param, param_len, 8,
2343 NULL, 0, BUFFER_SIZE,
2344 &rparam, &rprcnt,
2345 &rdata, &rdrcnt);
2346 if (i % 100 == 0) {
2347 printf("%d/%d\r", i,count);
2350 printf("%d/%d\n", i, count);
2352 if (!torture_close_connection(cli)) {
2353 correct = False;
2356 printf("finished random ipc test\n");
2358 return correct;
2363 static void browse_callback(const char *sname, uint32 stype,
2364 const char *comment, void *state)
2366 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2372 This test checks the browse list code
2375 static BOOL run_browsetest(int dummy)
2377 static struct cli_state *cli;
2378 BOOL correct = True;
2380 printf("starting browse test\n");
2382 if (!torture_open_connection(&cli, 0)) {
2383 return False;
2386 printf("domain list:\n");
2387 cli_NetServerEnum(cli, cli->server_domain,
2388 SV_TYPE_DOMAIN_ENUM,
2389 browse_callback, NULL);
2391 printf("machine list:\n");
2392 cli_NetServerEnum(cli, cli->server_domain,
2393 SV_TYPE_ALL,
2394 browse_callback, NULL);
2396 if (!torture_close_connection(cli)) {
2397 correct = False;
2400 printf("browse test finished\n");
2402 return correct;
2408 This checks how the getatr calls works
2410 static BOOL run_attrtest(int dummy)
2412 struct cli_state *cli;
2413 int fnum;
2414 time_t t, t2;
2415 const char *fname = "\\attrib123456789.tst";
2416 BOOL correct = True;
2418 printf("starting attrib test\n");
2420 if (!torture_open_connection(&cli, 0)) {
2421 return False;
2424 cli_unlink(cli, fname);
2425 fnum = cli_open(cli, fname,
2426 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2427 cli_close(cli, fnum);
2428 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2429 printf("getatr failed (%s)\n", cli_errstr(cli));
2430 correct = False;
2433 if (abs(t - time(NULL)) > 60*60*24*10) {
2434 printf("ERROR: SMBgetatr bug. time is %s",
2435 ctime(&t));
2436 t = time(NULL);
2437 correct = True;
2440 t2 = t-60*60*24; /* 1 day ago */
2442 if (!cli_setatr(cli, fname, 0, t2)) {
2443 printf("setatr failed (%s)\n", cli_errstr(cli));
2444 correct = True;
2447 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2448 printf("getatr failed (%s)\n", cli_errstr(cli));
2449 correct = True;
2452 if (t != t2) {
2453 printf("ERROR: getatr/setatr bug. times are\n%s",
2454 ctime(&t));
2455 printf("%s", ctime(&t2));
2456 correct = True;
2459 cli_unlink(cli, fname);
2461 if (!torture_close_connection(cli)) {
2462 correct = False;
2465 printf("attrib test finished\n");
2467 return correct;
2472 This checks a couple of trans2 calls
2474 static BOOL run_trans2test(int dummy)
2476 struct cli_state *cli;
2477 int fnum;
2478 SMB_OFF_T size;
2479 time_t c_time, a_time, m_time;
2480 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2481 const char *fname = "\\trans2.tst";
2482 const char *dname = "\\trans2";
2483 const char *fname2 = "\\trans2\\trans2.tst";
2484 pstring pname;
2485 BOOL correct = True;
2487 printf("starting trans2 test\n");
2489 if (!torture_open_connection(&cli, 0)) {
2490 return False;
2493 cli_unlink(cli, fname);
2494 fnum = cli_open(cli, fname,
2495 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2496 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2497 &m_time_ts, NULL)) {
2498 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2499 correct = False;
2502 if (!cli_qfilename(cli, fnum, pname)) {
2503 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2504 correct = False;
2507 if (strcmp(pname, fname)) {
2508 printf("qfilename gave different name? [%s] [%s]\n",
2509 fname, pname);
2510 correct = False;
2513 cli_close(cli, fnum);
2515 sleep(2);
2517 cli_unlink(cli, fname);
2518 fnum = cli_open(cli, fname,
2519 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2520 if (fnum == -1) {
2521 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2522 return False;
2524 cli_close(cli, fnum);
2526 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2527 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2528 correct = False;
2529 } else {
2530 if (c_time != m_time) {
2531 printf("create time=%s", ctime(&c_time));
2532 printf("modify time=%s", ctime(&m_time));
2533 printf("This system appears to have sticky create times\n");
2535 if (a_time % (60*60) == 0) {
2536 printf("access time=%s", ctime(&a_time));
2537 printf("This system appears to set a midnight access time\n");
2538 correct = False;
2541 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2542 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2543 correct = False;
2548 cli_unlink(cli, fname);
2549 fnum = cli_open(cli, fname,
2550 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2551 cli_close(cli, fnum);
2552 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2553 &m_time_ts, &size, NULL, NULL)) {
2554 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2555 correct = False;
2556 } else {
2557 if (w_time_ts.tv_sec < 60*60*24*2) {
2558 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2559 printf("This system appears to set a initial 0 write time\n");
2560 correct = False;
2564 cli_unlink(cli, fname);
2567 /* check if the server updates the directory modification time
2568 when creating a new file */
2569 if (!cli_mkdir(cli, dname)) {
2570 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2571 correct = False;
2573 sleep(3);
2574 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2575 &m_time_ts, &size, NULL, NULL)) {
2576 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2577 correct = False;
2580 fnum = cli_open(cli, fname2,
2581 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2582 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2583 cli_close(cli, fnum);
2584 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2585 &m_time2_ts, &size, NULL, NULL)) {
2586 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2587 correct = False;
2588 } else {
2589 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2590 == 0) {
2591 printf("This system does not update directory modification times\n");
2592 correct = False;
2595 cli_unlink(cli, fname2);
2596 cli_rmdir(cli, dname);
2598 if (!torture_close_connection(cli)) {
2599 correct = False;
2602 printf("trans2 test finished\n");
2604 return correct;
2608 This checks new W2K calls.
2611 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2613 char *buf = NULL;
2614 uint32 len;
2615 BOOL correct = True;
2617 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2618 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2619 correct = False;
2620 } else {
2621 printf("qfileinfo: level %d, len = %u\n", level, len);
2622 dump_data(0, buf, len);
2623 printf("\n");
2625 SAFE_FREE(buf);
2626 return correct;
2629 static BOOL run_w2ktest(int dummy)
2631 struct cli_state *cli;
2632 int fnum;
2633 const char *fname = "\\w2ktest\\w2k.tst";
2634 int level;
2635 BOOL correct = True;
2637 printf("starting w2k test\n");
2639 if (!torture_open_connection(&cli, 0)) {
2640 return False;
2643 fnum = cli_open(cli, fname,
2644 O_RDWR | O_CREAT , DENY_NONE);
2646 for (level = 1004; level < 1040; level++) {
2647 new_trans(cli, fnum, level);
2650 cli_close(cli, fnum);
2652 if (!torture_close_connection(cli)) {
2653 correct = False;
2656 printf("w2k test finished\n");
2658 return correct;
2663 this is a harness for some oplock tests
2665 static BOOL run_oplock1(int dummy)
2667 struct cli_state *cli1;
2668 const char *fname = "\\lockt1.lck";
2669 int fnum1;
2670 BOOL correct = True;
2672 printf("starting oplock test 1\n");
2674 if (!torture_open_connection(&cli1, 0)) {
2675 return False;
2678 cli_unlink(cli1, fname);
2680 cli_sockopt(cli1, sockops);
2682 cli1->use_oplocks = True;
2684 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2685 if (fnum1 == -1) {
2686 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2687 return False;
2690 cli1->use_oplocks = False;
2692 cli_unlink(cli1, fname);
2693 cli_unlink(cli1, fname);
2695 if (!cli_close(cli1, fnum1)) {
2696 printf("close2 failed (%s)\n", cli_errstr(cli1));
2697 return False;
2700 if (!cli_unlink(cli1, fname)) {
2701 printf("unlink failed (%s)\n", cli_errstr(cli1));
2702 return False;
2705 if (!torture_close_connection(cli1)) {
2706 correct = False;
2709 printf("finished oplock test 1\n");
2711 return correct;
2714 static BOOL run_oplock2(int dummy)
2716 struct cli_state *cli1, *cli2;
2717 const char *fname = "\\lockt2.lck";
2718 int fnum1, fnum2;
2719 int saved_use_oplocks = use_oplocks;
2720 char buf[4];
2721 BOOL correct = True;
2722 volatile BOOL *shared_correct;
2724 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2725 *shared_correct = True;
2727 use_level_II_oplocks = True;
2728 use_oplocks = True;
2730 printf("starting oplock test 2\n");
2732 if (!torture_open_connection(&cli1, 0)) {
2733 use_level_II_oplocks = False;
2734 use_oplocks = saved_use_oplocks;
2735 return False;
2738 cli1->use_oplocks = True;
2739 cli1->use_level_II_oplocks = True;
2741 if (!torture_open_connection(&cli2, 1)) {
2742 use_level_II_oplocks = False;
2743 use_oplocks = saved_use_oplocks;
2744 return False;
2747 cli2->use_oplocks = True;
2748 cli2->use_level_II_oplocks = True;
2750 cli_unlink(cli1, fname);
2752 cli_sockopt(cli1, sockops);
2753 cli_sockopt(cli2, sockops);
2755 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2756 if (fnum1 == -1) {
2757 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2758 return False;
2761 /* Don't need the globals any more. */
2762 use_level_II_oplocks = False;
2763 use_oplocks = saved_use_oplocks;
2765 if (fork() == 0) {
2766 /* Child code */
2767 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2768 if (fnum2 == -1) {
2769 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2770 *shared_correct = False;
2771 exit(0);
2774 sleep(2);
2776 if (!cli_close(cli2, fnum2)) {
2777 printf("close2 failed (%s)\n", cli_errstr(cli1));
2778 *shared_correct = False;
2781 exit(0);
2784 sleep(2);
2786 /* Ensure cli1 processes the break. Empty file should always return 0
2787 * bytes. */
2789 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2790 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2791 correct = False;
2794 /* Should now be at level II. */
2795 /* Test if sending a write locks causes a break to none. */
2797 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2798 printf("lock failed (%s)\n", cli_errstr(cli1));
2799 correct = False;
2802 cli_unlock(cli1, fnum1, 0, 4);
2804 sleep(2);
2806 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2807 printf("lock failed (%s)\n", cli_errstr(cli1));
2808 correct = False;
2811 cli_unlock(cli1, fnum1, 0, 4);
2813 sleep(2);
2815 cli_read(cli1, fnum1, buf, 0, 4);
2817 #if 0
2818 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2819 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2820 correct = False;
2822 #endif
2824 if (!cli_close(cli1, fnum1)) {
2825 printf("close1 failed (%s)\n", cli_errstr(cli1));
2826 correct = False;
2829 sleep(4);
2831 if (!cli_unlink(cli1, fname)) {
2832 printf("unlink failed (%s)\n", cli_errstr(cli1));
2833 correct = False;
2836 if (!torture_close_connection(cli1)) {
2837 correct = False;
2840 if (!*shared_correct) {
2841 correct = False;
2844 printf("finished oplock test 2\n");
2846 return correct;
2849 /* handler for oplock 3 tests */
2850 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2852 printf("got oplock break fnum=%d level=%d\n",
2853 fnum, level);
2854 return cli_oplock_ack(cli, fnum, level);
2857 static BOOL run_oplock3(int dummy)
2859 struct cli_state *cli;
2860 const char *fname = "\\oplockt3.dat";
2861 int fnum;
2862 char buf[4] = "abcd";
2863 BOOL correct = True;
2864 volatile BOOL *shared_correct;
2866 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2867 *shared_correct = True;
2869 printf("starting oplock test 3\n");
2871 if (fork() == 0) {
2872 /* Child code */
2873 use_oplocks = True;
2874 use_level_II_oplocks = True;
2875 if (!torture_open_connection(&cli, 0)) {
2876 *shared_correct = False;
2877 exit(0);
2879 sleep(2);
2880 /* try to trigger a oplock break in parent */
2881 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2882 cli_write(cli, fnum, 0, buf, 0, 4);
2883 exit(0);
2886 /* parent code */
2887 use_oplocks = True;
2888 use_level_II_oplocks = True;
2889 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2890 return False;
2892 cli_oplock_handler(cli, oplock3_handler);
2893 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2894 cli_write(cli, fnum, 0, buf, 0, 4);
2895 cli_close(cli, fnum);
2896 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2897 cli->timeout = 20000;
2898 cli_receive_smb(cli);
2899 printf("finished oplock test 3\n");
2901 return (correct && *shared_correct);
2903 /* What are we looking for here? What's sucess and what's FAILURE? */
2909 Test delete on close semantics.
2911 static BOOL run_deletetest(int dummy)
2913 struct cli_state *cli1 = NULL;
2914 struct cli_state *cli2 = NULL;
2915 const char *fname = "\\delete.file";
2916 int fnum1 = -1;
2917 int fnum2 = -1;
2918 BOOL correct = True;
2920 printf("starting delete test\n");
2922 if (!torture_open_connection(&cli1, 0)) {
2923 return False;
2926 cli_sockopt(cli1, sockops);
2928 /* Test 1 - this should delete the file on close. */
2930 cli_setatr(cli1, fname, 0, 0);
2931 cli_unlink(cli1, fname);
2933 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2934 0, FILE_OVERWRITE_IF,
2935 FILE_DELETE_ON_CLOSE, 0);
2937 if (fnum1 == -1) {
2938 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2939 correct = False;
2940 goto fail;
2943 #if 0 /* JRATEST */
2945 uint32 *accinfo = NULL;
2946 uint32 len;
2947 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2948 if (accinfo)
2949 printf("access mode = 0x%lx\n", *accinfo);
2950 SAFE_FREE(accinfo);
2952 #endif
2954 if (!cli_close(cli1, fnum1)) {
2955 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2956 correct = False;
2957 goto fail;
2960 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2961 if (fnum1 != -1) {
2962 printf("[1] open of %s succeeded (should fail)\n", fname);
2963 correct = False;
2964 goto fail;
2967 printf("first delete on close test succeeded.\n");
2969 /* Test 2 - this should delete the file on close. */
2971 cli_setatr(cli1, fname, 0, 0);
2972 cli_unlink(cli1, fname);
2974 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
2975 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2976 FILE_OVERWRITE_IF, 0, 0);
2978 if (fnum1 == -1) {
2979 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2980 correct = False;
2981 goto fail;
2984 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2985 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2986 correct = False;
2987 goto fail;
2990 if (!cli_close(cli1, fnum1)) {
2991 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2992 correct = False;
2993 goto fail;
2996 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2997 if (fnum1 != -1) {
2998 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2999 if (!cli_close(cli1, fnum1)) {
3000 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3001 correct = False;
3002 goto fail;
3004 cli_unlink(cli1, fname);
3005 } else
3006 printf("second delete on close test succeeded.\n");
3008 /* Test 3 - ... */
3009 cli_setatr(cli1, fname, 0, 0);
3010 cli_unlink(cli1, fname);
3012 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3013 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3015 if (fnum1 == -1) {
3016 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3017 correct = False;
3018 goto fail;
3021 /* This should fail with a sharing violation - open for delete is only compatible
3022 with SHARE_DELETE. */
3024 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3025 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3027 if (fnum2 != -1) {
3028 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3029 correct = False;
3030 goto fail;
3033 /* This should succeed. */
3035 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3036 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3038 if (fnum2 == -1) {
3039 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3040 correct = False;
3041 goto fail;
3044 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3045 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3046 correct = False;
3047 goto fail;
3050 if (!cli_close(cli1, fnum1)) {
3051 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3052 correct = False;
3053 goto fail;
3056 if (!cli_close(cli1, fnum2)) {
3057 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3058 correct = False;
3059 goto fail;
3062 /* This should fail - file should no longer be there. */
3064 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3065 if (fnum1 != -1) {
3066 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3067 if (!cli_close(cli1, fnum1)) {
3068 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3070 cli_unlink(cli1, fname);
3071 correct = False;
3072 goto fail;
3073 } else
3074 printf("third delete on close test succeeded.\n");
3076 /* Test 4 ... */
3077 cli_setatr(cli1, fname, 0, 0);
3078 cli_unlink(cli1, fname);
3080 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3081 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3083 if (fnum1 == -1) {
3084 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3085 correct = False;
3086 goto fail;
3089 /* This should succeed. */
3090 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3091 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3092 if (fnum2 == -1) {
3093 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3094 correct = False;
3095 goto fail;
3098 if (!cli_close(cli1, fnum2)) {
3099 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3100 correct = False;
3101 goto fail;
3104 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3105 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3106 correct = False;
3107 goto fail;
3110 /* This should fail - no more opens once delete on close set. */
3111 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3112 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3113 FILE_OPEN, 0, 0);
3114 if (fnum2 != -1) {
3115 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3116 correct = False;
3117 goto fail;
3118 } else
3119 printf("fourth delete on close test succeeded.\n");
3121 if (!cli_close(cli1, fnum1)) {
3122 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3123 correct = False;
3124 goto fail;
3127 /* Test 5 ... */
3128 cli_setatr(cli1, fname, 0, 0);
3129 cli_unlink(cli1, fname);
3131 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3132 if (fnum1 == -1) {
3133 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3134 correct = False;
3135 goto fail;
3138 /* This should fail - only allowed on NT opens with DELETE access. */
3140 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3141 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3142 correct = False;
3143 goto fail;
3146 if (!cli_close(cli1, fnum1)) {
3147 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3148 correct = False;
3149 goto fail;
3152 printf("fifth delete on close test succeeded.\n");
3154 /* Test 6 ... */
3155 cli_setatr(cli1, fname, 0, 0);
3156 cli_unlink(cli1, fname);
3158 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3159 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3160 FILE_OVERWRITE_IF, 0, 0);
3162 if (fnum1 == -1) {
3163 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3164 correct = False;
3165 goto fail;
3168 /* This should fail - only allowed on NT opens with DELETE access. */
3170 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3171 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3172 correct = False;
3173 goto fail;
3176 if (!cli_close(cli1, fnum1)) {
3177 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3178 correct = False;
3179 goto fail;
3182 printf("sixth delete on close test succeeded.\n");
3184 /* Test 7 ... */
3185 cli_setatr(cli1, fname, 0, 0);
3186 cli_unlink(cli1, fname);
3188 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3189 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3191 if (fnum1 == -1) {
3192 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3193 correct = False;
3194 goto fail;
3197 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3198 printf("[7] setting delete_on_close on file failed !\n");
3199 correct = False;
3200 goto fail;
3203 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3204 printf("[7] unsetting delete_on_close on file failed !\n");
3205 correct = False;
3206 goto fail;
3209 if (!cli_close(cli1, fnum1)) {
3210 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3211 correct = False;
3212 goto fail;
3215 /* This next open should succeed - we reset the flag. */
3217 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3218 if (fnum1 == -1) {
3219 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3220 correct = False;
3221 goto fail;
3224 if (!cli_close(cli1, fnum1)) {
3225 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3226 correct = False;
3227 goto fail;
3230 printf("seventh delete on close test succeeded.\n");
3232 /* Test 7 ... */
3233 cli_setatr(cli1, fname, 0, 0);
3234 cli_unlink(cli1, fname);
3236 if (!torture_open_connection(&cli2, 1)) {
3237 printf("[8] failed to open second connection.\n");
3238 correct = False;
3239 goto fail;
3242 cli_sockopt(cli1, sockops);
3244 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3245 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3246 FILE_OVERWRITE_IF, 0, 0);
3248 if (fnum1 == -1) {
3249 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3250 correct = False;
3251 goto fail;
3254 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3255 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3256 FILE_OPEN, 0, 0);
3258 if (fnum2 == -1) {
3259 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3260 correct = False;
3261 goto fail;
3264 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3265 printf("[8] setting delete_on_close on file failed !\n");
3266 correct = False;
3267 goto fail;
3270 if (!cli_close(cli1, fnum1)) {
3271 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3272 correct = False;
3273 goto fail;
3276 if (!cli_close(cli2, fnum2)) {
3277 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3278 correct = False;
3279 goto fail;
3282 /* This should fail.. */
3283 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3284 if (fnum1 != -1) {
3285 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3286 goto fail;
3287 correct = False;
3288 } else
3289 printf("eighth delete on close test succeeded.\n");
3291 /* This should fail - we need to set DELETE_ACCESS. */
3292 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3293 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3295 if (fnum1 != -1) {
3296 printf("[9] open of %s succeeded should have failed!\n", fname);
3297 correct = False;
3298 goto fail;
3301 printf("ninth delete on close test succeeded.\n");
3303 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3304 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3305 if (fnum1 == -1) {
3306 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3307 correct = False;
3308 goto fail;
3311 /* This should delete the file. */
3312 if (!cli_close(cli1, fnum1)) {
3313 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3314 correct = False;
3315 goto fail;
3318 /* This should fail.. */
3319 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3320 if (fnum1 != -1) {
3321 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3322 goto fail;
3323 correct = False;
3324 } else
3325 printf("tenth delete on close test succeeded.\n");
3327 cli_setatr(cli1, fname, 0, 0);
3328 cli_unlink(cli1, fname);
3330 /* What error do we get when attempting to open a read-only file with
3331 delete access ? */
3333 /* Create a readonly file. */
3334 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3335 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3336 if (fnum1 == -1) {
3337 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3338 correct = False;
3339 goto fail;
3342 if (!cli_close(cli1, fnum1)) {
3343 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3344 correct = False;
3345 goto fail;
3348 /* Now try open for delete access. */
3349 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3350 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3351 FILE_OVERWRITE_IF, 0, 0);
3353 if (fnum1 != -1) {
3354 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3355 cli_close(cli1, fnum1);
3356 goto fail;
3357 correct = False;
3358 } else {
3359 NTSTATUS nterr = cli_nt_error(cli1);
3360 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3361 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3362 goto fail;
3363 correct = False;
3364 } else {
3365 printf("eleventh delete on close test succeeded.\n");
3369 printf("finished delete test\n");
3371 fail:
3372 /* FIXME: This will crash if we aborted before cli2 got
3373 * intialized, because these functions don't handle
3374 * uninitialized connections. */
3376 if (fnum1 != -1) cli_close(cli1, fnum1);
3377 if (fnum2 != -1) cli_close(cli1, fnum2);
3378 cli_setatr(cli1, fname, 0, 0);
3379 cli_unlink(cli1, fname);
3381 if (cli1 && !torture_close_connection(cli1)) {
3382 correct = False;
3384 if (cli2 && !torture_close_connection(cli2)) {
3385 correct = False;
3387 return correct;
3392 print out server properties
3394 static BOOL run_properties(int dummy)
3396 static struct cli_state *cli;
3397 BOOL correct = True;
3399 printf("starting properties test\n");
3401 ZERO_STRUCT(cli);
3403 if (!torture_open_connection(&cli, 0)) {
3404 return False;
3407 cli_sockopt(cli, sockops);
3409 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3411 if (!torture_close_connection(cli)) {
3412 correct = False;
3415 return correct;
3420 /* FIRST_DESIRED_ACCESS 0xf019f */
3421 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3422 FILE_READ_EA| /* 0xf */ \
3423 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3424 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3425 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3426 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3427 /* SECOND_DESIRED_ACCESS 0xe0080 */
3428 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3429 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3430 WRITE_OWNER_ACCESS /* 0xe0000 */
3432 #if 0
3433 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3434 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3435 FILE_READ_DATA|\
3436 WRITE_OWNER_ACCESS /* */
3437 #endif
3440 Test ntcreate calls made by xcopy
3442 static BOOL run_xcopy(int dummy)
3444 static struct cli_state *cli1;
3445 const char *fname = "\\test.txt";
3446 BOOL correct = True;
3447 int fnum1, fnum2;
3449 printf("starting xcopy test\n");
3451 if (!torture_open_connection(&cli1, 0)) {
3452 return False;
3455 fnum1 = cli_nt_create_full(cli1, fname, 0,
3456 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3457 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3458 0x4044, 0);
3460 if (fnum1 == -1) {
3461 printf("First open failed - %s\n", cli_errstr(cli1));
3462 return False;
3465 fnum2 = cli_nt_create_full(cli1, fname, 0,
3466 SECOND_DESIRED_ACCESS, 0,
3467 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3468 0x200000, 0);
3469 if (fnum2 == -1) {
3470 printf("second open failed - %s\n", cli_errstr(cli1));
3471 return False;
3474 if (!torture_close_connection(cli1)) {
3475 correct = False;
3478 return correct;
3482 Test rename on files open with share delete and no share delete.
3484 static BOOL run_rename(int dummy)
3486 static struct cli_state *cli1;
3487 const char *fname = "\\test.txt";
3488 const char *fname1 = "\\test1.txt";
3489 BOOL correct = True;
3490 int fnum1;
3492 printf("starting rename test\n");
3494 if (!torture_open_connection(&cli1, 0)) {
3495 return False;
3498 cli_unlink(cli1, fname);
3499 cli_unlink(cli1, fname1);
3500 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3501 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3503 if (fnum1 == -1) {
3504 printf("First open failed - %s\n", cli_errstr(cli1));
3505 return False;
3508 if (!cli_rename(cli1, fname, fname1)) {
3509 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3510 } else {
3511 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3512 correct = False;
3515 if (!cli_close(cli1, fnum1)) {
3516 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3517 return False;
3520 cli_unlink(cli1, fname);
3521 cli_unlink(cli1, fname1);
3522 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3523 #if 0
3524 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3525 #else
3526 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3527 #endif
3529 if (fnum1 == -1) {
3530 printf("Second open failed - %s\n", cli_errstr(cli1));
3531 return False;
3534 if (!cli_rename(cli1, fname, fname1)) {
3535 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3536 correct = False;
3537 } else {
3538 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3541 if (!cli_close(cli1, fnum1)) {
3542 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3543 return False;
3546 cli_unlink(cli1, fname);
3547 cli_unlink(cli1, fname1);
3549 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3550 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3552 if (fnum1 == -1) {
3553 printf("Third open failed - %s\n", cli_errstr(cli1));
3554 return False;
3558 #if 0
3560 int fnum2;
3562 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3563 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3565 if (fnum2 == -1) {
3566 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3567 return False;
3569 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3570 printf("[8] setting delete_on_close on file failed !\n");
3571 return False;
3574 if (!cli_close(cli1, fnum2)) {
3575 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3576 return False;
3579 #endif
3581 if (!cli_rename(cli1, fname, fname1)) {
3582 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3583 correct = False;
3584 } else {
3585 printf("Third rename succeeded (SHARE_NONE)\n");
3588 if (!cli_close(cli1, fnum1)) {
3589 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3590 return False;
3593 cli_unlink(cli1, fname);
3594 cli_unlink(cli1, fname1);
3596 /*----*/
3598 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3599 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3601 if (fnum1 == -1) {
3602 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3603 return False;
3606 if (!cli_rename(cli1, fname, fname1)) {
3607 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3608 } else {
3609 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3610 correct = False;
3613 if (!cli_close(cli1, fnum1)) {
3614 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3615 return False;
3618 cli_unlink(cli1, fname);
3619 cli_unlink(cli1, fname1);
3621 /*--*/
3623 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3624 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3626 if (fnum1 == -1) {
3627 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3628 return False;
3631 if (!cli_rename(cli1, fname, fname1)) {
3632 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
3633 correct = False;
3634 } else {
3635 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3639 * Now check if the first name still exists ...
3642 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3643 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3645 if (fnum2 == -1) {
3646 printf("Opening original file after rename of open file fails: %s\n",
3647 cli_errstr(cli1));
3649 else {
3650 printf("Opening original file after rename of open file works ...\n");
3651 (void)cli_close(cli1, fnum2);
3652 } */
3654 /*--*/
3657 if (!cli_close(cli1, fnum1)) {
3658 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3659 return False;
3662 cli_unlink(cli1, fname);
3663 cli_unlink(cli1, fname1);
3665 if (!torture_close_connection(cli1)) {
3666 correct = False;
3669 return correct;
3672 static BOOL run_pipe_number(int dummy)
3674 struct cli_state *cli1;
3675 const char *pipe_name = "\\SPOOLSS";
3676 int fnum;
3677 int num_pipes = 0;
3679 printf("starting pipenumber test\n");
3680 if (!torture_open_connection(&cli1, 0)) {
3681 return False;
3684 cli_sockopt(cli1, sockops);
3685 while(1) {
3686 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3687 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3689 if (fnum == -1) {
3690 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3691 break;
3693 num_pipes++;
3694 printf("\r%6d", num_pipes);
3697 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3698 torture_close_connection(cli1);
3699 return True;
3703 Test open mode returns on read-only files.
3705 static BOOL run_opentest(int dummy)
3707 static struct cli_state *cli1;
3708 static struct cli_state *cli2;
3709 const char *fname = "\\readonly.file";
3710 int fnum1, fnum2;
3711 char buf[20];
3712 SMB_OFF_T fsize;
3713 BOOL correct = True;
3714 char *tmp_path;
3716 printf("starting open test\n");
3718 if (!torture_open_connection(&cli1, 0)) {
3719 return False;
3722 cli_setatr(cli1, fname, 0, 0);
3723 cli_unlink(cli1, fname);
3725 cli_sockopt(cli1, sockops);
3727 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3728 if (fnum1 == -1) {
3729 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3730 return False;
3733 if (!cli_close(cli1, fnum1)) {
3734 printf("close2 failed (%s)\n", cli_errstr(cli1));
3735 return False;
3738 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3739 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3740 return False;
3743 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3744 if (fnum1 == -1) {
3745 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3746 return False;
3749 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3750 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3752 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3753 NT_STATUS_ACCESS_DENIED)) {
3754 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3757 printf("finished open test 1\n");
3759 cli_close(cli1, fnum1);
3761 /* Now try not readonly and ensure ERRbadshare is returned. */
3763 cli_setatr(cli1, fname, 0, 0);
3765 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3766 if (fnum1 == -1) {
3767 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3768 return False;
3771 /* This will fail - but the error should be ERRshare. */
3772 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3774 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3775 NT_STATUS_SHARING_VIOLATION)) {
3776 printf("correct error code ERRDOS/ERRbadshare returned\n");
3779 if (!cli_close(cli1, fnum1)) {
3780 printf("close2 failed (%s)\n", cli_errstr(cli1));
3781 return False;
3784 cli_unlink(cli1, fname);
3786 printf("finished open test 2\n");
3788 /* Test truncate open disposition on file opened for read. */
3790 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3791 if (fnum1 == -1) {
3792 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3793 return False;
3796 /* write 20 bytes. */
3798 memset(buf, '\0', 20);
3800 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3801 printf("write failed (%s)\n", cli_errstr(cli1));
3802 correct = False;
3805 if (!cli_close(cli1, fnum1)) {
3806 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3807 return False;
3810 /* Ensure size == 20. */
3811 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3812 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3813 return False;
3816 if (fsize != 20) {
3817 printf("(3) file size != 20\n");
3818 return False;
3821 /* Now test if we can truncate a file opened for readonly. */
3823 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3824 if (fnum1 == -1) {
3825 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3826 return False;
3829 if (!cli_close(cli1, fnum1)) {
3830 printf("close2 failed (%s)\n", cli_errstr(cli1));
3831 return False;
3834 /* Ensure size == 0. */
3835 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3836 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3837 return False;
3840 if (fsize != 0) {
3841 printf("(3) file size != 0\n");
3842 return False;
3844 printf("finished open test 3\n");
3846 cli_unlink(cli1, fname);
3849 printf("testing ctemp\n");
3850 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3851 if (fnum1 == -1) {
3852 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3853 return False;
3855 printf("ctemp gave path %s\n", tmp_path);
3856 if (!cli_close(cli1, fnum1)) {
3857 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3859 if (!cli_unlink(cli1, tmp_path)) {
3860 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3863 /* Test the non-io opens... */
3865 if (!torture_open_connection(&cli2, 1)) {
3866 return False;
3869 cli_setatr(cli2, fname, 0, 0);
3870 cli_unlink(cli2, fname);
3872 cli_sockopt(cli2, sockops);
3874 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3876 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3877 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3879 if (fnum1 == -1) {
3880 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3881 return False;
3884 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3885 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3887 if (fnum2 == -1) {
3888 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3889 return False;
3892 if (!cli_close(cli1, fnum1)) {
3893 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3894 return False;
3896 if (!cli_close(cli2, fnum2)) {
3897 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3898 return False;
3901 printf("non-io open test #1 passed.\n");
3903 cli_unlink(cli1, fname);
3905 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3907 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3908 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3910 if (fnum1 == -1) {
3911 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3912 return False;
3915 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3916 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3918 if (fnum2 == -1) {
3919 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3920 return False;
3923 if (!cli_close(cli1, fnum1)) {
3924 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3925 return False;
3927 if (!cli_close(cli2, fnum2)) {
3928 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3929 return False;
3932 printf("non-io open test #2 passed.\n");
3934 cli_unlink(cli1, fname);
3936 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3938 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3939 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3941 if (fnum1 == -1) {
3942 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3943 return False;
3946 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3947 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3949 if (fnum2 == -1) {
3950 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3951 return False;
3954 if (!cli_close(cli1, fnum1)) {
3955 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3956 return False;
3958 if (!cli_close(cli2, fnum2)) {
3959 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3960 return False;
3963 printf("non-io open test #3 passed.\n");
3965 cli_unlink(cli1, fname);
3967 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3969 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3970 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3972 if (fnum1 == -1) {
3973 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3974 return False;
3977 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3978 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3980 if (fnum2 != -1) {
3981 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3982 return False;
3985 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3987 if (!cli_close(cli1, fnum1)) {
3988 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3989 return False;
3992 printf("non-io open test #4 passed.\n");
3994 cli_unlink(cli1, fname);
3996 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3998 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3999 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4001 if (fnum1 == -1) {
4002 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4003 return False;
4006 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4007 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4009 if (fnum2 == -1) {
4010 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4011 return False;
4014 if (!cli_close(cli1, fnum1)) {
4015 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4016 return False;
4019 if (!cli_close(cli2, fnum2)) {
4020 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4021 return False;
4024 printf("non-io open test #5 passed.\n");
4026 printf("TEST #6 testing 1 non-io open, one io open\n");
4028 cli_unlink(cli1, fname);
4030 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4031 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4033 if (fnum1 == -1) {
4034 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4035 return False;
4038 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4039 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4041 if (fnum2 == -1) {
4042 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4043 return False;
4046 if (!cli_close(cli1, fnum1)) {
4047 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4048 return False;
4051 if (!cli_close(cli2, fnum2)) {
4052 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4053 return False;
4056 printf("non-io open test #6 passed.\n");
4058 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4060 cli_unlink(cli1, fname);
4062 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4063 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4065 if (fnum1 == -1) {
4066 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4067 return False;
4070 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4071 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4073 if (fnum2 != -1) {
4074 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4075 return False;
4078 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4080 if (!cli_close(cli1, fnum1)) {
4081 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4082 return False;
4085 printf("non-io open test #7 passed.\n");
4087 cli_unlink(cli1, fname);
4089 if (!torture_close_connection(cli1)) {
4090 correct = False;
4092 if (!torture_close_connection(cli2)) {
4093 correct = False;
4096 return correct;
4099 static uint32 open_attrs_table[] = {
4100 FILE_ATTRIBUTE_NORMAL,
4101 FILE_ATTRIBUTE_ARCHIVE,
4102 FILE_ATTRIBUTE_READONLY,
4103 FILE_ATTRIBUTE_HIDDEN,
4104 FILE_ATTRIBUTE_SYSTEM,
4106 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4109 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4110 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4111 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4113 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4114 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4115 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4116 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4119 struct trunc_open_results {
4120 unsigned int num;
4121 uint32 init_attr;
4122 uint32 trunc_attr;
4123 uint32 result_attr;
4126 static struct trunc_open_results attr_results[] = {
4127 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4128 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4129 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4130 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4131 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4132 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4133 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4134 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4135 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4136 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4137 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4138 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4139 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4140 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4141 { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4142 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4143 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4144 { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4145 { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
4146 { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
4147 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4148 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4149 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4150 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4151 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4152 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4155 static BOOL run_openattrtest(int dummy)
4157 static struct cli_state *cli1;
4158 const char *fname = "\\openattr.file";
4159 int fnum1;
4160 BOOL correct = True;
4161 uint16 attr;
4162 unsigned int i, j, k, l;
4164 printf("starting open attr test\n");
4166 if (!torture_open_connection(&cli1, 0)) {
4167 return False;
4170 cli_sockopt(cli1, sockops);
4172 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4173 cli_setatr(cli1, fname, 0, 0);
4174 cli_unlink(cli1, fname);
4175 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4176 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4178 if (fnum1 == -1) {
4179 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4180 return False;
4183 if (!cli_close(cli1, fnum1)) {
4184 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4185 return False;
4188 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4189 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4190 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4192 if (fnum1 == -1) {
4193 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4194 if (attr_results[l].num == k) {
4195 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4196 k, open_attrs_table[i],
4197 open_attrs_table[j],
4198 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4199 correct = False;
4202 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4203 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4204 k, open_attrs_table[i], open_attrs_table[j],
4205 cli_errstr(cli1));
4206 correct = False;
4208 #if 0
4209 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4210 #endif
4211 k++;
4212 continue;
4215 if (!cli_close(cli1, fnum1)) {
4216 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4217 return False;
4220 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4221 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4222 return False;
4225 #if 0
4226 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4227 k, open_attrs_table[i], open_attrs_table[j], attr );
4228 #endif
4230 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4231 if (attr_results[l].num == k) {
4232 if (attr != attr_results[l].result_attr ||
4233 open_attrs_table[i] != attr_results[l].init_attr ||
4234 open_attrs_table[j] != attr_results[l].trunc_attr) {
4235 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4236 open_attrs_table[i],
4237 open_attrs_table[j],
4238 (unsigned int)attr,
4239 attr_results[l].result_attr);
4240 correct = False;
4242 break;
4245 k++;
4249 cli_setatr(cli1, fname, 0, 0);
4250 cli_unlink(cli1, fname);
4252 printf("open attr test %s.\n", correct ? "passed" : "failed");
4254 if (!torture_close_connection(cli1)) {
4255 correct = False;
4257 return correct;
4260 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4266 test directory listing speed
4268 static BOOL run_dirtest(int dummy)
4270 int i;
4271 static struct cli_state *cli;
4272 int fnum;
4273 double t1;
4274 BOOL correct = True;
4276 printf("starting directory test\n");
4278 if (!torture_open_connection(&cli, 0)) {
4279 return False;
4282 cli_sockopt(cli, sockops);
4284 srandom(0);
4285 for (i=0;i<torture_numops;i++) {
4286 fstring fname;
4287 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4288 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4289 if (fnum == -1) {
4290 fprintf(stderr,"Failed to open %s\n", fname);
4291 return False;
4293 cli_close(cli, fnum);
4296 t1 = end_timer();
4298 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4299 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4300 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4302 printf("dirtest core %g seconds\n", end_timer() - t1);
4304 srandom(0);
4305 for (i=0;i<torture_numops;i++) {
4306 fstring fname;
4307 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4308 cli_unlink(cli, fname);
4311 if (!torture_close_connection(cli)) {
4312 correct = False;
4315 printf("finished dirtest\n");
4317 return correct;
4320 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4322 struct cli_state *pcli = (struct cli_state *)state;
4323 fstring fname;
4324 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4326 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4327 return;
4329 if (finfo->mode & aDIR) {
4330 if (!cli_rmdir(pcli, fname))
4331 printf("del_fn: failed to rmdir %s\n,", fname );
4332 } else {
4333 if (!cli_unlink(pcli, fname))
4334 printf("del_fn: failed to unlink %s\n,", fname );
4340 sees what IOCTLs are supported
4342 BOOL torture_ioctl_test(int dummy)
4344 static struct cli_state *cli;
4345 uint16 device, function;
4346 int fnum;
4347 const char *fname = "\\ioctl.dat";
4348 DATA_BLOB blob;
4349 NTSTATUS status;
4351 if (!torture_open_connection(&cli, 0)) {
4352 return False;
4355 printf("starting ioctl test\n");
4357 cli_unlink(cli, fname);
4359 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4360 if (fnum == -1) {
4361 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4362 return False;
4365 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4366 printf("ioctl device info: %s\n", cli_errstr(cli));
4368 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4369 printf("ioctl job info: %s\n", cli_errstr(cli));
4371 for (device=0;device<0x100;device++) {
4372 printf("testing device=0x%x\n", device);
4373 for (function=0;function<0x100;function++) {
4374 uint32 code = (device<<16) | function;
4376 status = cli_raw_ioctl(cli, fnum, code, &blob);
4378 if (NT_STATUS_IS_OK(status)) {
4379 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4380 (int)blob.length);
4381 data_blob_free(&blob);
4386 if (!torture_close_connection(cli)) {
4387 return False;
4390 return True;
4395 tries varients of chkpath
4397 BOOL torture_chkpath_test(int dummy)
4399 static struct cli_state *cli;
4400 int fnum;
4401 BOOL ret;
4403 if (!torture_open_connection(&cli, 0)) {
4404 return False;
4407 printf("starting chkpath test\n");
4409 /* cleanup from an old run */
4410 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4411 cli_unlink(cli, "\\chkpath.dir\\*");
4412 cli_rmdir(cli, "\\chkpath.dir");
4414 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4415 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4416 return False;
4419 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4420 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4421 return False;
4424 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4425 if (fnum == -1) {
4426 printf("open1 failed (%s)\n", cli_errstr(cli));
4427 return False;
4429 cli_close(cli, fnum);
4431 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4432 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4433 ret = False;
4436 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4437 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4438 ret = False;
4441 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4442 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4443 NT_STATUS_NOT_A_DIRECTORY);
4444 } else {
4445 printf("* chkpath on a file should fail\n");
4446 ret = False;
4449 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4450 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4451 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4452 } else {
4453 printf("* chkpath on a non existant file should fail\n");
4454 ret = False;
4457 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4458 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4459 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4460 } else {
4461 printf("* chkpath on a non existent component should fail\n");
4462 ret = False;
4465 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4466 cli_unlink(cli, "\\chkpath.dir\\*");
4467 cli_rmdir(cli, "\\chkpath.dir");
4469 if (!torture_close_connection(cli)) {
4470 return False;
4473 return ret;
4476 static BOOL run_eatest(int dummy)
4478 static struct cli_state *cli;
4479 const char *fname = "\\eatest.txt";
4480 BOOL correct = True;
4481 int fnum, i;
4482 size_t num_eas;
4483 struct ea_struct *ea_list = NULL;
4484 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4486 printf("starting eatest\n");
4488 if (!torture_open_connection(&cli, 0)) {
4489 talloc_destroy(mem_ctx);
4490 return False;
4493 cli_unlink(cli, fname);
4494 fnum = cli_nt_create_full(cli, fname, 0,
4495 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4496 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4497 0x4044, 0);
4499 if (fnum == -1) {
4500 printf("open failed - %s\n", cli_errstr(cli));
4501 talloc_destroy(mem_ctx);
4502 return False;
4505 for (i = 0; i < 10; i++) {
4506 fstring ea_name, ea_val;
4508 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4509 memset(ea_val, (char)i+1, i+1);
4510 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4511 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4512 talloc_destroy(mem_ctx);
4513 return False;
4517 cli_close(cli, fnum);
4518 for (i = 0; i < 10; i++) {
4519 fstring ea_name, ea_val;
4521 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4522 memset(ea_val, (char)i+1, i+1);
4523 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4524 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4525 talloc_destroy(mem_ctx);
4526 return False;
4530 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4531 printf("ea_get list failed - %s\n", cli_errstr(cli));
4532 correct = False;
4535 printf("num_eas = %d\n", (int)num_eas);
4537 if (num_eas != 20) {
4538 printf("Should be 20 EA's stored... failing.\n");
4539 correct = False;
4542 for (i = 0; i < num_eas; i++) {
4543 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4544 dump_data(0, (char *)ea_list[i].value.data,
4545 ea_list[i].value.length);
4548 /* Setting EA's to zero length deletes them. Test this */
4549 printf("Now deleting all EA's - case indepenent....\n");
4551 #if 1
4552 cli_set_ea_path(cli, fname, "", "", 0);
4553 #else
4554 for (i = 0; i < 20; i++) {
4555 fstring ea_name;
4556 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4557 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4558 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4559 talloc_destroy(mem_ctx);
4560 return False;
4563 #endif
4565 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4566 printf("ea_get list failed - %s\n", cli_errstr(cli));
4567 correct = False;
4570 printf("num_eas = %d\n", (int)num_eas);
4571 for (i = 0; i < num_eas; i++) {
4572 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4573 dump_data(0, (char *)ea_list[i].value.data,
4574 ea_list[i].value.length);
4577 if (num_eas != 0) {
4578 printf("deleting EA's failed.\n");
4579 correct = False;
4582 /* Try and delete a non existant EA. */
4583 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4584 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4585 correct = False;
4588 talloc_destroy(mem_ctx);
4589 if (!torture_close_connection(cli)) {
4590 correct = False;
4593 return correct;
4596 static BOOL run_dirtest1(int dummy)
4598 int i;
4599 static struct cli_state *cli;
4600 int fnum, num_seen;
4601 BOOL correct = True;
4603 printf("starting directory test\n");
4605 if (!torture_open_connection(&cli, 0)) {
4606 return False;
4609 cli_sockopt(cli, sockops);
4611 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4612 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4613 cli_rmdir(cli, "\\LISTDIR");
4614 cli_mkdir(cli, "\\LISTDIR");
4616 /* Create 1000 files and 1000 directories. */
4617 for (i=0;i<1000;i++) {
4618 fstring fname;
4619 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4620 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4621 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4622 if (fnum == -1) {
4623 fprintf(stderr,"Failed to open %s\n", fname);
4624 return False;
4626 cli_close(cli, fnum);
4628 for (i=0;i<1000;i++) {
4629 fstring fname;
4630 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4631 if (!cli_mkdir(cli, fname)) {
4632 fprintf(stderr,"Failed to open %s\n", fname);
4633 return False;
4637 /* Now ensure that doing an old list sees both files and directories. */
4638 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4639 printf("num_seen = %d\n", num_seen );
4640 /* We should see 100 files + 1000 directories + . and .. */
4641 if (num_seen != 2002)
4642 correct = False;
4644 /* Ensure if we have the "must have" bits we only see the
4645 * relevent entries.
4647 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4648 printf("num_seen = %d\n", num_seen );
4649 if (num_seen != 1002)
4650 correct = False;
4652 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4653 printf("num_seen = %d\n", num_seen );
4654 if (num_seen != 1000)
4655 correct = False;
4657 /* Delete everything. */
4658 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4659 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4660 cli_rmdir(cli, "\\LISTDIR");
4662 #if 0
4663 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4664 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4665 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4666 #endif
4668 if (!torture_close_connection(cli)) {
4669 correct = False;
4672 printf("finished dirtest1\n");
4674 return correct;
4677 static BOOL run_error_map_extract(int dummy) {
4679 static struct cli_state *c_dos;
4680 static struct cli_state *c_nt;
4682 uint32 error;
4684 uint32 flgs2, errnum;
4685 uint8 errclass;
4687 NTSTATUS nt_status;
4689 fstring user;
4691 /* NT-Error connection */
4693 if (!(c_nt = open_nbt_connection())) {
4694 return False;
4697 c_nt->use_spnego = False;
4699 if (!cli_negprot(c_nt)) {
4700 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
4701 cli_shutdown(c_nt);
4702 return False;
4705 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4706 workgroup))) {
4707 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4708 return False;
4711 /* DOS-Error connection */
4713 if (!(c_dos = open_nbt_connection())) {
4714 return False;
4717 c_dos->use_spnego = False;
4718 c_dos->force_dos_errors = True;
4720 if (!cli_negprot(c_dos)) {
4721 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
4722 cli_shutdown(c_dos);
4723 return False;
4726 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4727 workgroup))) {
4728 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4729 return False;
4732 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4733 fstr_sprintf(user, "%X", error);
4735 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4736 password, strlen(password),
4737 password, strlen(password),
4738 workgroup))) {
4739 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4742 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4744 /* Case #1: 32-bit NT errors */
4745 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4746 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4747 } else {
4748 printf("/** Dos error on NT connection! (%s) */\n",
4749 cli_errstr(c_nt));
4750 nt_status = NT_STATUS(0xc0000000);
4753 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4754 password, strlen(password),
4755 password, strlen(password),
4756 workgroup))) {
4757 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4759 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4761 /* Case #1: 32-bit NT errors */
4762 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4763 printf("/** NT error on DOS connection! (%s) */\n",
4764 cli_errstr(c_nt));
4765 errnum = errclass = 0;
4766 } else {
4767 cli_dos_error(c_dos, &errclass, &errnum);
4770 if (NT_STATUS_V(nt_status) != error) {
4771 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4772 get_nt_error_c_code(NT_STATUS(error)),
4773 get_nt_error_c_code(nt_status));
4776 printf("\t{%s,\t%s,\t%s},\n",
4777 smb_dos_err_class(errclass),
4778 smb_dos_err_name(errclass, errnum),
4779 get_nt_error_c_code(NT_STATUS(error)));
4781 return True;
4784 static BOOL run_local_substitute(int dummy)
4786 TALLOC_CTX *mem_ctx;
4787 int diff = 0;
4789 if ((mem_ctx = talloc_init("run_local_subst")) == NULL) {
4790 printf("talloc_init failed\n");
4791 return False;
4794 diff |= strcmp(talloc_sub_specified(mem_ctx, "%U", "bla", "", -1, -1),
4795 "bla");
4796 diff |= strcmp(talloc_sub_specified(mem_ctx, "%u%U", "bla", "", -1, -1),
4797 "blabla");
4798 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, -1),
4799 "NO_GROUP");
4800 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, -1),
4801 "NO_GROUP");
4802 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, 0),
4803 gidtoname(0));
4804 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, 0),
4805 gidtoname(0));
4806 diff |= strcmp(talloc_sub_specified(mem_ctx, "%D%u", "u", "dom", -1, 0),
4807 "domu");
4808 diff |= strcmp(talloc_sub_specified(mem_ctx, "%i %I", "", "", -1, -1),
4809 "0.0.0.0 0.0.0.0");
4811 /* Different captialization rules in sub_basic... */
4813 diff |= strcmp(talloc_sub_basic(mem_ctx, "BLA", "dom", "%U%D"),
4814 "blaDOM");
4816 TALLOC_FREE(mem_ctx);
4817 return (diff == 0);
4820 static BOOL run_local_gencache(int dummy)
4822 char *val;
4823 time_t tm;
4825 if (!gencache_init()) {
4826 d_printf("%s: gencache_init() failed\n", __location__);
4827 return False;
4830 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
4831 d_printf("%s: gencache_set() failed\n", __location__);
4832 return False;
4835 if (!gencache_get("foo", &val, &tm)) {
4836 d_printf("%s: gencache_get() failed\n", __location__);
4837 return False;
4840 if (strcmp(val, "bar") != 0) {
4841 d_printf("%s: gencache_get() returned %s, expected %s\n",
4842 __location__, val, "bar");
4843 SAFE_FREE(val);
4844 return False;
4847 SAFE_FREE(val);
4849 if (!gencache_del("foo")) {
4850 d_printf("%s: gencache_del() failed\n", __location__);
4851 return False;
4853 if (gencache_del("foo")) {
4854 d_printf("%s: second gencache_del() succeeded\n",
4855 __location__);
4856 return False;
4859 if (gencache_get("foo", &val, &tm)) {
4860 d_printf("%s: gencache_get() on deleted entry "
4861 "succeeded\n", __location__);
4862 return False;
4865 if (!gencache_shutdown()) {
4866 d_printf("%s: gencache_shutdown() failed\n", __location__);
4867 return False;
4870 if (gencache_shutdown()) {
4871 d_printf("%s: second gencache_shutdown() succeeded\n",
4872 __location__);
4873 return False;
4876 return True;
4879 static double create_procs(BOOL (*fn)(int), BOOL *result)
4881 int i, status;
4882 volatile pid_t *child_status;
4883 volatile BOOL *child_status_out;
4884 int synccount;
4885 int tries = 8;
4887 synccount = 0;
4889 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4890 if (!child_status) {
4891 printf("Failed to setup shared memory\n");
4892 return -1;
4895 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4896 if (!child_status_out) {
4897 printf("Failed to setup result status shared memory\n");
4898 return -1;
4901 for (i = 0; i < nprocs; i++) {
4902 child_status[i] = 0;
4903 child_status_out[i] = True;
4906 start_timer();
4908 for (i=0;i<nprocs;i++) {
4909 procnum = i;
4910 if (fork() == 0) {
4911 pid_t mypid = getpid();
4912 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4914 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4916 while (1) {
4917 if (torture_open_connection(&current_cli, i)) break;
4918 if (tries-- == 0) {
4919 printf("pid %d failed to start\n", (int)getpid());
4920 _exit(1);
4922 smb_msleep(10);
4925 child_status[i] = getpid();
4927 while (child_status[i] && end_timer() < 5) smb_msleep(2);
4929 child_status_out[i] = fn(i);
4930 _exit(0);
4934 do {
4935 synccount = 0;
4936 for (i=0;i<nprocs;i++) {
4937 if (child_status[i]) synccount++;
4939 if (synccount == nprocs) break;
4940 smb_msleep(10);
4941 } while (end_timer() < 30);
4943 if (synccount != nprocs) {
4944 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4945 *result = False;
4946 return end_timer();
4949 /* start the client load */
4950 start_timer();
4952 for (i=0;i<nprocs;i++) {
4953 child_status[i] = 0;
4956 printf("%d clients started\n", nprocs);
4958 for (i=0;i<nprocs;i++) {
4959 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
4962 printf("\n");
4964 for (i=0;i<nprocs;i++) {
4965 if (!child_status_out[i]) {
4966 *result = False;
4969 return end_timer();
4972 #define FLAG_MULTIPROC 1
4974 static struct {
4975 const char *name;
4976 BOOL (*fn)(int);
4977 unsigned flags;
4978 } torture_ops[] = {
4979 {"FDPASS", run_fdpasstest, 0},
4980 {"LOCK1", run_locktest1, 0},
4981 {"LOCK2", run_locktest2, 0},
4982 {"LOCK3", run_locktest3, 0},
4983 {"LOCK4", run_locktest4, 0},
4984 {"LOCK5", run_locktest5, 0},
4985 {"LOCK6", run_locktest6, 0},
4986 {"LOCK7", run_locktest7, 0},
4987 {"UNLINK", run_unlinktest, 0},
4988 {"BROWSE", run_browsetest, 0},
4989 {"ATTR", run_attrtest, 0},
4990 {"TRANS2", run_trans2test, 0},
4991 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4992 {"TORTURE",run_torture, FLAG_MULTIPROC},
4993 {"RANDOMIPC", run_randomipc, 0},
4994 {"NEGNOWAIT", run_negprot_nowait, 0},
4995 {"NBENCH", run_nbench, 0},
4996 {"OPLOCK1", run_oplock1, 0},
4997 {"OPLOCK2", run_oplock2, 0},
4998 {"OPLOCK3", run_oplock3, 0},
4999 {"DIR", run_dirtest, 0},
5000 {"DIR1", run_dirtest1, 0},
5001 {"DENY1", torture_denytest1, 0},
5002 {"DENY2", torture_denytest2, 0},
5003 {"TCON", run_tcon_test, 0},
5004 {"TCONDEV", run_tcon_devtype_test, 0},
5005 {"RW1", run_readwritetest, 0},
5006 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5007 {"RW3", run_readwritelarge, 0},
5008 {"OPEN", run_opentest, 0},
5009 #if 1
5010 {"OPENATTR", run_openattrtest, 0},
5011 #endif
5012 {"XCOPY", run_xcopy, 0},
5013 {"RENAME", run_rename, 0},
5014 {"DELETE", run_deletetest, 0},
5015 {"PROPERTIES", run_properties, 0},
5016 {"MANGLE", torture_mangle, 0},
5017 {"W2K", run_w2ktest, 0},
5018 {"TRANS2SCAN", torture_trans2_scan, 0},
5019 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5020 {"UTABLE", torture_utable, 0},
5021 {"CASETABLE", torture_casetable, 0},
5022 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5023 {"PIPE_NUMBER", run_pipe_number, 0},
5024 {"TCON2", run_tcon2_test, 0},
5025 {"IOCTL", torture_ioctl_test, 0},
5026 {"CHKPATH", torture_chkpath_test, 0},
5027 {"FDSESS", run_fdsesstest, 0},
5028 { "EATEST", run_eatest, 0},
5029 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5030 { "LOCAL-GENCACHE", run_local_gencache, 0},
5031 {NULL, NULL, 0}};
5035 /****************************************************************************
5036 run a specified test or "ALL"
5037 ****************************************************************************/
5038 static BOOL run_test(const char *name)
5040 BOOL ret = True;
5041 BOOL result = True;
5042 BOOL found = False;
5043 int i;
5044 double t;
5045 if (strequal(name,"ALL")) {
5046 for (i=0;torture_ops[i].name;i++) {
5047 run_test(torture_ops[i].name);
5049 found = True;
5052 for (i=0;torture_ops[i].name;i++) {
5053 fstr_sprintf(randomfname, "\\XX%x",
5054 (unsigned)random());
5056 if (strequal(name, torture_ops[i].name)) {
5057 found = True;
5058 printf("Running %s\n", name);
5059 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5060 t = create_procs(torture_ops[i].fn, &result);
5061 if (!result) {
5062 ret = False;
5063 printf("TEST %s FAILED!\n", name);
5066 } else {
5067 start_timer();
5068 if (!torture_ops[i].fn(0)) {
5069 ret = False;
5070 printf("TEST %s FAILED!\n", name);
5072 t = end_timer();
5074 printf("%s took %g secs\n\n", name, t);
5078 if (!found) {
5079 printf("Did not find a test named %s\n", name);
5080 ret = False;
5083 return ret;
5087 static void usage(void)
5089 int i;
5091 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5092 printf("Please use samba4 torture.\n\n");
5094 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5096 printf("\t-d debuglevel\n");
5097 printf("\t-U user%%pass\n");
5098 printf("\t-k use kerberos\n");
5099 printf("\t-N numprocs\n");
5100 printf("\t-n my_netbios_name\n");
5101 printf("\t-W workgroup\n");
5102 printf("\t-o num_operations\n");
5103 printf("\t-O socket_options\n");
5104 printf("\t-m maximum protocol\n");
5105 printf("\t-L use oplocks\n");
5106 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5107 printf("\t-A showall\n");
5108 printf("\t-p port\n");
5109 printf("\t-s seed\n");
5110 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5111 printf("\n\n");
5113 printf("tests are:");
5114 for (i=0;torture_ops[i].name;i++) {
5115 printf(" %s", torture_ops[i].name);
5117 printf("\n");
5119 printf("default test is ALL\n");
5121 exit(1);
5124 /****************************************************************************
5125 main program
5126 ****************************************************************************/
5127 int main(int argc,char *argv[])
5129 int opt, i;
5130 char *p;
5131 int gotuser = 0;
5132 int gotpass = 0;
5133 BOOL correct = True;
5135 dbf = x_stdout;
5137 #ifdef HAVE_SETBUFFER
5138 setbuffer(stdout, NULL, 0);
5139 #endif
5141 load_case_tables();
5143 lp_load(dyn_CONFIGFILE,True,False,False,True);
5144 load_interfaces();
5146 if (argc < 2) {
5147 usage();
5150 for(p = argv[1]; *p; p++)
5151 if(*p == '\\')
5152 *p = '/';
5154 if (strncmp(argv[1], "//", 2)) {
5155 usage();
5158 fstrcpy(host, &argv[1][2]);
5159 p = strchr_m(&host[2],'/');
5160 if (!p) {
5161 usage();
5163 *p = 0;
5164 fstrcpy(share, p+1);
5166 get_myname(myname);
5168 if (*username == 0 && getenv("LOGNAME")) {
5169 fstrcpy(username,getenv("LOGNAME"));
5172 argc--;
5173 argv++;
5175 srandom(time(NULL));
5177 fstrcpy(workgroup, lp_workgroup());
5179 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
5180 switch (opt) {
5181 case 'p':
5182 port_to_use = atoi(optarg);
5183 break;
5184 case 's':
5185 srandom(atoi(optarg));
5186 break;
5187 case 'W':
5188 fstrcpy(workgroup,optarg);
5189 break;
5190 case 'm':
5191 max_protocol = interpret_protocol(optarg, max_protocol);
5192 break;
5193 case 'N':
5194 nprocs = atoi(optarg);
5195 break;
5196 case 'o':
5197 torture_numops = atoi(optarg);
5198 break;
5199 case 'd':
5200 DEBUGLEVEL = atoi(optarg);
5201 break;
5202 case 'O':
5203 sockops = optarg;
5204 break;
5205 case 'L':
5206 use_oplocks = True;
5207 break;
5208 case 'A':
5209 torture_showall = True;
5210 break;
5211 case 'n':
5212 fstrcpy(myname, optarg);
5213 break;
5214 case 'c':
5215 client_txt = optarg;
5216 break;
5217 case 'k':
5218 #ifdef HAVE_KRB5
5219 use_kerberos = True;
5220 #else
5221 d_printf("No kerberos support compiled in\n");
5222 exit(1);
5223 #endif
5224 break;
5225 case 'U':
5226 gotuser = 1;
5227 fstrcpy(username,optarg);
5228 p = strchr_m(username,'%');
5229 if (p) {
5230 *p = 0;
5231 fstrcpy(password, p+1);
5232 gotpass = 1;
5234 break;
5235 case 'b':
5236 fstrcpy(multishare_conn_fname, optarg);
5237 use_multishare_conn = True;
5238 break;
5239 default:
5240 printf("Unknown option %c (%d)\n", (char)opt, opt);
5241 usage();
5245 if(use_kerberos && !gotuser) gotpass = True;
5247 while (!gotpass) {
5248 p = getpass("Password:");
5249 if (p) {
5250 fstrcpy(password, p);
5251 gotpass = 1;
5255 printf("host=%s share=%s user=%s myname=%s\n",
5256 host, share, username, myname);
5258 if (argc == optind) {
5259 correct = run_test("ALL");
5260 } else {
5261 for (i=optind;i<argc;i++) {
5262 if (!run_test(argv[i])) {
5263 correct = False;
5268 if (correct) {
5269 return(0);
5270 } else {
5271 return(1);