Fix the build of bin/smbtorture in source3. Guenther please check !
[Samba/ekacnet.git] / source3 / torture / torture.c
blob72b22969b8da09eb14d814ebe91a1350c2f83e01
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
28 extern char *optarg;
29 extern int optind;
31 static fstring host, workgroup, share, password, username, myname;
32 static int max_protocol = PROTOCOL_NT1;
33 static const char *sockops="TCP_NODELAY";
34 static int nprocs=1;
35 static int port_to_use=0;
36 int torture_numops=100;
37 int torture_blocksize=1024*1024;
38 static int procnum; /* records process count number when forking */
39 static struct cli_state *current_cli;
40 static fstring randomfname;
41 static bool use_oplocks;
42 static bool use_level_II_oplocks;
43 static const char *client_txt = "client_oplocks.txt";
44 static bool use_kerberos;
45 static fstring multishare_conn_fname;
46 static bool use_multishare_conn = False;
47 static bool do_encrypt;
48 static const char *local_path = NULL;
50 bool torture_showall = False;
52 static double create_procs(bool (*fn)(int), bool *result);
55 /* return a pointer to a anonymous shared memory segment of size "size"
56 which will persist across fork() but will disappear when all processes
57 exit
59 The memory is not zeroed
61 This function uses system5 shared memory. It takes advantage of a property
62 that the memory is not destroyed if it is attached when the id is removed
64 void *shm_setup(int size)
66 int shmid;
67 void *ret;
69 #ifdef __QNXNTO__
70 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
71 if (shmid == -1) {
72 printf("can't get shared memory\n");
73 exit(1);
75 shm_unlink("private");
76 if (ftruncate(shmid, size) == -1) {
77 printf("can't set shared memory size\n");
78 exit(1);
80 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
81 if (ret == MAP_FAILED) {
82 printf("can't map shared memory\n");
83 exit(1);
85 #else
86 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
87 if (shmid == -1) {
88 printf("can't get shared memory\n");
89 exit(1);
91 ret = (void *)shmat(shmid, 0, 0);
92 if (!ret || ret == (void *)-1) {
93 printf("can't attach to shared memory\n");
94 return NULL;
96 /* the following releases the ipc, but note that this process
97 and all its children will still have access to the memory, its
98 just that the shmid is no longer valid for other shm calls. This
99 means we don't leave behind lots of shm segments after we exit
101 See Stevens "advanced programming in unix env" for details
103 shmctl(shmid, IPC_RMID, 0);
104 #endif
106 return ret;
109 /********************************************************************
110 Ensure a connection is encrypted.
111 ********************************************************************/
113 static bool force_cli_encryption(struct cli_state *c,
114 const char *sharename)
116 uint16 major, minor;
117 uint32 caplow, caphigh;
118 NTSTATUS status;
120 if (!SERVER_HAS_UNIX_CIFS(c)) {
121 d_printf("Encryption required and "
122 "server that doesn't support "
123 "UNIX extensions - failing connect\n");
124 return false;
127 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
128 &caphigh);
129 if (!NT_STATUS_IS_OK(status)) {
130 d_printf("Encryption required and "
131 "can't get UNIX CIFS extensions "
132 "version from server: %s\n", nt_errstr(status));
133 return false;
136 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
137 d_printf("Encryption required and "
138 "share %s doesn't support "
139 "encryption.\n", sharename);
140 return false;
143 if (c->use_kerberos) {
144 status = cli_gss_smb_encryption_start(c);
145 } else {
146 status = cli_raw_ntlm_smb_encryption_start(c,
147 username,
148 password,
149 workgroup);
152 if (!NT_STATUS_IS_OK(status)) {
153 d_printf("Encryption required and "
154 "setup failed with error %s.\n",
155 nt_errstr(status));
156 return false;
159 return true;
163 static struct cli_state *open_nbt_connection(void)
165 struct nmb_name called, calling;
166 struct sockaddr_storage ss;
167 struct cli_state *c;
168 NTSTATUS status;
170 make_nmb_name(&calling, myname, 0x0);
171 make_nmb_name(&called , host, 0x20);
173 zero_sockaddr(&ss);
175 if (!(c = cli_initialise())) {
176 printf("Failed initialize cli_struct to connect with %s\n", host);
177 return NULL;
180 c->port = port_to_use;
182 status = cli_connect(c, host, &ss);
183 if (!NT_STATUS_IS_OK(status)) {
184 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
185 return NULL;
188 c->use_kerberos = use_kerberos;
190 c->timeout = 120000; /* set a really long timeout (2 minutes) */
191 if (use_oplocks) c->use_oplocks = True;
192 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
194 if (!cli_session_request(c, &calling, &called)) {
196 * Well, that failed, try *SMBSERVER ...
197 * However, we must reconnect as well ...
199 status = cli_connect(c, host, &ss);
200 if (!NT_STATUS_IS_OK(status)) {
201 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
202 return NULL;
205 make_nmb_name(&called, "*SMBSERVER", 0x20);
206 if (!cli_session_request(c, &calling, &called)) {
207 printf("%s rejected the session\n",host);
208 printf("We tried with a called name of %s & %s\n",
209 host, "*SMBSERVER");
210 cli_shutdown(c);
211 return NULL;
215 return c;
218 /* Insert a NULL at the first separator of the given path and return a pointer
219 * to the remainder of the string.
221 static char *
222 terminate_path_at_separator(char * path)
224 char * p;
226 if (!path) {
227 return NULL;
230 if ((p = strchr_m(path, '/'))) {
231 *p = '\0';
232 return p + 1;
235 if ((p = strchr_m(path, '\\'))) {
236 *p = '\0';
237 return p + 1;
240 /* No separator. */
241 return NULL;
245 parse a //server/share type UNC name
247 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
248 char **hostname, char **sharename)
250 char *p;
252 *hostname = *sharename = NULL;
254 if (strncmp(unc_name, "\\\\", 2) &&
255 strncmp(unc_name, "//", 2)) {
256 return False;
259 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
260 p = terminate_path_at_separator(*hostname);
262 if (p && *p) {
263 *sharename = talloc_strdup(mem_ctx, p);
264 terminate_path_at_separator(*sharename);
267 if (*hostname && *sharename) {
268 return True;
271 TALLOC_FREE(*hostname);
272 TALLOC_FREE(*sharename);
273 return False;
276 static bool torture_open_connection_share(struct cli_state **c,
277 const char *hostname,
278 const char *sharename)
280 bool retry;
281 int flags = 0;
282 NTSTATUS status;
284 if (use_kerberos)
285 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
286 if (use_oplocks)
287 flags |= CLI_FULL_CONNECTION_OPLOCKS;
288 if (use_level_II_oplocks)
289 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
291 status = cli_full_connection(c, myname,
292 hostname, NULL, port_to_use,
293 sharename, "?????",
294 username, workgroup,
295 password, flags, Undefined, &retry);
296 if (!NT_STATUS_IS_OK(status)) {
297 printf("failed to open share connection: //%s/%s port:%d - %s\n",
298 hostname, sharename, port_to_use, nt_errstr(status));
299 return False;
302 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
304 if (do_encrypt) {
305 return force_cli_encryption(*c,
306 sharename);
308 return True;
311 bool torture_open_connection(struct cli_state **c, int conn_index)
313 char **unc_list = NULL;
314 int num_unc_names = 0;
315 bool result;
317 if (use_multishare_conn==True) {
318 char *h, *s;
319 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
320 if (!unc_list || num_unc_names <= 0) {
321 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
322 exit(1);
325 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
326 NULL, &h, &s)) {
327 printf("Failed to parse UNC name %s\n",
328 unc_list[conn_index % num_unc_names]);
329 TALLOC_FREE(unc_list);
330 exit(1);
333 result = torture_open_connection_share(c, h, s);
335 /* h, s were copied earlier */
336 TALLOC_FREE(unc_list);
337 return result;
340 return torture_open_connection_share(c, host, share);
343 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
345 uint16 old_vuid = cli->vuid;
346 fstring old_user_name;
347 size_t passlen = strlen(password);
348 NTSTATUS status;
349 bool ret;
351 fstrcpy(old_user_name, cli->user_name);
352 cli->vuid = 0;
353 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
354 password, passlen,
355 password, passlen,
356 workgroup));
357 *new_vuid = cli->vuid;
358 cli->vuid = old_vuid;
359 status = cli_set_username(cli, old_user_name);
360 if (!NT_STATUS_IS_OK(status)) {
361 return false;
363 return ret;
367 bool torture_close_connection(struct cli_state *c)
369 bool ret = True;
370 NTSTATUS status;
372 status = cli_tdis(c);
373 if (!NT_STATUS_IS_OK(status)) {
374 printf("tdis failed (%s)\n", nt_errstr(status));
375 ret = False;
378 cli_shutdown(c);
380 return ret;
384 /* check if the server produced the expected error code */
385 static bool check_error(int line, struct cli_state *c,
386 uint8 eclass, uint32 ecode, NTSTATUS nterr)
388 if (cli_is_dos_error(c)) {
389 uint8 cclass;
390 uint32 num;
392 /* Check DOS error */
394 cli_dos_error(c, &cclass, &num);
396 if (eclass != cclass || ecode != num) {
397 printf("unexpected error code class=%d code=%d\n",
398 (int)cclass, (int)num);
399 printf(" expected %d/%d %s (line=%d)\n",
400 (int)eclass, (int)ecode, nt_errstr(nterr), line);
401 return False;
404 } else {
405 NTSTATUS status;
407 /* Check NT error */
409 status = cli_nt_error(c);
411 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
412 printf("unexpected error code %s\n", nt_errstr(status));
413 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
414 return False;
418 return True;
422 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
424 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
425 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
427 return True;
431 static bool rw_torture(struct cli_state *c)
433 const char *lockfname = "\\torture.lck";
434 fstring fname;
435 uint16_t fnum;
436 uint16_t fnum2;
437 pid_t pid2, pid = getpid();
438 int i, j;
439 char buf[1024];
440 bool correct = True;
441 NTSTATUS status;
443 memset(buf, '\0', sizeof(buf));
445 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
446 DENY_NONE, &fnum2);
447 if (!NT_STATUS_IS_OK(status)) {
448 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
450 if (!NT_STATUS_IS_OK(status)) {
451 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
452 return False;
455 for (i=0;i<torture_numops;i++) {
456 unsigned n = (unsigned)sys_random()%10;
457 if (i % 10 == 0) {
458 printf("%d\r", i); fflush(stdout);
460 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
462 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
463 return False;
466 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
467 printf("open failed (%s)\n", cli_errstr(c));
468 correct = False;
469 break;
472 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
473 printf("write failed (%s)\n", cli_errstr(c));
474 correct = False;
477 for (j=0;j<50;j++) {
478 if (cli_write(c, fnum, 0, (char *)buf,
479 sizeof(pid)+(j*sizeof(buf)),
480 sizeof(buf)) != sizeof(buf)) {
481 printf("write failed (%s)\n", cli_errstr(c));
482 correct = False;
486 pid2 = 0;
488 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
489 printf("read failed (%s)\n", cli_errstr(c));
490 correct = False;
493 if (pid2 != pid) {
494 printf("data corruption!\n");
495 correct = False;
498 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
499 printf("close failed (%s)\n", cli_errstr(c));
500 correct = False;
503 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
504 printf("unlink failed (%s)\n", cli_errstr(c));
505 correct = False;
508 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
509 printf("unlock failed (%s)\n", cli_errstr(c));
510 correct = False;
514 cli_close(c, fnum2);
515 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
517 printf("%d\n", i);
519 return correct;
522 static bool run_torture(int dummy)
524 struct cli_state *cli;
525 bool ret;
527 cli = current_cli;
529 cli_sockopt(cli, sockops);
531 ret = rw_torture(cli);
533 if (!torture_close_connection(cli)) {
534 ret = False;
537 return ret;
540 static bool rw_torture3(struct cli_state *c, char *lockfname)
542 uint16_t fnum = (uint16_t)-1;
543 unsigned int i = 0;
544 char buf[131072];
545 char buf_rd[131072];
546 unsigned count;
547 unsigned countprev = 0;
548 ssize_t sent = 0;
549 bool correct = True;
550 NTSTATUS status;
552 srandom(1);
553 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
555 SIVAL(buf, i, sys_random());
558 if (procnum == 0)
560 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
561 DENY_NONE, &fnum))) {
562 printf("first open read/write of %s failed (%s)\n",
563 lockfname, cli_errstr(c));
564 return False;
567 else
569 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
571 status = cli_open(c, lockfname, O_RDONLY,
572 DENY_NONE, &fnum);
573 if (!NT_STATUS_IS_OK(status)) {
574 break;
576 smb_msleep(10);
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("second open read-only of %s failed (%s)\n",
580 lockfname, cli_errstr(c));
581 return False;
585 i = 0;
586 for (count = 0; count < sizeof(buf); count += sent)
588 if (count >= countprev) {
589 printf("%d %8d\r", i, count);
590 fflush(stdout);
591 i++;
592 countprev += (sizeof(buf) / 20);
595 if (procnum == 0)
597 sent = ((unsigned)sys_random()%(20))+ 1;
598 if (sent > sizeof(buf) - count)
600 sent = sizeof(buf) - count;
603 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
604 printf("write failed (%s)\n", cli_errstr(c));
605 correct = False;
608 else
610 sent = cli_read(c, fnum, buf_rd+count, count,
611 sizeof(buf)-count);
612 if (sent < 0)
614 printf("read failed offset:%d size:%ld (%s)\n",
615 count, (unsigned long)sizeof(buf)-count,
616 cli_errstr(c));
617 correct = False;
618 sent = 0;
620 if (sent > 0)
622 if (memcmp(buf_rd+count, buf+count, sent) != 0)
624 printf("read/write compare failed\n");
625 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
626 correct = False;
627 break;
634 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
635 printf("close failed (%s)\n", cli_errstr(c));
636 correct = False;
639 return correct;
642 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
644 const char *lockfname = "\\torture2.lck";
645 uint16_t fnum1;
646 uint16_t fnum2;
647 int i;
648 char buf[131072];
649 char buf_rd[131072];
650 bool correct = True;
651 ssize_t bytes_read;
653 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
654 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
657 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
658 DENY_NONE, &fnum1))) {
659 printf("first open read/write of %s failed (%s)\n",
660 lockfname, cli_errstr(c1));
661 return False;
663 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
664 DENY_NONE, &fnum2))) {
665 printf("second open read-only of %s failed (%s)\n",
666 lockfname, cli_errstr(c2));
667 cli_close(c1, fnum1);
668 return False;
671 for (i=0;i<torture_numops;i++)
673 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
674 if (i % 10 == 0) {
675 printf("%d\r", i); fflush(stdout);
678 generate_random_buffer((unsigned char *)buf, buf_size);
680 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
681 printf("write failed (%s)\n", cli_errstr(c1));
682 correct = False;
683 break;
686 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
687 printf("read failed (%s)\n", cli_errstr(c2));
688 printf("read %d, expected %ld\n", (int)bytes_read,
689 (unsigned long)buf_size);
690 correct = False;
691 break;
694 if (memcmp(buf_rd, buf, buf_size) != 0)
696 printf("read/write compare failed\n");
697 correct = False;
698 break;
702 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
703 printf("close failed (%s)\n", cli_errstr(c2));
704 correct = False;
706 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
707 printf("close failed (%s)\n", cli_errstr(c1));
708 correct = False;
711 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
712 printf("unlink failed (%s)\n", cli_errstr(c1));
713 correct = False;
716 return correct;
719 static bool run_readwritetest(int dummy)
721 struct cli_state *cli1, *cli2;
722 bool test1, test2 = False;
724 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
725 return False;
727 cli_sockopt(cli1, sockops);
728 cli_sockopt(cli2, sockops);
730 printf("starting readwritetest\n");
732 test1 = rw_torture2(cli1, cli2);
733 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
735 if (test1) {
736 test2 = rw_torture2(cli1, cli1);
737 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
740 if (!torture_close_connection(cli1)) {
741 test1 = False;
744 if (!torture_close_connection(cli2)) {
745 test2 = False;
748 return (test1 && test2);
751 static bool run_readwritemulti(int dummy)
753 struct cli_state *cli;
754 bool test;
756 cli = current_cli;
758 cli_sockopt(cli, sockops);
760 printf("run_readwritemulti: fname %s\n", randomfname);
761 test = rw_torture3(cli, randomfname);
763 if (!torture_close_connection(cli)) {
764 test = False;
767 return test;
770 static bool run_readwritelarge(int dummy)
772 static struct cli_state *cli1;
773 uint16_t fnum1;
774 const char *lockfname = "\\large.dat";
775 SMB_OFF_T fsize;
776 char buf[126*1024];
777 bool correct = True;
779 if (!torture_open_connection(&cli1, 0)) {
780 return False;
782 cli_sockopt(cli1, sockops);
783 memset(buf,'\0',sizeof(buf));
785 cli1->max_xmit = 128*1024;
787 printf("starting readwritelarge\n");
789 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
791 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
792 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
793 return False;
796 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
798 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
799 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
800 correct = False;
803 if (fsize == sizeof(buf))
804 printf("readwritelarge test 1 succeeded (size = %lx)\n",
805 (unsigned long)fsize);
806 else {
807 printf("readwritelarge test 1 failed (size = %lx)\n",
808 (unsigned long)fsize);
809 correct = False;
812 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
813 printf("close failed (%s)\n", cli_errstr(cli1));
814 correct = False;
817 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
818 printf("unlink failed (%s)\n", cli_errstr(cli1));
819 correct = False;
822 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
823 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
824 return False;
827 cli1->max_xmit = 4*1024;
829 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
831 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
832 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
833 correct = False;
836 if (fsize == sizeof(buf))
837 printf("readwritelarge test 2 succeeded (size = %lx)\n",
838 (unsigned long)fsize);
839 else {
840 printf("readwritelarge test 2 failed (size = %lx)\n",
841 (unsigned long)fsize);
842 correct = False;
845 #if 0
846 /* ToDo - set allocation. JRA */
847 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
848 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
849 return False;
851 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
852 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
853 correct = False;
855 if (fsize != 0)
856 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
857 #endif
859 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
860 printf("close failed (%s)\n", cli_errstr(cli1));
861 correct = False;
864 if (!torture_close_connection(cli1)) {
865 correct = False;
867 return correct;
870 int line_count = 0;
871 int nbio_id;
873 #define ival(s) strtol(s, NULL, 0)
875 /* run a test that simulates an approximate netbench client load */
876 static bool run_netbench(int client)
878 struct cli_state *cli;
879 int i;
880 char line[1024];
881 char cname[20];
882 FILE *f;
883 const char *params[20];
884 bool correct = True;
886 cli = current_cli;
888 nbio_id = client;
890 cli_sockopt(cli, sockops);
892 nb_setup(cli);
894 slprintf(cname,sizeof(cname)-1, "client%d", client);
896 f = fopen(client_txt, "r");
898 if (!f) {
899 perror(client_txt);
900 return False;
903 while (fgets(line, sizeof(line)-1, f)) {
904 char *saveptr;
905 line_count++;
907 line[strlen(line)-1] = 0;
909 /* printf("[%d] %s\n", line_count, line); */
911 all_string_sub(line,"client1", cname, sizeof(line));
913 /* parse the command parameters */
914 params[0] = strtok_r(line, " ", &saveptr);
915 i = 0;
916 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
918 params[i] = "";
920 if (i < 2) continue;
922 if (!strncmp(params[0],"SMB", 3)) {
923 printf("ERROR: You are using a dbench 1 load file\n");
924 exit(1);
927 if (!strcmp(params[0],"NTCreateX")) {
928 nb_createx(params[1], ival(params[2]), ival(params[3]),
929 ival(params[4]));
930 } else if (!strcmp(params[0],"Close")) {
931 nb_close(ival(params[1]));
932 } else if (!strcmp(params[0],"Rename")) {
933 nb_rename(params[1], params[2]);
934 } else if (!strcmp(params[0],"Unlink")) {
935 nb_unlink(params[1]);
936 } else if (!strcmp(params[0],"Deltree")) {
937 nb_deltree(params[1]);
938 } else if (!strcmp(params[0],"Rmdir")) {
939 nb_rmdir(params[1]);
940 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
941 nb_qpathinfo(params[1]);
942 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
943 nb_qfileinfo(ival(params[1]));
944 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
945 nb_qfsinfo(ival(params[1]));
946 } else if (!strcmp(params[0],"FIND_FIRST")) {
947 nb_findfirst(params[1]);
948 } else if (!strcmp(params[0],"WriteX")) {
949 nb_writex(ival(params[1]),
950 ival(params[2]), ival(params[3]), ival(params[4]));
951 } else if (!strcmp(params[0],"ReadX")) {
952 nb_readx(ival(params[1]),
953 ival(params[2]), ival(params[3]), ival(params[4]));
954 } else if (!strcmp(params[0],"Flush")) {
955 nb_flush(ival(params[1]));
956 } else {
957 printf("Unknown operation %s\n", params[0]);
958 exit(1);
961 fclose(f);
963 nb_cleanup();
965 if (!torture_close_connection(cli)) {
966 correct = False;
969 return correct;
973 /* run a test that simulates an approximate netbench client load */
974 static bool run_nbench(int dummy)
976 double t;
977 bool correct = True;
979 nbio_shmem(nprocs);
981 nbio_id = -1;
983 signal(SIGALRM, nb_alarm);
984 alarm(1);
985 t = create_procs(run_netbench, &correct);
986 alarm(0);
988 printf("\nThroughput %g MB/sec\n",
989 1.0e-6 * nbio_total() / t);
990 return correct;
995 This test checks for two things:
997 1) correct support for retaining locks over a close (ie. the server
998 must not use posix semantics)
999 2) support for lock timeouts
1001 static bool run_locktest1(int dummy)
1003 struct cli_state *cli1, *cli2;
1004 const char *fname = "\\lockt1.lck";
1005 uint16_t fnum1, fnum2, fnum3;
1006 time_t t1, t2;
1007 unsigned lock_timeout;
1009 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1010 return False;
1012 cli_sockopt(cli1, sockops);
1013 cli_sockopt(cli2, sockops);
1015 printf("starting locktest1\n");
1017 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1019 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1020 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1021 return False;
1023 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1024 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1025 return False;
1027 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1028 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1029 return False;
1032 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1033 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1034 return False;
1038 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1039 printf("lock2 succeeded! This is a locking bug\n");
1040 return False;
1041 } else {
1042 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1043 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1047 lock_timeout = (1 + (random() % 20));
1048 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1049 t1 = time(NULL);
1050 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1051 printf("lock3 succeeded! This is a locking bug\n");
1052 return False;
1053 } else {
1054 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1055 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1057 t2 = time(NULL);
1059 if (ABS(t2 - t1) < lock_timeout-1) {
1060 printf("error: This server appears not to support timed lock requests\n");
1063 printf("server slept for %u seconds for a %u second timeout\n",
1064 (unsigned int)(t2-t1), lock_timeout);
1066 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1067 printf("close1 failed (%s)\n", cli_errstr(cli1));
1068 return False;
1071 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1072 printf("lock4 succeeded! This is a locking bug\n");
1073 return False;
1074 } else {
1075 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1076 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1079 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1080 printf("close2 failed (%s)\n", cli_errstr(cli1));
1081 return False;
1084 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1085 printf("close3 failed (%s)\n", cli_errstr(cli2));
1086 return False;
1089 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1090 printf("unlink failed (%s)\n", cli_errstr(cli1));
1091 return False;
1095 if (!torture_close_connection(cli1)) {
1096 return False;
1099 if (!torture_close_connection(cli2)) {
1100 return False;
1103 printf("Passed locktest1\n");
1104 return True;
1108 this checks to see if a secondary tconx can use open files from an
1109 earlier tconx
1111 static bool run_tcon_test(int dummy)
1113 static struct cli_state *cli;
1114 const char *fname = "\\tcontest.tmp";
1115 uint16 fnum1;
1116 uint16 cnum1, cnum2, cnum3;
1117 uint16 vuid1, vuid2;
1118 char buf[4];
1119 bool ret = True;
1120 NTSTATUS status;
1122 memset(buf, '\0', sizeof(buf));
1124 if (!torture_open_connection(&cli, 0)) {
1125 return False;
1127 cli_sockopt(cli, sockops);
1129 printf("starting tcontest\n");
1131 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1133 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1134 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1135 return False;
1138 cnum1 = cli->cnum;
1139 vuid1 = cli->vuid;
1141 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1142 printf("initial write failed (%s)", cli_errstr(cli));
1143 return False;
1146 status = cli_tcon_andx(cli, share, "?????",
1147 password, strlen(password)+1);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 printf("%s refused 2nd tree connect (%s)\n", host,
1150 nt_errstr(status));
1151 cli_shutdown(cli);
1152 return False;
1155 cnum2 = cli->cnum;
1156 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1157 vuid2 = cli->vuid + 1;
1159 /* try a write with the wrong tid */
1160 cli->cnum = cnum2;
1162 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1163 printf("* server allows write with wrong TID\n");
1164 ret = False;
1165 } else {
1166 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1170 /* try a write with an invalid tid */
1171 cli->cnum = cnum3;
1173 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1174 printf("* server allows write with invalid TID\n");
1175 ret = False;
1176 } else {
1177 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1180 /* try a write with an invalid vuid */
1181 cli->vuid = vuid2;
1182 cli->cnum = cnum1;
1184 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1185 printf("* server allows write with invalid VUID\n");
1186 ret = False;
1187 } else {
1188 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1191 cli->cnum = cnum1;
1192 cli->vuid = vuid1;
1194 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1195 printf("close failed (%s)\n", cli_errstr(cli));
1196 return False;
1199 cli->cnum = cnum2;
1201 status = cli_tdis(cli);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1204 return False;
1207 cli->cnum = cnum1;
1209 if (!torture_close_connection(cli)) {
1210 return False;
1213 return ret;
1218 checks for old style tcon support
1220 static bool run_tcon2_test(int dummy)
1222 static struct cli_state *cli;
1223 uint16 cnum, max_xmit;
1224 char *service;
1225 NTSTATUS status;
1227 if (!torture_open_connection(&cli, 0)) {
1228 return False;
1230 cli_sockopt(cli, sockops);
1232 printf("starting tcon2 test\n");
1234 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1235 return false;
1238 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 printf("tcon2 failed : %s\n", cli_errstr(cli));
1242 } else {
1243 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1244 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1247 if (!torture_close_connection(cli)) {
1248 return False;
1251 printf("Passed tcon2 test\n");
1252 return True;
1255 static bool tcon_devtest(struct cli_state *cli,
1256 const char *myshare, const char *devtype,
1257 const char *return_devtype,
1258 NTSTATUS expected_error)
1260 NTSTATUS status;
1261 bool ret;
1263 status = cli_tcon_andx(cli, myshare, devtype,
1264 password, strlen(password)+1);
1266 if (NT_STATUS_IS_OK(expected_error)) {
1267 if (NT_STATUS_IS_OK(status)) {
1268 if (strcmp(cli->dev, return_devtype) == 0) {
1269 ret = True;
1270 } else {
1271 printf("tconX to share %s with type %s "
1272 "succeeded but returned the wrong "
1273 "device type (got [%s] but should have got [%s])\n",
1274 myshare, devtype, cli->dev, return_devtype);
1275 ret = False;
1277 } else {
1278 printf("tconX to share %s with type %s "
1279 "should have succeeded but failed\n",
1280 myshare, devtype);
1281 ret = False;
1283 cli_tdis(cli);
1284 } else {
1285 if (NT_STATUS_IS_OK(status)) {
1286 printf("tconx to share %s with type %s "
1287 "should have failed but succeeded\n",
1288 myshare, devtype);
1289 ret = False;
1290 } else {
1291 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1292 expected_error)) {
1293 ret = True;
1294 } else {
1295 printf("Returned unexpected error\n");
1296 ret = False;
1300 return ret;
1304 checks for correct tconX support
1306 static bool run_tcon_devtype_test(int dummy)
1308 static struct cli_state *cli1 = NULL;
1309 bool retry;
1310 int flags = 0;
1311 NTSTATUS status;
1312 bool ret = True;
1314 status = cli_full_connection(&cli1, myname,
1315 host, NULL, port_to_use,
1316 NULL, NULL,
1317 username, workgroup,
1318 password, flags, Undefined, &retry);
1320 if (!NT_STATUS_IS_OK(status)) {
1321 printf("could not open connection\n");
1322 return False;
1325 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1326 ret = False;
1328 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1329 ret = False;
1331 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332 ret = False;
1334 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1335 ret = False;
1337 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338 ret = False;
1340 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1341 ret = False;
1343 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1344 ret = False;
1346 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1347 ret = False;
1349 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1350 ret = False;
1352 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1353 ret = False;
1355 cli_shutdown(cli1);
1357 if (ret)
1358 printf("Passed tcondevtest\n");
1360 return ret;
1365 This test checks that
1367 1) the server supports multiple locking contexts on the one SMB
1368 connection, distinguished by PID.
1370 2) the server correctly fails overlapping locks made by the same PID (this
1371 goes against POSIX behaviour, which is why it is tricky to implement)
1373 3) the server denies unlock requests by an incorrect client PID
1375 static bool run_locktest2(int dummy)
1377 static struct cli_state *cli;
1378 const char *fname = "\\lockt2.lck";
1379 uint16_t fnum1, fnum2, fnum3;
1380 bool correct = True;
1382 if (!torture_open_connection(&cli, 0)) {
1383 return False;
1386 cli_sockopt(cli, sockops);
1388 printf("starting locktest2\n");
1390 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1392 cli_setpid(cli, 1);
1394 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1395 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1396 return False;
1399 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1400 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1401 return False;
1404 cli_setpid(cli, 2);
1406 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1407 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1408 return False;
1411 cli_setpid(cli, 1);
1413 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1414 printf("lock1 failed (%s)\n", cli_errstr(cli));
1415 return False;
1418 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1419 printf("WRITE lock1 succeeded! This is a locking bug\n");
1420 correct = False;
1421 } else {
1422 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1423 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1426 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1427 printf("WRITE lock2 succeeded! This is a locking bug\n");
1428 correct = False;
1429 } else {
1430 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1431 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1434 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1435 printf("READ lock2 succeeded! This is a locking bug\n");
1436 correct = False;
1437 } else {
1438 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1439 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1442 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1443 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1445 cli_setpid(cli, 2);
1446 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1447 printf("unlock at 100 succeeded! This is a locking bug\n");
1448 correct = False;
1451 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1452 printf("unlock1 succeeded! This is a locking bug\n");
1453 correct = False;
1454 } else {
1455 if (!check_error(__LINE__, cli,
1456 ERRDOS, ERRlock,
1457 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1460 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1461 printf("unlock2 succeeded! This is a locking bug\n");
1462 correct = False;
1463 } else {
1464 if (!check_error(__LINE__, cli,
1465 ERRDOS, ERRlock,
1466 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1469 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1470 printf("lock3 succeeded! This is a locking bug\n");
1471 correct = False;
1472 } else {
1473 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1476 cli_setpid(cli, 1);
1478 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1479 printf("close1 failed (%s)\n", cli_errstr(cli));
1480 return False;
1483 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1484 printf("close2 failed (%s)\n", cli_errstr(cli));
1485 return False;
1488 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1489 printf("close3 failed (%s)\n", cli_errstr(cli));
1490 return False;
1493 if (!torture_close_connection(cli)) {
1494 correct = False;
1497 printf("locktest2 finished\n");
1499 return correct;
1504 This test checks that
1506 1) the server supports the full offset range in lock requests
1508 static bool run_locktest3(int dummy)
1510 static struct cli_state *cli1, *cli2;
1511 const char *fname = "\\lockt3.lck";
1512 uint16_t fnum1, fnum2;
1513 int i;
1514 uint32 offset;
1515 bool correct = True;
1517 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1519 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1520 return False;
1522 cli_sockopt(cli1, sockops);
1523 cli_sockopt(cli2, sockops);
1525 printf("starting locktest3\n");
1527 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1529 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1530 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1531 return False;
1533 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1534 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1535 return False;
1538 for (offset=i=0;i<torture_numops;i++) {
1539 NEXT_OFFSET;
1540 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1541 printf("lock1 %d failed (%s)\n",
1543 cli_errstr(cli1));
1544 return False;
1547 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1548 printf("lock2 %d failed (%s)\n",
1550 cli_errstr(cli1));
1551 return False;
1555 for (offset=i=0;i<torture_numops;i++) {
1556 NEXT_OFFSET;
1558 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1559 printf("error: lock1 %d succeeded!\n", i);
1560 return False;
1563 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1564 printf("error: lock2 %d succeeded!\n", i);
1565 return False;
1568 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1569 printf("error: lock3 %d succeeded!\n", i);
1570 return False;
1573 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1574 printf("error: lock4 %d succeeded!\n", i);
1575 return False;
1579 for (offset=i=0;i<torture_numops;i++) {
1580 NEXT_OFFSET;
1582 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1583 printf("unlock1 %d failed (%s)\n",
1585 cli_errstr(cli1));
1586 return False;
1589 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1590 printf("unlock2 %d failed (%s)\n",
1592 cli_errstr(cli1));
1593 return False;
1597 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1598 printf("close1 failed (%s)\n", cli_errstr(cli1));
1599 return False;
1602 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1603 printf("close2 failed (%s)\n", cli_errstr(cli2));
1604 return False;
1607 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1608 printf("unlink failed (%s)\n", cli_errstr(cli1));
1609 return False;
1612 if (!torture_close_connection(cli1)) {
1613 correct = False;
1616 if (!torture_close_connection(cli2)) {
1617 correct = False;
1620 printf("finished locktest3\n");
1622 return correct;
1625 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1626 printf("** "); correct = False; \
1630 looks at overlapping locks
1632 static bool run_locktest4(int dummy)
1634 static struct cli_state *cli1, *cli2;
1635 const char *fname = "\\lockt4.lck";
1636 uint16_t fnum1, fnum2, f;
1637 bool ret;
1638 char buf[1000];
1639 bool correct = True;
1641 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1642 return False;
1645 cli_sockopt(cli1, sockops);
1646 cli_sockopt(cli2, sockops);
1648 printf("starting locktest4\n");
1650 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1652 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1653 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1655 memset(buf, 0, sizeof(buf));
1657 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1658 printf("Failed to create file\n");
1659 correct = False;
1660 goto fail;
1663 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1664 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1665 EXPECTED(ret, False);
1666 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1668 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1669 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1670 EXPECTED(ret, True);
1671 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1673 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1674 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1675 EXPECTED(ret, False);
1676 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1678 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1679 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1680 EXPECTED(ret, True);
1681 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1683 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1684 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1685 EXPECTED(ret, False);
1686 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1688 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1689 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1690 EXPECTED(ret, True);
1691 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1693 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1694 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1695 EXPECTED(ret, True);
1696 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1698 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1699 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1700 EXPECTED(ret, False);
1701 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1703 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1704 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1705 EXPECTED(ret, False);
1706 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1708 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1709 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1710 EXPECTED(ret, True);
1711 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1713 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1714 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1715 EXPECTED(ret, False);
1716 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1718 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1719 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1720 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1721 EXPECTED(ret, False);
1722 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1725 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1726 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1727 EXPECTED(ret, False);
1728 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1730 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1731 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1732 EXPECTED(ret, False);
1733 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1736 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1737 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1738 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1739 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1740 EXPECTED(ret, True);
1741 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1744 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1745 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1746 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1747 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1748 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1749 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1750 EXPECTED(ret, True);
1751 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1753 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1754 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1755 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1756 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1757 EXPECTED(ret, True);
1758 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1760 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1761 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1762 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1763 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1764 EXPECTED(ret, True);
1765 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1767 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1768 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1769 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1770 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1771 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1772 EXPECTED(ret, True);
1773 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1775 cli_close(cli1, fnum1);
1776 cli_close(cli2, fnum2);
1777 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1778 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1779 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1780 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1781 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1782 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1783 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1784 cli_close(cli1, f);
1785 cli_close(cli1, fnum1);
1786 EXPECTED(ret, True);
1787 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1789 fail:
1790 cli_close(cli1, fnum1);
1791 cli_close(cli2, fnum2);
1792 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1793 torture_close_connection(cli1);
1794 torture_close_connection(cli2);
1796 printf("finished locktest4\n");
1797 return correct;
1801 looks at lock upgrade/downgrade.
1803 static bool run_locktest5(int dummy)
1805 static struct cli_state *cli1, *cli2;
1806 const char *fname = "\\lockt5.lck";
1807 uint16_t fnum1, fnum2, fnum3;
1808 bool ret;
1809 char buf[1000];
1810 bool correct = True;
1812 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1813 return False;
1816 cli_sockopt(cli1, sockops);
1817 cli_sockopt(cli2, sockops);
1819 printf("starting locktest5\n");
1821 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1823 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1824 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1825 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1827 memset(buf, 0, sizeof(buf));
1829 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1830 printf("Failed to create file\n");
1831 correct = False;
1832 goto fail;
1835 /* Check for NT bug... */
1836 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1837 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1838 cli_close(cli1, fnum1);
1839 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1840 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1841 EXPECTED(ret, True);
1842 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1843 cli_close(cli1, fnum1);
1844 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1845 cli_unlock(cli1, fnum3, 0, 1);
1847 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1848 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1849 EXPECTED(ret, True);
1850 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1852 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1853 EXPECTED(ret, False);
1855 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1857 /* Unlock the process 2 lock. */
1858 cli_unlock(cli2, fnum2, 0, 4);
1860 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1861 EXPECTED(ret, False);
1863 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1865 /* Unlock the process 1 fnum3 lock. */
1866 cli_unlock(cli1, fnum3, 0, 4);
1868 /* Stack 2 more locks here. */
1869 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1870 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1872 EXPECTED(ret, True);
1873 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1875 /* Unlock the first process lock, then check this was the WRITE lock that was
1876 removed. */
1878 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1879 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1881 EXPECTED(ret, True);
1882 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1884 /* Unlock the process 2 lock. */
1885 cli_unlock(cli2, fnum2, 0, 4);
1887 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1889 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1890 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1891 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1893 EXPECTED(ret, True);
1894 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1896 /* Ensure the next unlock fails. */
1897 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1898 EXPECTED(ret, False);
1899 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1901 /* Ensure connection 2 can get a write lock. */
1902 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1903 EXPECTED(ret, True);
1905 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1908 fail:
1909 cli_close(cli1, fnum1);
1910 cli_close(cli2, fnum2);
1911 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1912 if (!torture_close_connection(cli1)) {
1913 correct = False;
1915 if (!torture_close_connection(cli2)) {
1916 correct = False;
1919 printf("finished locktest5\n");
1921 return correct;
1925 tries the unusual lockingX locktype bits
1927 static bool run_locktest6(int dummy)
1929 static struct cli_state *cli;
1930 const char *fname[1] = { "\\lock6.txt" };
1931 int i;
1932 uint16_t fnum;
1933 NTSTATUS status;
1935 if (!torture_open_connection(&cli, 0)) {
1936 return False;
1939 cli_sockopt(cli, sockops);
1941 printf("starting locktest6\n");
1943 for (i=0;i<1;i++) {
1944 printf("Testing %s\n", fname[i]);
1946 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1948 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1949 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1950 cli_close(cli, fnum);
1951 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1953 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1954 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1955 cli_close(cli, fnum);
1956 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1958 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1961 torture_close_connection(cli);
1963 printf("finished locktest6\n");
1964 return True;
1967 static bool run_locktest7(int dummy)
1969 struct cli_state *cli1;
1970 const char *fname = "\\lockt7.lck";
1971 uint16_t fnum1;
1972 char buf[200];
1973 bool correct = False;
1975 if (!torture_open_connection(&cli1, 0)) {
1976 return False;
1979 cli_sockopt(cli1, sockops);
1981 printf("starting locktest7\n");
1983 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1985 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1987 memset(buf, 0, sizeof(buf));
1989 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1990 printf("Failed to create file\n");
1991 goto fail;
1994 cli_setpid(cli1, 1);
1996 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1997 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1998 goto fail;
1999 } else {
2000 printf("pid1 successfully locked range 130:4 for READ\n");
2003 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2004 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2005 goto fail;
2006 } else {
2007 printf("pid1 successfully read the range 130:4\n");
2010 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2011 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2012 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2013 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2014 goto fail;
2016 } else {
2017 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2018 goto fail;
2021 cli_setpid(cli1, 2);
2023 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2024 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2025 } else {
2026 printf("pid2 successfully read the range 130:4\n");
2029 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2030 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2031 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2032 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2033 goto fail;
2035 } else {
2036 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2037 goto fail;
2040 cli_setpid(cli1, 1);
2041 cli_unlock(cli1, fnum1, 130, 4);
2043 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2044 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2045 goto fail;
2046 } else {
2047 printf("pid1 successfully locked range 130:4 for WRITE\n");
2050 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2051 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2052 goto fail;
2053 } else {
2054 printf("pid1 successfully read the range 130:4\n");
2057 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2058 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2059 goto fail;
2060 } else {
2061 printf("pid1 successfully wrote to the range 130:4\n");
2064 cli_setpid(cli1, 2);
2066 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2067 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2068 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2069 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2070 goto fail;
2072 } else {
2073 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2074 goto fail;
2077 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2078 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2079 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2080 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2081 goto fail;
2083 } else {
2084 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2085 goto fail;
2088 cli_unlock(cli1, fnum1, 130, 0);
2089 correct = True;
2091 fail:
2092 cli_close(cli1, fnum1);
2093 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2094 torture_close_connection(cli1);
2096 printf("finished locktest7\n");
2097 return correct;
2101 * This demonstrates a problem with our use of GPFS share modes: A file
2102 * descriptor sitting in the pending close queue holding a GPFS share mode
2103 * blocks opening a file another time. Happens with Word 2007 temp files.
2104 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2105 * open is denied with NT_STATUS_SHARING_VIOLATION.
2108 static bool run_locktest8(int dummy)
2110 struct cli_state *cli1;
2111 const char *fname = "\\lockt8.lck";
2112 uint16_t fnum1, fnum2;
2113 char buf[200];
2114 bool correct = False;
2115 NTSTATUS status;
2117 if (!torture_open_connection(&cli1, 0)) {
2118 return False;
2121 cli_sockopt(cli1, sockops);
2123 printf("starting locktest8\n");
2125 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2127 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2128 &fnum1);
2129 if (!NT_STATUS_IS_OK(status)) {
2130 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2131 return false;
2134 memset(buf, 0, sizeof(buf));
2136 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2137 if (!NT_STATUS_IS_OK(status)) {
2138 d_fprintf(stderr, "cli_open second time returned %s\n",
2139 cli_errstr(cli1));
2140 goto fail;
2143 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2144 printf("Unable to apply read lock on range 1:1, error was "
2145 "%s\n", cli_errstr(cli1));
2146 goto fail;
2149 status = cli_close(cli1, fnum1);
2150 if (!NT_STATUS_IS_OK(status)) {
2151 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2152 goto fail;
2155 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 d_fprintf(stderr, "cli_open third time returned %s\n",
2158 cli_errstr(cli1));
2159 goto fail;
2162 correct = true;
2164 fail:
2165 cli_close(cli1, fnum1);
2166 cli_close(cli1, fnum2);
2167 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2168 torture_close_connection(cli1);
2170 printf("finished locktest8\n");
2171 return correct;
2175 * This test is designed to be run in conjunction with
2176 * external NFS or POSIX locks taken in the filesystem.
2177 * It checks that the smbd server will block until the
2178 * lock is released and then acquire it. JRA.
2181 static bool got_alarm;
2182 static int alarm_fd;
2184 static void alarm_handler(int dummy)
2186 got_alarm = True;
2189 static void alarm_handler_parent(int dummy)
2191 close(alarm_fd);
2194 static void do_local_lock(int read_fd, int write_fd)
2196 int fd;
2197 char c = '\0';
2198 struct flock lock;
2199 const char *local_pathname = NULL;
2200 int ret;
2202 local_pathname = talloc_asprintf(talloc_tos(),
2203 "%s/lockt9.lck", local_path);
2204 if (!local_pathname) {
2205 printf("child: alloc fail\n");
2206 exit(1);
2209 unlink(local_pathname);
2210 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2211 if (fd == -1) {
2212 printf("child: open of %s failed %s.\n",
2213 local_pathname, strerror(errno));
2214 exit(1);
2217 /* Now take a fcntl lock. */
2218 lock.l_type = F_WRLCK;
2219 lock.l_whence = SEEK_SET;
2220 lock.l_start = 0;
2221 lock.l_len = 4;
2222 lock.l_pid = getpid();
2224 ret = fcntl(fd,F_SETLK,&lock);
2225 if (ret == -1) {
2226 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2227 local_pathname, strerror(errno));
2228 exit(1);
2229 } else {
2230 printf("child: got lock 0:4 on file %s.\n",
2231 local_pathname );
2232 fflush(stdout);
2235 CatchSignal(SIGALRM, alarm_handler);
2236 alarm(5);
2237 /* Signal the parent. */
2238 if (write(write_fd, &c, 1) != 1) {
2239 printf("child: start signal fail %s.\n",
2240 strerror(errno));
2241 exit(1);
2243 alarm(0);
2245 alarm(10);
2246 /* Wait for the parent to be ready. */
2247 if (read(read_fd, &c, 1) != 1) {
2248 printf("child: reply signal fail %s.\n",
2249 strerror(errno));
2250 exit(1);
2252 alarm(0);
2254 sleep(5);
2255 close(fd);
2256 printf("child: released lock 0:4 on file %s.\n",
2257 local_pathname );
2258 fflush(stdout);
2259 exit(0);
2262 static bool run_locktest9(int dummy)
2264 struct cli_state *cli1;
2265 const char *fname = "\\lockt9.lck";
2266 uint16_t fnum;
2267 bool correct = False;
2268 int pipe_in[2], pipe_out[2];
2269 pid_t child_pid;
2270 char c = '\0';
2271 int ret;
2272 struct timeval start;
2273 double seconds;
2274 NTSTATUS status;
2276 printf("starting locktest9\n");
2278 if (local_path == NULL) {
2279 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2280 return false;
2283 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2284 return false;
2287 child_pid = fork();
2288 if (child_pid == -1) {
2289 return false;
2292 if (child_pid == 0) {
2293 /* Child. */
2294 do_local_lock(pipe_out[0], pipe_in[1]);
2295 exit(0);
2298 close(pipe_out[0]);
2299 close(pipe_in[1]);
2300 pipe_out[0] = -1;
2301 pipe_in[1] = -1;
2303 /* Parent. */
2304 ret = read(pipe_in[0], &c, 1);
2305 if (ret != 1) {
2306 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2307 strerror(errno));
2308 return false;
2311 if (!torture_open_connection(&cli1, 0)) {
2312 return false;
2315 cli_sockopt(cli1, sockops);
2317 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2318 &fnum);
2319 if (!NT_STATUS_IS_OK(status)) {
2320 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2321 return false;
2324 /* Ensure the child has the lock. */
2325 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2326 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2327 goto fail;
2328 } else {
2329 d_printf("Child has the lock.\n");
2332 /* Tell the child to wait 5 seconds then exit. */
2333 ret = write(pipe_out[1], &c, 1);
2334 if (ret != 1) {
2335 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2336 strerror(errno));
2337 goto fail;
2340 /* Wait 20 seconds for the lock. */
2341 alarm_fd = cli1->fd;
2342 CatchSignal(SIGALRM, alarm_handler_parent);
2343 alarm(20);
2345 start = timeval_current();
2347 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2348 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2349 "%s\n", cli_errstr(cli1));
2350 goto fail_nofd;
2352 alarm(0);
2354 seconds = timeval_elapsed(&start);
2356 printf("Parent got the lock after %.2f seconds.\n",
2357 seconds);
2359 status = cli_close(cli1, fnum);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2362 goto fail;
2365 correct = true;
2367 fail:
2368 cli_close(cli1, fnum);
2369 torture_close_connection(cli1);
2371 fail_nofd:
2373 printf("finished locktest9\n");
2374 return correct;
2378 test whether fnums and tids open on one VC are available on another (a major
2379 security hole)
2381 static bool run_fdpasstest(int dummy)
2383 struct cli_state *cli1, *cli2;
2384 const char *fname = "\\fdpass.tst";
2385 uint16_t fnum1;
2386 char buf[1024];
2388 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2389 return False;
2391 cli_sockopt(cli1, sockops);
2392 cli_sockopt(cli2, sockops);
2394 printf("starting fdpasstest\n");
2396 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2398 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2399 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2400 return False;
2403 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2404 printf("write failed (%s)\n", cli_errstr(cli1));
2405 return False;
2408 cli2->vuid = cli1->vuid;
2409 cli2->cnum = cli1->cnum;
2410 cli2->pid = cli1->pid;
2412 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2413 printf("read succeeded! nasty security hole [%s]\n",
2414 buf);
2415 return False;
2418 cli_close(cli1, fnum1);
2419 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2421 torture_close_connection(cli1);
2422 torture_close_connection(cli2);
2424 printf("finished fdpasstest\n");
2425 return True;
2428 static bool run_fdsesstest(int dummy)
2430 struct cli_state *cli;
2431 uint16 new_vuid;
2432 uint16 saved_vuid;
2433 uint16 new_cnum;
2434 uint16 saved_cnum;
2435 const char *fname = "\\fdsess.tst";
2436 const char *fname1 = "\\fdsess1.tst";
2437 uint16_t fnum1;
2438 uint16_t fnum2;
2439 char buf[1024];
2440 bool ret = True;
2442 if (!torture_open_connection(&cli, 0))
2443 return False;
2444 cli_sockopt(cli, sockops);
2446 if (!torture_cli_session_setup2(cli, &new_vuid))
2447 return False;
2449 saved_cnum = cli->cnum;
2450 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2451 return False;
2452 new_cnum = cli->cnum;
2453 cli->cnum = saved_cnum;
2455 printf("starting fdsesstest\n");
2457 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2458 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2460 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2461 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2462 return False;
2465 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2466 printf("write failed (%s)\n", cli_errstr(cli));
2467 return False;
2470 saved_vuid = cli->vuid;
2471 cli->vuid = new_vuid;
2473 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2474 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2475 buf);
2476 ret = False;
2478 /* Try to open a file with different vuid, samba cnum. */
2479 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2480 printf("create with different vuid, same cnum succeeded.\n");
2481 cli_close(cli, fnum2);
2482 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2483 } else {
2484 printf("create with different vuid, same cnum failed.\n");
2485 printf("This will cause problems with service clients.\n");
2486 ret = False;
2489 cli->vuid = saved_vuid;
2491 /* Try with same vuid, different cnum. */
2492 cli->cnum = new_cnum;
2494 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2495 printf("read succeeded with different cnum![%s]\n",
2496 buf);
2497 ret = False;
2500 cli->cnum = saved_cnum;
2501 cli_close(cli, fnum1);
2502 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2504 torture_close_connection(cli);
2506 printf("finished fdsesstest\n");
2507 return ret;
2511 This test checks that
2513 1) the server does not allow an unlink on a file that is open
2515 static bool run_unlinktest(int dummy)
2517 struct cli_state *cli;
2518 const char *fname = "\\unlink.tst";
2519 uint16_t fnum;
2520 bool correct = True;
2522 if (!torture_open_connection(&cli, 0)) {
2523 return False;
2526 cli_sockopt(cli, sockops);
2528 printf("starting unlink test\n");
2530 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2532 cli_setpid(cli, 1);
2534 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2535 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2536 return False;
2539 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2540 printf("error: server allowed unlink on an open file\n");
2541 correct = False;
2542 } else {
2543 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2544 NT_STATUS_SHARING_VIOLATION);
2547 cli_close(cli, fnum);
2548 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2550 if (!torture_close_connection(cli)) {
2551 correct = False;
2554 printf("unlink test finished\n");
2556 return correct;
2561 test how many open files this server supports on the one socket
2563 static bool run_maxfidtest(int dummy)
2565 struct cli_state *cli;
2566 const char *ftemplate = "\\maxfid.%d.%d";
2567 fstring fname;
2568 uint16_t fnums[0x11000];
2569 int i;
2570 int retries=4;
2571 bool correct = True;
2573 cli = current_cli;
2575 if (retries <= 0) {
2576 printf("failed to connect\n");
2577 return False;
2580 cli_sockopt(cli, sockops);
2582 for (i=0; i<0x11000; i++) {
2583 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2584 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2585 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2586 printf("open of %s failed (%s)\n",
2587 fname, cli_errstr(cli));
2588 printf("maximum fnum is %d\n", i);
2589 break;
2591 printf("%6d\r", i);
2593 printf("%6d\n", i);
2594 i--;
2596 printf("cleaning up\n");
2597 for (;i>=0;i--) {
2598 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2599 cli_close(cli, fnums[i]);
2600 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2601 printf("unlink of %s failed (%s)\n",
2602 fname, cli_errstr(cli));
2603 correct = False;
2605 printf("%6d\r", i);
2607 printf("%6d\n", 0);
2609 printf("maxfid test finished\n");
2610 if (!torture_close_connection(cli)) {
2611 correct = False;
2613 return correct;
2616 /* generate a random buffer */
2617 static void rand_buf(char *buf, int len)
2619 while (len--) {
2620 *buf = (char)sys_random();
2621 buf++;
2625 /* send smb negprot commands, not reading the response */
2626 static bool run_negprot_nowait(int dummy)
2628 int i;
2629 static struct cli_state *cli;
2630 bool correct = True;
2632 printf("starting negprot nowait test\n");
2634 if (!(cli = open_nbt_connection())) {
2635 return False;
2638 for (i=0;i<50000;i++) {
2639 cli_negprot_sendsync(cli);
2642 if (!torture_close_connection(cli)) {
2643 correct = False;
2646 printf("finished negprot nowait test\n");
2648 return correct;
2652 /* send random IPC commands */
2653 static bool run_randomipc(int dummy)
2655 char *rparam = NULL;
2656 char *rdata = NULL;
2657 unsigned int rdrcnt,rprcnt;
2658 char param[1024];
2659 int api, param_len, i;
2660 struct cli_state *cli;
2661 bool correct = True;
2662 int count = 50000;
2664 printf("starting random ipc test\n");
2666 if (!torture_open_connection(&cli, 0)) {
2667 return False;
2670 for (i=0;i<count;i++) {
2671 api = sys_random() % 500;
2672 param_len = (sys_random() % 64);
2674 rand_buf(param, param_len);
2676 SSVAL(param,0,api);
2678 cli_api(cli,
2679 param, param_len, 8,
2680 NULL, 0, BUFFER_SIZE,
2681 &rparam, &rprcnt,
2682 &rdata, &rdrcnt);
2683 if (i % 100 == 0) {
2684 printf("%d/%d\r", i,count);
2687 printf("%d/%d\n", i, count);
2689 if (!torture_close_connection(cli)) {
2690 correct = False;
2693 printf("finished random ipc test\n");
2695 return correct;
2700 static void browse_callback(const char *sname, uint32 stype,
2701 const char *comment, void *state)
2703 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2709 This test checks the browse list code
2712 static bool run_browsetest(int dummy)
2714 static struct cli_state *cli;
2715 bool correct = True;
2717 printf("starting browse test\n");
2719 if (!torture_open_connection(&cli, 0)) {
2720 return False;
2723 printf("domain list:\n");
2724 cli_NetServerEnum(cli, cli->server_domain,
2725 SV_TYPE_DOMAIN_ENUM,
2726 browse_callback, NULL);
2728 printf("machine list:\n");
2729 cli_NetServerEnum(cli, cli->server_domain,
2730 SV_TYPE_ALL,
2731 browse_callback, NULL);
2733 if (!torture_close_connection(cli)) {
2734 correct = False;
2737 printf("browse test finished\n");
2739 return correct;
2745 This checks how the getatr calls works
2747 static bool run_attrtest(int dummy)
2749 struct cli_state *cli;
2750 uint16_t fnum;
2751 time_t t, t2;
2752 const char *fname = "\\attrib123456789.tst";
2753 bool correct = True;
2755 printf("starting attrib test\n");
2757 if (!torture_open_connection(&cli, 0)) {
2758 return False;
2761 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2762 cli_open(cli, fname,
2763 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2764 cli_close(cli, fnum);
2765 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2766 printf("getatr failed (%s)\n", cli_errstr(cli));
2767 correct = False;
2770 if (abs(t - time(NULL)) > 60*60*24*10) {
2771 printf("ERROR: SMBgetatr bug. time is %s",
2772 ctime(&t));
2773 t = time(NULL);
2774 correct = True;
2777 t2 = t-60*60*24; /* 1 day ago */
2779 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2780 printf("setatr failed (%s)\n", cli_errstr(cli));
2781 correct = True;
2784 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2785 printf("getatr failed (%s)\n", cli_errstr(cli));
2786 correct = True;
2789 if (t != t2) {
2790 printf("ERROR: getatr/setatr bug. times are\n%s",
2791 ctime(&t));
2792 printf("%s", ctime(&t2));
2793 correct = True;
2796 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2798 if (!torture_close_connection(cli)) {
2799 correct = False;
2802 printf("attrib test finished\n");
2804 return correct;
2809 This checks a couple of trans2 calls
2811 static bool run_trans2test(int dummy)
2813 struct cli_state *cli;
2814 uint16_t fnum;
2815 SMB_OFF_T size;
2816 time_t c_time, a_time, m_time;
2817 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2818 const char *fname = "\\trans2.tst";
2819 const char *dname = "\\trans2";
2820 const char *fname2 = "\\trans2\\trans2.tst";
2821 char pname[1024];
2822 bool correct = True;
2823 NTSTATUS status;
2824 uint32_t fs_attr;
2826 printf("starting trans2 test\n");
2828 if (!torture_open_connection(&cli, 0)) {
2829 return False;
2832 status = cli_get_fs_attr_info(cli, &fs_attr);
2833 if (!NT_STATUS_IS_OK(status)) {
2834 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2835 nt_errstr(status));
2836 correct = false;
2839 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2840 cli_open(cli, fname,
2841 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2842 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2843 &m_time_ts, NULL)) {
2844 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2845 correct = False;
2848 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2849 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2850 correct = False;
2853 if (strcmp(pname, fname)) {
2854 printf("qfilename gave different name? [%s] [%s]\n",
2855 fname, pname);
2856 correct = False;
2859 cli_close(cli, fnum);
2861 sleep(2);
2863 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2864 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2865 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2866 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2867 return False;
2869 cli_close(cli, fnum);
2871 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2872 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2873 correct = False;
2874 } else {
2875 if (c_time != m_time) {
2876 printf("create time=%s", ctime(&c_time));
2877 printf("modify time=%s", ctime(&m_time));
2878 printf("This system appears to have sticky create times\n");
2880 if (a_time % (60*60) == 0) {
2881 printf("access time=%s", ctime(&a_time));
2882 printf("This system appears to set a midnight access time\n");
2883 correct = False;
2886 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2887 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2888 correct = False;
2893 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2894 cli_open(cli, fname,
2895 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2896 cli_close(cli, fnum);
2897 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2898 &m_time_ts, &size, NULL, NULL)) {
2899 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2900 correct = False;
2901 } else {
2902 if (w_time_ts.tv_sec < 60*60*24*2) {
2903 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2904 printf("This system appears to set a initial 0 write time\n");
2905 correct = False;
2909 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2912 /* check if the server updates the directory modification time
2913 when creating a new file */
2914 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2915 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2916 correct = False;
2918 sleep(3);
2919 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2920 &m_time_ts, &size, NULL, NULL)) {
2921 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2922 correct = False;
2925 cli_open(cli, fname2,
2926 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2927 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2928 cli_close(cli, fnum);
2929 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2930 &m_time2_ts, &size, NULL, NULL)) {
2931 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2932 correct = False;
2933 } else {
2934 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2935 == 0) {
2936 printf("This system does not update directory modification times\n");
2937 correct = False;
2940 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2941 cli_rmdir(cli, dname);
2943 if (!torture_close_connection(cli)) {
2944 correct = False;
2947 printf("trans2 test finished\n");
2949 return correct;
2953 This checks new W2K calls.
2956 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2958 char *buf = NULL;
2959 uint32 len;
2960 bool correct = True;
2962 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2963 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2964 correct = False;
2965 } else {
2966 printf("qfileinfo: level %d, len = %u\n", level, len);
2967 dump_data(0, (uint8 *)buf, len);
2968 printf("\n");
2970 SAFE_FREE(buf);
2971 return correct;
2974 static bool run_w2ktest(int dummy)
2976 struct cli_state *cli;
2977 uint16_t fnum;
2978 const char *fname = "\\w2ktest\\w2k.tst";
2979 int level;
2980 bool correct = True;
2982 printf("starting w2k test\n");
2984 if (!torture_open_connection(&cli, 0)) {
2985 return False;
2988 cli_open(cli, fname,
2989 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2991 for (level = 1004; level < 1040; level++) {
2992 new_trans(cli, fnum, level);
2995 cli_close(cli, fnum);
2997 if (!torture_close_connection(cli)) {
2998 correct = False;
3001 printf("w2k test finished\n");
3003 return correct;
3008 this is a harness for some oplock tests
3010 static bool run_oplock1(int dummy)
3012 struct cli_state *cli1;
3013 const char *fname = "\\lockt1.lck";
3014 uint16_t fnum1;
3015 bool correct = True;
3017 printf("starting oplock test 1\n");
3019 if (!torture_open_connection(&cli1, 0)) {
3020 return False;
3023 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3025 cli_sockopt(cli1, sockops);
3027 cli1->use_oplocks = True;
3029 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3030 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3031 return False;
3034 cli1->use_oplocks = False;
3036 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3037 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3039 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3040 printf("close2 failed (%s)\n", cli_errstr(cli1));
3041 return False;
3044 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3045 printf("unlink failed (%s)\n", cli_errstr(cli1));
3046 return False;
3049 if (!torture_close_connection(cli1)) {
3050 correct = False;
3053 printf("finished oplock test 1\n");
3055 return correct;
3058 static bool run_oplock2(int dummy)
3060 struct cli_state *cli1, *cli2;
3061 const char *fname = "\\lockt2.lck";
3062 uint16_t fnum1, fnum2;
3063 int saved_use_oplocks = use_oplocks;
3064 char buf[4];
3065 bool correct = True;
3066 volatile bool *shared_correct;
3068 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3069 *shared_correct = True;
3071 use_level_II_oplocks = True;
3072 use_oplocks = True;
3074 printf("starting oplock test 2\n");
3076 if (!torture_open_connection(&cli1, 0)) {
3077 use_level_II_oplocks = False;
3078 use_oplocks = saved_use_oplocks;
3079 return False;
3082 cli1->use_oplocks = True;
3083 cli1->use_level_II_oplocks = True;
3085 if (!torture_open_connection(&cli2, 1)) {
3086 use_level_II_oplocks = False;
3087 use_oplocks = saved_use_oplocks;
3088 return False;
3091 cli2->use_oplocks = True;
3092 cli2->use_level_II_oplocks = True;
3094 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3096 cli_sockopt(cli1, sockops);
3097 cli_sockopt(cli2, sockops);
3099 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3100 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3101 return False;
3104 /* Don't need the globals any more. */
3105 use_level_II_oplocks = False;
3106 use_oplocks = saved_use_oplocks;
3108 if (fork() == 0) {
3109 /* Child code */
3110 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3111 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3112 *shared_correct = False;
3113 exit(0);
3116 sleep(2);
3118 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3119 printf("close2 failed (%s)\n", cli_errstr(cli1));
3120 *shared_correct = False;
3123 exit(0);
3126 sleep(2);
3128 /* Ensure cli1 processes the break. Empty file should always return 0
3129 * bytes. */
3131 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3132 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3133 correct = False;
3136 /* Should now be at level II. */
3137 /* Test if sending a write locks causes a break to none. */
3139 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3140 printf("lock failed (%s)\n", cli_errstr(cli1));
3141 correct = False;
3144 cli_unlock(cli1, fnum1, 0, 4);
3146 sleep(2);
3148 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3149 printf("lock failed (%s)\n", cli_errstr(cli1));
3150 correct = False;
3153 cli_unlock(cli1, fnum1, 0, 4);
3155 sleep(2);
3157 cli_read(cli1, fnum1, buf, 0, 4);
3159 #if 0
3160 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3161 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3162 correct = False;
3164 #endif
3166 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3167 printf("close1 failed (%s)\n", cli_errstr(cli1));
3168 correct = False;
3171 sleep(4);
3173 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3174 printf("unlink failed (%s)\n", cli_errstr(cli1));
3175 correct = False;
3178 if (!torture_close_connection(cli1)) {
3179 correct = False;
3182 if (!*shared_correct) {
3183 correct = False;
3186 printf("finished oplock test 2\n");
3188 return correct;
3191 /* handler for oplock 3 tests */
3192 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3194 printf("got oplock break fnum=%d level=%d\n",
3195 fnum, level);
3196 return cli_oplock_ack(cli, fnum, level);
3199 static bool run_oplock3(int dummy)
3201 struct cli_state *cli;
3202 const char *fname = "\\oplockt3.dat";
3203 uint16_t fnum;
3204 char buf[4] = "abcd";
3205 bool correct = True;
3206 volatile bool *shared_correct;
3208 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3209 *shared_correct = True;
3211 printf("starting oplock test 3\n");
3213 if (fork() == 0) {
3214 /* Child code */
3215 use_oplocks = True;
3216 use_level_II_oplocks = True;
3217 if (!torture_open_connection(&cli, 0)) {
3218 *shared_correct = False;
3219 exit(0);
3221 sleep(2);
3222 /* try to trigger a oplock break in parent */
3223 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3224 cli_write(cli, fnum, 0, buf, 0, 4);
3225 exit(0);
3228 /* parent code */
3229 use_oplocks = True;
3230 use_level_II_oplocks = True;
3231 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3232 return False;
3234 cli_oplock_handler(cli, oplock3_handler);
3235 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3236 cli_write(cli, fnum, 0, buf, 0, 4);
3237 cli_close(cli, fnum);
3238 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3239 cli->timeout = 20000;
3240 cli_receive_smb(cli);
3241 printf("finished oplock test 3\n");
3243 return (correct && *shared_correct);
3245 /* What are we looking for here? What's sucess and what's FAILURE? */
3251 Test delete on close semantics.
3253 static bool run_deletetest(int dummy)
3255 struct cli_state *cli1 = NULL;
3256 struct cli_state *cli2 = NULL;
3257 const char *fname = "\\delete.file";
3258 uint16_t fnum1 = (uint16_t)-1;
3259 uint16_t fnum2 = (uint16_t)-1;
3260 bool correct = True;
3262 printf("starting delete test\n");
3264 if (!torture_open_connection(&cli1, 0)) {
3265 return False;
3268 cli_sockopt(cli1, sockops);
3270 /* Test 1 - this should delete the file on close. */
3272 cli_setatr(cli1, fname, 0, 0);
3273 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3275 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3276 0, FILE_OVERWRITE_IF,
3277 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3278 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3279 correct = False;
3280 goto fail;
3283 #if 0 /* JRATEST */
3285 uint32 *accinfo = NULL;
3286 uint32 len;
3287 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3288 if (accinfo)
3289 printf("access mode = 0x%lx\n", *accinfo);
3290 SAFE_FREE(accinfo);
3292 #endif
3294 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3295 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3296 correct = False;
3297 goto fail;
3300 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3301 printf("[1] open of %s succeeded (should fail)\n", fname);
3302 correct = False;
3303 goto fail;
3306 printf("first delete on close test succeeded.\n");
3308 /* Test 2 - this should delete the file on close. */
3310 cli_setatr(cli1, fname, 0, 0);
3311 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3313 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3314 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3315 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3316 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3317 correct = False;
3318 goto fail;
3321 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3322 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3323 correct = False;
3324 goto fail;
3327 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3328 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3329 correct = False;
3330 goto fail;
3333 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3334 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3335 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3336 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3337 correct = False;
3338 goto fail;
3340 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3341 } else
3342 printf("second delete on close test succeeded.\n");
3344 /* Test 3 - ... */
3345 cli_setatr(cli1, fname, 0, 0);
3346 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3348 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3349 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3350 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3351 correct = False;
3352 goto fail;
3355 /* This should fail with a sharing violation - open for delete is only compatible
3356 with SHARE_DELETE. */
3358 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3359 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3360 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3361 correct = False;
3362 goto fail;
3365 /* This should succeed. */
3367 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3368 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3369 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3370 correct = False;
3371 goto fail;
3374 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3375 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3376 correct = False;
3377 goto fail;
3380 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3381 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3382 correct = False;
3383 goto fail;
3386 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3387 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3388 correct = False;
3389 goto fail;
3392 /* This should fail - file should no longer be there. */
3394 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3395 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3396 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3397 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3399 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3400 correct = False;
3401 goto fail;
3402 } else
3403 printf("third delete on close test succeeded.\n");
3405 /* Test 4 ... */
3406 cli_setatr(cli1, fname, 0, 0);
3407 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3409 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3410 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3411 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3412 correct = False;
3413 goto fail;
3416 /* This should succeed. */
3417 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3418 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3419 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3420 correct = False;
3421 goto fail;
3424 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3425 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3426 correct = False;
3427 goto fail;
3430 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3431 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3432 correct = False;
3433 goto fail;
3436 /* This should fail - no more opens once delete on close set. */
3437 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3438 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3439 FILE_OPEN, 0, 0, &fnum2))) {
3440 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3441 correct = False;
3442 goto fail;
3443 } else
3444 printf("fourth delete on close test succeeded.\n");
3446 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3447 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3448 correct = False;
3449 goto fail;
3452 /* Test 5 ... */
3453 cli_setatr(cli1, fname, 0, 0);
3454 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3456 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3457 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3458 correct = False;
3459 goto fail;
3462 /* This should fail - only allowed on NT opens with DELETE access. */
3464 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3465 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3466 correct = False;
3467 goto fail;
3470 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3471 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3472 correct = False;
3473 goto fail;
3476 printf("fifth delete on close test succeeded.\n");
3478 /* Test 6 ... */
3479 cli_setatr(cli1, fname, 0, 0);
3480 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3482 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3483 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3484 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3485 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3486 correct = False;
3487 goto fail;
3490 /* This should fail - only allowed on NT opens with DELETE access. */
3492 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3493 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3494 correct = False;
3495 goto fail;
3498 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3499 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3500 correct = False;
3501 goto fail;
3504 printf("sixth delete on close test succeeded.\n");
3506 /* Test 7 ... */
3507 cli_setatr(cli1, fname, 0, 0);
3508 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3510 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3511 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3512 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3513 correct = False;
3514 goto fail;
3517 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3518 printf("[7] setting delete_on_close on file failed !\n");
3519 correct = False;
3520 goto fail;
3523 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3524 printf("[7] unsetting delete_on_close on file failed !\n");
3525 correct = False;
3526 goto fail;
3529 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3530 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3531 correct = False;
3532 goto fail;
3535 /* This next open should succeed - we reset the flag. */
3537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3538 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3539 correct = False;
3540 goto fail;
3543 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3544 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3545 correct = False;
3546 goto fail;
3549 printf("seventh delete on close test succeeded.\n");
3551 /* Test 7 ... */
3552 cli_setatr(cli1, fname, 0, 0);
3553 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3555 if (!torture_open_connection(&cli2, 1)) {
3556 printf("[8] failed to open second connection.\n");
3557 correct = False;
3558 goto fail;
3561 cli_sockopt(cli1, sockops);
3563 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3564 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3565 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3566 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3567 correct = False;
3568 goto fail;
3571 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3572 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3573 FILE_OPEN, 0, 0, &fnum2))) {
3574 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3575 correct = False;
3576 goto fail;
3579 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3580 printf("[8] setting delete_on_close on file failed !\n");
3581 correct = False;
3582 goto fail;
3585 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3586 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3587 correct = False;
3588 goto fail;
3591 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3592 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3593 correct = False;
3594 goto fail;
3597 /* This should fail.. */
3598 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3599 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3600 goto fail;
3601 correct = False;
3602 } else
3603 printf("eighth delete on close test succeeded.\n");
3605 /* This should fail - we need to set DELETE_ACCESS. */
3606 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3607 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3608 printf("[9] open of %s succeeded should have failed!\n", fname);
3609 correct = False;
3610 goto fail;
3613 printf("ninth delete on close test succeeded.\n");
3615 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3616 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3617 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3618 correct = False;
3619 goto fail;
3622 /* This should delete the file. */
3623 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3624 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3625 correct = False;
3626 goto fail;
3629 /* This should fail.. */
3630 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3631 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3632 goto fail;
3633 correct = False;
3634 } else
3635 printf("tenth delete on close test succeeded.\n");
3637 cli_setatr(cli1, fname, 0, 0);
3638 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3640 /* What error do we get when attempting to open a read-only file with
3641 delete access ? */
3643 /* Create a readonly file. */
3644 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3645 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3646 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3647 correct = False;
3648 goto fail;
3651 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3652 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3653 correct = False;
3654 goto fail;
3657 /* Now try open for delete access. */
3658 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3659 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3660 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3661 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3662 cli_close(cli1, fnum1);
3663 goto fail;
3664 correct = False;
3665 } else {
3666 NTSTATUS nterr = cli_nt_error(cli1);
3667 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3668 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3669 goto fail;
3670 correct = False;
3671 } else {
3672 printf("eleventh delete on close test succeeded.\n");
3676 printf("finished delete test\n");
3678 fail:
3679 /* FIXME: This will crash if we aborted before cli2 got
3680 * intialized, because these functions don't handle
3681 * uninitialized connections. */
3683 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3684 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3685 cli_setatr(cli1, fname, 0, 0);
3686 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3688 if (cli1 && !torture_close_connection(cli1)) {
3689 correct = False;
3691 if (cli2 && !torture_close_connection(cli2)) {
3692 correct = False;
3694 return correct;
3699 print out server properties
3701 static bool run_properties(int dummy)
3703 struct cli_state *cli;
3704 bool correct = True;
3706 printf("starting properties test\n");
3708 ZERO_STRUCT(cli);
3710 if (!torture_open_connection(&cli, 0)) {
3711 return False;
3714 cli_sockopt(cli, sockops);
3716 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3718 if (!torture_close_connection(cli)) {
3719 correct = False;
3722 return correct;
3727 /* FIRST_DESIRED_ACCESS 0xf019f */
3728 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3729 FILE_READ_EA| /* 0xf */ \
3730 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3731 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3732 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3733 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3734 /* SECOND_DESIRED_ACCESS 0xe0080 */
3735 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3736 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3737 WRITE_OWNER_ACCESS /* 0xe0000 */
3739 #if 0
3740 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3741 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3742 FILE_READ_DATA|\
3743 WRITE_OWNER_ACCESS /* */
3744 #endif
3747 Test ntcreate calls made by xcopy
3749 static bool run_xcopy(int dummy)
3751 static struct cli_state *cli1;
3752 const char *fname = "\\test.txt";
3753 bool correct = True;
3754 uint16_t fnum1, fnum2;
3756 printf("starting xcopy test\n");
3758 if (!torture_open_connection(&cli1, 0)) {
3759 return False;
3762 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3763 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3764 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3765 0x4044, 0, &fnum1))) {
3766 printf("First open failed - %s\n", cli_errstr(cli1));
3767 return False;
3770 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3771 SECOND_DESIRED_ACCESS, 0,
3772 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3773 0x200000, 0, &fnum2))) {
3774 printf("second open failed - %s\n", cli_errstr(cli1));
3775 return False;
3778 if (!torture_close_connection(cli1)) {
3779 correct = False;
3782 return correct;
3786 Test rename on files open with share delete and no share delete.
3788 static bool run_rename(int dummy)
3790 static struct cli_state *cli1;
3791 const char *fname = "\\test.txt";
3792 const char *fname1 = "\\test1.txt";
3793 bool correct = True;
3794 uint16_t fnum1;
3795 uint16_t attr;
3796 NTSTATUS status;
3798 printf("starting rename test\n");
3800 if (!torture_open_connection(&cli1, 0)) {
3801 return False;
3804 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3805 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3806 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3807 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3808 printf("First open failed - %s\n", cli_errstr(cli1));
3809 return False;
3812 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3813 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3814 } else {
3815 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3816 correct = False;
3819 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3820 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3821 return False;
3824 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3825 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3826 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3827 #if 0
3828 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3829 #else
3830 FILE_SHARE_DELETE|FILE_SHARE_READ,
3831 #endif
3832 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("Second open failed - %s\n", cli_errstr(cli1));
3835 return False;
3838 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3839 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3840 correct = False;
3841 } else {
3842 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3845 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3846 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3847 return False;
3850 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3851 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3853 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3854 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3855 printf("Third open failed - %s\n", cli_errstr(cli1));
3856 return False;
3860 #if 0
3862 uint16_t fnum2;
3864 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3865 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3866 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3867 return False;
3869 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3870 printf("[8] setting delete_on_close on file failed !\n");
3871 return False;
3874 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3875 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3876 return False;
3879 #endif
3881 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3882 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3883 correct = False;
3884 } else {
3885 printf("Third rename succeeded (SHARE_NONE)\n");
3888 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3889 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3890 return False;
3893 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3894 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3896 /*----*/
3898 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3899 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3900 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3901 return False;
3904 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3905 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3906 } else {
3907 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3908 correct = False;
3911 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3912 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3913 return False;
3916 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3917 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3919 /*--*/
3921 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3922 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3923 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3924 return False;
3927 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3928 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3929 cli_errstr(cli1));
3930 correct = False;
3931 } else {
3932 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3936 * Now check if the first name still exists ...
3939 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3940 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3941 printf("Opening original file after rename of open file fails: %s\n",
3942 cli_errstr(cli1));
3944 else {
3945 printf("Opening original file after rename of open file works ...\n");
3946 (void)cli_close(cli1, fnum2);
3947 } */
3949 /*--*/
3950 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3951 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3952 return False;
3955 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3956 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
3957 printf("getatr on file %s failed - %s ! \n",
3958 fname1,
3959 cli_errstr(cli1));
3960 correct = False;
3961 } else {
3962 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
3963 printf("Renamed file %s has wrong attr 0x%x "
3964 "(should be 0x%x)\n",
3965 fname1,
3966 attr,
3967 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
3968 correct = False;
3969 } else {
3970 printf("Renamed file %s has archive bit set\n", fname1);
3974 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3975 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3977 if (!torture_close_connection(cli1)) {
3978 correct = False;
3981 return correct;
3984 static bool run_pipe_number(int dummy)
3986 struct cli_state *cli1;
3987 const char *pipe_name = "\\SPOOLSS";
3988 uint16_t fnum;
3989 int num_pipes = 0;
3991 printf("starting pipenumber test\n");
3992 if (!torture_open_connection(&cli1, 0)) {
3993 return False;
3996 cli_sockopt(cli1, sockops);
3997 while(1) {
3998 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3999 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4000 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4001 break;
4003 num_pipes++;
4004 printf("\r%6d", num_pipes);
4007 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4008 torture_close_connection(cli1);
4009 return True;
4013 Test open mode returns on read-only files.
4015 static bool run_opentest(int dummy)
4017 static struct cli_state *cli1;
4018 static struct cli_state *cli2;
4019 const char *fname = "\\readonly.file";
4020 uint16_t fnum1, fnum2;
4021 char buf[20];
4022 SMB_OFF_T fsize;
4023 bool correct = True;
4024 char *tmp_path;
4026 printf("starting open test\n");
4028 if (!torture_open_connection(&cli1, 0)) {
4029 return False;
4032 cli_setatr(cli1, fname, 0, 0);
4033 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4035 cli_sockopt(cli1, sockops);
4037 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4038 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4039 return False;
4042 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4043 printf("close2 failed (%s)\n", cli_errstr(cli1));
4044 return False;
4047 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4048 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4049 return False;
4052 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4053 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4054 return False;
4057 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4058 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4060 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4061 NT_STATUS_ACCESS_DENIED)) {
4062 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4065 printf("finished open test 1\n");
4067 cli_close(cli1, fnum1);
4069 /* Now try not readonly and ensure ERRbadshare is returned. */
4071 cli_setatr(cli1, fname, 0, 0);
4073 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4074 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4075 return False;
4078 /* This will fail - but the error should be ERRshare. */
4079 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4081 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4082 NT_STATUS_SHARING_VIOLATION)) {
4083 printf("correct error code ERRDOS/ERRbadshare returned\n");
4086 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4087 printf("close2 failed (%s)\n", cli_errstr(cli1));
4088 return False;
4091 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4093 printf("finished open test 2\n");
4095 /* Test truncate open disposition on file opened for read. */
4097 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4098 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4099 return False;
4102 /* write 20 bytes. */
4104 memset(buf, '\0', 20);
4106 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4107 printf("write failed (%s)\n", cli_errstr(cli1));
4108 correct = False;
4111 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4112 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4113 return False;
4116 /* Ensure size == 20. */
4117 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4118 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4119 return False;
4122 if (fsize != 20) {
4123 printf("(3) file size != 20\n");
4124 return False;
4127 /* Now test if we can truncate a file opened for readonly. */
4129 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4130 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4131 return False;
4134 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4135 printf("close2 failed (%s)\n", cli_errstr(cli1));
4136 return False;
4139 /* Ensure size == 0. */
4140 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4141 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4142 return False;
4145 if (fsize != 0) {
4146 printf("(3) file size != 0\n");
4147 return False;
4149 printf("finished open test 3\n");
4151 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4154 printf("testing ctemp\n");
4155 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4156 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4157 return False;
4159 printf("ctemp gave path %s\n", tmp_path);
4160 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4161 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4163 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4164 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4167 /* Test the non-io opens... */
4169 if (!torture_open_connection(&cli2, 1)) {
4170 return False;
4173 cli_setatr(cli2, fname, 0, 0);
4174 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4176 cli_sockopt(cli2, sockops);
4178 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4180 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4181 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4182 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4183 return False;
4186 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4187 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4188 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4189 return False;
4192 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4193 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4194 return False;
4196 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4197 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4198 return False;
4201 printf("non-io open test #1 passed.\n");
4203 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4205 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4207 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4208 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4209 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4210 return False;
4213 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4214 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4215 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4216 return False;
4219 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4220 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4221 return False;
4223 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4224 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4225 return False;
4228 printf("non-io open test #2 passed.\n");
4230 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4232 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4234 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4235 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4236 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4237 return False;
4240 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4241 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4242 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4243 return False;
4246 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4247 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4248 return False;
4250 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4251 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4252 return False;
4255 printf("non-io open test #3 passed.\n");
4257 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4259 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4261 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4262 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4263 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4264 return False;
4267 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4268 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4269 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4270 return False;
4273 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4275 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4276 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4277 return False;
4280 printf("non-io open test #4 passed.\n");
4282 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4284 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4286 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4287 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4288 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4289 return False;
4292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4293 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4294 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4295 return False;
4298 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4299 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4300 return False;
4303 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4304 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4305 return False;
4308 printf("non-io open test #5 passed.\n");
4310 printf("TEST #6 testing 1 non-io open, one io open\n");
4312 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4314 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4315 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4316 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4317 return False;
4320 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4321 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4322 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4323 return False;
4326 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4327 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4328 return False;
4331 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4332 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4333 return False;
4336 printf("non-io open test #6 passed.\n");
4338 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4340 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4342 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4343 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4344 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4345 return False;
4348 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4349 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4350 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4351 return False;
4354 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4356 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4357 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4358 return False;
4361 printf("non-io open test #7 passed.\n");
4363 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4365 if (!torture_close_connection(cli1)) {
4366 correct = False;
4368 if (!torture_close_connection(cli2)) {
4369 correct = False;
4372 return correct;
4375 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4377 uint16 major, minor;
4378 uint32 caplow, caphigh;
4379 NTSTATUS status;
4381 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4382 printf("Server doesn't support UNIX CIFS extensions.\n");
4383 return NT_STATUS_NOT_SUPPORTED;
4386 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4387 &caphigh);
4388 if (!NT_STATUS_IS_OK(status)) {
4389 printf("Server didn't return UNIX CIFS extensions: %s\n",
4390 nt_errstr(status));
4391 return status;
4394 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4395 caplow, caphigh);
4396 if (!NT_STATUS_IS_OK(status)) {
4397 printf("Server doesn't support setting UNIX CIFS extensions: "
4398 "%s.\n", nt_errstr(status));
4399 return status;
4402 return NT_STATUS_OK;
4406 Test POSIX open /mkdir calls.
4408 static bool run_simple_posix_open_test(int dummy)
4410 static struct cli_state *cli1;
4411 const char *fname = "posix:file";
4412 const char *hname = "posix:hlink";
4413 const char *sname = "posix:symlink";
4414 const char *dname = "posix:dir";
4415 char buf[10];
4416 char namebuf[11];
4417 uint16_t fnum1 = (uint16_t)-1;
4418 SMB_STRUCT_STAT sbuf;
4419 bool correct = false;
4420 NTSTATUS status;
4422 printf("Starting simple POSIX open test\n");
4424 if (!torture_open_connection(&cli1, 0)) {
4425 return false;
4428 cli_sockopt(cli1, sockops);
4430 status = torture_setup_unix_extensions(cli1);
4431 if (!NT_STATUS_IS_OK(status)) {
4432 return false;
4435 cli_setatr(cli1, fname, 0, 0);
4436 cli_posix_unlink(cli1, fname);
4437 cli_setatr(cli1, dname, 0, 0);
4438 cli_posix_rmdir(cli1, dname);
4439 cli_setatr(cli1, hname, 0, 0);
4440 cli_posix_unlink(cli1, hname);
4441 cli_setatr(cli1, sname, 0, 0);
4442 cli_posix_unlink(cli1, sname);
4444 /* Create a directory. */
4445 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4446 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4447 goto out;
4450 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4451 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4452 goto out;
4455 /* Test ftruncate - set file size. */
4456 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4457 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4458 goto out;
4461 /* Ensure st_size == 1000 */
4462 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4463 printf("stat failed (%s)\n", cli_errstr(cli1));
4464 goto out;
4467 if (sbuf.st_ex_size != 1000) {
4468 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4469 goto out;
4472 /* Test ftruncate - set file size back to zero. */
4473 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4474 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4475 goto out;
4478 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4479 printf("close failed (%s)\n", cli_errstr(cli1));
4480 goto out;
4483 /* Now open the file again for read only. */
4484 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4485 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4486 goto out;
4489 /* Now unlink while open. */
4490 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4491 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4492 goto out;
4495 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4496 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4497 goto out;
4500 /* Ensure the file has gone. */
4501 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4502 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4503 goto out;
4506 /* What happens when we try and POSIX open a directory ? */
4507 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4508 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4509 goto out;
4510 } else {
4511 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4512 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4513 goto out;
4517 /* Create the file. */
4518 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4519 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4520 goto out;
4523 /* Write some data into it. */
4524 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4525 printf("cli_write failed: %s\n", cli_errstr(cli1));
4526 goto out;
4529 cli_close(cli1, fnum1);
4531 /* Now create a hardlink. */
4532 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4533 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4534 goto out;
4537 /* Now create a symlink. */
4538 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4539 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4540 goto out;
4543 /* Open the hardlink for read. */
4544 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4545 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4546 goto out;
4549 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4550 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4551 goto out;
4554 if (memcmp(buf, "TEST DATA\n", 10)) {
4555 printf("invalid data read from hardlink\n");
4556 goto out;
4559 /* Do a POSIX lock/unlock. */
4560 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4561 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4562 goto out;
4565 /* Punch a hole in the locked area. */
4566 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4567 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4568 goto out;
4571 cli_close(cli1, fnum1);
4573 /* Open the symlink for read - this should fail. A POSIX
4574 client should not be doing opens on a symlink. */
4575 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4576 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4577 goto out;
4578 } else {
4579 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4580 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4581 printf("POSIX open of %s should have failed "
4582 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4583 "failed with %s instead.\n",
4584 sname, cli_errstr(cli1));
4585 goto out;
4589 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4590 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4591 goto out;
4594 if (strcmp(namebuf, fname) != 0) {
4595 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4596 sname, fname, namebuf);
4597 goto out;
4600 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4601 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4602 goto out;
4605 printf("Simple POSIX open test passed\n");
4606 correct = true;
4608 out:
4610 if (fnum1 != (uint16_t)-1) {
4611 cli_close(cli1, fnum1);
4612 fnum1 = (uint16_t)-1;
4615 cli_setatr(cli1, sname, 0, 0);
4616 cli_posix_unlink(cli1, sname);
4617 cli_setatr(cli1, hname, 0, 0);
4618 cli_posix_unlink(cli1, hname);
4619 cli_setatr(cli1, fname, 0, 0);
4620 cli_posix_unlink(cli1, fname);
4621 cli_setatr(cli1, dname, 0, 0);
4622 cli_posix_rmdir(cli1, dname);
4624 if (!torture_close_connection(cli1)) {
4625 correct = false;
4628 return correct;
4632 static uint32 open_attrs_table[] = {
4633 FILE_ATTRIBUTE_NORMAL,
4634 FILE_ATTRIBUTE_ARCHIVE,
4635 FILE_ATTRIBUTE_READONLY,
4636 FILE_ATTRIBUTE_HIDDEN,
4637 FILE_ATTRIBUTE_SYSTEM,
4639 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4640 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4641 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4642 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4643 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4644 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4646 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4647 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4648 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4649 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4652 struct trunc_open_results {
4653 unsigned int num;
4654 uint32 init_attr;
4655 uint32 trunc_attr;
4656 uint32 result_attr;
4659 static struct trunc_open_results attr_results[] = {
4660 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4661 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4662 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4663 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4664 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4665 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4666 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4667 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4668 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4669 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4670 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4671 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4672 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4673 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4674 { 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 },
4675 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4676 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4677 { 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 },
4678 { 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 },
4679 { 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 },
4680 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4681 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4682 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4683 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4684 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4685 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4688 static bool run_openattrtest(int dummy)
4690 static struct cli_state *cli1;
4691 const char *fname = "\\openattr.file";
4692 uint16_t fnum1;
4693 bool correct = True;
4694 uint16 attr;
4695 unsigned int i, j, k, l;
4697 printf("starting open attr test\n");
4699 if (!torture_open_connection(&cli1, 0)) {
4700 return False;
4703 cli_sockopt(cli1, sockops);
4705 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4706 cli_setatr(cli1, fname, 0, 0);
4707 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4708 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4709 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4710 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4711 return False;
4714 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4715 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4716 return False;
4719 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4720 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4721 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4722 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4723 if (attr_results[l].num == k) {
4724 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4725 k, open_attrs_table[i],
4726 open_attrs_table[j],
4727 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4728 correct = False;
4731 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4732 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4733 k, open_attrs_table[i], open_attrs_table[j],
4734 cli_errstr(cli1));
4735 correct = False;
4737 #if 0
4738 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4739 #endif
4740 k++;
4741 continue;
4744 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4745 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4746 return False;
4749 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4750 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4751 return False;
4754 #if 0
4755 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4756 k, open_attrs_table[i], open_attrs_table[j], attr );
4757 #endif
4759 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4760 if (attr_results[l].num == k) {
4761 if (attr != attr_results[l].result_attr ||
4762 open_attrs_table[i] != attr_results[l].init_attr ||
4763 open_attrs_table[j] != attr_results[l].trunc_attr) {
4764 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4765 open_attrs_table[i],
4766 open_attrs_table[j],
4767 (unsigned int)attr,
4768 attr_results[l].result_attr);
4769 correct = False;
4771 break;
4774 k++;
4778 cli_setatr(cli1, fname, 0, 0);
4779 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4781 printf("open attr test %s.\n", correct ? "passed" : "failed");
4783 if (!torture_close_connection(cli1)) {
4784 correct = False;
4786 return correct;
4789 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4795 test directory listing speed
4797 static bool run_dirtest(int dummy)
4799 int i;
4800 static struct cli_state *cli;
4801 uint16_t fnum;
4802 struct timeval core_start;
4803 bool correct = True;
4805 printf("starting directory test\n");
4807 if (!torture_open_connection(&cli, 0)) {
4808 return False;
4811 cli_sockopt(cli, sockops);
4813 srandom(0);
4814 for (i=0;i<torture_numops;i++) {
4815 fstring fname;
4816 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4817 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4818 fprintf(stderr,"Failed to open %s\n", fname);
4819 return False;
4821 cli_close(cli, fnum);
4824 core_start = timeval_current();
4826 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4827 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4828 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4830 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4832 srandom(0);
4833 for (i=0;i<torture_numops;i++) {
4834 fstring fname;
4835 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4836 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4839 if (!torture_close_connection(cli)) {
4840 correct = False;
4843 printf("finished dirtest\n");
4845 return correct;
4848 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4850 struct cli_state *pcli = (struct cli_state *)state;
4851 fstring fname;
4852 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4854 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4855 return;
4857 if (finfo->mode & aDIR) {
4858 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4859 printf("del_fn: failed to rmdir %s\n,", fname );
4860 } else {
4861 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4862 printf("del_fn: failed to unlink %s\n,", fname );
4868 sees what IOCTLs are supported
4870 bool torture_ioctl_test(int dummy)
4872 static struct cli_state *cli;
4873 uint16_t device, function;
4874 uint16_t fnum;
4875 const char *fname = "\\ioctl.dat";
4876 DATA_BLOB blob;
4877 NTSTATUS status;
4879 if (!torture_open_connection(&cli, 0)) {
4880 return False;
4883 printf("starting ioctl test\n");
4885 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4887 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4888 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4889 return False;
4892 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4893 printf("ioctl device info: %s\n", nt_errstr(status));
4895 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4896 printf("ioctl job info: %s\n", nt_errstr(status));
4898 for (device=0;device<0x100;device++) {
4899 printf("testing device=0x%x\n", device);
4900 for (function=0;function<0x100;function++) {
4901 uint32 code = (device<<16) | function;
4903 status = cli_raw_ioctl(cli, fnum, code, &blob);
4905 if (NT_STATUS_IS_OK(status)) {
4906 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4907 (int)blob.length);
4908 data_blob_free(&blob);
4913 if (!torture_close_connection(cli)) {
4914 return False;
4917 return True;
4922 tries varients of chkpath
4924 bool torture_chkpath_test(int dummy)
4926 static struct cli_state *cli;
4927 uint16_t fnum;
4928 bool ret;
4930 if (!torture_open_connection(&cli, 0)) {
4931 return False;
4934 printf("starting chkpath test\n");
4936 /* cleanup from an old run */
4937 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4938 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4939 cli_rmdir(cli, "\\chkpath.dir");
4941 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4942 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4943 return False;
4946 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4947 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4948 return False;
4951 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4952 printf("open1 failed (%s)\n", cli_errstr(cli));
4953 return False;
4955 cli_close(cli, fnum);
4957 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4958 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4959 ret = False;
4962 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4963 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4964 ret = False;
4967 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4968 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4969 NT_STATUS_NOT_A_DIRECTORY);
4970 } else {
4971 printf("* chkpath on a file should fail\n");
4972 ret = False;
4975 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4976 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4977 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4978 } else {
4979 printf("* chkpath on a non existant file should fail\n");
4980 ret = False;
4983 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4984 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4985 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4986 } else {
4987 printf("* chkpath on a non existent component should fail\n");
4988 ret = False;
4991 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4992 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4993 cli_rmdir(cli, "\\chkpath.dir");
4995 if (!torture_close_connection(cli)) {
4996 return False;
4999 return ret;
5002 static bool run_eatest(int dummy)
5004 static struct cli_state *cli;
5005 const char *fname = "\\eatest.txt";
5006 bool correct = True;
5007 uint16_t fnum;
5008 int i;
5009 size_t num_eas;
5010 struct ea_struct *ea_list = NULL;
5011 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5013 printf("starting eatest\n");
5015 if (!torture_open_connection(&cli, 0)) {
5016 talloc_destroy(mem_ctx);
5017 return False;
5020 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5021 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5022 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5023 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5024 0x4044, 0, &fnum))) {
5025 printf("open failed - %s\n", cli_errstr(cli));
5026 talloc_destroy(mem_ctx);
5027 return False;
5030 for (i = 0; i < 10; i++) {
5031 fstring ea_name, ea_val;
5033 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5034 memset(ea_val, (char)i+1, i+1);
5035 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5036 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5037 talloc_destroy(mem_ctx);
5038 return False;
5042 cli_close(cli, fnum);
5043 for (i = 0; i < 10; i++) {
5044 fstring ea_name, ea_val;
5046 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5047 memset(ea_val, (char)i+1, i+1);
5048 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5049 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5050 talloc_destroy(mem_ctx);
5051 return False;
5055 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5056 printf("ea_get list failed - %s\n", cli_errstr(cli));
5057 correct = False;
5060 printf("num_eas = %d\n", (int)num_eas);
5062 if (num_eas != 20) {
5063 printf("Should be 20 EA's stored... failing.\n");
5064 correct = False;
5067 for (i = 0; i < num_eas; i++) {
5068 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5069 dump_data(0, ea_list[i].value.data,
5070 ea_list[i].value.length);
5073 /* Setting EA's to zero length deletes them. Test this */
5074 printf("Now deleting all EA's - case indepenent....\n");
5076 #if 1
5077 cli_set_ea_path(cli, fname, "", "", 0);
5078 #else
5079 for (i = 0; i < 20; i++) {
5080 fstring ea_name;
5081 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5082 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5083 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5084 talloc_destroy(mem_ctx);
5085 return False;
5088 #endif
5090 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5091 printf("ea_get list failed - %s\n", cli_errstr(cli));
5092 correct = False;
5095 printf("num_eas = %d\n", (int)num_eas);
5096 for (i = 0; i < num_eas; i++) {
5097 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5098 dump_data(0, ea_list[i].value.data,
5099 ea_list[i].value.length);
5102 if (num_eas != 0) {
5103 printf("deleting EA's failed.\n");
5104 correct = False;
5107 /* Try and delete a non existant EA. */
5108 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5109 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5110 correct = False;
5113 talloc_destroy(mem_ctx);
5114 if (!torture_close_connection(cli)) {
5115 correct = False;
5118 return correct;
5121 static bool run_dirtest1(int dummy)
5123 int i;
5124 static struct cli_state *cli;
5125 uint16_t fnum;
5126 int num_seen;
5127 bool correct = True;
5129 printf("starting directory test\n");
5131 if (!torture_open_connection(&cli, 0)) {
5132 return False;
5135 cli_sockopt(cli, sockops);
5137 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5138 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5139 cli_rmdir(cli, "\\LISTDIR");
5140 cli_mkdir(cli, "\\LISTDIR");
5142 /* Create 1000 files and 1000 directories. */
5143 for (i=0;i<1000;i++) {
5144 fstring fname;
5145 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5146 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5147 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5148 fprintf(stderr,"Failed to open %s\n", fname);
5149 return False;
5151 cli_close(cli, fnum);
5153 for (i=0;i<1000;i++) {
5154 fstring fname;
5155 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5156 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5157 fprintf(stderr,"Failed to open %s\n", fname);
5158 return False;
5162 /* Now ensure that doing an old list sees both files and directories. */
5163 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5164 printf("num_seen = %d\n", num_seen );
5165 /* We should see 100 files + 1000 directories + . and .. */
5166 if (num_seen != 2002)
5167 correct = False;
5169 /* Ensure if we have the "must have" bits we only see the
5170 * relevent entries.
5172 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5173 printf("num_seen = %d\n", num_seen );
5174 if (num_seen != 1002)
5175 correct = False;
5177 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5178 printf("num_seen = %d\n", num_seen );
5179 if (num_seen != 1000)
5180 correct = False;
5182 /* Delete everything. */
5183 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5184 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5185 cli_rmdir(cli, "\\LISTDIR");
5187 #if 0
5188 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5189 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5190 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5191 #endif
5193 if (!torture_close_connection(cli)) {
5194 correct = False;
5197 printf("finished dirtest1\n");
5199 return correct;
5202 static bool run_error_map_extract(int dummy) {
5204 static struct cli_state *c_dos;
5205 static struct cli_state *c_nt;
5206 NTSTATUS status;
5208 uint32 error;
5210 uint32 flgs2, errnum;
5211 uint8 errclass;
5213 NTSTATUS nt_status;
5215 fstring user;
5217 /* NT-Error connection */
5219 if (!(c_nt = open_nbt_connection())) {
5220 return False;
5223 c_nt->use_spnego = False;
5225 status = cli_negprot(c_nt);
5227 if (!NT_STATUS_IS_OK(status)) {
5228 printf("%s rejected the NT-error negprot (%s)\n", host,
5229 nt_errstr(status));
5230 cli_shutdown(c_nt);
5231 return False;
5234 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5235 workgroup))) {
5236 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5237 return False;
5240 /* DOS-Error connection */
5242 if (!(c_dos = open_nbt_connection())) {
5243 return False;
5246 c_dos->use_spnego = False;
5247 c_dos->force_dos_errors = True;
5249 status = cli_negprot(c_dos);
5250 if (!NT_STATUS_IS_OK(status)) {
5251 printf("%s rejected the DOS-error negprot (%s)\n", host,
5252 nt_errstr(status));
5253 cli_shutdown(c_dos);
5254 return False;
5257 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5258 workgroup))) {
5259 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5260 return False;
5263 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5264 fstr_sprintf(user, "%X", error);
5266 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5267 password, strlen(password),
5268 password, strlen(password),
5269 workgroup))) {
5270 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5273 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5275 /* Case #1: 32-bit NT errors */
5276 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5277 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5278 } else {
5279 printf("/** Dos error on NT connection! (%s) */\n",
5280 cli_errstr(c_nt));
5281 nt_status = NT_STATUS(0xc0000000);
5284 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5285 password, strlen(password),
5286 password, strlen(password),
5287 workgroup))) {
5288 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5290 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5292 /* Case #1: 32-bit NT errors */
5293 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5294 printf("/** NT error on DOS connection! (%s) */\n",
5295 cli_errstr(c_nt));
5296 errnum = errclass = 0;
5297 } else {
5298 cli_dos_error(c_dos, &errclass, &errnum);
5301 if (NT_STATUS_V(nt_status) != error) {
5302 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5303 get_nt_error_c_code(NT_STATUS(error)),
5304 get_nt_error_c_code(nt_status));
5307 printf("\t{%s,\t%s,\t%s},\n",
5308 smb_dos_err_class(errclass),
5309 smb_dos_err_name(errclass, errnum),
5310 get_nt_error_c_code(NT_STATUS(error)));
5312 return True;
5315 static bool run_sesssetup_bench(int dummy)
5317 static struct cli_state *c;
5318 const char *fname = "\\file.dat";
5319 uint16_t fnum;
5320 NTSTATUS status;
5321 int i;
5323 if (!torture_open_connection(&c, 0)) {
5324 return false;
5327 if (!NT_STATUS_IS_OK(cli_ntcreate(
5328 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5329 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5330 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5331 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5332 return false;
5335 for (i=0; i<torture_numops; i++) {
5336 status = cli_session_setup(
5337 c, username,
5338 password, strlen(password),
5339 password, strlen(password),
5340 workgroup);
5341 if (!NT_STATUS_IS_OK(status)) {
5342 d_printf("(%s) cli_session_setup failed: %s\n",
5343 __location__, nt_errstr(status));
5344 return false;
5347 d_printf("\r%d ", (int)c->vuid);
5349 status = cli_ulogoff(c);
5350 if (!NT_STATUS_IS_OK(status)) {
5351 d_printf("(%s) cli_ulogoff failed: %s\n",
5352 __location__, nt_errstr(status));
5353 return false;
5355 c->vuid = 0;
5358 return true;
5361 static bool subst_test(const char *str, const char *user, const char *domain,
5362 uid_t uid, gid_t gid, const char *expected)
5364 char *subst;
5365 bool result = true;
5367 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5369 if (strcmp(subst, expected) != 0) {
5370 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5371 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5372 expected);
5373 result = false;
5376 TALLOC_FREE(subst);
5377 return result;
5380 static void chain1_open_completion(struct tevent_req *req)
5382 uint16_t fnum;
5383 NTSTATUS status;
5384 status = cli_open_recv(req, &fnum);
5385 TALLOC_FREE(req);
5387 d_printf("cli_open_recv returned %s: %d\n",
5388 nt_errstr(status),
5389 NT_STATUS_IS_OK(status) ? fnum : -1);
5392 static void chain1_write_completion(struct tevent_req *req)
5394 size_t written;
5395 NTSTATUS status;
5396 status = cli_write_andx_recv(req, &written);
5397 TALLOC_FREE(req);
5399 d_printf("cli_write_andx_recv returned %s: %d\n",
5400 nt_errstr(status),
5401 NT_STATUS_IS_OK(status) ? (int)written : -1);
5404 static void chain1_close_completion(struct tevent_req *req)
5406 NTSTATUS status;
5407 bool *done = (bool *)tevent_req_callback_data_void(req);
5409 status = cli_close_recv(req);
5410 *done = true;
5412 TALLOC_FREE(req);
5414 d_printf("cli_close returned %s\n", nt_errstr(status));
5417 static bool run_chain1(int dummy)
5419 struct cli_state *cli1;
5420 struct event_context *evt = event_context_init(NULL);
5421 struct tevent_req *reqs[3], *smbreqs[3];
5422 bool done = false;
5423 const char *str = "foobar";
5424 NTSTATUS status;
5426 printf("starting chain1 test\n");
5427 if (!torture_open_connection(&cli1, 0)) {
5428 return False;
5431 cli_sockopt(cli1, sockops);
5433 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5434 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5435 if (reqs[0] == NULL) return false;
5436 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5439 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5440 (uint8_t *)str, 0, strlen(str)+1,
5441 smbreqs, 1, &smbreqs[1]);
5442 if (reqs[1] == NULL) return false;
5443 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5445 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5446 if (reqs[2] == NULL) return false;
5447 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5449 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5450 if (!NT_STATUS_IS_OK(status)) {
5451 return false;
5454 while (!done) {
5455 event_loop_once(evt);
5458 torture_close_connection(cli1);
5459 return True;
5462 static void chain2_sesssetup_completion(struct tevent_req *req)
5464 NTSTATUS status;
5465 status = cli_session_setup_guest_recv(req);
5466 d_printf("sesssetup returned %s\n", nt_errstr(status));
5469 static void chain2_tcon_completion(struct tevent_req *req)
5471 bool *done = (bool *)tevent_req_callback_data_void(req);
5472 NTSTATUS status;
5473 status = cli_tcon_andx_recv(req);
5474 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5475 *done = true;
5478 static bool run_chain2(int dummy)
5480 struct cli_state *cli1;
5481 struct event_context *evt = event_context_init(NULL);
5482 struct tevent_req *reqs[2], *smbreqs[2];
5483 bool done = false;
5484 NTSTATUS status;
5486 printf("starting chain2 test\n");
5487 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5488 port_to_use, Undefined, 0, NULL);
5489 if (!NT_STATUS_IS_OK(status)) {
5490 return False;
5493 cli_sockopt(cli1, sockops);
5495 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5496 &smbreqs[0]);
5497 if (reqs[0] == NULL) return false;
5498 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5500 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5501 "?????", NULL, 0, &smbreqs[1]);
5502 if (reqs[1] == NULL) return false;
5503 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5505 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5506 if (!NT_STATUS_IS_OK(status)) {
5507 return false;
5510 while (!done) {
5511 event_loop_once(evt);
5514 torture_close_connection(cli1);
5515 return True;
5519 struct torture_createdel_state {
5520 struct tevent_context *ev;
5521 struct cli_state *cli;
5524 static void torture_createdel_created(struct tevent_req *subreq);
5525 static void torture_createdel_closed(struct tevent_req *subreq);
5527 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5528 struct tevent_context *ev,
5529 struct cli_state *cli,
5530 const char *name)
5532 struct tevent_req *req, *subreq;
5533 struct torture_createdel_state *state;
5535 req = tevent_req_create(mem_ctx, &state,
5536 struct torture_createdel_state);
5537 if (req == NULL) {
5538 return NULL;
5540 state->ev = ev;
5541 state->cli = cli;
5543 subreq = cli_ntcreate_send(
5544 state, ev, cli, name, 0,
5545 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5546 FILE_ATTRIBUTE_NORMAL,
5547 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5548 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5550 if (tevent_req_nomem(subreq, req)) {
5551 return tevent_req_post(req, ev);
5553 tevent_req_set_callback(subreq, torture_createdel_created, req);
5554 return req;
5557 static void torture_createdel_created(struct tevent_req *subreq)
5559 struct tevent_req *req = tevent_req_callback_data(
5560 subreq, struct tevent_req);
5561 struct torture_createdel_state *state = tevent_req_data(
5562 req, struct torture_createdel_state);
5563 NTSTATUS status;
5564 uint16_t fnum;
5566 status = cli_ntcreate_recv(subreq, &fnum);
5567 TALLOC_FREE(subreq);
5568 if (!NT_STATUS_IS_OK(status)) {
5569 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5570 nt_errstr(status)));
5571 tevent_req_nterror(req, status);
5572 return;
5575 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5576 if (tevent_req_nomem(subreq, req)) {
5577 return;
5579 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5582 static void torture_createdel_closed(struct tevent_req *subreq)
5584 struct tevent_req *req = tevent_req_callback_data(
5585 subreq, struct tevent_req);
5586 NTSTATUS status;
5588 status = cli_close_recv(subreq);
5589 if (!NT_STATUS_IS_OK(status)) {
5590 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5591 tevent_req_nterror(req, status);
5592 return;
5594 tevent_req_done(req);
5597 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5599 return tevent_req_simple_recv_ntstatus(req);
5602 struct torture_createdels_state {
5603 struct tevent_context *ev;
5604 struct cli_state *cli;
5605 const char *base_name;
5606 int sent;
5607 int received;
5608 int num_files;
5609 struct tevent_req **reqs;
5612 static void torture_createdels_done(struct tevent_req *subreq);
5614 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5615 struct tevent_context *ev,
5616 struct cli_state *cli,
5617 const char *base_name,
5618 int num_parallel,
5619 int num_files)
5621 struct tevent_req *req;
5622 struct torture_createdels_state *state;
5623 int i;
5625 req = tevent_req_create(mem_ctx, &state,
5626 struct torture_createdels_state);
5627 if (req == NULL) {
5628 return NULL;
5630 state->ev = ev;
5631 state->cli = cli;
5632 state->base_name = talloc_strdup(state, base_name);
5633 if (tevent_req_nomem(state->base_name, req)) {
5634 return tevent_req_post(req, ev);
5636 state->num_files = MAX(num_parallel, num_files);
5637 state->sent = 0;
5638 state->received = 0;
5640 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5641 if (tevent_req_nomem(state->reqs, req)) {
5642 return tevent_req_post(req, ev);
5645 for (i=0; i<num_parallel; i++) {
5646 char *name;
5648 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5649 state->sent);
5650 if (tevent_req_nomem(name, req)) {
5651 return tevent_req_post(req, ev);
5653 state->reqs[i] = torture_createdel_send(
5654 state->reqs, state->ev, state->cli, name);
5655 if (tevent_req_nomem(state->reqs[i], req)) {
5656 return tevent_req_post(req, ev);
5658 name = talloc_move(state->reqs[i], &name);
5659 tevent_req_set_callback(state->reqs[i],
5660 torture_createdels_done, req);
5661 state->sent += 1;
5663 return req;
5666 static void torture_createdels_done(struct tevent_req *subreq)
5668 struct tevent_req *req = tevent_req_callback_data(
5669 subreq, struct tevent_req);
5670 struct torture_createdels_state *state = tevent_req_data(
5671 req, struct torture_createdels_state);
5672 size_t num_parallel = talloc_array_length(state->reqs);
5673 NTSTATUS status;
5674 char *name;
5675 int i;
5677 status = torture_createdel_recv(subreq);
5678 if (!NT_STATUS_IS_OK(status)){
5679 DEBUG(10, ("torture_createdel_recv returned %s\n",
5680 nt_errstr(status)));
5681 TALLOC_FREE(subreq);
5682 tevent_req_nterror(req, status);
5683 return;
5686 for (i=0; i<num_parallel; i++) {
5687 if (subreq == state->reqs[i]) {
5688 break;
5691 if (i == num_parallel) {
5692 DEBUG(10, ("received something we did not send\n"));
5693 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5694 return;
5696 TALLOC_FREE(state->reqs[i]);
5698 if (state->sent >= state->num_files) {
5699 tevent_req_done(req);
5700 return;
5703 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5704 state->sent);
5705 if (tevent_req_nomem(name, req)) {
5706 return;
5708 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5709 state->cli, name);
5710 if (tevent_req_nomem(state->reqs[i], req)) {
5711 return;
5713 name = talloc_move(state->reqs[i], &name);
5714 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5715 state->sent += 1;
5718 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5720 return tevent_req_simple_recv_ntstatus(req);
5723 struct swallow_notify_state {
5724 struct tevent_context *ev;
5725 struct cli_state *cli;
5726 uint16_t fnum;
5727 uint32_t completion_filter;
5728 bool recursive;
5729 bool (*fn)(uint32_t action, const char *name, void *priv);
5730 void *priv;
5733 static void swallow_notify_done(struct tevent_req *subreq);
5735 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5736 struct tevent_context *ev,
5737 struct cli_state *cli,
5738 uint16_t fnum,
5739 uint32_t completion_filter,
5740 bool recursive,
5741 bool (*fn)(uint32_t action,
5742 const char *name,
5743 void *priv),
5744 void *priv)
5746 struct tevent_req *req, *subreq;
5747 struct swallow_notify_state *state;
5749 req = tevent_req_create(mem_ctx, &state,
5750 struct swallow_notify_state);
5751 if (req == NULL) {
5752 return NULL;
5754 state->ev = ev;
5755 state->cli = cli;
5756 state->fnum = fnum;
5757 state->completion_filter = completion_filter;
5758 state->recursive = recursive;
5759 state->fn = fn;
5760 state->priv = priv;
5762 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5763 0xffff, state->completion_filter,
5764 state->recursive);
5765 if (tevent_req_nomem(subreq, req)) {
5766 return tevent_req_post(req, ev);
5768 tevent_req_set_callback(subreq, swallow_notify_done, req);
5769 return req;
5772 static void swallow_notify_done(struct tevent_req *subreq)
5774 struct tevent_req *req = tevent_req_callback_data(
5775 subreq, struct tevent_req);
5776 struct swallow_notify_state *state = tevent_req_data(
5777 req, struct swallow_notify_state);
5778 NTSTATUS status;
5779 uint32_t i, num_changes;
5780 struct notify_change *changes;
5782 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5783 TALLOC_FREE(subreq);
5784 if (!NT_STATUS_IS_OK(status)) {
5785 DEBUG(10, ("cli_notify_recv returned %s\n",
5786 nt_errstr(status)));
5787 tevent_req_nterror(req, status);
5788 return;
5791 for (i=0; i<num_changes; i++) {
5792 state->fn(changes[i].action, changes[i].name, state->priv);
5794 TALLOC_FREE(changes);
5796 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5797 0xffff, state->completion_filter,
5798 state->recursive);
5799 if (tevent_req_nomem(subreq, req)) {
5800 return;
5802 tevent_req_set_callback(subreq, swallow_notify_done, req);
5805 static bool print_notifies(uint32_t action, const char *name, void *priv)
5807 if (DEBUGLEVEL > 5) {
5808 d_printf("%d %s\n", (int)action, name);
5810 return true;
5813 static void notify_bench_done(struct tevent_req *req)
5815 int *num_finished = (int *)tevent_req_callback_data_void(req);
5816 *num_finished += 1;
5819 static bool run_notify_bench(int dummy)
5821 const char *dname = "\\notify-bench";
5822 struct tevent_context *ev;
5823 NTSTATUS status;
5824 uint16_t dnum;
5825 struct tevent_req *req1;
5826 struct tevent_req *req2 = NULL;
5827 int i, num_unc_names;
5828 int num_finished = 0;
5830 printf("starting notify-bench test\n");
5832 if (use_multishare_conn) {
5833 char **unc_list;
5834 unc_list = file_lines_load(multishare_conn_fname,
5835 &num_unc_names, 0, NULL);
5836 if (!unc_list || num_unc_names <= 0) {
5837 d_printf("Failed to load unc names list from '%s'\n",
5838 multishare_conn_fname);
5839 return false;
5841 TALLOC_FREE(unc_list);
5842 } else {
5843 num_unc_names = 1;
5846 ev = tevent_context_init(talloc_tos());
5847 if (ev == NULL) {
5848 d_printf("tevent_context_init failed\n");
5849 return false;
5852 for (i=0; i<num_unc_names; i++) {
5853 struct cli_state *cli;
5854 char *base_fname;
5856 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5857 dname, i);
5858 if (base_fname == NULL) {
5859 return false;
5862 if (!torture_open_connection(&cli, i)) {
5863 return false;
5866 status = cli_ntcreate(cli, dname, 0,
5867 MAXIMUM_ALLOWED_ACCESS,
5868 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5869 FILE_SHARE_DELETE,
5870 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5871 &dnum);
5873 if (!NT_STATUS_IS_OK(status)) {
5874 d_printf("Could not create %s: %s\n", dname,
5875 nt_errstr(status));
5876 return false;
5879 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5880 FILE_NOTIFY_CHANGE_FILE_NAME |
5881 FILE_NOTIFY_CHANGE_DIR_NAME |
5882 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5883 FILE_NOTIFY_CHANGE_LAST_WRITE,
5884 false, print_notifies, NULL);
5885 if (req1 == NULL) {
5886 d_printf("Could not create notify request\n");
5887 return false;
5890 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5891 base_fname, 10, torture_numops);
5892 if (req2 == NULL) {
5893 d_printf("Could not create createdels request\n");
5894 return false;
5896 TALLOC_FREE(base_fname);
5898 tevent_req_set_callback(req2, notify_bench_done,
5899 &num_finished);
5902 while (num_finished < num_unc_names) {
5903 int ret;
5904 ret = tevent_loop_once(ev);
5905 if (ret != 0) {
5906 d_printf("tevent_loop_once failed\n");
5907 return false;
5911 if (!tevent_req_poll(req2, ev)) {
5912 d_printf("tevent_req_poll failed\n");
5915 status = torture_createdels_recv(req2);
5916 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5918 return true;
5921 static bool run_mangle1(int dummy)
5923 struct cli_state *cli;
5924 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5925 uint16_t fnum;
5926 fstring alt_name;
5927 NTSTATUS status;
5928 time_t change_time, access_time, write_time;
5929 SMB_OFF_T size;
5930 uint16_t mode;
5932 printf("starting mangle1 test\n");
5933 if (!torture_open_connection(&cli, 0)) {
5934 return False;
5937 cli_sockopt(cli, sockops);
5939 if (!NT_STATUS_IS_OK(cli_ntcreate(
5940 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5941 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5942 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5943 return false;
5945 cli_close(cli, fnum);
5947 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5948 if (!NT_STATUS_IS_OK(status)) {
5949 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5950 nt_errstr(status));
5951 return false;
5953 d_printf("alt_name: %s\n", alt_name);
5955 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5956 d_printf("cli_open(%s) failed: %s\n", alt_name,
5957 cli_errstr(cli));
5958 return false;
5960 cli_close(cli, fnum);
5962 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5963 &write_time, &size, &mode)) {
5964 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5965 cli_errstr(cli));
5966 return false;
5969 return true;
5972 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5974 size_t *to_pull = (size_t *)priv;
5975 size_t thistime = *to_pull;
5977 thistime = MIN(thistime, n);
5978 if (thistime == 0) {
5979 return 0;
5982 memset(buf, 0, thistime);
5983 *to_pull -= thistime;
5984 return thistime;
5987 static bool run_windows_write(int dummy)
5989 struct cli_state *cli1;
5990 uint16_t fnum;
5991 int i;
5992 bool ret = false;
5993 const char *fname = "\\writetest.txt";
5994 struct timeval start_time;
5995 double seconds;
5996 double kbytes;
5998 printf("starting windows_write test\n");
5999 if (!torture_open_connection(&cli1, 0)) {
6000 return False;
6003 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6004 printf("open failed (%s)\n", cli_errstr(cli1));
6005 return False;
6008 cli_sockopt(cli1, sockops);
6010 start_time = timeval_current();
6012 for (i=0; i<torture_numops; i++) {
6013 char c = 0;
6014 off_t start = i * torture_blocksize;
6015 NTSTATUS status;
6016 size_t to_pull = torture_blocksize - 1;
6018 if (cli_write(cli1, fnum, 0, &c,
6019 start + torture_blocksize - 1, 1) != 1) {
6020 printf("cli_write failed: %s\n", cli_errstr(cli1));
6021 goto fail;
6024 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6025 null_source, &to_pull);
6026 if (!NT_STATUS_IS_OK(status)) {
6027 printf("cli_push returned: %s\n", nt_errstr(status));
6028 goto fail;
6032 seconds = timeval_elapsed(&start_time);
6033 kbytes = (double)torture_blocksize * torture_numops;
6034 kbytes /= 1024;
6036 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6037 (double)seconds, (int)(kbytes/seconds));
6039 ret = true;
6040 fail:
6041 cli_close(cli1, fnum);
6042 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6043 torture_close_connection(cli1);
6044 return ret;
6047 static bool run_cli_echo(int dummy)
6049 struct cli_state *cli;
6050 NTSTATUS status;
6052 printf("starting cli_echo test\n");
6053 if (!torture_open_connection(&cli, 0)) {
6054 return false;
6056 cli_sockopt(cli, sockops);
6058 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6060 d_printf("cli_echo returned %s\n", nt_errstr(status));
6062 torture_close_connection(cli);
6063 return NT_STATUS_IS_OK(status);
6066 static bool run_uid_regression_test(int dummy)
6068 static struct cli_state *cli;
6069 int16_t old_vuid;
6070 int16_t old_cnum;
6071 bool correct = True;
6072 NTSTATUS status;
6074 printf("starting uid regression test\n");
6076 if (!torture_open_connection(&cli, 0)) {
6077 return False;
6080 cli_sockopt(cli, sockops);
6082 /* Ok - now save then logoff our current user. */
6083 old_vuid = cli->vuid;
6085 status = cli_ulogoff(cli);
6086 if (!NT_STATUS_IS_OK(status)) {
6087 d_printf("(%s) cli_ulogoff failed: %s\n",
6088 __location__, nt_errstr(status));
6089 correct = false;
6090 goto out;
6093 cli->vuid = old_vuid;
6095 /* Try an operation. */
6096 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6097 /* We expect bad uid. */
6098 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6099 NT_STATUS_NO_SUCH_USER)) {
6100 return False;
6104 old_cnum = cli->cnum;
6106 /* Now try a SMBtdis with the invald vuid set to zero. */
6107 cli->vuid = 0;
6109 /* This should succeed. */
6110 status = cli_tdis(cli);
6112 if (NT_STATUS_IS_OK(status)) {
6113 printf("First tdis with invalid vuid should succeed.\n");
6114 } else {
6115 printf("First tdis failed (%s)\n", nt_errstr(status));
6118 cli->vuid = old_vuid;
6119 cli->cnum = old_cnum;
6121 /* This should fail. */
6122 status = cli_tdis(cli);
6123 if (NT_STATUS_IS_OK(status)) {
6124 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6125 } else {
6126 /* Should be bad tid. */
6127 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6128 NT_STATUS_NETWORK_NAME_DELETED)) {
6129 return False;
6133 cli_rmdir(cli, "\\uid_reg_test");
6135 out:
6137 cli_shutdown(cli);
6138 return correct;
6142 static const char *illegal_chars = "*\\/?<>|\":";
6143 static char force_shortname_chars[] = " +,.[];=\177";
6145 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
6147 struct cli_state *pcli = (struct cli_state *)state;
6148 fstring fname;
6149 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6151 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6152 return;
6154 if (finfo->mode & aDIR) {
6155 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6156 printf("del_fn: failed to rmdir %s\n,", fname );
6157 } else {
6158 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6159 printf("del_fn: failed to unlink %s\n,", fname );
6163 struct sn_state {
6164 int i;
6165 bool val;
6168 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
6170 struct sn_state *s = (struct sn_state *)state;
6171 int i = s->i;
6173 #if 0
6174 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6175 i, finfo->name, finfo->short_name);
6176 #endif
6178 if (strchr(force_shortname_chars, i)) {
6179 if (!finfo->short_name[0]) {
6180 /* Shortname not created when it should be. */
6181 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6182 __location__, finfo->name, i);
6183 s->val = true;
6185 } else if (finfo->short_name[0]){
6186 /* Shortname created when it should not be. */
6187 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6188 __location__, finfo->short_name, finfo->name);
6189 s->val = true;
6193 static bool run_shortname_test(int dummy)
6195 static struct cli_state *cli;
6196 bool correct = True;
6197 int i;
6198 struct sn_state s;
6199 char fname[20];
6201 printf("starting shortname test\n");
6203 if (!torture_open_connection(&cli, 0)) {
6204 return False;
6207 cli_sockopt(cli, sockops);
6209 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6210 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6211 cli_rmdir(cli, "\\shortname");
6213 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6214 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6215 __location__, cli_errstr(cli));
6216 correct = false;
6217 goto out;
6220 strlcpy(fname, "\\shortname\\", sizeof(fname));
6221 strlcat(fname, "test .txt", sizeof(fname));
6223 s.val = false;
6225 for (i = 32; i < 128; i++) {
6226 NTSTATUS status;
6227 uint16_t fnum = (uint16_t)-1;
6229 s.i = i;
6231 if (strchr(illegal_chars, i)) {
6232 continue;
6234 fname[15] = i;
6236 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6237 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6238 if (!NT_STATUS_IS_OK(status)) {
6239 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6240 __location__, fname, cli_errstr(cli));
6241 correct = false;
6242 goto out;
6244 cli_close(cli, fnum);
6245 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
6246 d_printf("(%s) failed to list %s: %s\n",
6247 __location__, fname, cli_errstr(cli));
6248 correct = false;
6249 goto out;
6251 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6252 d_printf("(%s) failed to delete %s: %s\n",
6253 __location__, fname, cli_errstr(cli));
6254 correct = false;
6255 goto out;
6258 if (s.val) {
6259 correct = false;
6260 goto out;
6264 out:
6266 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6267 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6268 cli_rmdir(cli, "\\shortname");
6269 torture_close_connection(cli);
6270 return correct;
6273 static void pagedsearch_cb(struct tevent_req *req)
6275 int rc;
6276 struct tldap_message *msg;
6277 char *dn;
6279 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6280 if (rc != TLDAP_SUCCESS) {
6281 d_printf("tldap_search_paged_recv failed: %s\n",
6282 tldap_err2string(rc));
6283 return;
6285 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6286 TALLOC_FREE(msg);
6287 return;
6289 if (!tldap_entry_dn(msg, &dn)) {
6290 d_printf("tldap_entry_dn failed\n");
6291 return;
6293 d_printf("%s\n", dn);
6294 TALLOC_FREE(msg);
6297 static bool run_tldap(int dummy)
6299 struct tldap_context *ld;
6300 int fd, rc;
6301 NTSTATUS status;
6302 struct sockaddr_storage addr;
6303 struct tevent_context *ev;
6304 struct tevent_req *req;
6305 char *basedn;
6306 const char *filter;
6308 if (!resolve_name(host, &addr, 0, false)) {
6309 d_printf("could not find host %s\n", host);
6310 return false;
6312 status = open_socket_out(&addr, 389, 9999, &fd);
6313 if (!NT_STATUS_IS_OK(status)) {
6314 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6315 return false;
6318 ld = tldap_context_create(talloc_tos(), fd);
6319 if (ld == NULL) {
6320 close(fd);
6321 d_printf("tldap_context_create failed\n");
6322 return false;
6325 rc = tldap_fetch_rootdse(ld);
6326 if (rc != TLDAP_SUCCESS) {
6327 d_printf("tldap_fetch_rootdse failed: %s\n",
6328 tldap_errstr(talloc_tos(), ld, rc));
6329 return false;
6332 basedn = tldap_talloc_single_attribute(
6333 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6334 if (basedn == NULL) {
6335 d_printf("no defaultNamingContext\n");
6336 return false;
6338 d_printf("defaultNamingContext: %s\n", basedn);
6340 ev = tevent_context_init(talloc_tos());
6341 if (ev == NULL) {
6342 d_printf("tevent_context_init failed\n");
6343 return false;
6346 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6347 TLDAP_SCOPE_SUB, "(objectclass=*)",
6348 NULL, 0, 0,
6349 NULL, 0, NULL, 0, 0, 0, 0, 5);
6350 if (req == NULL) {
6351 d_printf("tldap_search_paged_send failed\n");
6352 return false;
6354 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6356 tevent_req_poll(req, ev);
6358 TALLOC_FREE(req);
6360 /* test search filters against rootDSE */
6361 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6362 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6364 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6365 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6366 talloc_tos(), NULL, NULL);
6367 if (rc != TLDAP_SUCCESS) {
6368 d_printf("tldap_search with complex filter failed: %s\n",
6369 tldap_errstr(talloc_tos(), ld, rc));
6370 return false;
6373 TALLOC_FREE(ld);
6374 return true;
6377 /* Torture test to ensure no regression of :
6378 https://bugzilla.samba.org/show_bug.cgi?id=7084
6381 static bool run_dir_createtime(int dummy)
6383 struct cli_state *cli;
6384 const char *dname = "\\testdir";
6385 const char *fname = "\\testdir\\testfile";
6386 NTSTATUS status;
6387 struct timespec create_time;
6388 struct timespec create_time1;
6389 uint16_t fnum;
6390 bool ret = false;
6392 if (!torture_open_connection(&cli, 0)) {
6393 return false;
6396 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6397 cli_rmdir(cli, dname);
6399 status = cli_mkdir(cli, dname);
6400 if (!NT_STATUS_IS_OK(status)) {
6401 printf("mkdir failed: %s\n", nt_errstr(status));
6402 goto out;
6405 if (!cli_qpathinfo2(cli,
6406 dname,
6407 &create_time,
6408 NULL,
6409 NULL,
6410 NULL,
6411 NULL,
6412 NULL,
6413 NULL)) {
6414 status = cli_nt_error(cli);
6415 printf("cli_qpathinfo2 returned %s\n",
6416 nt_errstr(status));
6417 goto out;
6420 /* Sleep 3 seconds, then create a file. */
6421 sleep(3);
6423 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6424 DENY_NONE, &fnum);
6425 if (!NT_STATUS_IS_OK(status)) {
6426 printf("cli_open failed: %s\n", nt_errstr(status));
6427 goto out;
6430 if (!cli_qpathinfo2(cli,
6431 dname,
6432 &create_time1,
6433 NULL,
6434 NULL,
6435 NULL,
6436 NULL,
6437 NULL,
6438 NULL)) {
6439 status = cli_nt_error(cli);
6440 printf("cli_qpathinfo2 (2) returned %s\n",
6441 nt_errstr(status));
6442 goto out;
6445 if (timespec_compare(&create_time1, &create_time)) {
6446 printf("run_dir_createtime: create time was updated (error)\n");
6447 } else {
6448 printf("run_dir_createtime: create time was not updated (correct)\n");
6449 ret = true;
6452 out:
6454 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6455 cli_rmdir(cli, dname);
6456 if (!torture_close_connection(cli)) {
6457 ret = false;
6459 return ret;
6463 static bool run_streamerror(int dummy)
6465 struct cli_state *cli;
6466 const char *dname = "\\testdir";
6467 const char *streamname =
6468 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6469 NTSTATUS status;
6470 time_t change_time, access_time, write_time;
6471 SMB_OFF_T size;
6472 uint16_t mode, fnum;
6473 bool ret = true;
6475 if (!torture_open_connection(&cli, 0)) {
6476 return false;
6479 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6480 cli_rmdir(cli, dname);
6482 status = cli_mkdir(cli, dname);
6483 if (!NT_STATUS_IS_OK(status)) {
6484 printf("mkdir failed: %s\n", nt_errstr(status));
6485 return false;
6488 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
6489 &size, &mode);
6490 status = cli_nt_error(cli);
6492 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6493 printf("pathinfo returned %s, expected "
6494 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6495 nt_errstr(status));
6496 ret = false;
6499 status = cli_ntcreate(cli, streamname, 0x16,
6500 FILE_READ_DATA|FILE_READ_EA|
6501 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6502 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6503 FILE_OPEN, 0, 0, &fnum);
6505 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6506 printf("ntcreate returned %s, expected "
6507 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6508 nt_errstr(status));
6509 ret = false;
6513 cli_rmdir(cli, dname);
6514 return ret;
6517 static bool run_local_substitute(int dummy)
6519 bool ok = true;
6521 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6522 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6523 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6524 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6525 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6526 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6527 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6528 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6530 /* Different captialization rules in sub_basic... */
6532 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6533 "blaDOM") == 0);
6535 return ok;
6538 static bool run_local_base64(int dummy)
6540 int i;
6541 bool ret = true;
6543 for (i=1; i<2000; i++) {
6544 DATA_BLOB blob1, blob2;
6545 char *b64;
6547 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6548 blob1.length = i;
6549 generate_random_buffer(blob1.data, blob1.length);
6551 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6552 if (b64 == NULL) {
6553 d_fprintf(stderr, "base64_encode_data_blob failed "
6554 "for %d bytes\n", i);
6555 ret = false;
6557 blob2 = base64_decode_data_blob(b64);
6558 TALLOC_FREE(b64);
6560 if (data_blob_cmp(&blob1, &blob2)) {
6561 d_fprintf(stderr, "data_blob_cmp failed for %d "
6562 "bytes\n", i);
6563 ret = false;
6565 TALLOC_FREE(blob1.data);
6566 data_blob_free(&blob2);
6568 return ret;
6571 static bool run_local_gencache(int dummy)
6573 char *val;
6574 time_t tm;
6575 DATA_BLOB blob;
6577 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6578 d_printf("%s: gencache_set() failed\n", __location__);
6579 return False;
6582 if (!gencache_get("foo", NULL, NULL)) {
6583 d_printf("%s: gencache_get() failed\n", __location__);
6584 return False;
6587 if (!gencache_get("foo", &val, &tm)) {
6588 d_printf("%s: gencache_get() failed\n", __location__);
6589 return False;
6592 if (strcmp(val, "bar") != 0) {
6593 d_printf("%s: gencache_get() returned %s, expected %s\n",
6594 __location__, val, "bar");
6595 SAFE_FREE(val);
6596 return False;
6599 SAFE_FREE(val);
6601 if (!gencache_del("foo")) {
6602 d_printf("%s: gencache_del() failed\n", __location__);
6603 return False;
6605 if (gencache_del("foo")) {
6606 d_printf("%s: second gencache_del() succeeded\n",
6607 __location__);
6608 return False;
6611 if (gencache_get("foo", &val, &tm)) {
6612 d_printf("%s: gencache_get() on deleted entry "
6613 "succeeded\n", __location__);
6614 return False;
6617 blob = data_blob_string_const_null("bar");
6618 tm = time(NULL) + 60;
6620 if (!gencache_set_data_blob("foo", &blob, tm)) {
6621 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6622 return False;
6625 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6626 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6627 return False;
6630 if (strcmp((const char *)blob.data, "bar") != 0) {
6631 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6632 __location__, (const char *)blob.data, "bar");
6633 data_blob_free(&blob);
6634 return False;
6637 data_blob_free(&blob);
6639 if (!gencache_del("foo")) {
6640 d_printf("%s: gencache_del() failed\n", __location__);
6641 return False;
6643 if (gencache_del("foo")) {
6644 d_printf("%s: second gencache_del() succeeded\n",
6645 __location__);
6646 return False;
6649 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6650 d_printf("%s: gencache_get_data_blob() on deleted entry "
6651 "succeeded\n", __location__);
6652 return False;
6655 return True;
6658 static bool rbt_testval(struct db_context *db, const char *key,
6659 const char *value)
6661 struct db_record *rec;
6662 TDB_DATA data = string_tdb_data(value);
6663 bool ret = false;
6664 NTSTATUS status;
6666 rec = db->fetch_locked(db, db, string_tdb_data(key));
6667 if (rec == NULL) {
6668 d_fprintf(stderr, "fetch_locked failed\n");
6669 goto done;
6671 status = rec->store(rec, data, 0);
6672 if (!NT_STATUS_IS_OK(status)) {
6673 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6674 goto done;
6676 TALLOC_FREE(rec);
6678 rec = db->fetch_locked(db, db, string_tdb_data(key));
6679 if (rec == NULL) {
6680 d_fprintf(stderr, "second fetch_locked failed\n");
6681 goto done;
6683 if ((rec->value.dsize != data.dsize)
6684 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6685 d_fprintf(stderr, "Got wrong data back\n");
6686 goto done;
6689 ret = true;
6690 done:
6691 TALLOC_FREE(rec);
6692 return ret;
6695 static bool run_local_rbtree(int dummy)
6697 struct db_context *db;
6698 bool ret = false;
6699 int i;
6701 db = db_open_rbt(NULL);
6703 if (db == NULL) {
6704 d_fprintf(stderr, "db_open_rbt failed\n");
6705 return false;
6708 for (i=0; i<1000; i++) {
6709 char *key, *value;
6711 if (asprintf(&key, "key%ld", random()) == -1) {
6712 goto done;
6714 if (asprintf(&value, "value%ld", random()) == -1) {
6715 SAFE_FREE(key);
6716 goto done;
6719 if (!rbt_testval(db, key, value)) {
6720 SAFE_FREE(key);
6721 SAFE_FREE(value);
6722 goto done;
6725 SAFE_FREE(value);
6726 if (asprintf(&value, "value%ld", random()) == -1) {
6727 SAFE_FREE(key);
6728 goto done;
6731 if (!rbt_testval(db, key, value)) {
6732 SAFE_FREE(key);
6733 SAFE_FREE(value);
6734 goto done;
6737 SAFE_FREE(key);
6738 SAFE_FREE(value);
6741 ret = true;
6743 done:
6744 TALLOC_FREE(db);
6745 return ret;
6748 struct talloc_dict_test {
6749 int content;
6752 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6754 int *count = (int *)priv;
6755 *count += 1;
6756 return 0;
6759 static bool run_local_talloc_dict(int dummy)
6761 struct talloc_dict *dict;
6762 struct talloc_dict_test *t;
6763 int key, count;
6765 dict = talloc_dict_init(talloc_tos());
6766 if (dict == NULL) {
6767 return false;
6770 t = talloc(talloc_tos(), struct talloc_dict_test);
6771 if (t == NULL) {
6772 return false;
6775 key = 1;
6776 t->content = 1;
6777 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6778 return false;
6781 count = 0;
6782 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6783 return false;
6786 if (count != 1) {
6787 return false;
6790 TALLOC_FREE(dict);
6792 return true;
6795 static bool run_local_string_to_sid(int dummy) {
6796 struct dom_sid sid;
6798 if (string_to_sid(&sid, "S--1-5-32-545")) {
6799 printf("allowing S--1-5-32-545\n");
6800 return false;
6802 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6803 printf("allowing S-1-5-32-+545\n");
6804 return false;
6806 if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6807 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6808 return false;
6810 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6811 printf("allowing S-1-5-32-545-abc\n");
6812 return false;
6814 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6815 printf("could not parse S-1-5-32-545\n");
6816 return false;
6818 if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6819 printf("mis-parsed S-1-5-32-545 as %s\n",
6820 sid_string_tos(&sid));
6821 return false;
6823 return true;
6826 /* Split a path name into filename and stream name components. Canonicalise
6827 * such that an implicit $DATA token is always explicit.
6829 * The "specification" of this function can be found in the
6830 * run_local_stream_name() function in torture.c, I've tried those
6831 * combinations against a W2k3 server.
6834 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6835 char **pbase, char **pstream)
6837 char *base = NULL;
6838 char *stream = NULL;
6839 char *sname; /* stream name */
6840 const char *stype; /* stream type */
6842 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6844 sname = strchr_m(fname, ':');
6846 if (lp_posix_pathnames() || (sname == NULL)) {
6847 if (pbase != NULL) {
6848 base = talloc_strdup(mem_ctx, fname);
6849 NT_STATUS_HAVE_NO_MEMORY(base);
6851 goto done;
6854 if (pbase != NULL) {
6855 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6856 NT_STATUS_HAVE_NO_MEMORY(base);
6859 sname += 1;
6861 stype = strchr_m(sname, ':');
6863 if (stype == NULL) {
6864 sname = talloc_strdup(mem_ctx, sname);
6865 stype = "$DATA";
6867 else {
6868 if (StrCaseCmp(stype, ":$DATA") != 0) {
6870 * If there is an explicit stream type, so far we only
6871 * allow $DATA. Is there anything else allowed? -- vl
6873 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6874 TALLOC_FREE(base);
6875 return NT_STATUS_OBJECT_NAME_INVALID;
6877 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6878 stype += 1;
6881 if (sname == NULL) {
6882 TALLOC_FREE(base);
6883 return NT_STATUS_NO_MEMORY;
6886 if (sname[0] == '\0') {
6888 * no stream name, so no stream
6890 goto done;
6893 if (pstream != NULL) {
6894 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6895 if (stream == NULL) {
6896 TALLOC_FREE(sname);
6897 TALLOC_FREE(base);
6898 return NT_STATUS_NO_MEMORY;
6901 * upper-case the type field
6903 strupper_m(strchr_m(stream, ':')+1);
6906 done:
6907 if (pbase != NULL) {
6908 *pbase = base;
6910 if (pstream != NULL) {
6911 *pstream = stream;
6913 return NT_STATUS_OK;
6916 static bool test_stream_name(const char *fname, const char *expected_base,
6917 const char *expected_stream,
6918 NTSTATUS expected_status)
6920 NTSTATUS status;
6921 char *base = NULL;
6922 char *stream = NULL;
6924 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6925 if (!NT_STATUS_EQUAL(status, expected_status)) {
6926 goto error;
6929 if (!NT_STATUS_IS_OK(status)) {
6930 return true;
6933 if (base == NULL) goto error;
6935 if (strcmp(expected_base, base) != 0) goto error;
6937 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6938 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6940 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6941 goto error;
6943 TALLOC_FREE(base);
6944 TALLOC_FREE(stream);
6945 return true;
6947 error:
6948 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6949 fname, expected_base ? expected_base : "<NULL>",
6950 expected_stream ? expected_stream : "<NULL>",
6951 nt_errstr(expected_status));
6952 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6953 base ? base : "<NULL>", stream ? stream : "<NULL>",
6954 nt_errstr(status));
6955 TALLOC_FREE(base);
6956 TALLOC_FREE(stream);
6957 return false;
6960 static bool run_local_stream_name(int dummy)
6962 bool ret = true;
6964 ret &= test_stream_name(
6965 "bla", "bla", NULL, NT_STATUS_OK);
6966 ret &= test_stream_name(
6967 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6968 ret &= test_stream_name(
6969 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6970 ret &= test_stream_name(
6971 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6972 ret &= test_stream_name(
6973 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6974 ret &= test_stream_name(
6975 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6976 ret &= test_stream_name(
6977 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6978 ret &= test_stream_name(
6979 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6981 return ret;
6984 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6986 if (a.length != b.length) {
6987 printf("a.length=%d != b.length=%d\n",
6988 (int)a.length, (int)b.length);
6989 return false;
6991 if (memcmp(a.data, b.data, a.length) != 0) {
6992 printf("a.data and b.data differ\n");
6993 return false;
6995 return true;
6998 static bool run_local_memcache(int dummy)
7000 struct memcache *cache;
7001 DATA_BLOB k1, k2;
7002 DATA_BLOB d1, d2, d3;
7003 DATA_BLOB v1, v2, v3;
7005 TALLOC_CTX *mem_ctx;
7006 char *str1, *str2;
7007 size_t size1, size2;
7008 bool ret = false;
7010 cache = memcache_init(NULL, 100);
7012 if (cache == NULL) {
7013 printf("memcache_init failed\n");
7014 return false;
7017 d1 = data_blob_const("d1", 2);
7018 d2 = data_blob_const("d2", 2);
7019 d3 = data_blob_const("d3", 2);
7021 k1 = data_blob_const("d1", 2);
7022 k2 = data_blob_const("d2", 2);
7024 memcache_add(cache, STAT_CACHE, k1, d1);
7025 memcache_add(cache, GETWD_CACHE, k2, d2);
7027 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7028 printf("could not find k1\n");
7029 return false;
7031 if (!data_blob_equal(d1, v1)) {
7032 return false;
7035 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7036 printf("could not find k2\n");
7037 return false;
7039 if (!data_blob_equal(d2, v2)) {
7040 return false;
7043 memcache_add(cache, STAT_CACHE, k1, d3);
7045 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7046 printf("could not find replaced k1\n");
7047 return false;
7049 if (!data_blob_equal(d3, v3)) {
7050 return false;
7053 memcache_add(cache, GETWD_CACHE, k1, d1);
7055 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7056 printf("Did find k2, should have been purged\n");
7057 return false;
7060 TALLOC_FREE(cache);
7062 cache = memcache_init(NULL, 0);
7064 mem_ctx = talloc_init("foo");
7066 str1 = talloc_strdup(mem_ctx, "string1");
7067 str2 = talloc_strdup(mem_ctx, "string2");
7069 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7070 data_blob_string_const("torture"), &str1);
7071 size1 = talloc_total_size(cache);
7073 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7074 data_blob_string_const("torture"), &str2);
7075 size2 = talloc_total_size(cache);
7077 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7079 if (size2 > size1) {
7080 printf("memcache leaks memory!\n");
7081 goto fail;
7084 ret = true;
7085 fail:
7086 TALLOC_FREE(cache);
7087 return ret;
7090 static void wbclient_done(struct tevent_req *req)
7092 wbcErr wbc_err;
7093 struct winbindd_response *wb_resp;
7094 int *i = (int *)tevent_req_callback_data_void(req);
7096 wbc_err = wb_trans_recv(req, req, &wb_resp);
7097 TALLOC_FREE(req);
7098 *i += 1;
7099 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7102 static bool run_local_wbclient(int dummy)
7104 struct event_context *ev;
7105 struct wb_context **wb_ctx;
7106 struct winbindd_request wb_req;
7107 bool result = false;
7108 int i, j;
7110 BlockSignals(True, SIGPIPE);
7112 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7113 if (ev == NULL) {
7114 goto fail;
7117 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7118 if (wb_ctx == NULL) {
7119 goto fail;
7122 ZERO_STRUCT(wb_req);
7123 wb_req.cmd = WINBINDD_PING;
7125 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7127 for (i=0; i<nprocs; i++) {
7128 wb_ctx[i] = wb_context_init(ev, NULL);
7129 if (wb_ctx[i] == NULL) {
7130 goto fail;
7132 for (j=0; j<torture_numops; j++) {
7133 struct tevent_req *req;
7134 req = wb_trans_send(ev, ev, wb_ctx[i],
7135 (j % 2) == 0, &wb_req);
7136 if (req == NULL) {
7137 goto fail;
7139 tevent_req_set_callback(req, wbclient_done, &i);
7143 i = 0;
7145 while (i < nprocs * torture_numops) {
7146 event_loop_once(ev);
7149 result = true;
7150 fail:
7151 TALLOC_FREE(ev);
7152 return result;
7155 static void getaddrinfo_finished(struct tevent_req *req)
7157 char *name = (char *)tevent_req_callback_data_void(req);
7158 struct addrinfo *ainfo;
7159 int res;
7161 res = getaddrinfo_recv(req, &ainfo);
7162 if (res != 0) {
7163 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7164 return;
7166 d_printf("gai(%s) succeeded\n", name);
7167 freeaddrinfo(ainfo);
7170 static bool run_getaddrinfo_send(int dummy)
7172 TALLOC_CTX *frame = talloc_stackframe();
7173 struct fncall_context *ctx;
7174 struct tevent_context *ev;
7175 bool result = false;
7176 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7177 "www.slashdot.org", "heise.de" };
7178 struct tevent_req *reqs[4];
7179 int i;
7181 ev = event_context_init(frame);
7182 if (ev == NULL) {
7183 goto fail;
7186 ctx = fncall_context_init(frame, 4);
7188 for (i=0; i<ARRAY_SIZE(names); i++) {
7189 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7190 NULL);
7191 if (reqs[i] == NULL) {
7192 goto fail;
7194 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7195 (void *)names[i]);
7198 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7199 tevent_loop_once(ev);
7202 result = true;
7203 fail:
7204 TALLOC_FREE(frame);
7205 return result;
7208 static bool dbtrans_inc(struct db_context *db)
7210 struct db_record *rec;
7211 uint32_t *val;
7212 bool ret = false;
7213 NTSTATUS status;
7215 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7216 if (rec == NULL) {
7217 printf(__location__ "fetch_lock failed\n");
7218 return false;
7221 if (rec->value.dsize != sizeof(uint32_t)) {
7222 printf(__location__ "value.dsize = %d\n",
7223 (int)rec->value.dsize);
7224 goto fail;
7227 val = (uint32_t *)rec->value.dptr;
7228 *val += 1;
7230 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7231 sizeof(uint32_t)),
7233 if (!NT_STATUS_IS_OK(status)) {
7234 printf(__location__ "store failed: %s\n",
7235 nt_errstr(status));
7236 goto fail;
7239 ret = true;
7240 fail:
7241 TALLOC_FREE(rec);
7242 return ret;
7245 static bool run_local_dbtrans(int dummy)
7247 struct db_context *db;
7248 struct db_record *rec;
7249 NTSTATUS status;
7250 uint32_t initial;
7251 int res;
7253 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7254 O_RDWR|O_CREAT, 0600);
7255 if (db == NULL) {
7256 printf("Could not open transtest.db\n");
7257 return false;
7260 res = db->transaction_start(db);
7261 if (res == -1) {
7262 printf(__location__ "transaction_start failed\n");
7263 return false;
7266 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7267 if (rec == NULL) {
7268 printf(__location__ "fetch_lock failed\n");
7269 return false;
7272 if (rec->value.dptr == NULL) {
7273 initial = 0;
7274 status = rec->store(
7275 rec, make_tdb_data((uint8_t *)&initial,
7276 sizeof(initial)),
7278 if (!NT_STATUS_IS_OK(status)) {
7279 printf(__location__ "store returned %s\n",
7280 nt_errstr(status));
7281 return false;
7285 TALLOC_FREE(rec);
7287 res = db->transaction_commit(db);
7288 if (res == -1) {
7289 printf(__location__ "transaction_commit failed\n");
7290 return false;
7293 while (true) {
7294 uint32_t val, val2;
7295 int i;
7297 res = db->transaction_start(db);
7298 if (res == -1) {
7299 printf(__location__ "transaction_start failed\n");
7300 break;
7303 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7304 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7305 break;
7308 for (i=0; i<10; i++) {
7309 if (!dbtrans_inc(db)) {
7310 return false;
7314 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7315 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7316 break;
7319 if (val2 != val + 10) {
7320 printf(__location__ "val=%d, val2=%d\n",
7321 (int)val, (int)val2);
7322 break;
7325 printf("val2=%d\r", val2);
7327 res = db->transaction_commit(db);
7328 if (res == -1) {
7329 printf(__location__ "transaction_commit failed\n");
7330 break;
7334 TALLOC_FREE(db);
7335 return true;
7338 static double create_procs(bool (*fn)(int), bool *result)
7340 int i, status;
7341 volatile pid_t *child_status;
7342 volatile bool *child_status_out;
7343 int synccount;
7344 int tries = 8;
7345 struct timeval start;
7347 synccount = 0;
7349 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7350 if (!child_status) {
7351 printf("Failed to setup shared memory\n");
7352 return -1;
7355 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7356 if (!child_status_out) {
7357 printf("Failed to setup result status shared memory\n");
7358 return -1;
7361 for (i = 0; i < nprocs; i++) {
7362 child_status[i] = 0;
7363 child_status_out[i] = True;
7366 start = timeval_current();
7368 for (i=0;i<nprocs;i++) {
7369 procnum = i;
7370 if (fork() == 0) {
7371 pid_t mypid = getpid();
7372 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7374 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7376 while (1) {
7377 if (torture_open_connection(&current_cli, i)) break;
7378 if (tries-- == 0) {
7379 printf("pid %d failed to start\n", (int)getpid());
7380 _exit(1);
7382 smb_msleep(10);
7385 child_status[i] = getpid();
7387 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7389 child_status_out[i] = fn(i);
7390 _exit(0);
7394 do {
7395 synccount = 0;
7396 for (i=0;i<nprocs;i++) {
7397 if (child_status[i]) synccount++;
7399 if (synccount == nprocs) break;
7400 smb_msleep(10);
7401 } while (timeval_elapsed(&start) < 30);
7403 if (synccount != nprocs) {
7404 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7405 *result = False;
7406 return timeval_elapsed(&start);
7409 /* start the client load */
7410 start = timeval_current();
7412 for (i=0;i<nprocs;i++) {
7413 child_status[i] = 0;
7416 printf("%d clients started\n", nprocs);
7418 for (i=0;i<nprocs;i++) {
7419 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7422 printf("\n");
7424 for (i=0;i<nprocs;i++) {
7425 if (!child_status_out[i]) {
7426 *result = False;
7429 return timeval_elapsed(&start);
7432 #define FLAG_MULTIPROC 1
7434 static struct {
7435 const char *name;
7436 bool (*fn)(int);
7437 unsigned flags;
7438 } torture_ops[] = {
7439 {"FDPASS", run_fdpasstest, 0},
7440 {"LOCK1", run_locktest1, 0},
7441 {"LOCK2", run_locktest2, 0},
7442 {"LOCK3", run_locktest3, 0},
7443 {"LOCK4", run_locktest4, 0},
7444 {"LOCK5", run_locktest5, 0},
7445 {"LOCK6", run_locktest6, 0},
7446 {"LOCK7", run_locktest7, 0},
7447 {"LOCK8", run_locktest8, 0},
7448 {"LOCK9", run_locktest9, 0},
7449 {"UNLINK", run_unlinktest, 0},
7450 {"BROWSE", run_browsetest, 0},
7451 {"ATTR", run_attrtest, 0},
7452 {"TRANS2", run_trans2test, 0},
7453 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7454 {"TORTURE",run_torture, FLAG_MULTIPROC},
7455 {"RANDOMIPC", run_randomipc, 0},
7456 {"NEGNOWAIT", run_negprot_nowait, 0},
7457 {"NBENCH", run_nbench, 0},
7458 {"OPLOCK1", run_oplock1, 0},
7459 {"OPLOCK2", run_oplock2, 0},
7460 {"OPLOCK3", run_oplock3, 0},
7461 {"DIR", run_dirtest, 0},
7462 {"DIR1", run_dirtest1, 0},
7463 {"DIR-CREATETIME", run_dir_createtime, 0},
7464 {"DENY1", torture_denytest1, 0},
7465 {"DENY2", torture_denytest2, 0},
7466 {"TCON", run_tcon_test, 0},
7467 {"TCONDEV", run_tcon_devtype_test, 0},
7468 {"RW1", run_readwritetest, 0},
7469 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7470 {"RW3", run_readwritelarge, 0},
7471 {"OPEN", run_opentest, 0},
7472 {"POSIX", run_simple_posix_open_test, 0},
7473 {"POSIX-APPEND", run_posix_append, 0},
7474 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7475 { "SHORTNAME-TEST", run_shortname_test, 0},
7476 #if 1
7477 {"OPENATTR", run_openattrtest, 0},
7478 #endif
7479 {"XCOPY", run_xcopy, 0},
7480 {"RENAME", run_rename, 0},
7481 {"DELETE", run_deletetest, 0},
7482 {"PROPERTIES", run_properties, 0},
7483 {"MANGLE", torture_mangle, 0},
7484 {"MANGLE1", run_mangle1, 0},
7485 {"W2K", run_w2ktest, 0},
7486 {"TRANS2SCAN", torture_trans2_scan, 0},
7487 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7488 {"UTABLE", torture_utable, 0},
7489 {"CASETABLE", torture_casetable, 0},
7490 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7491 {"PIPE_NUMBER", run_pipe_number, 0},
7492 {"TCON2", run_tcon2_test, 0},
7493 {"IOCTL", torture_ioctl_test, 0},
7494 {"CHKPATH", torture_chkpath_test, 0},
7495 {"FDSESS", run_fdsesstest, 0},
7496 { "EATEST", run_eatest, 0},
7497 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7498 { "CHAIN1", run_chain1, 0},
7499 { "CHAIN2", run_chain2, 0},
7500 { "WINDOWS-WRITE", run_windows_write, 0},
7501 { "CLI_ECHO", run_cli_echo, 0},
7502 { "GETADDRINFO", run_getaddrinfo_send, 0},
7503 { "TLDAP", run_tldap },
7504 { "STREAMERROR", run_streamerror },
7505 { "NOTIFY-BENCH", run_notify_bench },
7506 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7507 { "LOCAL-GENCACHE", run_local_gencache, 0},
7508 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7509 { "LOCAL-BASE64", run_local_base64, 0},
7510 { "LOCAL-RBTREE", run_local_rbtree, 0},
7511 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7512 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7513 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7514 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7515 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7516 {NULL, NULL, 0}};
7520 /****************************************************************************
7521 run a specified test or "ALL"
7522 ****************************************************************************/
7523 static bool run_test(const char *name)
7525 bool ret = True;
7526 bool result = True;
7527 bool found = False;
7528 int i;
7529 double t;
7530 if (strequal(name,"ALL")) {
7531 for (i=0;torture_ops[i].name;i++) {
7532 run_test(torture_ops[i].name);
7534 found = True;
7537 for (i=0;torture_ops[i].name;i++) {
7538 fstr_sprintf(randomfname, "\\XX%x",
7539 (unsigned)random());
7541 if (strequal(name, torture_ops[i].name)) {
7542 found = True;
7543 printf("Running %s\n", name);
7544 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7545 t = create_procs(torture_ops[i].fn, &result);
7546 if (!result) {
7547 ret = False;
7548 printf("TEST %s FAILED!\n", name);
7550 } else {
7551 struct timeval start;
7552 start = timeval_current();
7553 if (!torture_ops[i].fn(0)) {
7554 ret = False;
7555 printf("TEST %s FAILED!\n", name);
7557 t = timeval_elapsed(&start);
7559 printf("%s took %g secs\n\n", name, t);
7563 if (!found) {
7564 printf("Did not find a test named %s\n", name);
7565 ret = False;
7568 return ret;
7572 static void usage(void)
7574 int i;
7576 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7577 printf("Please use samba4 torture.\n\n");
7579 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7581 printf("\t-d debuglevel\n");
7582 printf("\t-U user%%pass\n");
7583 printf("\t-k use kerberos\n");
7584 printf("\t-N numprocs\n");
7585 printf("\t-n my_netbios_name\n");
7586 printf("\t-W workgroup\n");
7587 printf("\t-o num_operations\n");
7588 printf("\t-O socket_options\n");
7589 printf("\t-m maximum protocol\n");
7590 printf("\t-L use oplocks\n");
7591 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7592 printf("\t-A showall\n");
7593 printf("\t-p port\n");
7594 printf("\t-s seed\n");
7595 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7596 printf("\n\n");
7598 printf("tests are:");
7599 for (i=0;torture_ops[i].name;i++) {
7600 printf(" %s", torture_ops[i].name);
7602 printf("\n");
7604 printf("default test is ALL\n");
7606 exit(1);
7609 /****************************************************************************
7610 main program
7611 ****************************************************************************/
7612 int main(int argc,char *argv[])
7614 int opt, i;
7615 char *p;
7616 int gotuser = 0;
7617 int gotpass = 0;
7618 bool correct = True;
7619 TALLOC_CTX *frame = talloc_stackframe();
7620 int seed = time(NULL);
7622 dbf = x_stdout;
7624 #ifdef HAVE_SETBUFFER
7625 setbuffer(stdout, NULL, 0);
7626 #endif
7628 load_case_tables();
7630 setup_logging("smbtorture", true);
7632 if (is_default_dyn_CONFIGFILE()) {
7633 if(getenv("SMB_CONF_PATH")) {
7634 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7637 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7638 load_interfaces();
7640 if (argc < 2) {
7641 usage();
7644 for(p = argv[1]; *p; p++)
7645 if(*p == '\\')
7646 *p = '/';
7648 if (strncmp(argv[1], "//", 2)) {
7649 usage();
7652 fstrcpy(host, &argv[1][2]);
7653 p = strchr_m(&host[2],'/');
7654 if (!p) {
7655 usage();
7657 *p = 0;
7658 fstrcpy(share, p+1);
7660 fstrcpy(myname, get_myname(talloc_tos()));
7661 if (!*myname) {
7662 fprintf(stderr, "Failed to get my hostname.\n");
7663 return 1;
7666 if (*username == 0 && getenv("LOGNAME")) {
7667 fstrcpy(username,getenv("LOGNAME"));
7670 argc--;
7671 argv++;
7673 fstrcpy(workgroup, lp_workgroup());
7675 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7676 switch (opt) {
7677 case 'p':
7678 port_to_use = atoi(optarg);
7679 break;
7680 case 's':
7681 seed = atoi(optarg);
7682 break;
7683 case 'W':
7684 fstrcpy(workgroup,optarg);
7685 break;
7686 case 'm':
7687 max_protocol = interpret_protocol(optarg, max_protocol);
7688 break;
7689 case 'N':
7690 nprocs = atoi(optarg);
7691 break;
7692 case 'o':
7693 torture_numops = atoi(optarg);
7694 break;
7695 case 'd':
7696 DEBUGLEVEL = atoi(optarg);
7697 break;
7698 case 'O':
7699 sockops = optarg;
7700 break;
7701 case 'L':
7702 use_oplocks = True;
7703 break;
7704 case 'l':
7705 local_path = optarg;
7706 break;
7707 case 'A':
7708 torture_showall = True;
7709 break;
7710 case 'n':
7711 fstrcpy(myname, optarg);
7712 break;
7713 case 'c':
7714 client_txt = optarg;
7715 break;
7716 case 'e':
7717 do_encrypt = true;
7718 break;
7719 case 'k':
7720 #ifdef HAVE_KRB5
7721 use_kerberos = True;
7722 #else
7723 d_printf("No kerberos support compiled in\n");
7724 exit(1);
7725 #endif
7726 break;
7727 case 'U':
7728 gotuser = 1;
7729 fstrcpy(username,optarg);
7730 p = strchr_m(username,'%');
7731 if (p) {
7732 *p = 0;
7733 fstrcpy(password, p+1);
7734 gotpass = 1;
7736 break;
7737 case 'b':
7738 fstrcpy(multishare_conn_fname, optarg);
7739 use_multishare_conn = True;
7740 break;
7741 case 'B':
7742 torture_blocksize = atoi(optarg);
7743 break;
7744 default:
7745 printf("Unknown option %c (%d)\n", (char)opt, opt);
7746 usage();
7750 d_printf("using seed %d\n", seed);
7752 srandom(seed);
7754 if(use_kerberos && !gotuser) gotpass = True;
7756 while (!gotpass) {
7757 p = getpass("Password:");
7758 if (p) {
7759 fstrcpy(password, p);
7760 gotpass = 1;
7764 printf("host=%s share=%s user=%s myname=%s\n",
7765 host, share, username, myname);
7767 if (argc == optind) {
7768 correct = run_test("ALL");
7769 } else {
7770 for (i=optind;i<argc;i++) {
7771 if (!run_test(argv[i])) {
7772 correct = False;
7777 TALLOC_FREE(frame);
7779 if (correct) {
7780 return(0);
7781 } else {
7782 return(1);