Fix all other modules to use ldb_module.h instead of ldb_private.h
[Samba.git] / source3 / torture / torture.c
blob1210a36a392714774e5ccaa1c3d0431afa42a25d
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 3 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, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
22 extern char *optarg;
23 extern int optind;
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 static int port_to_use=0;
30 int torture_numops=100;
31 int torture_blocksize=1024*1024;
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;
41 static bool do_encrypt;
43 bool torture_showall = False;
45 static double create_procs(bool (*fn)(int), bool *result);
48 static struct timeval tp1,tp2;
51 void start_timer(void)
53 GetTimeOfDay(&tp1);
56 double end_timer(void)
58 GetTimeOfDay(&tp2);
59 return((tp2.tv_sec - tp1.tv_sec) +
60 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
64 /* return a pointer to a anonymous shared memory segment of size "size"
65 which will persist across fork() but will disappear when all processes
66 exit
68 The memory is not zeroed
70 This function uses system5 shared memory. It takes advantage of a property
71 that the memory is not destroyed if it is attached when the id is removed
73 void *shm_setup(int size)
75 int shmid;
76 void *ret;
78 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
79 if (shmid == -1) {
80 printf("can't get shared memory\n");
81 exit(1);
83 ret = (void *)shmat(shmid, 0, 0);
84 if (!ret || ret == (void *)-1) {
85 printf("can't attach to shared memory\n");
86 return NULL;
88 /* the following releases the ipc, but note that this process
89 and all its children will still have access to the memory, its
90 just that the shmid is no longer valid for other shm calls. This
91 means we don't leave behind lots of shm segments after we exit
93 See Stevens "advanced programming in unix env" for details
95 shmctl(shmid, IPC_RMID, 0);
97 return ret;
100 /********************************************************************
101 Ensure a connection is encrypted.
102 ********************************************************************/
104 static bool force_cli_encryption(struct cli_state *c,
105 const char *sharename)
107 uint16 major, minor;
108 uint32 caplow, caphigh;
109 NTSTATUS status;
111 if (!SERVER_HAS_UNIX_CIFS(c)) {
112 d_printf("Encryption required and "
113 "server that doesn't support "
114 "UNIX extensions - failing connect\n");
115 return false;
118 if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
119 d_printf("Encryption required and "
120 "can't get UNIX CIFS extensions "
121 "version from server.\n");
122 return false;
125 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
126 d_printf("Encryption required and "
127 "share %s doesn't support "
128 "encryption.\n", sharename);
129 return false;
132 if (c->use_kerberos) {
133 status = cli_gss_smb_encryption_start(c);
134 } else {
135 status = cli_raw_ntlm_smb_encryption_start(c,
136 username,
137 password,
138 workgroup);
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "setup failed with error %s.\n",
144 nt_errstr(status));
145 return false;
148 return true;
152 static struct cli_state *open_nbt_connection(void)
154 struct nmb_name called, calling;
155 struct sockaddr_storage ss;
156 struct cli_state *c;
157 NTSTATUS status;
159 make_nmb_name(&calling, myname, 0x0);
160 make_nmb_name(&called , host, 0x20);
162 zero_sockaddr(&ss);
164 if (!(c = cli_initialise())) {
165 printf("Failed initialize cli_struct to connect with %s\n", host);
166 return NULL;
169 c->port = port_to_use;
171 status = cli_connect(c, host, &ss);
172 if (!NT_STATUS_IS_OK(status)) {
173 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
174 return NULL;
177 c->use_kerberos = use_kerberos;
179 c->timeout = 120000; /* set a really long timeout (2 minutes) */
180 if (use_oplocks) c->use_oplocks = True;
181 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
183 if (!cli_session_request(c, &calling, &called)) {
185 * Well, that failed, try *SMBSERVER ...
186 * However, we must reconnect as well ...
188 status = cli_connect(c, host, &ss);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191 return NULL;
194 make_nmb_name(&called, "*SMBSERVER", 0x20);
195 if (!cli_session_request(c, &calling, &called)) {
196 printf("%s rejected the session\n",host);
197 printf("We tried with a called name of %s & %s\n",
198 host, "*SMBSERVER");
199 cli_shutdown(c);
200 return NULL;
204 return c;
207 /* Insert a NULL at the first separator of the given path and return a pointer
208 * to the remainder of the string.
210 static char *
211 terminate_path_at_separator(char * path)
213 char * p;
215 if (!path) {
216 return NULL;
219 if ((p = strchr_m(path, '/'))) {
220 *p = '\0';
221 return p + 1;
224 if ((p = strchr_m(path, '\\'))) {
225 *p = '\0';
226 return p + 1;
229 /* No separator. */
230 return NULL;
234 parse a //server/share type UNC name
236 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
237 char **hostname, char **sharename)
239 char *p;
241 *hostname = *sharename = NULL;
243 if (strncmp(unc_name, "\\\\", 2) &&
244 strncmp(unc_name, "//", 2)) {
245 return False;
248 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
249 p = terminate_path_at_separator(*hostname);
251 if (p && *p) {
252 *sharename = talloc_strdup(mem_ctx, p);
253 terminate_path_at_separator(*sharename);
256 if (*hostname && *sharename) {
257 return True;
260 TALLOC_FREE(*hostname);
261 TALLOC_FREE(*sharename);
262 return False;
265 static bool torture_open_connection_share(struct cli_state **c,
266 const char *hostname,
267 const char *sharename)
269 bool retry;
270 int flags = 0;
271 NTSTATUS status;
273 if (use_kerberos)
274 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
276 status = cli_full_connection(c, myname,
277 hostname, NULL, port_to_use,
278 sharename, "?????",
279 username, workgroup,
280 password, flags, Undefined, &retry);
281 if (!NT_STATUS_IS_OK(status)) {
282 printf("failed to open share connection: //%s/%s port:%d - %s\n",
283 hostname, sharename, port_to_use, nt_errstr(status));
284 return False;
287 if (use_oplocks) (*c)->use_oplocks = True;
288 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
289 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
291 if (do_encrypt) {
292 return force_cli_encryption(*c,
293 sharename);
295 return True;
298 bool torture_open_connection(struct cli_state **c, int conn_index)
300 char **unc_list = NULL;
301 int num_unc_names = 0;
302 bool result;
304 if (use_multishare_conn==True) {
305 char *h, *s;
306 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
307 if (!unc_list || num_unc_names <= 0) {
308 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
309 exit(1);
312 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
313 NULL, &h, &s)) {
314 printf("Failed to parse UNC name %s\n",
315 unc_list[conn_index % num_unc_names]);
316 TALLOC_FREE(unc_list);
317 exit(1);
320 result = torture_open_connection_share(c, h, s);
322 /* h, s were copied earlier */
323 TALLOC_FREE(unc_list);
324 return result;
327 return torture_open_connection_share(c, host, share);
330 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
332 uint16 old_vuid = cli->vuid;
333 fstring old_user_name;
334 size_t passlen = strlen(password);
335 bool ret;
337 fstrcpy(old_user_name, cli->user_name);
338 cli->vuid = 0;
339 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
340 password, passlen,
341 password, passlen,
342 workgroup));
343 *new_vuid = cli->vuid;
344 cli->vuid = old_vuid;
345 fstrcpy(cli->user_name, old_user_name);
346 return ret;
350 bool torture_close_connection(struct cli_state *c)
352 bool ret = True;
353 if (!cli_tdis(c)) {
354 printf("tdis failed (%s)\n", cli_errstr(c));
355 ret = False;
358 cli_shutdown(c);
360 return ret;
364 /* check if the server produced the expected error code */
365 static bool check_error(int line, struct cli_state *c,
366 uint8 eclass, uint32 ecode, NTSTATUS nterr)
368 if (cli_is_dos_error(c)) {
369 uint8 cclass;
370 uint32 num;
372 /* Check DOS error */
374 cli_dos_error(c, &cclass, &num);
376 if (eclass != cclass || ecode != num) {
377 printf("unexpected error code class=%d code=%d\n",
378 (int)cclass, (int)num);
379 printf(" expected %d/%d %s (line=%d)\n",
380 (int)eclass, (int)ecode, nt_errstr(nterr), line);
381 return False;
384 } else {
385 NTSTATUS status;
387 /* Check NT error */
389 status = cli_nt_error(c);
391 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
392 printf("unexpected error code %s\n", nt_errstr(status));
393 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
394 return False;
398 return True;
402 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
404 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
405 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
407 return True;
411 static bool rw_torture(struct cli_state *c)
413 const char *lockfname = "\\torture.lck";
414 fstring fname;
415 int fnum;
416 int fnum2;
417 pid_t pid2, pid = getpid();
418 int i, j;
419 char buf[1024];
420 bool correct = True;
422 memset(buf, '\0', sizeof(buf));
424 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
425 DENY_NONE);
426 if (fnum2 == -1)
427 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
428 if (fnum2 == -1) {
429 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
430 return False;
434 for (i=0;i<torture_numops;i++) {
435 unsigned n = (unsigned)sys_random()%10;
436 if (i % 10 == 0) {
437 printf("%d\r", i); fflush(stdout);
439 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
441 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
442 return False;
445 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
446 if (fnum == -1) {
447 printf("open failed (%s)\n", cli_errstr(c));
448 correct = False;
449 break;
452 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
453 printf("write failed (%s)\n", cli_errstr(c));
454 correct = False;
457 for (j=0;j<50;j++) {
458 if (cli_write(c, fnum, 0, (char *)buf,
459 sizeof(pid)+(j*sizeof(buf)),
460 sizeof(buf)) != sizeof(buf)) {
461 printf("write failed (%s)\n", cli_errstr(c));
462 correct = False;
466 pid2 = 0;
468 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
469 printf("read failed (%s)\n", cli_errstr(c));
470 correct = False;
473 if (pid2 != pid) {
474 printf("data corruption!\n");
475 correct = False;
478 if (!cli_close(c, fnum)) {
479 printf("close failed (%s)\n", cli_errstr(c));
480 correct = False;
483 if (!cli_unlink(c, fname)) {
484 printf("unlink failed (%s)\n", cli_errstr(c));
485 correct = False;
488 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
489 printf("unlock failed (%s)\n", cli_errstr(c));
490 correct = False;
494 cli_close(c, fnum2);
495 cli_unlink(c, lockfname);
497 printf("%d\n", i);
499 return correct;
502 static bool run_torture(int dummy)
504 struct cli_state *cli;
505 bool ret;
507 cli = current_cli;
509 cli_sockopt(cli, sockops);
511 ret = rw_torture(cli);
513 if (!torture_close_connection(cli)) {
514 ret = False;
517 return ret;
520 static bool rw_torture3(struct cli_state *c, char *lockfname)
522 int fnum = -1;
523 unsigned int i = 0;
524 char buf[131072];
525 char buf_rd[131072];
526 unsigned count;
527 unsigned countprev = 0;
528 ssize_t sent = 0;
529 bool correct = True;
531 srandom(1);
532 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
534 SIVAL(buf, i, sys_random());
537 if (procnum == 0)
539 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
540 DENY_NONE);
541 if (fnum == -1) {
542 printf("first open read/write of %s failed (%s)\n",
543 lockfname, cli_errstr(c));
544 return False;
547 else
549 for (i = 0; i < 500 && fnum == -1; i++)
551 fnum = cli_open(c, lockfname, O_RDONLY,
552 DENY_NONE);
553 smb_msleep(10);
555 if (fnum == -1) {
556 printf("second open read-only of %s failed (%s)\n",
557 lockfname, cli_errstr(c));
558 return False;
562 i = 0;
563 for (count = 0; count < sizeof(buf); count += sent)
565 if (count >= countprev) {
566 printf("%d %8d\r", i, count);
567 fflush(stdout);
568 i++;
569 countprev += (sizeof(buf) / 20);
572 if (procnum == 0)
574 sent = ((unsigned)sys_random()%(20))+ 1;
575 if (sent > sizeof(buf) - count)
577 sent = sizeof(buf) - count;
580 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
581 printf("write failed (%s)\n", cli_errstr(c));
582 correct = False;
585 else
587 sent = cli_read(c, fnum, buf_rd+count, count,
588 sizeof(buf)-count);
589 if (sent < 0)
591 printf("read failed offset:%d size:%ld (%s)\n",
592 count, (unsigned long)sizeof(buf)-count,
593 cli_errstr(c));
594 correct = False;
595 sent = 0;
597 if (sent > 0)
599 if (memcmp(buf_rd+count, buf+count, sent) != 0)
601 printf("read/write compare failed\n");
602 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
603 correct = False;
604 break;
611 if (!cli_close(c, fnum)) {
612 printf("close failed (%s)\n", cli_errstr(c));
613 correct = False;
616 return correct;
619 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
621 const char *lockfname = "\\torture2.lck";
622 int fnum1;
623 int fnum2;
624 int i;
625 char buf[131072];
626 char buf_rd[131072];
627 bool correct = True;
628 ssize_t bytes_read;
630 if (!cli_unlink(c1, lockfname)) {
631 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
634 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
635 DENY_NONE);
636 if (fnum1 == -1) {
637 printf("first open read/write of %s failed (%s)\n",
638 lockfname, cli_errstr(c1));
639 return False;
641 fnum2 = cli_open(c2, lockfname, O_RDONLY,
642 DENY_NONE);
643 if (fnum2 == -1) {
644 printf("second open read-only of %s failed (%s)\n",
645 lockfname, cli_errstr(c2));
646 cli_close(c1, fnum1);
647 return False;
650 for (i=0;i<torture_numops;i++)
652 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
653 if (i % 10 == 0) {
654 printf("%d\r", i); fflush(stdout);
657 generate_random_buffer((unsigned char *)buf, buf_size);
659 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
660 printf("write failed (%s)\n", cli_errstr(c1));
661 correct = False;
662 break;
665 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
666 printf("read failed (%s)\n", cli_errstr(c2));
667 printf("read %d, expected %ld\n", (int)bytes_read,
668 (unsigned long)buf_size);
669 correct = False;
670 break;
673 if (memcmp(buf_rd, buf, buf_size) != 0)
675 printf("read/write compare failed\n");
676 correct = False;
677 break;
681 if (!cli_close(c2, fnum2)) {
682 printf("close failed (%s)\n", cli_errstr(c2));
683 correct = False;
685 if (!cli_close(c1, fnum1)) {
686 printf("close failed (%s)\n", cli_errstr(c1));
687 correct = False;
690 if (!cli_unlink(c1, lockfname)) {
691 printf("unlink failed (%s)\n", cli_errstr(c1));
692 correct = False;
695 return correct;
698 static bool run_readwritetest(int dummy)
700 static struct cli_state *cli1, *cli2;
701 bool test1, test2 = False;
703 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
704 return False;
706 cli_sockopt(cli1, sockops);
707 cli_sockopt(cli2, sockops);
709 printf("starting readwritetest\n");
711 test1 = rw_torture2(cli1, cli2);
712 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
714 if (test1) {
715 test2 = rw_torture2(cli1, cli1);
716 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
719 if (!torture_close_connection(cli1)) {
720 test1 = False;
723 if (!torture_close_connection(cli2)) {
724 test2 = False;
727 return (test1 && test2);
730 static bool run_readwritemulti(int dummy)
732 struct cli_state *cli;
733 bool test;
735 cli = current_cli;
737 cli_sockopt(cli, sockops);
739 printf("run_readwritemulti: fname %s\n", randomfname);
740 test = rw_torture3(cli, randomfname);
742 if (!torture_close_connection(cli)) {
743 test = False;
746 return test;
749 static bool run_readwritelarge(int dummy)
751 static struct cli_state *cli1;
752 int fnum1;
753 const char *lockfname = "\\large.dat";
754 SMB_OFF_T fsize;
755 char buf[126*1024];
756 bool correct = True;
758 if (!torture_open_connection(&cli1, 0)) {
759 return False;
761 cli_sockopt(cli1, sockops);
762 memset(buf,'\0',sizeof(buf));
764 cli1->max_xmit = 128*1024;
766 printf("starting readwritelarge\n");
768 cli_unlink(cli1, lockfname);
770 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
771 if (fnum1 == -1) {
772 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
773 return False;
776 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
778 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
779 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
780 correct = False;
783 if (fsize == sizeof(buf))
784 printf("readwritelarge test 1 succeeded (size = %lx)\n",
785 (unsigned long)fsize);
786 else {
787 printf("readwritelarge test 1 failed (size = %lx)\n",
788 (unsigned long)fsize);
789 correct = False;
792 if (!cli_close(cli1, fnum1)) {
793 printf("close failed (%s)\n", cli_errstr(cli1));
794 correct = False;
797 if (!cli_unlink(cli1, lockfname)) {
798 printf("unlink failed (%s)\n", cli_errstr(cli1));
799 correct = False;
802 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
803 if (fnum1 == -1) {
804 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
805 return False;
808 cli1->max_xmit = 4*1024;
810 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
812 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
813 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
814 correct = False;
817 if (fsize == sizeof(buf))
818 printf("readwritelarge test 2 succeeded (size = %lx)\n",
819 (unsigned long)fsize);
820 else {
821 printf("readwritelarge test 2 failed (size = %lx)\n",
822 (unsigned long)fsize);
823 correct = False;
826 #if 0
827 /* ToDo - set allocation. JRA */
828 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
829 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
830 return False;
832 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
833 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
834 correct = False;
836 if (fsize != 0)
837 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
838 #endif
840 if (!cli_close(cli1, fnum1)) {
841 printf("close failed (%s)\n", cli_errstr(cli1));
842 correct = False;
845 if (!torture_close_connection(cli1)) {
846 correct = False;
848 return correct;
851 int line_count = 0;
852 int nbio_id;
854 #define ival(s) strtol(s, NULL, 0)
856 /* run a test that simulates an approximate netbench client load */
857 static bool run_netbench(int client)
859 struct cli_state *cli;
860 int i;
861 char line[1024];
862 char cname[20];
863 FILE *f;
864 const char *params[20];
865 bool correct = True;
867 cli = current_cli;
869 nbio_id = client;
871 cli_sockopt(cli, sockops);
873 nb_setup(cli);
875 slprintf(cname,sizeof(cname)-1, "client%d", client);
877 f = fopen(client_txt, "r");
879 if (!f) {
880 perror(client_txt);
881 return False;
884 while (fgets(line, sizeof(line)-1, f)) {
885 char *saveptr;
886 line_count++;
888 line[strlen(line)-1] = 0;
890 /* printf("[%d] %s\n", line_count, line); */
892 all_string_sub(line,"client1", cname, sizeof(line));
894 /* parse the command parameters */
895 params[0] = strtok_r(line, " ", &saveptr);
896 i = 0;
897 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
899 params[i] = "";
901 if (i < 2) continue;
903 if (!strncmp(params[0],"SMB", 3)) {
904 printf("ERROR: You are using a dbench 1 load file\n");
905 exit(1);
908 if (!strcmp(params[0],"NTCreateX")) {
909 nb_createx(params[1], ival(params[2]), ival(params[3]),
910 ival(params[4]));
911 } else if (!strcmp(params[0],"Close")) {
912 nb_close(ival(params[1]));
913 } else if (!strcmp(params[0],"Rename")) {
914 nb_rename(params[1], params[2]);
915 } else if (!strcmp(params[0],"Unlink")) {
916 nb_unlink(params[1]);
917 } else if (!strcmp(params[0],"Deltree")) {
918 nb_deltree(params[1]);
919 } else if (!strcmp(params[0],"Rmdir")) {
920 nb_rmdir(params[1]);
921 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
922 nb_qpathinfo(params[1]);
923 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
924 nb_qfileinfo(ival(params[1]));
925 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
926 nb_qfsinfo(ival(params[1]));
927 } else if (!strcmp(params[0],"FIND_FIRST")) {
928 nb_findfirst(params[1]);
929 } else if (!strcmp(params[0],"WriteX")) {
930 nb_writex(ival(params[1]),
931 ival(params[2]), ival(params[3]), ival(params[4]));
932 } else if (!strcmp(params[0],"ReadX")) {
933 nb_readx(ival(params[1]),
934 ival(params[2]), ival(params[3]), ival(params[4]));
935 } else if (!strcmp(params[0],"Flush")) {
936 nb_flush(ival(params[1]));
937 } else {
938 printf("Unknown operation %s\n", params[0]);
939 exit(1);
942 fclose(f);
944 nb_cleanup();
946 if (!torture_close_connection(cli)) {
947 correct = False;
950 return correct;
954 /* run a test that simulates an approximate netbench client load */
955 static bool run_nbench(int dummy)
957 double t;
958 bool correct = True;
960 nbio_shmem(nprocs);
962 nbio_id = -1;
964 signal(SIGALRM, nb_alarm);
965 alarm(1);
966 t = create_procs(run_netbench, &correct);
967 alarm(0);
969 printf("\nThroughput %g MB/sec\n",
970 1.0e-6 * nbio_total() / t);
971 return correct;
976 This test checks for two things:
978 1) correct support for retaining locks over a close (ie. the server
979 must not use posix semantics)
980 2) support for lock timeouts
982 static bool run_locktest1(int dummy)
984 struct cli_state *cli1, *cli2;
985 const char *fname = "\\lockt1.lck";
986 int fnum1, fnum2, fnum3;
987 time_t t1, t2;
988 unsigned lock_timeout;
990 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
991 return False;
993 cli_sockopt(cli1, sockops);
994 cli_sockopt(cli2, sockops);
996 printf("starting locktest1\n");
998 cli_unlink(cli1, fname);
1000 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1001 if (fnum1 == -1) {
1002 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1003 return False;
1005 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1006 if (fnum2 == -1) {
1007 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1008 return False;
1010 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1011 if (fnum3 == -1) {
1012 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1013 return False;
1016 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1017 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1018 return False;
1022 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1023 printf("lock2 succeeded! This is a locking bug\n");
1024 return False;
1025 } else {
1026 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1027 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1031 lock_timeout = (1 + (random() % 20));
1032 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1033 t1 = time(NULL);
1034 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1035 printf("lock3 succeeded! This is a locking bug\n");
1036 return False;
1037 } else {
1038 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1039 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1041 t2 = time(NULL);
1043 if (ABS(t2 - t1) < lock_timeout-1) {
1044 printf("error: This server appears not to support timed lock requests\n");
1047 printf("server slept for %u seconds for a %u second timeout\n",
1048 (unsigned int)(t2-t1), lock_timeout);
1050 if (!cli_close(cli1, fnum2)) {
1051 printf("close1 failed (%s)\n", cli_errstr(cli1));
1052 return False;
1055 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1056 printf("lock4 succeeded! This is a locking bug\n");
1057 return False;
1058 } else {
1059 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1060 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1063 if (!cli_close(cli1, fnum1)) {
1064 printf("close2 failed (%s)\n", cli_errstr(cli1));
1065 return False;
1068 if (!cli_close(cli2, fnum3)) {
1069 printf("close3 failed (%s)\n", cli_errstr(cli2));
1070 return False;
1073 if (!cli_unlink(cli1, fname)) {
1074 printf("unlink failed (%s)\n", cli_errstr(cli1));
1075 return False;
1079 if (!torture_close_connection(cli1)) {
1080 return False;
1083 if (!torture_close_connection(cli2)) {
1084 return False;
1087 printf("Passed locktest1\n");
1088 return True;
1092 this checks to see if a secondary tconx can use open files from an
1093 earlier tconx
1095 static bool run_tcon_test(int dummy)
1097 static struct cli_state *cli;
1098 const char *fname = "\\tcontest.tmp";
1099 int fnum1;
1100 uint16 cnum1, cnum2, cnum3;
1101 uint16 vuid1, vuid2;
1102 char buf[4];
1103 bool ret = True;
1104 NTSTATUS status;
1106 memset(buf, '\0', sizeof(buf));
1108 if (!torture_open_connection(&cli, 0)) {
1109 return False;
1111 cli_sockopt(cli, sockops);
1113 printf("starting tcontest\n");
1115 cli_unlink(cli, fname);
1117 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1118 if (fnum1 == -1) {
1119 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1120 return False;
1123 cnum1 = cli->cnum;
1124 vuid1 = cli->vuid;
1126 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1127 printf("initial write failed (%s)", cli_errstr(cli));
1128 return False;
1131 status = cli_tcon_andx(cli, share, "?????",
1132 password, strlen(password)+1);
1133 if (!NT_STATUS_IS_OK(status)) {
1134 printf("%s refused 2nd tree connect (%s)\n", host,
1135 nt_errstr(status));
1136 cli_shutdown(cli);
1137 return False;
1140 cnum2 = cli->cnum;
1141 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1142 vuid2 = cli->vuid + 1;
1144 /* try a write with the wrong tid */
1145 cli->cnum = cnum2;
1147 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1148 printf("* server allows write with wrong TID\n");
1149 ret = False;
1150 } else {
1151 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1155 /* try a write with an invalid tid */
1156 cli->cnum = cnum3;
1158 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1159 printf("* server allows write with invalid TID\n");
1160 ret = False;
1161 } else {
1162 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1165 /* try a write with an invalid vuid */
1166 cli->vuid = vuid2;
1167 cli->cnum = cnum1;
1169 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1170 printf("* server allows write with invalid VUID\n");
1171 ret = False;
1172 } else {
1173 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1176 cli->cnum = cnum1;
1177 cli->vuid = vuid1;
1179 if (!cli_close(cli, fnum1)) {
1180 printf("close failed (%s)\n", cli_errstr(cli));
1181 return False;
1184 cli->cnum = cnum2;
1186 if (!cli_tdis(cli)) {
1187 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1188 return False;
1191 cli->cnum = cnum1;
1193 if (!torture_close_connection(cli)) {
1194 return False;
1197 return ret;
1202 checks for old style tcon support
1204 static bool run_tcon2_test(int dummy)
1206 static struct cli_state *cli;
1207 uint16 cnum, max_xmit;
1208 char *service;
1209 NTSTATUS status;
1211 if (!torture_open_connection(&cli, 0)) {
1212 return False;
1214 cli_sockopt(cli, sockops);
1216 printf("starting tcon2 test\n");
1218 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1219 return false;
1222 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 printf("tcon2 failed : %s\n", cli_errstr(cli));
1226 } else {
1227 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1228 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1231 if (!torture_close_connection(cli)) {
1232 return False;
1235 printf("Passed tcon2 test\n");
1236 return True;
1239 static bool tcon_devtest(struct cli_state *cli,
1240 const char *myshare, const char *devtype,
1241 const char *return_devtype,
1242 NTSTATUS expected_error)
1244 NTSTATUS status;
1245 bool ret;
1247 status = cli_tcon_andx(cli, myshare, devtype,
1248 password, strlen(password)+1);
1250 if (NT_STATUS_IS_OK(expected_error)) {
1251 if (NT_STATUS_IS_OK(status)) {
1252 if (strcmp(cli->dev, return_devtype) == 0) {
1253 ret = True;
1254 } else {
1255 printf("tconX to share %s with type %s "
1256 "succeeded but returned the wrong "
1257 "device type (got [%s] but should have got [%s])\n",
1258 myshare, devtype, cli->dev, return_devtype);
1259 ret = False;
1261 } else {
1262 printf("tconX to share %s with type %s "
1263 "should have succeeded but failed\n",
1264 myshare, devtype);
1265 ret = False;
1267 cli_tdis(cli);
1268 } else {
1269 if (NT_STATUS_IS_OK(status)) {
1270 printf("tconx to share %s with type %s "
1271 "should have failed but succeeded\n",
1272 myshare, devtype);
1273 ret = False;
1274 } else {
1275 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1276 expected_error)) {
1277 ret = True;
1278 } else {
1279 printf("Returned unexpected error\n");
1280 ret = False;
1284 return ret;
1288 checks for correct tconX support
1290 static bool run_tcon_devtype_test(int dummy)
1292 static struct cli_state *cli1 = NULL;
1293 bool retry;
1294 int flags = 0;
1295 NTSTATUS status;
1296 bool ret = True;
1298 status = cli_full_connection(&cli1, myname,
1299 host, NULL, port_to_use,
1300 NULL, NULL,
1301 username, workgroup,
1302 password, flags, Undefined, &retry);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 printf("could not open connection\n");
1306 return False;
1309 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1310 ret = False;
1312 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1313 ret = False;
1315 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1316 ret = False;
1318 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1319 ret = False;
1321 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1322 ret = False;
1324 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1325 ret = False;
1327 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1328 ret = False;
1330 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1331 ret = False;
1333 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1334 ret = False;
1336 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1337 ret = False;
1339 cli_shutdown(cli1);
1341 if (ret)
1342 printf("Passed tcondevtest\n");
1344 return ret;
1349 This test checks that
1351 1) the server supports multiple locking contexts on the one SMB
1352 connection, distinguished by PID.
1354 2) the server correctly fails overlapping locks made by the same PID (this
1355 goes against POSIX behaviour, which is why it is tricky to implement)
1357 3) the server denies unlock requests by an incorrect client PID
1359 static bool run_locktest2(int dummy)
1361 static struct cli_state *cli;
1362 const char *fname = "\\lockt2.lck";
1363 int fnum1, fnum2, fnum3;
1364 bool correct = True;
1366 if (!torture_open_connection(&cli, 0)) {
1367 return False;
1370 cli_sockopt(cli, sockops);
1372 printf("starting locktest2\n");
1374 cli_unlink(cli, fname);
1376 cli_setpid(cli, 1);
1378 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1379 if (fnum1 == -1) {
1380 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1381 return False;
1384 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1385 if (fnum2 == -1) {
1386 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1387 return False;
1390 cli_setpid(cli, 2);
1392 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1393 if (fnum3 == -1) {
1394 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1395 return False;
1398 cli_setpid(cli, 1);
1400 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1401 printf("lock1 failed (%s)\n", cli_errstr(cli));
1402 return False;
1405 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1406 printf("WRITE lock1 succeeded! This is a locking bug\n");
1407 correct = False;
1408 } else {
1409 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1410 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1413 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1414 printf("WRITE lock2 succeeded! This is a locking bug\n");
1415 correct = False;
1416 } else {
1417 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1418 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1421 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1422 printf("READ lock2 succeeded! This is a locking bug\n");
1423 correct = False;
1424 } else {
1425 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1426 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1429 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1430 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1432 cli_setpid(cli, 2);
1433 if (cli_unlock(cli, fnum1, 100, 4)) {
1434 printf("unlock at 100 succeeded! This is a locking bug\n");
1435 correct = False;
1438 if (cli_unlock(cli, fnum1, 0, 4)) {
1439 printf("unlock1 succeeded! This is a locking bug\n");
1440 correct = False;
1441 } else {
1442 if (!check_error(__LINE__, cli,
1443 ERRDOS, ERRlock,
1444 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1447 if (cli_unlock(cli, fnum1, 0, 8)) {
1448 printf("unlock2 succeeded! This is a locking bug\n");
1449 correct = False;
1450 } else {
1451 if (!check_error(__LINE__, cli,
1452 ERRDOS, ERRlock,
1453 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1456 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1457 printf("lock3 succeeded! This is a locking bug\n");
1458 correct = False;
1459 } else {
1460 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1463 cli_setpid(cli, 1);
1465 if (!cli_close(cli, fnum1)) {
1466 printf("close1 failed (%s)\n", cli_errstr(cli));
1467 return False;
1470 if (!cli_close(cli, fnum2)) {
1471 printf("close2 failed (%s)\n", cli_errstr(cli));
1472 return False;
1475 if (!cli_close(cli, fnum3)) {
1476 printf("close3 failed (%s)\n", cli_errstr(cli));
1477 return False;
1480 if (!torture_close_connection(cli)) {
1481 correct = False;
1484 printf("locktest2 finished\n");
1486 return correct;
1491 This test checks that
1493 1) the server supports the full offset range in lock requests
1495 static bool run_locktest3(int dummy)
1497 static struct cli_state *cli1, *cli2;
1498 const char *fname = "\\lockt3.lck";
1499 int fnum1, fnum2, i;
1500 uint32 offset;
1501 bool correct = True;
1503 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1505 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1506 return False;
1508 cli_sockopt(cli1, sockops);
1509 cli_sockopt(cli2, sockops);
1511 printf("starting locktest3\n");
1513 cli_unlink(cli1, fname);
1515 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1516 if (fnum1 == -1) {
1517 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1518 return False;
1520 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1521 if (fnum2 == -1) {
1522 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1523 return False;
1526 for (offset=i=0;i<torture_numops;i++) {
1527 NEXT_OFFSET;
1528 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1529 printf("lock1 %d failed (%s)\n",
1531 cli_errstr(cli1));
1532 return False;
1535 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1536 printf("lock2 %d failed (%s)\n",
1538 cli_errstr(cli1));
1539 return False;
1543 for (offset=i=0;i<torture_numops;i++) {
1544 NEXT_OFFSET;
1546 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1547 printf("error: lock1 %d succeeded!\n", i);
1548 return False;
1551 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1552 printf("error: lock2 %d succeeded!\n", i);
1553 return False;
1556 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1557 printf("error: lock3 %d succeeded!\n", i);
1558 return False;
1561 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1562 printf("error: lock4 %d succeeded!\n", i);
1563 return False;
1567 for (offset=i=0;i<torture_numops;i++) {
1568 NEXT_OFFSET;
1570 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1571 printf("unlock1 %d failed (%s)\n",
1573 cli_errstr(cli1));
1574 return False;
1577 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1578 printf("unlock2 %d failed (%s)\n",
1580 cli_errstr(cli1));
1581 return False;
1585 if (!cli_close(cli1, fnum1)) {
1586 printf("close1 failed (%s)\n", cli_errstr(cli1));
1587 return False;
1590 if (!cli_close(cli2, fnum2)) {
1591 printf("close2 failed (%s)\n", cli_errstr(cli2));
1592 return False;
1595 if (!cli_unlink(cli1, fname)) {
1596 printf("unlink failed (%s)\n", cli_errstr(cli1));
1597 return False;
1600 if (!torture_close_connection(cli1)) {
1601 correct = False;
1604 if (!torture_close_connection(cli2)) {
1605 correct = False;
1608 printf("finished locktest3\n");
1610 return correct;
1613 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1614 printf("** "); correct = False; \
1618 looks at overlapping locks
1620 static bool run_locktest4(int dummy)
1622 static struct cli_state *cli1, *cli2;
1623 const char *fname = "\\lockt4.lck";
1624 int fnum1, fnum2, f;
1625 bool ret;
1626 char buf[1000];
1627 bool correct = True;
1629 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1630 return False;
1633 cli_sockopt(cli1, sockops);
1634 cli_sockopt(cli2, sockops);
1636 printf("starting locktest4\n");
1638 cli_unlink(cli1, fname);
1640 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1641 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1643 memset(buf, 0, sizeof(buf));
1645 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1646 printf("Failed to create file\n");
1647 correct = False;
1648 goto fail;
1651 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1652 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1653 EXPECTED(ret, False);
1654 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1656 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1657 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1658 EXPECTED(ret, True);
1659 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1661 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1662 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1663 EXPECTED(ret, False);
1664 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1666 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1667 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1668 EXPECTED(ret, True);
1669 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1671 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1672 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1673 EXPECTED(ret, False);
1674 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1676 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1677 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1678 EXPECTED(ret, True);
1679 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1681 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1682 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1683 EXPECTED(ret, True);
1684 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1686 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1687 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1688 EXPECTED(ret, False);
1689 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1691 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1692 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1693 EXPECTED(ret, False);
1694 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1696 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1697 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1698 EXPECTED(ret, True);
1699 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1701 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1702 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1703 EXPECTED(ret, False);
1704 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1706 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1707 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1708 cli_unlock(cli1, fnum1, 110, 6);
1709 EXPECTED(ret, False);
1710 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1713 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1714 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1715 EXPECTED(ret, False);
1716 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1718 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1719 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1720 EXPECTED(ret, False);
1721 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1724 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1725 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1726 cli_unlock(cli1, fnum1, 140, 4) &&
1727 cli_unlock(cli1, fnum1, 140, 4);
1728 EXPECTED(ret, True);
1729 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1732 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1733 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1734 cli_unlock(cli1, fnum1, 150, 4) &&
1735 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1736 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1737 cli_unlock(cli1, fnum1, 150, 4);
1738 EXPECTED(ret, True);
1739 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1741 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1742 cli_unlock(cli1, fnum1, 160, 4) &&
1743 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1744 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1745 EXPECTED(ret, True);
1746 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1748 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1749 cli_unlock(cli1, fnum1, 170, 4) &&
1750 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1751 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1752 EXPECTED(ret, True);
1753 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1755 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1756 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1757 cli_unlock(cli1, fnum1, 190, 4) &&
1758 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1759 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1760 EXPECTED(ret, True);
1761 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1763 cli_close(cli1, fnum1);
1764 cli_close(cli2, fnum2);
1765 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1766 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1767 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1768 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1769 cli_close(cli1, fnum1) &&
1770 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1771 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1772 cli_close(cli1, f);
1773 cli_close(cli1, fnum1);
1774 EXPECTED(ret, True);
1775 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1777 fail:
1778 cli_close(cli1, fnum1);
1779 cli_close(cli2, fnum2);
1780 cli_unlink(cli1, fname);
1781 torture_close_connection(cli1);
1782 torture_close_connection(cli2);
1784 printf("finished locktest4\n");
1785 return correct;
1789 looks at lock upgrade/downgrade.
1791 static bool run_locktest5(int dummy)
1793 static struct cli_state *cli1, *cli2;
1794 const char *fname = "\\lockt5.lck";
1795 int fnum1, fnum2, fnum3;
1796 bool ret;
1797 char buf[1000];
1798 bool correct = True;
1800 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1801 return False;
1804 cli_sockopt(cli1, sockops);
1805 cli_sockopt(cli2, sockops);
1807 printf("starting locktest5\n");
1809 cli_unlink(cli1, fname);
1811 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1812 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1813 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1815 memset(buf, 0, sizeof(buf));
1817 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1818 printf("Failed to create file\n");
1819 correct = False;
1820 goto fail;
1823 /* Check for NT bug... */
1824 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1825 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1826 cli_close(cli1, fnum1);
1827 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1828 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1829 EXPECTED(ret, True);
1830 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1831 cli_close(cli1, fnum1);
1832 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1833 cli_unlock(cli1, fnum3, 0, 1);
1835 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1836 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1837 EXPECTED(ret, True);
1838 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1840 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1841 EXPECTED(ret, False);
1843 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1845 /* Unlock the process 2 lock. */
1846 cli_unlock(cli2, fnum2, 0, 4);
1848 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1849 EXPECTED(ret, False);
1851 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1853 /* Unlock the process 1 fnum3 lock. */
1854 cli_unlock(cli1, fnum3, 0, 4);
1856 /* Stack 2 more locks here. */
1857 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1858 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1860 EXPECTED(ret, True);
1861 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1863 /* Unlock the first process lock, then check this was the WRITE lock that was
1864 removed. */
1866 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1867 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1869 EXPECTED(ret, True);
1870 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1872 /* Unlock the process 2 lock. */
1873 cli_unlock(cli2, fnum2, 0, 4);
1875 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1877 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1878 cli_unlock(cli1, fnum1, 0, 4) &&
1879 cli_unlock(cli1, fnum1, 0, 4);
1881 EXPECTED(ret, True);
1882 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1884 /* Ensure the next unlock fails. */
1885 ret = cli_unlock(cli1, fnum1, 0, 4);
1886 EXPECTED(ret, False);
1887 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1889 /* Ensure connection 2 can get a write lock. */
1890 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1891 EXPECTED(ret, True);
1893 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1896 fail:
1897 cli_close(cli1, fnum1);
1898 cli_close(cli2, fnum2);
1899 cli_unlink(cli1, fname);
1900 if (!torture_close_connection(cli1)) {
1901 correct = False;
1903 if (!torture_close_connection(cli2)) {
1904 correct = False;
1907 printf("finished locktest5\n");
1909 return correct;
1913 tries the unusual lockingX locktype bits
1915 static bool run_locktest6(int dummy)
1917 static struct cli_state *cli;
1918 const char *fname[1] = { "\\lock6.txt" };
1919 int i;
1920 int fnum;
1921 NTSTATUS status;
1923 if (!torture_open_connection(&cli, 0)) {
1924 return False;
1927 cli_sockopt(cli, sockops);
1929 printf("starting locktest6\n");
1931 for (i=0;i<1;i++) {
1932 printf("Testing %s\n", fname[i]);
1934 cli_unlink(cli, fname[i]);
1936 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1937 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1938 cli_close(cli, fnum);
1939 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1941 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1942 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1943 cli_close(cli, fnum);
1944 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1946 cli_unlink(cli, fname[i]);
1949 torture_close_connection(cli);
1951 printf("finished locktest6\n");
1952 return True;
1955 static bool run_locktest7(int dummy)
1957 struct cli_state *cli1;
1958 const char *fname = "\\lockt7.lck";
1959 int fnum1;
1960 char buf[200];
1961 bool correct = False;
1963 if (!torture_open_connection(&cli1, 0)) {
1964 return False;
1967 cli_sockopt(cli1, sockops);
1969 printf("starting locktest7\n");
1971 cli_unlink(cli1, fname);
1973 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1975 memset(buf, 0, sizeof(buf));
1977 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1978 printf("Failed to create file\n");
1979 goto fail;
1982 cli_setpid(cli1, 1);
1984 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1985 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1986 goto fail;
1987 } else {
1988 printf("pid1 successfully locked range 130:4 for READ\n");
1991 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1992 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1993 goto fail;
1994 } else {
1995 printf("pid1 successfully read the range 130:4\n");
1998 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1999 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2000 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2001 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2002 goto fail;
2004 } else {
2005 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2006 goto fail;
2009 cli_setpid(cli1, 2);
2011 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2012 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2013 } else {
2014 printf("pid2 successfully read the range 130:4\n");
2017 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2018 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2019 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2020 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2021 goto fail;
2023 } else {
2024 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2025 goto fail;
2028 cli_setpid(cli1, 1);
2029 cli_unlock(cli1, fnum1, 130, 4);
2031 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2032 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2033 goto fail;
2034 } else {
2035 printf("pid1 successfully locked range 130:4 for WRITE\n");
2038 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2039 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2040 goto fail;
2041 } else {
2042 printf("pid1 successfully read the range 130:4\n");
2045 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2046 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2047 goto fail;
2048 } else {
2049 printf("pid1 successfully wrote to the range 130:4\n");
2052 cli_setpid(cli1, 2);
2054 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2055 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2056 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2057 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2058 goto fail;
2060 } else {
2061 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2062 goto fail;
2065 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2066 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2067 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2068 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2069 goto fail;
2071 } else {
2072 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2073 goto fail;
2076 cli_unlock(cli1, fnum1, 130, 0);
2077 correct = True;
2079 fail:
2080 cli_close(cli1, fnum1);
2081 cli_unlink(cli1, fname);
2082 torture_close_connection(cli1);
2084 printf("finished locktest7\n");
2085 return correct;
2089 test whether fnums and tids open on one VC are available on another (a major
2090 security hole)
2092 static bool run_fdpasstest(int dummy)
2094 struct cli_state *cli1, *cli2;
2095 const char *fname = "\\fdpass.tst";
2096 int fnum1;
2097 char buf[1024];
2099 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2100 return False;
2102 cli_sockopt(cli1, sockops);
2103 cli_sockopt(cli2, sockops);
2105 printf("starting fdpasstest\n");
2107 cli_unlink(cli1, fname);
2109 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2110 if (fnum1 == -1) {
2111 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2112 return False;
2115 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2116 printf("write failed (%s)\n", cli_errstr(cli1));
2117 return False;
2120 cli2->vuid = cli1->vuid;
2121 cli2->cnum = cli1->cnum;
2122 cli2->pid = cli1->pid;
2124 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2125 printf("read succeeded! nasty security hole [%s]\n",
2126 buf);
2127 return False;
2130 cli_close(cli1, fnum1);
2131 cli_unlink(cli1, fname);
2133 torture_close_connection(cli1);
2134 torture_close_connection(cli2);
2136 printf("finished fdpasstest\n");
2137 return True;
2140 static bool run_fdsesstest(int dummy)
2142 struct cli_state *cli;
2143 uint16 new_vuid;
2144 uint16 saved_vuid;
2145 uint16 new_cnum;
2146 uint16 saved_cnum;
2147 const char *fname = "\\fdsess.tst";
2148 const char *fname1 = "\\fdsess1.tst";
2149 int fnum1;
2150 int fnum2;
2151 char buf[1024];
2152 bool ret = True;
2154 if (!torture_open_connection(&cli, 0))
2155 return False;
2156 cli_sockopt(cli, sockops);
2158 if (!torture_cli_session_setup2(cli, &new_vuid))
2159 return False;
2161 saved_cnum = cli->cnum;
2162 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2163 return False;
2164 new_cnum = cli->cnum;
2165 cli->cnum = saved_cnum;
2167 printf("starting fdsesstest\n");
2169 cli_unlink(cli, fname);
2170 cli_unlink(cli, fname1);
2172 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2173 if (fnum1 == -1) {
2174 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2175 return False;
2178 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2179 printf("write failed (%s)\n", cli_errstr(cli));
2180 return False;
2183 saved_vuid = cli->vuid;
2184 cli->vuid = new_vuid;
2186 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2187 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2188 buf);
2189 ret = False;
2191 /* Try to open a file with different vuid, samba cnum. */
2192 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2193 if (fnum2 != -1) {
2194 printf("create with different vuid, same cnum succeeded.\n");
2195 cli_close(cli, fnum2);
2196 cli_unlink(cli, fname1);
2197 } else {
2198 printf("create with different vuid, same cnum failed.\n");
2199 printf("This will cause problems with service clients.\n");
2200 ret = False;
2203 cli->vuid = saved_vuid;
2205 /* Try with same vuid, different cnum. */
2206 cli->cnum = new_cnum;
2208 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2209 printf("read succeeded with different cnum![%s]\n",
2210 buf);
2211 ret = False;
2214 cli->cnum = saved_cnum;
2215 cli_close(cli, fnum1);
2216 cli_unlink(cli, fname);
2218 torture_close_connection(cli);
2220 printf("finished fdsesstest\n");
2221 return ret;
2225 This test checks that
2227 1) the server does not allow an unlink on a file that is open
2229 static bool run_unlinktest(int dummy)
2231 struct cli_state *cli;
2232 const char *fname = "\\unlink.tst";
2233 int fnum;
2234 bool correct = True;
2236 if (!torture_open_connection(&cli, 0)) {
2237 return False;
2240 cli_sockopt(cli, sockops);
2242 printf("starting unlink test\n");
2244 cli_unlink(cli, fname);
2246 cli_setpid(cli, 1);
2248 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2249 if (fnum == -1) {
2250 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2251 return False;
2254 if (cli_unlink(cli, fname)) {
2255 printf("error: server allowed unlink on an open file\n");
2256 correct = False;
2257 } else {
2258 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2259 NT_STATUS_SHARING_VIOLATION);
2262 cli_close(cli, fnum);
2263 cli_unlink(cli, fname);
2265 if (!torture_close_connection(cli)) {
2266 correct = False;
2269 printf("unlink test finished\n");
2271 return correct;
2276 test how many open files this server supports on the one socket
2278 static bool run_maxfidtest(int dummy)
2280 struct cli_state *cli;
2281 const char *ftemplate = "\\maxfid.%d.%d";
2282 fstring fname;
2283 int fnums[0x11000], i;
2284 int retries=4;
2285 bool correct = True;
2287 cli = current_cli;
2289 if (retries <= 0) {
2290 printf("failed to connect\n");
2291 return False;
2294 cli_sockopt(cli, sockops);
2296 for (i=0; i<0x11000; i++) {
2297 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2298 if ((fnums[i] = cli_open(cli, fname,
2299 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2300 -1) {
2301 printf("open of %s failed (%s)\n",
2302 fname, cli_errstr(cli));
2303 printf("maximum fnum is %d\n", i);
2304 break;
2306 printf("%6d\r", i);
2308 printf("%6d\n", i);
2309 i--;
2311 printf("cleaning up\n");
2312 for (;i>=0;i--) {
2313 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2314 cli_close(cli, fnums[i]);
2315 if (!cli_unlink(cli, fname)) {
2316 printf("unlink of %s failed (%s)\n",
2317 fname, cli_errstr(cli));
2318 correct = False;
2320 printf("%6d\r", i);
2322 printf("%6d\n", 0);
2324 printf("maxfid test finished\n");
2325 if (!torture_close_connection(cli)) {
2326 correct = False;
2328 return correct;
2331 /* generate a random buffer */
2332 static void rand_buf(char *buf, int len)
2334 while (len--) {
2335 *buf = (char)sys_random();
2336 buf++;
2340 /* send smb negprot commands, not reading the response */
2341 static bool run_negprot_nowait(int dummy)
2343 int i;
2344 static struct cli_state *cli;
2345 bool correct = True;
2347 printf("starting negprot nowait test\n");
2349 if (!(cli = open_nbt_connection())) {
2350 return False;
2353 for (i=0;i<50000;i++) {
2354 cli_negprot_sendsync(cli);
2357 if (!torture_close_connection(cli)) {
2358 correct = False;
2361 printf("finished negprot nowait test\n");
2363 return correct;
2367 /* send random IPC commands */
2368 static bool run_randomipc(int dummy)
2370 char *rparam = NULL;
2371 char *rdata = NULL;
2372 unsigned int rdrcnt,rprcnt;
2373 char param[1024];
2374 int api, param_len, i;
2375 struct cli_state *cli;
2376 bool correct = True;
2377 int count = 50000;
2379 printf("starting random ipc test\n");
2381 if (!torture_open_connection(&cli, 0)) {
2382 return False;
2385 for (i=0;i<count;i++) {
2386 api = sys_random() % 500;
2387 param_len = (sys_random() % 64);
2389 rand_buf(param, param_len);
2391 SSVAL(param,0,api);
2393 cli_api(cli,
2394 param, param_len, 8,
2395 NULL, 0, BUFFER_SIZE,
2396 &rparam, &rprcnt,
2397 &rdata, &rdrcnt);
2398 if (i % 100 == 0) {
2399 printf("%d/%d\r", i,count);
2402 printf("%d/%d\n", i, count);
2404 if (!torture_close_connection(cli)) {
2405 correct = False;
2408 printf("finished random ipc test\n");
2410 return correct;
2415 static void browse_callback(const char *sname, uint32 stype,
2416 const char *comment, void *state)
2418 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2424 This test checks the browse list code
2427 static bool run_browsetest(int dummy)
2429 static struct cli_state *cli;
2430 bool correct = True;
2432 printf("starting browse test\n");
2434 if (!torture_open_connection(&cli, 0)) {
2435 return False;
2438 printf("domain list:\n");
2439 cli_NetServerEnum(cli, cli->server_domain,
2440 SV_TYPE_DOMAIN_ENUM,
2441 browse_callback, NULL);
2443 printf("machine list:\n");
2444 cli_NetServerEnum(cli, cli->server_domain,
2445 SV_TYPE_ALL,
2446 browse_callback, NULL);
2448 if (!torture_close_connection(cli)) {
2449 correct = False;
2452 printf("browse test finished\n");
2454 return correct;
2460 This checks how the getatr calls works
2462 static bool run_attrtest(int dummy)
2464 struct cli_state *cli;
2465 int fnum;
2466 time_t t, t2;
2467 const char *fname = "\\attrib123456789.tst";
2468 bool correct = True;
2470 printf("starting attrib test\n");
2472 if (!torture_open_connection(&cli, 0)) {
2473 return False;
2476 cli_unlink(cli, fname);
2477 fnum = cli_open(cli, fname,
2478 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2479 cli_close(cli, fnum);
2480 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2481 printf("getatr failed (%s)\n", cli_errstr(cli));
2482 correct = False;
2485 if (abs(t - time(NULL)) > 60*60*24*10) {
2486 printf("ERROR: SMBgetatr bug. time is %s",
2487 ctime(&t));
2488 t = time(NULL);
2489 correct = True;
2492 t2 = t-60*60*24; /* 1 day ago */
2494 if (!cli_setatr(cli, fname, 0, t2)) {
2495 printf("setatr failed (%s)\n", cli_errstr(cli));
2496 correct = True;
2499 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2500 printf("getatr failed (%s)\n", cli_errstr(cli));
2501 correct = True;
2504 if (t != t2) {
2505 printf("ERROR: getatr/setatr bug. times are\n%s",
2506 ctime(&t));
2507 printf("%s", ctime(&t2));
2508 correct = True;
2511 cli_unlink(cli, fname);
2513 if (!torture_close_connection(cli)) {
2514 correct = False;
2517 printf("attrib test finished\n");
2519 return correct;
2524 This checks a couple of trans2 calls
2526 static bool run_trans2test(int dummy)
2528 struct cli_state *cli;
2529 int fnum;
2530 SMB_OFF_T size;
2531 time_t c_time, a_time, m_time;
2532 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2533 const char *fname = "\\trans2.tst";
2534 const char *dname = "\\trans2";
2535 const char *fname2 = "\\trans2\\trans2.tst";
2536 char pname[1024];
2537 bool correct = True;
2539 printf("starting trans2 test\n");
2541 if (!torture_open_connection(&cli, 0)) {
2542 return False;
2545 cli_unlink(cli, fname);
2546 fnum = cli_open(cli, fname,
2547 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2548 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2549 &m_time_ts, NULL)) {
2550 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2551 correct = False;
2554 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2555 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2556 correct = False;
2559 if (strcmp(pname, fname)) {
2560 printf("qfilename gave different name? [%s] [%s]\n",
2561 fname, pname);
2562 correct = False;
2565 cli_close(cli, fnum);
2567 sleep(2);
2569 cli_unlink(cli, fname);
2570 fnum = cli_open(cli, fname,
2571 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2572 if (fnum == -1) {
2573 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2574 return False;
2576 cli_close(cli, fnum);
2578 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2579 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2580 correct = False;
2581 } else {
2582 if (c_time != m_time) {
2583 printf("create time=%s", ctime(&c_time));
2584 printf("modify time=%s", ctime(&m_time));
2585 printf("This system appears to have sticky create times\n");
2587 if (a_time % (60*60) == 0) {
2588 printf("access time=%s", ctime(&a_time));
2589 printf("This system appears to set a midnight access time\n");
2590 correct = False;
2593 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2594 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2595 correct = False;
2600 cli_unlink(cli, fname);
2601 fnum = cli_open(cli, fname,
2602 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2603 cli_close(cli, fnum);
2604 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2605 &m_time_ts, &size, NULL, NULL)) {
2606 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2607 correct = False;
2608 } else {
2609 if (w_time_ts.tv_sec < 60*60*24*2) {
2610 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2611 printf("This system appears to set a initial 0 write time\n");
2612 correct = False;
2616 cli_unlink(cli, fname);
2619 /* check if the server updates the directory modification time
2620 when creating a new file */
2621 if (!cli_mkdir(cli, dname)) {
2622 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2623 correct = False;
2625 sleep(3);
2626 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2627 &m_time_ts, &size, NULL, NULL)) {
2628 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2629 correct = False;
2632 fnum = cli_open(cli, fname2,
2633 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2634 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2635 cli_close(cli, fnum);
2636 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2637 &m_time2_ts, &size, NULL, NULL)) {
2638 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2639 correct = False;
2640 } else {
2641 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2642 == 0) {
2643 printf("This system does not update directory modification times\n");
2644 correct = False;
2647 cli_unlink(cli, fname2);
2648 cli_rmdir(cli, dname);
2650 if (!torture_close_connection(cli)) {
2651 correct = False;
2654 printf("trans2 test finished\n");
2656 return correct;
2660 This checks new W2K calls.
2663 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2665 char *buf = NULL;
2666 uint32 len;
2667 bool correct = True;
2669 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2670 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2671 correct = False;
2672 } else {
2673 printf("qfileinfo: level %d, len = %u\n", level, len);
2674 dump_data(0, (uint8 *)buf, len);
2675 printf("\n");
2677 SAFE_FREE(buf);
2678 return correct;
2681 static bool run_w2ktest(int dummy)
2683 struct cli_state *cli;
2684 int fnum;
2685 const char *fname = "\\w2ktest\\w2k.tst";
2686 int level;
2687 bool correct = True;
2689 printf("starting w2k test\n");
2691 if (!torture_open_connection(&cli, 0)) {
2692 return False;
2695 fnum = cli_open(cli, fname,
2696 O_RDWR | O_CREAT , DENY_NONE);
2698 for (level = 1004; level < 1040; level++) {
2699 new_trans(cli, fnum, level);
2702 cli_close(cli, fnum);
2704 if (!torture_close_connection(cli)) {
2705 correct = False;
2708 printf("w2k test finished\n");
2710 return correct;
2715 this is a harness for some oplock tests
2717 static bool run_oplock1(int dummy)
2719 struct cli_state *cli1;
2720 const char *fname = "\\lockt1.lck";
2721 int fnum1;
2722 bool correct = True;
2724 printf("starting oplock test 1\n");
2726 if (!torture_open_connection(&cli1, 0)) {
2727 return False;
2730 cli_unlink(cli1, fname);
2732 cli_sockopt(cli1, sockops);
2734 cli1->use_oplocks = True;
2736 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2737 if (fnum1 == -1) {
2738 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2739 return False;
2742 cli1->use_oplocks = False;
2744 cli_unlink(cli1, fname);
2745 cli_unlink(cli1, fname);
2747 if (!cli_close(cli1, fnum1)) {
2748 printf("close2 failed (%s)\n", cli_errstr(cli1));
2749 return False;
2752 if (!cli_unlink(cli1, fname)) {
2753 printf("unlink failed (%s)\n", cli_errstr(cli1));
2754 return False;
2757 if (!torture_close_connection(cli1)) {
2758 correct = False;
2761 printf("finished oplock test 1\n");
2763 return correct;
2766 static bool run_oplock2(int dummy)
2768 struct cli_state *cli1, *cli2;
2769 const char *fname = "\\lockt2.lck";
2770 int fnum1, fnum2;
2771 int saved_use_oplocks = use_oplocks;
2772 char buf[4];
2773 bool correct = True;
2774 volatile bool *shared_correct;
2776 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2777 *shared_correct = True;
2779 use_level_II_oplocks = True;
2780 use_oplocks = True;
2782 printf("starting oplock test 2\n");
2784 if (!torture_open_connection(&cli1, 0)) {
2785 use_level_II_oplocks = False;
2786 use_oplocks = saved_use_oplocks;
2787 return False;
2790 cli1->use_oplocks = True;
2791 cli1->use_level_II_oplocks = True;
2793 if (!torture_open_connection(&cli2, 1)) {
2794 use_level_II_oplocks = False;
2795 use_oplocks = saved_use_oplocks;
2796 return False;
2799 cli2->use_oplocks = True;
2800 cli2->use_level_II_oplocks = True;
2802 cli_unlink(cli1, fname);
2804 cli_sockopt(cli1, sockops);
2805 cli_sockopt(cli2, sockops);
2807 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2808 if (fnum1 == -1) {
2809 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2810 return False;
2813 /* Don't need the globals any more. */
2814 use_level_II_oplocks = False;
2815 use_oplocks = saved_use_oplocks;
2817 if (fork() == 0) {
2818 /* Child code */
2819 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2820 if (fnum2 == -1) {
2821 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2822 *shared_correct = False;
2823 exit(0);
2826 sleep(2);
2828 if (!cli_close(cli2, fnum2)) {
2829 printf("close2 failed (%s)\n", cli_errstr(cli1));
2830 *shared_correct = False;
2833 exit(0);
2836 sleep(2);
2838 /* Ensure cli1 processes the break. Empty file should always return 0
2839 * bytes. */
2841 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2842 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2843 correct = False;
2846 /* Should now be at level II. */
2847 /* Test if sending a write locks causes a break to none. */
2849 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2850 printf("lock failed (%s)\n", cli_errstr(cli1));
2851 correct = False;
2854 cli_unlock(cli1, fnum1, 0, 4);
2856 sleep(2);
2858 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2859 printf("lock failed (%s)\n", cli_errstr(cli1));
2860 correct = False;
2863 cli_unlock(cli1, fnum1, 0, 4);
2865 sleep(2);
2867 cli_read(cli1, fnum1, buf, 0, 4);
2869 #if 0
2870 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2871 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2872 correct = False;
2874 #endif
2876 if (!cli_close(cli1, fnum1)) {
2877 printf("close1 failed (%s)\n", cli_errstr(cli1));
2878 correct = False;
2881 sleep(4);
2883 if (!cli_unlink(cli1, fname)) {
2884 printf("unlink failed (%s)\n", cli_errstr(cli1));
2885 correct = False;
2888 if (!torture_close_connection(cli1)) {
2889 correct = False;
2892 if (!*shared_correct) {
2893 correct = False;
2896 printf("finished oplock test 2\n");
2898 return correct;
2901 /* handler for oplock 3 tests */
2902 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2904 printf("got oplock break fnum=%d level=%d\n",
2905 fnum, level);
2906 return cli_oplock_ack(cli, fnum, level);
2909 static bool run_oplock3(int dummy)
2911 struct cli_state *cli;
2912 const char *fname = "\\oplockt3.dat";
2913 int fnum;
2914 char buf[4] = "abcd";
2915 bool correct = True;
2916 volatile bool *shared_correct;
2918 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2919 *shared_correct = True;
2921 printf("starting oplock test 3\n");
2923 if (fork() == 0) {
2924 /* Child code */
2925 use_oplocks = True;
2926 use_level_II_oplocks = True;
2927 if (!torture_open_connection(&cli, 0)) {
2928 *shared_correct = False;
2929 exit(0);
2931 sleep(2);
2932 /* try to trigger a oplock break in parent */
2933 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2934 cli_write(cli, fnum, 0, buf, 0, 4);
2935 exit(0);
2938 /* parent code */
2939 use_oplocks = True;
2940 use_level_II_oplocks = True;
2941 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2942 return False;
2944 cli_oplock_handler(cli, oplock3_handler);
2945 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2946 cli_write(cli, fnum, 0, buf, 0, 4);
2947 cli_close(cli, fnum);
2948 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2949 cli->timeout = 20000;
2950 cli_receive_smb(cli);
2951 printf("finished oplock test 3\n");
2953 return (correct && *shared_correct);
2955 /* What are we looking for here? What's sucess and what's FAILURE? */
2961 Test delete on close semantics.
2963 static bool run_deletetest(int dummy)
2965 struct cli_state *cli1 = NULL;
2966 struct cli_state *cli2 = NULL;
2967 const char *fname = "\\delete.file";
2968 int fnum1 = -1;
2969 int fnum2 = -1;
2970 bool correct = True;
2972 printf("starting delete test\n");
2974 if (!torture_open_connection(&cli1, 0)) {
2975 return False;
2978 cli_sockopt(cli1, sockops);
2980 /* Test 1 - this should delete the file on close. */
2982 cli_setatr(cli1, fname, 0, 0);
2983 cli_unlink(cli1, fname);
2985 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2986 0, FILE_OVERWRITE_IF,
2987 FILE_DELETE_ON_CLOSE, 0);
2989 if (fnum1 == -1) {
2990 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2991 correct = False;
2992 goto fail;
2995 #if 0 /* JRATEST */
2997 uint32 *accinfo = NULL;
2998 uint32 len;
2999 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3000 if (accinfo)
3001 printf("access mode = 0x%lx\n", *accinfo);
3002 SAFE_FREE(accinfo);
3004 #endif
3006 if (!cli_close(cli1, fnum1)) {
3007 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3008 correct = False;
3009 goto fail;
3012 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3013 if (fnum1 != -1) {
3014 printf("[1] open of %s succeeded (should fail)\n", fname);
3015 correct = False;
3016 goto fail;
3019 printf("first delete on close test succeeded.\n");
3021 /* Test 2 - this should delete the file on close. */
3023 cli_setatr(cli1, fname, 0, 0);
3024 cli_unlink(cli1, fname);
3026 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3027 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3028 FILE_OVERWRITE_IF, 0, 0);
3030 if (fnum1 == -1) {
3031 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3032 correct = False;
3033 goto fail;
3036 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3037 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3038 correct = False;
3039 goto fail;
3042 if (!cli_close(cli1, fnum1)) {
3043 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3044 correct = False;
3045 goto fail;
3048 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3049 if (fnum1 != -1) {
3050 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3051 if (!cli_close(cli1, fnum1)) {
3052 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3053 correct = False;
3054 goto fail;
3056 cli_unlink(cli1, fname);
3057 } else
3058 printf("second delete on close test succeeded.\n");
3060 /* Test 3 - ... */
3061 cli_setatr(cli1, fname, 0, 0);
3062 cli_unlink(cli1, fname);
3064 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3065 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3067 if (fnum1 == -1) {
3068 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3069 correct = False;
3070 goto fail;
3073 /* This should fail with a sharing violation - open for delete is only compatible
3074 with SHARE_DELETE. */
3076 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3077 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3079 if (fnum2 != -1) {
3080 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3081 correct = False;
3082 goto fail;
3085 /* This should succeed. */
3087 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3088 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3090 if (fnum2 == -1) {
3091 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3092 correct = False;
3093 goto fail;
3096 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3097 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3098 correct = False;
3099 goto fail;
3102 if (!cli_close(cli1, fnum1)) {
3103 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3104 correct = False;
3105 goto fail;
3108 if (!cli_close(cli1, fnum2)) {
3109 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3110 correct = False;
3111 goto fail;
3114 /* This should fail - file should no longer be there. */
3116 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3117 if (fnum1 != -1) {
3118 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3119 if (!cli_close(cli1, fnum1)) {
3120 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3122 cli_unlink(cli1, fname);
3123 correct = False;
3124 goto fail;
3125 } else
3126 printf("third delete on close test succeeded.\n");
3128 /* Test 4 ... */
3129 cli_setatr(cli1, fname, 0, 0);
3130 cli_unlink(cli1, fname);
3132 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3133 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3135 if (fnum1 == -1) {
3136 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3137 correct = False;
3138 goto fail;
3141 /* This should succeed. */
3142 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3143 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3144 if (fnum2 == -1) {
3145 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3146 correct = False;
3147 goto fail;
3150 if (!cli_close(cli1, fnum2)) {
3151 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3152 correct = False;
3153 goto fail;
3156 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3157 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3158 correct = False;
3159 goto fail;
3162 /* This should fail - no more opens once delete on close set. */
3163 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3164 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3165 FILE_OPEN, 0, 0);
3166 if (fnum2 != -1) {
3167 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3168 correct = False;
3169 goto fail;
3170 } else
3171 printf("fourth delete on close test succeeded.\n");
3173 if (!cli_close(cli1, fnum1)) {
3174 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3175 correct = False;
3176 goto fail;
3179 /* Test 5 ... */
3180 cli_setatr(cli1, fname, 0, 0);
3181 cli_unlink(cli1, fname);
3183 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3184 if (fnum1 == -1) {
3185 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3186 correct = False;
3187 goto fail;
3190 /* This should fail - only allowed on NT opens with DELETE access. */
3192 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3193 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3194 correct = False;
3195 goto fail;
3198 if (!cli_close(cli1, fnum1)) {
3199 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3200 correct = False;
3201 goto fail;
3204 printf("fifth delete on close test succeeded.\n");
3206 /* Test 6 ... */
3207 cli_setatr(cli1, fname, 0, 0);
3208 cli_unlink(cli1, fname);
3210 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3211 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3212 FILE_OVERWRITE_IF, 0, 0);
3214 if (fnum1 == -1) {
3215 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3216 correct = False;
3217 goto fail;
3220 /* This should fail - only allowed on NT opens with DELETE access. */
3222 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3223 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3224 correct = False;
3225 goto fail;
3228 if (!cli_close(cli1, fnum1)) {
3229 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3230 correct = False;
3231 goto fail;
3234 printf("sixth delete on close test succeeded.\n");
3236 /* Test 7 ... */
3237 cli_setatr(cli1, fname, 0, 0);
3238 cli_unlink(cli1, fname);
3240 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3241 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3243 if (fnum1 == -1) {
3244 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3245 correct = False;
3246 goto fail;
3249 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3250 printf("[7] setting delete_on_close on file failed !\n");
3251 correct = False;
3252 goto fail;
3255 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3256 printf("[7] unsetting delete_on_close on file failed !\n");
3257 correct = False;
3258 goto fail;
3261 if (!cli_close(cli1, fnum1)) {
3262 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3263 correct = False;
3264 goto fail;
3267 /* This next open should succeed - we reset the flag. */
3269 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3270 if (fnum1 == -1) {
3271 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3272 correct = False;
3273 goto fail;
3276 if (!cli_close(cli1, fnum1)) {
3277 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3278 correct = False;
3279 goto fail;
3282 printf("seventh delete on close test succeeded.\n");
3284 /* Test 7 ... */
3285 cli_setatr(cli1, fname, 0, 0);
3286 cli_unlink(cli1, fname);
3288 if (!torture_open_connection(&cli2, 1)) {
3289 printf("[8] failed to open second connection.\n");
3290 correct = False;
3291 goto fail;
3294 cli_sockopt(cli1, sockops);
3296 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3297 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3298 FILE_OVERWRITE_IF, 0, 0);
3300 if (fnum1 == -1) {
3301 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3302 correct = False;
3303 goto fail;
3306 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3307 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3308 FILE_OPEN, 0, 0);
3310 if (fnum2 == -1) {
3311 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3312 correct = False;
3313 goto fail;
3316 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3317 printf("[8] setting delete_on_close on file failed !\n");
3318 correct = False;
3319 goto fail;
3322 if (!cli_close(cli1, fnum1)) {
3323 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3324 correct = False;
3325 goto fail;
3328 if (!cli_close(cli2, fnum2)) {
3329 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3330 correct = False;
3331 goto fail;
3334 /* This should fail.. */
3335 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3336 if (fnum1 != -1) {
3337 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3338 goto fail;
3339 correct = False;
3340 } else
3341 printf("eighth delete on close test succeeded.\n");
3343 /* This should fail - we need to set DELETE_ACCESS. */
3344 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3345 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3347 if (fnum1 != -1) {
3348 printf("[9] open of %s succeeded should have failed!\n", fname);
3349 correct = False;
3350 goto fail;
3353 printf("ninth delete on close test succeeded.\n");
3355 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3356 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3357 if (fnum1 == -1) {
3358 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3359 correct = False;
3360 goto fail;
3363 /* This should delete the file. */
3364 if (!cli_close(cli1, fnum1)) {
3365 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3366 correct = False;
3367 goto fail;
3370 /* This should fail.. */
3371 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3372 if (fnum1 != -1) {
3373 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3374 goto fail;
3375 correct = False;
3376 } else
3377 printf("tenth delete on close test succeeded.\n");
3379 cli_setatr(cli1, fname, 0, 0);
3380 cli_unlink(cli1, fname);
3382 /* What error do we get when attempting to open a read-only file with
3383 delete access ? */
3385 /* Create a readonly file. */
3386 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3387 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3388 if (fnum1 == -1) {
3389 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3390 correct = False;
3391 goto fail;
3394 if (!cli_close(cli1, fnum1)) {
3395 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3396 correct = False;
3397 goto fail;
3400 /* Now try open for delete access. */
3401 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3402 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3403 FILE_OVERWRITE_IF, 0, 0);
3405 if (fnum1 != -1) {
3406 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3407 cli_close(cli1, fnum1);
3408 goto fail;
3409 correct = False;
3410 } else {
3411 NTSTATUS nterr = cli_nt_error(cli1);
3412 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3413 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3414 goto fail;
3415 correct = False;
3416 } else {
3417 printf("eleventh delete on close test succeeded.\n");
3421 printf("finished delete test\n");
3423 fail:
3424 /* FIXME: This will crash if we aborted before cli2 got
3425 * intialized, because these functions don't handle
3426 * uninitialized connections. */
3428 if (fnum1 != -1) cli_close(cli1, fnum1);
3429 if (fnum2 != -1) cli_close(cli1, fnum2);
3430 cli_setatr(cli1, fname, 0, 0);
3431 cli_unlink(cli1, fname);
3433 if (cli1 && !torture_close_connection(cli1)) {
3434 correct = False;
3436 if (cli2 && !torture_close_connection(cli2)) {
3437 correct = False;
3439 return correct;
3444 print out server properties
3446 static bool run_properties(int dummy)
3448 static struct cli_state *cli;
3449 bool correct = True;
3451 printf("starting properties test\n");
3453 ZERO_STRUCT(cli);
3455 if (!torture_open_connection(&cli, 0)) {
3456 return False;
3459 cli_sockopt(cli, sockops);
3461 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3463 if (!torture_close_connection(cli)) {
3464 correct = False;
3467 return correct;
3472 /* FIRST_DESIRED_ACCESS 0xf019f */
3473 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3474 FILE_READ_EA| /* 0xf */ \
3475 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3476 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3477 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3478 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3479 /* SECOND_DESIRED_ACCESS 0xe0080 */
3480 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3481 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3482 WRITE_OWNER_ACCESS /* 0xe0000 */
3484 #if 0
3485 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3486 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3487 FILE_READ_DATA|\
3488 WRITE_OWNER_ACCESS /* */
3489 #endif
3492 Test ntcreate calls made by xcopy
3494 static bool run_xcopy(int dummy)
3496 static struct cli_state *cli1;
3497 const char *fname = "\\test.txt";
3498 bool correct = True;
3499 int fnum1, fnum2;
3501 printf("starting xcopy test\n");
3503 if (!torture_open_connection(&cli1, 0)) {
3504 return False;
3507 fnum1 = cli_nt_create_full(cli1, fname, 0,
3508 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3509 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3510 0x4044, 0);
3512 if (fnum1 == -1) {
3513 printf("First open failed - %s\n", cli_errstr(cli1));
3514 return False;
3517 fnum2 = cli_nt_create_full(cli1, fname, 0,
3518 SECOND_DESIRED_ACCESS, 0,
3519 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3520 0x200000, 0);
3521 if (fnum2 == -1) {
3522 printf("second open failed - %s\n", cli_errstr(cli1));
3523 return False;
3526 if (!torture_close_connection(cli1)) {
3527 correct = False;
3530 return correct;
3534 Test rename on files open with share delete and no share delete.
3536 static bool run_rename(int dummy)
3538 static struct cli_state *cli1;
3539 const char *fname = "\\test.txt";
3540 const char *fname1 = "\\test1.txt";
3541 bool correct = True;
3542 int fnum1;
3544 printf("starting rename test\n");
3546 if (!torture_open_connection(&cli1, 0)) {
3547 return False;
3550 cli_unlink(cli1, fname);
3551 cli_unlink(cli1, fname1);
3552 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3553 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3555 if (fnum1 == -1) {
3556 printf("First open failed - %s\n", cli_errstr(cli1));
3557 return False;
3560 if (!cli_rename(cli1, fname, fname1)) {
3561 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3562 } else {
3563 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3564 correct = False;
3567 if (!cli_close(cli1, fnum1)) {
3568 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3569 return False;
3572 cli_unlink(cli1, fname);
3573 cli_unlink(cli1, fname1);
3574 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3575 #if 0
3576 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3577 #else
3578 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3579 #endif
3581 if (fnum1 == -1) {
3582 printf("Second open failed - %s\n", cli_errstr(cli1));
3583 return False;
3586 if (!cli_rename(cli1, fname, fname1)) {
3587 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3588 correct = False;
3589 } else {
3590 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3593 if (!cli_close(cli1, fnum1)) {
3594 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3595 return False;
3598 cli_unlink(cli1, fname);
3599 cli_unlink(cli1, fname1);
3601 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3602 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3604 if (fnum1 == -1) {
3605 printf("Third open failed - %s\n", cli_errstr(cli1));
3606 return False;
3610 #if 0
3612 int fnum2;
3614 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3615 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3617 if (fnum2 == -1) {
3618 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3619 return False;
3621 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3622 printf("[8] setting delete_on_close on file failed !\n");
3623 return False;
3626 if (!cli_close(cli1, fnum2)) {
3627 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3628 return False;
3631 #endif
3633 if (!cli_rename(cli1, fname, fname1)) {
3634 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3635 correct = False;
3636 } else {
3637 printf("Third rename succeeded (SHARE_NONE)\n");
3640 if (!cli_close(cli1, fnum1)) {
3641 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3642 return False;
3645 cli_unlink(cli1, fname);
3646 cli_unlink(cli1, fname1);
3648 /*----*/
3650 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3651 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3653 if (fnum1 == -1) {
3654 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3655 return False;
3658 if (!cli_rename(cli1, fname, fname1)) {
3659 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3660 } else {
3661 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3662 correct = False;
3665 if (!cli_close(cli1, fnum1)) {
3666 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3667 return False;
3670 cli_unlink(cli1, fname);
3671 cli_unlink(cli1, fname1);
3673 /*--*/
3675 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3676 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3678 if (fnum1 == -1) {
3679 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3680 return False;
3683 if (!cli_rename(cli1, fname, fname1)) {
3684 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3685 cli_errstr(cli1));
3686 correct = False;
3687 } else {
3688 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3692 * Now check if the first name still exists ...
3695 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3696 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3698 if (fnum2 == -1) {
3699 printf("Opening original file after rename of open file fails: %s\n",
3700 cli_errstr(cli1));
3702 else {
3703 printf("Opening original file after rename of open file works ...\n");
3704 (void)cli_close(cli1, fnum2);
3705 } */
3707 /*--*/
3710 if (!cli_close(cli1, fnum1)) {
3711 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3712 return False;
3715 cli_unlink(cli1, fname);
3716 cli_unlink(cli1, fname1);
3718 if (!torture_close_connection(cli1)) {
3719 correct = False;
3722 return correct;
3725 static bool run_pipe_number(int dummy)
3727 struct cli_state *cli1;
3728 const char *pipe_name = "\\SPOOLSS";
3729 int fnum;
3730 int num_pipes = 0;
3732 printf("starting pipenumber test\n");
3733 if (!torture_open_connection(&cli1, 0)) {
3734 return False;
3737 cli_sockopt(cli1, sockops);
3738 while(1) {
3739 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3740 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3742 if (fnum == -1) {
3743 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3744 break;
3746 num_pipes++;
3747 printf("\r%6d", num_pipes);
3750 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3751 torture_close_connection(cli1);
3752 return True;
3756 Test open mode returns on read-only files.
3758 static bool run_opentest(int dummy)
3760 static struct cli_state *cli1;
3761 static struct cli_state *cli2;
3762 const char *fname = "\\readonly.file";
3763 int fnum1, fnum2;
3764 char buf[20];
3765 SMB_OFF_T fsize;
3766 bool correct = True;
3767 char *tmp_path;
3769 printf("starting open test\n");
3771 if (!torture_open_connection(&cli1, 0)) {
3772 return False;
3775 cli_setatr(cli1, fname, 0, 0);
3776 cli_unlink(cli1, fname);
3778 cli_sockopt(cli1, sockops);
3780 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3781 if (fnum1 == -1) {
3782 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3783 return False;
3786 if (!cli_close(cli1, fnum1)) {
3787 printf("close2 failed (%s)\n", cli_errstr(cli1));
3788 return False;
3791 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3792 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3793 return False;
3796 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3797 if (fnum1 == -1) {
3798 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3799 return False;
3802 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3803 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3805 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3806 NT_STATUS_ACCESS_DENIED)) {
3807 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3810 printf("finished open test 1\n");
3812 cli_close(cli1, fnum1);
3814 /* Now try not readonly and ensure ERRbadshare is returned. */
3816 cli_setatr(cli1, fname, 0, 0);
3818 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3819 if (fnum1 == -1) {
3820 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3821 return False;
3824 /* This will fail - but the error should be ERRshare. */
3825 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3827 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3828 NT_STATUS_SHARING_VIOLATION)) {
3829 printf("correct error code ERRDOS/ERRbadshare returned\n");
3832 if (!cli_close(cli1, fnum1)) {
3833 printf("close2 failed (%s)\n", cli_errstr(cli1));
3834 return False;
3837 cli_unlink(cli1, fname);
3839 printf("finished open test 2\n");
3841 /* Test truncate open disposition on file opened for read. */
3843 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3844 if (fnum1 == -1) {
3845 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3846 return False;
3849 /* write 20 bytes. */
3851 memset(buf, '\0', 20);
3853 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3854 printf("write failed (%s)\n", cli_errstr(cli1));
3855 correct = False;
3858 if (!cli_close(cli1, fnum1)) {
3859 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3860 return False;
3863 /* Ensure size == 20. */
3864 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3865 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3866 return False;
3869 if (fsize != 20) {
3870 printf("(3) file size != 20\n");
3871 return False;
3874 /* Now test if we can truncate a file opened for readonly. */
3876 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3877 if (fnum1 == -1) {
3878 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3879 return False;
3882 if (!cli_close(cli1, fnum1)) {
3883 printf("close2 failed (%s)\n", cli_errstr(cli1));
3884 return False;
3887 /* Ensure size == 0. */
3888 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3889 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3890 return False;
3893 if (fsize != 0) {
3894 printf("(3) file size != 0\n");
3895 return False;
3897 printf("finished open test 3\n");
3899 cli_unlink(cli1, fname);
3902 printf("testing ctemp\n");
3903 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3904 if (fnum1 == -1) {
3905 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3906 return False;
3908 printf("ctemp gave path %s\n", tmp_path);
3909 if (!cli_close(cli1, fnum1)) {
3910 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3912 if (!cli_unlink(cli1, tmp_path)) {
3913 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3916 /* Test the non-io opens... */
3918 if (!torture_open_connection(&cli2, 1)) {
3919 return False;
3922 cli_setatr(cli2, fname, 0, 0);
3923 cli_unlink(cli2, fname);
3925 cli_sockopt(cli2, sockops);
3927 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3929 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3930 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3932 if (fnum1 == -1) {
3933 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3934 return False;
3937 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3938 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3940 if (fnum2 == -1) {
3941 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3942 return False;
3945 if (!cli_close(cli1, fnum1)) {
3946 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3947 return False;
3949 if (!cli_close(cli2, fnum2)) {
3950 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3951 return False;
3954 printf("non-io open test #1 passed.\n");
3956 cli_unlink(cli1, fname);
3958 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3960 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3961 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3963 if (fnum1 == -1) {
3964 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3965 return False;
3968 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3969 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3971 if (fnum2 == -1) {
3972 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3973 return False;
3976 if (!cli_close(cli1, fnum1)) {
3977 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3978 return False;
3980 if (!cli_close(cli2, fnum2)) {
3981 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3982 return False;
3985 printf("non-io open test #2 passed.\n");
3987 cli_unlink(cli1, fname);
3989 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3991 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3992 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3994 if (fnum1 == -1) {
3995 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3996 return False;
3999 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4000 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4002 if (fnum2 == -1) {
4003 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4004 return False;
4007 if (!cli_close(cli1, fnum1)) {
4008 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4009 return False;
4011 if (!cli_close(cli2, fnum2)) {
4012 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4013 return False;
4016 printf("non-io open test #3 passed.\n");
4018 cli_unlink(cli1, fname);
4020 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4022 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4023 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4025 if (fnum1 == -1) {
4026 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4027 return False;
4030 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4031 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4033 if (fnum2 != -1) {
4034 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4035 return False;
4038 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4040 if (!cli_close(cli1, fnum1)) {
4041 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4042 return False;
4045 printf("non-io open test #4 passed.\n");
4047 cli_unlink(cli1, fname);
4049 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4051 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4052 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4054 if (fnum1 == -1) {
4055 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4056 return False;
4059 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4060 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4062 if (fnum2 == -1) {
4063 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4064 return False;
4067 if (!cli_close(cli1, fnum1)) {
4068 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4069 return False;
4072 if (!cli_close(cli2, fnum2)) {
4073 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4074 return False;
4077 printf("non-io open test #5 passed.\n");
4079 printf("TEST #6 testing 1 non-io open, one io open\n");
4081 cli_unlink(cli1, fname);
4083 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4084 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4086 if (fnum1 == -1) {
4087 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4088 return False;
4091 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4092 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4094 if (fnum2 == -1) {
4095 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4096 return False;
4099 if (!cli_close(cli1, fnum1)) {
4100 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4101 return False;
4104 if (!cli_close(cli2, fnum2)) {
4105 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4106 return False;
4109 printf("non-io open test #6 passed.\n");
4111 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4113 cli_unlink(cli1, fname);
4115 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4116 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4118 if (fnum1 == -1) {
4119 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4120 return False;
4123 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4124 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4126 if (fnum2 != -1) {
4127 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4128 return False;
4131 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4133 if (!cli_close(cli1, fnum1)) {
4134 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4135 return False;
4138 printf("non-io open test #7 passed.\n");
4140 cli_unlink(cli1, fname);
4142 if (!torture_close_connection(cli1)) {
4143 correct = False;
4145 if (!torture_close_connection(cli2)) {
4146 correct = False;
4149 return correct;
4152 static uint32 open_attrs_table[] = {
4153 FILE_ATTRIBUTE_NORMAL,
4154 FILE_ATTRIBUTE_ARCHIVE,
4155 FILE_ATTRIBUTE_READONLY,
4156 FILE_ATTRIBUTE_HIDDEN,
4157 FILE_ATTRIBUTE_SYSTEM,
4159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4161 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4162 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4163 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4164 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4166 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4167 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4168 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4169 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4172 struct trunc_open_results {
4173 unsigned int num;
4174 uint32 init_attr;
4175 uint32 trunc_attr;
4176 uint32 result_attr;
4179 static struct trunc_open_results attr_results[] = {
4180 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4181 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4182 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4183 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4184 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4185 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4186 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4187 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4188 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4189 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4190 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4191 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4192 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4193 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4194 { 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 },
4195 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4196 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4197 { 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 },
4198 { 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 },
4199 { 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 },
4200 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4201 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4202 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4203 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4204 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4205 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4208 static bool run_openattrtest(int dummy)
4210 static struct cli_state *cli1;
4211 const char *fname = "\\openattr.file";
4212 int fnum1;
4213 bool correct = True;
4214 uint16 attr;
4215 unsigned int i, j, k, l;
4217 printf("starting open attr test\n");
4219 if (!torture_open_connection(&cli1, 0)) {
4220 return False;
4223 cli_sockopt(cli1, sockops);
4225 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4226 cli_setatr(cli1, fname, 0, 0);
4227 cli_unlink(cli1, fname);
4228 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4229 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4231 if (fnum1 == -1) {
4232 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4233 return False;
4236 if (!cli_close(cli1, fnum1)) {
4237 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4238 return False;
4241 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4242 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4243 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4245 if (fnum1 == -1) {
4246 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4247 if (attr_results[l].num == k) {
4248 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4249 k, open_attrs_table[i],
4250 open_attrs_table[j],
4251 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4252 correct = False;
4255 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4256 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4257 k, open_attrs_table[i], open_attrs_table[j],
4258 cli_errstr(cli1));
4259 correct = False;
4261 #if 0
4262 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4263 #endif
4264 k++;
4265 continue;
4268 if (!cli_close(cli1, fnum1)) {
4269 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4270 return False;
4273 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4274 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4275 return False;
4278 #if 0
4279 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4280 k, open_attrs_table[i], open_attrs_table[j], attr );
4281 #endif
4283 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4284 if (attr_results[l].num == k) {
4285 if (attr != attr_results[l].result_attr ||
4286 open_attrs_table[i] != attr_results[l].init_attr ||
4287 open_attrs_table[j] != attr_results[l].trunc_attr) {
4288 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4289 open_attrs_table[i],
4290 open_attrs_table[j],
4291 (unsigned int)attr,
4292 attr_results[l].result_attr);
4293 correct = False;
4295 break;
4298 k++;
4302 cli_setatr(cli1, fname, 0, 0);
4303 cli_unlink(cli1, fname);
4305 printf("open attr test %s.\n", correct ? "passed" : "failed");
4307 if (!torture_close_connection(cli1)) {
4308 correct = False;
4310 return correct;
4313 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4319 test directory listing speed
4321 static bool run_dirtest(int dummy)
4323 int i;
4324 static struct cli_state *cli;
4325 int fnum;
4326 double t1;
4327 bool correct = True;
4329 printf("starting directory test\n");
4331 if (!torture_open_connection(&cli, 0)) {
4332 return False;
4335 cli_sockopt(cli, sockops);
4337 srandom(0);
4338 for (i=0;i<torture_numops;i++) {
4339 fstring fname;
4340 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4341 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4342 if (fnum == -1) {
4343 fprintf(stderr,"Failed to open %s\n", fname);
4344 return False;
4346 cli_close(cli, fnum);
4349 t1 = end_timer();
4351 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4352 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4353 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4355 printf("dirtest core %g seconds\n", end_timer() - t1);
4357 srandom(0);
4358 for (i=0;i<torture_numops;i++) {
4359 fstring fname;
4360 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4361 cli_unlink(cli, fname);
4364 if (!torture_close_connection(cli)) {
4365 correct = False;
4368 printf("finished dirtest\n");
4370 return correct;
4373 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4375 struct cli_state *pcli = (struct cli_state *)state;
4376 fstring fname;
4377 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4379 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4380 return;
4382 if (finfo->mode & aDIR) {
4383 if (!cli_rmdir(pcli, fname))
4384 printf("del_fn: failed to rmdir %s\n,", fname );
4385 } else {
4386 if (!cli_unlink(pcli, fname))
4387 printf("del_fn: failed to unlink %s\n,", fname );
4393 sees what IOCTLs are supported
4395 bool torture_ioctl_test(int dummy)
4397 static struct cli_state *cli;
4398 uint16 device, function;
4399 int fnum;
4400 const char *fname = "\\ioctl.dat";
4401 DATA_BLOB blob;
4402 NTSTATUS status;
4404 if (!torture_open_connection(&cli, 0)) {
4405 return False;
4408 printf("starting ioctl test\n");
4410 cli_unlink(cli, fname);
4412 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4413 if (fnum == -1) {
4414 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4415 return False;
4418 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4419 printf("ioctl device info: %s\n", cli_errstr(cli));
4421 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4422 printf("ioctl job info: %s\n", cli_errstr(cli));
4424 for (device=0;device<0x100;device++) {
4425 printf("testing device=0x%x\n", device);
4426 for (function=0;function<0x100;function++) {
4427 uint32 code = (device<<16) | function;
4429 status = cli_raw_ioctl(cli, fnum, code, &blob);
4431 if (NT_STATUS_IS_OK(status)) {
4432 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4433 (int)blob.length);
4434 data_blob_free(&blob);
4439 if (!torture_close_connection(cli)) {
4440 return False;
4443 return True;
4448 tries varients of chkpath
4450 bool torture_chkpath_test(int dummy)
4452 static struct cli_state *cli;
4453 int fnum;
4454 bool ret;
4456 if (!torture_open_connection(&cli, 0)) {
4457 return False;
4460 printf("starting chkpath test\n");
4462 /* cleanup from an old run */
4463 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4464 cli_unlink(cli, "\\chkpath.dir\\*");
4465 cli_rmdir(cli, "\\chkpath.dir");
4467 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4468 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4469 return False;
4472 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4473 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4474 return False;
4477 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4478 if (fnum == -1) {
4479 printf("open1 failed (%s)\n", cli_errstr(cli));
4480 return False;
4482 cli_close(cli, fnum);
4484 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4485 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4486 ret = False;
4489 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4490 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4491 ret = False;
4494 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4495 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4496 NT_STATUS_NOT_A_DIRECTORY);
4497 } else {
4498 printf("* chkpath on a file should fail\n");
4499 ret = False;
4502 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4503 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4504 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4505 } else {
4506 printf("* chkpath on a non existant file should fail\n");
4507 ret = False;
4510 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4511 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4512 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4513 } else {
4514 printf("* chkpath on a non existent component should fail\n");
4515 ret = False;
4518 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4519 cli_unlink(cli, "\\chkpath.dir\\*");
4520 cli_rmdir(cli, "\\chkpath.dir");
4522 if (!torture_close_connection(cli)) {
4523 return False;
4526 return ret;
4529 static bool run_eatest(int dummy)
4531 static struct cli_state *cli;
4532 const char *fname = "\\eatest.txt";
4533 bool correct = True;
4534 int fnum, i;
4535 size_t num_eas;
4536 struct ea_struct *ea_list = NULL;
4537 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4539 printf("starting eatest\n");
4541 if (!torture_open_connection(&cli, 0)) {
4542 talloc_destroy(mem_ctx);
4543 return False;
4546 cli_unlink(cli, fname);
4547 fnum = cli_nt_create_full(cli, fname, 0,
4548 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4549 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4550 0x4044, 0);
4552 if (fnum == -1) {
4553 printf("open failed - %s\n", cli_errstr(cli));
4554 talloc_destroy(mem_ctx);
4555 return False;
4558 for (i = 0; i < 10; i++) {
4559 fstring ea_name, ea_val;
4561 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4562 memset(ea_val, (char)i+1, i+1);
4563 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4564 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4565 talloc_destroy(mem_ctx);
4566 return False;
4570 cli_close(cli, fnum);
4571 for (i = 0; i < 10; i++) {
4572 fstring ea_name, ea_val;
4574 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4575 memset(ea_val, (char)i+1, i+1);
4576 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4577 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4578 talloc_destroy(mem_ctx);
4579 return False;
4583 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4584 printf("ea_get list failed - %s\n", cli_errstr(cli));
4585 correct = False;
4588 printf("num_eas = %d\n", (int)num_eas);
4590 if (num_eas != 20) {
4591 printf("Should be 20 EA's stored... failing.\n");
4592 correct = False;
4595 for (i = 0; i < num_eas; i++) {
4596 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4597 dump_data(0, ea_list[i].value.data,
4598 ea_list[i].value.length);
4601 /* Setting EA's to zero length deletes them. Test this */
4602 printf("Now deleting all EA's - case indepenent....\n");
4604 #if 1
4605 cli_set_ea_path(cli, fname, "", "", 0);
4606 #else
4607 for (i = 0; i < 20; i++) {
4608 fstring ea_name;
4609 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4610 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4611 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4612 talloc_destroy(mem_ctx);
4613 return False;
4616 #endif
4618 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4619 printf("ea_get list failed - %s\n", cli_errstr(cli));
4620 correct = False;
4623 printf("num_eas = %d\n", (int)num_eas);
4624 for (i = 0; i < num_eas; i++) {
4625 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4626 dump_data(0, ea_list[i].value.data,
4627 ea_list[i].value.length);
4630 if (num_eas != 0) {
4631 printf("deleting EA's failed.\n");
4632 correct = False;
4635 /* Try and delete a non existant EA. */
4636 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4637 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4638 correct = False;
4641 talloc_destroy(mem_ctx);
4642 if (!torture_close_connection(cli)) {
4643 correct = False;
4646 return correct;
4649 static bool run_dirtest1(int dummy)
4651 int i;
4652 static struct cli_state *cli;
4653 int fnum, num_seen;
4654 bool correct = True;
4656 printf("starting directory test\n");
4658 if (!torture_open_connection(&cli, 0)) {
4659 return False;
4662 cli_sockopt(cli, sockops);
4664 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4665 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4666 cli_rmdir(cli, "\\LISTDIR");
4667 cli_mkdir(cli, "\\LISTDIR");
4669 /* Create 1000 files and 1000 directories. */
4670 for (i=0;i<1000;i++) {
4671 fstring fname;
4672 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4673 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4674 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4675 if (fnum == -1) {
4676 fprintf(stderr,"Failed to open %s\n", fname);
4677 return False;
4679 cli_close(cli, fnum);
4681 for (i=0;i<1000;i++) {
4682 fstring fname;
4683 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4684 if (!cli_mkdir(cli, fname)) {
4685 fprintf(stderr,"Failed to open %s\n", fname);
4686 return False;
4690 /* Now ensure that doing an old list sees both files and directories. */
4691 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4692 printf("num_seen = %d\n", num_seen );
4693 /* We should see 100 files + 1000 directories + . and .. */
4694 if (num_seen != 2002)
4695 correct = False;
4697 /* Ensure if we have the "must have" bits we only see the
4698 * relevent entries.
4700 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4701 printf("num_seen = %d\n", num_seen );
4702 if (num_seen != 1002)
4703 correct = False;
4705 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4706 printf("num_seen = %d\n", num_seen );
4707 if (num_seen != 1000)
4708 correct = False;
4710 /* Delete everything. */
4711 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4712 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4713 cli_rmdir(cli, "\\LISTDIR");
4715 #if 0
4716 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4717 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4718 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4719 #endif
4721 if (!torture_close_connection(cli)) {
4722 correct = False;
4725 printf("finished dirtest1\n");
4727 return correct;
4730 static bool run_error_map_extract(int dummy) {
4732 static struct cli_state *c_dos;
4733 static struct cli_state *c_nt;
4734 NTSTATUS status;
4736 uint32 error;
4738 uint32 flgs2, errnum;
4739 uint8 errclass;
4741 NTSTATUS nt_status;
4743 fstring user;
4745 /* NT-Error connection */
4747 if (!(c_nt = open_nbt_connection())) {
4748 return False;
4751 c_nt->use_spnego = False;
4753 status = cli_negprot(c_nt);
4755 if (!NT_STATUS_IS_OK(status)) {
4756 printf("%s rejected the NT-error negprot (%s)\n", host,
4757 nt_errstr(status));
4758 cli_shutdown(c_nt);
4759 return False;
4762 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4763 workgroup))) {
4764 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4765 return False;
4768 /* DOS-Error connection */
4770 if (!(c_dos = open_nbt_connection())) {
4771 return False;
4774 c_dos->use_spnego = False;
4775 c_dos->force_dos_errors = True;
4777 status = cli_negprot(c_dos);
4778 if (!NT_STATUS_IS_OK(status)) {
4779 printf("%s rejected the DOS-error negprot (%s)\n", host,
4780 nt_errstr(status));
4781 cli_shutdown(c_dos);
4782 return False;
4785 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4786 workgroup))) {
4787 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4788 return False;
4791 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4792 fstr_sprintf(user, "%X", error);
4794 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4795 password, strlen(password),
4796 password, strlen(password),
4797 workgroup))) {
4798 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4801 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4803 /* Case #1: 32-bit NT errors */
4804 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4805 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4806 } else {
4807 printf("/** Dos error on NT connection! (%s) */\n",
4808 cli_errstr(c_nt));
4809 nt_status = NT_STATUS(0xc0000000);
4812 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4813 password, strlen(password),
4814 password, strlen(password),
4815 workgroup))) {
4816 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4818 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4820 /* Case #1: 32-bit NT errors */
4821 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4822 printf("/** NT error on DOS connection! (%s) */\n",
4823 cli_errstr(c_nt));
4824 errnum = errclass = 0;
4825 } else {
4826 cli_dos_error(c_dos, &errclass, &errnum);
4829 if (NT_STATUS_V(nt_status) != error) {
4830 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4831 get_nt_error_c_code(NT_STATUS(error)),
4832 get_nt_error_c_code(nt_status));
4835 printf("\t{%s,\t%s,\t%s},\n",
4836 smb_dos_err_class(errclass),
4837 smb_dos_err_name(errclass, errnum),
4838 get_nt_error_c_code(NT_STATUS(error)));
4840 return True;
4843 static bool run_sesssetup_bench(int dummy)
4845 static struct cli_state *c;
4846 const char *fname = "\\file.dat";
4847 int fnum;
4848 NTSTATUS status;
4849 int i;
4851 if (!torture_open_connection(&c, 0)) {
4852 return false;
4855 fnum = cli_nt_create_full(
4856 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4857 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4858 FILE_DELETE_ON_CLOSE, 0);
4859 if (fnum == -1) {
4860 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4861 return false;
4864 for (i=0; i<torture_numops; i++) {
4865 status = cli_session_setup(
4866 c, username,
4867 password, strlen(password),
4868 password, strlen(password),
4869 workgroup);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 d_printf("(%s) cli_session_setup failed: %s\n",
4872 __location__, nt_errstr(status));
4873 return false;
4876 d_printf("\r%d ", (int)c->vuid);
4878 if (!cli_ulogoff(c)) {
4879 d_printf("(%s) cli_ulogoff failed: %s\n",
4880 __location__, cli_errstr(c));
4881 return false;
4883 c->vuid = 0;
4886 return true;
4889 static bool subst_test(const char *str, const char *user, const char *domain,
4890 uid_t uid, gid_t gid, const char *expected)
4892 char *subst;
4893 bool result = true;
4895 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
4897 if (strcmp(subst, expected) != 0) {
4898 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
4899 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
4900 expected);
4901 result = false;
4904 TALLOC_FREE(subst);
4905 return result;
4908 static void chain1_open_completion(struct async_req *req)
4910 int fnum;
4911 NTSTATUS status;
4913 status = cli_open_recv(req, &fnum);
4914 TALLOC_FREE(req);
4916 d_printf("cli_open_recv returned %s: %d\n",
4917 nt_errstr(status),
4918 NT_STATUS_IS_OK(status) ? fnum : -1);
4921 static void chain1_read_completion(struct async_req *req)
4923 NTSTATUS status;
4924 ssize_t received;
4925 uint8_t *rcvbuf;
4927 status = cli_read_andx_recv(req, &received, &rcvbuf);
4928 if (!NT_STATUS_IS_OK(status)) {
4929 TALLOC_FREE(req);
4930 d_printf("cli_read_andx_recv returned %s\n",
4931 nt_errstr(status));
4932 return;
4935 d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
4936 (char *)rcvbuf);
4937 TALLOC_FREE(req);
4940 static void chain1_write_completion(struct async_req *req)
4942 NTSTATUS status;
4943 size_t written;
4945 status = cli_write_andx_recv(req, &written);
4946 if (!NT_STATUS_IS_OK(status)) {
4947 TALLOC_FREE(req);
4948 d_printf("cli_write_andx_recv returned %s\n",
4949 nt_errstr(status));
4950 return;
4953 d_printf("wrote %d bytes\n", (int)written);
4954 TALLOC_FREE(req);
4957 static void chain1_close_completion(struct async_req *req)
4959 NTSTATUS status;
4961 status = cli_close_recv(req);
4962 *((bool *)(req->async.priv)) = true;
4964 TALLOC_FREE(req);
4966 d_printf("cli_close returned %s\n", nt_errstr(status));
4969 static bool run_chain1(int dummy)
4971 struct cli_state *cli1;
4972 struct event_context *evt = event_context_init(NULL);
4973 struct async_req *reqs[4];
4974 bool done = false;
4975 const char *text = "hallo";
4977 printf("starting chain1 test\n");
4978 if (!torture_open_connection(&cli1, 0)) {
4979 return False;
4982 cli_sockopt(cli1, sockops);
4984 cli_chain_cork(cli1, evt, 0);
4985 reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
4986 O_CREAT|O_RDWR, 0);
4987 reqs[0]->async.fn = chain1_open_completion;
4988 reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
4989 (uint8_t *)text, 0, strlen(text));
4990 reqs[1]->async.fn = chain1_write_completion;
4991 reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
4992 reqs[2]->async.fn = chain1_read_completion;
4993 reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
4994 reqs[3]->async.fn = chain1_close_completion;
4995 reqs[3]->async.priv = (void *)&done;
4996 cli_chain_uncork(cli1);
4998 while (!done) {
4999 event_loop_once(evt);
5002 torture_close_connection(cli1);
5003 return True;
5006 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5008 size_t *to_pull = (size_t *)priv;
5009 size_t thistime = *to_pull;
5011 thistime = MIN(thistime, n);
5012 if (thistime == 0) {
5013 return 0;
5016 memset(buf, 0, thistime);
5017 *to_pull -= thistime;
5018 return thistime;
5021 static bool run_windows_write(int dummy)
5023 struct cli_state *cli1;
5024 int fnum;
5025 int i;
5026 bool ret = false;
5027 const char *fname = "\\writetest.txt";
5028 double seconds;
5029 double kbytes;
5031 printf("starting windows_write test\n");
5032 if (!torture_open_connection(&cli1, 0)) {
5033 return False;
5036 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5037 if (fnum == -1) {
5038 printf("open failed (%s)\n", cli_errstr(cli1));
5039 return False;
5042 cli_sockopt(cli1, sockops);
5044 start_timer();
5046 for (i=0; i<torture_numops; i++) {
5047 char c = 0;
5048 off_t start = i * torture_blocksize;
5049 NTSTATUS status;
5050 size_t to_pull = torture_blocksize - 1;
5052 if (cli_write(cli1, fnum, 0, &c,
5053 start + torture_blocksize - 1, 1) != 1) {
5054 printf("cli_write failed: %s\n", cli_errstr(cli1));
5055 goto fail;
5058 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5059 null_source, &to_pull);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 printf("cli_push returned: %s\n", nt_errstr(status));
5062 goto fail;
5066 seconds = end_timer();
5067 kbytes = (double)torture_blocksize * torture_numops;
5068 kbytes /= 1024;
5070 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5071 (double)seconds, (int)(kbytes/seconds));
5073 ret = true;
5074 fail:
5075 cli_close(cli1, fnum);
5076 cli_unlink(cli1, fname);
5077 torture_close_connection(cli1);
5078 return ret;
5081 static bool run_cli_echo(int dummy)
5083 struct cli_state *cli;
5084 struct event_context *ev = event_context_init(NULL);
5085 struct async_req *req;
5086 NTSTATUS status;
5088 printf("starting chain1 test\n");
5089 if (!torture_open_connection(&cli, 0)) {
5090 return false;
5092 cli_sockopt(cli, sockops);
5094 req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5095 if (req == NULL) {
5096 d_printf("cli_echo_send failed\n");
5097 return false;
5100 while (req->state < ASYNC_REQ_DONE) {
5101 event_loop_once(ev);
5104 status = cli_echo_recv(req);
5105 d_printf("cli_echo returned %s\n", nt_errstr(status));
5107 TALLOC_FREE(req);
5109 torture_close_connection(cli);
5110 return NT_STATUS_IS_OK(status);
5113 static bool run_local_substitute(int dummy)
5115 bool ok = true;
5117 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5118 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5119 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5120 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5121 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5122 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5123 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5124 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5126 /* Different captialization rules in sub_basic... */
5128 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5129 "blaDOM") == 0);
5131 return ok;
5134 static bool run_local_gencache(int dummy)
5136 char *val;
5137 time_t tm;
5138 DATA_BLOB blob;
5140 if (!gencache_init()) {
5141 d_printf("%s: gencache_init() failed\n", __location__);
5142 return False;
5145 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5146 d_printf("%s: gencache_set() failed\n", __location__);
5147 return False;
5150 if (!gencache_get("foo", &val, &tm)) {
5151 d_printf("%s: gencache_get() failed\n", __location__);
5152 return False;
5155 if (strcmp(val, "bar") != 0) {
5156 d_printf("%s: gencache_get() returned %s, expected %s\n",
5157 __location__, val, "bar");
5158 SAFE_FREE(val);
5159 return False;
5162 SAFE_FREE(val);
5164 if (!gencache_del("foo")) {
5165 d_printf("%s: gencache_del() failed\n", __location__);
5166 return False;
5168 if (gencache_del("foo")) {
5169 d_printf("%s: second gencache_del() succeeded\n",
5170 __location__);
5171 return False;
5174 if (gencache_get("foo", &val, &tm)) {
5175 d_printf("%s: gencache_get() on deleted entry "
5176 "succeeded\n", __location__);
5177 return False;
5180 blob = data_blob_string_const_null("bar");
5181 tm = time(NULL);
5183 if (!gencache_set_data_blob("foo", &blob, tm)) {
5184 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5185 return False;
5188 data_blob_free(&blob);
5190 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5191 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5192 return False;
5195 if (strcmp((const char *)blob.data, "bar") != 0) {
5196 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5197 __location__, (const char *)blob.data, "bar");
5198 data_blob_free(&blob);
5199 return False;
5202 data_blob_free(&blob);
5204 if (!gencache_del("foo")) {
5205 d_printf("%s: gencache_del() failed\n", __location__);
5206 return False;
5208 if (gencache_del("foo")) {
5209 d_printf("%s: second gencache_del() succeeded\n",
5210 __location__);
5211 return False;
5214 if (gencache_get_data_blob("foo", &blob, NULL)) {
5215 d_printf("%s: gencache_get_data_blob() on deleted entry "
5216 "succeeded\n", __location__);
5217 return False;
5220 if (!gencache_shutdown()) {
5221 d_printf("%s: gencache_shutdown() failed\n", __location__);
5222 return False;
5225 if (gencache_shutdown()) {
5226 d_printf("%s: second gencache_shutdown() succeeded\n",
5227 __location__);
5228 return False;
5231 return True;
5234 static bool rbt_testval(struct db_context *db, const char *key,
5235 const char *value)
5237 struct db_record *rec;
5238 TDB_DATA data = string_tdb_data(value);
5239 bool ret = false;
5240 NTSTATUS status;
5242 rec = db->fetch_locked(db, db, string_tdb_data(key));
5243 if (rec == NULL) {
5244 d_fprintf(stderr, "fetch_locked failed\n");
5245 goto done;
5247 status = rec->store(rec, data, 0);
5248 if (!NT_STATUS_IS_OK(status)) {
5249 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5250 goto done;
5252 TALLOC_FREE(rec);
5254 rec = db->fetch_locked(db, db, string_tdb_data(key));
5255 if (rec == NULL) {
5256 d_fprintf(stderr, "second fetch_locked failed\n");
5257 goto done;
5259 if ((rec->value.dsize != data.dsize)
5260 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5261 d_fprintf(stderr, "Got wrong data back\n");
5262 goto done;
5265 ret = true;
5266 done:
5267 TALLOC_FREE(rec);
5268 return ret;
5271 static bool run_local_rbtree(int dummy)
5273 struct db_context *db;
5274 bool ret = false;
5275 int i;
5277 db = db_open_rbt(NULL);
5279 if (db == NULL) {
5280 d_fprintf(stderr, "db_open_rbt failed\n");
5281 return false;
5284 for (i=0; i<1000; i++) {
5285 char *key, *value;
5287 if (asprintf(&key, "key%ld", random()) == -1) {
5288 goto done;
5290 if (asprintf(&value, "value%ld", random()) == -1) {
5291 SAFE_FREE(key);
5292 goto done;
5295 if (!rbt_testval(db, key, value)) {
5296 SAFE_FREE(key);
5297 SAFE_FREE(value);
5298 goto done;
5301 SAFE_FREE(value);
5302 if (asprintf(&value, "value%ld", random()) == -1) {
5303 SAFE_FREE(key);
5304 goto done;
5307 if (!rbt_testval(db, key, value)) {
5308 SAFE_FREE(key);
5309 SAFE_FREE(value);
5310 goto done;
5313 SAFE_FREE(key);
5314 SAFE_FREE(value);
5317 ret = true;
5319 done:
5320 TALLOC_FREE(db);
5321 return ret;
5324 static bool test_stream_name(const char *fname, const char *expected_base,
5325 const char *expected_stream,
5326 NTSTATUS expected_status)
5328 NTSTATUS status;
5329 char *base = NULL;
5330 char *stream = NULL;
5332 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5333 if (!NT_STATUS_EQUAL(status, expected_status)) {
5334 goto error;
5337 if (!NT_STATUS_IS_OK(status)) {
5338 return true;
5341 if (base == NULL) goto error;
5343 if (strcmp(expected_base, base) != 0) goto error;
5345 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5346 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5348 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5349 goto error;
5351 TALLOC_FREE(base);
5352 TALLOC_FREE(stream);
5353 return true;
5355 error:
5356 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5357 fname, expected_base ? expected_base : "<NULL>",
5358 expected_stream ? expected_stream : "<NULL>",
5359 nt_errstr(expected_status));
5360 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5361 base ? base : "<NULL>", stream ? stream : "<NULL>",
5362 nt_errstr(status));
5363 TALLOC_FREE(base);
5364 TALLOC_FREE(stream);
5365 return false;
5368 static bool run_local_stream_name(int dummy)
5370 bool ret = true;
5372 ret &= test_stream_name(
5373 "bla", "bla", NULL, NT_STATUS_OK);
5374 ret &= test_stream_name(
5375 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5376 ret &= test_stream_name(
5377 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5378 ret &= test_stream_name(
5379 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5380 ret &= test_stream_name(
5381 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5382 ret &= test_stream_name(
5383 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5384 ret &= test_stream_name(
5385 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5386 ret &= test_stream_name(
5387 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5389 return ret;
5392 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5394 if (a.length != b.length) {
5395 printf("a.length=%d != b.length=%d\n",
5396 (int)a.length, (int)b.length);
5397 return false;
5399 if (memcmp(a.data, b.data, a.length) != 0) {
5400 printf("a.data and b.data differ\n");
5401 return false;
5403 return true;
5406 static bool run_local_memcache(int dummy)
5408 struct memcache *cache;
5409 DATA_BLOB k1, k2;
5410 DATA_BLOB d1, d2, d3;
5411 DATA_BLOB v1, v2, v3;
5413 TALLOC_CTX *mem_ctx;
5414 char *str1, *str2;
5415 size_t size1, size2;
5416 bool ret = false;
5418 cache = memcache_init(NULL, 100);
5420 if (cache == NULL) {
5421 printf("memcache_init failed\n");
5422 return false;
5425 d1 = data_blob_const("d1", 2);
5426 d2 = data_blob_const("d2", 2);
5427 d3 = data_blob_const("d3", 2);
5429 k1 = data_blob_const("d1", 2);
5430 k2 = data_blob_const("d2", 2);
5432 memcache_add(cache, STAT_CACHE, k1, d1);
5433 memcache_add(cache, GETWD_CACHE, k2, d2);
5435 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5436 printf("could not find k1\n");
5437 return false;
5439 if (!data_blob_equal(d1, v1)) {
5440 return false;
5443 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5444 printf("could not find k2\n");
5445 return false;
5447 if (!data_blob_equal(d2, v2)) {
5448 return false;
5451 memcache_add(cache, STAT_CACHE, k1, d3);
5453 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5454 printf("could not find replaced k1\n");
5455 return false;
5457 if (!data_blob_equal(d3, v3)) {
5458 return false;
5461 memcache_add(cache, GETWD_CACHE, k1, d1);
5463 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5464 printf("Did find k2, should have been purged\n");
5465 return false;
5468 TALLOC_FREE(cache);
5470 cache = memcache_init(NULL, 0);
5472 mem_ctx = talloc_init("foo");
5474 str1 = talloc_strdup(mem_ctx, "string1");
5475 str2 = talloc_strdup(mem_ctx, "string2");
5477 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5478 data_blob_string_const("torture"), &str1);
5479 size1 = talloc_total_size(cache);
5481 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5482 data_blob_string_const("torture"), &str2);
5483 size2 = talloc_total_size(cache);
5485 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5487 if (size2 > size1) {
5488 printf("memcache leaks memory!\n");
5489 goto fail;
5492 ret = true;
5493 fail:
5494 TALLOC_FREE(cache);
5495 return ret;
5498 static void wbclient_done(struct async_req *req)
5500 NTSTATUS status;
5501 struct winbindd_response *wb_resp;
5502 int *i = (int *)req->async.priv;
5504 status = wb_trans_recv(req, req, &wb_resp);
5505 TALLOC_FREE(req);
5506 *i += 1;
5507 d_printf("wb_trans_recv %d returned %s\n", *i, nt_errstr(status));
5510 static bool run_local_wbclient(int dummy)
5512 struct event_context *ev;
5513 struct wb_context **wb_ctx;
5514 struct winbindd_request wb_req;
5515 bool result = false;
5516 int i, j;
5518 BlockSignals(True, SIGPIPE);
5520 ev = event_context_init(talloc_tos());
5521 if (ev == NULL) {
5522 goto fail;
5525 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5526 if (wb_ctx == NULL) {
5527 goto fail;
5530 ZERO_STRUCT(wb_req);
5531 wb_req.cmd = WINBINDD_PING;
5533 for (i=0; i<torture_numops; i++) {
5534 wb_ctx[i] = wb_context_init(ev);
5535 if (wb_ctx[i] == NULL) {
5536 goto fail;
5538 for (j=0; j<5; j++) {
5539 struct async_req *req;
5540 req = wb_trans_send(ev, ev, wb_ctx[i],
5541 (j % 2) == 0, &wb_req);
5542 if (req == NULL) {
5543 goto fail;
5545 req->async.fn = wbclient_done;
5546 req->async.priv = &i;
5550 i = 0;
5552 while (i < 5 * torture_numops) {
5553 event_loop_once(ev);
5556 result = true;
5557 fail:
5558 TALLOC_FREE(ev);
5559 return result;
5562 static double create_procs(bool (*fn)(int), bool *result)
5564 int i, status;
5565 volatile pid_t *child_status;
5566 volatile bool *child_status_out;
5567 int synccount;
5568 int tries = 8;
5570 synccount = 0;
5572 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5573 if (!child_status) {
5574 printf("Failed to setup shared memory\n");
5575 return -1;
5578 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5579 if (!child_status_out) {
5580 printf("Failed to setup result status shared memory\n");
5581 return -1;
5584 for (i = 0; i < nprocs; i++) {
5585 child_status[i] = 0;
5586 child_status_out[i] = True;
5589 start_timer();
5591 for (i=0;i<nprocs;i++) {
5592 procnum = i;
5593 if (fork() == 0) {
5594 pid_t mypid = getpid();
5595 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5597 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5599 while (1) {
5600 if (torture_open_connection(&current_cli, i)) break;
5601 if (tries-- == 0) {
5602 printf("pid %d failed to start\n", (int)getpid());
5603 _exit(1);
5605 smb_msleep(10);
5608 child_status[i] = getpid();
5610 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5612 child_status_out[i] = fn(i);
5613 _exit(0);
5617 do {
5618 synccount = 0;
5619 for (i=0;i<nprocs;i++) {
5620 if (child_status[i]) synccount++;
5622 if (synccount == nprocs) break;
5623 smb_msleep(10);
5624 } while (end_timer() < 30);
5626 if (synccount != nprocs) {
5627 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5628 *result = False;
5629 return end_timer();
5632 /* start the client load */
5633 start_timer();
5635 for (i=0;i<nprocs;i++) {
5636 child_status[i] = 0;
5639 printf("%d clients started\n", nprocs);
5641 for (i=0;i<nprocs;i++) {
5642 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5645 printf("\n");
5647 for (i=0;i<nprocs;i++) {
5648 if (!child_status_out[i]) {
5649 *result = False;
5652 return end_timer();
5655 #define FLAG_MULTIPROC 1
5657 static struct {
5658 const char *name;
5659 bool (*fn)(int);
5660 unsigned flags;
5661 } torture_ops[] = {
5662 {"FDPASS", run_fdpasstest, 0},
5663 {"LOCK1", run_locktest1, 0},
5664 {"LOCK2", run_locktest2, 0},
5665 {"LOCK3", run_locktest3, 0},
5666 {"LOCK4", run_locktest4, 0},
5667 {"LOCK5", run_locktest5, 0},
5668 {"LOCK6", run_locktest6, 0},
5669 {"LOCK7", run_locktest7, 0},
5670 {"UNLINK", run_unlinktest, 0},
5671 {"BROWSE", run_browsetest, 0},
5672 {"ATTR", run_attrtest, 0},
5673 {"TRANS2", run_trans2test, 0},
5674 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5675 {"TORTURE",run_torture, FLAG_MULTIPROC},
5676 {"RANDOMIPC", run_randomipc, 0},
5677 {"NEGNOWAIT", run_negprot_nowait, 0},
5678 {"NBENCH", run_nbench, 0},
5679 {"OPLOCK1", run_oplock1, 0},
5680 {"OPLOCK2", run_oplock2, 0},
5681 {"OPLOCK3", run_oplock3, 0},
5682 {"DIR", run_dirtest, 0},
5683 {"DIR1", run_dirtest1, 0},
5684 {"DENY1", torture_denytest1, 0},
5685 {"DENY2", torture_denytest2, 0},
5686 {"TCON", run_tcon_test, 0},
5687 {"TCONDEV", run_tcon_devtype_test, 0},
5688 {"RW1", run_readwritetest, 0},
5689 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5690 {"RW3", run_readwritelarge, 0},
5691 {"OPEN", run_opentest, 0},
5692 #if 1
5693 {"OPENATTR", run_openattrtest, 0},
5694 #endif
5695 {"XCOPY", run_xcopy, 0},
5696 {"RENAME", run_rename, 0},
5697 {"DELETE", run_deletetest, 0},
5698 {"PROPERTIES", run_properties, 0},
5699 {"MANGLE", torture_mangle, 0},
5700 {"W2K", run_w2ktest, 0},
5701 {"TRANS2SCAN", torture_trans2_scan, 0},
5702 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5703 {"UTABLE", torture_utable, 0},
5704 {"CASETABLE", torture_casetable, 0},
5705 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5706 {"PIPE_NUMBER", run_pipe_number, 0},
5707 {"TCON2", run_tcon2_test, 0},
5708 {"IOCTL", torture_ioctl_test, 0},
5709 {"CHKPATH", torture_chkpath_test, 0},
5710 {"FDSESS", run_fdsesstest, 0},
5711 { "EATEST", run_eatest, 0},
5712 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5713 { "CHAIN1", run_chain1, 0},
5714 { "WINDOWS-WRITE", run_windows_write, 0},
5715 { "CLI_ECHO", run_cli_echo, 0},
5716 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5717 { "LOCAL-GENCACHE", run_local_gencache, 0},
5718 { "LOCAL-RBTREE", run_local_rbtree, 0},
5719 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5720 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5721 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5722 {NULL, NULL, 0}};
5726 /****************************************************************************
5727 run a specified test or "ALL"
5728 ****************************************************************************/
5729 static bool run_test(const char *name)
5731 bool ret = True;
5732 bool result = True;
5733 bool found = False;
5734 int i;
5735 double t;
5736 if (strequal(name,"ALL")) {
5737 for (i=0;torture_ops[i].name;i++) {
5738 run_test(torture_ops[i].name);
5740 found = True;
5743 for (i=0;torture_ops[i].name;i++) {
5744 fstr_sprintf(randomfname, "\\XX%x",
5745 (unsigned)random());
5747 if (strequal(name, torture_ops[i].name)) {
5748 found = True;
5749 printf("Running %s\n", name);
5750 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5751 t = create_procs(torture_ops[i].fn, &result);
5752 if (!result) {
5753 ret = False;
5754 printf("TEST %s FAILED!\n", name);
5757 } else {
5758 start_timer();
5759 if (!torture_ops[i].fn(0)) {
5760 ret = False;
5761 printf("TEST %s FAILED!\n", name);
5763 t = end_timer();
5765 printf("%s took %g secs\n\n", name, t);
5769 if (!found) {
5770 printf("Did not find a test named %s\n", name);
5771 ret = False;
5774 return ret;
5778 static void usage(void)
5780 int i;
5782 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5783 printf("Please use samba4 torture.\n\n");
5785 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5787 printf("\t-d debuglevel\n");
5788 printf("\t-U user%%pass\n");
5789 printf("\t-k use kerberos\n");
5790 printf("\t-N numprocs\n");
5791 printf("\t-n my_netbios_name\n");
5792 printf("\t-W workgroup\n");
5793 printf("\t-o num_operations\n");
5794 printf("\t-O socket_options\n");
5795 printf("\t-m maximum protocol\n");
5796 printf("\t-L use oplocks\n");
5797 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5798 printf("\t-A showall\n");
5799 printf("\t-p port\n");
5800 printf("\t-s seed\n");
5801 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5802 printf("\n\n");
5804 printf("tests are:");
5805 for (i=0;torture_ops[i].name;i++) {
5806 printf(" %s", torture_ops[i].name);
5808 printf("\n");
5810 printf("default test is ALL\n");
5812 exit(1);
5815 /****************************************************************************
5816 main program
5817 ****************************************************************************/
5818 int main(int argc,char *argv[])
5820 int opt, i;
5821 char *p;
5822 int gotuser = 0;
5823 int gotpass = 0;
5824 bool correct = True;
5825 TALLOC_CTX *frame = talloc_stackframe();
5826 int seed = time(NULL);
5828 dbf = x_stdout;
5830 #ifdef HAVE_SETBUFFER
5831 setbuffer(stdout, NULL, 0);
5832 #endif
5834 load_case_tables();
5836 if (is_default_dyn_CONFIGFILE()) {
5837 if(getenv("SMB_CONF_PATH")) {
5838 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
5841 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
5842 load_interfaces();
5844 if (argc < 2) {
5845 usage();
5848 for(p = argv[1]; *p; p++)
5849 if(*p == '\\')
5850 *p = '/';
5852 if (strncmp(argv[1], "//", 2)) {
5853 usage();
5856 fstrcpy(host, &argv[1][2]);
5857 p = strchr_m(&host[2],'/');
5858 if (!p) {
5859 usage();
5861 *p = 0;
5862 fstrcpy(share, p+1);
5864 fstrcpy(myname, talloc_get_myname(talloc_tos()));
5865 if (!*myname) {
5866 fprintf(stderr, "Failed to get my hostname.\n");
5867 return 1;
5870 if (*username == 0 && getenv("LOGNAME")) {
5871 fstrcpy(username,getenv("LOGNAME"));
5874 argc--;
5875 argv++;
5877 fstrcpy(workgroup, lp_workgroup());
5879 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
5880 switch (opt) {
5881 case 'p':
5882 port_to_use = atoi(optarg);
5883 break;
5884 case 's':
5885 seed = atoi(optarg);
5886 break;
5887 case 'W':
5888 fstrcpy(workgroup,optarg);
5889 break;
5890 case 'm':
5891 max_protocol = interpret_protocol(optarg, max_protocol);
5892 break;
5893 case 'N':
5894 nprocs = atoi(optarg);
5895 break;
5896 case 'o':
5897 torture_numops = atoi(optarg);
5898 break;
5899 case 'd':
5900 DEBUGLEVEL = atoi(optarg);
5901 break;
5902 case 'O':
5903 sockops = optarg;
5904 break;
5905 case 'L':
5906 use_oplocks = True;
5907 break;
5908 case 'A':
5909 torture_showall = True;
5910 break;
5911 case 'n':
5912 fstrcpy(myname, optarg);
5913 break;
5914 case 'c':
5915 client_txt = optarg;
5916 break;
5917 case 'e':
5918 do_encrypt = true;
5919 break;
5920 case 'k':
5921 #ifdef HAVE_KRB5
5922 use_kerberos = True;
5923 #else
5924 d_printf("No kerberos support compiled in\n");
5925 exit(1);
5926 #endif
5927 break;
5928 case 'U':
5929 gotuser = 1;
5930 fstrcpy(username,optarg);
5931 p = strchr_m(username,'%');
5932 if (p) {
5933 *p = 0;
5934 fstrcpy(password, p+1);
5935 gotpass = 1;
5937 break;
5938 case 'b':
5939 fstrcpy(multishare_conn_fname, optarg);
5940 use_multishare_conn = True;
5941 break;
5942 case 'B':
5943 torture_blocksize = atoi(optarg);
5944 break;
5945 default:
5946 printf("Unknown option %c (%d)\n", (char)opt, opt);
5947 usage();
5951 d_printf("using seed %d\n", seed);
5953 srandom(seed);
5955 if(use_kerberos && !gotuser) gotpass = True;
5957 while (!gotpass) {
5958 p = getpass("Password:");
5959 if (p) {
5960 fstrcpy(password, p);
5961 gotpass = 1;
5965 printf("host=%s share=%s user=%s myname=%s\n",
5966 host, share, username, myname);
5968 if (argc == optind) {
5969 correct = run_test("ALL");
5970 } else {
5971 for (i=optind;i<argc;i++) {
5972 if (!run_test(argv[i])) {
5973 correct = False;
5978 TALLOC_FREE(frame);
5980 if (correct) {
5981 return(0);
5982 } else {
5983 return(1);