r22001: change prototype of dump_data(), so that it takes unsigned char * now,
[Samba.git] / source / torture / torture.c
blob39495c6a3e7b2c3ccc23a9a24287b8d2d019ba5c
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;
106 make_nmb_name(&calling, myname, 0x0);
107 make_nmb_name(&called , host, 0x20);
109 zero_ip(&ip);
111 if (!(c = cli_initialise())) {
112 printf("Failed initialize cli_struct to connect with %s\n", host);
113 return NULL;
116 c->port = port_to_use;
118 if (!cli_connect(c, host, &ip)) {
119 printf("Failed to connect with %s\n", host);
120 return NULL;
123 c->use_kerberos = use_kerberos;
125 c->timeout = 120000; /* set a really long timeout (2 minutes) */
126 if (use_oplocks) c->use_oplocks = True;
127 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
129 if (!cli_session_request(c, &calling, &called)) {
131 * Well, that failed, try *SMBSERVER ...
132 * However, we must reconnect as well ...
134 if (!cli_connect(c, host, &ip)) {
135 printf("Failed to connect with %s\n", host);
136 return NULL;
139 make_nmb_name(&called, "*SMBSERVER", 0x20);
140 if (!cli_session_request(c, &calling, &called)) {
141 printf("%s rejected the session\n",host);
142 printf("We tried with a called name of %s & %s\n",
143 host, "*SMBSERVER");
144 cli_shutdown(c);
145 return NULL;
149 return c;
152 /* Insert a NULL at the first separator of the given path and return a pointer
153 * to the remainder of the string.
155 static char *
156 terminate_path_at_separator(char * path)
158 char * p;
160 if (!path) {
161 return NULL;
164 if ((p = strchr_m(path, '/'))) {
165 *p = '\0';
166 return p + 1;
169 if ((p = strchr_m(path, '\\'))) {
170 *p = '\0';
171 return p + 1;
174 /* No separator. */
175 return NULL;
179 parse a //server/share type UNC name
181 BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
182 char **hostname, char **sharename)
184 char *p;
186 *hostname = *sharename = NULL;
188 if (strncmp(unc_name, "\\\\", 2) &&
189 strncmp(unc_name, "//", 2)) {
190 return False;
193 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
194 p = terminate_path_at_separator(*hostname);
196 if (p && *p) {
197 *sharename = talloc_strdup(mem_ctx, p);
198 terminate_path_at_separator(*sharename);
201 if (*hostname && *sharename) {
202 return True;
205 TALLOC_FREE(*hostname);
206 TALLOC_FREE(*sharename);
207 return False;
210 static BOOL torture_open_connection_share(struct cli_state **c,
211 const char *hostname,
212 const char *sharename)
214 BOOL retry;
215 int flags = 0;
216 NTSTATUS status;
218 if (use_kerberos)
219 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
221 status = cli_full_connection(c, myname,
222 hostname, NULL, port_to_use,
223 sharename, "?????",
224 username, workgroup,
225 password, flags, Undefined, &retry);
226 if (!NT_STATUS_IS_OK(status)) {
227 printf("failed to open share connection: //%s/%s port:%d - %s\n",
228 hostname, sharename, port_to_use, nt_errstr(status));
229 return False;
232 if (use_oplocks) (*c)->use_oplocks = True;
233 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
234 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
236 return True;
239 void torture_open_connection_free_unclist(char **unc_list)
241 if (unc_list!=NULL)
243 SAFE_FREE(unc_list[0]);
244 SAFE_FREE(unc_list);
248 BOOL torture_open_connection(struct cli_state **c, int conn_index)
250 char **unc_list = NULL;
251 int num_unc_names = 0;
252 BOOL result;
254 if (use_multishare_conn==True) {
255 char *h, *s;
256 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
257 if (!unc_list || num_unc_names <= 0) {
258 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
259 exit(1);
262 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
263 NULL, &h, &s)) {
264 printf("Failed to parse UNC name %s\n",
265 unc_list[conn_index % num_unc_names]);
266 torture_open_connection_free_unclist(unc_list);
267 exit(1);
270 result = torture_open_connection_share(c, h, s);
272 /* h, s were copied earlier */
273 torture_open_connection_free_unclist(unc_list);
274 return result;
277 return torture_open_connection_share(c, host, share);
280 BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
282 uint16 old_vuid = cli->vuid;
283 fstring old_user_name;
284 size_t passlen = strlen(password);
285 BOOL ret;
287 fstrcpy(old_user_name, cli->user_name);
288 cli->vuid = 0;
289 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
290 password, passlen,
291 password, passlen,
292 workgroup));
293 *new_vuid = cli->vuid;
294 cli->vuid = old_vuid;
295 fstrcpy(cli->user_name, old_user_name);
296 return ret;
300 BOOL torture_close_connection(struct cli_state *c)
302 BOOL ret = True;
303 if (!cli_tdis(c)) {
304 printf("tdis failed (%s)\n", cli_errstr(c));
305 ret = False;
308 cli_shutdown(c);
310 return ret;
314 /* check if the server produced the expected error code */
315 static BOOL check_error(int line, struct cli_state *c,
316 uint8 eclass, uint32 ecode, NTSTATUS nterr)
318 if (cli_is_dos_error(c)) {
319 uint8 cclass;
320 uint32 num;
322 /* Check DOS error */
324 cli_dos_error(c, &cclass, &num);
326 if (eclass != cclass || ecode != num) {
327 printf("unexpected error code class=%d code=%d\n",
328 (int)cclass, (int)num);
329 printf(" expected %d/%d %s (line=%d)\n",
330 (int)eclass, (int)ecode, nt_errstr(nterr), line);
331 return False;
334 } else {
335 NTSTATUS status;
337 /* Check NT error */
339 status = cli_nt_error(c);
341 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
342 printf("unexpected error code %s\n", nt_errstr(status));
343 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
344 return False;
348 return True;
352 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
354 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
355 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
357 return True;
361 static BOOL rw_torture(struct cli_state *c)
363 const char *lockfname = "\\torture.lck";
364 fstring fname;
365 int fnum;
366 int fnum2;
367 pid_t pid2, pid = getpid();
368 int i, j;
369 char buf[1024];
370 BOOL correct = True;
372 memset(buf, '\0', sizeof(buf));
374 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
375 DENY_NONE);
376 if (fnum2 == -1)
377 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
378 if (fnum2 == -1) {
379 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
380 return False;
384 for (i=0;i<torture_numops;i++) {
385 unsigned n = (unsigned)sys_random()%10;
386 if (i % 10 == 0) {
387 printf("%d\r", i); fflush(stdout);
389 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
391 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
392 return False;
395 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
396 if (fnum == -1) {
397 printf("open failed (%s)\n", cli_errstr(c));
398 correct = False;
399 break;
402 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
403 printf("write failed (%s)\n", cli_errstr(c));
404 correct = False;
407 for (j=0;j<50;j++) {
408 if (cli_write(c, fnum, 0, (char *)buf,
409 sizeof(pid)+(j*sizeof(buf)),
410 sizeof(buf)) != sizeof(buf)) {
411 printf("write failed (%s)\n", cli_errstr(c));
412 correct = False;
416 pid2 = 0;
418 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
419 printf("read failed (%s)\n", cli_errstr(c));
420 correct = False;
423 if (pid2 != pid) {
424 printf("data corruption!\n");
425 correct = False;
428 if (!cli_close(c, fnum)) {
429 printf("close failed (%s)\n", cli_errstr(c));
430 correct = False;
433 if (!cli_unlink(c, fname)) {
434 printf("unlink failed (%s)\n", cli_errstr(c));
435 correct = False;
438 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
439 printf("unlock failed (%s)\n", cli_errstr(c));
440 correct = False;
444 cli_close(c, fnum2);
445 cli_unlink(c, lockfname);
447 printf("%d\n", i);
449 return correct;
452 static BOOL run_torture(int dummy)
454 struct cli_state *cli;
455 BOOL ret;
457 cli = current_cli;
459 cli_sockopt(cli, sockops);
461 ret = rw_torture(cli);
463 if (!torture_close_connection(cli)) {
464 ret = False;
467 return ret;
470 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
472 int fnum = -1;
473 unsigned int i = 0;
474 char buf[131072];
475 char buf_rd[131072];
476 unsigned count;
477 unsigned countprev = 0;
478 ssize_t sent = 0;
479 BOOL correct = True;
481 srandom(1);
482 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
484 SIVAL(buf, i, sys_random());
487 if (procnum == 0)
489 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
490 DENY_NONE);
491 if (fnum == -1) {
492 printf("first open read/write of %s failed (%s)\n",
493 lockfname, cli_errstr(c));
494 return False;
497 else
499 for (i = 0; i < 500 && fnum == -1; i++)
501 fnum = cli_open(c, lockfname, O_RDONLY,
502 DENY_NONE);
503 smb_msleep(10);
505 if (fnum == -1) {
506 printf("second open read-only of %s failed (%s)\n",
507 lockfname, cli_errstr(c));
508 return False;
512 i = 0;
513 for (count = 0; count < sizeof(buf); count += sent)
515 if (count >= countprev) {
516 printf("%d %8d\r", i, count);
517 fflush(stdout);
518 i++;
519 countprev += (sizeof(buf) / 20);
522 if (procnum == 0)
524 sent = ((unsigned)sys_random()%(20))+ 1;
525 if (sent > sizeof(buf) - count)
527 sent = sizeof(buf) - count;
530 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
531 printf("write failed (%s)\n", cli_errstr(c));
532 correct = False;
535 else
537 sent = cli_read(c, fnum, buf_rd+count, count,
538 sizeof(buf)-count);
539 if (sent < 0)
541 printf("read failed offset:%d size:%ld (%s)\n",
542 count, (unsigned long)sizeof(buf)-count,
543 cli_errstr(c));
544 correct = False;
545 sent = 0;
547 if (sent > 0)
549 if (memcmp(buf_rd+count, buf+count, sent) != 0)
551 printf("read/write compare failed\n");
552 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
553 correct = False;
554 break;
561 if (!cli_close(c, fnum)) {
562 printf("close failed (%s)\n", cli_errstr(c));
563 correct = False;
566 return correct;
569 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
571 const char *lockfname = "\\torture2.lck";
572 int fnum1;
573 int fnum2;
574 int i;
575 char buf[131072];
576 char buf_rd[131072];
577 BOOL correct = True;
578 ssize_t bytes_read;
580 if (!cli_unlink(c1, lockfname)) {
581 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
584 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
585 DENY_NONE);
586 if (fnum1 == -1) {
587 printf("first open read/write of %s failed (%s)\n",
588 lockfname, cli_errstr(c1));
589 return False;
591 fnum2 = cli_open(c2, lockfname, O_RDONLY,
592 DENY_NONE);
593 if (fnum2 == -1) {
594 printf("second open read-only of %s failed (%s)\n",
595 lockfname, cli_errstr(c2));
596 cli_close(c1, fnum1);
597 return False;
600 for (i=0;i<torture_numops;i++)
602 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
603 if (i % 10 == 0) {
604 printf("%d\r", i); fflush(stdout);
607 generate_random_buffer((unsigned char *)buf, buf_size);
609 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
610 printf("write failed (%s)\n", cli_errstr(c1));
611 correct = False;
612 break;
615 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
616 printf("read failed (%s)\n", cli_errstr(c2));
617 printf("read %d, expected %ld\n", (int)bytes_read,
618 (unsigned long)buf_size);
619 correct = False;
620 break;
623 if (memcmp(buf_rd, buf, buf_size) != 0)
625 printf("read/write compare failed\n");
626 correct = False;
627 break;
631 if (!cli_close(c2, fnum2)) {
632 printf("close failed (%s)\n", cli_errstr(c2));
633 correct = False;
635 if (!cli_close(c1, fnum1)) {
636 printf("close failed (%s)\n", cli_errstr(c1));
637 correct = False;
640 if (!cli_unlink(c1, lockfname)) {
641 printf("unlink failed (%s)\n", cli_errstr(c1));
642 correct = False;
645 return correct;
648 static BOOL run_readwritetest(int dummy)
650 static struct cli_state *cli1, *cli2;
651 BOOL test1, test2 = False;
653 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
654 return False;
656 cli_sockopt(cli1, sockops);
657 cli_sockopt(cli2, sockops);
659 printf("starting readwritetest\n");
661 test1 = rw_torture2(cli1, cli2);
662 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
664 if (test1) {
665 test2 = rw_torture2(cli1, cli1);
666 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
669 if (!torture_close_connection(cli1)) {
670 test1 = False;
673 if (!torture_close_connection(cli2)) {
674 test2 = False;
677 return (test1 && test2);
680 static BOOL run_readwritemulti(int dummy)
682 struct cli_state *cli;
683 BOOL test;
685 cli = current_cli;
687 cli_sockopt(cli, sockops);
689 printf("run_readwritemulti: fname %s\n", randomfname);
690 test = rw_torture3(cli, randomfname);
692 if (!torture_close_connection(cli)) {
693 test = False;
696 return test;
699 static BOOL run_readwritelarge(int dummy)
701 static struct cli_state *cli1;
702 int fnum1;
703 const char *lockfname = "\\large.dat";
704 SMB_OFF_T fsize;
705 char buf[126*1024];
706 BOOL correct = True;
708 if (!torture_open_connection(&cli1, 0)) {
709 return False;
711 cli_sockopt(cli1, sockops);
712 memset(buf,'\0',sizeof(buf));
714 cli1->max_xmit = 128*1024;
716 printf("starting readwritelarge\n");
718 cli_unlink(cli1, lockfname);
720 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
721 if (fnum1 == -1) {
722 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
723 return False;
726 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
728 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
729 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
730 correct = False;
733 if (fsize == sizeof(buf))
734 printf("readwritelarge test 1 succeeded (size = %lx)\n",
735 (unsigned long)fsize);
736 else {
737 printf("readwritelarge test 1 failed (size = %lx)\n",
738 (unsigned long)fsize);
739 correct = False;
742 if (!cli_close(cli1, fnum1)) {
743 printf("close failed (%s)\n", cli_errstr(cli1));
744 correct = False;
747 if (!cli_unlink(cli1, lockfname)) {
748 printf("unlink failed (%s)\n", cli_errstr(cli1));
749 correct = False;
752 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
753 if (fnum1 == -1) {
754 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
755 return False;
758 cli1->max_xmit = 4*1024;
760 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
762 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
763 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
764 correct = False;
767 if (fsize == sizeof(buf))
768 printf("readwritelarge test 2 succeeded (size = %lx)\n",
769 (unsigned long)fsize);
770 else {
771 printf("readwritelarge test 2 failed (size = %lx)\n",
772 (unsigned long)fsize);
773 correct = False;
776 #if 0
777 /* ToDo - set allocation. JRA */
778 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
779 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
780 return False;
782 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
783 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
784 correct = False;
786 if (fsize != 0)
787 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
788 #endif
790 if (!cli_close(cli1, fnum1)) {
791 printf("close failed (%s)\n", cli_errstr(cli1));
792 correct = False;
795 if (!torture_close_connection(cli1)) {
796 correct = False;
798 return correct;
801 int line_count = 0;
802 int nbio_id;
804 #define ival(s) strtol(s, NULL, 0)
806 /* run a test that simulates an approximate netbench client load */
807 static BOOL run_netbench(int client)
809 struct cli_state *cli;
810 int i;
811 pstring line;
812 char cname[20];
813 FILE *f;
814 const char *params[20];
815 BOOL correct = True;
817 cli = current_cli;
819 nbio_id = client;
821 cli_sockopt(cli, sockops);
823 nb_setup(cli);
825 slprintf(cname,sizeof(cname)-1, "client%d", client);
827 f = fopen(client_txt, "r");
829 if (!f) {
830 perror(client_txt);
831 return False;
834 while (fgets(line, sizeof(line)-1, f)) {
835 line_count++;
837 line[strlen(line)-1] = 0;
839 /* printf("[%d] %s\n", line_count, line); */
841 all_string_sub(line,"client1", cname, sizeof(line));
843 /* parse the command parameters */
844 params[0] = strtok(line," ");
845 i = 0;
846 while (params[i]) params[++i] = strtok(NULL," ");
848 params[i] = "";
850 if (i < 2) continue;
852 if (!strncmp(params[0],"SMB", 3)) {
853 printf("ERROR: You are using a dbench 1 load file\n");
854 exit(1);
857 if (!strcmp(params[0],"NTCreateX")) {
858 nb_createx(params[1], ival(params[2]), ival(params[3]),
859 ival(params[4]));
860 } else if (!strcmp(params[0],"Close")) {
861 nb_close(ival(params[1]));
862 } else if (!strcmp(params[0],"Rename")) {
863 nb_rename(params[1], params[2]);
864 } else if (!strcmp(params[0],"Unlink")) {
865 nb_unlink(params[1]);
866 } else if (!strcmp(params[0],"Deltree")) {
867 nb_deltree(params[1]);
868 } else if (!strcmp(params[0],"Rmdir")) {
869 nb_rmdir(params[1]);
870 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
871 nb_qpathinfo(params[1]);
872 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
873 nb_qfileinfo(ival(params[1]));
874 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
875 nb_qfsinfo(ival(params[1]));
876 } else if (!strcmp(params[0],"FIND_FIRST")) {
877 nb_findfirst(params[1]);
878 } else if (!strcmp(params[0],"WriteX")) {
879 nb_writex(ival(params[1]),
880 ival(params[2]), ival(params[3]), ival(params[4]));
881 } else if (!strcmp(params[0],"ReadX")) {
882 nb_readx(ival(params[1]),
883 ival(params[2]), ival(params[3]), ival(params[4]));
884 } else if (!strcmp(params[0],"Flush")) {
885 nb_flush(ival(params[1]));
886 } else {
887 printf("Unknown operation %s\n", params[0]);
888 exit(1);
891 fclose(f);
893 nb_cleanup();
895 if (!torture_close_connection(cli)) {
896 correct = False;
899 return correct;
903 /* run a test that simulates an approximate netbench client load */
904 static BOOL run_nbench(int dummy)
906 double t;
907 BOOL correct = True;
909 nbio_shmem(nprocs);
911 nbio_id = -1;
913 signal(SIGALRM, nb_alarm);
914 alarm(1);
915 t = create_procs(run_netbench, &correct);
916 alarm(0);
918 printf("\nThroughput %g MB/sec\n",
919 1.0e-6 * nbio_total() / t);
920 return correct;
925 This test checks for two things:
927 1) correct support for retaining locks over a close (ie. the server
928 must not use posix semantics)
929 2) support for lock timeouts
931 static BOOL run_locktest1(int dummy)
933 struct cli_state *cli1, *cli2;
934 const char *fname = "\\lockt1.lck";
935 int fnum1, fnum2, fnum3;
936 time_t t1, t2;
937 unsigned lock_timeout;
939 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
940 return False;
942 cli_sockopt(cli1, sockops);
943 cli_sockopt(cli2, sockops);
945 printf("starting locktest1\n");
947 cli_unlink(cli1, fname);
949 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
950 if (fnum1 == -1) {
951 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
952 return False;
954 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
955 if (fnum2 == -1) {
956 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
957 return False;
959 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
960 if (fnum3 == -1) {
961 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
962 return False;
965 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
966 printf("lock1 failed (%s)\n", cli_errstr(cli1));
967 return False;
971 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
972 printf("lock2 succeeded! This is a locking bug\n");
973 return False;
974 } else {
975 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
976 NT_STATUS_LOCK_NOT_GRANTED)) return False;
980 lock_timeout = (1 + (random() % 20));
981 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
982 t1 = time(NULL);
983 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
984 printf("lock3 succeeded! This is a locking bug\n");
985 return False;
986 } else {
987 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
988 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
990 t2 = time(NULL);
992 if (ABS(t2 - t1) < lock_timeout-1) {
993 printf("error: This server appears not to support timed lock requests\n");
996 printf("server slept for %u seconds for a %u second timeout\n",
997 (unsigned int)(t2-t1), lock_timeout);
999 if (!cli_close(cli1, fnum2)) {
1000 printf("close1 failed (%s)\n", cli_errstr(cli1));
1001 return False;
1004 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1005 printf("lock4 succeeded! This is a locking bug\n");
1006 return False;
1007 } else {
1008 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1009 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1012 if (!cli_close(cli1, fnum1)) {
1013 printf("close2 failed (%s)\n", cli_errstr(cli1));
1014 return False;
1017 if (!cli_close(cli2, fnum3)) {
1018 printf("close3 failed (%s)\n", cli_errstr(cli2));
1019 return False;
1022 if (!cli_unlink(cli1, fname)) {
1023 printf("unlink failed (%s)\n", cli_errstr(cli1));
1024 return False;
1028 if (!torture_close_connection(cli1)) {
1029 return False;
1032 if (!torture_close_connection(cli2)) {
1033 return False;
1036 printf("Passed locktest1\n");
1037 return True;
1041 this checks to see if a secondary tconx can use open files from an
1042 earlier tconx
1044 static BOOL run_tcon_test(int dummy)
1046 static struct cli_state *cli;
1047 const char *fname = "\\tcontest.tmp";
1048 int fnum1;
1049 uint16 cnum1, cnum2, cnum3;
1050 uint16 vuid1, vuid2;
1051 char buf[4];
1052 BOOL ret = True;
1054 memset(buf, '\0', sizeof(buf));
1056 if (!torture_open_connection(&cli, 0)) {
1057 return False;
1059 cli_sockopt(cli, sockops);
1061 printf("starting tcontest\n");
1063 cli_unlink(cli, fname);
1065 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1066 if (fnum1 == -1) {
1067 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1068 return False;
1071 cnum1 = cli->cnum;
1072 vuid1 = cli->vuid;
1074 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1075 printf("initial write failed (%s)", cli_errstr(cli));
1076 return False;
1079 if (!cli_send_tconX(cli, share, "?????",
1080 password, strlen(password)+1)) {
1081 printf("%s refused 2nd tree connect (%s)\n", host,
1082 cli_errstr(cli));
1083 cli_shutdown(cli);
1084 return False;
1087 cnum2 = cli->cnum;
1088 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1089 vuid2 = cli->vuid + 1;
1091 /* try a write with the wrong tid */
1092 cli->cnum = cnum2;
1094 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1095 printf("* server allows write with wrong TID\n");
1096 ret = False;
1097 } else {
1098 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1102 /* try a write with an invalid tid */
1103 cli->cnum = cnum3;
1105 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1106 printf("* server allows write with invalid TID\n");
1107 ret = False;
1108 } else {
1109 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1112 /* try a write with an invalid vuid */
1113 cli->vuid = vuid2;
1114 cli->cnum = cnum1;
1116 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1117 printf("* server allows write with invalid VUID\n");
1118 ret = False;
1119 } else {
1120 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1123 cli->cnum = cnum1;
1124 cli->vuid = vuid1;
1126 if (!cli_close(cli, fnum1)) {
1127 printf("close failed (%s)\n", cli_errstr(cli));
1128 return False;
1131 cli->cnum = cnum2;
1133 if (!cli_tdis(cli)) {
1134 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1135 return False;
1138 cli->cnum = cnum1;
1140 if (!torture_close_connection(cli)) {
1141 return False;
1144 return ret;
1149 checks for old style tcon support
1151 static BOOL run_tcon2_test(int dummy)
1153 static struct cli_state *cli;
1154 uint16 cnum, max_xmit;
1155 char *service;
1156 NTSTATUS status;
1158 if (!torture_open_connection(&cli, 0)) {
1159 return False;
1161 cli_sockopt(cli, sockops);
1163 printf("starting tcon2 test\n");
1165 asprintf(&service, "\\\\%s\\%s", host, share);
1167 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 printf("tcon2 failed : %s\n", cli_errstr(cli));
1171 } else {
1172 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1173 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1176 if (!torture_close_connection(cli)) {
1177 return False;
1180 printf("Passed tcon2 test\n");
1181 return True;
1184 static BOOL tcon_devtest(struct cli_state *cli,
1185 const char *myshare, const char *devtype,
1186 const char *return_devtype,
1187 NTSTATUS expected_error)
1189 BOOL status;
1190 BOOL ret;
1192 status = cli_send_tconX(cli, myshare, devtype,
1193 password, strlen(password)+1);
1195 if (NT_STATUS_IS_OK(expected_error)) {
1196 if (status) {
1197 if (strcmp(cli->dev, return_devtype) == 0) {
1198 ret = True;
1199 } else {
1200 printf("tconX to share %s with type %s "
1201 "succeeded but returned the wrong "
1202 "device type (got [%s] but should have got [%s])\n",
1203 myshare, devtype, cli->dev, return_devtype);
1204 ret = False;
1206 } else {
1207 printf("tconX to share %s with type %s "
1208 "should have succeeded but failed\n",
1209 myshare, devtype);
1210 ret = False;
1212 cli_tdis(cli);
1213 } else {
1214 if (status) {
1215 printf("tconx to share %s with type %s "
1216 "should have failed but succeeded\n",
1217 myshare, devtype);
1218 ret = False;
1219 } else {
1220 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1221 expected_error)) {
1222 ret = True;
1223 } else {
1224 printf("Returned unexpected error\n");
1225 ret = False;
1229 return ret;
1233 checks for correct tconX support
1235 static BOOL run_tcon_devtype_test(int dummy)
1237 static struct cli_state *cli1 = NULL;
1238 BOOL retry;
1239 int flags = 0;
1240 NTSTATUS status;
1241 BOOL ret = True;
1243 status = cli_full_connection(&cli1, myname,
1244 host, NULL, port_to_use,
1245 NULL, NULL,
1246 username, workgroup,
1247 password, flags, Undefined, &retry);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 printf("could not open connection\n");
1251 return False;
1254 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1255 ret = False;
1257 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1258 ret = False;
1260 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1261 ret = False;
1263 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1264 ret = False;
1266 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1267 ret = False;
1269 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1270 ret = False;
1272 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1273 ret = False;
1275 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1276 ret = False;
1278 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1279 ret = False;
1281 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1282 ret = False;
1284 cli_shutdown(cli1);
1286 if (ret)
1287 printf("Passed tcondevtest\n");
1289 return ret;
1294 This test checks that
1296 1) the server supports multiple locking contexts on the one SMB
1297 connection, distinguished by PID.
1299 2) the server correctly fails overlapping locks made by the same PID (this
1300 goes against POSIX behaviour, which is why it is tricky to implement)
1302 3) the server denies unlock requests by an incorrect client PID
1304 static BOOL run_locktest2(int dummy)
1306 static struct cli_state *cli;
1307 const char *fname = "\\lockt2.lck";
1308 int fnum1, fnum2, fnum3;
1309 BOOL correct = True;
1311 if (!torture_open_connection(&cli, 0)) {
1312 return False;
1315 cli_sockopt(cli, sockops);
1317 printf("starting locktest2\n");
1319 cli_unlink(cli, fname);
1321 cli_setpid(cli, 1);
1323 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1324 if (fnum1 == -1) {
1325 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1326 return False;
1329 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1330 if (fnum2 == -1) {
1331 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1332 return False;
1335 cli_setpid(cli, 2);
1337 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1338 if (fnum3 == -1) {
1339 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1340 return False;
1343 cli_setpid(cli, 1);
1345 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1346 printf("lock1 failed (%s)\n", cli_errstr(cli));
1347 return False;
1350 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1351 printf("WRITE lock1 succeeded! This is a locking bug\n");
1352 correct = False;
1353 } else {
1354 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1355 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1358 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1359 printf("WRITE lock2 succeeded! This is a locking bug\n");
1360 correct = False;
1361 } else {
1362 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1363 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1366 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1367 printf("READ lock2 succeeded! This is a locking bug\n");
1368 correct = False;
1369 } else {
1370 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1371 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1374 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1375 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1377 cli_setpid(cli, 2);
1378 if (cli_unlock(cli, fnum1, 100, 4)) {
1379 printf("unlock at 100 succeeded! This is a locking bug\n");
1380 correct = False;
1383 if (cli_unlock(cli, fnum1, 0, 4)) {
1384 printf("unlock1 succeeded! This is a locking bug\n");
1385 correct = False;
1386 } else {
1387 if (!check_error(__LINE__, cli,
1388 ERRDOS, ERRlock,
1389 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1392 if (cli_unlock(cli, fnum1, 0, 8)) {
1393 printf("unlock2 succeeded! This is a locking bug\n");
1394 correct = False;
1395 } else {
1396 if (!check_error(__LINE__, cli,
1397 ERRDOS, ERRlock,
1398 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1401 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1402 printf("lock3 succeeded! This is a locking bug\n");
1403 correct = False;
1404 } else {
1405 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1408 cli_setpid(cli, 1);
1410 if (!cli_close(cli, fnum1)) {
1411 printf("close1 failed (%s)\n", cli_errstr(cli));
1412 return False;
1415 if (!cli_close(cli, fnum2)) {
1416 printf("close2 failed (%s)\n", cli_errstr(cli));
1417 return False;
1420 if (!cli_close(cli, fnum3)) {
1421 printf("close3 failed (%s)\n", cli_errstr(cli));
1422 return False;
1425 if (!torture_close_connection(cli)) {
1426 correct = False;
1429 printf("locktest2 finished\n");
1431 return correct;
1436 This test checks that
1438 1) the server supports the full offset range in lock requests
1440 static BOOL run_locktest3(int dummy)
1442 static struct cli_state *cli1, *cli2;
1443 const char *fname = "\\lockt3.lck";
1444 int fnum1, fnum2, i;
1445 uint32 offset;
1446 BOOL correct = True;
1448 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1450 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1451 return False;
1453 cli_sockopt(cli1, sockops);
1454 cli_sockopt(cli2, sockops);
1456 printf("starting locktest3\n");
1458 cli_unlink(cli1, fname);
1460 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1461 if (fnum1 == -1) {
1462 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1463 return False;
1465 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1466 if (fnum2 == -1) {
1467 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1468 return False;
1471 for (offset=i=0;i<torture_numops;i++) {
1472 NEXT_OFFSET;
1473 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1474 printf("lock1 %d failed (%s)\n",
1476 cli_errstr(cli1));
1477 return False;
1480 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1481 printf("lock2 %d failed (%s)\n",
1483 cli_errstr(cli1));
1484 return False;
1488 for (offset=i=0;i<torture_numops;i++) {
1489 NEXT_OFFSET;
1491 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1492 printf("error: lock1 %d succeeded!\n", i);
1493 return False;
1496 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1497 printf("error: lock2 %d succeeded!\n", i);
1498 return False;
1501 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1502 printf("error: lock3 %d succeeded!\n", i);
1503 return False;
1506 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1507 printf("error: lock4 %d succeeded!\n", i);
1508 return False;
1512 for (offset=i=0;i<torture_numops;i++) {
1513 NEXT_OFFSET;
1515 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1516 printf("unlock1 %d failed (%s)\n",
1518 cli_errstr(cli1));
1519 return False;
1522 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1523 printf("unlock2 %d failed (%s)\n",
1525 cli_errstr(cli1));
1526 return False;
1530 if (!cli_close(cli1, fnum1)) {
1531 printf("close1 failed (%s)\n", cli_errstr(cli1));
1532 return False;
1535 if (!cli_close(cli2, fnum2)) {
1536 printf("close2 failed (%s)\n", cli_errstr(cli2));
1537 return False;
1540 if (!cli_unlink(cli1, fname)) {
1541 printf("unlink failed (%s)\n", cli_errstr(cli1));
1542 return False;
1545 if (!torture_close_connection(cli1)) {
1546 correct = False;
1549 if (!torture_close_connection(cli2)) {
1550 correct = False;
1553 printf("finished locktest3\n");
1555 return correct;
1558 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1559 printf("** "); correct = False; \
1563 looks at overlapping locks
1565 static BOOL run_locktest4(int dummy)
1567 static struct cli_state *cli1, *cli2;
1568 const char *fname = "\\lockt4.lck";
1569 int fnum1, fnum2, f;
1570 BOOL ret;
1571 char buf[1000];
1572 BOOL correct = True;
1574 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1575 return False;
1578 cli_sockopt(cli1, sockops);
1579 cli_sockopt(cli2, sockops);
1581 printf("starting locktest4\n");
1583 cli_unlink(cli1, fname);
1585 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1586 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1588 memset(buf, 0, sizeof(buf));
1590 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1591 printf("Failed to create file\n");
1592 correct = False;
1593 goto fail;
1596 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1597 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1598 EXPECTED(ret, False);
1599 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1601 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1602 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1603 EXPECTED(ret, True);
1604 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1606 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1607 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1608 EXPECTED(ret, False);
1609 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1611 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1612 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1613 EXPECTED(ret, True);
1614 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1616 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1617 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1618 EXPECTED(ret, False);
1619 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1621 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1622 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1623 EXPECTED(ret, True);
1624 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1626 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1627 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1628 EXPECTED(ret, True);
1629 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1631 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1632 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1633 EXPECTED(ret, False);
1634 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1636 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1637 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1638 EXPECTED(ret, False);
1639 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1641 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1642 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1643 EXPECTED(ret, True);
1644 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1646 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1647 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1648 EXPECTED(ret, False);
1649 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1651 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1652 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1653 cli_unlock(cli1, fnum1, 110, 6);
1654 EXPECTED(ret, False);
1655 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1658 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1659 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1660 EXPECTED(ret, False);
1661 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1663 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1664 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1665 EXPECTED(ret, False);
1666 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1669 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1670 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1671 cli_unlock(cli1, fnum1, 140, 4) &&
1672 cli_unlock(cli1, fnum1, 140, 4);
1673 EXPECTED(ret, True);
1674 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1677 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1678 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1679 cli_unlock(cli1, fnum1, 150, 4) &&
1680 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1681 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1682 cli_unlock(cli1, fnum1, 150, 4);
1683 EXPECTED(ret, True);
1684 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1686 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1687 cli_unlock(cli1, fnum1, 160, 4) &&
1688 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1689 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1690 EXPECTED(ret, True);
1691 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1693 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1694 cli_unlock(cli1, fnum1, 170, 4) &&
1695 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1696 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1697 EXPECTED(ret, True);
1698 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1700 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1701 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1702 cli_unlock(cli1, fnum1, 190, 4) &&
1703 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1704 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1705 EXPECTED(ret, True);
1706 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1708 cli_close(cli1, fnum1);
1709 cli_close(cli2, fnum2);
1710 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1711 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1712 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1713 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1714 cli_close(cli1, fnum1) &&
1715 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1716 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1717 cli_close(cli1, f);
1718 cli_close(cli1, fnum1);
1719 EXPECTED(ret, True);
1720 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1722 fail:
1723 cli_close(cli1, fnum1);
1724 cli_close(cli2, fnum2);
1725 cli_unlink(cli1, fname);
1726 torture_close_connection(cli1);
1727 torture_close_connection(cli2);
1729 printf("finished locktest4\n");
1730 return correct;
1734 looks at lock upgrade/downgrade.
1736 static BOOL run_locktest5(int dummy)
1738 static struct cli_state *cli1, *cli2;
1739 const char *fname = "\\lockt5.lck";
1740 int fnum1, fnum2, fnum3;
1741 BOOL ret;
1742 char buf[1000];
1743 BOOL correct = True;
1745 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1746 return False;
1749 cli_sockopt(cli1, sockops);
1750 cli_sockopt(cli2, sockops);
1752 printf("starting locktest5\n");
1754 cli_unlink(cli1, fname);
1756 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1757 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1758 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1760 memset(buf, 0, sizeof(buf));
1762 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1763 printf("Failed to create file\n");
1764 correct = False;
1765 goto fail;
1768 /* Check for NT bug... */
1769 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1770 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1771 cli_close(cli1, fnum1);
1772 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1773 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1774 EXPECTED(ret, True);
1775 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1776 cli_close(cli1, fnum1);
1777 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1778 cli_unlock(cli1, fnum3, 0, 1);
1780 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1781 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1782 EXPECTED(ret, True);
1783 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1785 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1786 EXPECTED(ret, False);
1788 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1790 /* Unlock the process 2 lock. */
1791 cli_unlock(cli2, fnum2, 0, 4);
1793 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1794 EXPECTED(ret, False);
1796 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1798 /* Unlock the process 1 fnum3 lock. */
1799 cli_unlock(cli1, fnum3, 0, 4);
1801 /* Stack 2 more locks here. */
1802 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1803 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1805 EXPECTED(ret, True);
1806 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1808 /* Unlock the first process lock, then check this was the WRITE lock that was
1809 removed. */
1811 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1812 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1814 EXPECTED(ret, True);
1815 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1817 /* Unlock the process 2 lock. */
1818 cli_unlock(cli2, fnum2, 0, 4);
1820 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1822 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1823 cli_unlock(cli1, fnum1, 0, 4) &&
1824 cli_unlock(cli1, fnum1, 0, 4);
1826 EXPECTED(ret, True);
1827 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1829 /* Ensure the next unlock fails. */
1830 ret = cli_unlock(cli1, fnum1, 0, 4);
1831 EXPECTED(ret, False);
1832 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1834 /* Ensure connection 2 can get a write lock. */
1835 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1836 EXPECTED(ret, True);
1838 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1841 fail:
1842 cli_close(cli1, fnum1);
1843 cli_close(cli2, fnum2);
1844 cli_unlink(cli1, fname);
1845 if (!torture_close_connection(cli1)) {
1846 correct = False;
1848 if (!torture_close_connection(cli2)) {
1849 correct = False;
1852 printf("finished locktest5\n");
1854 return correct;
1858 tries the unusual lockingX locktype bits
1860 static BOOL run_locktest6(int dummy)
1862 static struct cli_state *cli;
1863 const char *fname[1] = { "\\lock6.txt" };
1864 int i;
1865 int fnum;
1866 NTSTATUS status;
1868 if (!torture_open_connection(&cli, 0)) {
1869 return False;
1872 cli_sockopt(cli, sockops);
1874 printf("starting locktest6\n");
1876 for (i=0;i<1;i++) {
1877 printf("Testing %s\n", fname[i]);
1879 cli_unlink(cli, fname[i]);
1881 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1882 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1883 cli_close(cli, fnum);
1884 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1886 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1887 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1888 cli_close(cli, fnum);
1889 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1891 cli_unlink(cli, fname[i]);
1894 torture_close_connection(cli);
1896 printf("finished locktest6\n");
1897 return True;
1900 static BOOL run_locktest7(int dummy)
1902 struct cli_state *cli1;
1903 const char *fname = "\\lockt7.lck";
1904 int fnum1;
1905 char buf[200];
1906 BOOL correct = False;
1908 if (!torture_open_connection(&cli1, 0)) {
1909 return False;
1912 cli_sockopt(cli1, sockops);
1914 printf("starting locktest7\n");
1916 cli_unlink(cli1, fname);
1918 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1920 memset(buf, 0, sizeof(buf));
1922 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1923 printf("Failed to create file\n");
1924 goto fail;
1927 cli_setpid(cli1, 1);
1929 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1930 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1931 goto fail;
1932 } else {
1933 printf("pid1 successfully locked range 130:4 for READ\n");
1936 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1937 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1938 goto fail;
1939 } else {
1940 printf("pid1 successfully read the range 130:4\n");
1943 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1944 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1945 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1946 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1947 goto fail;
1949 } else {
1950 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1951 goto fail;
1954 cli_setpid(cli1, 2);
1956 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1957 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1958 } else {
1959 printf("pid2 successfully read the range 130:4\n");
1962 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1963 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1964 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1965 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1966 goto fail;
1968 } else {
1969 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1970 goto fail;
1973 cli_setpid(cli1, 1);
1974 cli_unlock(cli1, fnum1, 130, 4);
1976 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1977 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1978 goto fail;
1979 } else {
1980 printf("pid1 successfully locked range 130:4 for WRITE\n");
1983 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1984 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1985 goto fail;
1986 } else {
1987 printf("pid1 successfully read the range 130:4\n");
1990 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1991 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1992 goto fail;
1993 } else {
1994 printf("pid1 successfully wrote to the range 130:4\n");
1997 cli_setpid(cli1, 2);
1999 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2000 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2001 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2002 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2003 goto fail;
2005 } else {
2006 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2007 goto fail;
2010 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2011 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2012 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2013 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2014 goto fail;
2016 } else {
2017 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2018 goto fail;
2021 cli_unlock(cli1, fnum1, 130, 0);
2022 correct = True;
2024 fail:
2025 cli_close(cli1, fnum1);
2026 cli_unlink(cli1, fname);
2027 torture_close_connection(cli1);
2029 printf("finished locktest7\n");
2030 return correct;
2034 test whether fnums and tids open on one VC are available on another (a major
2035 security hole)
2037 static BOOL run_fdpasstest(int dummy)
2039 struct cli_state *cli1, *cli2;
2040 const char *fname = "\\fdpass.tst";
2041 int fnum1;
2042 pstring buf;
2044 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2045 return False;
2047 cli_sockopt(cli1, sockops);
2048 cli_sockopt(cli2, sockops);
2050 printf("starting fdpasstest\n");
2052 cli_unlink(cli1, fname);
2054 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2055 if (fnum1 == -1) {
2056 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2057 return False;
2060 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2061 printf("write failed (%s)\n", cli_errstr(cli1));
2062 return False;
2065 cli2->vuid = cli1->vuid;
2066 cli2->cnum = cli1->cnum;
2067 cli2->pid = cli1->pid;
2069 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2070 printf("read succeeded! nasty security hole [%s]\n",
2071 buf);
2072 return False;
2075 cli_close(cli1, fnum1);
2076 cli_unlink(cli1, fname);
2078 torture_close_connection(cli1);
2079 torture_close_connection(cli2);
2081 printf("finished fdpasstest\n");
2082 return True;
2085 static BOOL run_fdsesstest(int dummy)
2087 struct cli_state *cli;
2088 uint16 new_vuid;
2089 uint16 saved_vuid;
2090 uint16 new_cnum;
2091 uint16 saved_cnum;
2092 const char *fname = "\\fdsess.tst";
2093 const char *fname1 = "\\fdsess1.tst";
2094 int fnum1;
2095 int fnum2;
2096 pstring buf;
2097 BOOL ret = True;
2099 if (!torture_open_connection(&cli, 0))
2100 return False;
2101 cli_sockopt(cli, sockops);
2103 if (!torture_cli_session_setup2(cli, &new_vuid))
2104 return False;
2106 saved_cnum = cli->cnum;
2107 if (!cli_send_tconX(cli, share, "?????", "", 1))
2108 return False;
2109 new_cnum = cli->cnum;
2110 cli->cnum = saved_cnum;
2112 printf("starting fdsesstest\n");
2114 cli_unlink(cli, fname);
2115 cli_unlink(cli, fname1);
2117 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2118 if (fnum1 == -1) {
2119 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2120 return False;
2123 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2124 printf("write failed (%s)\n", cli_errstr(cli));
2125 return False;
2128 saved_vuid = cli->vuid;
2129 cli->vuid = new_vuid;
2131 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2132 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2133 buf);
2134 ret = False;
2136 /* Try to open a file with different vuid, samba cnum. */
2137 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2138 if (fnum2 != -1) {
2139 printf("create with different vuid, same cnum succeeded.\n");
2140 cli_close(cli, fnum2);
2141 cli_unlink(cli, fname1);
2142 } else {
2143 printf("create with different vuid, same cnum failed.\n");
2144 printf("This will cause problems with service clients.\n");
2145 ret = False;
2148 cli->vuid = saved_vuid;
2150 /* Try with same vuid, different cnum. */
2151 cli->cnum = new_cnum;
2153 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2154 printf("read succeeded with different cnum![%s]\n",
2155 buf);
2156 ret = False;
2159 cli->cnum = saved_cnum;
2160 cli_close(cli, fnum1);
2161 cli_unlink(cli, fname);
2163 torture_close_connection(cli);
2165 printf("finished fdsesstest\n");
2166 return ret;
2170 This test checks that
2172 1) the server does not allow an unlink on a file that is open
2174 static BOOL run_unlinktest(int dummy)
2176 struct cli_state *cli;
2177 const char *fname = "\\unlink.tst";
2178 int fnum;
2179 BOOL correct = True;
2181 if (!torture_open_connection(&cli, 0)) {
2182 return False;
2185 cli_sockopt(cli, sockops);
2187 printf("starting unlink test\n");
2189 cli_unlink(cli, fname);
2191 cli_setpid(cli, 1);
2193 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2194 if (fnum == -1) {
2195 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2196 return False;
2199 if (cli_unlink(cli, fname)) {
2200 printf("error: server allowed unlink on an open file\n");
2201 correct = False;
2202 } else {
2203 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2204 NT_STATUS_SHARING_VIOLATION);
2207 cli_close(cli, fnum);
2208 cli_unlink(cli, fname);
2210 if (!torture_close_connection(cli)) {
2211 correct = False;
2214 printf("unlink test finished\n");
2216 return correct;
2221 test how many open files this server supports on the one socket
2223 static BOOL run_maxfidtest(int dummy)
2225 struct cli_state *cli;
2226 const char *ftemplate = "\\maxfid.%d.%d";
2227 fstring fname;
2228 int fnums[0x11000], i;
2229 int retries=4;
2230 BOOL correct = True;
2232 cli = current_cli;
2234 if (retries <= 0) {
2235 printf("failed to connect\n");
2236 return False;
2239 cli_sockopt(cli, sockops);
2241 for (i=0; i<0x11000; i++) {
2242 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2243 if ((fnums[i] = cli_open(cli, fname,
2244 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2245 -1) {
2246 printf("open of %s failed (%s)\n",
2247 fname, cli_errstr(cli));
2248 printf("maximum fnum is %d\n", i);
2249 break;
2251 printf("%6d\r", i);
2253 printf("%6d\n", i);
2254 i--;
2256 printf("cleaning up\n");
2257 for (;i>=0;i--) {
2258 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2259 cli_close(cli, fnums[i]);
2260 if (!cli_unlink(cli, fname)) {
2261 printf("unlink of %s failed (%s)\n",
2262 fname, cli_errstr(cli));
2263 correct = False;
2265 printf("%6d\r", i);
2267 printf("%6d\n", 0);
2269 printf("maxfid test finished\n");
2270 if (!torture_close_connection(cli)) {
2271 correct = False;
2273 return correct;
2276 /* generate a random buffer */
2277 static void rand_buf(char *buf, int len)
2279 while (len--) {
2280 *buf = (char)sys_random();
2281 buf++;
2285 /* send smb negprot commands, not reading the response */
2286 static BOOL run_negprot_nowait(int dummy)
2288 int i;
2289 static struct cli_state *cli;
2290 BOOL correct = True;
2292 printf("starting negprot nowait test\n");
2294 if (!(cli = open_nbt_connection())) {
2295 return False;
2298 for (i=0;i<50000;i++) {
2299 cli_negprot_send(cli);
2302 if (!torture_close_connection(cli)) {
2303 correct = False;
2306 printf("finished negprot nowait test\n");
2308 return correct;
2312 /* send random IPC commands */
2313 static BOOL run_randomipc(int dummy)
2315 char *rparam = NULL;
2316 char *rdata = NULL;
2317 unsigned int rdrcnt,rprcnt;
2318 pstring param;
2319 int api, param_len, i;
2320 struct cli_state *cli;
2321 BOOL correct = True;
2322 int count = 50000;
2324 printf("starting random ipc test\n");
2326 if (!torture_open_connection(&cli, 0)) {
2327 return False;
2330 for (i=0;i<count;i++) {
2331 api = sys_random() % 500;
2332 param_len = (sys_random() % 64);
2334 rand_buf(param, param_len);
2336 SSVAL(param,0,api);
2338 cli_api(cli,
2339 param, param_len, 8,
2340 NULL, 0, BUFFER_SIZE,
2341 &rparam, &rprcnt,
2342 &rdata, &rdrcnt);
2343 if (i % 100 == 0) {
2344 printf("%d/%d\r", i,count);
2347 printf("%d/%d\n", i, count);
2349 if (!torture_close_connection(cli)) {
2350 correct = False;
2353 printf("finished random ipc test\n");
2355 return correct;
2360 static void browse_callback(const char *sname, uint32 stype,
2361 const char *comment, void *state)
2363 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2369 This test checks the browse list code
2372 static BOOL run_browsetest(int dummy)
2374 static struct cli_state *cli;
2375 BOOL correct = True;
2377 printf("starting browse test\n");
2379 if (!torture_open_connection(&cli, 0)) {
2380 return False;
2383 printf("domain list:\n");
2384 cli_NetServerEnum(cli, cli->server_domain,
2385 SV_TYPE_DOMAIN_ENUM,
2386 browse_callback, NULL);
2388 printf("machine list:\n");
2389 cli_NetServerEnum(cli, cli->server_domain,
2390 SV_TYPE_ALL,
2391 browse_callback, NULL);
2393 if (!torture_close_connection(cli)) {
2394 correct = False;
2397 printf("browse test finished\n");
2399 return correct;
2405 This checks how the getatr calls works
2407 static BOOL run_attrtest(int dummy)
2409 struct cli_state *cli;
2410 int fnum;
2411 time_t t, t2;
2412 const char *fname = "\\attrib123456789.tst";
2413 BOOL correct = True;
2415 printf("starting attrib test\n");
2417 if (!torture_open_connection(&cli, 0)) {
2418 return False;
2421 cli_unlink(cli, fname);
2422 fnum = cli_open(cli, fname,
2423 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2424 cli_close(cli, fnum);
2425 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2426 printf("getatr failed (%s)\n", cli_errstr(cli));
2427 correct = False;
2430 if (abs(t - time(NULL)) > 60*60*24*10) {
2431 printf("ERROR: SMBgetatr bug. time is %s",
2432 ctime(&t));
2433 t = time(NULL);
2434 correct = True;
2437 t2 = t-60*60*24; /* 1 day ago */
2439 if (!cli_setatr(cli, fname, 0, t2)) {
2440 printf("setatr failed (%s)\n", cli_errstr(cli));
2441 correct = True;
2444 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2445 printf("getatr failed (%s)\n", cli_errstr(cli));
2446 correct = True;
2449 if (t != t2) {
2450 printf("ERROR: getatr/setatr bug. times are\n%s",
2451 ctime(&t));
2452 printf("%s", ctime(&t2));
2453 correct = True;
2456 cli_unlink(cli, fname);
2458 if (!torture_close_connection(cli)) {
2459 correct = False;
2462 printf("attrib test finished\n");
2464 return correct;
2469 This checks a couple of trans2 calls
2471 static BOOL run_trans2test(int dummy)
2473 struct cli_state *cli;
2474 int fnum;
2475 SMB_OFF_T size;
2476 time_t c_time, a_time, m_time;
2477 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2478 const char *fname = "\\trans2.tst";
2479 const char *dname = "\\trans2";
2480 const char *fname2 = "\\trans2\\trans2.tst";
2481 pstring pname;
2482 BOOL correct = True;
2484 printf("starting trans2 test\n");
2486 if (!torture_open_connection(&cli, 0)) {
2487 return False;
2490 cli_unlink(cli, fname);
2491 fnum = cli_open(cli, fname,
2492 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2493 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2494 &m_time_ts, NULL)) {
2495 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2496 correct = False;
2499 if (!cli_qfilename(cli, fnum, pname)) {
2500 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2501 correct = False;
2504 if (strcmp(pname, fname)) {
2505 printf("qfilename gave different name? [%s] [%s]\n",
2506 fname, pname);
2507 correct = False;
2510 cli_close(cli, fnum);
2512 sleep(2);
2514 cli_unlink(cli, fname);
2515 fnum = cli_open(cli, fname,
2516 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2517 if (fnum == -1) {
2518 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2519 return False;
2521 cli_close(cli, fnum);
2523 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2524 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2525 correct = False;
2526 } else {
2527 if (c_time != m_time) {
2528 printf("create time=%s", ctime(&c_time));
2529 printf("modify time=%s", ctime(&m_time));
2530 printf("This system appears to have sticky create times\n");
2532 if (a_time % (60*60) == 0) {
2533 printf("access time=%s", ctime(&a_time));
2534 printf("This system appears to set a midnight access time\n");
2535 correct = False;
2538 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2539 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2540 correct = False;
2545 cli_unlink(cli, fname);
2546 fnum = cli_open(cli, fname,
2547 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2548 cli_close(cli, fnum);
2549 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2550 &m_time_ts, &size, NULL, NULL)) {
2551 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2552 correct = False;
2553 } else {
2554 if (w_time_ts.tv_sec < 60*60*24*2) {
2555 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2556 printf("This system appears to set a initial 0 write time\n");
2557 correct = False;
2561 cli_unlink(cli, fname);
2564 /* check if the server updates the directory modification time
2565 when creating a new file */
2566 if (!cli_mkdir(cli, dname)) {
2567 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2568 correct = False;
2570 sleep(3);
2571 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2572 &m_time_ts, &size, NULL, NULL)) {
2573 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2574 correct = False;
2577 fnum = cli_open(cli, fname2,
2578 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2579 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2580 cli_close(cli, fnum);
2581 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2582 &m_time2_ts, &size, NULL, NULL)) {
2583 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2584 correct = False;
2585 } else {
2586 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2587 == 0) {
2588 printf("This system does not update directory modification times\n");
2589 correct = False;
2592 cli_unlink(cli, fname2);
2593 cli_rmdir(cli, dname);
2595 if (!torture_close_connection(cli)) {
2596 correct = False;
2599 printf("trans2 test finished\n");
2601 return correct;
2605 This checks new W2K calls.
2608 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2610 char *buf = NULL;
2611 uint32 len;
2612 BOOL correct = True;
2614 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2615 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2616 correct = False;
2617 } else {
2618 printf("qfileinfo: level %d, len = %u\n", level, len);
2619 dump_data(0, (uint8 *)buf, len);
2620 printf("\n");
2622 SAFE_FREE(buf);
2623 return correct;
2626 static BOOL run_w2ktest(int dummy)
2628 struct cli_state *cli;
2629 int fnum;
2630 const char *fname = "\\w2ktest\\w2k.tst";
2631 int level;
2632 BOOL correct = True;
2634 printf("starting w2k test\n");
2636 if (!torture_open_connection(&cli, 0)) {
2637 return False;
2640 fnum = cli_open(cli, fname,
2641 O_RDWR | O_CREAT , DENY_NONE);
2643 for (level = 1004; level < 1040; level++) {
2644 new_trans(cli, fnum, level);
2647 cli_close(cli, fnum);
2649 if (!torture_close_connection(cli)) {
2650 correct = False;
2653 printf("w2k test finished\n");
2655 return correct;
2660 this is a harness for some oplock tests
2662 static BOOL run_oplock1(int dummy)
2664 struct cli_state *cli1;
2665 const char *fname = "\\lockt1.lck";
2666 int fnum1;
2667 BOOL correct = True;
2669 printf("starting oplock test 1\n");
2671 if (!torture_open_connection(&cli1, 0)) {
2672 return False;
2675 cli_unlink(cli1, fname);
2677 cli_sockopt(cli1, sockops);
2679 cli1->use_oplocks = True;
2681 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2682 if (fnum1 == -1) {
2683 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2684 return False;
2687 cli1->use_oplocks = False;
2689 cli_unlink(cli1, fname);
2690 cli_unlink(cli1, fname);
2692 if (!cli_close(cli1, fnum1)) {
2693 printf("close2 failed (%s)\n", cli_errstr(cli1));
2694 return False;
2697 if (!cli_unlink(cli1, fname)) {
2698 printf("unlink failed (%s)\n", cli_errstr(cli1));
2699 return False;
2702 if (!torture_close_connection(cli1)) {
2703 correct = False;
2706 printf("finished oplock test 1\n");
2708 return correct;
2711 static BOOL run_oplock2(int dummy)
2713 struct cli_state *cli1, *cli2;
2714 const char *fname = "\\lockt2.lck";
2715 int fnum1, fnum2;
2716 int saved_use_oplocks = use_oplocks;
2717 char buf[4];
2718 BOOL correct = True;
2719 volatile BOOL *shared_correct;
2721 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2722 *shared_correct = True;
2724 use_level_II_oplocks = True;
2725 use_oplocks = True;
2727 printf("starting oplock test 2\n");
2729 if (!torture_open_connection(&cli1, 0)) {
2730 use_level_II_oplocks = False;
2731 use_oplocks = saved_use_oplocks;
2732 return False;
2735 cli1->use_oplocks = True;
2736 cli1->use_level_II_oplocks = True;
2738 if (!torture_open_connection(&cli2, 1)) {
2739 use_level_II_oplocks = False;
2740 use_oplocks = saved_use_oplocks;
2741 return False;
2744 cli2->use_oplocks = True;
2745 cli2->use_level_II_oplocks = True;
2747 cli_unlink(cli1, fname);
2749 cli_sockopt(cli1, sockops);
2750 cli_sockopt(cli2, sockops);
2752 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2753 if (fnum1 == -1) {
2754 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2755 return False;
2758 /* Don't need the globals any more. */
2759 use_level_II_oplocks = False;
2760 use_oplocks = saved_use_oplocks;
2762 if (fork() == 0) {
2763 /* Child code */
2764 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2765 if (fnum2 == -1) {
2766 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2767 *shared_correct = False;
2768 exit(0);
2771 sleep(2);
2773 if (!cli_close(cli2, fnum2)) {
2774 printf("close2 failed (%s)\n", cli_errstr(cli1));
2775 *shared_correct = False;
2778 exit(0);
2781 sleep(2);
2783 /* Ensure cli1 processes the break. Empty file should always return 0
2784 * bytes. */
2786 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2787 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2788 correct = False;
2791 /* Should now be at level II. */
2792 /* Test if sending a write locks causes a break to none. */
2794 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2795 printf("lock failed (%s)\n", cli_errstr(cli1));
2796 correct = False;
2799 cli_unlock(cli1, fnum1, 0, 4);
2801 sleep(2);
2803 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2804 printf("lock failed (%s)\n", cli_errstr(cli1));
2805 correct = False;
2808 cli_unlock(cli1, fnum1, 0, 4);
2810 sleep(2);
2812 cli_read(cli1, fnum1, buf, 0, 4);
2814 #if 0
2815 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2816 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2817 correct = False;
2819 #endif
2821 if (!cli_close(cli1, fnum1)) {
2822 printf("close1 failed (%s)\n", cli_errstr(cli1));
2823 correct = False;
2826 sleep(4);
2828 if (!cli_unlink(cli1, fname)) {
2829 printf("unlink failed (%s)\n", cli_errstr(cli1));
2830 correct = False;
2833 if (!torture_close_connection(cli1)) {
2834 correct = False;
2837 if (!*shared_correct) {
2838 correct = False;
2841 printf("finished oplock test 2\n");
2843 return correct;
2846 /* handler for oplock 3 tests */
2847 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2849 printf("got oplock break fnum=%d level=%d\n",
2850 fnum, level);
2851 return cli_oplock_ack(cli, fnum, level);
2854 static BOOL run_oplock3(int dummy)
2856 struct cli_state *cli;
2857 const char *fname = "\\oplockt3.dat";
2858 int fnum;
2859 char buf[4] = "abcd";
2860 BOOL correct = True;
2861 volatile BOOL *shared_correct;
2863 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2864 *shared_correct = True;
2866 printf("starting oplock test 3\n");
2868 if (fork() == 0) {
2869 /* Child code */
2870 use_oplocks = True;
2871 use_level_II_oplocks = True;
2872 if (!torture_open_connection(&cli, 0)) {
2873 *shared_correct = False;
2874 exit(0);
2876 sleep(2);
2877 /* try to trigger a oplock break in parent */
2878 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2879 cli_write(cli, fnum, 0, buf, 0, 4);
2880 exit(0);
2883 /* parent code */
2884 use_oplocks = True;
2885 use_level_II_oplocks = True;
2886 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2887 return False;
2889 cli_oplock_handler(cli, oplock3_handler);
2890 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2891 cli_write(cli, fnum, 0, buf, 0, 4);
2892 cli_close(cli, fnum);
2893 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2894 cli->timeout = 20000;
2895 cli_receive_smb(cli);
2896 printf("finished oplock test 3\n");
2898 return (correct && *shared_correct);
2900 /* What are we looking for here? What's sucess and what's FAILURE? */
2906 Test delete on close semantics.
2908 static BOOL run_deletetest(int dummy)
2910 struct cli_state *cli1 = NULL;
2911 struct cli_state *cli2 = NULL;
2912 const char *fname = "\\delete.file";
2913 int fnum1 = -1;
2914 int fnum2 = -1;
2915 BOOL correct = True;
2917 printf("starting delete test\n");
2919 if (!torture_open_connection(&cli1, 0)) {
2920 return False;
2923 cli_sockopt(cli1, sockops);
2925 /* Test 1 - this should delete the file on close. */
2927 cli_setatr(cli1, fname, 0, 0);
2928 cli_unlink(cli1, fname);
2930 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2931 0, FILE_OVERWRITE_IF,
2932 FILE_DELETE_ON_CLOSE, 0);
2934 if (fnum1 == -1) {
2935 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2936 correct = False;
2937 goto fail;
2940 #if 0 /* JRATEST */
2942 uint32 *accinfo = NULL;
2943 uint32 len;
2944 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2945 if (accinfo)
2946 printf("access mode = 0x%lx\n", *accinfo);
2947 SAFE_FREE(accinfo);
2949 #endif
2951 if (!cli_close(cli1, fnum1)) {
2952 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2953 correct = False;
2954 goto fail;
2957 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2958 if (fnum1 != -1) {
2959 printf("[1] open of %s succeeded (should fail)\n", fname);
2960 correct = False;
2961 goto fail;
2964 printf("first delete on close test succeeded.\n");
2966 /* Test 2 - this should delete the file on close. */
2968 cli_setatr(cli1, fname, 0, 0);
2969 cli_unlink(cli1, fname);
2971 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
2972 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2973 FILE_OVERWRITE_IF, 0, 0);
2975 if (fnum1 == -1) {
2976 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2977 correct = False;
2978 goto fail;
2981 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2982 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2983 correct = False;
2984 goto fail;
2987 if (!cli_close(cli1, fnum1)) {
2988 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2989 correct = False;
2990 goto fail;
2993 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2994 if (fnum1 != -1) {
2995 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2996 if (!cli_close(cli1, fnum1)) {
2997 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2998 correct = False;
2999 goto fail;
3001 cli_unlink(cli1, fname);
3002 } else
3003 printf("second delete on close test succeeded.\n");
3005 /* Test 3 - ... */
3006 cli_setatr(cli1, fname, 0, 0);
3007 cli_unlink(cli1, fname);
3009 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3010 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3012 if (fnum1 == -1) {
3013 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3014 correct = False;
3015 goto fail;
3018 /* This should fail with a sharing violation - open for delete is only compatible
3019 with SHARE_DELETE. */
3021 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3022 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3024 if (fnum2 != -1) {
3025 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3026 correct = False;
3027 goto fail;
3030 /* This should succeed. */
3032 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3033 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3035 if (fnum2 == -1) {
3036 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3037 correct = False;
3038 goto fail;
3041 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3042 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3043 correct = False;
3044 goto fail;
3047 if (!cli_close(cli1, fnum1)) {
3048 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3049 correct = False;
3050 goto fail;
3053 if (!cli_close(cli1, fnum2)) {
3054 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3055 correct = False;
3056 goto fail;
3059 /* This should fail - file should no longer be there. */
3061 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3062 if (fnum1 != -1) {
3063 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3064 if (!cli_close(cli1, fnum1)) {
3065 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3067 cli_unlink(cli1, fname);
3068 correct = False;
3069 goto fail;
3070 } else
3071 printf("third delete on close test succeeded.\n");
3073 /* Test 4 ... */
3074 cli_setatr(cli1, fname, 0, 0);
3075 cli_unlink(cli1, fname);
3077 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3078 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3080 if (fnum1 == -1) {
3081 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3082 correct = False;
3083 goto fail;
3086 /* This should succeed. */
3087 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3088 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3089 if (fnum2 == -1) {
3090 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3091 correct = False;
3092 goto fail;
3095 if (!cli_close(cli1, fnum2)) {
3096 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3097 correct = False;
3098 goto fail;
3101 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3102 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3103 correct = False;
3104 goto fail;
3107 /* This should fail - no more opens once delete on close set. */
3108 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3109 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3110 FILE_OPEN, 0, 0);
3111 if (fnum2 != -1) {
3112 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3113 correct = False;
3114 goto fail;
3115 } else
3116 printf("fourth delete on close test succeeded.\n");
3118 if (!cli_close(cli1, fnum1)) {
3119 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3120 correct = False;
3121 goto fail;
3124 /* Test 5 ... */
3125 cli_setatr(cli1, fname, 0, 0);
3126 cli_unlink(cli1, fname);
3128 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3129 if (fnum1 == -1) {
3130 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3131 correct = False;
3132 goto fail;
3135 /* This should fail - only allowed on NT opens with DELETE access. */
3137 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3138 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3139 correct = False;
3140 goto fail;
3143 if (!cli_close(cli1, fnum1)) {
3144 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3145 correct = False;
3146 goto fail;
3149 printf("fifth delete on close test succeeded.\n");
3151 /* Test 6 ... */
3152 cli_setatr(cli1, fname, 0, 0);
3153 cli_unlink(cli1, fname);
3155 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3156 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3157 FILE_OVERWRITE_IF, 0, 0);
3159 if (fnum1 == -1) {
3160 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3161 correct = False;
3162 goto fail;
3165 /* This should fail - only allowed on NT opens with DELETE access. */
3167 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3168 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3169 correct = False;
3170 goto fail;
3173 if (!cli_close(cli1, fnum1)) {
3174 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3175 correct = False;
3176 goto fail;
3179 printf("sixth delete on close test succeeded.\n");
3181 /* Test 7 ... */
3182 cli_setatr(cli1, fname, 0, 0);
3183 cli_unlink(cli1, fname);
3185 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3186 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3188 if (fnum1 == -1) {
3189 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3190 correct = False;
3191 goto fail;
3194 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3195 printf("[7] setting delete_on_close on file failed !\n");
3196 correct = False;
3197 goto fail;
3200 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3201 printf("[7] unsetting delete_on_close on file failed !\n");
3202 correct = False;
3203 goto fail;
3206 if (!cli_close(cli1, fnum1)) {
3207 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3208 correct = False;
3209 goto fail;
3212 /* This next open should succeed - we reset the flag. */
3214 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3215 if (fnum1 == -1) {
3216 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3217 correct = False;
3218 goto fail;
3221 if (!cli_close(cli1, fnum1)) {
3222 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3223 correct = False;
3224 goto fail;
3227 printf("seventh delete on close test succeeded.\n");
3229 /* Test 7 ... */
3230 cli_setatr(cli1, fname, 0, 0);
3231 cli_unlink(cli1, fname);
3233 if (!torture_open_connection(&cli2, 1)) {
3234 printf("[8] failed to open second connection.\n");
3235 correct = False;
3236 goto fail;
3239 cli_sockopt(cli1, sockops);
3241 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3242 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3243 FILE_OVERWRITE_IF, 0, 0);
3245 if (fnum1 == -1) {
3246 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3247 correct = False;
3248 goto fail;
3251 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3252 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3253 FILE_OPEN, 0, 0);
3255 if (fnum2 == -1) {
3256 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3257 correct = False;
3258 goto fail;
3261 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3262 printf("[8] setting delete_on_close on file failed !\n");
3263 correct = False;
3264 goto fail;
3267 if (!cli_close(cli1, fnum1)) {
3268 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3269 correct = False;
3270 goto fail;
3273 if (!cli_close(cli2, fnum2)) {
3274 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3275 correct = False;
3276 goto fail;
3279 /* This should fail.. */
3280 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3281 if (fnum1 != -1) {
3282 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3283 goto fail;
3284 correct = False;
3285 } else
3286 printf("eighth delete on close test succeeded.\n");
3288 /* This should fail - we need to set DELETE_ACCESS. */
3289 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3290 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3292 if (fnum1 != -1) {
3293 printf("[9] open of %s succeeded should have failed!\n", fname);
3294 correct = False;
3295 goto fail;
3298 printf("ninth delete on close test succeeded.\n");
3300 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3301 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3302 if (fnum1 == -1) {
3303 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3304 correct = False;
3305 goto fail;
3308 /* This should delete the file. */
3309 if (!cli_close(cli1, fnum1)) {
3310 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3311 correct = False;
3312 goto fail;
3315 /* This should fail.. */
3316 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3317 if (fnum1 != -1) {
3318 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3319 goto fail;
3320 correct = False;
3321 } else
3322 printf("tenth delete on close test succeeded.\n");
3324 cli_setatr(cli1, fname, 0, 0);
3325 cli_unlink(cli1, fname);
3327 /* What error do we get when attempting to open a read-only file with
3328 delete access ? */
3330 /* Create a readonly file. */
3331 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3332 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3333 if (fnum1 == -1) {
3334 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3335 correct = False;
3336 goto fail;
3339 if (!cli_close(cli1, fnum1)) {
3340 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3341 correct = False;
3342 goto fail;
3345 /* Now try open for delete access. */
3346 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3347 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3348 FILE_OVERWRITE_IF, 0, 0);
3350 if (fnum1 != -1) {
3351 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3352 cli_close(cli1, fnum1);
3353 goto fail;
3354 correct = False;
3355 } else {
3356 NTSTATUS nterr = cli_nt_error(cli1);
3357 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3358 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3359 goto fail;
3360 correct = False;
3361 } else {
3362 printf("eleventh delete on close test succeeded.\n");
3366 printf("finished delete test\n");
3368 fail:
3369 /* FIXME: This will crash if we aborted before cli2 got
3370 * intialized, because these functions don't handle
3371 * uninitialized connections. */
3373 if (fnum1 != -1) cli_close(cli1, fnum1);
3374 if (fnum2 != -1) cli_close(cli1, fnum2);
3375 cli_setatr(cli1, fname, 0, 0);
3376 cli_unlink(cli1, fname);
3378 if (cli1 && !torture_close_connection(cli1)) {
3379 correct = False;
3381 if (cli2 && !torture_close_connection(cli2)) {
3382 correct = False;
3384 return correct;
3389 print out server properties
3391 static BOOL run_properties(int dummy)
3393 static struct cli_state *cli;
3394 BOOL correct = True;
3396 printf("starting properties test\n");
3398 ZERO_STRUCT(cli);
3400 if (!torture_open_connection(&cli, 0)) {
3401 return False;
3404 cli_sockopt(cli, sockops);
3406 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3408 if (!torture_close_connection(cli)) {
3409 correct = False;
3412 return correct;
3417 /* FIRST_DESIRED_ACCESS 0xf019f */
3418 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3419 FILE_READ_EA| /* 0xf */ \
3420 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3421 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3422 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3423 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3424 /* SECOND_DESIRED_ACCESS 0xe0080 */
3425 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3426 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3427 WRITE_OWNER_ACCESS /* 0xe0000 */
3429 #if 0
3430 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3431 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3432 FILE_READ_DATA|\
3433 WRITE_OWNER_ACCESS /* */
3434 #endif
3437 Test ntcreate calls made by xcopy
3439 static BOOL run_xcopy(int dummy)
3441 static struct cli_state *cli1;
3442 const char *fname = "\\test.txt";
3443 BOOL correct = True;
3444 int fnum1, fnum2;
3446 printf("starting xcopy test\n");
3448 if (!torture_open_connection(&cli1, 0)) {
3449 return False;
3452 fnum1 = cli_nt_create_full(cli1, fname, 0,
3453 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3454 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3455 0x4044, 0);
3457 if (fnum1 == -1) {
3458 printf("First open failed - %s\n", cli_errstr(cli1));
3459 return False;
3462 fnum2 = cli_nt_create_full(cli1, fname, 0,
3463 SECOND_DESIRED_ACCESS, 0,
3464 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3465 0x200000, 0);
3466 if (fnum2 == -1) {
3467 printf("second open failed - %s\n", cli_errstr(cli1));
3468 return False;
3471 if (!torture_close_connection(cli1)) {
3472 correct = False;
3475 return correct;
3479 Test rename on files open with share delete and no share delete.
3481 static BOOL run_rename(int dummy)
3483 static struct cli_state *cli1;
3484 const char *fname = "\\test.txt";
3485 const char *fname1 = "\\test1.txt";
3486 BOOL correct = True;
3487 int fnum1;
3489 printf("starting rename test\n");
3491 if (!torture_open_connection(&cli1, 0)) {
3492 return False;
3495 cli_unlink(cli1, fname);
3496 cli_unlink(cli1, fname1);
3497 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3498 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3500 if (fnum1 == -1) {
3501 printf("First open failed - %s\n", cli_errstr(cli1));
3502 return False;
3505 if (!cli_rename(cli1, fname, fname1)) {
3506 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3507 } else {
3508 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3509 correct = False;
3512 if (!cli_close(cli1, fnum1)) {
3513 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3514 return False;
3517 cli_unlink(cli1, fname);
3518 cli_unlink(cli1, fname1);
3519 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3520 #if 0
3521 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3522 #else
3523 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3524 #endif
3526 if (fnum1 == -1) {
3527 printf("Second open failed - %s\n", cli_errstr(cli1));
3528 return False;
3531 if (!cli_rename(cli1, fname, fname1)) {
3532 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3533 correct = False;
3534 } else {
3535 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3538 if (!cli_close(cli1, fnum1)) {
3539 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3540 return False;
3543 cli_unlink(cli1, fname);
3544 cli_unlink(cli1, fname1);
3546 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3547 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3549 if (fnum1 == -1) {
3550 printf("Third open failed - %s\n", cli_errstr(cli1));
3551 return False;
3555 #if 0
3557 int fnum2;
3559 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3560 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3562 if (fnum2 == -1) {
3563 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3564 return False;
3566 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3567 printf("[8] setting delete_on_close on file failed !\n");
3568 return False;
3571 if (!cli_close(cli1, fnum2)) {
3572 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3573 return False;
3576 #endif
3578 if (!cli_rename(cli1, fname, fname1)) {
3579 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3580 correct = False;
3581 } else {
3582 printf("Third rename succeeded (SHARE_NONE)\n");
3585 if (!cli_close(cli1, fnum1)) {
3586 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3587 return False;
3590 cli_unlink(cli1, fname);
3591 cli_unlink(cli1, fname1);
3593 /*----*/
3595 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3596 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3598 if (fnum1 == -1) {
3599 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3600 return False;
3603 if (!cli_rename(cli1, fname, fname1)) {
3604 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3605 } else {
3606 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3607 correct = False;
3610 if (!cli_close(cli1, fnum1)) {
3611 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3612 return False;
3615 cli_unlink(cli1, fname);
3616 cli_unlink(cli1, fname1);
3618 /*--*/
3620 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3621 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3623 if (fnum1 == -1) {
3624 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3625 return False;
3628 if (!cli_rename(cli1, fname, fname1)) {
3629 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n");
3630 correct = False;
3631 } else {
3632 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3636 * Now check if the first name still exists ...
3639 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3640 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3642 if (fnum2 == -1) {
3643 printf("Opening original file after rename of open file fails: %s\n",
3644 cli_errstr(cli1));
3646 else {
3647 printf("Opening original file after rename of open file works ...\n");
3648 (void)cli_close(cli1, fnum2);
3649 } */
3651 /*--*/
3654 if (!cli_close(cli1, fnum1)) {
3655 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3656 return False;
3659 cli_unlink(cli1, fname);
3660 cli_unlink(cli1, fname1);
3662 if (!torture_close_connection(cli1)) {
3663 correct = False;
3666 return correct;
3669 static BOOL run_pipe_number(int dummy)
3671 struct cli_state *cli1;
3672 const char *pipe_name = "\\SPOOLSS";
3673 int fnum;
3674 int num_pipes = 0;
3676 printf("starting pipenumber test\n");
3677 if (!torture_open_connection(&cli1, 0)) {
3678 return False;
3681 cli_sockopt(cli1, sockops);
3682 while(1) {
3683 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3684 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3686 if (fnum == -1) {
3687 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3688 break;
3690 num_pipes++;
3691 printf("\r%6d", num_pipes);
3694 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3695 torture_close_connection(cli1);
3696 return True;
3700 Test open mode returns on read-only files.
3702 static BOOL run_opentest(int dummy)
3704 static struct cli_state *cli1;
3705 static struct cli_state *cli2;
3706 const char *fname = "\\readonly.file";
3707 int fnum1, fnum2;
3708 char buf[20];
3709 SMB_OFF_T fsize;
3710 BOOL correct = True;
3711 char *tmp_path;
3713 printf("starting open test\n");
3715 if (!torture_open_connection(&cli1, 0)) {
3716 return False;
3719 cli_setatr(cli1, fname, 0, 0);
3720 cli_unlink(cli1, fname);
3722 cli_sockopt(cli1, sockops);
3724 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3725 if (fnum1 == -1) {
3726 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3727 return False;
3730 if (!cli_close(cli1, fnum1)) {
3731 printf("close2 failed (%s)\n", cli_errstr(cli1));
3732 return False;
3735 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3736 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3737 return False;
3740 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3741 if (fnum1 == -1) {
3742 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3743 return False;
3746 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3747 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3749 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3750 NT_STATUS_ACCESS_DENIED)) {
3751 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3754 printf("finished open test 1\n");
3756 cli_close(cli1, fnum1);
3758 /* Now try not readonly and ensure ERRbadshare is returned. */
3760 cli_setatr(cli1, fname, 0, 0);
3762 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3763 if (fnum1 == -1) {
3764 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3765 return False;
3768 /* This will fail - but the error should be ERRshare. */
3769 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3771 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3772 NT_STATUS_SHARING_VIOLATION)) {
3773 printf("correct error code ERRDOS/ERRbadshare returned\n");
3776 if (!cli_close(cli1, fnum1)) {
3777 printf("close2 failed (%s)\n", cli_errstr(cli1));
3778 return False;
3781 cli_unlink(cli1, fname);
3783 printf("finished open test 2\n");
3785 /* Test truncate open disposition on file opened for read. */
3787 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3788 if (fnum1 == -1) {
3789 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3790 return False;
3793 /* write 20 bytes. */
3795 memset(buf, '\0', 20);
3797 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3798 printf("write failed (%s)\n", cli_errstr(cli1));
3799 correct = False;
3802 if (!cli_close(cli1, fnum1)) {
3803 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3804 return False;
3807 /* Ensure size == 20. */
3808 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3809 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3810 return False;
3813 if (fsize != 20) {
3814 printf("(3) file size != 20\n");
3815 return False;
3818 /* Now test if we can truncate a file opened for readonly. */
3820 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3821 if (fnum1 == -1) {
3822 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3823 return False;
3826 if (!cli_close(cli1, fnum1)) {
3827 printf("close2 failed (%s)\n", cli_errstr(cli1));
3828 return False;
3831 /* Ensure size == 0. */
3832 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3833 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3834 return False;
3837 if (fsize != 0) {
3838 printf("(3) file size != 0\n");
3839 return False;
3841 printf("finished open test 3\n");
3843 cli_unlink(cli1, fname);
3846 printf("testing ctemp\n");
3847 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3848 if (fnum1 == -1) {
3849 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3850 return False;
3852 printf("ctemp gave path %s\n", tmp_path);
3853 if (!cli_close(cli1, fnum1)) {
3854 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3856 if (!cli_unlink(cli1, tmp_path)) {
3857 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3860 /* Test the non-io opens... */
3862 if (!torture_open_connection(&cli2, 1)) {
3863 return False;
3866 cli_setatr(cli2, fname, 0, 0);
3867 cli_unlink(cli2, fname);
3869 cli_sockopt(cli2, sockops);
3871 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3873 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3874 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3876 if (fnum1 == -1) {
3877 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3878 return False;
3881 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3882 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3884 if (fnum2 == -1) {
3885 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3886 return False;
3889 if (!cli_close(cli1, fnum1)) {
3890 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3891 return False;
3893 if (!cli_close(cli2, fnum2)) {
3894 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3895 return False;
3898 printf("non-io open test #1 passed.\n");
3900 cli_unlink(cli1, fname);
3902 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3904 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3905 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3907 if (fnum1 == -1) {
3908 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3909 return False;
3912 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3913 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3915 if (fnum2 == -1) {
3916 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3917 return False;
3920 if (!cli_close(cli1, fnum1)) {
3921 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3922 return False;
3924 if (!cli_close(cli2, fnum2)) {
3925 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3926 return False;
3929 printf("non-io open test #2 passed.\n");
3931 cli_unlink(cli1, fname);
3933 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3935 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3938 if (fnum1 == -1) {
3939 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3940 return False;
3943 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3944 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3946 if (fnum2 == -1) {
3947 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3948 return False;
3951 if (!cli_close(cli1, fnum1)) {
3952 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3953 return False;
3955 if (!cli_close(cli2, fnum2)) {
3956 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3957 return False;
3960 printf("non-io open test #3 passed.\n");
3962 cli_unlink(cli1, fname);
3964 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3966 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3967 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3969 if (fnum1 == -1) {
3970 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3971 return False;
3974 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3975 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3977 if (fnum2 != -1) {
3978 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3979 return False;
3982 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3984 if (!cli_close(cli1, fnum1)) {
3985 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3986 return False;
3989 printf("non-io open test #4 passed.\n");
3991 cli_unlink(cli1, fname);
3993 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3995 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3996 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3998 if (fnum1 == -1) {
3999 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4000 return False;
4003 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4004 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4006 if (fnum2 == -1) {
4007 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4008 return False;
4011 if (!cli_close(cli1, fnum1)) {
4012 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4013 return False;
4016 if (!cli_close(cli2, fnum2)) {
4017 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4018 return False;
4021 printf("non-io open test #5 passed.\n");
4023 printf("TEST #6 testing 1 non-io open, one io open\n");
4025 cli_unlink(cli1, fname);
4027 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4028 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4030 if (fnum1 == -1) {
4031 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4032 return False;
4035 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4036 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4038 if (fnum2 == -1) {
4039 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4040 return False;
4043 if (!cli_close(cli1, fnum1)) {
4044 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4045 return False;
4048 if (!cli_close(cli2, fnum2)) {
4049 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4050 return False;
4053 printf("non-io open test #6 passed.\n");
4055 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4057 cli_unlink(cli1, fname);
4059 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4060 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4062 if (fnum1 == -1) {
4063 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4064 return False;
4067 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4068 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4070 if (fnum2 != -1) {
4071 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4072 return False;
4075 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4077 if (!cli_close(cli1, fnum1)) {
4078 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4079 return False;
4082 printf("non-io open test #7 passed.\n");
4084 cli_unlink(cli1, fname);
4086 if (!torture_close_connection(cli1)) {
4087 correct = False;
4089 if (!torture_close_connection(cli2)) {
4090 correct = False;
4093 return correct;
4096 static uint32 open_attrs_table[] = {
4097 FILE_ATTRIBUTE_NORMAL,
4098 FILE_ATTRIBUTE_ARCHIVE,
4099 FILE_ATTRIBUTE_READONLY,
4100 FILE_ATTRIBUTE_HIDDEN,
4101 FILE_ATTRIBUTE_SYSTEM,
4103 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4104 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4105 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4106 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4110 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4111 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4112 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4113 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4116 struct trunc_open_results {
4117 unsigned int num;
4118 uint32 init_attr;
4119 uint32 trunc_attr;
4120 uint32 result_attr;
4123 static struct trunc_open_results attr_results[] = {
4124 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4125 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4126 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4127 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4128 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4129 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4130 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4131 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4132 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4133 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4134 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4135 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4136 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4137 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4138 { 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 },
4139 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4140 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4141 { 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 },
4142 { 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 },
4143 { 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 },
4144 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4145 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4146 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4147 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4148 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4149 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4152 static BOOL run_openattrtest(int dummy)
4154 static struct cli_state *cli1;
4155 const char *fname = "\\openattr.file";
4156 int fnum1;
4157 BOOL correct = True;
4158 uint16 attr;
4159 unsigned int i, j, k, l;
4161 printf("starting open attr test\n");
4163 if (!torture_open_connection(&cli1, 0)) {
4164 return False;
4167 cli_sockopt(cli1, sockops);
4169 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4170 cli_setatr(cli1, fname, 0, 0);
4171 cli_unlink(cli1, fname);
4172 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4173 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4175 if (fnum1 == -1) {
4176 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4177 return False;
4180 if (!cli_close(cli1, fnum1)) {
4181 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4182 return False;
4185 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4186 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4187 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4189 if (fnum1 == -1) {
4190 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4191 if (attr_results[l].num == k) {
4192 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4193 k, open_attrs_table[i],
4194 open_attrs_table[j],
4195 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4196 correct = False;
4199 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4200 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4201 k, open_attrs_table[i], open_attrs_table[j],
4202 cli_errstr(cli1));
4203 correct = False;
4205 #if 0
4206 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4207 #endif
4208 k++;
4209 continue;
4212 if (!cli_close(cli1, fnum1)) {
4213 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4214 return False;
4217 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4218 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4219 return False;
4222 #if 0
4223 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4224 k, open_attrs_table[i], open_attrs_table[j], attr );
4225 #endif
4227 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4228 if (attr_results[l].num == k) {
4229 if (attr != attr_results[l].result_attr ||
4230 open_attrs_table[i] != attr_results[l].init_attr ||
4231 open_attrs_table[j] != attr_results[l].trunc_attr) {
4232 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4233 open_attrs_table[i],
4234 open_attrs_table[j],
4235 (unsigned int)attr,
4236 attr_results[l].result_attr);
4237 correct = False;
4239 break;
4242 k++;
4246 cli_setatr(cli1, fname, 0, 0);
4247 cli_unlink(cli1, fname);
4249 printf("open attr test %s.\n", correct ? "passed" : "failed");
4251 if (!torture_close_connection(cli1)) {
4252 correct = False;
4254 return correct;
4257 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4263 test directory listing speed
4265 static BOOL run_dirtest(int dummy)
4267 int i;
4268 static struct cli_state *cli;
4269 int fnum;
4270 double t1;
4271 BOOL correct = True;
4273 printf("starting directory test\n");
4275 if (!torture_open_connection(&cli, 0)) {
4276 return False;
4279 cli_sockopt(cli, sockops);
4281 srandom(0);
4282 for (i=0;i<torture_numops;i++) {
4283 fstring fname;
4284 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4285 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4286 if (fnum == -1) {
4287 fprintf(stderr,"Failed to open %s\n", fname);
4288 return False;
4290 cli_close(cli, fnum);
4293 t1 = end_timer();
4295 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4296 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4297 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4299 printf("dirtest core %g seconds\n", end_timer() - t1);
4301 srandom(0);
4302 for (i=0;i<torture_numops;i++) {
4303 fstring fname;
4304 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4305 cli_unlink(cli, fname);
4308 if (!torture_close_connection(cli)) {
4309 correct = False;
4312 printf("finished dirtest\n");
4314 return correct;
4317 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4319 struct cli_state *pcli = (struct cli_state *)state;
4320 fstring fname;
4321 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4323 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4324 return;
4326 if (finfo->mode & aDIR) {
4327 if (!cli_rmdir(pcli, fname))
4328 printf("del_fn: failed to rmdir %s\n,", fname );
4329 } else {
4330 if (!cli_unlink(pcli, fname))
4331 printf("del_fn: failed to unlink %s\n,", fname );
4337 sees what IOCTLs are supported
4339 BOOL torture_ioctl_test(int dummy)
4341 static struct cli_state *cli;
4342 uint16 device, function;
4343 int fnum;
4344 const char *fname = "\\ioctl.dat";
4345 DATA_BLOB blob;
4346 NTSTATUS status;
4348 if (!torture_open_connection(&cli, 0)) {
4349 return False;
4352 printf("starting ioctl test\n");
4354 cli_unlink(cli, fname);
4356 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4357 if (fnum == -1) {
4358 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4359 return False;
4362 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4363 printf("ioctl device info: %s\n", cli_errstr(cli));
4365 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4366 printf("ioctl job info: %s\n", cli_errstr(cli));
4368 for (device=0;device<0x100;device++) {
4369 printf("testing device=0x%x\n", device);
4370 for (function=0;function<0x100;function++) {
4371 uint32 code = (device<<16) | function;
4373 status = cli_raw_ioctl(cli, fnum, code, &blob);
4375 if (NT_STATUS_IS_OK(status)) {
4376 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4377 (int)blob.length);
4378 data_blob_free(&blob);
4383 if (!torture_close_connection(cli)) {
4384 return False;
4387 return True;
4392 tries varients of chkpath
4394 BOOL torture_chkpath_test(int dummy)
4396 static struct cli_state *cli;
4397 int fnum;
4398 BOOL ret;
4400 if (!torture_open_connection(&cli, 0)) {
4401 return False;
4404 printf("starting chkpath test\n");
4406 /* cleanup from an old run */
4407 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4408 cli_unlink(cli, "\\chkpath.dir\\*");
4409 cli_rmdir(cli, "\\chkpath.dir");
4411 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4412 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4413 return False;
4416 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4417 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4418 return False;
4421 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4422 if (fnum == -1) {
4423 printf("open1 failed (%s)\n", cli_errstr(cli));
4424 return False;
4426 cli_close(cli, fnum);
4428 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4429 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4430 ret = False;
4433 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4434 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4435 ret = False;
4438 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4439 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4440 NT_STATUS_NOT_A_DIRECTORY);
4441 } else {
4442 printf("* chkpath on a file should fail\n");
4443 ret = False;
4446 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4447 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4448 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4449 } else {
4450 printf("* chkpath on a non existant file should fail\n");
4451 ret = False;
4454 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4455 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4456 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4457 } else {
4458 printf("* chkpath on a non existent component should fail\n");
4459 ret = False;
4462 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4463 cli_unlink(cli, "\\chkpath.dir\\*");
4464 cli_rmdir(cli, "\\chkpath.dir");
4466 if (!torture_close_connection(cli)) {
4467 return False;
4470 return ret;
4473 static BOOL run_eatest(int dummy)
4475 static struct cli_state *cli;
4476 const char *fname = "\\eatest.txt";
4477 BOOL correct = True;
4478 int fnum, i;
4479 size_t num_eas;
4480 struct ea_struct *ea_list = NULL;
4481 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4483 printf("starting eatest\n");
4485 if (!torture_open_connection(&cli, 0)) {
4486 talloc_destroy(mem_ctx);
4487 return False;
4490 cli_unlink(cli, fname);
4491 fnum = cli_nt_create_full(cli, fname, 0,
4492 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4493 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4494 0x4044, 0);
4496 if (fnum == -1) {
4497 printf("open failed - %s\n", cli_errstr(cli));
4498 talloc_destroy(mem_ctx);
4499 return False;
4502 for (i = 0; i < 10; i++) {
4503 fstring ea_name, ea_val;
4505 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4506 memset(ea_val, (char)i+1, i+1);
4507 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4508 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4509 talloc_destroy(mem_ctx);
4510 return False;
4514 cli_close(cli, fnum);
4515 for (i = 0; i < 10; i++) {
4516 fstring ea_name, ea_val;
4518 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4519 memset(ea_val, (char)i+1, i+1);
4520 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4521 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4522 talloc_destroy(mem_ctx);
4523 return False;
4527 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4528 printf("ea_get list failed - %s\n", cli_errstr(cli));
4529 correct = False;
4532 printf("num_eas = %d\n", (int)num_eas);
4534 if (num_eas != 20) {
4535 printf("Should be 20 EA's stored... failing.\n");
4536 correct = False;
4539 for (i = 0; i < num_eas; i++) {
4540 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4541 dump_data(0, ea_list[i].value.data,
4542 ea_list[i].value.length);
4545 /* Setting EA's to zero length deletes them. Test this */
4546 printf("Now deleting all EA's - case indepenent....\n");
4548 #if 1
4549 cli_set_ea_path(cli, fname, "", "", 0);
4550 #else
4551 for (i = 0; i < 20; i++) {
4552 fstring ea_name;
4553 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4554 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4555 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4556 talloc_destroy(mem_ctx);
4557 return False;
4560 #endif
4562 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4563 printf("ea_get list failed - %s\n", cli_errstr(cli));
4564 correct = False;
4567 printf("num_eas = %d\n", (int)num_eas);
4568 for (i = 0; i < num_eas; i++) {
4569 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4570 dump_data(0, ea_list[i].value.data,
4571 ea_list[i].value.length);
4574 if (num_eas != 0) {
4575 printf("deleting EA's failed.\n");
4576 correct = False;
4579 /* Try and delete a non existant EA. */
4580 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4581 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4582 correct = False;
4585 talloc_destroy(mem_ctx);
4586 if (!torture_close_connection(cli)) {
4587 correct = False;
4590 return correct;
4593 static BOOL run_dirtest1(int dummy)
4595 int i;
4596 static struct cli_state *cli;
4597 int fnum, num_seen;
4598 BOOL correct = True;
4600 printf("starting directory test\n");
4602 if (!torture_open_connection(&cli, 0)) {
4603 return False;
4606 cli_sockopt(cli, sockops);
4608 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4609 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4610 cli_rmdir(cli, "\\LISTDIR");
4611 cli_mkdir(cli, "\\LISTDIR");
4613 /* Create 1000 files and 1000 directories. */
4614 for (i=0;i<1000;i++) {
4615 fstring fname;
4616 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4617 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4618 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4619 if (fnum == -1) {
4620 fprintf(stderr,"Failed to open %s\n", fname);
4621 return False;
4623 cli_close(cli, fnum);
4625 for (i=0;i<1000;i++) {
4626 fstring fname;
4627 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4628 if (!cli_mkdir(cli, fname)) {
4629 fprintf(stderr,"Failed to open %s\n", fname);
4630 return False;
4634 /* Now ensure that doing an old list sees both files and directories. */
4635 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4636 printf("num_seen = %d\n", num_seen );
4637 /* We should see 100 files + 1000 directories + . and .. */
4638 if (num_seen != 2002)
4639 correct = False;
4641 /* Ensure if we have the "must have" bits we only see the
4642 * relevent entries.
4644 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4645 printf("num_seen = %d\n", num_seen );
4646 if (num_seen != 1002)
4647 correct = False;
4649 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4650 printf("num_seen = %d\n", num_seen );
4651 if (num_seen != 1000)
4652 correct = False;
4654 /* Delete everything. */
4655 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4656 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4657 cli_rmdir(cli, "\\LISTDIR");
4659 #if 0
4660 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4661 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4662 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4663 #endif
4665 if (!torture_close_connection(cli)) {
4666 correct = False;
4669 printf("finished dirtest1\n");
4671 return correct;
4674 static BOOL run_error_map_extract(int dummy) {
4676 static struct cli_state *c_dos;
4677 static struct cli_state *c_nt;
4679 uint32 error;
4681 uint32 flgs2, errnum;
4682 uint8 errclass;
4684 NTSTATUS nt_status;
4686 fstring user;
4688 /* NT-Error connection */
4690 if (!(c_nt = open_nbt_connection())) {
4691 return False;
4694 c_nt->use_spnego = False;
4696 if (!cli_negprot(c_nt)) {
4697 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
4698 cli_shutdown(c_nt);
4699 return False;
4702 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4703 workgroup))) {
4704 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4705 return False;
4708 /* DOS-Error connection */
4710 if (!(c_dos = open_nbt_connection())) {
4711 return False;
4714 c_dos->use_spnego = False;
4715 c_dos->force_dos_errors = True;
4717 if (!cli_negprot(c_dos)) {
4718 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
4719 cli_shutdown(c_dos);
4720 return False;
4723 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4724 workgroup))) {
4725 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4726 return False;
4729 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4730 fstr_sprintf(user, "%X", error);
4732 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4733 password, strlen(password),
4734 password, strlen(password),
4735 workgroup))) {
4736 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4739 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4741 /* Case #1: 32-bit NT errors */
4742 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4743 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4744 } else {
4745 printf("/** Dos error on NT connection! (%s) */\n",
4746 cli_errstr(c_nt));
4747 nt_status = NT_STATUS(0xc0000000);
4750 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4751 password, strlen(password),
4752 password, strlen(password),
4753 workgroup))) {
4754 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4756 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4758 /* Case #1: 32-bit NT errors */
4759 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4760 printf("/** NT error on DOS connection! (%s) */\n",
4761 cli_errstr(c_nt));
4762 errnum = errclass = 0;
4763 } else {
4764 cli_dos_error(c_dos, &errclass, &errnum);
4767 if (NT_STATUS_V(nt_status) != error) {
4768 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4769 get_nt_error_c_code(NT_STATUS(error)),
4770 get_nt_error_c_code(nt_status));
4773 printf("\t{%s,\t%s,\t%s},\n",
4774 smb_dos_err_class(errclass),
4775 smb_dos_err_name(errclass, errnum),
4776 get_nt_error_c_code(NT_STATUS(error)));
4778 return True;
4781 static BOOL run_local_substitute(int dummy)
4783 TALLOC_CTX *mem_ctx;
4784 int diff = 0;
4786 if ((mem_ctx = talloc_init("run_local_subst")) == NULL) {
4787 printf("talloc_init failed\n");
4788 return False;
4791 diff |= strcmp(talloc_sub_specified(mem_ctx, "%U", "bla", "", -1, -1),
4792 "bla");
4793 diff |= strcmp(talloc_sub_specified(mem_ctx, "%u%U", "bla", "", -1, -1),
4794 "blabla");
4795 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, -1),
4796 "NO_GROUP");
4797 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, -1),
4798 "NO_GROUP");
4799 diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, 0),
4800 gidtoname(0));
4801 diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, 0),
4802 gidtoname(0));
4803 diff |= strcmp(talloc_sub_specified(mem_ctx, "%D%u", "u", "dom", -1, 0),
4804 "domu");
4805 diff |= strcmp(talloc_sub_specified(mem_ctx, "%i %I", "", "", -1, -1),
4806 "0.0.0.0 0.0.0.0");
4808 /* Different captialization rules in sub_basic... */
4810 diff |= strcmp(talloc_sub_basic(mem_ctx, "BLA", "dom", "%U%D"),
4811 "blaDOM");
4813 TALLOC_FREE(mem_ctx);
4814 return (diff == 0);
4817 static BOOL run_local_gencache(int dummy)
4819 char *val;
4820 time_t tm;
4822 if (!gencache_init()) {
4823 d_printf("%s: gencache_init() failed\n", __location__);
4824 return False;
4827 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
4828 d_printf("%s: gencache_set() failed\n", __location__);
4829 return False;
4832 if (!gencache_get("foo", &val, &tm)) {
4833 d_printf("%s: gencache_get() failed\n", __location__);
4834 return False;
4837 if (strcmp(val, "bar") != 0) {
4838 d_printf("%s: gencache_get() returned %s, expected %s\n",
4839 __location__, val, "bar");
4840 SAFE_FREE(val);
4841 return False;
4844 SAFE_FREE(val);
4846 if (!gencache_del("foo")) {
4847 d_printf("%s: gencache_del() failed\n", __location__);
4848 return False;
4850 if (gencache_del("foo")) {
4851 d_printf("%s: second gencache_del() succeeded\n",
4852 __location__);
4853 return False;
4856 if (gencache_get("foo", &val, &tm)) {
4857 d_printf("%s: gencache_get() on deleted entry "
4858 "succeeded\n", __location__);
4859 return False;
4862 if (!gencache_shutdown()) {
4863 d_printf("%s: gencache_shutdown() failed\n", __location__);
4864 return False;
4867 if (gencache_shutdown()) {
4868 d_printf("%s: second gencache_shutdown() succeeded\n",
4869 __location__);
4870 return False;
4873 return True;
4876 static double create_procs(BOOL (*fn)(int), BOOL *result)
4878 int i, status;
4879 volatile pid_t *child_status;
4880 volatile BOOL *child_status_out;
4881 int synccount;
4882 int tries = 8;
4884 synccount = 0;
4886 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4887 if (!child_status) {
4888 printf("Failed to setup shared memory\n");
4889 return -1;
4892 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4893 if (!child_status_out) {
4894 printf("Failed to setup result status shared memory\n");
4895 return -1;
4898 for (i = 0; i < nprocs; i++) {
4899 child_status[i] = 0;
4900 child_status_out[i] = True;
4903 start_timer();
4905 for (i=0;i<nprocs;i++) {
4906 procnum = i;
4907 if (fork() == 0) {
4908 pid_t mypid = getpid();
4909 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4911 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4913 while (1) {
4914 if (torture_open_connection(&current_cli, i)) break;
4915 if (tries-- == 0) {
4916 printf("pid %d failed to start\n", (int)getpid());
4917 _exit(1);
4919 smb_msleep(10);
4922 child_status[i] = getpid();
4924 while (child_status[i] && end_timer() < 5) smb_msleep(2);
4926 child_status_out[i] = fn(i);
4927 _exit(0);
4931 do {
4932 synccount = 0;
4933 for (i=0;i<nprocs;i++) {
4934 if (child_status[i]) synccount++;
4936 if (synccount == nprocs) break;
4937 smb_msleep(10);
4938 } while (end_timer() < 30);
4940 if (synccount != nprocs) {
4941 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4942 *result = False;
4943 return end_timer();
4946 /* start the client load */
4947 start_timer();
4949 for (i=0;i<nprocs;i++) {
4950 child_status[i] = 0;
4953 printf("%d clients started\n", nprocs);
4955 for (i=0;i<nprocs;i++) {
4956 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
4959 printf("\n");
4961 for (i=0;i<nprocs;i++) {
4962 if (!child_status_out[i]) {
4963 *result = False;
4966 return end_timer();
4969 #define FLAG_MULTIPROC 1
4971 static struct {
4972 const char *name;
4973 BOOL (*fn)(int);
4974 unsigned flags;
4975 } torture_ops[] = {
4976 {"FDPASS", run_fdpasstest, 0},
4977 {"LOCK1", run_locktest1, 0},
4978 {"LOCK2", run_locktest2, 0},
4979 {"LOCK3", run_locktest3, 0},
4980 {"LOCK4", run_locktest4, 0},
4981 {"LOCK5", run_locktest5, 0},
4982 {"LOCK6", run_locktest6, 0},
4983 {"LOCK7", run_locktest7, 0},
4984 {"UNLINK", run_unlinktest, 0},
4985 {"BROWSE", run_browsetest, 0},
4986 {"ATTR", run_attrtest, 0},
4987 {"TRANS2", run_trans2test, 0},
4988 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4989 {"TORTURE",run_torture, FLAG_MULTIPROC},
4990 {"RANDOMIPC", run_randomipc, 0},
4991 {"NEGNOWAIT", run_negprot_nowait, 0},
4992 {"NBENCH", run_nbench, 0},
4993 {"OPLOCK1", run_oplock1, 0},
4994 {"OPLOCK2", run_oplock2, 0},
4995 {"OPLOCK3", run_oplock3, 0},
4996 {"DIR", run_dirtest, 0},
4997 {"DIR1", run_dirtest1, 0},
4998 {"DENY1", torture_denytest1, 0},
4999 {"DENY2", torture_denytest2, 0},
5000 {"TCON", run_tcon_test, 0},
5001 {"TCONDEV", run_tcon_devtype_test, 0},
5002 {"RW1", run_readwritetest, 0},
5003 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5004 {"RW3", run_readwritelarge, 0},
5005 {"OPEN", run_opentest, 0},
5006 #if 1
5007 {"OPENATTR", run_openattrtest, 0},
5008 #endif
5009 {"XCOPY", run_xcopy, 0},
5010 {"RENAME", run_rename, 0},
5011 {"DELETE", run_deletetest, 0},
5012 {"PROPERTIES", run_properties, 0},
5013 {"MANGLE", torture_mangle, 0},
5014 {"W2K", run_w2ktest, 0},
5015 {"TRANS2SCAN", torture_trans2_scan, 0},
5016 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5017 {"UTABLE", torture_utable, 0},
5018 {"CASETABLE", torture_casetable, 0},
5019 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5020 {"PIPE_NUMBER", run_pipe_number, 0},
5021 {"TCON2", run_tcon2_test, 0},
5022 {"IOCTL", torture_ioctl_test, 0},
5023 {"CHKPATH", torture_chkpath_test, 0},
5024 {"FDSESS", run_fdsesstest, 0},
5025 { "EATEST", run_eatest, 0},
5026 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5027 { "LOCAL-GENCACHE", run_local_gencache, 0},
5028 {NULL, NULL, 0}};
5032 /****************************************************************************
5033 run a specified test or "ALL"
5034 ****************************************************************************/
5035 static BOOL run_test(const char *name)
5037 BOOL ret = True;
5038 BOOL result = True;
5039 BOOL found = False;
5040 int i;
5041 double t;
5042 if (strequal(name,"ALL")) {
5043 for (i=0;torture_ops[i].name;i++) {
5044 run_test(torture_ops[i].name);
5046 found = True;
5049 for (i=0;torture_ops[i].name;i++) {
5050 fstr_sprintf(randomfname, "\\XX%x",
5051 (unsigned)random());
5053 if (strequal(name, torture_ops[i].name)) {
5054 found = True;
5055 printf("Running %s\n", name);
5056 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5057 t = create_procs(torture_ops[i].fn, &result);
5058 if (!result) {
5059 ret = False;
5060 printf("TEST %s FAILED!\n", name);
5063 } else {
5064 start_timer();
5065 if (!torture_ops[i].fn(0)) {
5066 ret = False;
5067 printf("TEST %s FAILED!\n", name);
5069 t = end_timer();
5071 printf("%s took %g secs\n\n", name, t);
5075 if (!found) {
5076 printf("Did not find a test named %s\n", name);
5077 ret = False;
5080 return ret;
5084 static void usage(void)
5086 int i;
5088 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5089 printf("Please use samba4 torture.\n\n");
5091 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5093 printf("\t-d debuglevel\n");
5094 printf("\t-U user%%pass\n");
5095 printf("\t-k use kerberos\n");
5096 printf("\t-N numprocs\n");
5097 printf("\t-n my_netbios_name\n");
5098 printf("\t-W workgroup\n");
5099 printf("\t-o num_operations\n");
5100 printf("\t-O socket_options\n");
5101 printf("\t-m maximum protocol\n");
5102 printf("\t-L use oplocks\n");
5103 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5104 printf("\t-A showall\n");
5105 printf("\t-p port\n");
5106 printf("\t-s seed\n");
5107 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5108 printf("\n\n");
5110 printf("tests are:");
5111 for (i=0;torture_ops[i].name;i++) {
5112 printf(" %s", torture_ops[i].name);
5114 printf("\n");
5116 printf("default test is ALL\n");
5118 exit(1);
5121 /****************************************************************************
5122 main program
5123 ****************************************************************************/
5124 int main(int argc,char *argv[])
5126 int opt, i;
5127 char *p;
5128 int gotuser = 0;
5129 int gotpass = 0;
5130 BOOL correct = True;
5132 dbf = x_stdout;
5134 #ifdef HAVE_SETBUFFER
5135 setbuffer(stdout, NULL, 0);
5136 #endif
5138 load_case_tables();
5140 lp_load(dyn_CONFIGFILE,True,False,False,True);
5141 load_interfaces();
5143 if (argc < 2) {
5144 usage();
5147 for(p = argv[1]; *p; p++)
5148 if(*p == '\\')
5149 *p = '/';
5151 if (strncmp(argv[1], "//", 2)) {
5152 usage();
5155 fstrcpy(host, &argv[1][2]);
5156 p = strchr_m(&host[2],'/');
5157 if (!p) {
5158 usage();
5160 *p = 0;
5161 fstrcpy(share, p+1);
5163 get_myname(myname);
5165 if (*username == 0 && getenv("LOGNAME")) {
5166 fstrcpy(username,getenv("LOGNAME"));
5169 argc--;
5170 argv++;
5172 srandom(time(NULL));
5174 fstrcpy(workgroup, lp_workgroup());
5176 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
5177 switch (opt) {
5178 case 'p':
5179 port_to_use = atoi(optarg);
5180 break;
5181 case 's':
5182 srandom(atoi(optarg));
5183 break;
5184 case 'W':
5185 fstrcpy(workgroup,optarg);
5186 break;
5187 case 'm':
5188 max_protocol = interpret_protocol(optarg, max_protocol);
5189 break;
5190 case 'N':
5191 nprocs = atoi(optarg);
5192 break;
5193 case 'o':
5194 torture_numops = atoi(optarg);
5195 break;
5196 case 'd':
5197 DEBUGLEVEL = atoi(optarg);
5198 break;
5199 case 'O':
5200 sockops = optarg;
5201 break;
5202 case 'L':
5203 use_oplocks = True;
5204 break;
5205 case 'A':
5206 torture_showall = True;
5207 break;
5208 case 'n':
5209 fstrcpy(myname, optarg);
5210 break;
5211 case 'c':
5212 client_txt = optarg;
5213 break;
5214 case 'k':
5215 #ifdef HAVE_KRB5
5216 use_kerberos = True;
5217 #else
5218 d_printf("No kerberos support compiled in\n");
5219 exit(1);
5220 #endif
5221 break;
5222 case 'U':
5223 gotuser = 1;
5224 fstrcpy(username,optarg);
5225 p = strchr_m(username,'%');
5226 if (p) {
5227 *p = 0;
5228 fstrcpy(password, p+1);
5229 gotpass = 1;
5231 break;
5232 case 'b':
5233 fstrcpy(multishare_conn_fname, optarg);
5234 use_multishare_conn = True;
5235 break;
5236 default:
5237 printf("Unknown option %c (%d)\n", (char)opt, opt);
5238 usage();
5242 if(use_kerberos && !gotuser) gotpass = True;
5244 while (!gotpass) {
5245 p = getpass("Password:");
5246 if (p) {
5247 fstrcpy(password, p);
5248 gotpass = 1;
5252 printf("host=%s share=%s user=%s myname=%s\n",
5253 host, share, username, myname);
5255 if (argc == optind) {
5256 correct = run_test("ALL");
5257 } else {
5258 for (i=optind;i<argc;i++) {
5259 if (!run_test(argv[i])) {
5260 correct = False;
5265 if (correct) {
5266 return(0);
5267 } else {
5268 return(1);