VERSION: Set version to 3.4.0pre1.
[Samba/gbeck.git] / source3 / torture / torture.c
blob64dfb5224c8e241928560bf828eb7a4bc0d67d79
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"
21 #include "wbc_async.h"
23 extern char *optarg;
24 extern int optind;
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static const char *sockops="TCP_NODELAY";
29 static int nprocs=1;
30 static int port_to_use=0;
31 int torture_numops=100;
32 int torture_blocksize=1024*1024;
33 static int procnum; /* records process count number when forking */
34 static struct cli_state *current_cli;
35 static fstring randomfname;
36 static bool use_oplocks;
37 static bool use_level_II_oplocks;
38 static const char *client_txt = "client_oplocks.txt";
39 static bool use_kerberos;
40 static fstring multishare_conn_fname;
41 static bool use_multishare_conn = False;
42 static bool do_encrypt;
44 bool torture_showall = False;
46 static double create_procs(bool (*fn)(int), bool *result);
49 static struct timeval tp1,tp2;
52 void start_timer(void)
54 GetTimeOfDay(&tp1);
57 double end_timer(void)
59 GetTimeOfDay(&tp2);
60 return((tp2.tv_sec - tp1.tv_sec) +
61 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
65 /* return a pointer to a anonymous shared memory segment of size "size"
66 which will persist across fork() but will disappear when all processes
67 exit
69 The memory is not zeroed
71 This function uses system5 shared memory. It takes advantage of a property
72 that the memory is not destroyed if it is attached when the id is removed
74 void *shm_setup(int size)
76 int shmid;
77 void *ret;
79 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
80 if (shmid == -1) {
81 printf("can't get shared memory\n");
82 exit(1);
84 ret = (void *)shmat(shmid, 0, 0);
85 if (!ret || ret == (void *)-1) {
86 printf("can't attach to shared memory\n");
87 return NULL;
89 /* the following releases the ipc, but note that this process
90 and all its children will still have access to the memory, its
91 just that the shmid is no longer valid for other shm calls. This
92 means we don't leave behind lots of shm segments after we exit
94 See Stevens "advanced programming in unix env" for details
96 shmctl(shmid, IPC_RMID, 0);
98 return ret;
101 /********************************************************************
102 Ensure a connection is encrypted.
103 ********************************************************************/
105 static bool force_cli_encryption(struct cli_state *c,
106 const char *sharename)
108 uint16 major, minor;
109 uint32 caplow, caphigh;
110 NTSTATUS status;
112 if (!SERVER_HAS_UNIX_CIFS(c)) {
113 d_printf("Encryption required and "
114 "server that doesn't support "
115 "UNIX extensions - failing connect\n");
116 return false;
119 if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
120 d_printf("Encryption required and "
121 "can't get UNIX CIFS extensions "
122 "version from server.\n");
123 return false;
126 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
127 d_printf("Encryption required and "
128 "share %s doesn't support "
129 "encryption.\n", sharename);
130 return false;
133 if (c->use_kerberos) {
134 status = cli_gss_smb_encryption_start(c);
135 } else {
136 status = cli_raw_ntlm_smb_encryption_start(c,
137 username,
138 password,
139 workgroup);
142 if (!NT_STATUS_IS_OK(status)) {
143 d_printf("Encryption required and "
144 "setup failed with error %s.\n",
145 nt_errstr(status));
146 return false;
149 return true;
153 static struct cli_state *open_nbt_connection(void)
155 struct nmb_name called, calling;
156 struct sockaddr_storage ss;
157 struct cli_state *c;
158 NTSTATUS status;
160 make_nmb_name(&calling, myname, 0x0);
161 make_nmb_name(&called , host, 0x20);
163 zero_sockaddr(&ss);
165 if (!(c = cli_initialise())) {
166 printf("Failed initialize cli_struct to connect with %s\n", host);
167 return NULL;
170 c->port = port_to_use;
172 status = cli_connect(c, host, &ss);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
175 return NULL;
178 c->use_kerberos = use_kerberos;
180 c->timeout = 120000; /* set a really long timeout (2 minutes) */
181 if (use_oplocks) c->use_oplocks = True;
182 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
184 if (!cli_session_request(c, &calling, &called)) {
186 * Well, that failed, try *SMBSERVER ...
187 * However, we must reconnect as well ...
189 status = cli_connect(c, host, &ss);
190 if (!NT_STATUS_IS_OK(status)) {
191 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
192 return NULL;
195 make_nmb_name(&called, "*SMBSERVER", 0x20);
196 if (!cli_session_request(c, &calling, &called)) {
197 printf("%s rejected the session\n",host);
198 printf("We tried with a called name of %s & %s\n",
199 host, "*SMBSERVER");
200 cli_shutdown(c);
201 return NULL;
205 return c;
208 /* Insert a NULL at the first separator of the given path and return a pointer
209 * to the remainder of the string.
211 static char *
212 terminate_path_at_separator(char * path)
214 char * p;
216 if (!path) {
217 return NULL;
220 if ((p = strchr_m(path, '/'))) {
221 *p = '\0';
222 return p + 1;
225 if ((p = strchr_m(path, '\\'))) {
226 *p = '\0';
227 return p + 1;
230 /* No separator. */
231 return NULL;
235 parse a //server/share type UNC name
237 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
238 char **hostname, char **sharename)
240 char *p;
242 *hostname = *sharename = NULL;
244 if (strncmp(unc_name, "\\\\", 2) &&
245 strncmp(unc_name, "//", 2)) {
246 return False;
249 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
250 p = terminate_path_at_separator(*hostname);
252 if (p && *p) {
253 *sharename = talloc_strdup(mem_ctx, p);
254 terminate_path_at_separator(*sharename);
257 if (*hostname && *sharename) {
258 return True;
261 TALLOC_FREE(*hostname);
262 TALLOC_FREE(*sharename);
263 return False;
266 static bool torture_open_connection_share(struct cli_state **c,
267 const char *hostname,
268 const char *sharename)
270 bool retry;
271 int flags = 0;
272 NTSTATUS status;
274 if (use_kerberos)
275 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
277 status = cli_full_connection(c, myname,
278 hostname, NULL, port_to_use,
279 sharename, "?????",
280 username, workgroup,
281 password, flags, Undefined, &retry);
282 if (!NT_STATUS_IS_OK(status)) {
283 printf("failed to open share connection: //%s/%s port:%d - %s\n",
284 hostname, sharename, port_to_use, nt_errstr(status));
285 return False;
288 if (use_oplocks) (*c)->use_oplocks = True;
289 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
290 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
292 if (do_encrypt) {
293 return force_cli_encryption(*c,
294 sharename);
296 return True;
299 bool torture_open_connection(struct cli_state **c, int conn_index)
301 char **unc_list = NULL;
302 int num_unc_names = 0;
303 bool result;
305 if (use_multishare_conn==True) {
306 char *h, *s;
307 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
308 if (!unc_list || num_unc_names <= 0) {
309 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
310 exit(1);
313 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
314 NULL, &h, &s)) {
315 printf("Failed to parse UNC name %s\n",
316 unc_list[conn_index % num_unc_names]);
317 TALLOC_FREE(unc_list);
318 exit(1);
321 result = torture_open_connection_share(c, h, s);
323 /* h, s were copied earlier */
324 TALLOC_FREE(unc_list);
325 return result;
328 return torture_open_connection_share(c, host, share);
331 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
333 uint16 old_vuid = cli->vuid;
334 fstring old_user_name;
335 size_t passlen = strlen(password);
336 bool ret;
338 fstrcpy(old_user_name, cli->user_name);
339 cli->vuid = 0;
340 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
341 password, passlen,
342 password, passlen,
343 workgroup));
344 *new_vuid = cli->vuid;
345 cli->vuid = old_vuid;
346 fstrcpy(cli->user_name, old_user_name);
347 return ret;
351 bool torture_close_connection(struct cli_state *c)
353 bool ret = True;
354 if (!cli_tdis(c)) {
355 printf("tdis failed (%s)\n", cli_errstr(c));
356 ret = False;
359 cli_shutdown(c);
361 return ret;
365 /* check if the server produced the expected error code */
366 static bool check_error(int line, struct cli_state *c,
367 uint8 eclass, uint32 ecode, NTSTATUS nterr)
369 if (cli_is_dos_error(c)) {
370 uint8 cclass;
371 uint32 num;
373 /* Check DOS error */
375 cli_dos_error(c, &cclass, &num);
377 if (eclass != cclass || ecode != num) {
378 printf("unexpected error code class=%d code=%d\n",
379 (int)cclass, (int)num);
380 printf(" expected %d/%d %s (line=%d)\n",
381 (int)eclass, (int)ecode, nt_errstr(nterr), line);
382 return False;
385 } else {
386 NTSTATUS status;
388 /* Check NT error */
390 status = cli_nt_error(c);
392 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
393 printf("unexpected error code %s\n", nt_errstr(status));
394 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
395 return False;
399 return True;
403 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
405 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
406 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
408 return True;
412 static bool rw_torture(struct cli_state *c)
414 const char *lockfname = "\\torture.lck";
415 fstring fname;
416 int fnum;
417 int fnum2;
418 pid_t pid2, pid = getpid();
419 int i, j;
420 char buf[1024];
421 bool correct = True;
423 memset(buf, '\0', sizeof(buf));
425 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
426 DENY_NONE);
427 if (fnum2 == -1)
428 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
429 if (fnum2 == -1) {
430 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
431 return False;
435 for (i=0;i<torture_numops;i++) {
436 unsigned n = (unsigned)sys_random()%10;
437 if (i % 10 == 0) {
438 printf("%d\r", i); fflush(stdout);
440 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
442 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
443 return False;
446 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
447 if (fnum == -1) {
448 printf("open failed (%s)\n", cli_errstr(c));
449 correct = False;
450 break;
453 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
454 printf("write failed (%s)\n", cli_errstr(c));
455 correct = False;
458 for (j=0;j<50;j++) {
459 if (cli_write(c, fnum, 0, (char *)buf,
460 sizeof(pid)+(j*sizeof(buf)),
461 sizeof(buf)) != sizeof(buf)) {
462 printf("write failed (%s)\n", cli_errstr(c));
463 correct = False;
467 pid2 = 0;
469 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
470 printf("read failed (%s)\n", cli_errstr(c));
471 correct = False;
474 if (pid2 != pid) {
475 printf("data corruption!\n");
476 correct = False;
479 if (!cli_close(c, fnum)) {
480 printf("close failed (%s)\n", cli_errstr(c));
481 correct = False;
484 if (!cli_unlink(c, fname)) {
485 printf("unlink failed (%s)\n", cli_errstr(c));
486 correct = False;
489 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
490 printf("unlock failed (%s)\n", cli_errstr(c));
491 correct = False;
495 cli_close(c, fnum2);
496 cli_unlink(c, lockfname);
498 printf("%d\n", i);
500 return correct;
503 static bool run_torture(int dummy)
505 struct cli_state *cli;
506 bool ret;
508 cli = current_cli;
510 cli_sockopt(cli, sockops);
512 ret = rw_torture(cli);
514 if (!torture_close_connection(cli)) {
515 ret = False;
518 return ret;
521 static bool rw_torture3(struct cli_state *c, char *lockfname)
523 int fnum = -1;
524 unsigned int i = 0;
525 char buf[131072];
526 char buf_rd[131072];
527 unsigned count;
528 unsigned countprev = 0;
529 ssize_t sent = 0;
530 bool correct = True;
532 srandom(1);
533 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
535 SIVAL(buf, i, sys_random());
538 if (procnum == 0)
540 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
541 DENY_NONE);
542 if (fnum == -1) {
543 printf("first open read/write of %s failed (%s)\n",
544 lockfname, cli_errstr(c));
545 return False;
548 else
550 for (i = 0; i < 500 && fnum == -1; i++)
552 fnum = cli_open(c, lockfname, O_RDONLY,
553 DENY_NONE);
554 smb_msleep(10);
556 if (fnum == -1) {
557 printf("second open read-only of %s failed (%s)\n",
558 lockfname, cli_errstr(c));
559 return False;
563 i = 0;
564 for (count = 0; count < sizeof(buf); count += sent)
566 if (count >= countprev) {
567 printf("%d %8d\r", i, count);
568 fflush(stdout);
569 i++;
570 countprev += (sizeof(buf) / 20);
573 if (procnum == 0)
575 sent = ((unsigned)sys_random()%(20))+ 1;
576 if (sent > sizeof(buf) - count)
578 sent = sizeof(buf) - count;
581 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
582 printf("write failed (%s)\n", cli_errstr(c));
583 correct = False;
586 else
588 sent = cli_read(c, fnum, buf_rd+count, count,
589 sizeof(buf)-count);
590 if (sent < 0)
592 printf("read failed offset:%d size:%ld (%s)\n",
593 count, (unsigned long)sizeof(buf)-count,
594 cli_errstr(c));
595 correct = False;
596 sent = 0;
598 if (sent > 0)
600 if (memcmp(buf_rd+count, buf+count, sent) != 0)
602 printf("read/write compare failed\n");
603 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
604 correct = False;
605 break;
612 if (!cli_close(c, fnum)) {
613 printf("close failed (%s)\n", cli_errstr(c));
614 correct = False;
617 return correct;
620 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
622 const char *lockfname = "\\torture2.lck";
623 int fnum1;
624 int fnum2;
625 int i;
626 char buf[131072];
627 char buf_rd[131072];
628 bool correct = True;
629 ssize_t bytes_read;
631 if (!cli_unlink(c1, lockfname)) {
632 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
635 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
636 DENY_NONE);
637 if (fnum1 == -1) {
638 printf("first open read/write of %s failed (%s)\n",
639 lockfname, cli_errstr(c1));
640 return False;
642 fnum2 = cli_open(c2, lockfname, O_RDONLY,
643 DENY_NONE);
644 if (fnum2 == -1) {
645 printf("second open read-only of %s failed (%s)\n",
646 lockfname, cli_errstr(c2));
647 cli_close(c1, fnum1);
648 return False;
651 for (i=0;i<torture_numops;i++)
653 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
654 if (i % 10 == 0) {
655 printf("%d\r", i); fflush(stdout);
658 generate_random_buffer((unsigned char *)buf, buf_size);
660 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
661 printf("write failed (%s)\n", cli_errstr(c1));
662 correct = False;
663 break;
666 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
667 printf("read failed (%s)\n", cli_errstr(c2));
668 printf("read %d, expected %ld\n", (int)bytes_read,
669 (unsigned long)buf_size);
670 correct = False;
671 break;
674 if (memcmp(buf_rd, buf, buf_size) != 0)
676 printf("read/write compare failed\n");
677 correct = False;
678 break;
682 if (!cli_close(c2, fnum2)) {
683 printf("close failed (%s)\n", cli_errstr(c2));
684 correct = False;
686 if (!cli_close(c1, fnum1)) {
687 printf("close failed (%s)\n", cli_errstr(c1));
688 correct = False;
691 if (!cli_unlink(c1, lockfname)) {
692 printf("unlink failed (%s)\n", cli_errstr(c1));
693 correct = False;
696 return correct;
699 static bool run_readwritetest(int dummy)
701 static struct cli_state *cli1, *cli2;
702 bool test1, test2 = False;
704 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
705 return False;
707 cli_sockopt(cli1, sockops);
708 cli_sockopt(cli2, sockops);
710 printf("starting readwritetest\n");
712 test1 = rw_torture2(cli1, cli2);
713 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
715 if (test1) {
716 test2 = rw_torture2(cli1, cli1);
717 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
720 if (!torture_close_connection(cli1)) {
721 test1 = False;
724 if (!torture_close_connection(cli2)) {
725 test2 = False;
728 return (test1 && test2);
731 static bool run_readwritemulti(int dummy)
733 struct cli_state *cli;
734 bool test;
736 cli = current_cli;
738 cli_sockopt(cli, sockops);
740 printf("run_readwritemulti: fname %s\n", randomfname);
741 test = rw_torture3(cli, randomfname);
743 if (!torture_close_connection(cli)) {
744 test = False;
747 return test;
750 static bool run_readwritelarge(int dummy)
752 static struct cli_state *cli1;
753 int fnum1;
754 const char *lockfname = "\\large.dat";
755 SMB_OFF_T fsize;
756 char buf[126*1024];
757 bool correct = True;
759 if (!torture_open_connection(&cli1, 0)) {
760 return False;
762 cli_sockopt(cli1, sockops);
763 memset(buf,'\0',sizeof(buf));
765 cli1->max_xmit = 128*1024;
767 printf("starting readwritelarge\n");
769 cli_unlink(cli1, lockfname);
771 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
772 if (fnum1 == -1) {
773 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
774 return False;
777 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
779 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
780 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
781 correct = False;
784 if (fsize == sizeof(buf))
785 printf("readwritelarge test 1 succeeded (size = %lx)\n",
786 (unsigned long)fsize);
787 else {
788 printf("readwritelarge test 1 failed (size = %lx)\n",
789 (unsigned long)fsize);
790 correct = False;
793 if (!cli_close(cli1, fnum1)) {
794 printf("close failed (%s)\n", cli_errstr(cli1));
795 correct = False;
798 if (!cli_unlink(cli1, lockfname)) {
799 printf("unlink failed (%s)\n", cli_errstr(cli1));
800 correct = False;
803 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
804 if (fnum1 == -1) {
805 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
806 return False;
809 cli1->max_xmit = 4*1024;
811 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
813 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
814 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
815 correct = False;
818 if (fsize == sizeof(buf))
819 printf("readwritelarge test 2 succeeded (size = %lx)\n",
820 (unsigned long)fsize);
821 else {
822 printf("readwritelarge test 2 failed (size = %lx)\n",
823 (unsigned long)fsize);
824 correct = False;
827 #if 0
828 /* ToDo - set allocation. JRA */
829 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
830 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
831 return False;
833 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
834 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
835 correct = False;
837 if (fsize != 0)
838 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
839 #endif
841 if (!cli_close(cli1, fnum1)) {
842 printf("close failed (%s)\n", cli_errstr(cli1));
843 correct = False;
846 if (!torture_close_connection(cli1)) {
847 correct = False;
849 return correct;
852 int line_count = 0;
853 int nbio_id;
855 #define ival(s) strtol(s, NULL, 0)
857 /* run a test that simulates an approximate netbench client load */
858 static bool run_netbench(int client)
860 struct cli_state *cli;
861 int i;
862 char line[1024];
863 char cname[20];
864 FILE *f;
865 const char *params[20];
866 bool correct = True;
868 cli = current_cli;
870 nbio_id = client;
872 cli_sockopt(cli, sockops);
874 nb_setup(cli);
876 slprintf(cname,sizeof(cname)-1, "client%d", client);
878 f = fopen(client_txt, "r");
880 if (!f) {
881 perror(client_txt);
882 return False;
885 while (fgets(line, sizeof(line)-1, f)) {
886 char *saveptr;
887 line_count++;
889 line[strlen(line)-1] = 0;
891 /* printf("[%d] %s\n", line_count, line); */
893 all_string_sub(line,"client1", cname, sizeof(line));
895 /* parse the command parameters */
896 params[0] = strtok_r(line, " ", &saveptr);
897 i = 0;
898 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
900 params[i] = "";
902 if (i < 2) continue;
904 if (!strncmp(params[0],"SMB", 3)) {
905 printf("ERROR: You are using a dbench 1 load file\n");
906 exit(1);
909 if (!strcmp(params[0],"NTCreateX")) {
910 nb_createx(params[1], ival(params[2]), ival(params[3]),
911 ival(params[4]));
912 } else if (!strcmp(params[0],"Close")) {
913 nb_close(ival(params[1]));
914 } else if (!strcmp(params[0],"Rename")) {
915 nb_rename(params[1], params[2]);
916 } else if (!strcmp(params[0],"Unlink")) {
917 nb_unlink(params[1]);
918 } else if (!strcmp(params[0],"Deltree")) {
919 nb_deltree(params[1]);
920 } else if (!strcmp(params[0],"Rmdir")) {
921 nb_rmdir(params[1]);
922 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
923 nb_qpathinfo(params[1]);
924 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
925 nb_qfileinfo(ival(params[1]));
926 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
927 nb_qfsinfo(ival(params[1]));
928 } else if (!strcmp(params[0],"FIND_FIRST")) {
929 nb_findfirst(params[1]);
930 } else if (!strcmp(params[0],"WriteX")) {
931 nb_writex(ival(params[1]),
932 ival(params[2]), ival(params[3]), ival(params[4]));
933 } else if (!strcmp(params[0],"ReadX")) {
934 nb_readx(ival(params[1]),
935 ival(params[2]), ival(params[3]), ival(params[4]));
936 } else if (!strcmp(params[0],"Flush")) {
937 nb_flush(ival(params[1]));
938 } else {
939 printf("Unknown operation %s\n", params[0]);
940 exit(1);
943 fclose(f);
945 nb_cleanup();
947 if (!torture_close_connection(cli)) {
948 correct = False;
951 return correct;
955 /* run a test that simulates an approximate netbench client load */
956 static bool run_nbench(int dummy)
958 double t;
959 bool correct = True;
961 nbio_shmem(nprocs);
963 nbio_id = -1;
965 signal(SIGALRM, nb_alarm);
966 alarm(1);
967 t = create_procs(run_netbench, &correct);
968 alarm(0);
970 printf("\nThroughput %g MB/sec\n",
971 1.0e-6 * nbio_total() / t);
972 return correct;
977 This test checks for two things:
979 1) correct support for retaining locks over a close (ie. the server
980 must not use posix semantics)
981 2) support for lock timeouts
983 static bool run_locktest1(int dummy)
985 struct cli_state *cli1, *cli2;
986 const char *fname = "\\lockt1.lck";
987 int fnum1, fnum2, fnum3;
988 time_t t1, t2;
989 unsigned lock_timeout;
991 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
992 return False;
994 cli_sockopt(cli1, sockops);
995 cli_sockopt(cli2, sockops);
997 printf("starting locktest1\n");
999 cli_unlink(cli1, fname);
1001 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1002 if (fnum1 == -1) {
1003 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1004 return False;
1006 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1007 if (fnum2 == -1) {
1008 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1009 return False;
1011 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1012 if (fnum3 == -1) {
1013 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1014 return False;
1017 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1018 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1019 return False;
1023 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1024 printf("lock2 succeeded! This is a locking bug\n");
1025 return False;
1026 } else {
1027 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1028 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1032 lock_timeout = (1 + (random() % 20));
1033 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1034 t1 = time(NULL);
1035 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1036 printf("lock3 succeeded! This is a locking bug\n");
1037 return False;
1038 } else {
1039 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1040 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1042 t2 = time(NULL);
1044 if (ABS(t2 - t1) < lock_timeout-1) {
1045 printf("error: This server appears not to support timed lock requests\n");
1048 printf("server slept for %u seconds for a %u second timeout\n",
1049 (unsigned int)(t2-t1), lock_timeout);
1051 if (!cli_close(cli1, fnum2)) {
1052 printf("close1 failed (%s)\n", cli_errstr(cli1));
1053 return False;
1056 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1057 printf("lock4 succeeded! This is a locking bug\n");
1058 return False;
1059 } else {
1060 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1061 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1064 if (!cli_close(cli1, fnum1)) {
1065 printf("close2 failed (%s)\n", cli_errstr(cli1));
1066 return False;
1069 if (!cli_close(cli2, fnum3)) {
1070 printf("close3 failed (%s)\n", cli_errstr(cli2));
1071 return False;
1074 if (!cli_unlink(cli1, fname)) {
1075 printf("unlink failed (%s)\n", cli_errstr(cli1));
1076 return False;
1080 if (!torture_close_connection(cli1)) {
1081 return False;
1084 if (!torture_close_connection(cli2)) {
1085 return False;
1088 printf("Passed locktest1\n");
1089 return True;
1093 this checks to see if a secondary tconx can use open files from an
1094 earlier tconx
1096 static bool run_tcon_test(int dummy)
1098 static struct cli_state *cli;
1099 const char *fname = "\\tcontest.tmp";
1100 int fnum1;
1101 uint16 cnum1, cnum2, cnum3;
1102 uint16 vuid1, vuid2;
1103 char buf[4];
1104 bool ret = True;
1105 NTSTATUS status;
1107 memset(buf, '\0', sizeof(buf));
1109 if (!torture_open_connection(&cli, 0)) {
1110 return False;
1112 cli_sockopt(cli, sockops);
1114 printf("starting tcontest\n");
1116 cli_unlink(cli, fname);
1118 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1119 if (fnum1 == -1) {
1120 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1121 return False;
1124 cnum1 = cli->cnum;
1125 vuid1 = cli->vuid;
1127 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1128 printf("initial write failed (%s)", cli_errstr(cli));
1129 return False;
1132 status = cli_tcon_andx(cli, share, "?????",
1133 password, strlen(password)+1);
1134 if (!NT_STATUS_IS_OK(status)) {
1135 printf("%s refused 2nd tree connect (%s)\n", host,
1136 nt_errstr(status));
1137 cli_shutdown(cli);
1138 return False;
1141 cnum2 = cli->cnum;
1142 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1143 vuid2 = cli->vuid + 1;
1145 /* try a write with the wrong tid */
1146 cli->cnum = cnum2;
1148 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1149 printf("* server allows write with wrong TID\n");
1150 ret = False;
1151 } else {
1152 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1156 /* try a write with an invalid tid */
1157 cli->cnum = cnum3;
1159 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1160 printf("* server allows write with invalid TID\n");
1161 ret = False;
1162 } else {
1163 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1166 /* try a write with an invalid vuid */
1167 cli->vuid = vuid2;
1168 cli->cnum = cnum1;
1170 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1171 printf("* server allows write with invalid VUID\n");
1172 ret = False;
1173 } else {
1174 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1177 cli->cnum = cnum1;
1178 cli->vuid = vuid1;
1180 if (!cli_close(cli, fnum1)) {
1181 printf("close failed (%s)\n", cli_errstr(cli));
1182 return False;
1185 cli->cnum = cnum2;
1187 if (!cli_tdis(cli)) {
1188 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1189 return False;
1192 cli->cnum = cnum1;
1194 if (!torture_close_connection(cli)) {
1195 return False;
1198 return ret;
1203 checks for old style tcon support
1205 static bool run_tcon2_test(int dummy)
1207 static struct cli_state *cli;
1208 uint16 cnum, max_xmit;
1209 char *service;
1210 NTSTATUS status;
1212 if (!torture_open_connection(&cli, 0)) {
1213 return False;
1215 cli_sockopt(cli, sockops);
1217 printf("starting tcon2 test\n");
1219 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1220 return false;
1223 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1225 if (!NT_STATUS_IS_OK(status)) {
1226 printf("tcon2 failed : %s\n", cli_errstr(cli));
1227 } else {
1228 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1229 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1232 if (!torture_close_connection(cli)) {
1233 return False;
1236 printf("Passed tcon2 test\n");
1237 return True;
1240 static bool tcon_devtest(struct cli_state *cli,
1241 const char *myshare, const char *devtype,
1242 const char *return_devtype,
1243 NTSTATUS expected_error)
1245 NTSTATUS status;
1246 bool ret;
1248 status = cli_tcon_andx(cli, myshare, devtype,
1249 password, strlen(password)+1);
1251 if (NT_STATUS_IS_OK(expected_error)) {
1252 if (NT_STATUS_IS_OK(status)) {
1253 if (strcmp(cli->dev, return_devtype) == 0) {
1254 ret = True;
1255 } else {
1256 printf("tconX to share %s with type %s "
1257 "succeeded but returned the wrong "
1258 "device type (got [%s] but should have got [%s])\n",
1259 myshare, devtype, cli->dev, return_devtype);
1260 ret = False;
1262 } else {
1263 printf("tconX to share %s with type %s "
1264 "should have succeeded but failed\n",
1265 myshare, devtype);
1266 ret = False;
1268 cli_tdis(cli);
1269 } else {
1270 if (NT_STATUS_IS_OK(status)) {
1271 printf("tconx to share %s with type %s "
1272 "should have failed but succeeded\n",
1273 myshare, devtype);
1274 ret = False;
1275 } else {
1276 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1277 expected_error)) {
1278 ret = True;
1279 } else {
1280 printf("Returned unexpected error\n");
1281 ret = False;
1285 return ret;
1289 checks for correct tconX support
1291 static bool run_tcon_devtype_test(int dummy)
1293 static struct cli_state *cli1 = NULL;
1294 bool retry;
1295 int flags = 0;
1296 NTSTATUS status;
1297 bool ret = True;
1299 status = cli_full_connection(&cli1, myname,
1300 host, NULL, port_to_use,
1301 NULL, NULL,
1302 username, workgroup,
1303 password, flags, Undefined, &retry);
1305 if (!NT_STATUS_IS_OK(status)) {
1306 printf("could not open connection\n");
1307 return False;
1310 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1311 ret = False;
1313 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1314 ret = False;
1316 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1317 ret = False;
1319 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1320 ret = False;
1322 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1323 ret = False;
1325 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1326 ret = False;
1328 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1329 ret = False;
1331 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332 ret = False;
1334 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1335 ret = False;
1337 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338 ret = False;
1340 cli_shutdown(cli1);
1342 if (ret)
1343 printf("Passed tcondevtest\n");
1345 return ret;
1350 This test checks that
1352 1) the server supports multiple locking contexts on the one SMB
1353 connection, distinguished by PID.
1355 2) the server correctly fails overlapping locks made by the same PID (this
1356 goes against POSIX behaviour, which is why it is tricky to implement)
1358 3) the server denies unlock requests by an incorrect client PID
1360 static bool run_locktest2(int dummy)
1362 static struct cli_state *cli;
1363 const char *fname = "\\lockt2.lck";
1364 int fnum1, fnum2, fnum3;
1365 bool correct = True;
1367 if (!torture_open_connection(&cli, 0)) {
1368 return False;
1371 cli_sockopt(cli, sockops);
1373 printf("starting locktest2\n");
1375 cli_unlink(cli, fname);
1377 cli_setpid(cli, 1);
1379 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1380 if (fnum1 == -1) {
1381 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1382 return False;
1385 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1386 if (fnum2 == -1) {
1387 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1388 return False;
1391 cli_setpid(cli, 2);
1393 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1394 if (fnum3 == -1) {
1395 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1396 return False;
1399 cli_setpid(cli, 1);
1401 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1402 printf("lock1 failed (%s)\n", cli_errstr(cli));
1403 return False;
1406 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1407 printf("WRITE lock1 succeeded! This is a locking bug\n");
1408 correct = False;
1409 } else {
1410 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1411 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1414 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1415 printf("WRITE lock2 succeeded! This is a locking bug\n");
1416 correct = False;
1417 } else {
1418 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1419 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1422 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1423 printf("READ lock2 succeeded! This is a locking bug\n");
1424 correct = False;
1425 } else {
1426 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1427 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1430 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1431 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1433 cli_setpid(cli, 2);
1434 if (cli_unlock(cli, fnum1, 100, 4)) {
1435 printf("unlock at 100 succeeded! This is a locking bug\n");
1436 correct = False;
1439 if (cli_unlock(cli, fnum1, 0, 4)) {
1440 printf("unlock1 succeeded! This is a locking bug\n");
1441 correct = False;
1442 } else {
1443 if (!check_error(__LINE__, cli,
1444 ERRDOS, ERRlock,
1445 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1448 if (cli_unlock(cli, fnum1, 0, 8)) {
1449 printf("unlock2 succeeded! This is a locking bug\n");
1450 correct = False;
1451 } else {
1452 if (!check_error(__LINE__, cli,
1453 ERRDOS, ERRlock,
1454 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1457 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1458 printf("lock3 succeeded! This is a locking bug\n");
1459 correct = False;
1460 } else {
1461 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1464 cli_setpid(cli, 1);
1466 if (!cli_close(cli, fnum1)) {
1467 printf("close1 failed (%s)\n", cli_errstr(cli));
1468 return False;
1471 if (!cli_close(cli, fnum2)) {
1472 printf("close2 failed (%s)\n", cli_errstr(cli));
1473 return False;
1476 if (!cli_close(cli, fnum3)) {
1477 printf("close3 failed (%s)\n", cli_errstr(cli));
1478 return False;
1481 if (!torture_close_connection(cli)) {
1482 correct = False;
1485 printf("locktest2 finished\n");
1487 return correct;
1492 This test checks that
1494 1) the server supports the full offset range in lock requests
1496 static bool run_locktest3(int dummy)
1498 static struct cli_state *cli1, *cli2;
1499 const char *fname = "\\lockt3.lck";
1500 int fnum1, fnum2, i;
1501 uint32 offset;
1502 bool correct = True;
1504 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1506 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1507 return False;
1509 cli_sockopt(cli1, sockops);
1510 cli_sockopt(cli2, sockops);
1512 printf("starting locktest3\n");
1514 cli_unlink(cli1, fname);
1516 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1517 if (fnum1 == -1) {
1518 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1519 return False;
1521 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1522 if (fnum2 == -1) {
1523 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1524 return False;
1527 for (offset=i=0;i<torture_numops;i++) {
1528 NEXT_OFFSET;
1529 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1530 printf("lock1 %d failed (%s)\n",
1532 cli_errstr(cli1));
1533 return False;
1536 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1537 printf("lock2 %d failed (%s)\n",
1539 cli_errstr(cli1));
1540 return False;
1544 for (offset=i=0;i<torture_numops;i++) {
1545 NEXT_OFFSET;
1547 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1548 printf("error: lock1 %d succeeded!\n", i);
1549 return False;
1552 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1553 printf("error: lock2 %d succeeded!\n", i);
1554 return False;
1557 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1558 printf("error: lock3 %d succeeded!\n", i);
1559 return False;
1562 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1563 printf("error: lock4 %d succeeded!\n", i);
1564 return False;
1568 for (offset=i=0;i<torture_numops;i++) {
1569 NEXT_OFFSET;
1571 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1572 printf("unlock1 %d failed (%s)\n",
1574 cli_errstr(cli1));
1575 return False;
1578 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1579 printf("unlock2 %d failed (%s)\n",
1581 cli_errstr(cli1));
1582 return False;
1586 if (!cli_close(cli1, fnum1)) {
1587 printf("close1 failed (%s)\n", cli_errstr(cli1));
1588 return False;
1591 if (!cli_close(cli2, fnum2)) {
1592 printf("close2 failed (%s)\n", cli_errstr(cli2));
1593 return False;
1596 if (!cli_unlink(cli1, fname)) {
1597 printf("unlink failed (%s)\n", cli_errstr(cli1));
1598 return False;
1601 if (!torture_close_connection(cli1)) {
1602 correct = False;
1605 if (!torture_close_connection(cli2)) {
1606 correct = False;
1609 printf("finished locktest3\n");
1611 return correct;
1614 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1615 printf("** "); correct = False; \
1619 looks at overlapping locks
1621 static bool run_locktest4(int dummy)
1623 static struct cli_state *cli1, *cli2;
1624 const char *fname = "\\lockt4.lck";
1625 int fnum1, fnum2, f;
1626 bool ret;
1627 char buf[1000];
1628 bool correct = True;
1630 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1631 return False;
1634 cli_sockopt(cli1, sockops);
1635 cli_sockopt(cli2, sockops);
1637 printf("starting locktest4\n");
1639 cli_unlink(cli1, fname);
1641 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1642 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1644 memset(buf, 0, sizeof(buf));
1646 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1647 printf("Failed to create file\n");
1648 correct = False;
1649 goto fail;
1652 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1653 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1654 EXPECTED(ret, False);
1655 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1657 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1658 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1659 EXPECTED(ret, True);
1660 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1662 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1663 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1664 EXPECTED(ret, False);
1665 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1667 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1668 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1669 EXPECTED(ret, True);
1670 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1672 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1673 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1674 EXPECTED(ret, False);
1675 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1677 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1678 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1679 EXPECTED(ret, True);
1680 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1682 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1683 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1684 EXPECTED(ret, True);
1685 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1687 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1688 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1689 EXPECTED(ret, False);
1690 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1692 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1693 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1694 EXPECTED(ret, False);
1695 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1697 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1698 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1699 EXPECTED(ret, True);
1700 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1702 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1703 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1704 EXPECTED(ret, False);
1705 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1707 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1708 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1709 cli_unlock(cli1, fnum1, 110, 6);
1710 EXPECTED(ret, False);
1711 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1714 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1715 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1716 EXPECTED(ret, False);
1717 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1719 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1720 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1721 EXPECTED(ret, False);
1722 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1725 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1726 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1727 cli_unlock(cli1, fnum1, 140, 4) &&
1728 cli_unlock(cli1, fnum1, 140, 4);
1729 EXPECTED(ret, True);
1730 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1733 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1734 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1735 cli_unlock(cli1, fnum1, 150, 4) &&
1736 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1737 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1738 cli_unlock(cli1, fnum1, 150, 4);
1739 EXPECTED(ret, True);
1740 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1742 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1743 cli_unlock(cli1, fnum1, 160, 4) &&
1744 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1745 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1746 EXPECTED(ret, True);
1747 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1749 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1750 cli_unlock(cli1, fnum1, 170, 4) &&
1751 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1752 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1753 EXPECTED(ret, True);
1754 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1756 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1757 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1758 cli_unlock(cli1, fnum1, 190, 4) &&
1759 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1760 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1761 EXPECTED(ret, True);
1762 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1764 cli_close(cli1, fnum1);
1765 cli_close(cli2, fnum2);
1766 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1767 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1768 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1769 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1770 cli_close(cli1, fnum1) &&
1771 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1772 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1773 cli_close(cli1, f);
1774 cli_close(cli1, fnum1);
1775 EXPECTED(ret, True);
1776 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1778 fail:
1779 cli_close(cli1, fnum1);
1780 cli_close(cli2, fnum2);
1781 cli_unlink(cli1, fname);
1782 torture_close_connection(cli1);
1783 torture_close_connection(cli2);
1785 printf("finished locktest4\n");
1786 return correct;
1790 looks at lock upgrade/downgrade.
1792 static bool run_locktest5(int dummy)
1794 static struct cli_state *cli1, *cli2;
1795 const char *fname = "\\lockt5.lck";
1796 int fnum1, fnum2, fnum3;
1797 bool ret;
1798 char buf[1000];
1799 bool correct = True;
1801 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1802 return False;
1805 cli_sockopt(cli1, sockops);
1806 cli_sockopt(cli2, sockops);
1808 printf("starting locktest5\n");
1810 cli_unlink(cli1, fname);
1812 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1813 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1814 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1816 memset(buf, 0, sizeof(buf));
1818 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1819 printf("Failed to create file\n");
1820 correct = False;
1821 goto fail;
1824 /* Check for NT bug... */
1825 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1826 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1827 cli_close(cli1, fnum1);
1828 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1829 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1830 EXPECTED(ret, True);
1831 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1832 cli_close(cli1, fnum1);
1833 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1834 cli_unlock(cli1, fnum3, 0, 1);
1836 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1837 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1838 EXPECTED(ret, True);
1839 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1841 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1842 EXPECTED(ret, False);
1844 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1846 /* Unlock the process 2 lock. */
1847 cli_unlock(cli2, fnum2, 0, 4);
1849 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1850 EXPECTED(ret, False);
1852 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1854 /* Unlock the process 1 fnum3 lock. */
1855 cli_unlock(cli1, fnum3, 0, 4);
1857 /* Stack 2 more locks here. */
1858 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1859 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1861 EXPECTED(ret, True);
1862 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1864 /* Unlock the first process lock, then check this was the WRITE lock that was
1865 removed. */
1867 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1868 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1870 EXPECTED(ret, True);
1871 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1873 /* Unlock the process 2 lock. */
1874 cli_unlock(cli2, fnum2, 0, 4);
1876 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1878 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1879 cli_unlock(cli1, fnum1, 0, 4) &&
1880 cli_unlock(cli1, fnum1, 0, 4);
1882 EXPECTED(ret, True);
1883 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1885 /* Ensure the next unlock fails. */
1886 ret = cli_unlock(cli1, fnum1, 0, 4);
1887 EXPECTED(ret, False);
1888 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1890 /* Ensure connection 2 can get a write lock. */
1891 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1892 EXPECTED(ret, True);
1894 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1897 fail:
1898 cli_close(cli1, fnum1);
1899 cli_close(cli2, fnum2);
1900 cli_unlink(cli1, fname);
1901 if (!torture_close_connection(cli1)) {
1902 correct = False;
1904 if (!torture_close_connection(cli2)) {
1905 correct = False;
1908 printf("finished locktest5\n");
1910 return correct;
1914 tries the unusual lockingX locktype bits
1916 static bool run_locktest6(int dummy)
1918 static struct cli_state *cli;
1919 const char *fname[1] = { "\\lock6.txt" };
1920 int i;
1921 int fnum;
1922 NTSTATUS status;
1924 if (!torture_open_connection(&cli, 0)) {
1925 return False;
1928 cli_sockopt(cli, sockops);
1930 printf("starting locktest6\n");
1932 for (i=0;i<1;i++) {
1933 printf("Testing %s\n", fname[i]);
1935 cli_unlink(cli, fname[i]);
1937 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1938 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1939 cli_close(cli, fnum);
1940 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1942 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1943 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1944 cli_close(cli, fnum);
1945 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1947 cli_unlink(cli, fname[i]);
1950 torture_close_connection(cli);
1952 printf("finished locktest6\n");
1953 return True;
1956 static bool run_locktest7(int dummy)
1958 struct cli_state *cli1;
1959 const char *fname = "\\lockt7.lck";
1960 int fnum1;
1961 char buf[200];
1962 bool correct = False;
1964 if (!torture_open_connection(&cli1, 0)) {
1965 return False;
1968 cli_sockopt(cli1, sockops);
1970 printf("starting locktest7\n");
1972 cli_unlink(cli1, fname);
1974 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1976 memset(buf, 0, sizeof(buf));
1978 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1979 printf("Failed to create file\n");
1980 goto fail;
1983 cli_setpid(cli1, 1);
1985 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1986 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1987 goto fail;
1988 } else {
1989 printf("pid1 successfully locked range 130:4 for READ\n");
1992 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1993 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1994 goto fail;
1995 } else {
1996 printf("pid1 successfully read the range 130:4\n");
1999 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2000 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2001 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2002 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2003 goto fail;
2005 } else {
2006 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2007 goto fail;
2010 cli_setpid(cli1, 2);
2012 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2013 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2014 } else {
2015 printf("pid2 successfully read the range 130:4\n");
2018 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2019 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2020 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2021 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2022 goto fail;
2024 } else {
2025 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2026 goto fail;
2029 cli_setpid(cli1, 1);
2030 cli_unlock(cli1, fnum1, 130, 4);
2032 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2033 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2034 goto fail;
2035 } else {
2036 printf("pid1 successfully locked range 130:4 for WRITE\n");
2039 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2040 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2041 goto fail;
2042 } else {
2043 printf("pid1 successfully read the range 130:4\n");
2046 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2047 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2048 goto fail;
2049 } else {
2050 printf("pid1 successfully wrote to the range 130:4\n");
2053 cli_setpid(cli1, 2);
2055 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2056 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2057 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2058 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2059 goto fail;
2061 } else {
2062 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2063 goto fail;
2066 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2067 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2068 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2069 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2070 goto fail;
2072 } else {
2073 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2074 goto fail;
2077 cli_unlock(cli1, fnum1, 130, 0);
2078 correct = True;
2080 fail:
2081 cli_close(cli1, fnum1);
2082 cli_unlink(cli1, fname);
2083 torture_close_connection(cli1);
2085 printf("finished locktest7\n");
2086 return correct;
2090 test whether fnums and tids open on one VC are available on another (a major
2091 security hole)
2093 static bool run_fdpasstest(int dummy)
2095 struct cli_state *cli1, *cli2;
2096 const char *fname = "\\fdpass.tst";
2097 int fnum1;
2098 char buf[1024];
2100 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2101 return False;
2103 cli_sockopt(cli1, sockops);
2104 cli_sockopt(cli2, sockops);
2106 printf("starting fdpasstest\n");
2108 cli_unlink(cli1, fname);
2110 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2111 if (fnum1 == -1) {
2112 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2113 return False;
2116 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2117 printf("write failed (%s)\n", cli_errstr(cli1));
2118 return False;
2121 cli2->vuid = cli1->vuid;
2122 cli2->cnum = cli1->cnum;
2123 cli2->pid = cli1->pid;
2125 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2126 printf("read succeeded! nasty security hole [%s]\n",
2127 buf);
2128 return False;
2131 cli_close(cli1, fnum1);
2132 cli_unlink(cli1, fname);
2134 torture_close_connection(cli1);
2135 torture_close_connection(cli2);
2137 printf("finished fdpasstest\n");
2138 return True;
2141 static bool run_fdsesstest(int dummy)
2143 struct cli_state *cli;
2144 uint16 new_vuid;
2145 uint16 saved_vuid;
2146 uint16 new_cnum;
2147 uint16 saved_cnum;
2148 const char *fname = "\\fdsess.tst";
2149 const char *fname1 = "\\fdsess1.tst";
2150 int fnum1;
2151 int fnum2;
2152 char buf[1024];
2153 bool ret = True;
2155 if (!torture_open_connection(&cli, 0))
2156 return False;
2157 cli_sockopt(cli, sockops);
2159 if (!torture_cli_session_setup2(cli, &new_vuid))
2160 return False;
2162 saved_cnum = cli->cnum;
2163 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2164 return False;
2165 new_cnum = cli->cnum;
2166 cli->cnum = saved_cnum;
2168 printf("starting fdsesstest\n");
2170 cli_unlink(cli, fname);
2171 cli_unlink(cli, fname1);
2173 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2174 if (fnum1 == -1) {
2175 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2176 return False;
2179 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2180 printf("write failed (%s)\n", cli_errstr(cli));
2181 return False;
2184 saved_vuid = cli->vuid;
2185 cli->vuid = new_vuid;
2187 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2188 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2189 buf);
2190 ret = False;
2192 /* Try to open a file with different vuid, samba cnum. */
2193 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2194 if (fnum2 != -1) {
2195 printf("create with different vuid, same cnum succeeded.\n");
2196 cli_close(cli, fnum2);
2197 cli_unlink(cli, fname1);
2198 } else {
2199 printf("create with different vuid, same cnum failed.\n");
2200 printf("This will cause problems with service clients.\n");
2201 ret = False;
2204 cli->vuid = saved_vuid;
2206 /* Try with same vuid, different cnum. */
2207 cli->cnum = new_cnum;
2209 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2210 printf("read succeeded with different cnum![%s]\n",
2211 buf);
2212 ret = False;
2215 cli->cnum = saved_cnum;
2216 cli_close(cli, fnum1);
2217 cli_unlink(cli, fname);
2219 torture_close_connection(cli);
2221 printf("finished fdsesstest\n");
2222 return ret;
2226 This test checks that
2228 1) the server does not allow an unlink on a file that is open
2230 static bool run_unlinktest(int dummy)
2232 struct cli_state *cli;
2233 const char *fname = "\\unlink.tst";
2234 int fnum;
2235 bool correct = True;
2237 if (!torture_open_connection(&cli, 0)) {
2238 return False;
2241 cli_sockopt(cli, sockops);
2243 printf("starting unlink test\n");
2245 cli_unlink(cli, fname);
2247 cli_setpid(cli, 1);
2249 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2250 if (fnum == -1) {
2251 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2252 return False;
2255 if (cli_unlink(cli, fname)) {
2256 printf("error: server allowed unlink on an open file\n");
2257 correct = False;
2258 } else {
2259 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2260 NT_STATUS_SHARING_VIOLATION);
2263 cli_close(cli, fnum);
2264 cli_unlink(cli, fname);
2266 if (!torture_close_connection(cli)) {
2267 correct = False;
2270 printf("unlink test finished\n");
2272 return correct;
2277 test how many open files this server supports on the one socket
2279 static bool run_maxfidtest(int dummy)
2281 struct cli_state *cli;
2282 const char *ftemplate = "\\maxfid.%d.%d";
2283 fstring fname;
2284 int fnums[0x11000], i;
2285 int retries=4;
2286 bool correct = True;
2288 cli = current_cli;
2290 if (retries <= 0) {
2291 printf("failed to connect\n");
2292 return False;
2295 cli_sockopt(cli, sockops);
2297 for (i=0; i<0x11000; i++) {
2298 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2299 if ((fnums[i] = cli_open(cli, fname,
2300 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2301 -1) {
2302 printf("open of %s failed (%s)\n",
2303 fname, cli_errstr(cli));
2304 printf("maximum fnum is %d\n", i);
2305 break;
2307 printf("%6d\r", i);
2309 printf("%6d\n", i);
2310 i--;
2312 printf("cleaning up\n");
2313 for (;i>=0;i--) {
2314 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2315 cli_close(cli, fnums[i]);
2316 if (!cli_unlink(cli, fname)) {
2317 printf("unlink of %s failed (%s)\n",
2318 fname, cli_errstr(cli));
2319 correct = False;
2321 printf("%6d\r", i);
2323 printf("%6d\n", 0);
2325 printf("maxfid test finished\n");
2326 if (!torture_close_connection(cli)) {
2327 correct = False;
2329 return correct;
2332 /* generate a random buffer */
2333 static void rand_buf(char *buf, int len)
2335 while (len--) {
2336 *buf = (char)sys_random();
2337 buf++;
2341 /* send smb negprot commands, not reading the response */
2342 static bool run_negprot_nowait(int dummy)
2344 int i;
2345 static struct cli_state *cli;
2346 bool correct = True;
2348 printf("starting negprot nowait test\n");
2350 if (!(cli = open_nbt_connection())) {
2351 return False;
2354 for (i=0;i<50000;i++) {
2355 cli_negprot_sendsync(cli);
2358 if (!torture_close_connection(cli)) {
2359 correct = False;
2362 printf("finished negprot nowait test\n");
2364 return correct;
2368 /* send random IPC commands */
2369 static bool run_randomipc(int dummy)
2371 char *rparam = NULL;
2372 char *rdata = NULL;
2373 unsigned int rdrcnt,rprcnt;
2374 char param[1024];
2375 int api, param_len, i;
2376 struct cli_state *cli;
2377 bool correct = True;
2378 int count = 50000;
2380 printf("starting random ipc test\n");
2382 if (!torture_open_connection(&cli, 0)) {
2383 return False;
2386 for (i=0;i<count;i++) {
2387 api = sys_random() % 500;
2388 param_len = (sys_random() % 64);
2390 rand_buf(param, param_len);
2392 SSVAL(param,0,api);
2394 cli_api(cli,
2395 param, param_len, 8,
2396 NULL, 0, BUFFER_SIZE,
2397 &rparam, &rprcnt,
2398 &rdata, &rdrcnt);
2399 if (i % 100 == 0) {
2400 printf("%d/%d\r", i,count);
2403 printf("%d/%d\n", i, count);
2405 if (!torture_close_connection(cli)) {
2406 correct = False;
2409 printf("finished random ipc test\n");
2411 return correct;
2416 static void browse_callback(const char *sname, uint32 stype,
2417 const char *comment, void *state)
2419 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2425 This test checks the browse list code
2428 static bool run_browsetest(int dummy)
2430 static struct cli_state *cli;
2431 bool correct = True;
2433 printf("starting browse test\n");
2435 if (!torture_open_connection(&cli, 0)) {
2436 return False;
2439 printf("domain list:\n");
2440 cli_NetServerEnum(cli, cli->server_domain,
2441 SV_TYPE_DOMAIN_ENUM,
2442 browse_callback, NULL);
2444 printf("machine list:\n");
2445 cli_NetServerEnum(cli, cli->server_domain,
2446 SV_TYPE_ALL,
2447 browse_callback, NULL);
2449 if (!torture_close_connection(cli)) {
2450 correct = False;
2453 printf("browse test finished\n");
2455 return correct;
2461 This checks how the getatr calls works
2463 static bool run_attrtest(int dummy)
2465 struct cli_state *cli;
2466 int fnum;
2467 time_t t, t2;
2468 const char *fname = "\\attrib123456789.tst";
2469 bool correct = True;
2471 printf("starting attrib test\n");
2473 if (!torture_open_connection(&cli, 0)) {
2474 return False;
2477 cli_unlink(cli, fname);
2478 fnum = cli_open(cli, fname,
2479 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2480 cli_close(cli, fnum);
2481 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2482 printf("getatr failed (%s)\n", cli_errstr(cli));
2483 correct = False;
2486 if (abs(t - time(NULL)) > 60*60*24*10) {
2487 printf("ERROR: SMBgetatr bug. time is %s",
2488 ctime(&t));
2489 t = time(NULL);
2490 correct = True;
2493 t2 = t-60*60*24; /* 1 day ago */
2495 if (!cli_setatr(cli, fname, 0, t2)) {
2496 printf("setatr failed (%s)\n", cli_errstr(cli));
2497 correct = True;
2500 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2501 printf("getatr failed (%s)\n", cli_errstr(cli));
2502 correct = True;
2505 if (t != t2) {
2506 printf("ERROR: getatr/setatr bug. times are\n%s",
2507 ctime(&t));
2508 printf("%s", ctime(&t2));
2509 correct = True;
2512 cli_unlink(cli, fname);
2514 if (!torture_close_connection(cli)) {
2515 correct = False;
2518 printf("attrib test finished\n");
2520 return correct;
2525 This checks a couple of trans2 calls
2527 static bool run_trans2test(int dummy)
2529 struct cli_state *cli;
2530 int fnum;
2531 SMB_OFF_T size;
2532 time_t c_time, a_time, m_time;
2533 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2534 const char *fname = "\\trans2.tst";
2535 const char *dname = "\\trans2";
2536 const char *fname2 = "\\trans2\\trans2.tst";
2537 char pname[1024];
2538 bool correct = True;
2540 printf("starting trans2 test\n");
2542 if (!torture_open_connection(&cli, 0)) {
2543 return False;
2546 cli_unlink(cli, fname);
2547 fnum = cli_open(cli, fname,
2548 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2549 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2550 &m_time_ts, NULL)) {
2551 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2552 correct = False;
2555 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2556 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2557 correct = False;
2560 if (strcmp(pname, fname)) {
2561 printf("qfilename gave different name? [%s] [%s]\n",
2562 fname, pname);
2563 correct = False;
2566 cli_close(cli, fnum);
2568 sleep(2);
2570 cli_unlink(cli, fname);
2571 fnum = cli_open(cli, fname,
2572 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2573 if (fnum == -1) {
2574 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2575 return False;
2577 cli_close(cli, fnum);
2579 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2580 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2581 correct = False;
2582 } else {
2583 if (c_time != m_time) {
2584 printf("create time=%s", ctime(&c_time));
2585 printf("modify time=%s", ctime(&m_time));
2586 printf("This system appears to have sticky create times\n");
2588 if (a_time % (60*60) == 0) {
2589 printf("access time=%s", ctime(&a_time));
2590 printf("This system appears to set a midnight access time\n");
2591 correct = False;
2594 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2595 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2596 correct = False;
2601 cli_unlink(cli, fname);
2602 fnum = cli_open(cli, fname,
2603 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2604 cli_close(cli, fnum);
2605 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2606 &m_time_ts, &size, NULL, NULL)) {
2607 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2608 correct = False;
2609 } else {
2610 if (w_time_ts.tv_sec < 60*60*24*2) {
2611 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2612 printf("This system appears to set a initial 0 write time\n");
2613 correct = False;
2617 cli_unlink(cli, fname);
2620 /* check if the server updates the directory modification time
2621 when creating a new file */
2622 if (!cli_mkdir(cli, dname)) {
2623 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2624 correct = False;
2626 sleep(3);
2627 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2628 &m_time_ts, &size, NULL, NULL)) {
2629 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2630 correct = False;
2633 fnum = cli_open(cli, fname2,
2634 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2635 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2636 cli_close(cli, fnum);
2637 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2638 &m_time2_ts, &size, NULL, NULL)) {
2639 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2640 correct = False;
2641 } else {
2642 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2643 == 0) {
2644 printf("This system does not update directory modification times\n");
2645 correct = False;
2648 cli_unlink(cli, fname2);
2649 cli_rmdir(cli, dname);
2651 if (!torture_close_connection(cli)) {
2652 correct = False;
2655 printf("trans2 test finished\n");
2657 return correct;
2661 This checks new W2K calls.
2664 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2666 char *buf = NULL;
2667 uint32 len;
2668 bool correct = True;
2670 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2671 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2672 correct = False;
2673 } else {
2674 printf("qfileinfo: level %d, len = %u\n", level, len);
2675 dump_data(0, (uint8 *)buf, len);
2676 printf("\n");
2678 SAFE_FREE(buf);
2679 return correct;
2682 static bool run_w2ktest(int dummy)
2684 struct cli_state *cli;
2685 int fnum;
2686 const char *fname = "\\w2ktest\\w2k.tst";
2687 int level;
2688 bool correct = True;
2690 printf("starting w2k test\n");
2692 if (!torture_open_connection(&cli, 0)) {
2693 return False;
2696 fnum = cli_open(cli, fname,
2697 O_RDWR | O_CREAT , DENY_NONE);
2699 for (level = 1004; level < 1040; level++) {
2700 new_trans(cli, fnum, level);
2703 cli_close(cli, fnum);
2705 if (!torture_close_connection(cli)) {
2706 correct = False;
2709 printf("w2k test finished\n");
2711 return correct;
2716 this is a harness for some oplock tests
2718 static bool run_oplock1(int dummy)
2720 struct cli_state *cli1;
2721 const char *fname = "\\lockt1.lck";
2722 int fnum1;
2723 bool correct = True;
2725 printf("starting oplock test 1\n");
2727 if (!torture_open_connection(&cli1, 0)) {
2728 return False;
2731 cli_unlink(cli1, fname);
2733 cli_sockopt(cli1, sockops);
2735 cli1->use_oplocks = True;
2737 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2738 if (fnum1 == -1) {
2739 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2740 return False;
2743 cli1->use_oplocks = False;
2745 cli_unlink(cli1, fname);
2746 cli_unlink(cli1, fname);
2748 if (!cli_close(cli1, fnum1)) {
2749 printf("close2 failed (%s)\n", cli_errstr(cli1));
2750 return False;
2753 if (!cli_unlink(cli1, fname)) {
2754 printf("unlink failed (%s)\n", cli_errstr(cli1));
2755 return False;
2758 if (!torture_close_connection(cli1)) {
2759 correct = False;
2762 printf("finished oplock test 1\n");
2764 return correct;
2767 static bool run_oplock2(int dummy)
2769 struct cli_state *cli1, *cli2;
2770 const char *fname = "\\lockt2.lck";
2771 int fnum1, fnum2;
2772 int saved_use_oplocks = use_oplocks;
2773 char buf[4];
2774 bool correct = True;
2775 volatile bool *shared_correct;
2777 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2778 *shared_correct = True;
2780 use_level_II_oplocks = True;
2781 use_oplocks = True;
2783 printf("starting oplock test 2\n");
2785 if (!torture_open_connection(&cli1, 0)) {
2786 use_level_II_oplocks = False;
2787 use_oplocks = saved_use_oplocks;
2788 return False;
2791 cli1->use_oplocks = True;
2792 cli1->use_level_II_oplocks = True;
2794 if (!torture_open_connection(&cli2, 1)) {
2795 use_level_II_oplocks = False;
2796 use_oplocks = saved_use_oplocks;
2797 return False;
2800 cli2->use_oplocks = True;
2801 cli2->use_level_II_oplocks = True;
2803 cli_unlink(cli1, fname);
2805 cli_sockopt(cli1, sockops);
2806 cli_sockopt(cli2, sockops);
2808 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2809 if (fnum1 == -1) {
2810 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2811 return False;
2814 /* Don't need the globals any more. */
2815 use_level_II_oplocks = False;
2816 use_oplocks = saved_use_oplocks;
2818 if (fork() == 0) {
2819 /* Child code */
2820 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2821 if (fnum2 == -1) {
2822 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2823 *shared_correct = False;
2824 exit(0);
2827 sleep(2);
2829 if (!cli_close(cli2, fnum2)) {
2830 printf("close2 failed (%s)\n", cli_errstr(cli1));
2831 *shared_correct = False;
2834 exit(0);
2837 sleep(2);
2839 /* Ensure cli1 processes the break. Empty file should always return 0
2840 * bytes. */
2842 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2843 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2844 correct = False;
2847 /* Should now be at level II. */
2848 /* Test if sending a write locks causes a break to none. */
2850 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2851 printf("lock failed (%s)\n", cli_errstr(cli1));
2852 correct = False;
2855 cli_unlock(cli1, fnum1, 0, 4);
2857 sleep(2);
2859 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2860 printf("lock failed (%s)\n", cli_errstr(cli1));
2861 correct = False;
2864 cli_unlock(cli1, fnum1, 0, 4);
2866 sleep(2);
2868 cli_read(cli1, fnum1, buf, 0, 4);
2870 #if 0
2871 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2872 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2873 correct = False;
2875 #endif
2877 if (!cli_close(cli1, fnum1)) {
2878 printf("close1 failed (%s)\n", cli_errstr(cli1));
2879 correct = False;
2882 sleep(4);
2884 if (!cli_unlink(cli1, fname)) {
2885 printf("unlink failed (%s)\n", cli_errstr(cli1));
2886 correct = False;
2889 if (!torture_close_connection(cli1)) {
2890 correct = False;
2893 if (!*shared_correct) {
2894 correct = False;
2897 printf("finished oplock test 2\n");
2899 return correct;
2902 /* handler for oplock 3 tests */
2903 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2905 printf("got oplock break fnum=%d level=%d\n",
2906 fnum, level);
2907 return cli_oplock_ack(cli, fnum, level);
2910 static bool run_oplock3(int dummy)
2912 struct cli_state *cli;
2913 const char *fname = "\\oplockt3.dat";
2914 int fnum;
2915 char buf[4] = "abcd";
2916 bool correct = True;
2917 volatile bool *shared_correct;
2919 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2920 *shared_correct = True;
2922 printf("starting oplock test 3\n");
2924 if (fork() == 0) {
2925 /* Child code */
2926 use_oplocks = True;
2927 use_level_II_oplocks = True;
2928 if (!torture_open_connection(&cli, 0)) {
2929 *shared_correct = False;
2930 exit(0);
2932 sleep(2);
2933 /* try to trigger a oplock break in parent */
2934 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2935 cli_write(cli, fnum, 0, buf, 0, 4);
2936 exit(0);
2939 /* parent code */
2940 use_oplocks = True;
2941 use_level_II_oplocks = True;
2942 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2943 return False;
2945 cli_oplock_handler(cli, oplock3_handler);
2946 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2947 cli_write(cli, fnum, 0, buf, 0, 4);
2948 cli_close(cli, fnum);
2949 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2950 cli->timeout = 20000;
2951 cli_receive_smb(cli);
2952 printf("finished oplock test 3\n");
2954 return (correct && *shared_correct);
2956 /* What are we looking for here? What's sucess and what's FAILURE? */
2962 Test delete on close semantics.
2964 static bool run_deletetest(int dummy)
2966 struct cli_state *cli1 = NULL;
2967 struct cli_state *cli2 = NULL;
2968 const char *fname = "\\delete.file";
2969 int fnum1 = -1;
2970 int fnum2 = -1;
2971 bool correct = True;
2973 printf("starting delete test\n");
2975 if (!torture_open_connection(&cli1, 0)) {
2976 return False;
2979 cli_sockopt(cli1, sockops);
2981 /* Test 1 - this should delete the file on close. */
2983 cli_setatr(cli1, fname, 0, 0);
2984 cli_unlink(cli1, fname);
2986 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2987 0, FILE_OVERWRITE_IF,
2988 FILE_DELETE_ON_CLOSE, 0);
2990 if (fnum1 == -1) {
2991 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2992 correct = False;
2993 goto fail;
2996 #if 0 /* JRATEST */
2998 uint32 *accinfo = NULL;
2999 uint32 len;
3000 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3001 if (accinfo)
3002 printf("access mode = 0x%lx\n", *accinfo);
3003 SAFE_FREE(accinfo);
3005 #endif
3007 if (!cli_close(cli1, fnum1)) {
3008 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3009 correct = False;
3010 goto fail;
3013 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3014 if (fnum1 != -1) {
3015 printf("[1] open of %s succeeded (should fail)\n", fname);
3016 correct = False;
3017 goto fail;
3020 printf("first delete on close test succeeded.\n");
3022 /* Test 2 - this should delete the file on close. */
3024 cli_setatr(cli1, fname, 0, 0);
3025 cli_unlink(cli1, fname);
3027 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3028 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3029 FILE_OVERWRITE_IF, 0, 0);
3031 if (fnum1 == -1) {
3032 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3033 correct = False;
3034 goto fail;
3037 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3038 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3039 correct = False;
3040 goto fail;
3043 if (!cli_close(cli1, fnum1)) {
3044 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3045 correct = False;
3046 goto fail;
3049 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3050 if (fnum1 != -1) {
3051 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3052 if (!cli_close(cli1, fnum1)) {
3053 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3054 correct = False;
3055 goto fail;
3057 cli_unlink(cli1, fname);
3058 } else
3059 printf("second delete on close test succeeded.\n");
3061 /* Test 3 - ... */
3062 cli_setatr(cli1, fname, 0, 0);
3063 cli_unlink(cli1, fname);
3065 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3066 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3068 if (fnum1 == -1) {
3069 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3070 correct = False;
3071 goto fail;
3074 /* This should fail with a sharing violation - open for delete is only compatible
3075 with SHARE_DELETE. */
3077 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3078 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3080 if (fnum2 != -1) {
3081 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3082 correct = False;
3083 goto fail;
3086 /* This should succeed. */
3088 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3089 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3091 if (fnum2 == -1) {
3092 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3093 correct = False;
3094 goto fail;
3097 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3098 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3099 correct = False;
3100 goto fail;
3103 if (!cli_close(cli1, fnum1)) {
3104 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3105 correct = False;
3106 goto fail;
3109 if (!cli_close(cli1, fnum2)) {
3110 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3111 correct = False;
3112 goto fail;
3115 /* This should fail - file should no longer be there. */
3117 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3118 if (fnum1 != -1) {
3119 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3120 if (!cli_close(cli1, fnum1)) {
3121 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3123 cli_unlink(cli1, fname);
3124 correct = False;
3125 goto fail;
3126 } else
3127 printf("third delete on close test succeeded.\n");
3129 /* Test 4 ... */
3130 cli_setatr(cli1, fname, 0, 0);
3131 cli_unlink(cli1, fname);
3133 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3134 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3136 if (fnum1 == -1) {
3137 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3138 correct = False;
3139 goto fail;
3142 /* This should succeed. */
3143 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3144 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3145 if (fnum2 == -1) {
3146 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3147 correct = False;
3148 goto fail;
3151 if (!cli_close(cli1, fnum2)) {
3152 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3153 correct = False;
3154 goto fail;
3157 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3158 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3159 correct = False;
3160 goto fail;
3163 /* This should fail - no more opens once delete on close set. */
3164 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3165 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3166 FILE_OPEN, 0, 0);
3167 if (fnum2 != -1) {
3168 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3169 correct = False;
3170 goto fail;
3171 } else
3172 printf("fourth delete on close test succeeded.\n");
3174 if (!cli_close(cli1, fnum1)) {
3175 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3176 correct = False;
3177 goto fail;
3180 /* Test 5 ... */
3181 cli_setatr(cli1, fname, 0, 0);
3182 cli_unlink(cli1, fname);
3184 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3185 if (fnum1 == -1) {
3186 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3187 correct = False;
3188 goto fail;
3191 /* This should fail - only allowed on NT opens with DELETE access. */
3193 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3194 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3195 correct = False;
3196 goto fail;
3199 if (!cli_close(cli1, fnum1)) {
3200 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3201 correct = False;
3202 goto fail;
3205 printf("fifth delete on close test succeeded.\n");
3207 /* Test 6 ... */
3208 cli_setatr(cli1, fname, 0, 0);
3209 cli_unlink(cli1, fname);
3211 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3212 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3213 FILE_OVERWRITE_IF, 0, 0);
3215 if (fnum1 == -1) {
3216 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3217 correct = False;
3218 goto fail;
3221 /* This should fail - only allowed on NT opens with DELETE access. */
3223 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3224 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3225 correct = False;
3226 goto fail;
3229 if (!cli_close(cli1, fnum1)) {
3230 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3231 correct = False;
3232 goto fail;
3235 printf("sixth delete on close test succeeded.\n");
3237 /* Test 7 ... */
3238 cli_setatr(cli1, fname, 0, 0);
3239 cli_unlink(cli1, fname);
3241 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3242 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3244 if (fnum1 == -1) {
3245 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3246 correct = False;
3247 goto fail;
3250 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3251 printf("[7] setting delete_on_close on file failed !\n");
3252 correct = False;
3253 goto fail;
3256 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3257 printf("[7] unsetting delete_on_close on file failed !\n");
3258 correct = False;
3259 goto fail;
3262 if (!cli_close(cli1, fnum1)) {
3263 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3264 correct = False;
3265 goto fail;
3268 /* This next open should succeed - we reset the flag. */
3270 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3271 if (fnum1 == -1) {
3272 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3273 correct = False;
3274 goto fail;
3277 if (!cli_close(cli1, fnum1)) {
3278 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3279 correct = False;
3280 goto fail;
3283 printf("seventh delete on close test succeeded.\n");
3285 /* Test 7 ... */
3286 cli_setatr(cli1, fname, 0, 0);
3287 cli_unlink(cli1, fname);
3289 if (!torture_open_connection(&cli2, 1)) {
3290 printf("[8] failed to open second connection.\n");
3291 correct = False;
3292 goto fail;
3295 cli_sockopt(cli1, sockops);
3297 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3298 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3299 FILE_OVERWRITE_IF, 0, 0);
3301 if (fnum1 == -1) {
3302 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3303 correct = False;
3304 goto fail;
3307 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3308 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3309 FILE_OPEN, 0, 0);
3311 if (fnum2 == -1) {
3312 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3313 correct = False;
3314 goto fail;
3317 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3318 printf("[8] setting delete_on_close on file failed !\n");
3319 correct = False;
3320 goto fail;
3323 if (!cli_close(cli1, fnum1)) {
3324 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3325 correct = False;
3326 goto fail;
3329 if (!cli_close(cli2, fnum2)) {
3330 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3331 correct = False;
3332 goto fail;
3335 /* This should fail.. */
3336 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3337 if (fnum1 != -1) {
3338 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3339 goto fail;
3340 correct = False;
3341 } else
3342 printf("eighth delete on close test succeeded.\n");
3344 /* This should fail - we need to set DELETE_ACCESS. */
3345 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3346 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3348 if (fnum1 != -1) {
3349 printf("[9] open of %s succeeded should have failed!\n", fname);
3350 correct = False;
3351 goto fail;
3354 printf("ninth delete on close test succeeded.\n");
3356 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3357 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3358 if (fnum1 == -1) {
3359 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3360 correct = False;
3361 goto fail;
3364 /* This should delete the file. */
3365 if (!cli_close(cli1, fnum1)) {
3366 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3367 correct = False;
3368 goto fail;
3371 /* This should fail.. */
3372 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3373 if (fnum1 != -1) {
3374 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3375 goto fail;
3376 correct = False;
3377 } else
3378 printf("tenth delete on close test succeeded.\n");
3380 cli_setatr(cli1, fname, 0, 0);
3381 cli_unlink(cli1, fname);
3383 /* What error do we get when attempting to open a read-only file with
3384 delete access ? */
3386 /* Create a readonly file. */
3387 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3388 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3389 if (fnum1 == -1) {
3390 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3391 correct = False;
3392 goto fail;
3395 if (!cli_close(cli1, fnum1)) {
3396 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3397 correct = False;
3398 goto fail;
3401 /* Now try open for delete access. */
3402 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3403 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3404 FILE_OVERWRITE_IF, 0, 0);
3406 if (fnum1 != -1) {
3407 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3408 cli_close(cli1, fnum1);
3409 goto fail;
3410 correct = False;
3411 } else {
3412 NTSTATUS nterr = cli_nt_error(cli1);
3413 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3414 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3415 goto fail;
3416 correct = False;
3417 } else {
3418 printf("eleventh delete on close test succeeded.\n");
3422 printf("finished delete test\n");
3424 fail:
3425 /* FIXME: This will crash if we aborted before cli2 got
3426 * intialized, because these functions don't handle
3427 * uninitialized connections. */
3429 if (fnum1 != -1) cli_close(cli1, fnum1);
3430 if (fnum2 != -1) cli_close(cli1, fnum2);
3431 cli_setatr(cli1, fname, 0, 0);
3432 cli_unlink(cli1, fname);
3434 if (cli1 && !torture_close_connection(cli1)) {
3435 correct = False;
3437 if (cli2 && !torture_close_connection(cli2)) {
3438 correct = False;
3440 return correct;
3445 print out server properties
3447 static bool run_properties(int dummy)
3449 static struct cli_state *cli;
3450 bool correct = True;
3452 printf("starting properties test\n");
3454 ZERO_STRUCT(cli);
3456 if (!torture_open_connection(&cli, 0)) {
3457 return False;
3460 cli_sockopt(cli, sockops);
3462 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3464 if (!torture_close_connection(cli)) {
3465 correct = False;
3468 return correct;
3473 /* FIRST_DESIRED_ACCESS 0xf019f */
3474 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3475 FILE_READ_EA| /* 0xf */ \
3476 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3477 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3478 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3479 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3480 /* SECOND_DESIRED_ACCESS 0xe0080 */
3481 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3482 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3483 WRITE_OWNER_ACCESS /* 0xe0000 */
3485 #if 0
3486 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3487 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3488 FILE_READ_DATA|\
3489 WRITE_OWNER_ACCESS /* */
3490 #endif
3493 Test ntcreate calls made by xcopy
3495 static bool run_xcopy(int dummy)
3497 static struct cli_state *cli1;
3498 const char *fname = "\\test.txt";
3499 bool correct = True;
3500 int fnum1, fnum2;
3502 printf("starting xcopy test\n");
3504 if (!torture_open_connection(&cli1, 0)) {
3505 return False;
3508 fnum1 = cli_nt_create_full(cli1, fname, 0,
3509 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3510 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3511 0x4044, 0);
3513 if (fnum1 == -1) {
3514 printf("First open failed - %s\n", cli_errstr(cli1));
3515 return False;
3518 fnum2 = cli_nt_create_full(cli1, fname, 0,
3519 SECOND_DESIRED_ACCESS, 0,
3520 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3521 0x200000, 0);
3522 if (fnum2 == -1) {
3523 printf("second open failed - %s\n", cli_errstr(cli1));
3524 return False;
3527 if (!torture_close_connection(cli1)) {
3528 correct = False;
3531 return correct;
3535 Test rename on files open with share delete and no share delete.
3537 static bool run_rename(int dummy)
3539 static struct cli_state *cli1;
3540 const char *fname = "\\test.txt";
3541 const char *fname1 = "\\test1.txt";
3542 bool correct = True;
3543 int fnum1;
3545 printf("starting rename test\n");
3547 if (!torture_open_connection(&cli1, 0)) {
3548 return False;
3551 cli_unlink(cli1, fname);
3552 cli_unlink(cli1, fname1);
3553 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3554 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3556 if (fnum1 == -1) {
3557 printf("First open failed - %s\n", cli_errstr(cli1));
3558 return False;
3561 if (!cli_rename(cli1, fname, fname1)) {
3562 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3563 } else {
3564 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3565 correct = False;
3568 if (!cli_close(cli1, fnum1)) {
3569 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3570 return False;
3573 cli_unlink(cli1, fname);
3574 cli_unlink(cli1, fname1);
3575 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3576 #if 0
3577 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3578 #else
3579 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3580 #endif
3582 if (fnum1 == -1) {
3583 printf("Second open failed - %s\n", cli_errstr(cli1));
3584 return False;
3587 if (!cli_rename(cli1, fname, fname1)) {
3588 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3589 correct = False;
3590 } else {
3591 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3594 if (!cli_close(cli1, fnum1)) {
3595 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3596 return False;
3599 cli_unlink(cli1, fname);
3600 cli_unlink(cli1, fname1);
3602 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3603 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3605 if (fnum1 == -1) {
3606 printf("Third open failed - %s\n", cli_errstr(cli1));
3607 return False;
3611 #if 0
3613 int fnum2;
3615 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3616 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3618 if (fnum2 == -1) {
3619 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3620 return False;
3622 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3623 printf("[8] setting delete_on_close on file failed !\n");
3624 return False;
3627 if (!cli_close(cli1, fnum2)) {
3628 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3629 return False;
3632 #endif
3634 if (!cli_rename(cli1, fname, fname1)) {
3635 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3636 correct = False;
3637 } else {
3638 printf("Third rename succeeded (SHARE_NONE)\n");
3641 if (!cli_close(cli1, fnum1)) {
3642 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3643 return False;
3646 cli_unlink(cli1, fname);
3647 cli_unlink(cli1, fname1);
3649 /*----*/
3651 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3652 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3654 if (fnum1 == -1) {
3655 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3656 return False;
3659 if (!cli_rename(cli1, fname, fname1)) {
3660 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3661 } else {
3662 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3663 correct = False;
3666 if (!cli_close(cli1, fnum1)) {
3667 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3668 return False;
3671 cli_unlink(cli1, fname);
3672 cli_unlink(cli1, fname1);
3674 /*--*/
3676 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3677 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3679 if (fnum1 == -1) {
3680 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3681 return False;
3684 if (!cli_rename(cli1, fname, fname1)) {
3685 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3686 cli_errstr(cli1));
3687 correct = False;
3688 } else {
3689 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3693 * Now check if the first name still exists ...
3696 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3697 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3699 if (fnum2 == -1) {
3700 printf("Opening original file after rename of open file fails: %s\n",
3701 cli_errstr(cli1));
3703 else {
3704 printf("Opening original file after rename of open file works ...\n");
3705 (void)cli_close(cli1, fnum2);
3706 } */
3708 /*--*/
3711 if (!cli_close(cli1, fnum1)) {
3712 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3713 return False;
3716 cli_unlink(cli1, fname);
3717 cli_unlink(cli1, fname1);
3719 if (!torture_close_connection(cli1)) {
3720 correct = False;
3723 return correct;
3726 static bool run_pipe_number(int dummy)
3728 struct cli_state *cli1;
3729 const char *pipe_name = "\\SPOOLSS";
3730 int fnum;
3731 int num_pipes = 0;
3733 printf("starting pipenumber test\n");
3734 if (!torture_open_connection(&cli1, 0)) {
3735 return False;
3738 cli_sockopt(cli1, sockops);
3739 while(1) {
3740 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3741 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3743 if (fnum == -1) {
3744 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3745 break;
3747 num_pipes++;
3748 printf("\r%6d", num_pipes);
3751 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3752 torture_close_connection(cli1);
3753 return True;
3757 Test open mode returns on read-only files.
3759 static bool run_opentest(int dummy)
3761 static struct cli_state *cli1;
3762 static struct cli_state *cli2;
3763 const char *fname = "\\readonly.file";
3764 int fnum1, fnum2;
3765 char buf[20];
3766 SMB_OFF_T fsize;
3767 bool correct = True;
3768 char *tmp_path;
3770 printf("starting open test\n");
3772 if (!torture_open_connection(&cli1, 0)) {
3773 return False;
3776 cli_setatr(cli1, fname, 0, 0);
3777 cli_unlink(cli1, fname);
3779 cli_sockopt(cli1, sockops);
3781 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3782 if (fnum1 == -1) {
3783 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3784 return False;
3787 if (!cli_close(cli1, fnum1)) {
3788 printf("close2 failed (%s)\n", cli_errstr(cli1));
3789 return False;
3792 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3793 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3794 return False;
3797 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3798 if (fnum1 == -1) {
3799 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3800 return False;
3803 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3804 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3806 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3807 NT_STATUS_ACCESS_DENIED)) {
3808 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3811 printf("finished open test 1\n");
3813 cli_close(cli1, fnum1);
3815 /* Now try not readonly and ensure ERRbadshare is returned. */
3817 cli_setatr(cli1, fname, 0, 0);
3819 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3820 if (fnum1 == -1) {
3821 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3822 return False;
3825 /* This will fail - but the error should be ERRshare. */
3826 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3828 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3829 NT_STATUS_SHARING_VIOLATION)) {
3830 printf("correct error code ERRDOS/ERRbadshare returned\n");
3833 if (!cli_close(cli1, fnum1)) {
3834 printf("close2 failed (%s)\n", cli_errstr(cli1));
3835 return False;
3838 cli_unlink(cli1, fname);
3840 printf("finished open test 2\n");
3842 /* Test truncate open disposition on file opened for read. */
3844 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3845 if (fnum1 == -1) {
3846 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3847 return False;
3850 /* write 20 bytes. */
3852 memset(buf, '\0', 20);
3854 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3855 printf("write failed (%s)\n", cli_errstr(cli1));
3856 correct = False;
3859 if (!cli_close(cli1, fnum1)) {
3860 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3861 return False;
3864 /* Ensure size == 20. */
3865 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3866 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3867 return False;
3870 if (fsize != 20) {
3871 printf("(3) file size != 20\n");
3872 return False;
3875 /* Now test if we can truncate a file opened for readonly. */
3877 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3878 if (fnum1 == -1) {
3879 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3880 return False;
3883 if (!cli_close(cli1, fnum1)) {
3884 printf("close2 failed (%s)\n", cli_errstr(cli1));
3885 return False;
3888 /* Ensure size == 0. */
3889 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3890 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3891 return False;
3894 if (fsize != 0) {
3895 printf("(3) file size != 0\n");
3896 return False;
3898 printf("finished open test 3\n");
3900 cli_unlink(cli1, fname);
3903 printf("testing ctemp\n");
3904 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3905 if (fnum1 == -1) {
3906 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3907 return False;
3909 printf("ctemp gave path %s\n", tmp_path);
3910 if (!cli_close(cli1, fnum1)) {
3911 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3913 if (!cli_unlink(cli1, tmp_path)) {
3914 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3917 /* Test the non-io opens... */
3919 if (!torture_open_connection(&cli2, 1)) {
3920 return False;
3923 cli_setatr(cli2, fname, 0, 0);
3924 cli_unlink(cli2, fname);
3926 cli_sockopt(cli2, sockops);
3928 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3930 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3931 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3933 if (fnum1 == -1) {
3934 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3935 return False;
3938 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3939 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3941 if (fnum2 == -1) {
3942 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3943 return False;
3946 if (!cli_close(cli1, fnum1)) {
3947 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3948 return False;
3950 if (!cli_close(cli2, fnum2)) {
3951 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3952 return False;
3955 printf("non-io open test #1 passed.\n");
3957 cli_unlink(cli1, fname);
3959 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3961 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3962 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3964 if (fnum1 == -1) {
3965 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3966 return False;
3969 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3970 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3972 if (fnum2 == -1) {
3973 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3974 return False;
3977 if (!cli_close(cli1, fnum1)) {
3978 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3979 return False;
3981 if (!cli_close(cli2, fnum2)) {
3982 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3983 return False;
3986 printf("non-io open test #2 passed.\n");
3988 cli_unlink(cli1, fname);
3990 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3992 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3993 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3995 if (fnum1 == -1) {
3996 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3997 return False;
4000 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4001 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4003 if (fnum2 == -1) {
4004 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4005 return False;
4008 if (!cli_close(cli1, fnum1)) {
4009 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4010 return False;
4012 if (!cli_close(cli2, fnum2)) {
4013 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4014 return False;
4017 printf("non-io open test #3 passed.\n");
4019 cli_unlink(cli1, fname);
4021 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4023 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4024 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4026 if (fnum1 == -1) {
4027 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4028 return False;
4031 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4032 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4034 if (fnum2 != -1) {
4035 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4036 return False;
4039 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4041 if (!cli_close(cli1, fnum1)) {
4042 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4043 return False;
4046 printf("non-io open test #4 passed.\n");
4048 cli_unlink(cli1, fname);
4050 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4052 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4053 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4055 if (fnum1 == -1) {
4056 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4057 return False;
4060 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4061 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4063 if (fnum2 == -1) {
4064 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4065 return False;
4068 if (!cli_close(cli1, fnum1)) {
4069 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4070 return False;
4073 if (!cli_close(cli2, fnum2)) {
4074 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4075 return False;
4078 printf("non-io open test #5 passed.\n");
4080 printf("TEST #6 testing 1 non-io open, one io open\n");
4082 cli_unlink(cli1, fname);
4084 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4085 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4087 if (fnum1 == -1) {
4088 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4089 return False;
4092 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4093 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4095 if (fnum2 == -1) {
4096 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4097 return False;
4100 if (!cli_close(cli1, fnum1)) {
4101 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4102 return False;
4105 if (!cli_close(cli2, fnum2)) {
4106 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4107 return False;
4110 printf("non-io open test #6 passed.\n");
4112 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4114 cli_unlink(cli1, fname);
4116 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4117 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4119 if (fnum1 == -1) {
4120 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4121 return False;
4124 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4125 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4127 if (fnum2 != -1) {
4128 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4129 return False;
4132 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4134 if (!cli_close(cli1, fnum1)) {
4135 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4136 return False;
4139 printf("non-io open test #7 passed.\n");
4141 cli_unlink(cli1, fname);
4143 if (!torture_close_connection(cli1)) {
4144 correct = False;
4146 if (!torture_close_connection(cli2)) {
4147 correct = False;
4150 return correct;
4154 Test POSIX open /mkdir calls.
4156 static bool run_simple_posix_open_test(int dummy)
4158 static struct cli_state *cli1;
4159 const char *fname = "\\posix.file";
4160 const char *dname = "\\posix.dir";
4161 uint16 major, minor;
4162 uint32 caplow, caphigh;
4163 int fnum1 = -1;
4164 bool correct = false;
4166 printf("Starting simple POSIX open test\n");
4168 if (!torture_open_connection(&cli1, 0)) {
4169 return false;
4172 cli_sockopt(cli1, sockops);
4174 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4175 printf("Server doesn't support UNIX CIFS extensions.\n");
4176 return false;
4179 if (!cli_unix_extensions_version(cli1, &major,
4180 &minor, &caplow, &caphigh)) {
4181 printf("Server didn't return UNIX CIFS extensions.\n");
4182 return false;
4185 if (!cli_set_unix_extensions_capabilities(cli1,
4186 major, minor, caplow, caphigh)) {
4187 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4188 return false;
4191 cli_setatr(cli1, fname, 0, 0);
4192 cli_posix_unlink(cli1, fname);
4193 cli_setatr(cli1, dname, 0, 0);
4194 cli_posix_rmdir(cli1, dname);
4196 /* Create a directory. */
4197 if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
4198 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4199 goto out;
4202 fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
4203 if (fnum1 == -1) {
4204 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4205 goto out;
4208 if (!cli_close(cli1, fnum1)) {
4209 printf("close failed (%s)\n", cli_errstr(cli1));
4210 goto out;
4213 /* Now open the file again for read only. */
4214 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4215 if (fnum1 == -1) {
4216 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4217 goto out;
4220 /* Now unlink while open. */
4221 if (!cli_posix_unlink(cli1, fname)) {
4222 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4223 goto out;
4226 if (!cli_close(cli1, fnum1)) {
4227 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4228 goto out;
4231 /* Ensure the file has gone. */
4232 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4233 if (fnum1 != -1) {
4234 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4235 goto out;
4238 if (!cli_posix_rmdir(cli1, dname)) {
4239 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4240 goto out;
4243 printf("Simple POSIX open test passed\n");
4244 correct = true;
4246 out:
4248 if (fnum1 != -1) {
4249 cli_close(cli1, fnum1);
4250 fnum1 = -1;
4253 cli_setatr(cli1, fname, 0, 0);
4254 cli_posix_unlink(cli1, fname);
4255 cli_setatr(cli1, dname, 0, 0);
4256 cli_posix_rmdir(cli1, dname);
4258 if (!torture_close_connection(cli1)) {
4259 correct = false;
4262 return correct;
4266 static uint32 open_attrs_table[] = {
4267 FILE_ATTRIBUTE_NORMAL,
4268 FILE_ATTRIBUTE_ARCHIVE,
4269 FILE_ATTRIBUTE_READONLY,
4270 FILE_ATTRIBUTE_HIDDEN,
4271 FILE_ATTRIBUTE_SYSTEM,
4273 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4274 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4275 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4276 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4277 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4278 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4280 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4281 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4282 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4283 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4286 struct trunc_open_results {
4287 unsigned int num;
4288 uint32 init_attr;
4289 uint32 trunc_attr;
4290 uint32 result_attr;
4293 static struct trunc_open_results attr_results[] = {
4294 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4295 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4296 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4297 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4298 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4299 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4300 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4301 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4302 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4303 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4304 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4305 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4306 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4307 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4308 { 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 },
4309 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4310 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4311 { 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 },
4312 { 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 },
4313 { 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 },
4314 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4315 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4316 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4317 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4318 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4319 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4322 static bool run_openattrtest(int dummy)
4324 static struct cli_state *cli1;
4325 const char *fname = "\\openattr.file";
4326 int fnum1;
4327 bool correct = True;
4328 uint16 attr;
4329 unsigned int i, j, k, l;
4331 printf("starting open attr test\n");
4333 if (!torture_open_connection(&cli1, 0)) {
4334 return False;
4337 cli_sockopt(cli1, sockops);
4339 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4340 cli_setatr(cli1, fname, 0, 0);
4341 cli_unlink(cli1, fname);
4342 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4343 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4345 if (fnum1 == -1) {
4346 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4347 return False;
4350 if (!cli_close(cli1, fnum1)) {
4351 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4352 return False;
4355 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4356 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4357 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4359 if (fnum1 == -1) {
4360 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4361 if (attr_results[l].num == k) {
4362 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4363 k, open_attrs_table[i],
4364 open_attrs_table[j],
4365 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4366 correct = False;
4369 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4370 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4371 k, open_attrs_table[i], open_attrs_table[j],
4372 cli_errstr(cli1));
4373 correct = False;
4375 #if 0
4376 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4377 #endif
4378 k++;
4379 continue;
4382 if (!cli_close(cli1, fnum1)) {
4383 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4384 return False;
4387 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4388 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4389 return False;
4392 #if 0
4393 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4394 k, open_attrs_table[i], open_attrs_table[j], attr );
4395 #endif
4397 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4398 if (attr_results[l].num == k) {
4399 if (attr != attr_results[l].result_attr ||
4400 open_attrs_table[i] != attr_results[l].init_attr ||
4401 open_attrs_table[j] != attr_results[l].trunc_attr) {
4402 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4403 open_attrs_table[i],
4404 open_attrs_table[j],
4405 (unsigned int)attr,
4406 attr_results[l].result_attr);
4407 correct = False;
4409 break;
4412 k++;
4416 cli_setatr(cli1, fname, 0, 0);
4417 cli_unlink(cli1, fname);
4419 printf("open attr test %s.\n", correct ? "passed" : "failed");
4421 if (!torture_close_connection(cli1)) {
4422 correct = False;
4424 return correct;
4427 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4433 test directory listing speed
4435 static bool run_dirtest(int dummy)
4437 int i;
4438 static struct cli_state *cli;
4439 int fnum;
4440 double t1;
4441 bool correct = True;
4443 printf("starting directory test\n");
4445 if (!torture_open_connection(&cli, 0)) {
4446 return False;
4449 cli_sockopt(cli, sockops);
4451 srandom(0);
4452 for (i=0;i<torture_numops;i++) {
4453 fstring fname;
4454 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4455 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4456 if (fnum == -1) {
4457 fprintf(stderr,"Failed to open %s\n", fname);
4458 return False;
4460 cli_close(cli, fnum);
4463 t1 = end_timer();
4465 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4466 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4467 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4469 printf("dirtest core %g seconds\n", end_timer() - t1);
4471 srandom(0);
4472 for (i=0;i<torture_numops;i++) {
4473 fstring fname;
4474 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4475 cli_unlink(cli, fname);
4478 if (!torture_close_connection(cli)) {
4479 correct = False;
4482 printf("finished dirtest\n");
4484 return correct;
4487 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4489 struct cli_state *pcli = (struct cli_state *)state;
4490 fstring fname;
4491 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4493 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4494 return;
4496 if (finfo->mode & aDIR) {
4497 if (!cli_rmdir(pcli, fname))
4498 printf("del_fn: failed to rmdir %s\n,", fname );
4499 } else {
4500 if (!cli_unlink(pcli, fname))
4501 printf("del_fn: failed to unlink %s\n,", fname );
4507 sees what IOCTLs are supported
4509 bool torture_ioctl_test(int dummy)
4511 static struct cli_state *cli;
4512 uint16 device, function;
4513 int fnum;
4514 const char *fname = "\\ioctl.dat";
4515 DATA_BLOB blob;
4516 NTSTATUS status;
4518 if (!torture_open_connection(&cli, 0)) {
4519 return False;
4522 printf("starting ioctl test\n");
4524 cli_unlink(cli, fname);
4526 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4527 if (fnum == -1) {
4528 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4529 return False;
4532 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4533 printf("ioctl device info: %s\n", cli_errstr(cli));
4535 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4536 printf("ioctl job info: %s\n", cli_errstr(cli));
4538 for (device=0;device<0x100;device++) {
4539 printf("testing device=0x%x\n", device);
4540 for (function=0;function<0x100;function++) {
4541 uint32 code = (device<<16) | function;
4543 status = cli_raw_ioctl(cli, fnum, code, &blob);
4545 if (NT_STATUS_IS_OK(status)) {
4546 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4547 (int)blob.length);
4548 data_blob_free(&blob);
4553 if (!torture_close_connection(cli)) {
4554 return False;
4557 return True;
4562 tries varients of chkpath
4564 bool torture_chkpath_test(int dummy)
4566 static struct cli_state *cli;
4567 int fnum;
4568 bool ret;
4570 if (!torture_open_connection(&cli, 0)) {
4571 return False;
4574 printf("starting chkpath test\n");
4576 /* cleanup from an old run */
4577 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4578 cli_unlink(cli, "\\chkpath.dir\\*");
4579 cli_rmdir(cli, "\\chkpath.dir");
4581 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4582 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4583 return False;
4586 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4587 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4588 return False;
4591 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4592 if (fnum == -1) {
4593 printf("open1 failed (%s)\n", cli_errstr(cli));
4594 return False;
4596 cli_close(cli, fnum);
4598 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4599 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4600 ret = False;
4603 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4604 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4605 ret = False;
4608 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4609 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4610 NT_STATUS_NOT_A_DIRECTORY);
4611 } else {
4612 printf("* chkpath on a file should fail\n");
4613 ret = False;
4616 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4617 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4618 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4619 } else {
4620 printf("* chkpath on a non existant file should fail\n");
4621 ret = False;
4624 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4625 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4626 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4627 } else {
4628 printf("* chkpath on a non existent component should fail\n");
4629 ret = False;
4632 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4633 cli_unlink(cli, "\\chkpath.dir\\*");
4634 cli_rmdir(cli, "\\chkpath.dir");
4636 if (!torture_close_connection(cli)) {
4637 return False;
4640 return ret;
4643 static bool run_eatest(int dummy)
4645 static struct cli_state *cli;
4646 const char *fname = "\\eatest.txt";
4647 bool correct = True;
4648 int fnum, i;
4649 size_t num_eas;
4650 struct ea_struct *ea_list = NULL;
4651 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4653 printf("starting eatest\n");
4655 if (!torture_open_connection(&cli, 0)) {
4656 talloc_destroy(mem_ctx);
4657 return False;
4660 cli_unlink(cli, fname);
4661 fnum = cli_nt_create_full(cli, fname, 0,
4662 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4663 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4664 0x4044, 0);
4666 if (fnum == -1) {
4667 printf("open failed - %s\n", cli_errstr(cli));
4668 talloc_destroy(mem_ctx);
4669 return False;
4672 for (i = 0; i < 10; i++) {
4673 fstring ea_name, ea_val;
4675 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4676 memset(ea_val, (char)i+1, i+1);
4677 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4678 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4679 talloc_destroy(mem_ctx);
4680 return False;
4684 cli_close(cli, fnum);
4685 for (i = 0; i < 10; i++) {
4686 fstring ea_name, ea_val;
4688 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4689 memset(ea_val, (char)i+1, i+1);
4690 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4691 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4692 talloc_destroy(mem_ctx);
4693 return False;
4697 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4698 printf("ea_get list failed - %s\n", cli_errstr(cli));
4699 correct = False;
4702 printf("num_eas = %d\n", (int)num_eas);
4704 if (num_eas != 20) {
4705 printf("Should be 20 EA's stored... failing.\n");
4706 correct = False;
4709 for (i = 0; i < num_eas; i++) {
4710 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4711 dump_data(0, ea_list[i].value.data,
4712 ea_list[i].value.length);
4715 /* Setting EA's to zero length deletes them. Test this */
4716 printf("Now deleting all EA's - case indepenent....\n");
4718 #if 1
4719 cli_set_ea_path(cli, fname, "", "", 0);
4720 #else
4721 for (i = 0; i < 20; i++) {
4722 fstring ea_name;
4723 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4724 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4725 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4726 talloc_destroy(mem_ctx);
4727 return False;
4730 #endif
4732 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4733 printf("ea_get list failed - %s\n", cli_errstr(cli));
4734 correct = False;
4737 printf("num_eas = %d\n", (int)num_eas);
4738 for (i = 0; i < num_eas; i++) {
4739 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4740 dump_data(0, ea_list[i].value.data,
4741 ea_list[i].value.length);
4744 if (num_eas != 0) {
4745 printf("deleting EA's failed.\n");
4746 correct = False;
4749 /* Try and delete a non existant EA. */
4750 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4751 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4752 correct = False;
4755 talloc_destroy(mem_ctx);
4756 if (!torture_close_connection(cli)) {
4757 correct = False;
4760 return correct;
4763 static bool run_dirtest1(int dummy)
4765 int i;
4766 static struct cli_state *cli;
4767 int fnum, num_seen;
4768 bool correct = True;
4770 printf("starting directory test\n");
4772 if (!torture_open_connection(&cli, 0)) {
4773 return False;
4776 cli_sockopt(cli, sockops);
4778 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4779 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4780 cli_rmdir(cli, "\\LISTDIR");
4781 cli_mkdir(cli, "\\LISTDIR");
4783 /* Create 1000 files and 1000 directories. */
4784 for (i=0;i<1000;i++) {
4785 fstring fname;
4786 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4787 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4788 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4789 if (fnum == -1) {
4790 fprintf(stderr,"Failed to open %s\n", fname);
4791 return False;
4793 cli_close(cli, fnum);
4795 for (i=0;i<1000;i++) {
4796 fstring fname;
4797 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4798 if (!cli_mkdir(cli, fname)) {
4799 fprintf(stderr,"Failed to open %s\n", fname);
4800 return False;
4804 /* Now ensure that doing an old list sees both files and directories. */
4805 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4806 printf("num_seen = %d\n", num_seen );
4807 /* We should see 100 files + 1000 directories + . and .. */
4808 if (num_seen != 2002)
4809 correct = False;
4811 /* Ensure if we have the "must have" bits we only see the
4812 * relevent entries.
4814 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4815 printf("num_seen = %d\n", num_seen );
4816 if (num_seen != 1002)
4817 correct = False;
4819 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4820 printf("num_seen = %d\n", num_seen );
4821 if (num_seen != 1000)
4822 correct = False;
4824 /* Delete everything. */
4825 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4826 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4827 cli_rmdir(cli, "\\LISTDIR");
4829 #if 0
4830 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4831 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4832 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4833 #endif
4835 if (!torture_close_connection(cli)) {
4836 correct = False;
4839 printf("finished dirtest1\n");
4841 return correct;
4844 static bool run_error_map_extract(int dummy) {
4846 static struct cli_state *c_dos;
4847 static struct cli_state *c_nt;
4848 NTSTATUS status;
4850 uint32 error;
4852 uint32 flgs2, errnum;
4853 uint8 errclass;
4855 NTSTATUS nt_status;
4857 fstring user;
4859 /* NT-Error connection */
4861 if (!(c_nt = open_nbt_connection())) {
4862 return False;
4865 c_nt->use_spnego = False;
4867 status = cli_negprot(c_nt);
4869 if (!NT_STATUS_IS_OK(status)) {
4870 printf("%s rejected the NT-error negprot (%s)\n", host,
4871 nt_errstr(status));
4872 cli_shutdown(c_nt);
4873 return False;
4876 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4877 workgroup))) {
4878 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4879 return False;
4882 /* DOS-Error connection */
4884 if (!(c_dos = open_nbt_connection())) {
4885 return False;
4888 c_dos->use_spnego = False;
4889 c_dos->force_dos_errors = True;
4891 status = cli_negprot(c_dos);
4892 if (!NT_STATUS_IS_OK(status)) {
4893 printf("%s rejected the DOS-error negprot (%s)\n", host,
4894 nt_errstr(status));
4895 cli_shutdown(c_dos);
4896 return False;
4899 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4900 workgroup))) {
4901 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4902 return False;
4905 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4906 fstr_sprintf(user, "%X", error);
4908 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4909 password, strlen(password),
4910 password, strlen(password),
4911 workgroup))) {
4912 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4915 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4917 /* Case #1: 32-bit NT errors */
4918 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4919 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4920 } else {
4921 printf("/** Dos error on NT connection! (%s) */\n",
4922 cli_errstr(c_nt));
4923 nt_status = NT_STATUS(0xc0000000);
4926 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4927 password, strlen(password),
4928 password, strlen(password),
4929 workgroup))) {
4930 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4932 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4934 /* Case #1: 32-bit NT errors */
4935 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4936 printf("/** NT error on DOS connection! (%s) */\n",
4937 cli_errstr(c_nt));
4938 errnum = errclass = 0;
4939 } else {
4940 cli_dos_error(c_dos, &errclass, &errnum);
4943 if (NT_STATUS_V(nt_status) != error) {
4944 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4945 get_nt_error_c_code(NT_STATUS(error)),
4946 get_nt_error_c_code(nt_status));
4949 printf("\t{%s,\t%s,\t%s},\n",
4950 smb_dos_err_class(errclass),
4951 smb_dos_err_name(errclass, errnum),
4952 get_nt_error_c_code(NT_STATUS(error)));
4954 return True;
4957 static bool run_sesssetup_bench(int dummy)
4959 static struct cli_state *c;
4960 const char *fname = "\\file.dat";
4961 int fnum;
4962 NTSTATUS status;
4963 int i;
4965 if (!torture_open_connection(&c, 0)) {
4966 return false;
4969 fnum = cli_nt_create_full(
4970 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4971 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4972 FILE_DELETE_ON_CLOSE, 0);
4973 if (fnum == -1) {
4974 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4975 return false;
4978 for (i=0; i<torture_numops; i++) {
4979 status = cli_session_setup(
4980 c, username,
4981 password, strlen(password),
4982 password, strlen(password),
4983 workgroup);
4984 if (!NT_STATUS_IS_OK(status)) {
4985 d_printf("(%s) cli_session_setup failed: %s\n",
4986 __location__, nt_errstr(status));
4987 return false;
4990 d_printf("\r%d ", (int)c->vuid);
4992 if (!cli_ulogoff(c)) {
4993 d_printf("(%s) cli_ulogoff failed: %s\n",
4994 __location__, cli_errstr(c));
4995 return false;
4997 c->vuid = 0;
5000 return true;
5003 static bool subst_test(const char *str, const char *user, const char *domain,
5004 uid_t uid, gid_t gid, const char *expected)
5006 char *subst;
5007 bool result = true;
5009 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5011 if (strcmp(subst, expected) != 0) {
5012 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5013 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5014 expected);
5015 result = false;
5018 TALLOC_FREE(subst);
5019 return result;
5022 static void chain1_open_completion(struct async_req *req)
5024 int fnum;
5025 NTSTATUS status;
5027 status = cli_open_recv(req, &fnum);
5028 TALLOC_FREE(req);
5030 d_printf("cli_open_recv returned %s: %d\n",
5031 nt_errstr(status),
5032 NT_STATUS_IS_OK(status) ? fnum : -1);
5035 static void chain1_read_completion(struct async_req *req)
5037 NTSTATUS status;
5038 ssize_t received;
5039 uint8_t *rcvbuf;
5041 status = cli_read_andx_recv(req, &received, &rcvbuf);
5042 if (!NT_STATUS_IS_OK(status)) {
5043 TALLOC_FREE(req);
5044 d_printf("cli_read_andx_recv returned %s\n",
5045 nt_errstr(status));
5046 return;
5049 d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
5050 (char *)rcvbuf);
5051 TALLOC_FREE(req);
5054 static void chain1_write_completion(struct async_req *req)
5056 NTSTATUS status;
5057 size_t written;
5059 status = cli_write_andx_recv(req, &written);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 TALLOC_FREE(req);
5062 d_printf("cli_write_andx_recv returned %s\n",
5063 nt_errstr(status));
5064 return;
5067 d_printf("wrote %d bytes\n", (int)written);
5068 TALLOC_FREE(req);
5071 static void chain1_close_completion(struct async_req *req)
5073 NTSTATUS status;
5075 status = cli_close_recv(req);
5076 *((bool *)(req->async.priv)) = true;
5078 TALLOC_FREE(req);
5080 d_printf("cli_close returned %s\n", nt_errstr(status));
5083 static bool run_chain1(int dummy)
5085 struct cli_state *cli1;
5086 struct event_context *evt = event_context_init(NULL);
5087 struct async_req *reqs[4];
5088 bool done = false;
5089 const char *text = "hallo";
5091 printf("starting chain1 test\n");
5092 if (!torture_open_connection(&cli1, 0)) {
5093 return False;
5096 cli_sockopt(cli1, sockops);
5098 cli_chain_cork(cli1, evt, 0);
5099 reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
5100 O_CREAT|O_RDWR, 0);
5101 reqs[0]->async.fn = chain1_open_completion;
5102 reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
5103 (uint8_t *)text, 0, strlen(text));
5104 reqs[1]->async.fn = chain1_write_completion;
5105 reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
5106 reqs[2]->async.fn = chain1_read_completion;
5107 reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
5108 reqs[3]->async.fn = chain1_close_completion;
5109 reqs[3]->async.priv = (void *)&done;
5110 cli_chain_uncork(cli1);
5112 while (!done) {
5113 event_loop_once(evt);
5116 torture_close_connection(cli1);
5117 return True;
5120 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5122 size_t *to_pull = (size_t *)priv;
5123 size_t thistime = *to_pull;
5125 thistime = MIN(thistime, n);
5126 if (thistime == 0) {
5127 return 0;
5130 memset(buf, 0, thistime);
5131 *to_pull -= thistime;
5132 return thistime;
5135 static bool run_windows_write(int dummy)
5137 struct cli_state *cli1;
5138 int fnum;
5139 int i;
5140 bool ret = false;
5141 const char *fname = "\\writetest.txt";
5142 double seconds;
5143 double kbytes;
5145 printf("starting windows_write test\n");
5146 if (!torture_open_connection(&cli1, 0)) {
5147 return False;
5150 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5151 if (fnum == -1) {
5152 printf("open failed (%s)\n", cli_errstr(cli1));
5153 return False;
5156 cli_sockopt(cli1, sockops);
5158 start_timer();
5160 for (i=0; i<torture_numops; i++) {
5161 char c = 0;
5162 off_t start = i * torture_blocksize;
5163 NTSTATUS status;
5164 size_t to_pull = torture_blocksize - 1;
5166 if (cli_write(cli1, fnum, 0, &c,
5167 start + torture_blocksize - 1, 1) != 1) {
5168 printf("cli_write failed: %s\n", cli_errstr(cli1));
5169 goto fail;
5172 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5173 null_source, &to_pull);
5174 if (!NT_STATUS_IS_OK(status)) {
5175 printf("cli_push returned: %s\n", nt_errstr(status));
5176 goto fail;
5180 seconds = end_timer();
5181 kbytes = (double)torture_blocksize * torture_numops;
5182 kbytes /= 1024;
5184 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5185 (double)seconds, (int)(kbytes/seconds));
5187 ret = true;
5188 fail:
5189 cli_close(cli1, fnum);
5190 cli_unlink(cli1, fname);
5191 torture_close_connection(cli1);
5192 return ret;
5195 static bool run_cli_echo(int dummy)
5197 struct cli_state *cli;
5198 struct event_context *ev = event_context_init(NULL);
5199 struct async_req *req;
5200 NTSTATUS status;
5202 printf("starting chain1 test\n");
5203 if (!torture_open_connection(&cli, 0)) {
5204 return false;
5206 cli_sockopt(cli, sockops);
5208 req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5209 if (req == NULL) {
5210 d_printf("cli_echo_send failed\n");
5211 return false;
5214 while (req->state < ASYNC_REQ_DONE) {
5215 event_loop_once(ev);
5218 status = cli_echo_recv(req);
5219 d_printf("cli_echo returned %s\n", nt_errstr(status));
5221 TALLOC_FREE(req);
5223 torture_close_connection(cli);
5224 return NT_STATUS_IS_OK(status);
5227 static bool run_local_substitute(int dummy)
5229 bool ok = true;
5231 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5232 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5233 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5234 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5235 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5236 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5237 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5238 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5240 /* Different captialization rules in sub_basic... */
5242 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5243 "blaDOM") == 0);
5245 return ok;
5248 static bool run_local_gencache(int dummy)
5250 char *val;
5251 time_t tm;
5252 DATA_BLOB blob;
5254 if (!gencache_init()) {
5255 d_printf("%s: gencache_init() failed\n", __location__);
5256 return False;
5259 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5260 d_printf("%s: gencache_set() failed\n", __location__);
5261 return False;
5264 if (!gencache_get("foo", &val, &tm)) {
5265 d_printf("%s: gencache_get() failed\n", __location__);
5266 return False;
5269 if (strcmp(val, "bar") != 0) {
5270 d_printf("%s: gencache_get() returned %s, expected %s\n",
5271 __location__, val, "bar");
5272 SAFE_FREE(val);
5273 return False;
5276 SAFE_FREE(val);
5278 if (!gencache_del("foo")) {
5279 d_printf("%s: gencache_del() failed\n", __location__);
5280 return False;
5282 if (gencache_del("foo")) {
5283 d_printf("%s: second gencache_del() succeeded\n",
5284 __location__);
5285 return False;
5288 if (gencache_get("foo", &val, &tm)) {
5289 d_printf("%s: gencache_get() on deleted entry "
5290 "succeeded\n", __location__);
5291 return False;
5294 blob = data_blob_string_const_null("bar");
5295 tm = time(NULL);
5297 if (!gencache_set_data_blob("foo", &blob, tm)) {
5298 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5299 return False;
5302 data_blob_free(&blob);
5304 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5305 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5306 return False;
5309 if (strcmp((const char *)blob.data, "bar") != 0) {
5310 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5311 __location__, (const char *)blob.data, "bar");
5312 data_blob_free(&blob);
5313 return False;
5316 data_blob_free(&blob);
5318 if (!gencache_del("foo")) {
5319 d_printf("%s: gencache_del() failed\n", __location__);
5320 return False;
5322 if (gencache_del("foo")) {
5323 d_printf("%s: second gencache_del() succeeded\n",
5324 __location__);
5325 return False;
5328 if (gencache_get_data_blob("foo", &blob, NULL)) {
5329 d_printf("%s: gencache_get_data_blob() on deleted entry "
5330 "succeeded\n", __location__);
5331 return False;
5334 if (!gencache_shutdown()) {
5335 d_printf("%s: gencache_shutdown() failed\n", __location__);
5336 return False;
5339 if (gencache_shutdown()) {
5340 d_printf("%s: second gencache_shutdown() succeeded\n",
5341 __location__);
5342 return False;
5345 return True;
5348 static bool rbt_testval(struct db_context *db, const char *key,
5349 const char *value)
5351 struct db_record *rec;
5352 TDB_DATA data = string_tdb_data(value);
5353 bool ret = false;
5354 NTSTATUS status;
5356 rec = db->fetch_locked(db, db, string_tdb_data(key));
5357 if (rec == NULL) {
5358 d_fprintf(stderr, "fetch_locked failed\n");
5359 goto done;
5361 status = rec->store(rec, data, 0);
5362 if (!NT_STATUS_IS_OK(status)) {
5363 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5364 goto done;
5366 TALLOC_FREE(rec);
5368 rec = db->fetch_locked(db, db, string_tdb_data(key));
5369 if (rec == NULL) {
5370 d_fprintf(stderr, "second fetch_locked failed\n");
5371 goto done;
5373 if ((rec->value.dsize != data.dsize)
5374 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5375 d_fprintf(stderr, "Got wrong data back\n");
5376 goto done;
5379 ret = true;
5380 done:
5381 TALLOC_FREE(rec);
5382 return ret;
5385 static bool run_local_rbtree(int dummy)
5387 struct db_context *db;
5388 bool ret = false;
5389 int i;
5391 db = db_open_rbt(NULL);
5393 if (db == NULL) {
5394 d_fprintf(stderr, "db_open_rbt failed\n");
5395 return false;
5398 for (i=0; i<1000; i++) {
5399 char *key, *value;
5401 if (asprintf(&key, "key%ld", random()) == -1) {
5402 goto done;
5404 if (asprintf(&value, "value%ld", random()) == -1) {
5405 SAFE_FREE(key);
5406 goto done;
5409 if (!rbt_testval(db, key, value)) {
5410 SAFE_FREE(key);
5411 SAFE_FREE(value);
5412 goto done;
5415 SAFE_FREE(value);
5416 if (asprintf(&value, "value%ld", random()) == -1) {
5417 SAFE_FREE(key);
5418 goto done;
5421 if (!rbt_testval(db, key, value)) {
5422 SAFE_FREE(key);
5423 SAFE_FREE(value);
5424 goto done;
5427 SAFE_FREE(key);
5428 SAFE_FREE(value);
5431 ret = true;
5433 done:
5434 TALLOC_FREE(db);
5435 return ret;
5438 static bool test_stream_name(const char *fname, const char *expected_base,
5439 const char *expected_stream,
5440 NTSTATUS expected_status)
5442 NTSTATUS status;
5443 char *base = NULL;
5444 char *stream = NULL;
5446 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5447 if (!NT_STATUS_EQUAL(status, expected_status)) {
5448 goto error;
5451 if (!NT_STATUS_IS_OK(status)) {
5452 return true;
5455 if (base == NULL) goto error;
5457 if (strcmp(expected_base, base) != 0) goto error;
5459 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5460 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5462 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5463 goto error;
5465 TALLOC_FREE(base);
5466 TALLOC_FREE(stream);
5467 return true;
5469 error:
5470 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5471 fname, expected_base ? expected_base : "<NULL>",
5472 expected_stream ? expected_stream : "<NULL>",
5473 nt_errstr(expected_status));
5474 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5475 base ? base : "<NULL>", stream ? stream : "<NULL>",
5476 nt_errstr(status));
5477 TALLOC_FREE(base);
5478 TALLOC_FREE(stream);
5479 return false;
5482 static bool run_local_stream_name(int dummy)
5484 bool ret = true;
5486 ret &= test_stream_name(
5487 "bla", "bla", NULL, NT_STATUS_OK);
5488 ret &= test_stream_name(
5489 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5490 ret &= test_stream_name(
5491 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5492 ret &= test_stream_name(
5493 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5494 ret &= test_stream_name(
5495 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5496 ret &= test_stream_name(
5497 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5498 ret &= test_stream_name(
5499 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5500 ret &= test_stream_name(
5501 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5503 return ret;
5506 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5508 if (a.length != b.length) {
5509 printf("a.length=%d != b.length=%d\n",
5510 (int)a.length, (int)b.length);
5511 return false;
5513 if (memcmp(a.data, b.data, a.length) != 0) {
5514 printf("a.data and b.data differ\n");
5515 return false;
5517 return true;
5520 static bool run_local_memcache(int dummy)
5522 struct memcache *cache;
5523 DATA_BLOB k1, k2;
5524 DATA_BLOB d1, d2, d3;
5525 DATA_BLOB v1, v2, v3;
5527 TALLOC_CTX *mem_ctx;
5528 char *str1, *str2;
5529 size_t size1, size2;
5530 bool ret = false;
5532 cache = memcache_init(NULL, 100);
5534 if (cache == NULL) {
5535 printf("memcache_init failed\n");
5536 return false;
5539 d1 = data_blob_const("d1", 2);
5540 d2 = data_blob_const("d2", 2);
5541 d3 = data_blob_const("d3", 2);
5543 k1 = data_blob_const("d1", 2);
5544 k2 = data_blob_const("d2", 2);
5546 memcache_add(cache, STAT_CACHE, k1, d1);
5547 memcache_add(cache, GETWD_CACHE, k2, d2);
5549 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5550 printf("could not find k1\n");
5551 return false;
5553 if (!data_blob_equal(d1, v1)) {
5554 return false;
5557 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5558 printf("could not find k2\n");
5559 return false;
5561 if (!data_blob_equal(d2, v2)) {
5562 return false;
5565 memcache_add(cache, STAT_CACHE, k1, d3);
5567 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5568 printf("could not find replaced k1\n");
5569 return false;
5571 if (!data_blob_equal(d3, v3)) {
5572 return false;
5575 memcache_add(cache, GETWD_CACHE, k1, d1);
5577 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5578 printf("Did find k2, should have been purged\n");
5579 return false;
5582 TALLOC_FREE(cache);
5584 cache = memcache_init(NULL, 0);
5586 mem_ctx = talloc_init("foo");
5588 str1 = talloc_strdup(mem_ctx, "string1");
5589 str2 = talloc_strdup(mem_ctx, "string2");
5591 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5592 data_blob_string_const("torture"), &str1);
5593 size1 = talloc_total_size(cache);
5595 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5596 data_blob_string_const("torture"), &str2);
5597 size2 = talloc_total_size(cache);
5599 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5601 if (size2 > size1) {
5602 printf("memcache leaks memory!\n");
5603 goto fail;
5606 ret = true;
5607 fail:
5608 TALLOC_FREE(cache);
5609 return ret;
5612 static void wbclient_done(struct async_req *req)
5614 wbcErr wbc_err;
5615 struct winbindd_response *wb_resp;
5616 int *i = (int *)req->async.priv;
5618 wbc_err = wb_trans_recv(req, req, &wb_resp);
5619 TALLOC_FREE(req);
5620 *i += 1;
5621 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5624 static bool run_local_wbclient(int dummy)
5626 struct event_context *ev;
5627 struct wb_context **wb_ctx;
5628 struct winbindd_request wb_req;
5629 bool result = false;
5630 int i, j;
5632 BlockSignals(True, SIGPIPE);
5634 ev = event_context_init(talloc_tos());
5635 if (ev == NULL) {
5636 goto fail;
5639 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5640 if (wb_ctx == NULL) {
5641 goto fail;
5644 ZERO_STRUCT(wb_req);
5645 wb_req.cmd = WINBINDD_PING;
5647 for (i=0; i<torture_numops; i++) {
5648 wb_ctx[i] = wb_context_init(ev);
5649 if (wb_ctx[i] == NULL) {
5650 goto fail;
5652 for (j=0; j<5; j++) {
5653 struct async_req *req;
5654 req = wb_trans_send(ev, ev, wb_ctx[i],
5655 (j % 2) == 0, &wb_req);
5656 if (req == NULL) {
5657 goto fail;
5659 req->async.fn = wbclient_done;
5660 req->async.priv = &i;
5664 i = 0;
5666 while (i < 5 * torture_numops) {
5667 event_loop_once(ev);
5670 result = true;
5671 fail:
5672 TALLOC_FREE(ev);
5673 return result;
5676 static double create_procs(bool (*fn)(int), bool *result)
5678 int i, status;
5679 volatile pid_t *child_status;
5680 volatile bool *child_status_out;
5681 int synccount;
5682 int tries = 8;
5684 synccount = 0;
5686 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5687 if (!child_status) {
5688 printf("Failed to setup shared memory\n");
5689 return -1;
5692 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5693 if (!child_status_out) {
5694 printf("Failed to setup result status shared memory\n");
5695 return -1;
5698 for (i = 0; i < nprocs; i++) {
5699 child_status[i] = 0;
5700 child_status_out[i] = True;
5703 start_timer();
5705 for (i=0;i<nprocs;i++) {
5706 procnum = i;
5707 if (fork() == 0) {
5708 pid_t mypid = getpid();
5709 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5711 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5713 while (1) {
5714 if (torture_open_connection(&current_cli, i)) break;
5715 if (tries-- == 0) {
5716 printf("pid %d failed to start\n", (int)getpid());
5717 _exit(1);
5719 smb_msleep(10);
5722 child_status[i] = getpid();
5724 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5726 child_status_out[i] = fn(i);
5727 _exit(0);
5731 do {
5732 synccount = 0;
5733 for (i=0;i<nprocs;i++) {
5734 if (child_status[i]) synccount++;
5736 if (synccount == nprocs) break;
5737 smb_msleep(10);
5738 } while (end_timer() < 30);
5740 if (synccount != nprocs) {
5741 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5742 *result = False;
5743 return end_timer();
5746 /* start the client load */
5747 start_timer();
5749 for (i=0;i<nprocs;i++) {
5750 child_status[i] = 0;
5753 printf("%d clients started\n", nprocs);
5755 for (i=0;i<nprocs;i++) {
5756 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5759 printf("\n");
5761 for (i=0;i<nprocs;i++) {
5762 if (!child_status_out[i]) {
5763 *result = False;
5766 return end_timer();
5769 #define FLAG_MULTIPROC 1
5771 static struct {
5772 const char *name;
5773 bool (*fn)(int);
5774 unsigned flags;
5775 } torture_ops[] = {
5776 {"FDPASS", run_fdpasstest, 0},
5777 {"LOCK1", run_locktest1, 0},
5778 {"LOCK2", run_locktest2, 0},
5779 {"LOCK3", run_locktest3, 0},
5780 {"LOCK4", run_locktest4, 0},
5781 {"LOCK5", run_locktest5, 0},
5782 {"LOCK6", run_locktest6, 0},
5783 {"LOCK7", run_locktest7, 0},
5784 {"UNLINK", run_unlinktest, 0},
5785 {"BROWSE", run_browsetest, 0},
5786 {"ATTR", run_attrtest, 0},
5787 {"TRANS2", run_trans2test, 0},
5788 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5789 {"TORTURE",run_torture, FLAG_MULTIPROC},
5790 {"RANDOMIPC", run_randomipc, 0},
5791 {"NEGNOWAIT", run_negprot_nowait, 0},
5792 {"NBENCH", run_nbench, 0},
5793 {"OPLOCK1", run_oplock1, 0},
5794 {"OPLOCK2", run_oplock2, 0},
5795 {"OPLOCK3", run_oplock3, 0},
5796 {"DIR", run_dirtest, 0},
5797 {"DIR1", run_dirtest1, 0},
5798 {"DENY1", torture_denytest1, 0},
5799 {"DENY2", torture_denytest2, 0},
5800 {"TCON", run_tcon_test, 0},
5801 {"TCONDEV", run_tcon_devtype_test, 0},
5802 {"RW1", run_readwritetest, 0},
5803 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5804 {"RW3", run_readwritelarge, 0},
5805 {"OPEN", run_opentest, 0},
5806 {"POSIX", run_simple_posix_open_test, 0},
5807 #if 1
5808 {"OPENATTR", run_openattrtest, 0},
5809 #endif
5810 {"XCOPY", run_xcopy, 0},
5811 {"RENAME", run_rename, 0},
5812 {"DELETE", run_deletetest, 0},
5813 {"PROPERTIES", run_properties, 0},
5814 {"MANGLE", torture_mangle, 0},
5815 {"W2K", run_w2ktest, 0},
5816 {"TRANS2SCAN", torture_trans2_scan, 0},
5817 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5818 {"UTABLE", torture_utable, 0},
5819 {"CASETABLE", torture_casetable, 0},
5820 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5821 {"PIPE_NUMBER", run_pipe_number, 0},
5822 {"TCON2", run_tcon2_test, 0},
5823 {"IOCTL", torture_ioctl_test, 0},
5824 {"CHKPATH", torture_chkpath_test, 0},
5825 {"FDSESS", run_fdsesstest, 0},
5826 { "EATEST", run_eatest, 0},
5827 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5828 { "CHAIN1", run_chain1, 0},
5829 { "WINDOWS-WRITE", run_windows_write, 0},
5830 { "CLI_ECHO", run_cli_echo, 0},
5831 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5832 { "LOCAL-GENCACHE", run_local_gencache, 0},
5833 { "LOCAL-RBTREE", run_local_rbtree, 0},
5834 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5835 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5836 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5837 {NULL, NULL, 0}};
5841 /****************************************************************************
5842 run a specified test or "ALL"
5843 ****************************************************************************/
5844 static bool run_test(const char *name)
5846 bool ret = True;
5847 bool result = True;
5848 bool found = False;
5849 int i;
5850 double t;
5851 if (strequal(name,"ALL")) {
5852 for (i=0;torture_ops[i].name;i++) {
5853 run_test(torture_ops[i].name);
5855 found = True;
5858 for (i=0;torture_ops[i].name;i++) {
5859 fstr_sprintf(randomfname, "\\XX%x",
5860 (unsigned)random());
5862 if (strequal(name, torture_ops[i].name)) {
5863 found = True;
5864 printf("Running %s\n", name);
5865 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5866 t = create_procs(torture_ops[i].fn, &result);
5867 if (!result) {
5868 ret = False;
5869 printf("TEST %s FAILED!\n", name);
5872 } else {
5873 start_timer();
5874 if (!torture_ops[i].fn(0)) {
5875 ret = False;
5876 printf("TEST %s FAILED!\n", name);
5878 t = end_timer();
5880 printf("%s took %g secs\n\n", name, t);
5884 if (!found) {
5885 printf("Did not find a test named %s\n", name);
5886 ret = False;
5889 return ret;
5893 static void usage(void)
5895 int i;
5897 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5898 printf("Please use samba4 torture.\n\n");
5900 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5902 printf("\t-d debuglevel\n");
5903 printf("\t-U user%%pass\n");
5904 printf("\t-k use kerberos\n");
5905 printf("\t-N numprocs\n");
5906 printf("\t-n my_netbios_name\n");
5907 printf("\t-W workgroup\n");
5908 printf("\t-o num_operations\n");
5909 printf("\t-O socket_options\n");
5910 printf("\t-m maximum protocol\n");
5911 printf("\t-L use oplocks\n");
5912 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5913 printf("\t-A showall\n");
5914 printf("\t-p port\n");
5915 printf("\t-s seed\n");
5916 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5917 printf("\n\n");
5919 printf("tests are:");
5920 for (i=0;torture_ops[i].name;i++) {
5921 printf(" %s", torture_ops[i].name);
5923 printf("\n");
5925 printf("default test is ALL\n");
5927 exit(1);
5930 /****************************************************************************
5931 main program
5932 ****************************************************************************/
5933 int main(int argc,char *argv[])
5935 int opt, i;
5936 char *p;
5937 int gotuser = 0;
5938 int gotpass = 0;
5939 bool correct = True;
5940 TALLOC_CTX *frame = talloc_stackframe();
5941 int seed = time(NULL);
5943 dbf = x_stdout;
5945 #ifdef HAVE_SETBUFFER
5946 setbuffer(stdout, NULL, 0);
5947 #endif
5949 load_case_tables();
5951 if (is_default_dyn_CONFIGFILE()) {
5952 if(getenv("SMB_CONF_PATH")) {
5953 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
5956 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
5957 load_interfaces();
5959 if (argc < 2) {
5960 usage();
5963 for(p = argv[1]; *p; p++)
5964 if(*p == '\\')
5965 *p = '/';
5967 if (strncmp(argv[1], "//", 2)) {
5968 usage();
5971 fstrcpy(host, &argv[1][2]);
5972 p = strchr_m(&host[2],'/');
5973 if (!p) {
5974 usage();
5976 *p = 0;
5977 fstrcpy(share, p+1);
5979 fstrcpy(myname, get_myname(talloc_tos()));
5980 if (!*myname) {
5981 fprintf(stderr, "Failed to get my hostname.\n");
5982 return 1;
5985 if (*username == 0 && getenv("LOGNAME")) {
5986 fstrcpy(username,getenv("LOGNAME"));
5989 argc--;
5990 argv++;
5992 fstrcpy(workgroup, lp_workgroup());
5994 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
5995 switch (opt) {
5996 case 'p':
5997 port_to_use = atoi(optarg);
5998 break;
5999 case 's':
6000 seed = atoi(optarg);
6001 break;
6002 case 'W':
6003 fstrcpy(workgroup,optarg);
6004 break;
6005 case 'm':
6006 max_protocol = interpret_protocol(optarg, max_protocol);
6007 break;
6008 case 'N':
6009 nprocs = atoi(optarg);
6010 break;
6011 case 'o':
6012 torture_numops = atoi(optarg);
6013 break;
6014 case 'd':
6015 DEBUGLEVEL = atoi(optarg);
6016 break;
6017 case 'O':
6018 sockops = optarg;
6019 break;
6020 case 'L':
6021 use_oplocks = True;
6022 break;
6023 case 'A':
6024 torture_showall = True;
6025 break;
6026 case 'n':
6027 fstrcpy(myname, optarg);
6028 break;
6029 case 'c':
6030 client_txt = optarg;
6031 break;
6032 case 'e':
6033 do_encrypt = true;
6034 break;
6035 case 'k':
6036 #ifdef HAVE_KRB5
6037 use_kerberos = True;
6038 #else
6039 d_printf("No kerberos support compiled in\n");
6040 exit(1);
6041 #endif
6042 break;
6043 case 'U':
6044 gotuser = 1;
6045 fstrcpy(username,optarg);
6046 p = strchr_m(username,'%');
6047 if (p) {
6048 *p = 0;
6049 fstrcpy(password, p+1);
6050 gotpass = 1;
6052 break;
6053 case 'b':
6054 fstrcpy(multishare_conn_fname, optarg);
6055 use_multishare_conn = True;
6056 break;
6057 case 'B':
6058 torture_blocksize = atoi(optarg);
6059 break;
6060 default:
6061 printf("Unknown option %c (%d)\n", (char)opt, opt);
6062 usage();
6066 d_printf("using seed %d\n", seed);
6068 srandom(seed);
6070 if(use_kerberos && !gotuser) gotpass = True;
6072 while (!gotpass) {
6073 p = getpass("Password:");
6074 if (p) {
6075 fstrcpy(password, p);
6076 gotpass = 1;
6080 printf("host=%s share=%s user=%s myname=%s\n",
6081 host, share, username, myname);
6083 if (argc == optind) {
6084 correct = run_test("ALL");
6085 } else {
6086 for (i=optind;i<argc;i++) {
6087 if (!run_test(argv[i])) {
6088 correct = False;
6093 TALLOC_FREE(frame);
6095 if (correct) {
6096 return(0);
6097 } else {
6098 return(1);