ads_connect: Return immediately on a failed GC connection.
[Samba/gebeck_regimport.git] / source3 / torture / torture.c
blob8a1a61e79ac57b972a8a0d4edf33dbc4c9f52d96
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;
1105 memset(buf, '\0', sizeof(buf));
1107 if (!torture_open_connection(&cli, 0)) {
1108 return False;
1110 cli_sockopt(cli, sockops);
1112 printf("starting tcontest\n");
1114 cli_unlink(cli, fname);
1116 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1117 if (fnum1 == -1) {
1118 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1119 return False;
1122 cnum1 = cli->cnum;
1123 vuid1 = cli->vuid;
1125 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1126 printf("initial write failed (%s)", cli_errstr(cli));
1127 return False;
1130 if (!cli_send_tconX(cli, share, "?????",
1131 password, strlen(password)+1)) {
1132 printf("%s refused 2nd tree connect (%s)\n", host,
1133 cli_errstr(cli));
1134 cli_shutdown(cli);
1135 return False;
1138 cnum2 = cli->cnum;
1139 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1140 vuid2 = cli->vuid + 1;
1142 /* try a write with the wrong tid */
1143 cli->cnum = cnum2;
1145 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1146 printf("* server allows write with wrong TID\n");
1147 ret = False;
1148 } else {
1149 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1153 /* try a write with an invalid tid */
1154 cli->cnum = cnum3;
1156 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1157 printf("* server allows write with invalid TID\n");
1158 ret = False;
1159 } else {
1160 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1163 /* try a write with an invalid vuid */
1164 cli->vuid = vuid2;
1165 cli->cnum = cnum1;
1167 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168 printf("* server allows write with invalid VUID\n");
1169 ret = False;
1170 } else {
1171 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1174 cli->cnum = cnum1;
1175 cli->vuid = vuid1;
1177 if (!cli_close(cli, fnum1)) {
1178 printf("close failed (%s)\n", cli_errstr(cli));
1179 return False;
1182 cli->cnum = cnum2;
1184 if (!cli_tdis(cli)) {
1185 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1186 return False;
1189 cli->cnum = cnum1;
1191 if (!torture_close_connection(cli)) {
1192 return False;
1195 return ret;
1200 checks for old style tcon support
1202 static bool run_tcon2_test(int dummy)
1204 static struct cli_state *cli;
1205 uint16 cnum, max_xmit;
1206 char *service;
1207 NTSTATUS status;
1209 if (!torture_open_connection(&cli, 0)) {
1210 return False;
1212 cli_sockopt(cli, sockops);
1214 printf("starting tcon2 test\n");
1216 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1217 return false;
1220 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("tcon2 failed : %s\n", cli_errstr(cli));
1224 } else {
1225 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1226 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1229 if (!torture_close_connection(cli)) {
1230 return False;
1233 printf("Passed tcon2 test\n");
1234 return True;
1237 static bool tcon_devtest(struct cli_state *cli,
1238 const char *myshare, const char *devtype,
1239 const char *return_devtype,
1240 NTSTATUS expected_error)
1242 bool status;
1243 bool ret;
1245 status = cli_send_tconX(cli, myshare, devtype,
1246 password, strlen(password)+1);
1248 if (NT_STATUS_IS_OK(expected_error)) {
1249 if (status) {
1250 if (strcmp(cli->dev, return_devtype) == 0) {
1251 ret = True;
1252 } else {
1253 printf("tconX to share %s with type %s "
1254 "succeeded but returned the wrong "
1255 "device type (got [%s] but should have got [%s])\n",
1256 myshare, devtype, cli->dev, return_devtype);
1257 ret = False;
1259 } else {
1260 printf("tconX to share %s with type %s "
1261 "should have succeeded but failed\n",
1262 myshare, devtype);
1263 ret = False;
1265 cli_tdis(cli);
1266 } else {
1267 if (status) {
1268 printf("tconx to share %s with type %s "
1269 "should have failed but succeeded\n",
1270 myshare, devtype);
1271 ret = False;
1272 } else {
1273 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1274 expected_error)) {
1275 ret = True;
1276 } else {
1277 printf("Returned unexpected error\n");
1278 ret = False;
1282 return ret;
1286 checks for correct tconX support
1288 static bool run_tcon_devtype_test(int dummy)
1290 static struct cli_state *cli1 = NULL;
1291 bool retry;
1292 int flags = 0;
1293 NTSTATUS status;
1294 bool ret = True;
1296 status = cli_full_connection(&cli1, myname,
1297 host, NULL, port_to_use,
1298 NULL, NULL,
1299 username, workgroup,
1300 password, flags, Undefined, &retry);
1302 if (!NT_STATUS_IS_OK(status)) {
1303 printf("could not open connection\n");
1304 return False;
1307 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1308 ret = False;
1310 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1311 ret = False;
1313 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1314 ret = False;
1316 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1317 ret = False;
1319 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1320 ret = False;
1322 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1323 ret = False;
1325 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1326 ret = False;
1328 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1329 ret = False;
1331 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332 ret = False;
1334 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1335 ret = False;
1337 cli_shutdown(cli1);
1339 if (ret)
1340 printf("Passed tcondevtest\n");
1342 return ret;
1347 This test checks that
1349 1) the server supports multiple locking contexts on the one SMB
1350 connection, distinguished by PID.
1352 2) the server correctly fails overlapping locks made by the same PID (this
1353 goes against POSIX behaviour, which is why it is tricky to implement)
1355 3) the server denies unlock requests by an incorrect client PID
1357 static bool run_locktest2(int dummy)
1359 static struct cli_state *cli;
1360 const char *fname = "\\lockt2.lck";
1361 int fnum1, fnum2, fnum3;
1362 bool correct = True;
1364 if (!torture_open_connection(&cli, 0)) {
1365 return False;
1368 cli_sockopt(cli, sockops);
1370 printf("starting locktest2\n");
1372 cli_unlink(cli, fname);
1374 cli_setpid(cli, 1);
1376 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1377 if (fnum1 == -1) {
1378 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1379 return False;
1382 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1383 if (fnum2 == -1) {
1384 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1385 return False;
1388 cli_setpid(cli, 2);
1390 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1391 if (fnum3 == -1) {
1392 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1393 return False;
1396 cli_setpid(cli, 1);
1398 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1399 printf("lock1 failed (%s)\n", cli_errstr(cli));
1400 return False;
1403 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1404 printf("WRITE lock1 succeeded! This is a locking bug\n");
1405 correct = False;
1406 } else {
1407 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1408 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1411 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1412 printf("WRITE lock2 succeeded! This is a locking bug\n");
1413 correct = False;
1414 } else {
1415 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1416 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1419 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1420 printf("READ lock2 succeeded! This is a locking bug\n");
1421 correct = False;
1422 } else {
1423 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1424 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1427 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1428 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1430 cli_setpid(cli, 2);
1431 if (cli_unlock(cli, fnum1, 100, 4)) {
1432 printf("unlock at 100 succeeded! This is a locking bug\n");
1433 correct = False;
1436 if (cli_unlock(cli, fnum1, 0, 4)) {
1437 printf("unlock1 succeeded! This is a locking bug\n");
1438 correct = False;
1439 } else {
1440 if (!check_error(__LINE__, cli,
1441 ERRDOS, ERRlock,
1442 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1445 if (cli_unlock(cli, fnum1, 0, 8)) {
1446 printf("unlock2 succeeded! This is a locking bug\n");
1447 correct = False;
1448 } else {
1449 if (!check_error(__LINE__, cli,
1450 ERRDOS, ERRlock,
1451 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1454 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1455 printf("lock3 succeeded! This is a locking bug\n");
1456 correct = False;
1457 } else {
1458 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1461 cli_setpid(cli, 1);
1463 if (!cli_close(cli, fnum1)) {
1464 printf("close1 failed (%s)\n", cli_errstr(cli));
1465 return False;
1468 if (!cli_close(cli, fnum2)) {
1469 printf("close2 failed (%s)\n", cli_errstr(cli));
1470 return False;
1473 if (!cli_close(cli, fnum3)) {
1474 printf("close3 failed (%s)\n", cli_errstr(cli));
1475 return False;
1478 if (!torture_close_connection(cli)) {
1479 correct = False;
1482 printf("locktest2 finished\n");
1484 return correct;
1489 This test checks that
1491 1) the server supports the full offset range in lock requests
1493 static bool run_locktest3(int dummy)
1495 static struct cli_state *cli1, *cli2;
1496 const char *fname = "\\lockt3.lck";
1497 int fnum1, fnum2, i;
1498 uint32 offset;
1499 bool correct = True;
1501 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1503 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1504 return False;
1506 cli_sockopt(cli1, sockops);
1507 cli_sockopt(cli2, sockops);
1509 printf("starting locktest3\n");
1511 cli_unlink(cli1, fname);
1513 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1514 if (fnum1 == -1) {
1515 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1516 return False;
1518 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1519 if (fnum2 == -1) {
1520 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1521 return False;
1524 for (offset=i=0;i<torture_numops;i++) {
1525 NEXT_OFFSET;
1526 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1527 printf("lock1 %d failed (%s)\n",
1529 cli_errstr(cli1));
1530 return False;
1533 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1534 printf("lock2 %d failed (%s)\n",
1536 cli_errstr(cli1));
1537 return False;
1541 for (offset=i=0;i<torture_numops;i++) {
1542 NEXT_OFFSET;
1544 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1545 printf("error: lock1 %d succeeded!\n", i);
1546 return False;
1549 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1550 printf("error: lock2 %d succeeded!\n", i);
1551 return False;
1554 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1555 printf("error: lock3 %d succeeded!\n", i);
1556 return False;
1559 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1560 printf("error: lock4 %d succeeded!\n", i);
1561 return False;
1565 for (offset=i=0;i<torture_numops;i++) {
1566 NEXT_OFFSET;
1568 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1569 printf("unlock1 %d failed (%s)\n",
1571 cli_errstr(cli1));
1572 return False;
1575 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1576 printf("unlock2 %d failed (%s)\n",
1578 cli_errstr(cli1));
1579 return False;
1583 if (!cli_close(cli1, fnum1)) {
1584 printf("close1 failed (%s)\n", cli_errstr(cli1));
1585 return False;
1588 if (!cli_close(cli2, fnum2)) {
1589 printf("close2 failed (%s)\n", cli_errstr(cli2));
1590 return False;
1593 if (!cli_unlink(cli1, fname)) {
1594 printf("unlink failed (%s)\n", cli_errstr(cli1));
1595 return False;
1598 if (!torture_close_connection(cli1)) {
1599 correct = False;
1602 if (!torture_close_connection(cli2)) {
1603 correct = False;
1606 printf("finished locktest3\n");
1608 return correct;
1611 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1612 printf("** "); correct = False; \
1616 looks at overlapping locks
1618 static bool run_locktest4(int dummy)
1620 static struct cli_state *cli1, *cli2;
1621 const char *fname = "\\lockt4.lck";
1622 int fnum1, fnum2, f;
1623 bool ret;
1624 char buf[1000];
1625 bool correct = True;
1627 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1628 return False;
1631 cli_sockopt(cli1, sockops);
1632 cli_sockopt(cli2, sockops);
1634 printf("starting locktest4\n");
1636 cli_unlink(cli1, fname);
1638 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1639 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1641 memset(buf, 0, sizeof(buf));
1643 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1644 printf("Failed to create file\n");
1645 correct = False;
1646 goto fail;
1649 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1650 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1651 EXPECTED(ret, False);
1652 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1654 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1655 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1656 EXPECTED(ret, True);
1657 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1659 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1660 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1661 EXPECTED(ret, False);
1662 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1664 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1665 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1666 EXPECTED(ret, True);
1667 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1669 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1670 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1671 EXPECTED(ret, False);
1672 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1674 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1675 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1676 EXPECTED(ret, True);
1677 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1679 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1680 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1681 EXPECTED(ret, True);
1682 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1684 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1685 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1686 EXPECTED(ret, False);
1687 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1689 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1690 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1691 EXPECTED(ret, False);
1692 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1694 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1695 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1696 EXPECTED(ret, True);
1697 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1699 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1700 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1701 EXPECTED(ret, False);
1702 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1704 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1705 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1706 cli_unlock(cli1, fnum1, 110, 6);
1707 EXPECTED(ret, False);
1708 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1711 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1712 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1713 EXPECTED(ret, False);
1714 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1716 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1717 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1718 EXPECTED(ret, False);
1719 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1722 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1723 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1724 cli_unlock(cli1, fnum1, 140, 4) &&
1725 cli_unlock(cli1, fnum1, 140, 4);
1726 EXPECTED(ret, True);
1727 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1730 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1731 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1732 cli_unlock(cli1, fnum1, 150, 4) &&
1733 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1734 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1735 cli_unlock(cli1, fnum1, 150, 4);
1736 EXPECTED(ret, True);
1737 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1739 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1740 cli_unlock(cli1, fnum1, 160, 4) &&
1741 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1742 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1743 EXPECTED(ret, True);
1744 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1746 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1747 cli_unlock(cli1, fnum1, 170, 4) &&
1748 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1749 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1750 EXPECTED(ret, True);
1751 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1753 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1754 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1755 cli_unlock(cli1, fnum1, 190, 4) &&
1756 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1757 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1758 EXPECTED(ret, True);
1759 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1761 cli_close(cli1, fnum1);
1762 cli_close(cli2, fnum2);
1763 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1764 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1765 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1766 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1767 cli_close(cli1, fnum1) &&
1768 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1769 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1770 cli_close(cli1, f);
1771 cli_close(cli1, fnum1);
1772 EXPECTED(ret, True);
1773 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1775 fail:
1776 cli_close(cli1, fnum1);
1777 cli_close(cli2, fnum2);
1778 cli_unlink(cli1, fname);
1779 torture_close_connection(cli1);
1780 torture_close_connection(cli2);
1782 printf("finished locktest4\n");
1783 return correct;
1787 looks at lock upgrade/downgrade.
1789 static bool run_locktest5(int dummy)
1791 static struct cli_state *cli1, *cli2;
1792 const char *fname = "\\lockt5.lck";
1793 int fnum1, fnum2, fnum3;
1794 bool ret;
1795 char buf[1000];
1796 bool correct = True;
1798 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1799 return False;
1802 cli_sockopt(cli1, sockops);
1803 cli_sockopt(cli2, sockops);
1805 printf("starting locktest5\n");
1807 cli_unlink(cli1, fname);
1809 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1810 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1811 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1813 memset(buf, 0, sizeof(buf));
1815 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1816 printf("Failed to create file\n");
1817 correct = False;
1818 goto fail;
1821 /* Check for NT bug... */
1822 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1823 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1824 cli_close(cli1, fnum1);
1825 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1826 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1827 EXPECTED(ret, True);
1828 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1829 cli_close(cli1, fnum1);
1830 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1831 cli_unlock(cli1, fnum3, 0, 1);
1833 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1834 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1835 EXPECTED(ret, True);
1836 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1838 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1839 EXPECTED(ret, False);
1841 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1843 /* Unlock the process 2 lock. */
1844 cli_unlock(cli2, fnum2, 0, 4);
1846 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1847 EXPECTED(ret, False);
1849 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1851 /* Unlock the process 1 fnum3 lock. */
1852 cli_unlock(cli1, fnum3, 0, 4);
1854 /* Stack 2 more locks here. */
1855 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1856 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1858 EXPECTED(ret, True);
1859 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1861 /* Unlock the first process lock, then check this was the WRITE lock that was
1862 removed. */
1864 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1865 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1867 EXPECTED(ret, True);
1868 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1870 /* Unlock the process 2 lock. */
1871 cli_unlock(cli2, fnum2, 0, 4);
1873 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1875 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1876 cli_unlock(cli1, fnum1, 0, 4) &&
1877 cli_unlock(cli1, fnum1, 0, 4);
1879 EXPECTED(ret, True);
1880 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1882 /* Ensure the next unlock fails. */
1883 ret = cli_unlock(cli1, fnum1, 0, 4);
1884 EXPECTED(ret, False);
1885 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1887 /* Ensure connection 2 can get a write lock. */
1888 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1889 EXPECTED(ret, True);
1891 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1894 fail:
1895 cli_close(cli1, fnum1);
1896 cli_close(cli2, fnum2);
1897 cli_unlink(cli1, fname);
1898 if (!torture_close_connection(cli1)) {
1899 correct = False;
1901 if (!torture_close_connection(cli2)) {
1902 correct = False;
1905 printf("finished locktest5\n");
1907 return correct;
1911 tries the unusual lockingX locktype bits
1913 static bool run_locktest6(int dummy)
1915 static struct cli_state *cli;
1916 const char *fname[1] = { "\\lock6.txt" };
1917 int i;
1918 int fnum;
1919 NTSTATUS status;
1921 if (!torture_open_connection(&cli, 0)) {
1922 return False;
1925 cli_sockopt(cli, sockops);
1927 printf("starting locktest6\n");
1929 for (i=0;i<1;i++) {
1930 printf("Testing %s\n", fname[i]);
1932 cli_unlink(cli, fname[i]);
1934 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1935 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1936 cli_close(cli, fnum);
1937 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1939 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1940 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1941 cli_close(cli, fnum);
1942 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1944 cli_unlink(cli, fname[i]);
1947 torture_close_connection(cli);
1949 printf("finished locktest6\n");
1950 return True;
1953 static bool run_locktest7(int dummy)
1955 struct cli_state *cli1;
1956 const char *fname = "\\lockt7.lck";
1957 int fnum1;
1958 char buf[200];
1959 bool correct = False;
1961 if (!torture_open_connection(&cli1, 0)) {
1962 return False;
1965 cli_sockopt(cli1, sockops);
1967 printf("starting locktest7\n");
1969 cli_unlink(cli1, fname);
1971 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1973 memset(buf, 0, sizeof(buf));
1975 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1976 printf("Failed to create file\n");
1977 goto fail;
1980 cli_setpid(cli1, 1);
1982 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1983 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1984 goto fail;
1985 } else {
1986 printf("pid1 successfully locked range 130:4 for READ\n");
1989 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1990 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1991 goto fail;
1992 } else {
1993 printf("pid1 successfully read the range 130:4\n");
1996 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1997 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1998 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1999 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2000 goto fail;
2002 } else {
2003 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2004 goto fail;
2007 cli_setpid(cli1, 2);
2009 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2010 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2011 } else {
2012 printf("pid2 successfully read the range 130:4\n");
2015 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2016 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2017 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2018 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2019 goto fail;
2021 } else {
2022 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2023 goto fail;
2026 cli_setpid(cli1, 1);
2027 cli_unlock(cli1, fnum1, 130, 4);
2029 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2030 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2031 goto fail;
2032 } else {
2033 printf("pid1 successfully locked range 130:4 for WRITE\n");
2036 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2037 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2038 goto fail;
2039 } else {
2040 printf("pid1 successfully read the range 130:4\n");
2043 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2044 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2045 goto fail;
2046 } else {
2047 printf("pid1 successfully wrote to the range 130:4\n");
2050 cli_setpid(cli1, 2);
2052 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2053 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2054 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2055 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2056 goto fail;
2058 } else {
2059 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2060 goto fail;
2063 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2064 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2065 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2066 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2067 goto fail;
2069 } else {
2070 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2071 goto fail;
2074 cli_unlock(cli1, fnum1, 130, 0);
2075 correct = True;
2077 fail:
2078 cli_close(cli1, fnum1);
2079 cli_unlink(cli1, fname);
2080 torture_close_connection(cli1);
2082 printf("finished locktest7\n");
2083 return correct;
2087 test whether fnums and tids open on one VC are available on another (a major
2088 security hole)
2090 static bool run_fdpasstest(int dummy)
2092 struct cli_state *cli1, *cli2;
2093 const char *fname = "\\fdpass.tst";
2094 int fnum1;
2095 char buf[1024];
2097 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2098 return False;
2100 cli_sockopt(cli1, sockops);
2101 cli_sockopt(cli2, sockops);
2103 printf("starting fdpasstest\n");
2105 cli_unlink(cli1, fname);
2107 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2108 if (fnum1 == -1) {
2109 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2110 return False;
2113 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2114 printf("write failed (%s)\n", cli_errstr(cli1));
2115 return False;
2118 cli2->vuid = cli1->vuid;
2119 cli2->cnum = cli1->cnum;
2120 cli2->pid = cli1->pid;
2122 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2123 printf("read succeeded! nasty security hole [%s]\n",
2124 buf);
2125 return False;
2128 cli_close(cli1, fnum1);
2129 cli_unlink(cli1, fname);
2131 torture_close_connection(cli1);
2132 torture_close_connection(cli2);
2134 printf("finished fdpasstest\n");
2135 return True;
2138 static bool run_fdsesstest(int dummy)
2140 struct cli_state *cli;
2141 uint16 new_vuid;
2142 uint16 saved_vuid;
2143 uint16 new_cnum;
2144 uint16 saved_cnum;
2145 const char *fname = "\\fdsess.tst";
2146 const char *fname1 = "\\fdsess1.tst";
2147 int fnum1;
2148 int fnum2;
2149 char buf[1024];
2150 bool ret = True;
2152 if (!torture_open_connection(&cli, 0))
2153 return False;
2154 cli_sockopt(cli, sockops);
2156 if (!torture_cli_session_setup2(cli, &new_vuid))
2157 return False;
2159 saved_cnum = cli->cnum;
2160 if (!cli_send_tconX(cli, share, "?????", "", 1))
2161 return False;
2162 new_cnum = cli->cnum;
2163 cli->cnum = saved_cnum;
2165 printf("starting fdsesstest\n");
2167 cli_unlink(cli, fname);
2168 cli_unlink(cli, fname1);
2170 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2171 if (fnum1 == -1) {
2172 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2173 return False;
2176 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2177 printf("write failed (%s)\n", cli_errstr(cli));
2178 return False;
2181 saved_vuid = cli->vuid;
2182 cli->vuid = new_vuid;
2184 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2185 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2186 buf);
2187 ret = False;
2189 /* Try to open a file with different vuid, samba cnum. */
2190 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2191 if (fnum2 != -1) {
2192 printf("create with different vuid, same cnum succeeded.\n");
2193 cli_close(cli, fnum2);
2194 cli_unlink(cli, fname1);
2195 } else {
2196 printf("create with different vuid, same cnum failed.\n");
2197 printf("This will cause problems with service clients.\n");
2198 ret = False;
2201 cli->vuid = saved_vuid;
2203 /* Try with same vuid, different cnum. */
2204 cli->cnum = new_cnum;
2206 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2207 printf("read succeeded with different cnum![%s]\n",
2208 buf);
2209 ret = False;
2212 cli->cnum = saved_cnum;
2213 cli_close(cli, fnum1);
2214 cli_unlink(cli, fname);
2216 torture_close_connection(cli);
2218 printf("finished fdsesstest\n");
2219 return ret;
2223 This test checks that
2225 1) the server does not allow an unlink on a file that is open
2227 static bool run_unlinktest(int dummy)
2229 struct cli_state *cli;
2230 const char *fname = "\\unlink.tst";
2231 int fnum;
2232 bool correct = True;
2234 if (!torture_open_connection(&cli, 0)) {
2235 return False;
2238 cli_sockopt(cli, sockops);
2240 printf("starting unlink test\n");
2242 cli_unlink(cli, fname);
2244 cli_setpid(cli, 1);
2246 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2247 if (fnum == -1) {
2248 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2249 return False;
2252 if (cli_unlink(cli, fname)) {
2253 printf("error: server allowed unlink on an open file\n");
2254 correct = False;
2255 } else {
2256 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2257 NT_STATUS_SHARING_VIOLATION);
2260 cli_close(cli, fnum);
2261 cli_unlink(cli, fname);
2263 if (!torture_close_connection(cli)) {
2264 correct = False;
2267 printf("unlink test finished\n");
2269 return correct;
2274 test how many open files this server supports on the one socket
2276 static bool run_maxfidtest(int dummy)
2278 struct cli_state *cli;
2279 const char *ftemplate = "\\maxfid.%d.%d";
2280 fstring fname;
2281 int fnums[0x11000], i;
2282 int retries=4;
2283 bool correct = True;
2285 cli = current_cli;
2287 if (retries <= 0) {
2288 printf("failed to connect\n");
2289 return False;
2292 cli_sockopt(cli, sockops);
2294 for (i=0; i<0x11000; i++) {
2295 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2296 if ((fnums[i] = cli_open(cli, fname,
2297 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2298 -1) {
2299 printf("open of %s failed (%s)\n",
2300 fname, cli_errstr(cli));
2301 printf("maximum fnum is %d\n", i);
2302 break;
2304 printf("%6d\r", i);
2306 printf("%6d\n", i);
2307 i--;
2309 printf("cleaning up\n");
2310 for (;i>=0;i--) {
2311 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2312 cli_close(cli, fnums[i]);
2313 if (!cli_unlink(cli, fname)) {
2314 printf("unlink of %s failed (%s)\n",
2315 fname, cli_errstr(cli));
2316 correct = False;
2318 printf("%6d\r", i);
2320 printf("%6d\n", 0);
2322 printf("maxfid test finished\n");
2323 if (!torture_close_connection(cli)) {
2324 correct = False;
2326 return correct;
2329 /* generate a random buffer */
2330 static void rand_buf(char *buf, int len)
2332 while (len--) {
2333 *buf = (char)sys_random();
2334 buf++;
2338 /* send smb negprot commands, not reading the response */
2339 static bool run_negprot_nowait(int dummy)
2341 int i;
2342 static struct cli_state *cli;
2343 bool correct = True;
2345 printf("starting negprot nowait test\n");
2347 if (!(cli = open_nbt_connection())) {
2348 return False;
2351 for (i=0;i<50000;i++) {
2352 cli_negprot_sendsync(cli);
2355 if (!torture_close_connection(cli)) {
2356 correct = False;
2359 printf("finished negprot nowait test\n");
2361 return correct;
2365 /* send random IPC commands */
2366 static bool run_randomipc(int dummy)
2368 char *rparam = NULL;
2369 char *rdata = NULL;
2370 unsigned int rdrcnt,rprcnt;
2371 char param[1024];
2372 int api, param_len, i;
2373 struct cli_state *cli;
2374 bool correct = True;
2375 int count = 50000;
2377 printf("starting random ipc test\n");
2379 if (!torture_open_connection(&cli, 0)) {
2380 return False;
2383 for (i=0;i<count;i++) {
2384 api = sys_random() % 500;
2385 param_len = (sys_random() % 64);
2387 rand_buf(param, param_len);
2389 SSVAL(param,0,api);
2391 cli_api(cli,
2392 param, param_len, 8,
2393 NULL, 0, BUFFER_SIZE,
2394 &rparam, &rprcnt,
2395 &rdata, &rdrcnt);
2396 if (i % 100 == 0) {
2397 printf("%d/%d\r", i,count);
2400 printf("%d/%d\n", i, count);
2402 if (!torture_close_connection(cli)) {
2403 correct = False;
2406 printf("finished random ipc test\n");
2408 return correct;
2413 static void browse_callback(const char *sname, uint32 stype,
2414 const char *comment, void *state)
2416 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2422 This test checks the browse list code
2425 static bool run_browsetest(int dummy)
2427 static struct cli_state *cli;
2428 bool correct = True;
2430 printf("starting browse test\n");
2432 if (!torture_open_connection(&cli, 0)) {
2433 return False;
2436 printf("domain list:\n");
2437 cli_NetServerEnum(cli, cli->server_domain,
2438 SV_TYPE_DOMAIN_ENUM,
2439 browse_callback, NULL);
2441 printf("machine list:\n");
2442 cli_NetServerEnum(cli, cli->server_domain,
2443 SV_TYPE_ALL,
2444 browse_callback, NULL);
2446 if (!torture_close_connection(cli)) {
2447 correct = False;
2450 printf("browse test finished\n");
2452 return correct;
2458 This checks how the getatr calls works
2460 static bool run_attrtest(int dummy)
2462 struct cli_state *cli;
2463 int fnum;
2464 time_t t, t2;
2465 const char *fname = "\\attrib123456789.tst";
2466 bool correct = True;
2468 printf("starting attrib test\n");
2470 if (!torture_open_connection(&cli, 0)) {
2471 return False;
2474 cli_unlink(cli, fname);
2475 fnum = cli_open(cli, fname,
2476 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2477 cli_close(cli, fnum);
2478 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2479 printf("getatr failed (%s)\n", cli_errstr(cli));
2480 correct = False;
2483 if (abs(t - time(NULL)) > 60*60*24*10) {
2484 printf("ERROR: SMBgetatr bug. time is %s",
2485 ctime(&t));
2486 t = time(NULL);
2487 correct = True;
2490 t2 = t-60*60*24; /* 1 day ago */
2492 if (!cli_setatr(cli, fname, 0, t2)) {
2493 printf("setatr failed (%s)\n", cli_errstr(cli));
2494 correct = True;
2497 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2498 printf("getatr failed (%s)\n", cli_errstr(cli));
2499 correct = True;
2502 if (t != t2) {
2503 printf("ERROR: getatr/setatr bug. times are\n%s",
2504 ctime(&t));
2505 printf("%s", ctime(&t2));
2506 correct = True;
2509 cli_unlink(cli, fname);
2511 if (!torture_close_connection(cli)) {
2512 correct = False;
2515 printf("attrib test finished\n");
2517 return correct;
2522 This checks a couple of trans2 calls
2524 static bool run_trans2test(int dummy)
2526 struct cli_state *cli;
2527 int fnum;
2528 SMB_OFF_T size;
2529 time_t c_time, a_time, m_time;
2530 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2531 const char *fname = "\\trans2.tst";
2532 const char *dname = "\\trans2";
2533 const char *fname2 = "\\trans2\\trans2.tst";
2534 char pname[1024];
2535 bool correct = True;
2537 printf("starting trans2 test\n");
2539 if (!torture_open_connection(&cli, 0)) {
2540 return False;
2543 cli_unlink(cli, fname);
2544 fnum = cli_open(cli, fname,
2545 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2546 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2547 &m_time_ts, NULL)) {
2548 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2549 correct = False;
2552 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2553 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2554 correct = False;
2557 if (strcmp(pname, fname)) {
2558 printf("qfilename gave different name? [%s] [%s]\n",
2559 fname, pname);
2560 correct = False;
2563 cli_close(cli, fnum);
2565 sleep(2);
2567 cli_unlink(cli, fname);
2568 fnum = cli_open(cli, fname,
2569 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2570 if (fnum == -1) {
2571 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2572 return False;
2574 cli_close(cli, fnum);
2576 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2577 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2578 correct = False;
2579 } else {
2580 if (c_time != m_time) {
2581 printf("create time=%s", ctime(&c_time));
2582 printf("modify time=%s", ctime(&m_time));
2583 printf("This system appears to have sticky create times\n");
2585 if (a_time % (60*60) == 0) {
2586 printf("access time=%s", ctime(&a_time));
2587 printf("This system appears to set a midnight access time\n");
2588 correct = False;
2591 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2592 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2593 correct = False;
2598 cli_unlink(cli, fname);
2599 fnum = cli_open(cli, fname,
2600 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2601 cli_close(cli, fnum);
2602 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2603 &m_time_ts, &size, NULL, NULL)) {
2604 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2605 correct = False;
2606 } else {
2607 if (w_time_ts.tv_sec < 60*60*24*2) {
2608 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2609 printf("This system appears to set a initial 0 write time\n");
2610 correct = False;
2614 cli_unlink(cli, fname);
2617 /* check if the server updates the directory modification time
2618 when creating a new file */
2619 if (!cli_mkdir(cli, dname)) {
2620 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2621 correct = False;
2623 sleep(3);
2624 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2625 &m_time_ts, &size, NULL, NULL)) {
2626 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2627 correct = False;
2630 fnum = cli_open(cli, fname2,
2631 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2632 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2633 cli_close(cli, fnum);
2634 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2635 &m_time2_ts, &size, NULL, NULL)) {
2636 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2637 correct = False;
2638 } else {
2639 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2640 == 0) {
2641 printf("This system does not update directory modification times\n");
2642 correct = False;
2645 cli_unlink(cli, fname2);
2646 cli_rmdir(cli, dname);
2648 if (!torture_close_connection(cli)) {
2649 correct = False;
2652 printf("trans2 test finished\n");
2654 return correct;
2658 This checks new W2K calls.
2661 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2663 char *buf = NULL;
2664 uint32 len;
2665 bool correct = True;
2667 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2668 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2669 correct = False;
2670 } else {
2671 printf("qfileinfo: level %d, len = %u\n", level, len);
2672 dump_data(0, (uint8 *)buf, len);
2673 printf("\n");
2675 SAFE_FREE(buf);
2676 return correct;
2679 static bool run_w2ktest(int dummy)
2681 struct cli_state *cli;
2682 int fnum;
2683 const char *fname = "\\w2ktest\\w2k.tst";
2684 int level;
2685 bool correct = True;
2687 printf("starting w2k test\n");
2689 if (!torture_open_connection(&cli, 0)) {
2690 return False;
2693 fnum = cli_open(cli, fname,
2694 O_RDWR | O_CREAT , DENY_NONE);
2696 for (level = 1004; level < 1040; level++) {
2697 new_trans(cli, fnum, level);
2700 cli_close(cli, fnum);
2702 if (!torture_close_connection(cli)) {
2703 correct = False;
2706 printf("w2k test finished\n");
2708 return correct;
2713 this is a harness for some oplock tests
2715 static bool run_oplock1(int dummy)
2717 struct cli_state *cli1;
2718 const char *fname = "\\lockt1.lck";
2719 int fnum1;
2720 bool correct = True;
2722 printf("starting oplock test 1\n");
2724 if (!torture_open_connection(&cli1, 0)) {
2725 return False;
2728 cli_unlink(cli1, fname);
2730 cli_sockopt(cli1, sockops);
2732 cli1->use_oplocks = True;
2734 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2735 if (fnum1 == -1) {
2736 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2737 return False;
2740 cli1->use_oplocks = False;
2742 cli_unlink(cli1, fname);
2743 cli_unlink(cli1, fname);
2745 if (!cli_close(cli1, fnum1)) {
2746 printf("close2 failed (%s)\n", cli_errstr(cli1));
2747 return False;
2750 if (!cli_unlink(cli1, fname)) {
2751 printf("unlink failed (%s)\n", cli_errstr(cli1));
2752 return False;
2755 if (!torture_close_connection(cli1)) {
2756 correct = False;
2759 printf("finished oplock test 1\n");
2761 return correct;
2764 static bool run_oplock2(int dummy)
2766 struct cli_state *cli1, *cli2;
2767 const char *fname = "\\lockt2.lck";
2768 int fnum1, fnum2;
2769 int saved_use_oplocks = use_oplocks;
2770 char buf[4];
2771 bool correct = True;
2772 volatile bool *shared_correct;
2774 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2775 *shared_correct = True;
2777 use_level_II_oplocks = True;
2778 use_oplocks = True;
2780 printf("starting oplock test 2\n");
2782 if (!torture_open_connection(&cli1, 0)) {
2783 use_level_II_oplocks = False;
2784 use_oplocks = saved_use_oplocks;
2785 return False;
2788 cli1->use_oplocks = True;
2789 cli1->use_level_II_oplocks = True;
2791 if (!torture_open_connection(&cli2, 1)) {
2792 use_level_II_oplocks = False;
2793 use_oplocks = saved_use_oplocks;
2794 return False;
2797 cli2->use_oplocks = True;
2798 cli2->use_level_II_oplocks = True;
2800 cli_unlink(cli1, fname);
2802 cli_sockopt(cli1, sockops);
2803 cli_sockopt(cli2, sockops);
2805 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2806 if (fnum1 == -1) {
2807 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2808 return False;
2811 /* Don't need the globals any more. */
2812 use_level_II_oplocks = False;
2813 use_oplocks = saved_use_oplocks;
2815 if (fork() == 0) {
2816 /* Child code */
2817 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2818 if (fnum2 == -1) {
2819 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2820 *shared_correct = False;
2821 exit(0);
2824 sleep(2);
2826 if (!cli_close(cli2, fnum2)) {
2827 printf("close2 failed (%s)\n", cli_errstr(cli1));
2828 *shared_correct = False;
2831 exit(0);
2834 sleep(2);
2836 /* Ensure cli1 processes the break. Empty file should always return 0
2837 * bytes. */
2839 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2840 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2841 correct = False;
2844 /* Should now be at level II. */
2845 /* Test if sending a write locks causes a break to none. */
2847 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2848 printf("lock failed (%s)\n", cli_errstr(cli1));
2849 correct = False;
2852 cli_unlock(cli1, fnum1, 0, 4);
2854 sleep(2);
2856 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2857 printf("lock failed (%s)\n", cli_errstr(cli1));
2858 correct = False;
2861 cli_unlock(cli1, fnum1, 0, 4);
2863 sleep(2);
2865 cli_read(cli1, fnum1, buf, 0, 4);
2867 #if 0
2868 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2869 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2870 correct = False;
2872 #endif
2874 if (!cli_close(cli1, fnum1)) {
2875 printf("close1 failed (%s)\n", cli_errstr(cli1));
2876 correct = False;
2879 sleep(4);
2881 if (!cli_unlink(cli1, fname)) {
2882 printf("unlink failed (%s)\n", cli_errstr(cli1));
2883 correct = False;
2886 if (!torture_close_connection(cli1)) {
2887 correct = False;
2890 if (!*shared_correct) {
2891 correct = False;
2894 printf("finished oplock test 2\n");
2896 return correct;
2899 /* handler for oplock 3 tests */
2900 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2902 printf("got oplock break fnum=%d level=%d\n",
2903 fnum, level);
2904 return cli_oplock_ack(cli, fnum, level);
2907 static bool run_oplock3(int dummy)
2909 struct cli_state *cli;
2910 const char *fname = "\\oplockt3.dat";
2911 int fnum;
2912 char buf[4] = "abcd";
2913 bool correct = True;
2914 volatile bool *shared_correct;
2916 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2917 *shared_correct = True;
2919 printf("starting oplock test 3\n");
2921 if (fork() == 0) {
2922 /* Child code */
2923 use_oplocks = True;
2924 use_level_II_oplocks = True;
2925 if (!torture_open_connection(&cli, 0)) {
2926 *shared_correct = False;
2927 exit(0);
2929 sleep(2);
2930 /* try to trigger a oplock break in parent */
2931 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2932 cli_write(cli, fnum, 0, buf, 0, 4);
2933 exit(0);
2936 /* parent code */
2937 use_oplocks = True;
2938 use_level_II_oplocks = True;
2939 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2940 return False;
2942 cli_oplock_handler(cli, oplock3_handler);
2943 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2944 cli_write(cli, fnum, 0, buf, 0, 4);
2945 cli_close(cli, fnum);
2946 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2947 cli->timeout = 20000;
2948 cli_receive_smb(cli);
2949 printf("finished oplock test 3\n");
2951 return (correct && *shared_correct);
2953 /* What are we looking for here? What's sucess and what's FAILURE? */
2959 Test delete on close semantics.
2961 static bool run_deletetest(int dummy)
2963 struct cli_state *cli1 = NULL;
2964 struct cli_state *cli2 = NULL;
2965 const char *fname = "\\delete.file";
2966 int fnum1 = -1;
2967 int fnum2 = -1;
2968 bool correct = True;
2970 printf("starting delete test\n");
2972 if (!torture_open_connection(&cli1, 0)) {
2973 return False;
2976 cli_sockopt(cli1, sockops);
2978 /* Test 1 - this should delete the file on close. */
2980 cli_setatr(cli1, fname, 0, 0);
2981 cli_unlink(cli1, fname);
2983 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2984 0, FILE_OVERWRITE_IF,
2985 FILE_DELETE_ON_CLOSE, 0);
2987 if (fnum1 == -1) {
2988 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2989 correct = False;
2990 goto fail;
2993 #if 0 /* JRATEST */
2995 uint32 *accinfo = NULL;
2996 uint32 len;
2997 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2998 if (accinfo)
2999 printf("access mode = 0x%lx\n", *accinfo);
3000 SAFE_FREE(accinfo);
3002 #endif
3004 if (!cli_close(cli1, fnum1)) {
3005 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3006 correct = False;
3007 goto fail;
3010 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3011 if (fnum1 != -1) {
3012 printf("[1] open of %s succeeded (should fail)\n", fname);
3013 correct = False;
3014 goto fail;
3017 printf("first delete on close test succeeded.\n");
3019 /* Test 2 - this should delete the file on close. */
3021 cli_setatr(cli1, fname, 0, 0);
3022 cli_unlink(cli1, fname);
3024 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3025 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3026 FILE_OVERWRITE_IF, 0, 0);
3028 if (fnum1 == -1) {
3029 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3030 correct = False;
3031 goto fail;
3034 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3035 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3036 correct = False;
3037 goto fail;
3040 if (!cli_close(cli1, fnum1)) {
3041 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3042 correct = False;
3043 goto fail;
3046 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3047 if (fnum1 != -1) {
3048 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3049 if (!cli_close(cli1, fnum1)) {
3050 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3051 correct = False;
3052 goto fail;
3054 cli_unlink(cli1, fname);
3055 } else
3056 printf("second delete on close test succeeded.\n");
3058 /* Test 3 - ... */
3059 cli_setatr(cli1, fname, 0, 0);
3060 cli_unlink(cli1, fname);
3062 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3063 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3065 if (fnum1 == -1) {
3066 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3067 correct = False;
3068 goto fail;
3071 /* This should fail with a sharing violation - open for delete is only compatible
3072 with SHARE_DELETE. */
3074 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3075 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3077 if (fnum2 != -1) {
3078 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3079 correct = False;
3080 goto fail;
3083 /* This should succeed. */
3085 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3086 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3088 if (fnum2 == -1) {
3089 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3090 correct = False;
3091 goto fail;
3094 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3095 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3096 correct = False;
3097 goto fail;
3100 if (!cli_close(cli1, fnum1)) {
3101 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3102 correct = False;
3103 goto fail;
3106 if (!cli_close(cli1, fnum2)) {
3107 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3108 correct = False;
3109 goto fail;
3112 /* This should fail - file should no longer be there. */
3114 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3115 if (fnum1 != -1) {
3116 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3117 if (!cli_close(cli1, fnum1)) {
3118 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3120 cli_unlink(cli1, fname);
3121 correct = False;
3122 goto fail;
3123 } else
3124 printf("third delete on close test succeeded.\n");
3126 /* Test 4 ... */
3127 cli_setatr(cli1, fname, 0, 0);
3128 cli_unlink(cli1, fname);
3130 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3131 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3133 if (fnum1 == -1) {
3134 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3135 correct = False;
3136 goto fail;
3139 /* This should succeed. */
3140 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3141 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3142 if (fnum2 == -1) {
3143 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3144 correct = False;
3145 goto fail;
3148 if (!cli_close(cli1, fnum2)) {
3149 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3150 correct = False;
3151 goto fail;
3154 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3155 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3156 correct = False;
3157 goto fail;
3160 /* This should fail - no more opens once delete on close set. */
3161 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3162 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3163 FILE_OPEN, 0, 0);
3164 if (fnum2 != -1) {
3165 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3166 correct = False;
3167 goto fail;
3168 } else
3169 printf("fourth delete on close test succeeded.\n");
3171 if (!cli_close(cli1, fnum1)) {
3172 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3173 correct = False;
3174 goto fail;
3177 /* Test 5 ... */
3178 cli_setatr(cli1, fname, 0, 0);
3179 cli_unlink(cli1, fname);
3181 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3182 if (fnum1 == -1) {
3183 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3184 correct = False;
3185 goto fail;
3188 /* This should fail - only allowed on NT opens with DELETE access. */
3190 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3191 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3192 correct = False;
3193 goto fail;
3196 if (!cli_close(cli1, fnum1)) {
3197 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3198 correct = False;
3199 goto fail;
3202 printf("fifth delete on close test succeeded.\n");
3204 /* Test 6 ... */
3205 cli_setatr(cli1, fname, 0, 0);
3206 cli_unlink(cli1, fname);
3208 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3209 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3210 FILE_OVERWRITE_IF, 0, 0);
3212 if (fnum1 == -1) {
3213 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3214 correct = False;
3215 goto fail;
3218 /* This should fail - only allowed on NT opens with DELETE access. */
3220 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3221 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3222 correct = False;
3223 goto fail;
3226 if (!cli_close(cli1, fnum1)) {
3227 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3228 correct = False;
3229 goto fail;
3232 printf("sixth delete on close test succeeded.\n");
3234 /* Test 7 ... */
3235 cli_setatr(cli1, fname, 0, 0);
3236 cli_unlink(cli1, fname);
3238 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3239 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3241 if (fnum1 == -1) {
3242 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3243 correct = False;
3244 goto fail;
3247 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3248 printf("[7] setting delete_on_close on file failed !\n");
3249 correct = False;
3250 goto fail;
3253 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3254 printf("[7] unsetting delete_on_close on file failed !\n");
3255 correct = False;
3256 goto fail;
3259 if (!cli_close(cli1, fnum1)) {
3260 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3261 correct = False;
3262 goto fail;
3265 /* This next open should succeed - we reset the flag. */
3267 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3268 if (fnum1 == -1) {
3269 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3270 correct = False;
3271 goto fail;
3274 if (!cli_close(cli1, fnum1)) {
3275 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3276 correct = False;
3277 goto fail;
3280 printf("seventh delete on close test succeeded.\n");
3282 /* Test 7 ... */
3283 cli_setatr(cli1, fname, 0, 0);
3284 cli_unlink(cli1, fname);
3286 if (!torture_open_connection(&cli2, 1)) {
3287 printf("[8] failed to open second connection.\n");
3288 correct = False;
3289 goto fail;
3292 cli_sockopt(cli1, sockops);
3294 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3295 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3296 FILE_OVERWRITE_IF, 0, 0);
3298 if (fnum1 == -1) {
3299 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3300 correct = False;
3301 goto fail;
3304 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3305 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3306 FILE_OPEN, 0, 0);
3308 if (fnum2 == -1) {
3309 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3310 correct = False;
3311 goto fail;
3314 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3315 printf("[8] setting delete_on_close on file failed !\n");
3316 correct = False;
3317 goto fail;
3320 if (!cli_close(cli1, fnum1)) {
3321 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3322 correct = False;
3323 goto fail;
3326 if (!cli_close(cli2, fnum2)) {
3327 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3328 correct = False;
3329 goto fail;
3332 /* This should fail.. */
3333 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3334 if (fnum1 != -1) {
3335 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3336 goto fail;
3337 correct = False;
3338 } else
3339 printf("eighth delete on close test succeeded.\n");
3341 /* This should fail - we need to set DELETE_ACCESS. */
3342 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3343 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3345 if (fnum1 != -1) {
3346 printf("[9] open of %s succeeded should have failed!\n", fname);
3347 correct = False;
3348 goto fail;
3351 printf("ninth delete on close test succeeded.\n");
3353 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3354 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3355 if (fnum1 == -1) {
3356 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3357 correct = False;
3358 goto fail;
3361 /* This should delete the file. */
3362 if (!cli_close(cli1, fnum1)) {
3363 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3364 correct = False;
3365 goto fail;
3368 /* This should fail.. */
3369 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3370 if (fnum1 != -1) {
3371 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3372 goto fail;
3373 correct = False;
3374 } else
3375 printf("tenth delete on close test succeeded.\n");
3377 cli_setatr(cli1, fname, 0, 0);
3378 cli_unlink(cli1, fname);
3380 /* What error do we get when attempting to open a read-only file with
3381 delete access ? */
3383 /* Create a readonly file. */
3384 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3385 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3386 if (fnum1 == -1) {
3387 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3388 correct = False;
3389 goto fail;
3392 if (!cli_close(cli1, fnum1)) {
3393 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3394 correct = False;
3395 goto fail;
3398 /* Now try open for delete access. */
3399 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3400 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3401 FILE_OVERWRITE_IF, 0, 0);
3403 if (fnum1 != -1) {
3404 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3405 cli_close(cli1, fnum1);
3406 goto fail;
3407 correct = False;
3408 } else {
3409 NTSTATUS nterr = cli_nt_error(cli1);
3410 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3411 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3412 goto fail;
3413 correct = False;
3414 } else {
3415 printf("eleventh delete on close test succeeded.\n");
3419 printf("finished delete test\n");
3421 fail:
3422 /* FIXME: This will crash if we aborted before cli2 got
3423 * intialized, because these functions don't handle
3424 * uninitialized connections. */
3426 if (fnum1 != -1) cli_close(cli1, fnum1);
3427 if (fnum2 != -1) cli_close(cli1, fnum2);
3428 cli_setatr(cli1, fname, 0, 0);
3429 cli_unlink(cli1, fname);
3431 if (cli1 && !torture_close_connection(cli1)) {
3432 correct = False;
3434 if (cli2 && !torture_close_connection(cli2)) {
3435 correct = False;
3437 return correct;
3442 print out server properties
3444 static bool run_properties(int dummy)
3446 static struct cli_state *cli;
3447 bool correct = True;
3449 printf("starting properties test\n");
3451 ZERO_STRUCT(cli);
3453 if (!torture_open_connection(&cli, 0)) {
3454 return False;
3457 cli_sockopt(cli, sockops);
3459 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3461 if (!torture_close_connection(cli)) {
3462 correct = False;
3465 return correct;
3470 /* FIRST_DESIRED_ACCESS 0xf019f */
3471 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3472 FILE_READ_EA| /* 0xf */ \
3473 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3474 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3475 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3476 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3477 /* SECOND_DESIRED_ACCESS 0xe0080 */
3478 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3479 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3480 WRITE_OWNER_ACCESS /* 0xe0000 */
3482 #if 0
3483 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3484 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3485 FILE_READ_DATA|\
3486 WRITE_OWNER_ACCESS /* */
3487 #endif
3490 Test ntcreate calls made by xcopy
3492 static bool run_xcopy(int dummy)
3494 static struct cli_state *cli1;
3495 const char *fname = "\\test.txt";
3496 bool correct = True;
3497 int fnum1, fnum2;
3499 printf("starting xcopy test\n");
3501 if (!torture_open_connection(&cli1, 0)) {
3502 return False;
3505 fnum1 = cli_nt_create_full(cli1, fname, 0,
3506 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3507 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3508 0x4044, 0);
3510 if (fnum1 == -1) {
3511 printf("First open failed - %s\n", cli_errstr(cli1));
3512 return False;
3515 fnum2 = cli_nt_create_full(cli1, fname, 0,
3516 SECOND_DESIRED_ACCESS, 0,
3517 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3518 0x200000, 0);
3519 if (fnum2 == -1) {
3520 printf("second open failed - %s\n", cli_errstr(cli1));
3521 return False;
3524 if (!torture_close_connection(cli1)) {
3525 correct = False;
3528 return correct;
3532 Test rename on files open with share delete and no share delete.
3534 static bool run_rename(int dummy)
3536 static struct cli_state *cli1;
3537 const char *fname = "\\test.txt";
3538 const char *fname1 = "\\test1.txt";
3539 bool correct = True;
3540 int fnum1;
3542 printf("starting rename test\n");
3544 if (!torture_open_connection(&cli1, 0)) {
3545 return False;
3548 cli_unlink(cli1, fname);
3549 cli_unlink(cli1, fname1);
3550 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3551 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3553 if (fnum1 == -1) {
3554 printf("First open failed - %s\n", cli_errstr(cli1));
3555 return False;
3558 if (!cli_rename(cli1, fname, fname1)) {
3559 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3560 } else {
3561 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3562 correct = False;
3565 if (!cli_close(cli1, fnum1)) {
3566 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3567 return False;
3570 cli_unlink(cli1, fname);
3571 cli_unlink(cli1, fname1);
3572 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3573 #if 0
3574 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3575 #else
3576 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3577 #endif
3579 if (fnum1 == -1) {
3580 printf("Second open failed - %s\n", cli_errstr(cli1));
3581 return False;
3584 if (!cli_rename(cli1, fname, fname1)) {
3585 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3586 correct = False;
3587 } else {
3588 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3591 if (!cli_close(cli1, fnum1)) {
3592 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3593 return False;
3596 cli_unlink(cli1, fname);
3597 cli_unlink(cli1, fname1);
3599 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3600 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3602 if (fnum1 == -1) {
3603 printf("Third open failed - %s\n", cli_errstr(cli1));
3604 return False;
3608 #if 0
3610 int fnum2;
3612 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3613 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3615 if (fnum2 == -1) {
3616 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3617 return False;
3619 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3620 printf("[8] setting delete_on_close on file failed !\n");
3621 return False;
3624 if (!cli_close(cli1, fnum2)) {
3625 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3626 return False;
3629 #endif
3631 if (!cli_rename(cli1, fname, fname1)) {
3632 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3633 correct = False;
3634 } else {
3635 printf("Third rename succeeded (SHARE_NONE)\n");
3638 if (!cli_close(cli1, fnum1)) {
3639 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3640 return False;
3643 cli_unlink(cli1, fname);
3644 cli_unlink(cli1, fname1);
3646 /*----*/
3648 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3649 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3651 if (fnum1 == -1) {
3652 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3653 return False;
3656 if (!cli_rename(cli1, fname, fname1)) {
3657 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3658 } else {
3659 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3660 correct = False;
3663 if (!cli_close(cli1, fnum1)) {
3664 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3665 return False;
3668 cli_unlink(cli1, fname);
3669 cli_unlink(cli1, fname1);
3671 /*--*/
3673 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3674 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3676 if (fnum1 == -1) {
3677 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3678 return False;
3681 if (!cli_rename(cli1, fname, fname1)) {
3682 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3683 cli_errstr(cli1));
3684 correct = False;
3685 } else {
3686 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3690 * Now check if the first name still exists ...
3693 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3694 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3696 if (fnum2 == -1) {
3697 printf("Opening original file after rename of open file fails: %s\n",
3698 cli_errstr(cli1));
3700 else {
3701 printf("Opening original file after rename of open file works ...\n");
3702 (void)cli_close(cli1, fnum2);
3703 } */
3705 /*--*/
3708 if (!cli_close(cli1, fnum1)) {
3709 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3710 return False;
3713 cli_unlink(cli1, fname);
3714 cli_unlink(cli1, fname1);
3716 if (!torture_close_connection(cli1)) {
3717 correct = False;
3720 return correct;
3723 static bool run_pipe_number(int dummy)
3725 struct cli_state *cli1;
3726 const char *pipe_name = "\\SPOOLSS";
3727 int fnum;
3728 int num_pipes = 0;
3730 printf("starting pipenumber test\n");
3731 if (!torture_open_connection(&cli1, 0)) {
3732 return False;
3735 cli_sockopt(cli1, sockops);
3736 while(1) {
3737 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3738 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3740 if (fnum == -1) {
3741 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3742 break;
3744 num_pipes++;
3745 printf("\r%6d", num_pipes);
3748 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3749 torture_close_connection(cli1);
3750 return True;
3754 Test open mode returns on read-only files.
3756 static bool run_opentest(int dummy)
3758 static struct cli_state *cli1;
3759 static struct cli_state *cli2;
3760 const char *fname = "\\readonly.file";
3761 int fnum1, fnum2;
3762 char buf[20];
3763 SMB_OFF_T fsize;
3764 bool correct = True;
3765 char *tmp_path;
3767 printf("starting open test\n");
3769 if (!torture_open_connection(&cli1, 0)) {
3770 return False;
3773 cli_setatr(cli1, fname, 0, 0);
3774 cli_unlink(cli1, fname);
3776 cli_sockopt(cli1, sockops);
3778 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3779 if (fnum1 == -1) {
3780 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3781 return False;
3784 if (!cli_close(cli1, fnum1)) {
3785 printf("close2 failed (%s)\n", cli_errstr(cli1));
3786 return False;
3789 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3790 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3791 return False;
3794 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3795 if (fnum1 == -1) {
3796 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3797 return False;
3800 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3801 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3803 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3804 NT_STATUS_ACCESS_DENIED)) {
3805 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3808 printf("finished open test 1\n");
3810 cli_close(cli1, fnum1);
3812 /* Now try not readonly and ensure ERRbadshare is returned. */
3814 cli_setatr(cli1, fname, 0, 0);
3816 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3817 if (fnum1 == -1) {
3818 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3819 return False;
3822 /* This will fail - but the error should be ERRshare. */
3823 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3825 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3826 NT_STATUS_SHARING_VIOLATION)) {
3827 printf("correct error code ERRDOS/ERRbadshare returned\n");
3830 if (!cli_close(cli1, fnum1)) {
3831 printf("close2 failed (%s)\n", cli_errstr(cli1));
3832 return False;
3835 cli_unlink(cli1, fname);
3837 printf("finished open test 2\n");
3839 /* Test truncate open disposition on file opened for read. */
3841 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3842 if (fnum1 == -1) {
3843 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3844 return False;
3847 /* write 20 bytes. */
3849 memset(buf, '\0', 20);
3851 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3852 printf("write failed (%s)\n", cli_errstr(cli1));
3853 correct = False;
3856 if (!cli_close(cli1, fnum1)) {
3857 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3858 return False;
3861 /* Ensure size == 20. */
3862 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3863 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3864 return False;
3867 if (fsize != 20) {
3868 printf("(3) file size != 20\n");
3869 return False;
3872 /* Now test if we can truncate a file opened for readonly. */
3874 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3875 if (fnum1 == -1) {
3876 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3877 return False;
3880 if (!cli_close(cli1, fnum1)) {
3881 printf("close2 failed (%s)\n", cli_errstr(cli1));
3882 return False;
3885 /* Ensure size == 0. */
3886 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3887 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3888 return False;
3891 if (fsize != 0) {
3892 printf("(3) file size != 0\n");
3893 return False;
3895 printf("finished open test 3\n");
3897 cli_unlink(cli1, fname);
3900 printf("testing ctemp\n");
3901 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3902 if (fnum1 == -1) {
3903 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3904 return False;
3906 printf("ctemp gave path %s\n", tmp_path);
3907 if (!cli_close(cli1, fnum1)) {
3908 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3910 if (!cli_unlink(cli1, tmp_path)) {
3911 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3914 /* Test the non-io opens... */
3916 if (!torture_open_connection(&cli2, 1)) {
3917 return False;
3920 cli_setatr(cli2, fname, 0, 0);
3921 cli_unlink(cli2, fname);
3923 cli_sockopt(cli2, sockops);
3925 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3927 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3928 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3930 if (fnum1 == -1) {
3931 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3932 return False;
3935 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3938 if (fnum2 == -1) {
3939 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3940 return False;
3943 if (!cli_close(cli1, fnum1)) {
3944 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3945 return False;
3947 if (!cli_close(cli2, fnum2)) {
3948 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3949 return False;
3952 printf("non-io open test #1 passed.\n");
3954 cli_unlink(cli1, fname);
3956 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3958 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3959 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3961 if (fnum1 == -1) {
3962 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3963 return False;
3966 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3967 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3969 if (fnum2 == -1) {
3970 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3971 return False;
3974 if (!cli_close(cli1, fnum1)) {
3975 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3976 return False;
3978 if (!cli_close(cli2, fnum2)) {
3979 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3980 return False;
3983 printf("non-io open test #2 passed.\n");
3985 cli_unlink(cli1, fname);
3987 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3989 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3990 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3992 if (fnum1 == -1) {
3993 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3994 return False;
3997 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3998 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4000 if (fnum2 == -1) {
4001 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4002 return False;
4005 if (!cli_close(cli1, fnum1)) {
4006 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4007 return False;
4009 if (!cli_close(cli2, fnum2)) {
4010 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4011 return False;
4014 printf("non-io open test #3 passed.\n");
4016 cli_unlink(cli1, fname);
4018 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4020 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4021 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4023 if (fnum1 == -1) {
4024 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4025 return False;
4028 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4029 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4031 if (fnum2 != -1) {
4032 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4033 return False;
4036 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4038 if (!cli_close(cli1, fnum1)) {
4039 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4040 return False;
4043 printf("non-io open test #4 passed.\n");
4045 cli_unlink(cli1, fname);
4047 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4049 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4050 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4052 if (fnum1 == -1) {
4053 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4054 return False;
4057 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4058 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4060 if (fnum2 == -1) {
4061 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4062 return False;
4065 if (!cli_close(cli1, fnum1)) {
4066 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4067 return False;
4070 if (!cli_close(cli2, fnum2)) {
4071 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4072 return False;
4075 printf("non-io open test #5 passed.\n");
4077 printf("TEST #6 testing 1 non-io open, one io open\n");
4079 cli_unlink(cli1, fname);
4081 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4082 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4084 if (fnum1 == -1) {
4085 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4086 return False;
4089 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4090 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4092 if (fnum2 == -1) {
4093 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4094 return False;
4097 if (!cli_close(cli1, fnum1)) {
4098 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4099 return False;
4102 if (!cli_close(cli2, fnum2)) {
4103 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4104 return False;
4107 printf("non-io open test #6 passed.\n");
4109 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4111 cli_unlink(cli1, fname);
4113 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4114 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4116 if (fnum1 == -1) {
4117 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4118 return False;
4121 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4122 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4124 if (fnum2 != -1) {
4125 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4126 return False;
4129 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4131 if (!cli_close(cli1, fnum1)) {
4132 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4133 return False;
4136 printf("non-io open test #7 passed.\n");
4138 cli_unlink(cli1, fname);
4140 if (!torture_close_connection(cli1)) {
4141 correct = False;
4143 if (!torture_close_connection(cli2)) {
4144 correct = False;
4147 return correct;
4150 static uint32 open_attrs_table[] = {
4151 FILE_ATTRIBUTE_NORMAL,
4152 FILE_ATTRIBUTE_ARCHIVE,
4153 FILE_ATTRIBUTE_READONLY,
4154 FILE_ATTRIBUTE_HIDDEN,
4155 FILE_ATTRIBUTE_SYSTEM,
4157 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4158 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4161 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4162 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4164 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4165 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4166 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4167 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4170 struct trunc_open_results {
4171 unsigned int num;
4172 uint32 init_attr;
4173 uint32 trunc_attr;
4174 uint32 result_attr;
4177 static struct trunc_open_results attr_results[] = {
4178 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4179 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4180 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4181 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4182 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4183 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4184 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4185 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4186 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4187 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4188 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4189 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4190 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4191 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4192 { 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 },
4193 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4194 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4195 { 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 },
4196 { 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 },
4197 { 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 },
4198 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4199 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4200 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4201 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4202 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4203 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4206 static bool run_openattrtest(int dummy)
4208 static struct cli_state *cli1;
4209 const char *fname = "\\openattr.file";
4210 int fnum1;
4211 bool correct = True;
4212 uint16 attr;
4213 unsigned int i, j, k, l;
4215 printf("starting open attr test\n");
4217 if (!torture_open_connection(&cli1, 0)) {
4218 return False;
4221 cli_sockopt(cli1, sockops);
4223 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4224 cli_setatr(cli1, fname, 0, 0);
4225 cli_unlink(cli1, fname);
4226 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4227 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4229 if (fnum1 == -1) {
4230 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4231 return False;
4234 if (!cli_close(cli1, fnum1)) {
4235 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4236 return False;
4239 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4240 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4241 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4243 if (fnum1 == -1) {
4244 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4245 if (attr_results[l].num == k) {
4246 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4247 k, open_attrs_table[i],
4248 open_attrs_table[j],
4249 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4250 correct = False;
4253 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4254 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4255 k, open_attrs_table[i], open_attrs_table[j],
4256 cli_errstr(cli1));
4257 correct = False;
4259 #if 0
4260 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4261 #endif
4262 k++;
4263 continue;
4266 if (!cli_close(cli1, fnum1)) {
4267 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4268 return False;
4271 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4272 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4273 return False;
4276 #if 0
4277 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4278 k, open_attrs_table[i], open_attrs_table[j], attr );
4279 #endif
4281 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4282 if (attr_results[l].num == k) {
4283 if (attr != attr_results[l].result_attr ||
4284 open_attrs_table[i] != attr_results[l].init_attr ||
4285 open_attrs_table[j] != attr_results[l].trunc_attr) {
4286 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4287 open_attrs_table[i],
4288 open_attrs_table[j],
4289 (unsigned int)attr,
4290 attr_results[l].result_attr);
4291 correct = False;
4293 break;
4296 k++;
4300 cli_setatr(cli1, fname, 0, 0);
4301 cli_unlink(cli1, fname);
4303 printf("open attr test %s.\n", correct ? "passed" : "failed");
4305 if (!torture_close_connection(cli1)) {
4306 correct = False;
4308 return correct;
4311 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4317 test directory listing speed
4319 static bool run_dirtest(int dummy)
4321 int i;
4322 static struct cli_state *cli;
4323 int fnum;
4324 double t1;
4325 bool correct = True;
4327 printf("starting directory test\n");
4329 if (!torture_open_connection(&cli, 0)) {
4330 return False;
4333 cli_sockopt(cli, sockops);
4335 srandom(0);
4336 for (i=0;i<torture_numops;i++) {
4337 fstring fname;
4338 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4339 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4340 if (fnum == -1) {
4341 fprintf(stderr,"Failed to open %s\n", fname);
4342 return False;
4344 cli_close(cli, fnum);
4347 t1 = end_timer();
4349 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4350 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4351 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4353 printf("dirtest core %g seconds\n", end_timer() - t1);
4355 srandom(0);
4356 for (i=0;i<torture_numops;i++) {
4357 fstring fname;
4358 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4359 cli_unlink(cli, fname);
4362 if (!torture_close_connection(cli)) {
4363 correct = False;
4366 printf("finished dirtest\n");
4368 return correct;
4371 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4373 struct cli_state *pcli = (struct cli_state *)state;
4374 fstring fname;
4375 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4377 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4378 return;
4380 if (finfo->mode & aDIR) {
4381 if (!cli_rmdir(pcli, fname))
4382 printf("del_fn: failed to rmdir %s\n,", fname );
4383 } else {
4384 if (!cli_unlink(pcli, fname))
4385 printf("del_fn: failed to unlink %s\n,", fname );
4391 sees what IOCTLs are supported
4393 bool torture_ioctl_test(int dummy)
4395 static struct cli_state *cli;
4396 uint16 device, function;
4397 int fnum;
4398 const char *fname = "\\ioctl.dat";
4399 DATA_BLOB blob;
4400 NTSTATUS status;
4402 if (!torture_open_connection(&cli, 0)) {
4403 return False;
4406 printf("starting ioctl test\n");
4408 cli_unlink(cli, fname);
4410 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4411 if (fnum == -1) {
4412 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4413 return False;
4416 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4417 printf("ioctl device info: %s\n", cli_errstr(cli));
4419 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4420 printf("ioctl job info: %s\n", cli_errstr(cli));
4422 for (device=0;device<0x100;device++) {
4423 printf("testing device=0x%x\n", device);
4424 for (function=0;function<0x100;function++) {
4425 uint32 code = (device<<16) | function;
4427 status = cli_raw_ioctl(cli, fnum, code, &blob);
4429 if (NT_STATUS_IS_OK(status)) {
4430 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4431 (int)blob.length);
4432 data_blob_free(&blob);
4437 if (!torture_close_connection(cli)) {
4438 return False;
4441 return True;
4446 tries varients of chkpath
4448 bool torture_chkpath_test(int dummy)
4450 static struct cli_state *cli;
4451 int fnum;
4452 bool ret;
4454 if (!torture_open_connection(&cli, 0)) {
4455 return False;
4458 printf("starting chkpath test\n");
4460 /* cleanup from an old run */
4461 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4462 cli_unlink(cli, "\\chkpath.dir\\*");
4463 cli_rmdir(cli, "\\chkpath.dir");
4465 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4466 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4467 return False;
4470 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4471 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4472 return False;
4475 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4476 if (fnum == -1) {
4477 printf("open1 failed (%s)\n", cli_errstr(cli));
4478 return False;
4480 cli_close(cli, fnum);
4482 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4483 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4484 ret = False;
4487 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4488 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4489 ret = False;
4492 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4493 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4494 NT_STATUS_NOT_A_DIRECTORY);
4495 } else {
4496 printf("* chkpath on a file should fail\n");
4497 ret = False;
4500 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4501 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4502 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4503 } else {
4504 printf("* chkpath on a non existant file should fail\n");
4505 ret = False;
4508 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4509 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4510 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4511 } else {
4512 printf("* chkpath on a non existent component should fail\n");
4513 ret = False;
4516 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4517 cli_unlink(cli, "\\chkpath.dir\\*");
4518 cli_rmdir(cli, "\\chkpath.dir");
4520 if (!torture_close_connection(cli)) {
4521 return False;
4524 return ret;
4527 static bool run_eatest(int dummy)
4529 static struct cli_state *cli;
4530 const char *fname = "\\eatest.txt";
4531 bool correct = True;
4532 int fnum, i;
4533 size_t num_eas;
4534 struct ea_struct *ea_list = NULL;
4535 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4537 printf("starting eatest\n");
4539 if (!torture_open_connection(&cli, 0)) {
4540 talloc_destroy(mem_ctx);
4541 return False;
4544 cli_unlink(cli, fname);
4545 fnum = cli_nt_create_full(cli, fname, 0,
4546 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4547 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4548 0x4044, 0);
4550 if (fnum == -1) {
4551 printf("open failed - %s\n", cli_errstr(cli));
4552 talloc_destroy(mem_ctx);
4553 return False;
4556 for (i = 0; i < 10; i++) {
4557 fstring ea_name, ea_val;
4559 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4560 memset(ea_val, (char)i+1, i+1);
4561 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4562 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4563 talloc_destroy(mem_ctx);
4564 return False;
4568 cli_close(cli, fnum);
4569 for (i = 0; i < 10; i++) {
4570 fstring ea_name, ea_val;
4572 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4573 memset(ea_val, (char)i+1, i+1);
4574 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4575 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4576 talloc_destroy(mem_ctx);
4577 return False;
4581 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4582 printf("ea_get list failed - %s\n", cli_errstr(cli));
4583 correct = False;
4586 printf("num_eas = %d\n", (int)num_eas);
4588 if (num_eas != 20) {
4589 printf("Should be 20 EA's stored... failing.\n");
4590 correct = False;
4593 for (i = 0; i < num_eas; i++) {
4594 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4595 dump_data(0, ea_list[i].value.data,
4596 ea_list[i].value.length);
4599 /* Setting EA's to zero length deletes them. Test this */
4600 printf("Now deleting all EA's - case indepenent....\n");
4602 #if 1
4603 cli_set_ea_path(cli, fname, "", "", 0);
4604 #else
4605 for (i = 0; i < 20; i++) {
4606 fstring ea_name;
4607 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4608 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4609 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4610 talloc_destroy(mem_ctx);
4611 return False;
4614 #endif
4616 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4617 printf("ea_get list failed - %s\n", cli_errstr(cli));
4618 correct = False;
4621 printf("num_eas = %d\n", (int)num_eas);
4622 for (i = 0; i < num_eas; i++) {
4623 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4624 dump_data(0, ea_list[i].value.data,
4625 ea_list[i].value.length);
4628 if (num_eas != 0) {
4629 printf("deleting EA's failed.\n");
4630 correct = False;
4633 /* Try and delete a non existant EA. */
4634 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4635 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4636 correct = False;
4639 talloc_destroy(mem_ctx);
4640 if (!torture_close_connection(cli)) {
4641 correct = False;
4644 return correct;
4647 static bool run_dirtest1(int dummy)
4649 int i;
4650 static struct cli_state *cli;
4651 int fnum, num_seen;
4652 bool correct = True;
4654 printf("starting directory test\n");
4656 if (!torture_open_connection(&cli, 0)) {
4657 return False;
4660 cli_sockopt(cli, sockops);
4662 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4663 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4664 cli_rmdir(cli, "\\LISTDIR");
4665 cli_mkdir(cli, "\\LISTDIR");
4667 /* Create 1000 files and 1000 directories. */
4668 for (i=0;i<1000;i++) {
4669 fstring fname;
4670 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4671 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4672 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4673 if (fnum == -1) {
4674 fprintf(stderr,"Failed to open %s\n", fname);
4675 return False;
4677 cli_close(cli, fnum);
4679 for (i=0;i<1000;i++) {
4680 fstring fname;
4681 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4682 if (!cli_mkdir(cli, fname)) {
4683 fprintf(stderr,"Failed to open %s\n", fname);
4684 return False;
4688 /* Now ensure that doing an old list sees both files and directories. */
4689 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4690 printf("num_seen = %d\n", num_seen );
4691 /* We should see 100 files + 1000 directories + . and .. */
4692 if (num_seen != 2002)
4693 correct = False;
4695 /* Ensure if we have the "must have" bits we only see the
4696 * relevent entries.
4698 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4699 printf("num_seen = %d\n", num_seen );
4700 if (num_seen != 1002)
4701 correct = False;
4703 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4704 printf("num_seen = %d\n", num_seen );
4705 if (num_seen != 1000)
4706 correct = False;
4708 /* Delete everything. */
4709 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4710 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4711 cli_rmdir(cli, "\\LISTDIR");
4713 #if 0
4714 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4715 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4716 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4717 #endif
4719 if (!torture_close_connection(cli)) {
4720 correct = False;
4723 printf("finished dirtest1\n");
4725 return correct;
4728 static bool run_error_map_extract(int dummy) {
4730 static struct cli_state *c_dos;
4731 static struct cli_state *c_nt;
4732 NTSTATUS status;
4734 uint32 error;
4736 uint32 flgs2, errnum;
4737 uint8 errclass;
4739 NTSTATUS nt_status;
4741 fstring user;
4743 /* NT-Error connection */
4745 if (!(c_nt = open_nbt_connection())) {
4746 return False;
4749 c_nt->use_spnego = False;
4751 status = cli_negprot(c_nt);
4753 if (!NT_STATUS_IS_OK(status)) {
4754 printf("%s rejected the NT-error negprot (%s)\n", host,
4755 nt_errstr(status));
4756 cli_shutdown(c_nt);
4757 return False;
4760 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4761 workgroup))) {
4762 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4763 return False;
4766 /* DOS-Error connection */
4768 if (!(c_dos = open_nbt_connection())) {
4769 return False;
4772 c_dos->use_spnego = False;
4773 c_dos->force_dos_errors = True;
4775 status = cli_negprot(c_dos);
4776 if (!NT_STATUS_IS_OK(status)) {
4777 printf("%s rejected the DOS-error negprot (%s)\n", host,
4778 nt_errstr(status));
4779 cli_shutdown(c_dos);
4780 return False;
4783 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4784 workgroup))) {
4785 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4786 return False;
4789 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4790 fstr_sprintf(user, "%X", error);
4792 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4793 password, strlen(password),
4794 password, strlen(password),
4795 workgroup))) {
4796 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4799 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4801 /* Case #1: 32-bit NT errors */
4802 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4803 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4804 } else {
4805 printf("/** Dos error on NT connection! (%s) */\n",
4806 cli_errstr(c_nt));
4807 nt_status = NT_STATUS(0xc0000000);
4810 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4811 password, strlen(password),
4812 password, strlen(password),
4813 workgroup))) {
4814 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4816 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4818 /* Case #1: 32-bit NT errors */
4819 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4820 printf("/** NT error on DOS connection! (%s) */\n",
4821 cli_errstr(c_nt));
4822 errnum = errclass = 0;
4823 } else {
4824 cli_dos_error(c_dos, &errclass, &errnum);
4827 if (NT_STATUS_V(nt_status) != error) {
4828 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4829 get_nt_error_c_code(NT_STATUS(error)),
4830 get_nt_error_c_code(nt_status));
4833 printf("\t{%s,\t%s,\t%s},\n",
4834 smb_dos_err_class(errclass),
4835 smb_dos_err_name(errclass, errnum),
4836 get_nt_error_c_code(NT_STATUS(error)));
4838 return True;
4841 static bool run_sesssetup_bench(int dummy)
4843 static struct cli_state *c;
4844 const char *fname = "\\file.dat";
4845 int fnum;
4846 NTSTATUS status;
4847 int i;
4849 if (!torture_open_connection(&c, 0)) {
4850 return false;
4853 fnum = cli_nt_create_full(
4854 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4855 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4856 FILE_DELETE_ON_CLOSE, 0);
4857 if (fnum == -1) {
4858 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4859 return false;
4862 for (i=0; i<torture_numops; i++) {
4863 status = cli_session_setup(
4864 c, username,
4865 password, strlen(password),
4866 password, strlen(password),
4867 workgroup);
4868 if (!NT_STATUS_IS_OK(status)) {
4869 d_printf("(%s) cli_session_setup failed: %s\n",
4870 __location__, nt_errstr(status));
4871 return false;
4874 d_printf("\r%d ", (int)c->vuid);
4876 if (!cli_ulogoff(c)) {
4877 d_printf("(%s) cli_ulogoff failed: %s\n",
4878 __location__, cli_errstr(c));
4879 return false;
4881 c->vuid = 0;
4884 return true;
4887 static bool subst_test(const char *str, const char *user, const char *domain,
4888 uid_t uid, gid_t gid, const char *expected)
4890 char *subst;
4891 bool result = true;
4893 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
4895 if (strcmp(subst, expected) != 0) {
4896 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
4897 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
4898 expected);
4899 result = false;
4902 TALLOC_FREE(subst);
4903 return result;
4906 static void chain1_open_completion(struct async_req *req)
4908 int fnum;
4909 NTSTATUS status;
4911 status = cli_open_recv(req, &fnum);
4912 TALLOC_FREE(req);
4914 d_printf("cli_open_recv returned %s: %d\n",
4915 nt_errstr(status),
4916 NT_STATUS_IS_OK(status) ? fnum : -1);
4919 static void chain1_read_completion(struct async_req *req)
4921 NTSTATUS status;
4922 ssize_t received;
4923 uint8_t *rcvbuf;
4925 status = cli_read_andx_recv(req, &received, &rcvbuf);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 TALLOC_FREE(req);
4928 d_printf("cli_read_andx_recv returned %s\n",
4929 nt_errstr(status));
4930 return;
4933 d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
4934 (char *)rcvbuf);
4935 TALLOC_FREE(req);
4938 static void chain1_write_completion(struct async_req *req)
4940 NTSTATUS status;
4941 size_t written;
4943 status = cli_write_andx_recv(req, &written);
4944 if (!NT_STATUS_IS_OK(status)) {
4945 TALLOC_FREE(req);
4946 d_printf("cli_write_andx_recv returned %s\n",
4947 nt_errstr(status));
4948 return;
4951 d_printf("wrote %d bytes\n", (int)written);
4952 TALLOC_FREE(req);
4955 static void chain1_close_completion(struct async_req *req)
4957 NTSTATUS status;
4959 status = cli_close_recv(req);
4960 *((bool *)(req->async.priv)) = true;
4962 TALLOC_FREE(req);
4964 d_printf("cli_close returned %s\n", nt_errstr(status));
4967 static bool run_chain1(int dummy)
4969 struct cli_state *cli1;
4970 struct event_context *evt = event_context_init(NULL);
4971 struct async_req *reqs[4];
4972 bool done = false;
4973 const char *text = "hallo";
4975 printf("starting chain1 test\n");
4976 if (!torture_open_connection(&cli1, 0)) {
4977 return False;
4980 cli_sockopt(cli1, sockops);
4982 cli_chain_cork(cli1, evt, 0);
4983 reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
4984 O_CREAT|O_RDWR, 0);
4985 reqs[0]->async.fn = chain1_open_completion;
4986 reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
4987 (uint8_t *)text, 0, strlen(text));
4988 reqs[1]->async.fn = chain1_write_completion;
4989 reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
4990 reqs[2]->async.fn = chain1_read_completion;
4991 reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
4992 reqs[3]->async.fn = chain1_close_completion;
4993 reqs[3]->async.priv = (void *)&done;
4994 cli_chain_uncork(cli1);
4996 while (!done) {
4997 event_loop_once(evt);
5000 torture_close_connection(cli1);
5001 return True;
5004 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5006 size_t *to_pull = (size_t *)priv;
5007 size_t thistime = *to_pull;
5009 thistime = MIN(thistime, n);
5010 if (thistime == 0) {
5011 return 0;
5014 memset(buf, 0, thistime);
5015 *to_pull -= thistime;
5016 return thistime;
5019 static bool run_windows_write(int dummy)
5021 struct cli_state *cli1;
5022 int fnum;
5023 int i;
5024 bool ret = false;
5025 const char *fname = "\\writetest.txt";
5026 double seconds;
5027 double kbytes;
5029 printf("starting windows_write test\n");
5030 if (!torture_open_connection(&cli1, 0)) {
5031 return False;
5034 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5035 if (fnum == -1) {
5036 printf("open failed (%s)\n", cli_errstr(cli1));
5037 return False;
5040 cli_sockopt(cli1, sockops);
5042 start_timer();
5044 for (i=0; i<torture_numops; i++) {
5045 char c = 0;
5046 off_t start = i * torture_blocksize;
5047 NTSTATUS status;
5048 size_t to_pull = torture_blocksize - 1;
5050 if (cli_write(cli1, fnum, 0, &c,
5051 start + torture_blocksize - 1, 1) != 1) {
5052 printf("cli_write failed: %s\n", cli_errstr(cli1));
5053 goto fail;
5056 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5057 null_source, &to_pull);
5058 if (!NT_STATUS_IS_OK(status)) {
5059 printf("cli_push returned: %s\n", nt_errstr(status));
5060 goto fail;
5064 seconds = end_timer();
5065 kbytes = (double)torture_blocksize * torture_numops;
5066 kbytes /= 1024;
5068 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5069 (double)seconds, (int)(kbytes/seconds));
5071 ret = true;
5072 fail:
5073 cli_close(cli1, fnum);
5074 cli_unlink(cli1, fname);
5075 torture_close_connection(cli1);
5076 return ret;
5079 static bool run_cli_echo(int dummy)
5081 struct cli_state *cli;
5082 struct event_context *ev = event_context_init(NULL);
5083 struct async_req *req;
5084 NTSTATUS status;
5086 printf("starting chain1 test\n");
5087 if (!torture_open_connection(&cli, 0)) {
5088 return false;
5090 cli_sockopt(cli, sockops);
5092 req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5093 if (req == NULL) {
5094 d_printf("cli_echo_send failed\n");
5095 return false;
5098 while (req->state < ASYNC_REQ_DONE) {
5099 event_loop_once(ev);
5102 status = cli_echo_recv(req);
5103 d_printf("cli_echo returned %s\n", nt_errstr(status));
5105 TALLOC_FREE(req);
5107 torture_close_connection(cli);
5108 return NT_STATUS_IS_OK(status);
5111 static bool run_local_substitute(int dummy)
5113 bool ok = true;
5115 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5116 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5117 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5118 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5119 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5120 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5121 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5122 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5124 /* Different captialization rules in sub_basic... */
5126 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5127 "blaDOM") == 0);
5129 return ok;
5132 static bool run_local_gencache(int dummy)
5134 char *val;
5135 time_t tm;
5136 DATA_BLOB blob;
5138 if (!gencache_init()) {
5139 d_printf("%s: gencache_init() failed\n", __location__);
5140 return False;
5143 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5144 d_printf("%s: gencache_set() failed\n", __location__);
5145 return False;
5148 if (!gencache_get("foo", &val, &tm)) {
5149 d_printf("%s: gencache_get() failed\n", __location__);
5150 return False;
5153 if (strcmp(val, "bar") != 0) {
5154 d_printf("%s: gencache_get() returned %s, expected %s\n",
5155 __location__, val, "bar");
5156 SAFE_FREE(val);
5157 return False;
5160 SAFE_FREE(val);
5162 if (!gencache_del("foo")) {
5163 d_printf("%s: gencache_del() failed\n", __location__);
5164 return False;
5166 if (gencache_del("foo")) {
5167 d_printf("%s: second gencache_del() succeeded\n",
5168 __location__);
5169 return False;
5172 if (gencache_get("foo", &val, &tm)) {
5173 d_printf("%s: gencache_get() on deleted entry "
5174 "succeeded\n", __location__);
5175 return False;
5178 blob = data_blob_string_const_null("bar");
5179 tm = time(NULL);
5181 if (!gencache_set_data_blob("foo", &blob, tm)) {
5182 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5183 return False;
5186 data_blob_free(&blob);
5188 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5189 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5190 return False;
5193 if (strcmp((const char *)blob.data, "bar") != 0) {
5194 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5195 __location__, (const char *)blob.data, "bar");
5196 data_blob_free(&blob);
5197 return False;
5200 data_blob_free(&blob);
5202 if (!gencache_del("foo")) {
5203 d_printf("%s: gencache_del() failed\n", __location__);
5204 return False;
5206 if (gencache_del("foo")) {
5207 d_printf("%s: second gencache_del() succeeded\n",
5208 __location__);
5209 return False;
5212 if (gencache_get_data_blob("foo", &blob, NULL)) {
5213 d_printf("%s: gencache_get_data_blob() on deleted entry "
5214 "succeeded\n", __location__);
5215 return False;
5218 if (!gencache_shutdown()) {
5219 d_printf("%s: gencache_shutdown() failed\n", __location__);
5220 return False;
5223 if (gencache_shutdown()) {
5224 d_printf("%s: second gencache_shutdown() succeeded\n",
5225 __location__);
5226 return False;
5229 return True;
5232 static bool rbt_testval(struct db_context *db, const char *key,
5233 const char *value)
5235 struct db_record *rec;
5236 TDB_DATA data = string_tdb_data(value);
5237 bool ret = false;
5238 NTSTATUS status;
5240 rec = db->fetch_locked(db, db, string_tdb_data(key));
5241 if (rec == NULL) {
5242 d_fprintf(stderr, "fetch_locked failed\n");
5243 goto done;
5245 status = rec->store(rec, data, 0);
5246 if (!NT_STATUS_IS_OK(status)) {
5247 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5248 goto done;
5250 TALLOC_FREE(rec);
5252 rec = db->fetch_locked(db, db, string_tdb_data(key));
5253 if (rec == NULL) {
5254 d_fprintf(stderr, "second fetch_locked failed\n");
5255 goto done;
5257 if ((rec->value.dsize != data.dsize)
5258 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5259 d_fprintf(stderr, "Got wrong data back\n");
5260 goto done;
5263 ret = true;
5264 done:
5265 TALLOC_FREE(rec);
5266 return ret;
5269 static bool run_local_rbtree(int dummy)
5271 struct db_context *db;
5272 bool ret = false;
5273 int i;
5275 db = db_open_rbt(NULL);
5277 if (db == NULL) {
5278 d_fprintf(stderr, "db_open_rbt failed\n");
5279 return false;
5282 for (i=0; i<1000; i++) {
5283 char *key, *value;
5285 if (asprintf(&key, "key%ld", random()) == -1) {
5286 goto done;
5288 if (asprintf(&value, "value%ld", random()) == -1) {
5289 SAFE_FREE(key);
5290 goto done;
5293 if (!rbt_testval(db, key, value)) {
5294 SAFE_FREE(key);
5295 SAFE_FREE(value);
5296 goto done;
5299 SAFE_FREE(value);
5300 if (asprintf(&value, "value%ld", random()) == -1) {
5301 SAFE_FREE(key);
5302 goto done;
5305 if (!rbt_testval(db, key, value)) {
5306 SAFE_FREE(key);
5307 SAFE_FREE(value);
5308 goto done;
5311 SAFE_FREE(key);
5312 SAFE_FREE(value);
5315 ret = true;
5317 done:
5318 TALLOC_FREE(db);
5319 return ret;
5322 static bool test_stream_name(const char *fname, const char *expected_base,
5323 const char *expected_stream,
5324 NTSTATUS expected_status)
5326 NTSTATUS status;
5327 char *base = NULL;
5328 char *stream = NULL;
5330 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5331 if (!NT_STATUS_EQUAL(status, expected_status)) {
5332 goto error;
5335 if (!NT_STATUS_IS_OK(status)) {
5336 return true;
5339 if (base == NULL) goto error;
5341 if (strcmp(expected_base, base) != 0) goto error;
5343 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5344 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5346 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5347 goto error;
5349 TALLOC_FREE(base);
5350 TALLOC_FREE(stream);
5351 return true;
5353 error:
5354 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5355 fname, expected_base ? expected_base : "<NULL>",
5356 expected_stream ? expected_stream : "<NULL>",
5357 nt_errstr(expected_status));
5358 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5359 base ? base : "<NULL>", stream ? stream : "<NULL>",
5360 nt_errstr(status));
5361 TALLOC_FREE(base);
5362 TALLOC_FREE(stream);
5363 return false;
5366 static bool run_local_stream_name(int dummy)
5368 bool ret = true;
5370 ret &= test_stream_name(
5371 "bla", "bla", NULL, NT_STATUS_OK);
5372 ret &= test_stream_name(
5373 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5374 ret &= test_stream_name(
5375 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5376 ret &= test_stream_name(
5377 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5378 ret &= test_stream_name(
5379 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5380 ret &= test_stream_name(
5381 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5382 ret &= test_stream_name(
5383 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5384 ret &= test_stream_name(
5385 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5387 return ret;
5390 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5392 if (a.length != b.length) {
5393 printf("a.length=%d != b.length=%d\n",
5394 (int)a.length, (int)b.length);
5395 return false;
5397 if (memcmp(a.data, b.data, a.length) != 0) {
5398 printf("a.data and b.data differ\n");
5399 return false;
5401 return true;
5404 static bool run_local_memcache(int dummy)
5406 struct memcache *cache;
5407 DATA_BLOB k1, k2;
5408 DATA_BLOB d1, d2, d3;
5409 DATA_BLOB v1, v2, v3;
5411 TALLOC_CTX *mem_ctx;
5412 char *str1, *str2;
5413 size_t size1, size2;
5414 bool ret = false;
5416 cache = memcache_init(NULL, 100);
5418 if (cache == NULL) {
5419 printf("memcache_init failed\n");
5420 return false;
5423 d1 = data_blob_const("d1", 2);
5424 d2 = data_blob_const("d2", 2);
5425 d3 = data_blob_const("d3", 2);
5427 k1 = data_blob_const("d1", 2);
5428 k2 = data_blob_const("d2", 2);
5430 memcache_add(cache, STAT_CACHE, k1, d1);
5431 memcache_add(cache, GETWD_CACHE, k2, d2);
5433 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5434 printf("could not find k1\n");
5435 return false;
5437 if (!data_blob_equal(d1, v1)) {
5438 return false;
5441 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5442 printf("could not find k2\n");
5443 return false;
5445 if (!data_blob_equal(d2, v2)) {
5446 return false;
5449 memcache_add(cache, STAT_CACHE, k1, d3);
5451 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5452 printf("could not find replaced k1\n");
5453 return false;
5455 if (!data_blob_equal(d3, v3)) {
5456 return false;
5459 memcache_add(cache, GETWD_CACHE, k1, d1);
5461 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5462 printf("Did find k2, should have been purged\n");
5463 return false;
5466 TALLOC_FREE(cache);
5468 cache = memcache_init(NULL, 0);
5470 mem_ctx = talloc_init("foo");
5472 str1 = talloc_strdup(mem_ctx, "string1");
5473 str2 = talloc_strdup(mem_ctx, "string2");
5475 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5476 data_blob_string_const("torture"), &str1);
5477 size1 = talloc_total_size(cache);
5479 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5480 data_blob_string_const("torture"), &str2);
5481 size2 = talloc_total_size(cache);
5483 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5485 if (size2 > size1) {
5486 printf("memcache leaks memory!\n");
5487 goto fail;
5490 ret = true;
5491 fail:
5492 TALLOC_FREE(cache);
5493 return ret;
5496 static void wbclient_done(struct async_req *req)
5498 NTSTATUS status;
5499 struct winbindd_response *wb_resp;
5500 int *i = (int *)req->async.priv;
5502 status = wb_trans_recv(req, req, &wb_resp);
5503 TALLOC_FREE(req);
5504 *i += 1;
5505 d_printf("wb_trans_recv %d returned %s\n", *i, nt_errstr(status));
5508 static bool run_local_wbclient(int dummy)
5510 struct event_context *ev;
5511 struct wb_context **wb_ctx;
5512 struct winbindd_request wb_req;
5513 bool result = false;
5514 int i, j;
5516 BlockSignals(True, SIGPIPE);
5518 ev = event_context_init(talloc_tos());
5519 if (ev == NULL) {
5520 goto fail;
5523 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5524 if (wb_ctx == NULL) {
5525 goto fail;
5528 ZERO_STRUCT(wb_req);
5529 wb_req.cmd = WINBINDD_PING;
5531 for (i=0; i<torture_numops; i++) {
5532 wb_ctx[i] = wb_context_init(ev);
5533 if (wb_ctx[i] == NULL) {
5534 goto fail;
5536 for (j=0; j<5; j++) {
5537 struct async_req *req;
5538 req = wb_trans_send(ev, ev, wb_ctx[i],
5539 (j % 2) == 0, &wb_req);
5540 if (req == NULL) {
5541 goto fail;
5543 req->async.fn = wbclient_done;
5544 req->async.priv = &i;
5548 i = 0;
5550 while (i < 5 * torture_numops) {
5551 event_loop_once(ev);
5554 result = true;
5555 fail:
5556 TALLOC_FREE(ev);
5557 return result;
5560 static double create_procs(bool (*fn)(int), bool *result)
5562 int i, status;
5563 volatile pid_t *child_status;
5564 volatile bool *child_status_out;
5565 int synccount;
5566 int tries = 8;
5568 synccount = 0;
5570 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5571 if (!child_status) {
5572 printf("Failed to setup shared memory\n");
5573 return -1;
5576 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5577 if (!child_status_out) {
5578 printf("Failed to setup result status shared memory\n");
5579 return -1;
5582 for (i = 0; i < nprocs; i++) {
5583 child_status[i] = 0;
5584 child_status_out[i] = True;
5587 start_timer();
5589 for (i=0;i<nprocs;i++) {
5590 procnum = i;
5591 if (fork() == 0) {
5592 pid_t mypid = getpid();
5593 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5595 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5597 while (1) {
5598 if (torture_open_connection(&current_cli, i)) break;
5599 if (tries-- == 0) {
5600 printf("pid %d failed to start\n", (int)getpid());
5601 _exit(1);
5603 smb_msleep(10);
5606 child_status[i] = getpid();
5608 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5610 child_status_out[i] = fn(i);
5611 _exit(0);
5615 do {
5616 synccount = 0;
5617 for (i=0;i<nprocs;i++) {
5618 if (child_status[i]) synccount++;
5620 if (synccount == nprocs) break;
5621 smb_msleep(10);
5622 } while (end_timer() < 30);
5624 if (synccount != nprocs) {
5625 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5626 *result = False;
5627 return end_timer();
5630 /* start the client load */
5631 start_timer();
5633 for (i=0;i<nprocs;i++) {
5634 child_status[i] = 0;
5637 printf("%d clients started\n", nprocs);
5639 for (i=0;i<nprocs;i++) {
5640 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5643 printf("\n");
5645 for (i=0;i<nprocs;i++) {
5646 if (!child_status_out[i]) {
5647 *result = False;
5650 return end_timer();
5653 #define FLAG_MULTIPROC 1
5655 static struct {
5656 const char *name;
5657 bool (*fn)(int);
5658 unsigned flags;
5659 } torture_ops[] = {
5660 {"FDPASS", run_fdpasstest, 0},
5661 {"LOCK1", run_locktest1, 0},
5662 {"LOCK2", run_locktest2, 0},
5663 {"LOCK3", run_locktest3, 0},
5664 {"LOCK4", run_locktest4, 0},
5665 {"LOCK5", run_locktest5, 0},
5666 {"LOCK6", run_locktest6, 0},
5667 {"LOCK7", run_locktest7, 0},
5668 {"UNLINK", run_unlinktest, 0},
5669 {"BROWSE", run_browsetest, 0},
5670 {"ATTR", run_attrtest, 0},
5671 {"TRANS2", run_trans2test, 0},
5672 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5673 {"TORTURE",run_torture, FLAG_MULTIPROC},
5674 {"RANDOMIPC", run_randomipc, 0},
5675 {"NEGNOWAIT", run_negprot_nowait, 0},
5676 {"NBENCH", run_nbench, 0},
5677 {"OPLOCK1", run_oplock1, 0},
5678 {"OPLOCK2", run_oplock2, 0},
5679 {"OPLOCK3", run_oplock3, 0},
5680 {"DIR", run_dirtest, 0},
5681 {"DIR1", run_dirtest1, 0},
5682 {"DENY1", torture_denytest1, 0},
5683 {"DENY2", torture_denytest2, 0},
5684 {"TCON", run_tcon_test, 0},
5685 {"TCONDEV", run_tcon_devtype_test, 0},
5686 {"RW1", run_readwritetest, 0},
5687 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5688 {"RW3", run_readwritelarge, 0},
5689 {"OPEN", run_opentest, 0},
5690 #if 1
5691 {"OPENATTR", run_openattrtest, 0},
5692 #endif
5693 {"XCOPY", run_xcopy, 0},
5694 {"RENAME", run_rename, 0},
5695 {"DELETE", run_deletetest, 0},
5696 {"PROPERTIES", run_properties, 0},
5697 {"MANGLE", torture_mangle, 0},
5698 {"W2K", run_w2ktest, 0},
5699 {"TRANS2SCAN", torture_trans2_scan, 0},
5700 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5701 {"UTABLE", torture_utable, 0},
5702 {"CASETABLE", torture_casetable, 0},
5703 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5704 {"PIPE_NUMBER", run_pipe_number, 0},
5705 {"TCON2", run_tcon2_test, 0},
5706 {"IOCTL", torture_ioctl_test, 0},
5707 {"CHKPATH", torture_chkpath_test, 0},
5708 {"FDSESS", run_fdsesstest, 0},
5709 { "EATEST", run_eatest, 0},
5710 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5711 { "CHAIN1", run_chain1, 0},
5712 { "WINDOWS-WRITE", run_windows_write, 0},
5713 { "CLI_ECHO", run_cli_echo, 0},
5714 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5715 { "LOCAL-GENCACHE", run_local_gencache, 0},
5716 { "LOCAL-RBTREE", run_local_rbtree, 0},
5717 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5718 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5719 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5720 {NULL, NULL, 0}};
5724 /****************************************************************************
5725 run a specified test or "ALL"
5726 ****************************************************************************/
5727 static bool run_test(const char *name)
5729 bool ret = True;
5730 bool result = True;
5731 bool found = False;
5732 int i;
5733 double t;
5734 if (strequal(name,"ALL")) {
5735 for (i=0;torture_ops[i].name;i++) {
5736 run_test(torture_ops[i].name);
5738 found = True;
5741 for (i=0;torture_ops[i].name;i++) {
5742 fstr_sprintf(randomfname, "\\XX%x",
5743 (unsigned)random());
5745 if (strequal(name, torture_ops[i].name)) {
5746 found = True;
5747 printf("Running %s\n", name);
5748 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5749 t = create_procs(torture_ops[i].fn, &result);
5750 if (!result) {
5751 ret = False;
5752 printf("TEST %s FAILED!\n", name);
5755 } else {
5756 start_timer();
5757 if (!torture_ops[i].fn(0)) {
5758 ret = False;
5759 printf("TEST %s FAILED!\n", name);
5761 t = end_timer();
5763 printf("%s took %g secs\n\n", name, t);
5767 if (!found) {
5768 printf("Did not find a test named %s\n", name);
5769 ret = False;
5772 return ret;
5776 static void usage(void)
5778 int i;
5780 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5781 printf("Please use samba4 torture.\n\n");
5783 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5785 printf("\t-d debuglevel\n");
5786 printf("\t-U user%%pass\n");
5787 printf("\t-k use kerberos\n");
5788 printf("\t-N numprocs\n");
5789 printf("\t-n my_netbios_name\n");
5790 printf("\t-W workgroup\n");
5791 printf("\t-o num_operations\n");
5792 printf("\t-O socket_options\n");
5793 printf("\t-m maximum protocol\n");
5794 printf("\t-L use oplocks\n");
5795 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5796 printf("\t-A showall\n");
5797 printf("\t-p port\n");
5798 printf("\t-s seed\n");
5799 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5800 printf("\n\n");
5802 printf("tests are:");
5803 for (i=0;torture_ops[i].name;i++) {
5804 printf(" %s", torture_ops[i].name);
5806 printf("\n");
5808 printf("default test is ALL\n");
5810 exit(1);
5813 /****************************************************************************
5814 main program
5815 ****************************************************************************/
5816 int main(int argc,char *argv[])
5818 int opt, i;
5819 char *p;
5820 int gotuser = 0;
5821 int gotpass = 0;
5822 bool correct = True;
5823 TALLOC_CTX *frame = talloc_stackframe();
5824 int seed = time(NULL);
5826 dbf = x_stdout;
5828 #ifdef HAVE_SETBUFFER
5829 setbuffer(stdout, NULL, 0);
5830 #endif
5832 load_case_tables();
5834 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
5835 load_interfaces();
5837 if (argc < 2) {
5838 usage();
5841 for(p = argv[1]; *p; p++)
5842 if(*p == '\\')
5843 *p = '/';
5845 if (strncmp(argv[1], "//", 2)) {
5846 usage();
5849 fstrcpy(host, &argv[1][2]);
5850 p = strchr_m(&host[2],'/');
5851 if (!p) {
5852 usage();
5854 *p = 0;
5855 fstrcpy(share, p+1);
5857 fstrcpy(myname, talloc_get_myname(talloc_tos()));
5858 if (!*myname) {
5859 fprintf(stderr, "Failed to get my hostname.\n");
5860 return 1;
5863 if (*username == 0 && getenv("LOGNAME")) {
5864 fstrcpy(username,getenv("LOGNAME"));
5867 argc--;
5868 argv++;
5870 fstrcpy(workgroup, lp_workgroup());
5872 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
5873 switch (opt) {
5874 case 'p':
5875 port_to_use = atoi(optarg);
5876 break;
5877 case 's':
5878 seed = atoi(optarg);
5879 break;
5880 case 'W':
5881 fstrcpy(workgroup,optarg);
5882 break;
5883 case 'm':
5884 max_protocol = interpret_protocol(optarg, max_protocol);
5885 break;
5886 case 'N':
5887 nprocs = atoi(optarg);
5888 break;
5889 case 'o':
5890 torture_numops = atoi(optarg);
5891 break;
5892 case 'd':
5893 DEBUGLEVEL = atoi(optarg);
5894 break;
5895 case 'O':
5896 sockops = optarg;
5897 break;
5898 case 'L':
5899 use_oplocks = True;
5900 break;
5901 case 'A':
5902 torture_showall = True;
5903 break;
5904 case 'n':
5905 fstrcpy(myname, optarg);
5906 break;
5907 case 'c':
5908 client_txt = optarg;
5909 break;
5910 case 'e':
5911 do_encrypt = true;
5912 break;
5913 case 'k':
5914 #ifdef HAVE_KRB5
5915 use_kerberos = True;
5916 #else
5917 d_printf("No kerberos support compiled in\n");
5918 exit(1);
5919 #endif
5920 break;
5921 case 'U':
5922 gotuser = 1;
5923 fstrcpy(username,optarg);
5924 p = strchr_m(username,'%');
5925 if (p) {
5926 *p = 0;
5927 fstrcpy(password, p+1);
5928 gotpass = 1;
5930 break;
5931 case 'b':
5932 fstrcpy(multishare_conn_fname, optarg);
5933 use_multishare_conn = True;
5934 break;
5935 case 'B':
5936 torture_blocksize = atoi(optarg);
5937 break;
5938 default:
5939 printf("Unknown option %c (%d)\n", (char)opt, opt);
5940 usage();
5944 d_printf("using seed %d\n", seed);
5946 srandom(seed);
5948 if(use_kerberos && !gotuser) gotpass = True;
5950 while (!gotpass) {
5951 p = getpass("Password:");
5952 if (p) {
5953 fstrcpy(password, p);
5954 gotpass = 1;
5958 printf("host=%s share=%s user=%s myname=%s\n",
5959 host, share, username, myname);
5961 if (argc == optind) {
5962 correct = run_test("ALL");
5963 } else {
5964 for (i=optind;i<argc;i++) {
5965 if (!run_test(argv[i])) {
5966 correct = False;
5971 TALLOC_FREE(frame);
5973 if (correct) {
5974 return(0);
5975 } else {
5976 return(1);