Make cli_chkpath async.
[Samba/aatanasov.git] / source3 / torture / torture.c
blobc6efa803fa8d77d6606693c67dbc7f68992ac139
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 (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4588 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4589 return False;
4592 if (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4605 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4606 ret = False;
4609 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4610 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4611 ret = False;
4614 if (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(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 bool run_mangle1(int dummy)
5110 struct cli_state *cli;
5111 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5112 int fnum;
5113 fstring alt_name;
5114 NTSTATUS status;
5115 time_t change_time, access_time, write_time;
5116 SMB_OFF_T size;
5117 uint16_t mode;
5119 printf("starting chain1 test\n");
5120 if (!torture_open_connection(&cli, 0)) {
5121 return False;
5124 cli_sockopt(cli, sockops);
5126 fnum = cli_nt_create_full(
5127 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5128 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
5129 if (fnum == -1) {
5130 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5131 return false;
5133 cli_close(cli, fnum);
5135 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5136 if (!NT_STATUS_IS_OK(status)) {
5137 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5138 nt_errstr(status));
5139 return false;
5141 d_printf("alt_name: %s\n", alt_name);
5143 fnum = cli_open(cli, alt_name, O_RDONLY, DENY_NONE);
5144 if (fnum == -1) {
5145 d_printf("cli_open(%s) failed: %s\n", alt_name,
5146 cli_errstr(cli));
5147 return false;
5149 cli_close(cli, fnum);
5151 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5152 &write_time, &size, &mode)) {
5153 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5154 cli_errstr(cli));
5155 return false;
5158 return true;
5161 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5163 size_t *to_pull = (size_t *)priv;
5164 size_t thistime = *to_pull;
5166 thistime = MIN(thistime, n);
5167 if (thistime == 0) {
5168 return 0;
5171 memset(buf, 0, thistime);
5172 *to_pull -= thistime;
5173 return thistime;
5176 static bool run_windows_write(int dummy)
5178 struct cli_state *cli1;
5179 int fnum;
5180 int i;
5181 bool ret = false;
5182 const char *fname = "\\writetest.txt";
5183 double seconds;
5184 double kbytes;
5186 printf("starting windows_write test\n");
5187 if (!torture_open_connection(&cli1, 0)) {
5188 return False;
5191 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5192 if (fnum == -1) {
5193 printf("open failed (%s)\n", cli_errstr(cli1));
5194 return False;
5197 cli_sockopt(cli1, sockops);
5199 start_timer();
5201 for (i=0; i<torture_numops; i++) {
5202 char c = 0;
5203 off_t start = i * torture_blocksize;
5204 NTSTATUS status;
5205 size_t to_pull = torture_blocksize - 1;
5207 if (cli_write(cli1, fnum, 0, &c,
5208 start + torture_blocksize - 1, 1) != 1) {
5209 printf("cli_write failed: %s\n", cli_errstr(cli1));
5210 goto fail;
5213 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5214 null_source, &to_pull);
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("cli_push returned: %s\n", nt_errstr(status));
5217 goto fail;
5221 seconds = end_timer();
5222 kbytes = (double)torture_blocksize * torture_numops;
5223 kbytes /= 1024;
5225 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5226 (double)seconds, (int)(kbytes/seconds));
5228 ret = true;
5229 fail:
5230 cli_close(cli1, fnum);
5231 cli_unlink(cli1, fname);
5232 torture_close_connection(cli1);
5233 return ret;
5236 static bool run_cli_echo(int dummy)
5238 struct cli_state *cli;
5239 NTSTATUS status;
5241 printf("starting cli_echo test\n");
5242 if (!torture_open_connection(&cli, 0)) {
5243 return false;
5245 cli_sockopt(cli, sockops);
5247 status = cli_echo(cli, 5, data_blob_const("hello", 5));
5249 d_printf("cli_echo returned %s\n", nt_errstr(status));
5251 torture_close_connection(cli);
5252 return NT_STATUS_IS_OK(status);
5255 static bool run_uid_regression_test(int dummy)
5257 static struct cli_state *cli;
5258 int16_t old_vuid;
5259 bool correct = True;
5261 printf("starting uid regression test\n");
5263 if (!torture_open_connection(&cli, 0)) {
5264 return False;
5267 cli_sockopt(cli, sockops);
5269 /* Ok - now save then logoff our current user. */
5270 old_vuid = cli->vuid;
5272 if (!cli_ulogoff(cli)) {
5273 d_printf("(%s) cli_ulogoff failed: %s\n",
5274 __location__, cli_errstr(cli));
5275 correct = false;
5276 goto out;
5279 cli->vuid = old_vuid;
5281 /* Try an operation. */
5282 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
5283 /* We expect bad uid. */
5284 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5285 NT_STATUS_NO_SUCH_USER)) {
5286 return False;
5288 goto out;
5291 cli_rmdir(cli, "\\uid_reg_test");
5293 out:
5295 torture_close_connection(cli);
5296 return correct;
5299 static bool run_local_substitute(int dummy)
5301 bool ok = true;
5303 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5304 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5305 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5306 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5307 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5308 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5309 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5310 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5312 /* Different captialization rules in sub_basic... */
5314 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5315 "blaDOM") == 0);
5317 return ok;
5320 static bool run_local_gencache(int dummy)
5322 char *val;
5323 time_t tm;
5324 DATA_BLOB blob;
5326 if (!gencache_init()) {
5327 d_printf("%s: gencache_init() failed\n", __location__);
5328 return False;
5331 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5332 d_printf("%s: gencache_set() failed\n", __location__);
5333 return False;
5336 if (!gencache_get("foo", &val, &tm)) {
5337 d_printf("%s: gencache_get() failed\n", __location__);
5338 return False;
5341 if (strcmp(val, "bar") != 0) {
5342 d_printf("%s: gencache_get() returned %s, expected %s\n",
5343 __location__, val, "bar");
5344 SAFE_FREE(val);
5345 return False;
5348 SAFE_FREE(val);
5350 if (!gencache_del("foo")) {
5351 d_printf("%s: gencache_del() failed\n", __location__);
5352 return False;
5354 if (gencache_del("foo")) {
5355 d_printf("%s: second gencache_del() succeeded\n",
5356 __location__);
5357 return False;
5360 if (gencache_get("foo", &val, &tm)) {
5361 d_printf("%s: gencache_get() on deleted entry "
5362 "succeeded\n", __location__);
5363 return False;
5366 blob = data_blob_string_const_null("bar");
5367 tm = time(NULL);
5369 if (!gencache_set_data_blob("foo", &blob, tm)) {
5370 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5371 return False;
5374 data_blob_free(&blob);
5376 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5377 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5378 return False;
5381 if (strcmp((const char *)blob.data, "bar") != 0) {
5382 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5383 __location__, (const char *)blob.data, "bar");
5384 data_blob_free(&blob);
5385 return False;
5388 data_blob_free(&blob);
5390 if (!gencache_del("foo")) {
5391 d_printf("%s: gencache_del() failed\n", __location__);
5392 return False;
5394 if (gencache_del("foo")) {
5395 d_printf("%s: second gencache_del() succeeded\n",
5396 __location__);
5397 return False;
5400 if (gencache_get_data_blob("foo", &blob, NULL)) {
5401 d_printf("%s: gencache_get_data_blob() on deleted entry "
5402 "succeeded\n", __location__);
5403 return False;
5406 if (!gencache_shutdown()) {
5407 d_printf("%s: gencache_shutdown() failed\n", __location__);
5408 return False;
5411 if (gencache_shutdown()) {
5412 d_printf("%s: second gencache_shutdown() succeeded\n",
5413 __location__);
5414 return False;
5417 return True;
5420 static bool rbt_testval(struct db_context *db, const char *key,
5421 const char *value)
5423 struct db_record *rec;
5424 TDB_DATA data = string_tdb_data(value);
5425 bool ret = false;
5426 NTSTATUS status;
5428 rec = db->fetch_locked(db, db, string_tdb_data(key));
5429 if (rec == NULL) {
5430 d_fprintf(stderr, "fetch_locked failed\n");
5431 goto done;
5433 status = rec->store(rec, data, 0);
5434 if (!NT_STATUS_IS_OK(status)) {
5435 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5436 goto done;
5438 TALLOC_FREE(rec);
5440 rec = db->fetch_locked(db, db, string_tdb_data(key));
5441 if (rec == NULL) {
5442 d_fprintf(stderr, "second fetch_locked failed\n");
5443 goto done;
5445 if ((rec->value.dsize != data.dsize)
5446 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5447 d_fprintf(stderr, "Got wrong data back\n");
5448 goto done;
5451 ret = true;
5452 done:
5453 TALLOC_FREE(rec);
5454 return ret;
5457 static bool run_local_rbtree(int dummy)
5459 struct db_context *db;
5460 bool ret = false;
5461 int i;
5463 db = db_open_rbt(NULL);
5465 if (db == NULL) {
5466 d_fprintf(stderr, "db_open_rbt failed\n");
5467 return false;
5470 for (i=0; i<1000; i++) {
5471 char *key, *value;
5473 if (asprintf(&key, "key%ld", random()) == -1) {
5474 goto done;
5476 if (asprintf(&value, "value%ld", random()) == -1) {
5477 SAFE_FREE(key);
5478 goto done;
5481 if (!rbt_testval(db, key, value)) {
5482 SAFE_FREE(key);
5483 SAFE_FREE(value);
5484 goto done;
5487 SAFE_FREE(value);
5488 if (asprintf(&value, "value%ld", random()) == -1) {
5489 SAFE_FREE(key);
5490 goto done;
5493 if (!rbt_testval(db, key, value)) {
5494 SAFE_FREE(key);
5495 SAFE_FREE(value);
5496 goto done;
5499 SAFE_FREE(key);
5500 SAFE_FREE(value);
5503 ret = true;
5505 done:
5506 TALLOC_FREE(db);
5507 return ret;
5510 static bool test_stream_name(const char *fname, const char *expected_base,
5511 const char *expected_stream,
5512 NTSTATUS expected_status)
5514 NTSTATUS status;
5515 char *base = NULL;
5516 char *stream = NULL;
5518 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5519 if (!NT_STATUS_EQUAL(status, expected_status)) {
5520 goto error;
5523 if (!NT_STATUS_IS_OK(status)) {
5524 return true;
5527 if (base == NULL) goto error;
5529 if (strcmp(expected_base, base) != 0) goto error;
5531 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5532 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5534 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5535 goto error;
5537 TALLOC_FREE(base);
5538 TALLOC_FREE(stream);
5539 return true;
5541 error:
5542 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5543 fname, expected_base ? expected_base : "<NULL>",
5544 expected_stream ? expected_stream : "<NULL>",
5545 nt_errstr(expected_status));
5546 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5547 base ? base : "<NULL>", stream ? stream : "<NULL>",
5548 nt_errstr(status));
5549 TALLOC_FREE(base);
5550 TALLOC_FREE(stream);
5551 return false;
5554 static bool run_local_stream_name(int dummy)
5556 bool ret = true;
5558 ret &= test_stream_name(
5559 "bla", "bla", NULL, NT_STATUS_OK);
5560 ret &= test_stream_name(
5561 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5562 ret &= test_stream_name(
5563 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5564 ret &= test_stream_name(
5565 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5566 ret &= test_stream_name(
5567 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5568 ret &= test_stream_name(
5569 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5570 ret &= test_stream_name(
5571 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5572 ret &= test_stream_name(
5573 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5575 return ret;
5578 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5580 if (a.length != b.length) {
5581 printf("a.length=%d != b.length=%d\n",
5582 (int)a.length, (int)b.length);
5583 return false;
5585 if (memcmp(a.data, b.data, a.length) != 0) {
5586 printf("a.data and b.data differ\n");
5587 return false;
5589 return true;
5592 static bool run_local_memcache(int dummy)
5594 struct memcache *cache;
5595 DATA_BLOB k1, k2;
5596 DATA_BLOB d1, d2, d3;
5597 DATA_BLOB v1, v2, v3;
5599 TALLOC_CTX *mem_ctx;
5600 char *str1, *str2;
5601 size_t size1, size2;
5602 bool ret = false;
5604 cache = memcache_init(NULL, 100);
5606 if (cache == NULL) {
5607 printf("memcache_init failed\n");
5608 return false;
5611 d1 = data_blob_const("d1", 2);
5612 d2 = data_blob_const("d2", 2);
5613 d3 = data_blob_const("d3", 2);
5615 k1 = data_blob_const("d1", 2);
5616 k2 = data_blob_const("d2", 2);
5618 memcache_add(cache, STAT_CACHE, k1, d1);
5619 memcache_add(cache, GETWD_CACHE, k2, d2);
5621 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5622 printf("could not find k1\n");
5623 return false;
5625 if (!data_blob_equal(d1, v1)) {
5626 return false;
5629 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5630 printf("could not find k2\n");
5631 return false;
5633 if (!data_blob_equal(d2, v2)) {
5634 return false;
5637 memcache_add(cache, STAT_CACHE, k1, d3);
5639 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5640 printf("could not find replaced k1\n");
5641 return false;
5643 if (!data_blob_equal(d3, v3)) {
5644 return false;
5647 memcache_add(cache, GETWD_CACHE, k1, d1);
5649 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5650 printf("Did find k2, should have been purged\n");
5651 return false;
5654 TALLOC_FREE(cache);
5656 cache = memcache_init(NULL, 0);
5658 mem_ctx = talloc_init("foo");
5660 str1 = talloc_strdup(mem_ctx, "string1");
5661 str2 = talloc_strdup(mem_ctx, "string2");
5663 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5664 data_blob_string_const("torture"), &str1);
5665 size1 = talloc_total_size(cache);
5667 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5668 data_blob_string_const("torture"), &str2);
5669 size2 = talloc_total_size(cache);
5671 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5673 if (size2 > size1) {
5674 printf("memcache leaks memory!\n");
5675 goto fail;
5678 ret = true;
5679 fail:
5680 TALLOC_FREE(cache);
5681 return ret;
5684 static void wbclient_done(struct tevent_req *req)
5686 wbcErr wbc_err;
5687 struct winbindd_response *wb_resp;
5688 int *i = (int *)tevent_req_callback_data_void(req);
5690 wbc_err = wb_trans_recv(req, req, &wb_resp);
5691 TALLOC_FREE(req);
5692 *i += 1;
5693 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5696 static bool run_local_wbclient(int dummy)
5698 struct event_context *ev;
5699 struct wb_context **wb_ctx;
5700 struct winbindd_request wb_req;
5701 bool result = false;
5702 int i, j;
5704 BlockSignals(True, SIGPIPE);
5706 ev = event_context_init(talloc_tos());
5707 if (ev == NULL) {
5708 goto fail;
5711 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5712 if (wb_ctx == NULL) {
5713 goto fail;
5716 ZERO_STRUCT(wb_req);
5717 wb_req.cmd = WINBINDD_PING;
5719 for (i=0; i<torture_numops; i++) {
5720 wb_ctx[i] = wb_context_init(ev);
5721 if (wb_ctx[i] == NULL) {
5722 goto fail;
5724 for (j=0; j<5; j++) {
5725 struct tevent_req *req;
5726 req = wb_trans_send(ev, ev, wb_ctx[i],
5727 (j % 2) == 0, &wb_req);
5728 if (req == NULL) {
5729 goto fail;
5731 tevent_req_set_callback(req, wbclient_done, &i);
5735 i = 0;
5737 while (i < 5 * torture_numops) {
5738 event_loop_once(ev);
5741 result = true;
5742 fail:
5743 TALLOC_FREE(ev);
5744 return result;
5747 static double create_procs(bool (*fn)(int), bool *result)
5749 int i, status;
5750 volatile pid_t *child_status;
5751 volatile bool *child_status_out;
5752 int synccount;
5753 int tries = 8;
5755 synccount = 0;
5757 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5758 if (!child_status) {
5759 printf("Failed to setup shared memory\n");
5760 return -1;
5763 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5764 if (!child_status_out) {
5765 printf("Failed to setup result status shared memory\n");
5766 return -1;
5769 for (i = 0; i < nprocs; i++) {
5770 child_status[i] = 0;
5771 child_status_out[i] = True;
5774 start_timer();
5776 for (i=0;i<nprocs;i++) {
5777 procnum = i;
5778 if (fork() == 0) {
5779 pid_t mypid = getpid();
5780 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5782 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5784 while (1) {
5785 if (torture_open_connection(&current_cli, i)) break;
5786 if (tries-- == 0) {
5787 printf("pid %d failed to start\n", (int)getpid());
5788 _exit(1);
5790 smb_msleep(10);
5793 child_status[i] = getpid();
5795 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5797 child_status_out[i] = fn(i);
5798 _exit(0);
5802 do {
5803 synccount = 0;
5804 for (i=0;i<nprocs;i++) {
5805 if (child_status[i]) synccount++;
5807 if (synccount == nprocs) break;
5808 smb_msleep(10);
5809 } while (end_timer() < 30);
5811 if (synccount != nprocs) {
5812 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5813 *result = False;
5814 return end_timer();
5817 /* start the client load */
5818 start_timer();
5820 for (i=0;i<nprocs;i++) {
5821 child_status[i] = 0;
5824 printf("%d clients started\n", nprocs);
5826 for (i=0;i<nprocs;i++) {
5827 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5830 printf("\n");
5832 for (i=0;i<nprocs;i++) {
5833 if (!child_status_out[i]) {
5834 *result = False;
5837 return end_timer();
5840 #define FLAG_MULTIPROC 1
5842 static struct {
5843 const char *name;
5844 bool (*fn)(int);
5845 unsigned flags;
5846 } torture_ops[] = {
5847 {"FDPASS", run_fdpasstest, 0},
5848 {"LOCK1", run_locktest1, 0},
5849 {"LOCK2", run_locktest2, 0},
5850 {"LOCK3", run_locktest3, 0},
5851 {"LOCK4", run_locktest4, 0},
5852 {"LOCK5", run_locktest5, 0},
5853 {"LOCK6", run_locktest6, 0},
5854 {"LOCK7", run_locktest7, 0},
5855 {"UNLINK", run_unlinktest, 0},
5856 {"BROWSE", run_browsetest, 0},
5857 {"ATTR", run_attrtest, 0},
5858 {"TRANS2", run_trans2test, 0},
5859 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5860 {"TORTURE",run_torture, FLAG_MULTIPROC},
5861 {"RANDOMIPC", run_randomipc, 0},
5862 {"NEGNOWAIT", run_negprot_nowait, 0},
5863 {"NBENCH", run_nbench, 0},
5864 {"OPLOCK1", run_oplock1, 0},
5865 {"OPLOCK2", run_oplock2, 0},
5866 {"OPLOCK3", run_oplock3, 0},
5867 {"DIR", run_dirtest, 0},
5868 {"DIR1", run_dirtest1, 0},
5869 {"DENY1", torture_denytest1, 0},
5870 {"DENY2", torture_denytest2, 0},
5871 {"TCON", run_tcon_test, 0},
5872 {"TCONDEV", run_tcon_devtype_test, 0},
5873 {"RW1", run_readwritetest, 0},
5874 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5875 {"RW3", run_readwritelarge, 0},
5876 {"OPEN", run_opentest, 0},
5877 {"POSIX", run_simple_posix_open_test, 0},
5878 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
5879 #if 1
5880 {"OPENATTR", run_openattrtest, 0},
5881 #endif
5882 {"XCOPY", run_xcopy, 0},
5883 {"RENAME", run_rename, 0},
5884 {"DELETE", run_deletetest, 0},
5885 {"PROPERTIES", run_properties, 0},
5886 {"MANGLE", torture_mangle, 0},
5887 {"MANGLE1", run_mangle1, 0},
5888 {"W2K", run_w2ktest, 0},
5889 {"TRANS2SCAN", torture_trans2_scan, 0},
5890 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5891 {"UTABLE", torture_utable, 0},
5892 {"CASETABLE", torture_casetable, 0},
5893 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5894 {"PIPE_NUMBER", run_pipe_number, 0},
5895 {"TCON2", run_tcon2_test, 0},
5896 {"IOCTL", torture_ioctl_test, 0},
5897 {"CHKPATH", torture_chkpath_test, 0},
5898 {"FDSESS", run_fdsesstest, 0},
5899 { "EATEST", run_eatest, 0},
5900 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5901 { "CHAIN1", run_chain1, 0},
5902 { "WINDOWS-WRITE", run_windows_write, 0},
5903 { "CLI_ECHO", run_cli_echo, 0},
5904 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5905 { "LOCAL-GENCACHE", run_local_gencache, 0},
5906 { "LOCAL-RBTREE", run_local_rbtree, 0},
5907 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5908 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5909 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5910 {NULL, NULL, 0}};
5914 /****************************************************************************
5915 run a specified test or "ALL"
5916 ****************************************************************************/
5917 static bool run_test(const char *name)
5919 bool ret = True;
5920 bool result = True;
5921 bool found = False;
5922 int i;
5923 double t;
5924 if (strequal(name,"ALL")) {
5925 for (i=0;torture_ops[i].name;i++) {
5926 run_test(torture_ops[i].name);
5928 found = True;
5931 for (i=0;torture_ops[i].name;i++) {
5932 fstr_sprintf(randomfname, "\\XX%x",
5933 (unsigned)random());
5935 if (strequal(name, torture_ops[i].name)) {
5936 found = True;
5937 printf("Running %s\n", name);
5938 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5939 t = create_procs(torture_ops[i].fn, &result);
5940 if (!result) {
5941 ret = False;
5942 printf("TEST %s FAILED!\n", name);
5944 } else {
5945 start_timer();
5946 if (!torture_ops[i].fn(0)) {
5947 ret = False;
5948 printf("TEST %s FAILED!\n", name);
5950 t = end_timer();
5952 printf("%s took %g secs\n\n", name, t);
5956 if (!found) {
5957 printf("Did not find a test named %s\n", name);
5958 ret = False;
5961 return ret;
5965 static void usage(void)
5967 int i;
5969 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5970 printf("Please use samba4 torture.\n\n");
5972 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5974 printf("\t-d debuglevel\n");
5975 printf("\t-U user%%pass\n");
5976 printf("\t-k use kerberos\n");
5977 printf("\t-N numprocs\n");
5978 printf("\t-n my_netbios_name\n");
5979 printf("\t-W workgroup\n");
5980 printf("\t-o num_operations\n");
5981 printf("\t-O socket_options\n");
5982 printf("\t-m maximum protocol\n");
5983 printf("\t-L use oplocks\n");
5984 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5985 printf("\t-A showall\n");
5986 printf("\t-p port\n");
5987 printf("\t-s seed\n");
5988 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5989 printf("\n\n");
5991 printf("tests are:");
5992 for (i=0;torture_ops[i].name;i++) {
5993 printf(" %s", torture_ops[i].name);
5995 printf("\n");
5997 printf("default test is ALL\n");
5999 exit(1);
6002 /****************************************************************************
6003 main program
6004 ****************************************************************************/
6005 int main(int argc,char *argv[])
6007 int opt, i;
6008 char *p;
6009 int gotuser = 0;
6010 int gotpass = 0;
6011 bool correct = True;
6012 TALLOC_CTX *frame = talloc_stackframe();
6013 int seed = time(NULL);
6015 dbf = x_stdout;
6017 #ifdef HAVE_SETBUFFER
6018 setbuffer(stdout, NULL, 0);
6019 #endif
6021 load_case_tables();
6023 if (is_default_dyn_CONFIGFILE()) {
6024 if(getenv("SMB_CONF_PATH")) {
6025 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6028 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6029 load_interfaces();
6031 if (argc < 2) {
6032 usage();
6035 for(p = argv[1]; *p; p++)
6036 if(*p == '\\')
6037 *p = '/';
6039 if (strncmp(argv[1], "//", 2)) {
6040 usage();
6043 fstrcpy(host, &argv[1][2]);
6044 p = strchr_m(&host[2],'/');
6045 if (!p) {
6046 usage();
6048 *p = 0;
6049 fstrcpy(share, p+1);
6051 fstrcpy(myname, get_myname(talloc_tos()));
6052 if (!*myname) {
6053 fprintf(stderr, "Failed to get my hostname.\n");
6054 return 1;
6057 if (*username == 0 && getenv("LOGNAME")) {
6058 fstrcpy(username,getenv("LOGNAME"));
6061 argc--;
6062 argv++;
6064 fstrcpy(workgroup, lp_workgroup());
6066 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6067 switch (opt) {
6068 case 'p':
6069 port_to_use = atoi(optarg);
6070 break;
6071 case 's':
6072 seed = atoi(optarg);
6073 break;
6074 case 'W':
6075 fstrcpy(workgroup,optarg);
6076 break;
6077 case 'm':
6078 max_protocol = interpret_protocol(optarg, max_protocol);
6079 break;
6080 case 'N':
6081 nprocs = atoi(optarg);
6082 break;
6083 case 'o':
6084 torture_numops = atoi(optarg);
6085 break;
6086 case 'd':
6087 DEBUGLEVEL = atoi(optarg);
6088 break;
6089 case 'O':
6090 sockops = optarg;
6091 break;
6092 case 'L':
6093 use_oplocks = True;
6094 break;
6095 case 'A':
6096 torture_showall = True;
6097 break;
6098 case 'n':
6099 fstrcpy(myname, optarg);
6100 break;
6101 case 'c':
6102 client_txt = optarg;
6103 break;
6104 case 'e':
6105 do_encrypt = true;
6106 break;
6107 case 'k':
6108 #ifdef HAVE_KRB5
6109 use_kerberos = True;
6110 #else
6111 d_printf("No kerberos support compiled in\n");
6112 exit(1);
6113 #endif
6114 break;
6115 case 'U':
6116 gotuser = 1;
6117 fstrcpy(username,optarg);
6118 p = strchr_m(username,'%');
6119 if (p) {
6120 *p = 0;
6121 fstrcpy(password, p+1);
6122 gotpass = 1;
6124 break;
6125 case 'b':
6126 fstrcpy(multishare_conn_fname, optarg);
6127 use_multishare_conn = True;
6128 break;
6129 case 'B':
6130 torture_blocksize = atoi(optarg);
6131 break;
6132 default:
6133 printf("Unknown option %c (%d)\n", (char)opt, opt);
6134 usage();
6138 d_printf("using seed %d\n", seed);
6140 srandom(seed);
6142 if(use_kerberos && !gotuser) gotpass = True;
6144 while (!gotpass) {
6145 p = getpass("Password:");
6146 if (p) {
6147 fstrcpy(password, p);
6148 gotpass = 1;
6152 printf("host=%s share=%s user=%s myname=%s\n",
6153 host, share, username, myname);
6155 if (argc == optind) {
6156 correct = run_test("ALL");
6157 } else {
6158 for (i=optind;i<argc;i++) {
6159 if (!run_test(argv[i])) {
6160 correct = False;
6165 TALLOC_FREE(frame);
6167 if (correct) {
6168 return(0);
6169 } else {
6170 return(1);