Use an absolute path to ensure that we can always regenerate tables.c
[Samba/bb.git] / source3 / torture / torture.c
blob804e77251638238937bf4451e95562695a2a64c6
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;
276 if (use_oplocks)
277 flags |= CLI_FULL_CONNECTION_OPLOCKS;
278 if (use_level_II_oplocks)
279 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
281 status = cli_full_connection(c, myname,
282 hostname, NULL, port_to_use,
283 sharename, "?????",
284 username, workgroup,
285 password, flags, Undefined, &retry);
286 if (!NT_STATUS_IS_OK(status)) {
287 printf("failed to open share connection: //%s/%s port:%d - %s\n",
288 hostname, sharename, port_to_use, nt_errstr(status));
289 return False;
292 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
294 if (do_encrypt) {
295 return force_cli_encryption(*c,
296 sharename);
298 return True;
301 bool torture_open_connection(struct cli_state **c, int conn_index)
303 char **unc_list = NULL;
304 int num_unc_names = 0;
305 bool result;
307 if (use_multishare_conn==True) {
308 char *h, *s;
309 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
310 if (!unc_list || num_unc_names <= 0) {
311 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
312 exit(1);
315 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
316 NULL, &h, &s)) {
317 printf("Failed to parse UNC name %s\n",
318 unc_list[conn_index % num_unc_names]);
319 TALLOC_FREE(unc_list);
320 exit(1);
323 result = torture_open_connection_share(c, h, s);
325 /* h, s were copied earlier */
326 TALLOC_FREE(unc_list);
327 return result;
330 return torture_open_connection_share(c, host, share);
333 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
335 uint16 old_vuid = cli->vuid;
336 fstring old_user_name;
337 size_t passlen = strlen(password);
338 NTSTATUS status;
339 bool ret;
341 fstrcpy(old_user_name, cli->user_name);
342 cli->vuid = 0;
343 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
344 password, passlen,
345 password, passlen,
346 workgroup));
347 *new_vuid = cli->vuid;
348 cli->vuid = old_vuid;
349 status = cli_set_username(cli, old_user_name);
350 if (!NT_STATUS_IS_OK(status)) {
351 return false;
353 return ret;
357 bool torture_close_connection(struct cli_state *c)
359 bool ret = True;
360 if (!cli_tdis(c)) {
361 printf("tdis failed (%s)\n", cli_errstr(c));
362 ret = False;
365 cli_shutdown(c);
367 return ret;
371 /* check if the server produced the expected error code */
372 static bool check_error(int line, struct cli_state *c,
373 uint8 eclass, uint32 ecode, NTSTATUS nterr)
375 if (cli_is_dos_error(c)) {
376 uint8 cclass;
377 uint32 num;
379 /* Check DOS error */
381 cli_dos_error(c, &cclass, &num);
383 if (eclass != cclass || ecode != num) {
384 printf("unexpected error code class=%d code=%d\n",
385 (int)cclass, (int)num);
386 printf(" expected %d/%d %s (line=%d)\n",
387 (int)eclass, (int)ecode, nt_errstr(nterr), line);
388 return False;
391 } else {
392 NTSTATUS status;
394 /* Check NT error */
396 status = cli_nt_error(c);
398 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
399 printf("unexpected error code %s\n", nt_errstr(status));
400 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
401 return False;
405 return True;
409 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
411 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
412 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
414 return True;
418 static bool rw_torture(struct cli_state *c)
420 const char *lockfname = "\\torture.lck";
421 fstring fname;
422 int fnum;
423 int fnum2;
424 pid_t pid2, pid = getpid();
425 int i, j;
426 char buf[1024];
427 bool correct = True;
429 memset(buf, '\0', sizeof(buf));
431 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
432 DENY_NONE);
433 if (fnum2 == -1)
434 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
435 if (fnum2 == -1) {
436 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
437 return False;
441 for (i=0;i<torture_numops;i++) {
442 unsigned n = (unsigned)sys_random()%10;
443 if (i % 10 == 0) {
444 printf("%d\r", i); fflush(stdout);
446 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
448 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
449 return False;
452 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
453 if (fnum == -1) {
454 printf("open failed (%s)\n", cli_errstr(c));
455 correct = False;
456 break;
459 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
460 printf("write failed (%s)\n", cli_errstr(c));
461 correct = False;
464 for (j=0;j<50;j++) {
465 if (cli_write(c, fnum, 0, (char *)buf,
466 sizeof(pid)+(j*sizeof(buf)),
467 sizeof(buf)) != sizeof(buf)) {
468 printf("write failed (%s)\n", cli_errstr(c));
469 correct = False;
473 pid2 = 0;
475 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
476 printf("read failed (%s)\n", cli_errstr(c));
477 correct = False;
480 if (pid2 != pid) {
481 printf("data corruption!\n");
482 correct = False;
485 if (!cli_close(c, fnum)) {
486 printf("close failed (%s)\n", cli_errstr(c));
487 correct = False;
490 if (!cli_unlink(c, fname)) {
491 printf("unlink failed (%s)\n", cli_errstr(c));
492 correct = False;
495 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
496 printf("unlock failed (%s)\n", cli_errstr(c));
497 correct = False;
501 cli_close(c, fnum2);
502 cli_unlink(c, lockfname);
504 printf("%d\n", i);
506 return correct;
509 static bool run_torture(int dummy)
511 struct cli_state *cli;
512 bool ret;
514 cli = current_cli;
516 cli_sockopt(cli, sockops);
518 ret = rw_torture(cli);
520 if (!torture_close_connection(cli)) {
521 ret = False;
524 return ret;
527 static bool rw_torture3(struct cli_state *c, char *lockfname)
529 int fnum = -1;
530 unsigned int i = 0;
531 char buf[131072];
532 char buf_rd[131072];
533 unsigned count;
534 unsigned countprev = 0;
535 ssize_t sent = 0;
536 bool correct = True;
538 srandom(1);
539 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
541 SIVAL(buf, i, sys_random());
544 if (procnum == 0)
546 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
547 DENY_NONE);
548 if (fnum == -1) {
549 printf("first open read/write of %s failed (%s)\n",
550 lockfname, cli_errstr(c));
551 return False;
554 else
556 for (i = 0; i < 500 && fnum == -1; i++)
558 fnum = cli_open(c, lockfname, O_RDONLY,
559 DENY_NONE);
560 smb_msleep(10);
562 if (fnum == -1) {
563 printf("second open read-only of %s failed (%s)\n",
564 lockfname, cli_errstr(c));
565 return False;
569 i = 0;
570 for (count = 0; count < sizeof(buf); count += sent)
572 if (count >= countprev) {
573 printf("%d %8d\r", i, count);
574 fflush(stdout);
575 i++;
576 countprev += (sizeof(buf) / 20);
579 if (procnum == 0)
581 sent = ((unsigned)sys_random()%(20))+ 1;
582 if (sent > sizeof(buf) - count)
584 sent = sizeof(buf) - count;
587 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
588 printf("write failed (%s)\n", cli_errstr(c));
589 correct = False;
592 else
594 sent = cli_read(c, fnum, buf_rd+count, count,
595 sizeof(buf)-count);
596 if (sent < 0)
598 printf("read failed offset:%d size:%ld (%s)\n",
599 count, (unsigned long)sizeof(buf)-count,
600 cli_errstr(c));
601 correct = False;
602 sent = 0;
604 if (sent > 0)
606 if (memcmp(buf_rd+count, buf+count, sent) != 0)
608 printf("read/write compare failed\n");
609 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
610 correct = False;
611 break;
618 if (!cli_close(c, fnum)) {
619 printf("close failed (%s)\n", cli_errstr(c));
620 correct = False;
623 return correct;
626 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
628 const char *lockfname = "\\torture2.lck";
629 int fnum1;
630 int fnum2;
631 int i;
632 char buf[131072];
633 char buf_rd[131072];
634 bool correct = True;
635 ssize_t bytes_read;
637 if (!cli_unlink(c1, lockfname)) {
638 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
641 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
642 DENY_NONE);
643 if (fnum1 == -1) {
644 printf("first open read/write of %s failed (%s)\n",
645 lockfname, cli_errstr(c1));
646 return False;
648 fnum2 = cli_open(c2, lockfname, O_RDONLY,
649 DENY_NONE);
650 if (fnum2 == -1) {
651 printf("second open read-only of %s failed (%s)\n",
652 lockfname, cli_errstr(c2));
653 cli_close(c1, fnum1);
654 return False;
657 for (i=0;i<torture_numops;i++)
659 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
660 if (i % 10 == 0) {
661 printf("%d\r", i); fflush(stdout);
664 generate_random_buffer((unsigned char *)buf, buf_size);
666 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
667 printf("write failed (%s)\n", cli_errstr(c1));
668 correct = False;
669 break;
672 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
673 printf("read failed (%s)\n", cli_errstr(c2));
674 printf("read %d, expected %ld\n", (int)bytes_read,
675 (unsigned long)buf_size);
676 correct = False;
677 break;
680 if (memcmp(buf_rd, buf, buf_size) != 0)
682 printf("read/write compare failed\n");
683 correct = False;
684 break;
688 if (!cli_close(c2, fnum2)) {
689 printf("close failed (%s)\n", cli_errstr(c2));
690 correct = False;
692 if (!cli_close(c1, fnum1)) {
693 printf("close failed (%s)\n", cli_errstr(c1));
694 correct = False;
697 if (!cli_unlink(c1, lockfname)) {
698 printf("unlink failed (%s)\n", cli_errstr(c1));
699 correct = False;
702 return correct;
705 static bool run_readwritetest(int dummy)
707 static struct cli_state *cli1, *cli2;
708 bool test1, test2 = False;
710 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
711 return False;
713 cli_sockopt(cli1, sockops);
714 cli_sockopt(cli2, sockops);
716 printf("starting readwritetest\n");
718 test1 = rw_torture2(cli1, cli2);
719 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
721 if (test1) {
722 test2 = rw_torture2(cli1, cli1);
723 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
726 if (!torture_close_connection(cli1)) {
727 test1 = False;
730 if (!torture_close_connection(cli2)) {
731 test2 = False;
734 return (test1 && test2);
737 static bool run_readwritemulti(int dummy)
739 struct cli_state *cli;
740 bool test;
742 cli = current_cli;
744 cli_sockopt(cli, sockops);
746 printf("run_readwritemulti: fname %s\n", randomfname);
747 test = rw_torture3(cli, randomfname);
749 if (!torture_close_connection(cli)) {
750 test = False;
753 return test;
756 static bool run_readwritelarge(int dummy)
758 static struct cli_state *cli1;
759 int fnum1;
760 const char *lockfname = "\\large.dat";
761 SMB_OFF_T fsize;
762 char buf[126*1024];
763 bool correct = True;
765 if (!torture_open_connection(&cli1, 0)) {
766 return False;
768 cli_sockopt(cli1, sockops);
769 memset(buf,'\0',sizeof(buf));
771 cli1->max_xmit = 128*1024;
773 printf("starting readwritelarge\n");
775 cli_unlink(cli1, lockfname);
777 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
778 if (fnum1 == -1) {
779 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
780 return False;
783 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
785 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
786 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
787 correct = False;
790 if (fsize == sizeof(buf))
791 printf("readwritelarge test 1 succeeded (size = %lx)\n",
792 (unsigned long)fsize);
793 else {
794 printf("readwritelarge test 1 failed (size = %lx)\n",
795 (unsigned long)fsize);
796 correct = False;
799 if (!cli_close(cli1, fnum1)) {
800 printf("close failed (%s)\n", cli_errstr(cli1));
801 correct = False;
804 if (!cli_unlink(cli1, lockfname)) {
805 printf("unlink failed (%s)\n", cli_errstr(cli1));
806 correct = False;
809 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
810 if (fnum1 == -1) {
811 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
812 return False;
815 cli1->max_xmit = 4*1024;
817 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
819 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
820 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
821 correct = False;
824 if (fsize == sizeof(buf))
825 printf("readwritelarge test 2 succeeded (size = %lx)\n",
826 (unsigned long)fsize);
827 else {
828 printf("readwritelarge test 2 failed (size = %lx)\n",
829 (unsigned long)fsize);
830 correct = False;
833 #if 0
834 /* ToDo - set allocation. JRA */
835 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
836 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
837 return False;
839 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
840 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
841 correct = False;
843 if (fsize != 0)
844 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
845 #endif
847 if (!cli_close(cli1, fnum1)) {
848 printf("close failed (%s)\n", cli_errstr(cli1));
849 correct = False;
852 if (!torture_close_connection(cli1)) {
853 correct = False;
855 return correct;
858 int line_count = 0;
859 int nbio_id;
861 #define ival(s) strtol(s, NULL, 0)
863 /* run a test that simulates an approximate netbench client load */
864 static bool run_netbench(int client)
866 struct cli_state *cli;
867 int i;
868 char line[1024];
869 char cname[20];
870 FILE *f;
871 const char *params[20];
872 bool correct = True;
874 cli = current_cli;
876 nbio_id = client;
878 cli_sockopt(cli, sockops);
880 nb_setup(cli);
882 slprintf(cname,sizeof(cname)-1, "client%d", client);
884 f = fopen(client_txt, "r");
886 if (!f) {
887 perror(client_txt);
888 return False;
891 while (fgets(line, sizeof(line)-1, f)) {
892 char *saveptr;
893 line_count++;
895 line[strlen(line)-1] = 0;
897 /* printf("[%d] %s\n", line_count, line); */
899 all_string_sub(line,"client1", cname, sizeof(line));
901 /* parse the command parameters */
902 params[0] = strtok_r(line, " ", &saveptr);
903 i = 0;
904 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
906 params[i] = "";
908 if (i < 2) continue;
910 if (!strncmp(params[0],"SMB", 3)) {
911 printf("ERROR: You are using a dbench 1 load file\n");
912 exit(1);
915 if (!strcmp(params[0],"NTCreateX")) {
916 nb_createx(params[1], ival(params[2]), ival(params[3]),
917 ival(params[4]));
918 } else if (!strcmp(params[0],"Close")) {
919 nb_close(ival(params[1]));
920 } else if (!strcmp(params[0],"Rename")) {
921 nb_rename(params[1], params[2]);
922 } else if (!strcmp(params[0],"Unlink")) {
923 nb_unlink(params[1]);
924 } else if (!strcmp(params[0],"Deltree")) {
925 nb_deltree(params[1]);
926 } else if (!strcmp(params[0],"Rmdir")) {
927 nb_rmdir(params[1]);
928 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
929 nb_qpathinfo(params[1]);
930 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
931 nb_qfileinfo(ival(params[1]));
932 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
933 nb_qfsinfo(ival(params[1]));
934 } else if (!strcmp(params[0],"FIND_FIRST")) {
935 nb_findfirst(params[1]);
936 } else if (!strcmp(params[0],"WriteX")) {
937 nb_writex(ival(params[1]),
938 ival(params[2]), ival(params[3]), ival(params[4]));
939 } else if (!strcmp(params[0],"ReadX")) {
940 nb_readx(ival(params[1]),
941 ival(params[2]), ival(params[3]), ival(params[4]));
942 } else if (!strcmp(params[0],"Flush")) {
943 nb_flush(ival(params[1]));
944 } else {
945 printf("Unknown operation %s\n", params[0]);
946 exit(1);
949 fclose(f);
951 nb_cleanup();
953 if (!torture_close_connection(cli)) {
954 correct = False;
957 return correct;
961 /* run a test that simulates an approximate netbench client load */
962 static bool run_nbench(int dummy)
964 double t;
965 bool correct = True;
967 nbio_shmem(nprocs);
969 nbio_id = -1;
971 signal(SIGALRM, nb_alarm);
972 alarm(1);
973 t = create_procs(run_netbench, &correct);
974 alarm(0);
976 printf("\nThroughput %g MB/sec\n",
977 1.0e-6 * nbio_total() / t);
978 return correct;
983 This test checks for two things:
985 1) correct support for retaining locks over a close (ie. the server
986 must not use posix semantics)
987 2) support for lock timeouts
989 static bool run_locktest1(int dummy)
991 struct cli_state *cli1, *cli2;
992 const char *fname = "\\lockt1.lck";
993 int fnum1, fnum2, fnum3;
994 time_t t1, t2;
995 unsigned lock_timeout;
997 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
998 return False;
1000 cli_sockopt(cli1, sockops);
1001 cli_sockopt(cli2, sockops);
1003 printf("starting locktest1\n");
1005 cli_unlink(cli1, fname);
1007 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1008 if (fnum1 == -1) {
1009 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1010 return False;
1012 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1013 if (fnum2 == -1) {
1014 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1015 return False;
1017 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1018 if (fnum3 == -1) {
1019 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1020 return False;
1023 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1024 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1025 return False;
1029 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1030 printf("lock2 succeeded! This is a locking bug\n");
1031 return False;
1032 } else {
1033 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1034 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1038 lock_timeout = (1 + (random() % 20));
1039 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1040 t1 = time(NULL);
1041 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1042 printf("lock3 succeeded! This is a locking bug\n");
1043 return False;
1044 } else {
1045 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1046 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1048 t2 = time(NULL);
1050 if (ABS(t2 - t1) < lock_timeout-1) {
1051 printf("error: This server appears not to support timed lock requests\n");
1054 printf("server slept for %u seconds for a %u second timeout\n",
1055 (unsigned int)(t2-t1), lock_timeout);
1057 if (!cli_close(cli1, fnum2)) {
1058 printf("close1 failed (%s)\n", cli_errstr(cli1));
1059 return False;
1062 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1063 printf("lock4 succeeded! This is a locking bug\n");
1064 return False;
1065 } else {
1066 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1067 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1070 if (!cli_close(cli1, fnum1)) {
1071 printf("close2 failed (%s)\n", cli_errstr(cli1));
1072 return False;
1075 if (!cli_close(cli2, fnum3)) {
1076 printf("close3 failed (%s)\n", cli_errstr(cli2));
1077 return False;
1080 if (!cli_unlink(cli1, fname)) {
1081 printf("unlink failed (%s)\n", cli_errstr(cli1));
1082 return False;
1086 if (!torture_close_connection(cli1)) {
1087 return False;
1090 if (!torture_close_connection(cli2)) {
1091 return False;
1094 printf("Passed locktest1\n");
1095 return True;
1099 this checks to see if a secondary tconx can use open files from an
1100 earlier tconx
1102 static bool run_tcon_test(int dummy)
1104 static struct cli_state *cli;
1105 const char *fname = "\\tcontest.tmp";
1106 int fnum1;
1107 uint16 cnum1, cnum2, cnum3;
1108 uint16 vuid1, vuid2;
1109 char buf[4];
1110 bool ret = True;
1111 NTSTATUS status;
1113 memset(buf, '\0', sizeof(buf));
1115 if (!torture_open_connection(&cli, 0)) {
1116 return False;
1118 cli_sockopt(cli, sockops);
1120 printf("starting tcontest\n");
1122 cli_unlink(cli, fname);
1124 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1125 if (fnum1 == -1) {
1126 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1127 return False;
1130 cnum1 = cli->cnum;
1131 vuid1 = cli->vuid;
1133 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1134 printf("initial write failed (%s)", cli_errstr(cli));
1135 return False;
1138 status = cli_tcon_andx(cli, share, "?????",
1139 password, strlen(password)+1);
1140 if (!NT_STATUS_IS_OK(status)) {
1141 printf("%s refused 2nd tree connect (%s)\n", host,
1142 nt_errstr(status));
1143 cli_shutdown(cli);
1144 return False;
1147 cnum2 = cli->cnum;
1148 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1149 vuid2 = cli->vuid + 1;
1151 /* try a write with the wrong tid */
1152 cli->cnum = cnum2;
1154 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1155 printf("* server allows write with wrong TID\n");
1156 ret = False;
1157 } else {
1158 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1162 /* try a write with an invalid tid */
1163 cli->cnum = cnum3;
1165 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1166 printf("* server allows write with invalid TID\n");
1167 ret = False;
1168 } else {
1169 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1172 /* try a write with an invalid vuid */
1173 cli->vuid = vuid2;
1174 cli->cnum = cnum1;
1176 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1177 printf("* server allows write with invalid VUID\n");
1178 ret = False;
1179 } else {
1180 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1183 cli->cnum = cnum1;
1184 cli->vuid = vuid1;
1186 if (!cli_close(cli, fnum1)) {
1187 printf("close failed (%s)\n", cli_errstr(cli));
1188 return False;
1191 cli->cnum = cnum2;
1193 if (!cli_tdis(cli)) {
1194 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1195 return False;
1198 cli->cnum = cnum1;
1200 if (!torture_close_connection(cli)) {
1201 return False;
1204 return ret;
1209 checks for old style tcon support
1211 static bool run_tcon2_test(int dummy)
1213 static struct cli_state *cli;
1214 uint16 cnum, max_xmit;
1215 char *service;
1216 NTSTATUS status;
1218 if (!torture_open_connection(&cli, 0)) {
1219 return False;
1221 cli_sockopt(cli, sockops);
1223 printf("starting tcon2 test\n");
1225 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1226 return false;
1229 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1231 if (!NT_STATUS_IS_OK(status)) {
1232 printf("tcon2 failed : %s\n", cli_errstr(cli));
1233 } else {
1234 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1235 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1238 if (!torture_close_connection(cli)) {
1239 return False;
1242 printf("Passed tcon2 test\n");
1243 return True;
1246 static bool tcon_devtest(struct cli_state *cli,
1247 const char *myshare, const char *devtype,
1248 const char *return_devtype,
1249 NTSTATUS expected_error)
1251 NTSTATUS status;
1252 bool ret;
1254 status = cli_tcon_andx(cli, myshare, devtype,
1255 password, strlen(password)+1);
1257 if (NT_STATUS_IS_OK(expected_error)) {
1258 if (NT_STATUS_IS_OK(status)) {
1259 if (strcmp(cli->dev, return_devtype) == 0) {
1260 ret = True;
1261 } else {
1262 printf("tconX to share %s with type %s "
1263 "succeeded but returned the wrong "
1264 "device type (got [%s] but should have got [%s])\n",
1265 myshare, devtype, cli->dev, return_devtype);
1266 ret = False;
1268 } else {
1269 printf("tconX to share %s with type %s "
1270 "should have succeeded but failed\n",
1271 myshare, devtype);
1272 ret = False;
1274 cli_tdis(cli);
1275 } else {
1276 if (NT_STATUS_IS_OK(status)) {
1277 printf("tconx to share %s with type %s "
1278 "should have failed but succeeded\n",
1279 myshare, devtype);
1280 ret = False;
1281 } else {
1282 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1283 expected_error)) {
1284 ret = True;
1285 } else {
1286 printf("Returned unexpected error\n");
1287 ret = False;
1291 return ret;
1295 checks for correct tconX support
1297 static bool run_tcon_devtype_test(int dummy)
1299 static struct cli_state *cli1 = NULL;
1300 bool retry;
1301 int flags = 0;
1302 NTSTATUS status;
1303 bool ret = True;
1305 status = cli_full_connection(&cli1, myname,
1306 host, NULL, port_to_use,
1307 NULL, NULL,
1308 username, workgroup,
1309 password, flags, Undefined, &retry);
1311 if (!NT_STATUS_IS_OK(status)) {
1312 printf("could not open connection\n");
1313 return False;
1316 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1317 ret = False;
1319 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1320 ret = False;
1322 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1323 ret = False;
1325 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1326 ret = False;
1328 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1329 ret = False;
1331 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1332 ret = False;
1334 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1335 ret = False;
1337 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338 ret = False;
1340 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1341 ret = False;
1343 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1344 ret = False;
1346 cli_shutdown(cli1);
1348 if (ret)
1349 printf("Passed tcondevtest\n");
1351 return ret;
1356 This test checks that
1358 1) the server supports multiple locking contexts on the one SMB
1359 connection, distinguished by PID.
1361 2) the server correctly fails overlapping locks made by the same PID (this
1362 goes against POSIX behaviour, which is why it is tricky to implement)
1364 3) the server denies unlock requests by an incorrect client PID
1366 static bool run_locktest2(int dummy)
1368 static struct cli_state *cli;
1369 const char *fname = "\\lockt2.lck";
1370 int fnum1, fnum2, fnum3;
1371 bool correct = True;
1373 if (!torture_open_connection(&cli, 0)) {
1374 return False;
1377 cli_sockopt(cli, sockops);
1379 printf("starting locktest2\n");
1381 cli_unlink(cli, fname);
1383 cli_setpid(cli, 1);
1385 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1386 if (fnum1 == -1) {
1387 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1388 return False;
1391 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1392 if (fnum2 == -1) {
1393 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1394 return False;
1397 cli_setpid(cli, 2);
1399 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1400 if (fnum3 == -1) {
1401 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1402 return False;
1405 cli_setpid(cli, 1);
1407 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1408 printf("lock1 failed (%s)\n", cli_errstr(cli));
1409 return False;
1412 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1413 printf("WRITE lock1 succeeded! This is a locking bug\n");
1414 correct = False;
1415 } else {
1416 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1417 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1420 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1421 printf("WRITE lock2 succeeded! This is a locking bug\n");
1422 correct = False;
1423 } else {
1424 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1425 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1428 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1429 printf("READ lock2 succeeded! This is a locking bug\n");
1430 correct = False;
1431 } else {
1432 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1433 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1436 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1437 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1439 cli_setpid(cli, 2);
1440 if (cli_unlock(cli, fnum1, 100, 4)) {
1441 printf("unlock at 100 succeeded! This is a locking bug\n");
1442 correct = False;
1445 if (cli_unlock(cli, fnum1, 0, 4)) {
1446 printf("unlock1 succeeded! This is a locking bug\n");
1447 correct = False;
1448 } else {
1449 if (!check_error(__LINE__, cli,
1450 ERRDOS, ERRlock,
1451 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1454 if (cli_unlock(cli, fnum1, 0, 8)) {
1455 printf("unlock2 succeeded! This is a locking bug\n");
1456 correct = False;
1457 } else {
1458 if (!check_error(__LINE__, cli,
1459 ERRDOS, ERRlock,
1460 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1463 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1464 printf("lock3 succeeded! This is a locking bug\n");
1465 correct = False;
1466 } else {
1467 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1470 cli_setpid(cli, 1);
1472 if (!cli_close(cli, fnum1)) {
1473 printf("close1 failed (%s)\n", cli_errstr(cli));
1474 return False;
1477 if (!cli_close(cli, fnum2)) {
1478 printf("close2 failed (%s)\n", cli_errstr(cli));
1479 return False;
1482 if (!cli_close(cli, fnum3)) {
1483 printf("close3 failed (%s)\n", cli_errstr(cli));
1484 return False;
1487 if (!torture_close_connection(cli)) {
1488 correct = False;
1491 printf("locktest2 finished\n");
1493 return correct;
1498 This test checks that
1500 1) the server supports the full offset range in lock requests
1502 static bool run_locktest3(int dummy)
1504 static struct cli_state *cli1, *cli2;
1505 const char *fname = "\\lockt3.lck";
1506 int fnum1, fnum2, i;
1507 uint32 offset;
1508 bool correct = True;
1510 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1512 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1513 return False;
1515 cli_sockopt(cli1, sockops);
1516 cli_sockopt(cli2, sockops);
1518 printf("starting locktest3\n");
1520 cli_unlink(cli1, fname);
1522 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1523 if (fnum1 == -1) {
1524 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1525 return False;
1527 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1528 if (fnum2 == -1) {
1529 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1530 return False;
1533 for (offset=i=0;i<torture_numops;i++) {
1534 NEXT_OFFSET;
1535 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1536 printf("lock1 %d failed (%s)\n",
1538 cli_errstr(cli1));
1539 return False;
1542 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1543 printf("lock2 %d failed (%s)\n",
1545 cli_errstr(cli1));
1546 return False;
1550 for (offset=i=0;i<torture_numops;i++) {
1551 NEXT_OFFSET;
1553 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1554 printf("error: lock1 %d succeeded!\n", i);
1555 return False;
1558 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1559 printf("error: lock2 %d succeeded!\n", i);
1560 return False;
1563 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1564 printf("error: lock3 %d succeeded!\n", i);
1565 return False;
1568 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1569 printf("error: lock4 %d succeeded!\n", i);
1570 return False;
1574 for (offset=i=0;i<torture_numops;i++) {
1575 NEXT_OFFSET;
1577 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1578 printf("unlock1 %d failed (%s)\n",
1580 cli_errstr(cli1));
1581 return False;
1584 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1585 printf("unlock2 %d failed (%s)\n",
1587 cli_errstr(cli1));
1588 return False;
1592 if (!cli_close(cli1, fnum1)) {
1593 printf("close1 failed (%s)\n", cli_errstr(cli1));
1594 return False;
1597 if (!cli_close(cli2, fnum2)) {
1598 printf("close2 failed (%s)\n", cli_errstr(cli2));
1599 return False;
1602 if (!cli_unlink(cli1, fname)) {
1603 printf("unlink failed (%s)\n", cli_errstr(cli1));
1604 return False;
1607 if (!torture_close_connection(cli1)) {
1608 correct = False;
1611 if (!torture_close_connection(cli2)) {
1612 correct = False;
1615 printf("finished locktest3\n");
1617 return correct;
1620 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1621 printf("** "); correct = False; \
1625 looks at overlapping locks
1627 static bool run_locktest4(int dummy)
1629 static struct cli_state *cli1, *cli2;
1630 const char *fname = "\\lockt4.lck";
1631 int fnum1, fnum2, f;
1632 bool ret;
1633 char buf[1000];
1634 bool correct = True;
1636 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1637 return False;
1640 cli_sockopt(cli1, sockops);
1641 cli_sockopt(cli2, sockops);
1643 printf("starting locktest4\n");
1645 cli_unlink(cli1, fname);
1647 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1648 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1650 memset(buf, 0, sizeof(buf));
1652 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1653 printf("Failed to create file\n");
1654 correct = False;
1655 goto fail;
1658 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1659 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1660 EXPECTED(ret, False);
1661 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1663 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1664 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1665 EXPECTED(ret, True);
1666 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1668 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1669 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1670 EXPECTED(ret, False);
1671 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1673 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1674 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1675 EXPECTED(ret, True);
1676 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1678 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1679 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1680 EXPECTED(ret, False);
1681 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1683 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1684 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1685 EXPECTED(ret, True);
1686 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1688 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1689 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1690 EXPECTED(ret, True);
1691 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1693 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1694 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1695 EXPECTED(ret, False);
1696 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1698 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1699 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1700 EXPECTED(ret, False);
1701 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1703 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1704 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1705 EXPECTED(ret, True);
1706 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1708 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1709 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1710 EXPECTED(ret, False);
1711 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1713 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1714 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1715 cli_unlock(cli1, fnum1, 110, 6);
1716 EXPECTED(ret, False);
1717 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1720 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1721 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1722 EXPECTED(ret, False);
1723 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1725 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1726 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1727 EXPECTED(ret, False);
1728 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1731 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1732 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1733 cli_unlock(cli1, fnum1, 140, 4) &&
1734 cli_unlock(cli1, fnum1, 140, 4);
1735 EXPECTED(ret, True);
1736 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1739 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1740 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1741 cli_unlock(cli1, fnum1, 150, 4) &&
1742 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1743 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1744 cli_unlock(cli1, fnum1, 150, 4);
1745 EXPECTED(ret, True);
1746 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1748 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1749 cli_unlock(cli1, fnum1, 160, 4) &&
1750 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1751 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1752 EXPECTED(ret, True);
1753 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1755 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1756 cli_unlock(cli1, fnum1, 170, 4) &&
1757 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1758 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1759 EXPECTED(ret, True);
1760 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1762 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1763 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1764 cli_unlock(cli1, fnum1, 190, 4) &&
1765 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1766 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1767 EXPECTED(ret, True);
1768 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1770 cli_close(cli1, fnum1);
1771 cli_close(cli2, fnum2);
1772 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1773 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1774 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1775 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1776 cli_close(cli1, fnum1) &&
1777 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1778 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1779 cli_close(cli1, f);
1780 cli_close(cli1, fnum1);
1781 EXPECTED(ret, True);
1782 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1784 fail:
1785 cli_close(cli1, fnum1);
1786 cli_close(cli2, fnum2);
1787 cli_unlink(cli1, fname);
1788 torture_close_connection(cli1);
1789 torture_close_connection(cli2);
1791 printf("finished locktest4\n");
1792 return correct;
1796 looks at lock upgrade/downgrade.
1798 static bool run_locktest5(int dummy)
1800 static struct cli_state *cli1, *cli2;
1801 const char *fname = "\\lockt5.lck";
1802 int fnum1, fnum2, fnum3;
1803 bool ret;
1804 char buf[1000];
1805 bool correct = True;
1807 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1808 return False;
1811 cli_sockopt(cli1, sockops);
1812 cli_sockopt(cli2, sockops);
1814 printf("starting locktest5\n");
1816 cli_unlink(cli1, fname);
1818 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1819 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1820 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1822 memset(buf, 0, sizeof(buf));
1824 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1825 printf("Failed to create file\n");
1826 correct = False;
1827 goto fail;
1830 /* Check for NT bug... */
1831 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1832 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1833 cli_close(cli1, fnum1);
1834 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1835 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1836 EXPECTED(ret, True);
1837 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1838 cli_close(cli1, fnum1);
1839 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1840 cli_unlock(cli1, fnum3, 0, 1);
1842 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1843 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1844 EXPECTED(ret, True);
1845 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1847 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1848 EXPECTED(ret, False);
1850 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1852 /* Unlock the process 2 lock. */
1853 cli_unlock(cli2, fnum2, 0, 4);
1855 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1856 EXPECTED(ret, False);
1858 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1860 /* Unlock the process 1 fnum3 lock. */
1861 cli_unlock(cli1, fnum3, 0, 4);
1863 /* Stack 2 more locks here. */
1864 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1865 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1867 EXPECTED(ret, True);
1868 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1870 /* Unlock the first process lock, then check this was the WRITE lock that was
1871 removed. */
1873 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1874 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1876 EXPECTED(ret, True);
1877 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1879 /* Unlock the process 2 lock. */
1880 cli_unlock(cli2, fnum2, 0, 4);
1882 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1884 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1885 cli_unlock(cli1, fnum1, 0, 4) &&
1886 cli_unlock(cli1, fnum1, 0, 4);
1888 EXPECTED(ret, True);
1889 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1891 /* Ensure the next unlock fails. */
1892 ret = cli_unlock(cli1, fnum1, 0, 4);
1893 EXPECTED(ret, False);
1894 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1896 /* Ensure connection 2 can get a write lock. */
1897 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1898 EXPECTED(ret, True);
1900 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1903 fail:
1904 cli_close(cli1, fnum1);
1905 cli_close(cli2, fnum2);
1906 cli_unlink(cli1, fname);
1907 if (!torture_close_connection(cli1)) {
1908 correct = False;
1910 if (!torture_close_connection(cli2)) {
1911 correct = False;
1914 printf("finished locktest5\n");
1916 return correct;
1920 tries the unusual lockingX locktype bits
1922 static bool run_locktest6(int dummy)
1924 static struct cli_state *cli;
1925 const char *fname[1] = { "\\lock6.txt" };
1926 int i;
1927 int fnum;
1928 NTSTATUS status;
1930 if (!torture_open_connection(&cli, 0)) {
1931 return False;
1934 cli_sockopt(cli, sockops);
1936 printf("starting locktest6\n");
1938 for (i=0;i<1;i++) {
1939 printf("Testing %s\n", fname[i]);
1941 cli_unlink(cli, fname[i]);
1943 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1944 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1945 cli_close(cli, fnum);
1946 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1948 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1949 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1950 cli_close(cli, fnum);
1951 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1953 cli_unlink(cli, fname[i]);
1956 torture_close_connection(cli);
1958 printf("finished locktest6\n");
1959 return True;
1962 static bool run_locktest7(int dummy)
1964 struct cli_state *cli1;
1965 const char *fname = "\\lockt7.lck";
1966 int fnum1;
1967 char buf[200];
1968 bool correct = False;
1970 if (!torture_open_connection(&cli1, 0)) {
1971 return False;
1974 cli_sockopt(cli1, sockops);
1976 printf("starting locktest7\n");
1978 cli_unlink(cli1, fname);
1980 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1982 memset(buf, 0, sizeof(buf));
1984 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1985 printf("Failed to create file\n");
1986 goto fail;
1989 cli_setpid(cli1, 1);
1991 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1992 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1993 goto fail;
1994 } else {
1995 printf("pid1 successfully locked range 130:4 for READ\n");
1998 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1999 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2000 goto fail;
2001 } else {
2002 printf("pid1 successfully read the range 130:4\n");
2005 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2006 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2007 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2008 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2009 goto fail;
2011 } else {
2012 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2013 goto fail;
2016 cli_setpid(cli1, 2);
2018 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2019 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2020 } else {
2021 printf("pid2 successfully read the range 130:4\n");
2024 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2025 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2026 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2027 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2028 goto fail;
2030 } else {
2031 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2032 goto fail;
2035 cli_setpid(cli1, 1);
2036 cli_unlock(cli1, fnum1, 130, 4);
2038 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2039 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2040 goto fail;
2041 } else {
2042 printf("pid1 successfully locked range 130:4 for WRITE\n");
2045 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2046 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2047 goto fail;
2048 } else {
2049 printf("pid1 successfully read the range 130:4\n");
2052 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2053 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2054 goto fail;
2055 } else {
2056 printf("pid1 successfully wrote to the range 130:4\n");
2059 cli_setpid(cli1, 2);
2061 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2062 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2063 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2064 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2065 goto fail;
2067 } else {
2068 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2069 goto fail;
2072 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2073 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2074 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2075 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2076 goto fail;
2078 } else {
2079 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2080 goto fail;
2083 cli_unlock(cli1, fnum1, 130, 0);
2084 correct = True;
2086 fail:
2087 cli_close(cli1, fnum1);
2088 cli_unlink(cli1, fname);
2089 torture_close_connection(cli1);
2091 printf("finished locktest7\n");
2092 return correct;
2096 test whether fnums and tids open on one VC are available on another (a major
2097 security hole)
2099 static bool run_fdpasstest(int dummy)
2101 struct cli_state *cli1, *cli2;
2102 const char *fname = "\\fdpass.tst";
2103 int fnum1;
2104 char buf[1024];
2106 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2107 return False;
2109 cli_sockopt(cli1, sockops);
2110 cli_sockopt(cli2, sockops);
2112 printf("starting fdpasstest\n");
2114 cli_unlink(cli1, fname);
2116 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2117 if (fnum1 == -1) {
2118 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2119 return False;
2122 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2123 printf("write failed (%s)\n", cli_errstr(cli1));
2124 return False;
2127 cli2->vuid = cli1->vuid;
2128 cli2->cnum = cli1->cnum;
2129 cli2->pid = cli1->pid;
2131 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2132 printf("read succeeded! nasty security hole [%s]\n",
2133 buf);
2134 return False;
2137 cli_close(cli1, fnum1);
2138 cli_unlink(cli1, fname);
2140 torture_close_connection(cli1);
2141 torture_close_connection(cli2);
2143 printf("finished fdpasstest\n");
2144 return True;
2147 static bool run_fdsesstest(int dummy)
2149 struct cli_state *cli;
2150 uint16 new_vuid;
2151 uint16 saved_vuid;
2152 uint16 new_cnum;
2153 uint16 saved_cnum;
2154 const char *fname = "\\fdsess.tst";
2155 const char *fname1 = "\\fdsess1.tst";
2156 int fnum1;
2157 int fnum2;
2158 char buf[1024];
2159 bool ret = True;
2161 if (!torture_open_connection(&cli, 0))
2162 return False;
2163 cli_sockopt(cli, sockops);
2165 if (!torture_cli_session_setup2(cli, &new_vuid))
2166 return False;
2168 saved_cnum = cli->cnum;
2169 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2170 return False;
2171 new_cnum = cli->cnum;
2172 cli->cnum = saved_cnum;
2174 printf("starting fdsesstest\n");
2176 cli_unlink(cli, fname);
2177 cli_unlink(cli, fname1);
2179 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2180 if (fnum1 == -1) {
2181 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2182 return False;
2185 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2186 printf("write failed (%s)\n", cli_errstr(cli));
2187 return False;
2190 saved_vuid = cli->vuid;
2191 cli->vuid = new_vuid;
2193 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2194 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2195 buf);
2196 ret = False;
2198 /* Try to open a file with different vuid, samba cnum. */
2199 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2200 if (fnum2 != -1) {
2201 printf("create with different vuid, same cnum succeeded.\n");
2202 cli_close(cli, fnum2);
2203 cli_unlink(cli, fname1);
2204 } else {
2205 printf("create with different vuid, same cnum failed.\n");
2206 printf("This will cause problems with service clients.\n");
2207 ret = False;
2210 cli->vuid = saved_vuid;
2212 /* Try with same vuid, different cnum. */
2213 cli->cnum = new_cnum;
2215 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2216 printf("read succeeded with different cnum![%s]\n",
2217 buf);
2218 ret = False;
2221 cli->cnum = saved_cnum;
2222 cli_close(cli, fnum1);
2223 cli_unlink(cli, fname);
2225 torture_close_connection(cli);
2227 printf("finished fdsesstest\n");
2228 return ret;
2232 This test checks that
2234 1) the server does not allow an unlink on a file that is open
2236 static bool run_unlinktest(int dummy)
2238 struct cli_state *cli;
2239 const char *fname = "\\unlink.tst";
2240 int fnum;
2241 bool correct = True;
2243 if (!torture_open_connection(&cli, 0)) {
2244 return False;
2247 cli_sockopt(cli, sockops);
2249 printf("starting unlink test\n");
2251 cli_unlink(cli, fname);
2253 cli_setpid(cli, 1);
2255 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2256 if (fnum == -1) {
2257 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2258 return False;
2261 if (cli_unlink(cli, fname)) {
2262 printf("error: server allowed unlink on an open file\n");
2263 correct = False;
2264 } else {
2265 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2266 NT_STATUS_SHARING_VIOLATION);
2269 cli_close(cli, fnum);
2270 cli_unlink(cli, fname);
2272 if (!torture_close_connection(cli)) {
2273 correct = False;
2276 printf("unlink test finished\n");
2278 return correct;
2283 test how many open files this server supports on the one socket
2285 static bool run_maxfidtest(int dummy)
2287 struct cli_state *cli;
2288 const char *ftemplate = "\\maxfid.%d.%d";
2289 fstring fname;
2290 int fnums[0x11000], i;
2291 int retries=4;
2292 bool correct = True;
2294 cli = current_cli;
2296 if (retries <= 0) {
2297 printf("failed to connect\n");
2298 return False;
2301 cli_sockopt(cli, sockops);
2303 for (i=0; i<0x11000; i++) {
2304 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2305 if ((fnums[i] = cli_open(cli, fname,
2306 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2307 -1) {
2308 printf("open of %s failed (%s)\n",
2309 fname, cli_errstr(cli));
2310 printf("maximum fnum is %d\n", i);
2311 break;
2313 printf("%6d\r", i);
2315 printf("%6d\n", i);
2316 i--;
2318 printf("cleaning up\n");
2319 for (;i>=0;i--) {
2320 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2321 cli_close(cli, fnums[i]);
2322 if (!cli_unlink(cli, fname)) {
2323 printf("unlink of %s failed (%s)\n",
2324 fname, cli_errstr(cli));
2325 correct = False;
2327 printf("%6d\r", i);
2329 printf("%6d\n", 0);
2331 printf("maxfid test finished\n");
2332 if (!torture_close_connection(cli)) {
2333 correct = False;
2335 return correct;
2338 /* generate a random buffer */
2339 static void rand_buf(char *buf, int len)
2341 while (len--) {
2342 *buf = (char)sys_random();
2343 buf++;
2347 /* send smb negprot commands, not reading the response */
2348 static bool run_negprot_nowait(int dummy)
2350 int i;
2351 static struct cli_state *cli;
2352 bool correct = True;
2354 printf("starting negprot nowait test\n");
2356 if (!(cli = open_nbt_connection())) {
2357 return False;
2360 for (i=0;i<50000;i++) {
2361 cli_negprot_sendsync(cli);
2364 if (!torture_close_connection(cli)) {
2365 correct = False;
2368 printf("finished negprot nowait test\n");
2370 return correct;
2374 /* send random IPC commands */
2375 static bool run_randomipc(int dummy)
2377 char *rparam = NULL;
2378 char *rdata = NULL;
2379 unsigned int rdrcnt,rprcnt;
2380 char param[1024];
2381 int api, param_len, i;
2382 struct cli_state *cli;
2383 bool correct = True;
2384 int count = 50000;
2386 printf("starting random ipc test\n");
2388 if (!torture_open_connection(&cli, 0)) {
2389 return False;
2392 for (i=0;i<count;i++) {
2393 api = sys_random() % 500;
2394 param_len = (sys_random() % 64);
2396 rand_buf(param, param_len);
2398 SSVAL(param,0,api);
2400 cli_api(cli,
2401 param, param_len, 8,
2402 NULL, 0, BUFFER_SIZE,
2403 &rparam, &rprcnt,
2404 &rdata, &rdrcnt);
2405 if (i % 100 == 0) {
2406 printf("%d/%d\r", i,count);
2409 printf("%d/%d\n", i, count);
2411 if (!torture_close_connection(cli)) {
2412 correct = False;
2415 printf("finished random ipc test\n");
2417 return correct;
2422 static void browse_callback(const char *sname, uint32 stype,
2423 const char *comment, void *state)
2425 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2431 This test checks the browse list code
2434 static bool run_browsetest(int dummy)
2436 static struct cli_state *cli;
2437 bool correct = True;
2439 printf("starting browse test\n");
2441 if (!torture_open_connection(&cli, 0)) {
2442 return False;
2445 printf("domain list:\n");
2446 cli_NetServerEnum(cli, cli->server_domain,
2447 SV_TYPE_DOMAIN_ENUM,
2448 browse_callback, NULL);
2450 printf("machine list:\n");
2451 cli_NetServerEnum(cli, cli->server_domain,
2452 SV_TYPE_ALL,
2453 browse_callback, NULL);
2455 if (!torture_close_connection(cli)) {
2456 correct = False;
2459 printf("browse test finished\n");
2461 return correct;
2467 This checks how the getatr calls works
2469 static bool run_attrtest(int dummy)
2471 struct cli_state *cli;
2472 int fnum;
2473 time_t t, t2;
2474 const char *fname = "\\attrib123456789.tst";
2475 bool correct = True;
2477 printf("starting attrib test\n");
2479 if (!torture_open_connection(&cli, 0)) {
2480 return False;
2483 cli_unlink(cli, fname);
2484 fnum = cli_open(cli, fname,
2485 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2486 cli_close(cli, fnum);
2487 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2488 printf("getatr failed (%s)\n", cli_errstr(cli));
2489 correct = False;
2492 if (abs(t - time(NULL)) > 60*60*24*10) {
2493 printf("ERROR: SMBgetatr bug. time is %s",
2494 ctime(&t));
2495 t = time(NULL);
2496 correct = True;
2499 t2 = t-60*60*24; /* 1 day ago */
2501 if (!cli_setatr(cli, fname, 0, t2)) {
2502 printf("setatr failed (%s)\n", cli_errstr(cli));
2503 correct = True;
2506 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2507 printf("getatr failed (%s)\n", cli_errstr(cli));
2508 correct = True;
2511 if (t != t2) {
2512 printf("ERROR: getatr/setatr bug. times are\n%s",
2513 ctime(&t));
2514 printf("%s", ctime(&t2));
2515 correct = True;
2518 cli_unlink(cli, fname);
2520 if (!torture_close_connection(cli)) {
2521 correct = False;
2524 printf("attrib test finished\n");
2526 return correct;
2531 This checks a couple of trans2 calls
2533 static bool run_trans2test(int dummy)
2535 struct cli_state *cli;
2536 int fnum;
2537 SMB_OFF_T size;
2538 time_t c_time, a_time, m_time;
2539 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2540 const char *fname = "\\trans2.tst";
2541 const char *dname = "\\trans2";
2542 const char *fname2 = "\\trans2\\trans2.tst";
2543 char pname[1024];
2544 bool correct = True;
2546 printf("starting trans2 test\n");
2548 if (!torture_open_connection(&cli, 0)) {
2549 return False;
2552 cli_unlink(cli, fname);
2553 fnum = cli_open(cli, fname,
2554 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2555 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2556 &m_time_ts, NULL)) {
2557 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2558 correct = False;
2561 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2562 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2563 correct = False;
2566 if (strcmp(pname, fname)) {
2567 printf("qfilename gave different name? [%s] [%s]\n",
2568 fname, pname);
2569 correct = False;
2572 cli_close(cli, fnum);
2574 sleep(2);
2576 cli_unlink(cli, fname);
2577 fnum = cli_open(cli, fname,
2578 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2579 if (fnum == -1) {
2580 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2581 return False;
2583 cli_close(cli, fnum);
2585 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2586 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2587 correct = False;
2588 } else {
2589 if (c_time != m_time) {
2590 printf("create time=%s", ctime(&c_time));
2591 printf("modify time=%s", ctime(&m_time));
2592 printf("This system appears to have sticky create times\n");
2594 if (a_time % (60*60) == 0) {
2595 printf("access time=%s", ctime(&a_time));
2596 printf("This system appears to set a midnight access time\n");
2597 correct = False;
2600 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2601 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2602 correct = False;
2607 cli_unlink(cli, fname);
2608 fnum = cli_open(cli, fname,
2609 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2610 cli_close(cli, fnum);
2611 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2612 &m_time_ts, &size, NULL, NULL)) {
2613 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2614 correct = False;
2615 } else {
2616 if (w_time_ts.tv_sec < 60*60*24*2) {
2617 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2618 printf("This system appears to set a initial 0 write time\n");
2619 correct = False;
2623 cli_unlink(cli, fname);
2626 /* check if the server updates the directory modification time
2627 when creating a new file */
2628 if (!cli_mkdir(cli, dname)) {
2629 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2630 correct = False;
2632 sleep(3);
2633 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2634 &m_time_ts, &size, NULL, NULL)) {
2635 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2636 correct = False;
2639 fnum = cli_open(cli, fname2,
2640 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2641 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2642 cli_close(cli, fnum);
2643 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2644 &m_time2_ts, &size, NULL, NULL)) {
2645 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2646 correct = False;
2647 } else {
2648 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2649 == 0) {
2650 printf("This system does not update directory modification times\n");
2651 correct = False;
2654 cli_unlink(cli, fname2);
2655 cli_rmdir(cli, dname);
2657 if (!torture_close_connection(cli)) {
2658 correct = False;
2661 printf("trans2 test finished\n");
2663 return correct;
2667 This checks new W2K calls.
2670 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2672 char *buf = NULL;
2673 uint32 len;
2674 bool correct = True;
2676 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2677 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2678 correct = False;
2679 } else {
2680 printf("qfileinfo: level %d, len = %u\n", level, len);
2681 dump_data(0, (uint8 *)buf, len);
2682 printf("\n");
2684 SAFE_FREE(buf);
2685 return correct;
2688 static bool run_w2ktest(int dummy)
2690 struct cli_state *cli;
2691 int fnum;
2692 const char *fname = "\\w2ktest\\w2k.tst";
2693 int level;
2694 bool correct = True;
2696 printf("starting w2k test\n");
2698 if (!torture_open_connection(&cli, 0)) {
2699 return False;
2702 fnum = cli_open(cli, fname,
2703 O_RDWR | O_CREAT , DENY_NONE);
2705 for (level = 1004; level < 1040; level++) {
2706 new_trans(cli, fnum, level);
2709 cli_close(cli, fnum);
2711 if (!torture_close_connection(cli)) {
2712 correct = False;
2715 printf("w2k test finished\n");
2717 return correct;
2722 this is a harness for some oplock tests
2724 static bool run_oplock1(int dummy)
2726 struct cli_state *cli1;
2727 const char *fname = "\\lockt1.lck";
2728 int fnum1;
2729 bool correct = True;
2731 printf("starting oplock test 1\n");
2733 if (!torture_open_connection(&cli1, 0)) {
2734 return False;
2737 cli_unlink(cli1, fname);
2739 cli_sockopt(cli1, sockops);
2741 cli1->use_oplocks = True;
2743 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2744 if (fnum1 == -1) {
2745 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2746 return False;
2749 cli1->use_oplocks = False;
2751 cli_unlink(cli1, fname);
2752 cli_unlink(cli1, fname);
2754 if (!cli_close(cli1, fnum1)) {
2755 printf("close2 failed (%s)\n", cli_errstr(cli1));
2756 return False;
2759 if (!cli_unlink(cli1, fname)) {
2760 printf("unlink failed (%s)\n", cli_errstr(cli1));
2761 return False;
2764 if (!torture_close_connection(cli1)) {
2765 correct = False;
2768 printf("finished oplock test 1\n");
2770 return correct;
2773 static bool run_oplock2(int dummy)
2775 struct cli_state *cli1, *cli2;
2776 const char *fname = "\\lockt2.lck";
2777 int fnum1, fnum2;
2778 int saved_use_oplocks = use_oplocks;
2779 char buf[4];
2780 bool correct = True;
2781 volatile bool *shared_correct;
2783 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2784 *shared_correct = True;
2786 use_level_II_oplocks = True;
2787 use_oplocks = True;
2789 printf("starting oplock test 2\n");
2791 if (!torture_open_connection(&cli1, 0)) {
2792 use_level_II_oplocks = False;
2793 use_oplocks = saved_use_oplocks;
2794 return False;
2797 cli1->use_oplocks = True;
2798 cli1->use_level_II_oplocks = True;
2800 if (!torture_open_connection(&cli2, 1)) {
2801 use_level_II_oplocks = False;
2802 use_oplocks = saved_use_oplocks;
2803 return False;
2806 cli2->use_oplocks = True;
2807 cli2->use_level_II_oplocks = True;
2809 cli_unlink(cli1, fname);
2811 cli_sockopt(cli1, sockops);
2812 cli_sockopt(cli2, sockops);
2814 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2815 if (fnum1 == -1) {
2816 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2817 return False;
2820 /* Don't need the globals any more. */
2821 use_level_II_oplocks = False;
2822 use_oplocks = saved_use_oplocks;
2824 if (fork() == 0) {
2825 /* Child code */
2826 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2827 if (fnum2 == -1) {
2828 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2829 *shared_correct = False;
2830 exit(0);
2833 sleep(2);
2835 if (!cli_close(cli2, fnum2)) {
2836 printf("close2 failed (%s)\n", cli_errstr(cli1));
2837 *shared_correct = False;
2840 exit(0);
2843 sleep(2);
2845 /* Ensure cli1 processes the break. Empty file should always return 0
2846 * bytes. */
2848 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2849 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2850 correct = False;
2853 /* Should now be at level II. */
2854 /* Test if sending a write locks causes a break to none. */
2856 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2857 printf("lock failed (%s)\n", cli_errstr(cli1));
2858 correct = False;
2861 cli_unlock(cli1, fnum1, 0, 4);
2863 sleep(2);
2865 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2866 printf("lock failed (%s)\n", cli_errstr(cli1));
2867 correct = False;
2870 cli_unlock(cli1, fnum1, 0, 4);
2872 sleep(2);
2874 cli_read(cli1, fnum1, buf, 0, 4);
2876 #if 0
2877 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2878 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2879 correct = False;
2881 #endif
2883 if (!cli_close(cli1, fnum1)) {
2884 printf("close1 failed (%s)\n", cli_errstr(cli1));
2885 correct = False;
2888 sleep(4);
2890 if (!cli_unlink(cli1, fname)) {
2891 printf("unlink failed (%s)\n", cli_errstr(cli1));
2892 correct = False;
2895 if (!torture_close_connection(cli1)) {
2896 correct = False;
2899 if (!*shared_correct) {
2900 correct = False;
2903 printf("finished oplock test 2\n");
2905 return correct;
2908 /* handler for oplock 3 tests */
2909 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2911 printf("got oplock break fnum=%d level=%d\n",
2912 fnum, level);
2913 return cli_oplock_ack(cli, fnum, level);
2916 static bool run_oplock3(int dummy)
2918 struct cli_state *cli;
2919 const char *fname = "\\oplockt3.dat";
2920 int fnum;
2921 char buf[4] = "abcd";
2922 bool correct = True;
2923 volatile bool *shared_correct;
2925 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2926 *shared_correct = True;
2928 printf("starting oplock test 3\n");
2930 if (fork() == 0) {
2931 /* Child code */
2932 use_oplocks = True;
2933 use_level_II_oplocks = True;
2934 if (!torture_open_connection(&cli, 0)) {
2935 *shared_correct = False;
2936 exit(0);
2938 sleep(2);
2939 /* try to trigger a oplock break in parent */
2940 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2941 cli_write(cli, fnum, 0, buf, 0, 4);
2942 exit(0);
2945 /* parent code */
2946 use_oplocks = True;
2947 use_level_II_oplocks = True;
2948 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2949 return False;
2951 cli_oplock_handler(cli, oplock3_handler);
2952 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2953 cli_write(cli, fnum, 0, buf, 0, 4);
2954 cli_close(cli, fnum);
2955 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2956 cli->timeout = 20000;
2957 cli_receive_smb(cli);
2958 printf("finished oplock test 3\n");
2960 return (correct && *shared_correct);
2962 /* What are we looking for here? What's sucess and what's FAILURE? */
2968 Test delete on close semantics.
2970 static bool run_deletetest(int dummy)
2972 struct cli_state *cli1 = NULL;
2973 struct cli_state *cli2 = NULL;
2974 const char *fname = "\\delete.file";
2975 int fnum1 = -1;
2976 int fnum2 = -1;
2977 bool correct = True;
2979 printf("starting delete test\n");
2981 if (!torture_open_connection(&cli1, 0)) {
2982 return False;
2985 cli_sockopt(cli1, sockops);
2987 /* Test 1 - this should delete the file on close. */
2989 cli_setatr(cli1, fname, 0, 0);
2990 cli_unlink(cli1, fname);
2992 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2993 0, FILE_OVERWRITE_IF,
2994 FILE_DELETE_ON_CLOSE, 0);
2996 if (fnum1 == -1) {
2997 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2998 correct = False;
2999 goto fail;
3002 #if 0 /* JRATEST */
3004 uint32 *accinfo = NULL;
3005 uint32 len;
3006 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3007 if (accinfo)
3008 printf("access mode = 0x%lx\n", *accinfo);
3009 SAFE_FREE(accinfo);
3011 #endif
3013 if (!cli_close(cli1, fnum1)) {
3014 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3015 correct = False;
3016 goto fail;
3019 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3020 if (fnum1 != -1) {
3021 printf("[1] open of %s succeeded (should fail)\n", fname);
3022 correct = False;
3023 goto fail;
3026 printf("first delete on close test succeeded.\n");
3028 /* Test 2 - this should delete the file on close. */
3030 cli_setatr(cli1, fname, 0, 0);
3031 cli_unlink(cli1, fname);
3033 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3034 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3035 FILE_OVERWRITE_IF, 0, 0);
3037 if (fnum1 == -1) {
3038 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3039 correct = False;
3040 goto fail;
3043 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3044 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3045 correct = False;
3046 goto fail;
3049 if (!cli_close(cli1, fnum1)) {
3050 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3051 correct = False;
3052 goto fail;
3055 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3056 if (fnum1 != -1) {
3057 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3058 if (!cli_close(cli1, fnum1)) {
3059 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3060 correct = False;
3061 goto fail;
3063 cli_unlink(cli1, fname);
3064 } else
3065 printf("second delete on close test succeeded.\n");
3067 /* Test 3 - ... */
3068 cli_setatr(cli1, fname, 0, 0);
3069 cli_unlink(cli1, fname);
3071 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3072 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3074 if (fnum1 == -1) {
3075 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3076 correct = False;
3077 goto fail;
3080 /* This should fail with a sharing violation - open for delete is only compatible
3081 with SHARE_DELETE. */
3083 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3084 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3086 if (fnum2 != -1) {
3087 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3088 correct = False;
3089 goto fail;
3092 /* This should succeed. */
3094 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3095 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3097 if (fnum2 == -1) {
3098 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3099 correct = False;
3100 goto fail;
3103 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3104 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3105 correct = False;
3106 goto fail;
3109 if (!cli_close(cli1, fnum1)) {
3110 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3111 correct = False;
3112 goto fail;
3115 if (!cli_close(cli1, fnum2)) {
3116 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3117 correct = False;
3118 goto fail;
3121 /* This should fail - file should no longer be there. */
3123 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3124 if (fnum1 != -1) {
3125 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3126 if (!cli_close(cli1, fnum1)) {
3127 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3129 cli_unlink(cli1, fname);
3130 correct = False;
3131 goto fail;
3132 } else
3133 printf("third delete on close test succeeded.\n");
3135 /* Test 4 ... */
3136 cli_setatr(cli1, fname, 0, 0);
3137 cli_unlink(cli1, fname);
3139 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3140 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3142 if (fnum1 == -1) {
3143 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3144 correct = False;
3145 goto fail;
3148 /* This should succeed. */
3149 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3150 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3151 if (fnum2 == -1) {
3152 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3153 correct = False;
3154 goto fail;
3157 if (!cli_close(cli1, fnum2)) {
3158 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3159 correct = False;
3160 goto fail;
3163 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3164 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3165 correct = False;
3166 goto fail;
3169 /* This should fail - no more opens once delete on close set. */
3170 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3171 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3172 FILE_OPEN, 0, 0);
3173 if (fnum2 != -1) {
3174 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3175 correct = False;
3176 goto fail;
3177 } else
3178 printf("fourth delete on close test succeeded.\n");
3180 if (!cli_close(cli1, fnum1)) {
3181 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3182 correct = False;
3183 goto fail;
3186 /* Test 5 ... */
3187 cli_setatr(cli1, fname, 0, 0);
3188 cli_unlink(cli1, fname);
3190 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3191 if (fnum1 == -1) {
3192 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3193 correct = False;
3194 goto fail;
3197 /* This should fail - only allowed on NT opens with DELETE access. */
3199 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3200 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3201 correct = False;
3202 goto fail;
3205 if (!cli_close(cli1, fnum1)) {
3206 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3207 correct = False;
3208 goto fail;
3211 printf("fifth delete on close test succeeded.\n");
3213 /* Test 6 ... */
3214 cli_setatr(cli1, fname, 0, 0);
3215 cli_unlink(cli1, fname);
3217 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3218 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3219 FILE_OVERWRITE_IF, 0, 0);
3221 if (fnum1 == -1) {
3222 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3223 correct = False;
3224 goto fail;
3227 /* This should fail - only allowed on NT opens with DELETE access. */
3229 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3230 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3231 correct = False;
3232 goto fail;
3235 if (!cli_close(cli1, fnum1)) {
3236 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3237 correct = False;
3238 goto fail;
3241 printf("sixth delete on close test succeeded.\n");
3243 /* Test 7 ... */
3244 cli_setatr(cli1, fname, 0, 0);
3245 cli_unlink(cli1, fname);
3247 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3248 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3250 if (fnum1 == -1) {
3251 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3252 correct = False;
3253 goto fail;
3256 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3257 printf("[7] setting delete_on_close on file failed !\n");
3258 correct = False;
3259 goto fail;
3262 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3263 printf("[7] unsetting delete_on_close on file failed !\n");
3264 correct = False;
3265 goto fail;
3268 if (!cli_close(cli1, fnum1)) {
3269 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3270 correct = False;
3271 goto fail;
3274 /* This next open should succeed - we reset the flag. */
3276 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3277 if (fnum1 == -1) {
3278 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3279 correct = False;
3280 goto fail;
3283 if (!cli_close(cli1, fnum1)) {
3284 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3285 correct = False;
3286 goto fail;
3289 printf("seventh delete on close test succeeded.\n");
3291 /* Test 7 ... */
3292 cli_setatr(cli1, fname, 0, 0);
3293 cli_unlink(cli1, fname);
3295 if (!torture_open_connection(&cli2, 1)) {
3296 printf("[8] failed to open second connection.\n");
3297 correct = False;
3298 goto fail;
3301 cli_sockopt(cli1, sockops);
3303 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3304 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3305 FILE_OVERWRITE_IF, 0, 0);
3307 if (fnum1 == -1) {
3308 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3309 correct = False;
3310 goto fail;
3313 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3314 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3315 FILE_OPEN, 0, 0);
3317 if (fnum2 == -1) {
3318 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3319 correct = False;
3320 goto fail;
3323 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3324 printf("[8] setting delete_on_close on file failed !\n");
3325 correct = False;
3326 goto fail;
3329 if (!cli_close(cli1, fnum1)) {
3330 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3331 correct = False;
3332 goto fail;
3335 if (!cli_close(cli2, fnum2)) {
3336 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3337 correct = False;
3338 goto fail;
3341 /* This should fail.. */
3342 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3343 if (fnum1 != -1) {
3344 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3345 goto fail;
3346 correct = False;
3347 } else
3348 printf("eighth delete on close test succeeded.\n");
3350 /* This should fail - we need to set DELETE_ACCESS. */
3351 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3352 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3354 if (fnum1 != -1) {
3355 printf("[9] open of %s succeeded should have failed!\n", fname);
3356 correct = False;
3357 goto fail;
3360 printf("ninth delete on close test succeeded.\n");
3362 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3363 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3364 if (fnum1 == -1) {
3365 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3366 correct = False;
3367 goto fail;
3370 /* This should delete the file. */
3371 if (!cli_close(cli1, fnum1)) {
3372 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3373 correct = False;
3374 goto fail;
3377 /* This should fail.. */
3378 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3379 if (fnum1 != -1) {
3380 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3381 goto fail;
3382 correct = False;
3383 } else
3384 printf("tenth delete on close test succeeded.\n");
3386 cli_setatr(cli1, fname, 0, 0);
3387 cli_unlink(cli1, fname);
3389 /* What error do we get when attempting to open a read-only file with
3390 delete access ? */
3392 /* Create a readonly file. */
3393 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3394 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3395 if (fnum1 == -1) {
3396 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3397 correct = False;
3398 goto fail;
3401 if (!cli_close(cli1, fnum1)) {
3402 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3403 correct = False;
3404 goto fail;
3407 /* Now try open for delete access. */
3408 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3409 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3410 FILE_OVERWRITE_IF, 0, 0);
3412 if (fnum1 != -1) {
3413 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3414 cli_close(cli1, fnum1);
3415 goto fail;
3416 correct = False;
3417 } else {
3418 NTSTATUS nterr = cli_nt_error(cli1);
3419 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3420 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3421 goto fail;
3422 correct = False;
3423 } else {
3424 printf("eleventh delete on close test succeeded.\n");
3428 printf("finished delete test\n");
3430 fail:
3431 /* FIXME: This will crash if we aborted before cli2 got
3432 * intialized, because these functions don't handle
3433 * uninitialized connections. */
3435 if (fnum1 != -1) cli_close(cli1, fnum1);
3436 if (fnum2 != -1) cli_close(cli1, fnum2);
3437 cli_setatr(cli1, fname, 0, 0);
3438 cli_unlink(cli1, fname);
3440 if (cli1 && !torture_close_connection(cli1)) {
3441 correct = False;
3443 if (cli2 && !torture_close_connection(cli2)) {
3444 correct = False;
3446 return correct;
3451 print out server properties
3453 static bool run_properties(int dummy)
3455 static struct cli_state *cli;
3456 bool correct = True;
3458 printf("starting properties test\n");
3460 ZERO_STRUCT(cli);
3462 if (!torture_open_connection(&cli, 0)) {
3463 return False;
3466 cli_sockopt(cli, sockops);
3468 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3470 if (!torture_close_connection(cli)) {
3471 correct = False;
3474 return correct;
3479 /* FIRST_DESIRED_ACCESS 0xf019f */
3480 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3481 FILE_READ_EA| /* 0xf */ \
3482 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3483 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3484 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3485 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3486 /* SECOND_DESIRED_ACCESS 0xe0080 */
3487 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3488 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3489 WRITE_OWNER_ACCESS /* 0xe0000 */
3491 #if 0
3492 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3493 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3494 FILE_READ_DATA|\
3495 WRITE_OWNER_ACCESS /* */
3496 #endif
3499 Test ntcreate calls made by xcopy
3501 static bool run_xcopy(int dummy)
3503 static struct cli_state *cli1;
3504 const char *fname = "\\test.txt";
3505 bool correct = True;
3506 int fnum1, fnum2;
3508 printf("starting xcopy test\n");
3510 if (!torture_open_connection(&cli1, 0)) {
3511 return False;
3514 fnum1 = cli_nt_create_full(cli1, fname, 0,
3515 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3516 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3517 0x4044, 0);
3519 if (fnum1 == -1) {
3520 printf("First open failed - %s\n", cli_errstr(cli1));
3521 return False;
3524 fnum2 = cli_nt_create_full(cli1, fname, 0,
3525 SECOND_DESIRED_ACCESS, 0,
3526 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3527 0x200000, 0);
3528 if (fnum2 == -1) {
3529 printf("second open failed - %s\n", cli_errstr(cli1));
3530 return False;
3533 if (!torture_close_connection(cli1)) {
3534 correct = False;
3537 return correct;
3541 Test rename on files open with share delete and no share delete.
3543 static bool run_rename(int dummy)
3545 static struct cli_state *cli1;
3546 const char *fname = "\\test.txt";
3547 const char *fname1 = "\\test1.txt";
3548 bool correct = True;
3549 int fnum1;
3551 printf("starting rename test\n");
3553 if (!torture_open_connection(&cli1, 0)) {
3554 return False;
3557 cli_unlink(cli1, fname);
3558 cli_unlink(cli1, fname1);
3559 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3560 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3562 if (fnum1 == -1) {
3563 printf("First open failed - %s\n", cli_errstr(cli1));
3564 return False;
3567 if (!cli_rename(cli1, fname, fname1)) {
3568 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3569 } else {
3570 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3571 correct = False;
3574 if (!cli_close(cli1, fnum1)) {
3575 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3576 return False;
3579 cli_unlink(cli1, fname);
3580 cli_unlink(cli1, fname1);
3581 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3582 #if 0
3583 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3584 #else
3585 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3586 #endif
3588 if (fnum1 == -1) {
3589 printf("Second open failed - %s\n", cli_errstr(cli1));
3590 return False;
3593 if (!cli_rename(cli1, fname, fname1)) {
3594 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3595 correct = False;
3596 } else {
3597 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3600 if (!cli_close(cli1, fnum1)) {
3601 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3602 return False;
3605 cli_unlink(cli1, fname);
3606 cli_unlink(cli1, fname1);
3608 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3609 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3611 if (fnum1 == -1) {
3612 printf("Third open failed - %s\n", cli_errstr(cli1));
3613 return False;
3617 #if 0
3619 int fnum2;
3621 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3622 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3624 if (fnum2 == -1) {
3625 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3626 return False;
3628 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3629 printf("[8] setting delete_on_close on file failed !\n");
3630 return False;
3633 if (!cli_close(cli1, fnum2)) {
3634 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3635 return False;
3638 #endif
3640 if (!cli_rename(cli1, fname, fname1)) {
3641 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3642 correct = False;
3643 } else {
3644 printf("Third rename succeeded (SHARE_NONE)\n");
3647 if (!cli_close(cli1, fnum1)) {
3648 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3649 return False;
3652 cli_unlink(cli1, fname);
3653 cli_unlink(cli1, fname1);
3655 /*----*/
3657 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3658 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3660 if (fnum1 == -1) {
3661 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3662 return False;
3665 if (!cli_rename(cli1, fname, fname1)) {
3666 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3667 } else {
3668 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3669 correct = False;
3672 if (!cli_close(cli1, fnum1)) {
3673 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3674 return False;
3677 cli_unlink(cli1, fname);
3678 cli_unlink(cli1, fname1);
3680 /*--*/
3682 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3683 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3685 if (fnum1 == -1) {
3686 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3687 return False;
3690 if (!cli_rename(cli1, fname, fname1)) {
3691 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3692 cli_errstr(cli1));
3693 correct = False;
3694 } else {
3695 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3699 * Now check if the first name still exists ...
3702 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3703 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3705 if (fnum2 == -1) {
3706 printf("Opening original file after rename of open file fails: %s\n",
3707 cli_errstr(cli1));
3709 else {
3710 printf("Opening original file after rename of open file works ...\n");
3711 (void)cli_close(cli1, fnum2);
3712 } */
3714 /*--*/
3717 if (!cli_close(cli1, fnum1)) {
3718 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3719 return False;
3722 cli_unlink(cli1, fname);
3723 cli_unlink(cli1, fname1);
3725 if (!torture_close_connection(cli1)) {
3726 correct = False;
3729 return correct;
3732 static bool run_pipe_number(int dummy)
3734 struct cli_state *cli1;
3735 const char *pipe_name = "\\SPOOLSS";
3736 int fnum;
3737 int num_pipes = 0;
3739 printf("starting pipenumber test\n");
3740 if (!torture_open_connection(&cli1, 0)) {
3741 return False;
3744 cli_sockopt(cli1, sockops);
3745 while(1) {
3746 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3747 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3749 if (fnum == -1) {
3750 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3751 break;
3753 num_pipes++;
3754 printf("\r%6d", num_pipes);
3757 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3758 torture_close_connection(cli1);
3759 return True;
3763 Test open mode returns on read-only files.
3765 static bool run_opentest(int dummy)
3767 static struct cli_state *cli1;
3768 static struct cli_state *cli2;
3769 const char *fname = "\\readonly.file";
3770 int fnum1, fnum2;
3771 char buf[20];
3772 SMB_OFF_T fsize;
3773 bool correct = True;
3774 char *tmp_path;
3776 printf("starting open test\n");
3778 if (!torture_open_connection(&cli1, 0)) {
3779 return False;
3782 cli_setatr(cli1, fname, 0, 0);
3783 cli_unlink(cli1, fname);
3785 cli_sockopt(cli1, sockops);
3787 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3788 if (fnum1 == -1) {
3789 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3790 return False;
3793 if (!cli_close(cli1, fnum1)) {
3794 printf("close2 failed (%s)\n", cli_errstr(cli1));
3795 return False;
3798 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3799 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3800 return False;
3803 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3804 if (fnum1 == -1) {
3805 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3806 return False;
3809 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3810 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3812 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3813 NT_STATUS_ACCESS_DENIED)) {
3814 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3817 printf("finished open test 1\n");
3819 cli_close(cli1, fnum1);
3821 /* Now try not readonly and ensure ERRbadshare is returned. */
3823 cli_setatr(cli1, fname, 0, 0);
3825 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3826 if (fnum1 == -1) {
3827 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3828 return False;
3831 /* This will fail - but the error should be ERRshare. */
3832 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3834 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3835 NT_STATUS_SHARING_VIOLATION)) {
3836 printf("correct error code ERRDOS/ERRbadshare returned\n");
3839 if (!cli_close(cli1, fnum1)) {
3840 printf("close2 failed (%s)\n", cli_errstr(cli1));
3841 return False;
3844 cli_unlink(cli1, fname);
3846 printf("finished open test 2\n");
3848 /* Test truncate open disposition on file opened for read. */
3850 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3851 if (fnum1 == -1) {
3852 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3853 return False;
3856 /* write 20 bytes. */
3858 memset(buf, '\0', 20);
3860 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3861 printf("write failed (%s)\n", cli_errstr(cli1));
3862 correct = False;
3865 if (!cli_close(cli1, fnum1)) {
3866 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3867 return False;
3870 /* Ensure size == 20. */
3871 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3872 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3873 return False;
3876 if (fsize != 20) {
3877 printf("(3) file size != 20\n");
3878 return False;
3881 /* Now test if we can truncate a file opened for readonly. */
3883 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3884 if (fnum1 == -1) {
3885 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3886 return False;
3889 if (!cli_close(cli1, fnum1)) {
3890 printf("close2 failed (%s)\n", cli_errstr(cli1));
3891 return False;
3894 /* Ensure size == 0. */
3895 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3896 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3897 return False;
3900 if (fsize != 0) {
3901 printf("(3) file size != 0\n");
3902 return False;
3904 printf("finished open test 3\n");
3906 cli_unlink(cli1, fname);
3909 printf("testing ctemp\n");
3910 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3911 if (fnum1 == -1) {
3912 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3913 return False;
3915 printf("ctemp gave path %s\n", tmp_path);
3916 if (!cli_close(cli1, fnum1)) {
3917 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3919 if (!cli_unlink(cli1, tmp_path)) {
3920 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3923 /* Test the non-io opens... */
3925 if (!torture_open_connection(&cli2, 1)) {
3926 return False;
3929 cli_setatr(cli2, fname, 0, 0);
3930 cli_unlink(cli2, fname);
3932 cli_sockopt(cli2, sockops);
3934 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3936 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3937 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3939 if (fnum1 == -1) {
3940 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3941 return False;
3944 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3945 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3947 if (fnum2 == -1) {
3948 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3949 return False;
3952 if (!cli_close(cli1, fnum1)) {
3953 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3954 return False;
3956 if (!cli_close(cli2, fnum2)) {
3957 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3958 return False;
3961 printf("non-io open test #1 passed.\n");
3963 cli_unlink(cli1, fname);
3965 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3967 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3968 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3970 if (fnum1 == -1) {
3971 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3972 return False;
3975 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3976 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3978 if (fnum2 == -1) {
3979 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3980 return False;
3983 if (!cli_close(cli1, fnum1)) {
3984 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3985 return False;
3987 if (!cli_close(cli2, fnum2)) {
3988 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3989 return False;
3992 printf("non-io open test #2 passed.\n");
3994 cli_unlink(cli1, fname);
3996 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3998 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3999 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4001 if (fnum1 == -1) {
4002 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4003 return False;
4006 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4007 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4009 if (fnum2 == -1) {
4010 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4011 return False;
4014 if (!cli_close(cli1, fnum1)) {
4015 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4016 return False;
4018 if (!cli_close(cli2, fnum2)) {
4019 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4020 return False;
4023 printf("non-io open test #3 passed.\n");
4025 cli_unlink(cli1, fname);
4027 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4029 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4030 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4032 if (fnum1 == -1) {
4033 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4034 return False;
4037 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4038 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4040 if (fnum2 != -1) {
4041 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4042 return False;
4045 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4047 if (!cli_close(cli1, fnum1)) {
4048 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4049 return False;
4052 printf("non-io open test #4 passed.\n");
4054 cli_unlink(cli1, fname);
4056 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4058 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4059 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4061 if (fnum1 == -1) {
4062 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4063 return False;
4066 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4067 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4069 if (fnum2 == -1) {
4070 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4071 return False;
4074 if (!cli_close(cli1, fnum1)) {
4075 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4076 return False;
4079 if (!cli_close(cli2, fnum2)) {
4080 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4081 return False;
4084 printf("non-io open test #5 passed.\n");
4086 printf("TEST #6 testing 1 non-io open, one io open\n");
4088 cli_unlink(cli1, fname);
4090 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4091 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4093 if (fnum1 == -1) {
4094 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4095 return False;
4098 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4099 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4101 if (fnum2 == -1) {
4102 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4103 return False;
4106 if (!cli_close(cli1, fnum1)) {
4107 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4108 return False;
4111 if (!cli_close(cli2, fnum2)) {
4112 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4113 return False;
4116 printf("non-io open test #6 passed.\n");
4118 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4120 cli_unlink(cli1, fname);
4122 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4123 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4125 if (fnum1 == -1) {
4126 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4127 return False;
4130 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4131 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4133 if (fnum2 != -1) {
4134 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4135 return False;
4138 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4140 if (!cli_close(cli1, fnum1)) {
4141 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4142 return False;
4145 printf("non-io open test #7 passed.\n");
4147 cli_unlink(cli1, fname);
4149 if (!torture_close_connection(cli1)) {
4150 correct = False;
4152 if (!torture_close_connection(cli2)) {
4153 correct = False;
4156 return correct;
4160 Test POSIX open /mkdir calls.
4162 static bool run_simple_posix_open_test(int dummy)
4164 static struct cli_state *cli1;
4165 const char *fname = "\\posix:file";
4166 const char *dname = "\\posix:dir";
4167 uint16 major, minor;
4168 uint32 caplow, caphigh;
4169 int fnum1 = -1;
4170 bool correct = false;
4172 printf("Starting simple POSIX open test\n");
4174 if (!torture_open_connection(&cli1, 0)) {
4175 return false;
4178 cli_sockopt(cli1, sockops);
4180 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4181 printf("Server doesn't support UNIX CIFS extensions.\n");
4182 return false;
4185 if (!cli_unix_extensions_version(cli1, &major,
4186 &minor, &caplow, &caphigh)) {
4187 printf("Server didn't return UNIX CIFS extensions.\n");
4188 return false;
4191 if (!cli_set_unix_extensions_capabilities(cli1,
4192 major, minor, caplow, caphigh)) {
4193 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4194 return false;
4197 cli_setatr(cli1, fname, 0, 0);
4198 cli_posix_unlink(cli1, fname);
4199 cli_setatr(cli1, dname, 0, 0);
4200 cli_posix_rmdir(cli1, dname);
4202 /* Create a directory. */
4203 if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
4204 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4205 goto out;
4208 fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
4209 if (fnum1 == -1) {
4210 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4211 goto out;
4214 if (!cli_close(cli1, fnum1)) {
4215 printf("close failed (%s)\n", cli_errstr(cli1));
4216 goto out;
4219 /* Now open the file again for read only. */
4220 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4221 if (fnum1 == -1) {
4222 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4223 goto out;
4226 /* Now unlink while open. */
4227 if (!cli_posix_unlink(cli1, fname)) {
4228 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4229 goto out;
4232 if (!cli_close(cli1, fnum1)) {
4233 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4234 goto out;
4237 /* Ensure the file has gone. */
4238 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4239 if (fnum1 != -1) {
4240 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4241 goto out;
4244 if (!cli_posix_rmdir(cli1, dname)) {
4245 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4246 goto out;
4249 printf("Simple POSIX open test passed\n");
4250 correct = true;
4252 out:
4254 if (fnum1 != -1) {
4255 cli_close(cli1, fnum1);
4256 fnum1 = -1;
4259 cli_setatr(cli1, fname, 0, 0);
4260 cli_posix_unlink(cli1, fname);
4261 cli_setatr(cli1, dname, 0, 0);
4262 cli_posix_rmdir(cli1, dname);
4264 if (!torture_close_connection(cli1)) {
4265 correct = false;
4268 return correct;
4272 static uint32 open_attrs_table[] = {
4273 FILE_ATTRIBUTE_NORMAL,
4274 FILE_ATTRIBUTE_ARCHIVE,
4275 FILE_ATTRIBUTE_READONLY,
4276 FILE_ATTRIBUTE_HIDDEN,
4277 FILE_ATTRIBUTE_SYSTEM,
4279 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4280 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4281 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4282 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4283 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4284 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4286 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4287 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4288 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4289 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4292 struct trunc_open_results {
4293 unsigned int num;
4294 uint32 init_attr;
4295 uint32 trunc_attr;
4296 uint32 result_attr;
4299 static struct trunc_open_results attr_results[] = {
4300 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4301 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4302 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4303 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4304 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4305 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4306 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4307 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4308 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4309 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4310 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4311 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4312 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4313 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4314 { 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 },
4315 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4316 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4317 { 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 },
4318 { 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 },
4319 { 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 },
4320 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4321 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4322 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4323 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4324 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4325 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4328 static bool run_openattrtest(int dummy)
4330 static struct cli_state *cli1;
4331 const char *fname = "\\openattr.file";
4332 int fnum1;
4333 bool correct = True;
4334 uint16 attr;
4335 unsigned int i, j, k, l;
4337 printf("starting open attr test\n");
4339 if (!torture_open_connection(&cli1, 0)) {
4340 return False;
4343 cli_sockopt(cli1, sockops);
4345 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4346 cli_setatr(cli1, fname, 0, 0);
4347 cli_unlink(cli1, fname);
4348 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4349 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4351 if (fnum1 == -1) {
4352 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4353 return False;
4356 if (!cli_close(cli1, fnum1)) {
4357 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4358 return False;
4361 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4362 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4363 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4365 if (fnum1 == -1) {
4366 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4367 if (attr_results[l].num == k) {
4368 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4369 k, open_attrs_table[i],
4370 open_attrs_table[j],
4371 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4372 correct = False;
4375 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4376 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4377 k, open_attrs_table[i], open_attrs_table[j],
4378 cli_errstr(cli1));
4379 correct = False;
4381 #if 0
4382 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4383 #endif
4384 k++;
4385 continue;
4388 if (!cli_close(cli1, fnum1)) {
4389 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4390 return False;
4393 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4394 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4395 return False;
4398 #if 0
4399 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4400 k, open_attrs_table[i], open_attrs_table[j], attr );
4401 #endif
4403 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4404 if (attr_results[l].num == k) {
4405 if (attr != attr_results[l].result_attr ||
4406 open_attrs_table[i] != attr_results[l].init_attr ||
4407 open_attrs_table[j] != attr_results[l].trunc_attr) {
4408 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4409 open_attrs_table[i],
4410 open_attrs_table[j],
4411 (unsigned int)attr,
4412 attr_results[l].result_attr);
4413 correct = False;
4415 break;
4418 k++;
4422 cli_setatr(cli1, fname, 0, 0);
4423 cli_unlink(cli1, fname);
4425 printf("open attr test %s.\n", correct ? "passed" : "failed");
4427 if (!torture_close_connection(cli1)) {
4428 correct = False;
4430 return correct;
4433 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4439 test directory listing speed
4441 static bool run_dirtest(int dummy)
4443 int i;
4444 static struct cli_state *cli;
4445 int fnum;
4446 double t1;
4447 bool correct = True;
4449 printf("starting directory test\n");
4451 if (!torture_open_connection(&cli, 0)) {
4452 return False;
4455 cli_sockopt(cli, sockops);
4457 srandom(0);
4458 for (i=0;i<torture_numops;i++) {
4459 fstring fname;
4460 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4461 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4462 if (fnum == -1) {
4463 fprintf(stderr,"Failed to open %s\n", fname);
4464 return False;
4466 cli_close(cli, fnum);
4469 t1 = end_timer();
4471 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4472 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4473 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4475 printf("dirtest core %g seconds\n", end_timer() - t1);
4477 srandom(0);
4478 for (i=0;i<torture_numops;i++) {
4479 fstring fname;
4480 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4481 cli_unlink(cli, fname);
4484 if (!torture_close_connection(cli)) {
4485 correct = False;
4488 printf("finished dirtest\n");
4490 return correct;
4493 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4495 struct cli_state *pcli = (struct cli_state *)state;
4496 fstring fname;
4497 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4499 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4500 return;
4502 if (finfo->mode & aDIR) {
4503 if (!cli_rmdir(pcli, fname))
4504 printf("del_fn: failed to rmdir %s\n,", fname );
4505 } else {
4506 if (!cli_unlink(pcli, fname))
4507 printf("del_fn: failed to unlink %s\n,", fname );
4513 sees what IOCTLs are supported
4515 bool torture_ioctl_test(int dummy)
4517 static struct cli_state *cli;
4518 uint16 device, function;
4519 int fnum;
4520 const char *fname = "\\ioctl.dat";
4521 DATA_BLOB blob;
4522 NTSTATUS status;
4524 if (!torture_open_connection(&cli, 0)) {
4525 return False;
4528 printf("starting ioctl test\n");
4530 cli_unlink(cli, fname);
4532 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4533 if (fnum == -1) {
4534 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4535 return False;
4538 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4539 printf("ioctl device info: %s\n", cli_errstr(cli));
4541 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4542 printf("ioctl job info: %s\n", cli_errstr(cli));
4544 for (device=0;device<0x100;device++) {
4545 printf("testing device=0x%x\n", device);
4546 for (function=0;function<0x100;function++) {
4547 uint32 code = (device<<16) | function;
4549 status = cli_raw_ioctl(cli, fnum, code, &blob);
4551 if (NT_STATUS_IS_OK(status)) {
4552 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4553 (int)blob.length);
4554 data_blob_free(&blob);
4559 if (!torture_close_connection(cli)) {
4560 return False;
4563 return True;
4568 tries varients of chkpath
4570 bool torture_chkpath_test(int dummy)
4572 static struct cli_state *cli;
4573 int fnum;
4574 bool ret;
4576 if (!torture_open_connection(&cli, 0)) {
4577 return False;
4580 printf("starting chkpath test\n");
4582 /* cleanup from an old run */
4583 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4584 cli_unlink(cli, "\\chkpath.dir\\*");
4585 cli_rmdir(cli, "\\chkpath.dir");
4587 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4588 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4589 return False;
4592 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4593 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4594 return False;
4597 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4598 if (fnum == -1) {
4599 printf("open1 failed (%s)\n", cli_errstr(cli));
4600 return False;
4602 cli_close(cli, fnum);
4604 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4605 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4606 ret = False;
4609 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4610 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4611 ret = False;
4614 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4615 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4616 NT_STATUS_NOT_A_DIRECTORY);
4617 } else {
4618 printf("* chkpath on a file should fail\n");
4619 ret = False;
4622 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4623 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4624 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4625 } else {
4626 printf("* chkpath on a non existant file should fail\n");
4627 ret = False;
4630 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4631 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4632 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4633 } else {
4634 printf("* chkpath on a non existent component should fail\n");
4635 ret = False;
4638 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4639 cli_unlink(cli, "\\chkpath.dir\\*");
4640 cli_rmdir(cli, "\\chkpath.dir");
4642 if (!torture_close_connection(cli)) {
4643 return False;
4646 return ret;
4649 static bool run_eatest(int dummy)
4651 static struct cli_state *cli;
4652 const char *fname = "\\eatest.txt";
4653 bool correct = True;
4654 int fnum, i;
4655 size_t num_eas;
4656 struct ea_struct *ea_list = NULL;
4657 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4659 printf("starting eatest\n");
4661 if (!torture_open_connection(&cli, 0)) {
4662 talloc_destroy(mem_ctx);
4663 return False;
4666 cli_unlink(cli, fname);
4667 fnum = cli_nt_create_full(cli, fname, 0,
4668 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4669 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4670 0x4044, 0);
4672 if (fnum == -1) {
4673 printf("open failed - %s\n", cli_errstr(cli));
4674 talloc_destroy(mem_ctx);
4675 return False;
4678 for (i = 0; i < 10; i++) {
4679 fstring ea_name, ea_val;
4681 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4682 memset(ea_val, (char)i+1, i+1);
4683 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4684 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4685 talloc_destroy(mem_ctx);
4686 return False;
4690 cli_close(cli, fnum);
4691 for (i = 0; i < 10; i++) {
4692 fstring ea_name, ea_val;
4694 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4695 memset(ea_val, (char)i+1, i+1);
4696 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4697 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4698 talloc_destroy(mem_ctx);
4699 return False;
4703 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4704 printf("ea_get list failed - %s\n", cli_errstr(cli));
4705 correct = False;
4708 printf("num_eas = %d\n", (int)num_eas);
4710 if (num_eas != 20) {
4711 printf("Should be 20 EA's stored... failing.\n");
4712 correct = False;
4715 for (i = 0; i < num_eas; i++) {
4716 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4717 dump_data(0, ea_list[i].value.data,
4718 ea_list[i].value.length);
4721 /* Setting EA's to zero length deletes them. Test this */
4722 printf("Now deleting all EA's - case indepenent....\n");
4724 #if 1
4725 cli_set_ea_path(cli, fname, "", "", 0);
4726 #else
4727 for (i = 0; i < 20; i++) {
4728 fstring ea_name;
4729 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4730 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4731 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4732 talloc_destroy(mem_ctx);
4733 return False;
4736 #endif
4738 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4739 printf("ea_get list failed - %s\n", cli_errstr(cli));
4740 correct = False;
4743 printf("num_eas = %d\n", (int)num_eas);
4744 for (i = 0; i < num_eas; i++) {
4745 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4746 dump_data(0, ea_list[i].value.data,
4747 ea_list[i].value.length);
4750 if (num_eas != 0) {
4751 printf("deleting EA's failed.\n");
4752 correct = False;
4755 /* Try and delete a non existant EA. */
4756 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4757 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4758 correct = False;
4761 talloc_destroy(mem_ctx);
4762 if (!torture_close_connection(cli)) {
4763 correct = False;
4766 return correct;
4769 static bool run_dirtest1(int dummy)
4771 int i;
4772 static struct cli_state *cli;
4773 int fnum, num_seen;
4774 bool correct = True;
4776 printf("starting directory test\n");
4778 if (!torture_open_connection(&cli, 0)) {
4779 return False;
4782 cli_sockopt(cli, sockops);
4784 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4785 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4786 cli_rmdir(cli, "\\LISTDIR");
4787 cli_mkdir(cli, "\\LISTDIR");
4789 /* Create 1000 files and 1000 directories. */
4790 for (i=0;i<1000;i++) {
4791 fstring fname;
4792 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4793 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4794 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4795 if (fnum == -1) {
4796 fprintf(stderr,"Failed to open %s\n", fname);
4797 return False;
4799 cli_close(cli, fnum);
4801 for (i=0;i<1000;i++) {
4802 fstring fname;
4803 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4804 if (!cli_mkdir(cli, fname)) {
4805 fprintf(stderr,"Failed to open %s\n", fname);
4806 return False;
4810 /* Now ensure that doing an old list sees both files and directories. */
4811 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4812 printf("num_seen = %d\n", num_seen );
4813 /* We should see 100 files + 1000 directories + . and .. */
4814 if (num_seen != 2002)
4815 correct = False;
4817 /* Ensure if we have the "must have" bits we only see the
4818 * relevent entries.
4820 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4821 printf("num_seen = %d\n", num_seen );
4822 if (num_seen != 1002)
4823 correct = False;
4825 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4826 printf("num_seen = %d\n", num_seen );
4827 if (num_seen != 1000)
4828 correct = False;
4830 /* Delete everything. */
4831 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4832 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4833 cli_rmdir(cli, "\\LISTDIR");
4835 #if 0
4836 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4837 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4838 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4839 #endif
4841 if (!torture_close_connection(cli)) {
4842 correct = False;
4845 printf("finished dirtest1\n");
4847 return correct;
4850 static bool run_error_map_extract(int dummy) {
4852 static struct cli_state *c_dos;
4853 static struct cli_state *c_nt;
4854 NTSTATUS status;
4856 uint32 error;
4858 uint32 flgs2, errnum;
4859 uint8 errclass;
4861 NTSTATUS nt_status;
4863 fstring user;
4865 /* NT-Error connection */
4867 if (!(c_nt = open_nbt_connection())) {
4868 return False;
4871 c_nt->use_spnego = False;
4873 status = cli_negprot(c_nt);
4875 if (!NT_STATUS_IS_OK(status)) {
4876 printf("%s rejected the NT-error negprot (%s)\n", host,
4877 nt_errstr(status));
4878 cli_shutdown(c_nt);
4879 return False;
4882 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4883 workgroup))) {
4884 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4885 return False;
4888 /* DOS-Error connection */
4890 if (!(c_dos = open_nbt_connection())) {
4891 return False;
4894 c_dos->use_spnego = False;
4895 c_dos->force_dos_errors = True;
4897 status = cli_negprot(c_dos);
4898 if (!NT_STATUS_IS_OK(status)) {
4899 printf("%s rejected the DOS-error negprot (%s)\n", host,
4900 nt_errstr(status));
4901 cli_shutdown(c_dos);
4902 return False;
4905 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4906 workgroup))) {
4907 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4908 return False;
4911 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4912 fstr_sprintf(user, "%X", error);
4914 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4915 password, strlen(password),
4916 password, strlen(password),
4917 workgroup))) {
4918 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4921 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4923 /* Case #1: 32-bit NT errors */
4924 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4925 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4926 } else {
4927 printf("/** Dos error on NT connection! (%s) */\n",
4928 cli_errstr(c_nt));
4929 nt_status = NT_STATUS(0xc0000000);
4932 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4933 password, strlen(password),
4934 password, strlen(password),
4935 workgroup))) {
4936 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4938 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4940 /* Case #1: 32-bit NT errors */
4941 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4942 printf("/** NT error on DOS connection! (%s) */\n",
4943 cli_errstr(c_nt));
4944 errnum = errclass = 0;
4945 } else {
4946 cli_dos_error(c_dos, &errclass, &errnum);
4949 if (NT_STATUS_V(nt_status) != error) {
4950 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4951 get_nt_error_c_code(NT_STATUS(error)),
4952 get_nt_error_c_code(nt_status));
4955 printf("\t{%s,\t%s,\t%s},\n",
4956 smb_dos_err_class(errclass),
4957 smb_dos_err_name(errclass, errnum),
4958 get_nt_error_c_code(NT_STATUS(error)));
4960 return True;
4963 static bool run_sesssetup_bench(int dummy)
4965 static struct cli_state *c;
4966 const char *fname = "\\file.dat";
4967 int fnum;
4968 NTSTATUS status;
4969 int i;
4971 if (!torture_open_connection(&c, 0)) {
4972 return false;
4975 fnum = cli_nt_create_full(
4976 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4977 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4978 FILE_DELETE_ON_CLOSE, 0);
4979 if (fnum == -1) {
4980 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4981 return false;
4984 for (i=0; i<torture_numops; i++) {
4985 status = cli_session_setup(
4986 c, username,
4987 password, strlen(password),
4988 password, strlen(password),
4989 workgroup);
4990 if (!NT_STATUS_IS_OK(status)) {
4991 d_printf("(%s) cli_session_setup failed: %s\n",
4992 __location__, nt_errstr(status));
4993 return false;
4996 d_printf("\r%d ", (int)c->vuid);
4998 if (!cli_ulogoff(c)) {
4999 d_printf("(%s) cli_ulogoff failed: %s\n",
5000 __location__, cli_errstr(c));
5001 return false;
5003 c->vuid = 0;
5006 return true;
5009 static bool subst_test(const char *str, const char *user, const char *domain,
5010 uid_t uid, gid_t gid, const char *expected)
5012 char *subst;
5013 bool result = true;
5015 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5017 if (strcmp(subst, expected) != 0) {
5018 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5019 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5020 expected);
5021 result = false;
5024 TALLOC_FREE(subst);
5025 return result;
5028 static void chain1_open_completion(struct tevent_req *req)
5030 int fnum;
5031 NTSTATUS status;
5032 status = cli_open_recv(req, &fnum);
5033 TALLOC_FREE(req);
5035 d_printf("cli_open_recv returned %s: %d\n",
5036 nt_errstr(status),
5037 NT_STATUS_IS_OK(status) ? fnum : -1);
5040 static void chain1_write_completion(struct tevent_req *req)
5042 size_t written;
5043 NTSTATUS status;
5044 status = cli_write_andx_recv(req, &written);
5045 TALLOC_FREE(req);
5047 d_printf("cli_write_andx_recv returned %s: %d\n",
5048 nt_errstr(status),
5049 NT_STATUS_IS_OK(status) ? (int)written : -1);
5052 static void chain1_close_completion(struct tevent_req *req)
5054 NTSTATUS status;
5055 bool *done = (bool *)tevent_req_callback_data_void(req);
5057 status = cli_close_recv(req);
5058 *done = true;
5060 TALLOC_FREE(req);
5062 d_printf("cli_close returned %s\n", nt_errstr(status));
5065 static bool run_chain1(int dummy)
5067 struct cli_state *cli1;
5068 struct event_context *evt = event_context_init(NULL);
5069 struct tevent_req *reqs[3], *smbreqs[3];
5070 bool done = false;
5071 const char *str = "foobar";
5073 printf("starting chain1 test\n");
5074 if (!torture_open_connection(&cli1, 0)) {
5075 return False;
5078 cli_sockopt(cli1, sockops);
5080 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5081 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5082 if (reqs[0] == NULL) return false;
5083 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5086 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5087 (uint8_t *)str, 0, strlen(str)+1,
5088 smbreqs, 1, &smbreqs[1]);
5089 if (reqs[1] == NULL) return false;
5090 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5092 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5093 if (reqs[2] == NULL) return false;
5094 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5096 if (!cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs))) {
5097 return false;
5100 while (!done) {
5101 event_loop_once(evt);
5104 torture_close_connection(cli1);
5105 return True;
5108 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5110 size_t *to_pull = (size_t *)priv;
5111 size_t thistime = *to_pull;
5113 thistime = MIN(thistime, n);
5114 if (thistime == 0) {
5115 return 0;
5118 memset(buf, 0, thistime);
5119 *to_pull -= thistime;
5120 return thistime;
5123 static bool run_windows_write(int dummy)
5125 struct cli_state *cli1;
5126 int fnum;
5127 int i;
5128 bool ret = false;
5129 const char *fname = "\\writetest.txt";
5130 double seconds;
5131 double kbytes;
5133 printf("starting windows_write test\n");
5134 if (!torture_open_connection(&cli1, 0)) {
5135 return False;
5138 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5139 if (fnum == -1) {
5140 printf("open failed (%s)\n", cli_errstr(cli1));
5141 return False;
5144 cli_sockopt(cli1, sockops);
5146 start_timer();
5148 for (i=0; i<torture_numops; i++) {
5149 char c = 0;
5150 off_t start = i * torture_blocksize;
5151 NTSTATUS status;
5152 size_t to_pull = torture_blocksize - 1;
5154 if (cli_write(cli1, fnum, 0, &c,
5155 start + torture_blocksize - 1, 1) != 1) {
5156 printf("cli_write failed: %s\n", cli_errstr(cli1));
5157 goto fail;
5160 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5161 null_source, &to_pull);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 printf("cli_push returned: %s\n", nt_errstr(status));
5164 goto fail;
5168 seconds = end_timer();
5169 kbytes = (double)torture_blocksize * torture_numops;
5170 kbytes /= 1024;
5172 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5173 (double)seconds, (int)(kbytes/seconds));
5175 ret = true;
5176 fail:
5177 cli_close(cli1, fnum);
5178 cli_unlink(cli1, fname);
5179 torture_close_connection(cli1);
5180 return ret;
5183 static bool run_cli_echo(int dummy)
5185 struct cli_state *cli;
5186 NTSTATUS status;
5188 printf("starting cli_echo test\n");
5189 if (!torture_open_connection(&cli, 0)) {
5190 return false;
5192 cli_sockopt(cli, sockops);
5194 status = cli_echo(cli, 5, data_blob_const("hello", 5));
5196 d_printf("cli_echo returned %s\n", nt_errstr(status));
5198 torture_close_connection(cli);
5199 return NT_STATUS_IS_OK(status);
5202 static bool run_local_substitute(int dummy)
5204 bool ok = true;
5206 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5207 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5208 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5209 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5210 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5211 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5212 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5213 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5215 /* Different captialization rules in sub_basic... */
5217 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5218 "blaDOM") == 0);
5220 return ok;
5223 static bool run_local_gencache(int dummy)
5225 char *val;
5226 time_t tm;
5227 DATA_BLOB blob;
5229 if (!gencache_init()) {
5230 d_printf("%s: gencache_init() failed\n", __location__);
5231 return False;
5234 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5235 d_printf("%s: gencache_set() failed\n", __location__);
5236 return False;
5239 if (!gencache_get("foo", &val, &tm)) {
5240 d_printf("%s: gencache_get() failed\n", __location__);
5241 return False;
5244 if (strcmp(val, "bar") != 0) {
5245 d_printf("%s: gencache_get() returned %s, expected %s\n",
5246 __location__, val, "bar");
5247 SAFE_FREE(val);
5248 return False;
5251 SAFE_FREE(val);
5253 if (!gencache_del("foo")) {
5254 d_printf("%s: gencache_del() failed\n", __location__);
5255 return False;
5257 if (gencache_del("foo")) {
5258 d_printf("%s: second gencache_del() succeeded\n",
5259 __location__);
5260 return False;
5263 if (gencache_get("foo", &val, &tm)) {
5264 d_printf("%s: gencache_get() on deleted entry "
5265 "succeeded\n", __location__);
5266 return False;
5269 blob = data_blob_string_const_null("bar");
5270 tm = time(NULL);
5272 if (!gencache_set_data_blob("foo", &blob, tm)) {
5273 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5274 return False;
5277 data_blob_free(&blob);
5279 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5280 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5281 return False;
5284 if (strcmp((const char *)blob.data, "bar") != 0) {
5285 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5286 __location__, (const char *)blob.data, "bar");
5287 data_blob_free(&blob);
5288 return False;
5291 data_blob_free(&blob);
5293 if (!gencache_del("foo")) {
5294 d_printf("%s: gencache_del() failed\n", __location__);
5295 return False;
5297 if (gencache_del("foo")) {
5298 d_printf("%s: second gencache_del() succeeded\n",
5299 __location__);
5300 return False;
5303 if (gencache_get_data_blob("foo", &blob, NULL)) {
5304 d_printf("%s: gencache_get_data_blob() on deleted entry "
5305 "succeeded\n", __location__);
5306 return False;
5309 if (!gencache_shutdown()) {
5310 d_printf("%s: gencache_shutdown() failed\n", __location__);
5311 return False;
5314 if (gencache_shutdown()) {
5315 d_printf("%s: second gencache_shutdown() succeeded\n",
5316 __location__);
5317 return False;
5320 return True;
5323 static bool rbt_testval(struct db_context *db, const char *key,
5324 const char *value)
5326 struct db_record *rec;
5327 TDB_DATA data = string_tdb_data(value);
5328 bool ret = false;
5329 NTSTATUS status;
5331 rec = db->fetch_locked(db, db, string_tdb_data(key));
5332 if (rec == NULL) {
5333 d_fprintf(stderr, "fetch_locked failed\n");
5334 goto done;
5336 status = rec->store(rec, data, 0);
5337 if (!NT_STATUS_IS_OK(status)) {
5338 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5339 goto done;
5341 TALLOC_FREE(rec);
5343 rec = db->fetch_locked(db, db, string_tdb_data(key));
5344 if (rec == NULL) {
5345 d_fprintf(stderr, "second fetch_locked failed\n");
5346 goto done;
5348 if ((rec->value.dsize != data.dsize)
5349 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5350 d_fprintf(stderr, "Got wrong data back\n");
5351 goto done;
5354 ret = true;
5355 done:
5356 TALLOC_FREE(rec);
5357 return ret;
5360 static bool run_local_rbtree(int dummy)
5362 struct db_context *db;
5363 bool ret = false;
5364 int i;
5366 db = db_open_rbt(NULL);
5368 if (db == NULL) {
5369 d_fprintf(stderr, "db_open_rbt failed\n");
5370 return false;
5373 for (i=0; i<1000; i++) {
5374 char *key, *value;
5376 if (asprintf(&key, "key%ld", random()) == -1) {
5377 goto done;
5379 if (asprintf(&value, "value%ld", random()) == -1) {
5380 SAFE_FREE(key);
5381 goto done;
5384 if (!rbt_testval(db, key, value)) {
5385 SAFE_FREE(key);
5386 SAFE_FREE(value);
5387 goto done;
5390 SAFE_FREE(value);
5391 if (asprintf(&value, "value%ld", random()) == -1) {
5392 SAFE_FREE(key);
5393 goto done;
5396 if (!rbt_testval(db, key, value)) {
5397 SAFE_FREE(key);
5398 SAFE_FREE(value);
5399 goto done;
5402 SAFE_FREE(key);
5403 SAFE_FREE(value);
5406 ret = true;
5408 done:
5409 TALLOC_FREE(db);
5410 return ret;
5413 static bool test_stream_name(const char *fname, const char *expected_base,
5414 const char *expected_stream,
5415 NTSTATUS expected_status)
5417 NTSTATUS status;
5418 char *base = NULL;
5419 char *stream = NULL;
5421 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5422 if (!NT_STATUS_EQUAL(status, expected_status)) {
5423 goto error;
5426 if (!NT_STATUS_IS_OK(status)) {
5427 return true;
5430 if (base == NULL) goto error;
5432 if (strcmp(expected_base, base) != 0) goto error;
5434 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5435 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5437 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5438 goto error;
5440 TALLOC_FREE(base);
5441 TALLOC_FREE(stream);
5442 return true;
5444 error:
5445 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5446 fname, expected_base ? expected_base : "<NULL>",
5447 expected_stream ? expected_stream : "<NULL>",
5448 nt_errstr(expected_status));
5449 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5450 base ? base : "<NULL>", stream ? stream : "<NULL>",
5451 nt_errstr(status));
5452 TALLOC_FREE(base);
5453 TALLOC_FREE(stream);
5454 return false;
5457 static bool run_local_stream_name(int dummy)
5459 bool ret = true;
5461 ret &= test_stream_name(
5462 "bla", "bla", NULL, NT_STATUS_OK);
5463 ret &= test_stream_name(
5464 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5465 ret &= test_stream_name(
5466 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5467 ret &= test_stream_name(
5468 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5469 ret &= test_stream_name(
5470 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5471 ret &= test_stream_name(
5472 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5473 ret &= test_stream_name(
5474 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5475 ret &= test_stream_name(
5476 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5478 return ret;
5481 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5483 if (a.length != b.length) {
5484 printf("a.length=%d != b.length=%d\n",
5485 (int)a.length, (int)b.length);
5486 return false;
5488 if (memcmp(a.data, b.data, a.length) != 0) {
5489 printf("a.data and b.data differ\n");
5490 return false;
5492 return true;
5495 static bool run_local_memcache(int dummy)
5497 struct memcache *cache;
5498 DATA_BLOB k1, k2;
5499 DATA_BLOB d1, d2, d3;
5500 DATA_BLOB v1, v2, v3;
5502 TALLOC_CTX *mem_ctx;
5503 char *str1, *str2;
5504 size_t size1, size2;
5505 bool ret = false;
5507 cache = memcache_init(NULL, 100);
5509 if (cache == NULL) {
5510 printf("memcache_init failed\n");
5511 return false;
5514 d1 = data_blob_const("d1", 2);
5515 d2 = data_blob_const("d2", 2);
5516 d3 = data_blob_const("d3", 2);
5518 k1 = data_blob_const("d1", 2);
5519 k2 = data_blob_const("d2", 2);
5521 memcache_add(cache, STAT_CACHE, k1, d1);
5522 memcache_add(cache, GETWD_CACHE, k2, d2);
5524 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5525 printf("could not find k1\n");
5526 return false;
5528 if (!data_blob_equal(d1, v1)) {
5529 return false;
5532 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5533 printf("could not find k2\n");
5534 return false;
5536 if (!data_blob_equal(d2, v2)) {
5537 return false;
5540 memcache_add(cache, STAT_CACHE, k1, d3);
5542 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5543 printf("could not find replaced k1\n");
5544 return false;
5546 if (!data_blob_equal(d3, v3)) {
5547 return false;
5550 memcache_add(cache, GETWD_CACHE, k1, d1);
5552 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5553 printf("Did find k2, should have been purged\n");
5554 return false;
5557 TALLOC_FREE(cache);
5559 cache = memcache_init(NULL, 0);
5561 mem_ctx = talloc_init("foo");
5563 str1 = talloc_strdup(mem_ctx, "string1");
5564 str2 = talloc_strdup(mem_ctx, "string2");
5566 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5567 data_blob_string_const("torture"), &str1);
5568 size1 = talloc_total_size(cache);
5570 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5571 data_blob_string_const("torture"), &str2);
5572 size2 = talloc_total_size(cache);
5574 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5576 if (size2 > size1) {
5577 printf("memcache leaks memory!\n");
5578 goto fail;
5581 ret = true;
5582 fail:
5583 TALLOC_FREE(cache);
5584 return ret;
5587 static void wbclient_done(struct tevent_req *req)
5589 wbcErr wbc_err;
5590 struct winbindd_response *wb_resp;
5591 int *i = (int *)tevent_req_callback_data_void(req);
5593 wbc_err = wb_trans_recv(req, req, &wb_resp);
5594 TALLOC_FREE(req);
5595 *i += 1;
5596 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5599 static bool run_local_wbclient(int dummy)
5601 struct event_context *ev;
5602 struct wb_context **wb_ctx;
5603 struct winbindd_request wb_req;
5604 bool result = false;
5605 int i, j;
5607 BlockSignals(True, SIGPIPE);
5609 ev = event_context_init(talloc_tos());
5610 if (ev == NULL) {
5611 goto fail;
5614 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5615 if (wb_ctx == NULL) {
5616 goto fail;
5619 ZERO_STRUCT(wb_req);
5620 wb_req.cmd = WINBINDD_PING;
5622 for (i=0; i<torture_numops; i++) {
5623 wb_ctx[i] = wb_context_init(ev);
5624 if (wb_ctx[i] == NULL) {
5625 goto fail;
5627 for (j=0; j<5; j++) {
5628 struct tevent_req *req;
5629 req = wb_trans_send(ev, ev, wb_ctx[i],
5630 (j % 2) == 0, &wb_req);
5631 if (req == NULL) {
5632 goto fail;
5634 tevent_req_set_callback(req, wbclient_done, &i);
5638 i = 0;
5640 while (i < 5 * torture_numops) {
5641 event_loop_once(ev);
5644 result = true;
5645 fail:
5646 TALLOC_FREE(ev);
5647 return result;
5650 static double create_procs(bool (*fn)(int), bool *result)
5652 int i, status;
5653 volatile pid_t *child_status;
5654 volatile bool *child_status_out;
5655 int synccount;
5656 int tries = 8;
5658 synccount = 0;
5660 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5661 if (!child_status) {
5662 printf("Failed to setup shared memory\n");
5663 return -1;
5666 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5667 if (!child_status_out) {
5668 printf("Failed to setup result status shared memory\n");
5669 return -1;
5672 for (i = 0; i < nprocs; i++) {
5673 child_status[i] = 0;
5674 child_status_out[i] = True;
5677 start_timer();
5679 for (i=0;i<nprocs;i++) {
5680 procnum = i;
5681 if (fork() == 0) {
5682 pid_t mypid = getpid();
5683 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5685 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5687 while (1) {
5688 if (torture_open_connection(&current_cli, i)) break;
5689 if (tries-- == 0) {
5690 printf("pid %d failed to start\n", (int)getpid());
5691 _exit(1);
5693 smb_msleep(10);
5696 child_status[i] = getpid();
5698 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5700 child_status_out[i] = fn(i);
5701 _exit(0);
5705 do {
5706 synccount = 0;
5707 for (i=0;i<nprocs;i++) {
5708 if (child_status[i]) synccount++;
5710 if (synccount == nprocs) break;
5711 smb_msleep(10);
5712 } while (end_timer() < 30);
5714 if (synccount != nprocs) {
5715 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5716 *result = False;
5717 return end_timer();
5720 /* start the client load */
5721 start_timer();
5723 for (i=0;i<nprocs;i++) {
5724 child_status[i] = 0;
5727 printf("%d clients started\n", nprocs);
5729 for (i=0;i<nprocs;i++) {
5730 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5733 printf("\n");
5735 for (i=0;i<nprocs;i++) {
5736 if (!child_status_out[i]) {
5737 *result = False;
5740 return end_timer();
5743 #define FLAG_MULTIPROC 1
5745 static struct {
5746 const char *name;
5747 bool (*fn)(int);
5748 unsigned flags;
5749 } torture_ops[] = {
5750 {"FDPASS", run_fdpasstest, 0},
5751 {"LOCK1", run_locktest1, 0},
5752 {"LOCK2", run_locktest2, 0},
5753 {"LOCK3", run_locktest3, 0},
5754 {"LOCK4", run_locktest4, 0},
5755 {"LOCK5", run_locktest5, 0},
5756 {"LOCK6", run_locktest6, 0},
5757 {"LOCK7", run_locktest7, 0},
5758 {"UNLINK", run_unlinktest, 0},
5759 {"BROWSE", run_browsetest, 0},
5760 {"ATTR", run_attrtest, 0},
5761 {"TRANS2", run_trans2test, 0},
5762 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5763 {"TORTURE",run_torture, FLAG_MULTIPROC},
5764 {"RANDOMIPC", run_randomipc, 0},
5765 {"NEGNOWAIT", run_negprot_nowait, 0},
5766 {"NBENCH", run_nbench, 0},
5767 {"OPLOCK1", run_oplock1, 0},
5768 {"OPLOCK2", run_oplock2, 0},
5769 {"OPLOCK3", run_oplock3, 0},
5770 {"DIR", run_dirtest, 0},
5771 {"DIR1", run_dirtest1, 0},
5772 {"DENY1", torture_denytest1, 0},
5773 {"DENY2", torture_denytest2, 0},
5774 {"TCON", run_tcon_test, 0},
5775 {"TCONDEV", run_tcon_devtype_test, 0},
5776 {"RW1", run_readwritetest, 0},
5777 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5778 {"RW3", run_readwritelarge, 0},
5779 {"OPEN", run_opentest, 0},
5780 {"POSIX", run_simple_posix_open_test, 0},
5781 #if 1
5782 {"OPENATTR", run_openattrtest, 0},
5783 #endif
5784 {"XCOPY", run_xcopy, 0},
5785 {"RENAME", run_rename, 0},
5786 {"DELETE", run_deletetest, 0},
5787 {"PROPERTIES", run_properties, 0},
5788 {"MANGLE", torture_mangle, 0},
5789 {"W2K", run_w2ktest, 0},
5790 {"TRANS2SCAN", torture_trans2_scan, 0},
5791 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5792 {"UTABLE", torture_utable, 0},
5793 {"CASETABLE", torture_casetable, 0},
5794 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5795 {"PIPE_NUMBER", run_pipe_number, 0},
5796 {"TCON2", run_tcon2_test, 0},
5797 {"IOCTL", torture_ioctl_test, 0},
5798 {"CHKPATH", torture_chkpath_test, 0},
5799 {"FDSESS", run_fdsesstest, 0},
5800 { "EATEST", run_eatest, 0},
5801 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5802 { "CHAIN1", run_chain1, 0},
5803 { "WINDOWS-WRITE", run_windows_write, 0},
5804 { "CLI_ECHO", run_cli_echo, 0},
5805 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5806 { "LOCAL-GENCACHE", run_local_gencache, 0},
5807 { "LOCAL-RBTREE", run_local_rbtree, 0},
5808 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5809 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5810 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5811 {NULL, NULL, 0}};
5815 /****************************************************************************
5816 run a specified test or "ALL"
5817 ****************************************************************************/
5818 static bool run_test(const char *name)
5820 bool ret = True;
5821 bool result = True;
5822 bool found = False;
5823 int i;
5824 double t;
5825 if (strequal(name,"ALL")) {
5826 for (i=0;torture_ops[i].name;i++) {
5827 run_test(torture_ops[i].name);
5829 found = True;
5832 for (i=0;torture_ops[i].name;i++) {
5833 fstr_sprintf(randomfname, "\\XX%x",
5834 (unsigned)random());
5836 if (strequal(name, torture_ops[i].name)) {
5837 found = True;
5838 printf("Running %s\n", name);
5839 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5840 t = create_procs(torture_ops[i].fn, &result);
5841 if (!result) {
5842 ret = False;
5843 printf("TEST %s FAILED!\n", name);
5846 } else {
5847 start_timer();
5848 if (!torture_ops[i].fn(0)) {
5849 ret = False;
5850 printf("TEST %s FAILED!\n", name);
5852 t = end_timer();
5854 printf("%s took %g secs\n\n", name, t);
5858 if (!found) {
5859 printf("Did not find a test named %s\n", name);
5860 ret = False;
5863 return ret;
5867 static void usage(void)
5869 int i;
5871 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5872 printf("Please use samba4 torture.\n\n");
5874 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5876 printf("\t-d debuglevel\n");
5877 printf("\t-U user%%pass\n");
5878 printf("\t-k use kerberos\n");
5879 printf("\t-N numprocs\n");
5880 printf("\t-n my_netbios_name\n");
5881 printf("\t-W workgroup\n");
5882 printf("\t-o num_operations\n");
5883 printf("\t-O socket_options\n");
5884 printf("\t-m maximum protocol\n");
5885 printf("\t-L use oplocks\n");
5886 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5887 printf("\t-A showall\n");
5888 printf("\t-p port\n");
5889 printf("\t-s seed\n");
5890 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5891 printf("\n\n");
5893 printf("tests are:");
5894 for (i=0;torture_ops[i].name;i++) {
5895 printf(" %s", torture_ops[i].name);
5897 printf("\n");
5899 printf("default test is ALL\n");
5901 exit(1);
5904 /****************************************************************************
5905 main program
5906 ****************************************************************************/
5907 int main(int argc,char *argv[])
5909 int opt, i;
5910 char *p;
5911 int gotuser = 0;
5912 int gotpass = 0;
5913 bool correct = True;
5914 TALLOC_CTX *frame = talloc_stackframe();
5915 int seed = time(NULL);
5917 dbf = x_stdout;
5919 #ifdef HAVE_SETBUFFER
5920 setbuffer(stdout, NULL, 0);
5921 #endif
5923 load_case_tables();
5925 if (is_default_dyn_CONFIGFILE()) {
5926 if(getenv("SMB_CONF_PATH")) {
5927 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
5930 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
5931 load_interfaces();
5933 if (argc < 2) {
5934 usage();
5937 for(p = argv[1]; *p; p++)
5938 if(*p == '\\')
5939 *p = '/';
5941 if (strncmp(argv[1], "//", 2)) {
5942 usage();
5945 fstrcpy(host, &argv[1][2]);
5946 p = strchr_m(&host[2],'/');
5947 if (!p) {
5948 usage();
5950 *p = 0;
5951 fstrcpy(share, p+1);
5953 fstrcpy(myname, get_myname(talloc_tos()));
5954 if (!*myname) {
5955 fprintf(stderr, "Failed to get my hostname.\n");
5956 return 1;
5959 if (*username == 0 && getenv("LOGNAME")) {
5960 fstrcpy(username,getenv("LOGNAME"));
5963 argc--;
5964 argv++;
5966 fstrcpy(workgroup, lp_workgroup());
5968 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
5969 switch (opt) {
5970 case 'p':
5971 port_to_use = atoi(optarg);
5972 break;
5973 case 's':
5974 seed = atoi(optarg);
5975 break;
5976 case 'W':
5977 fstrcpy(workgroup,optarg);
5978 break;
5979 case 'm':
5980 max_protocol = interpret_protocol(optarg, max_protocol);
5981 break;
5982 case 'N':
5983 nprocs = atoi(optarg);
5984 break;
5985 case 'o':
5986 torture_numops = atoi(optarg);
5987 break;
5988 case 'd':
5989 DEBUGLEVEL = atoi(optarg);
5990 break;
5991 case 'O':
5992 sockops = optarg;
5993 break;
5994 case 'L':
5995 use_oplocks = True;
5996 break;
5997 case 'A':
5998 torture_showall = True;
5999 break;
6000 case 'n':
6001 fstrcpy(myname, optarg);
6002 break;
6003 case 'c':
6004 client_txt = optarg;
6005 break;
6006 case 'e':
6007 do_encrypt = true;
6008 break;
6009 case 'k':
6010 #ifdef HAVE_KRB5
6011 use_kerberos = True;
6012 #else
6013 d_printf("No kerberos support compiled in\n");
6014 exit(1);
6015 #endif
6016 break;
6017 case 'U':
6018 gotuser = 1;
6019 fstrcpy(username,optarg);
6020 p = strchr_m(username,'%');
6021 if (p) {
6022 *p = 0;
6023 fstrcpy(password, p+1);
6024 gotpass = 1;
6026 break;
6027 case 'b':
6028 fstrcpy(multishare_conn_fname, optarg);
6029 use_multishare_conn = True;
6030 break;
6031 case 'B':
6032 torture_blocksize = atoi(optarg);
6033 break;
6034 default:
6035 printf("Unknown option %c (%d)\n", (char)opt, opt);
6036 usage();
6040 d_printf("using seed %d\n", seed);
6042 srandom(seed);
6044 if(use_kerberos && !gotuser) gotpass = True;
6046 while (!gotpass) {
6047 p = getpass("Password:");
6048 if (p) {
6049 fstrcpy(password, p);
6050 gotpass = 1;
6054 printf("host=%s share=%s user=%s myname=%s\n",
6055 host, share, username, myname);
6057 if (argc == optind) {
6058 correct = run_test("ALL");
6059 } else {
6060 for (i=optind;i<argc;i++) {
6061 if (!run_test(argv[i])) {
6062 correct = False;
6067 TALLOC_FREE(frame);
6069 if (correct) {
6070 return(0);
6071 } else {
6072 return(1);