s4-drs: fixed the NC in the getncchanges RID alloc reply
[Samba/cd1.git] / source3 / torture / torture.c
blobc7a69ae403b0d2d1679a1e3811790eddded9a955
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"
25 extern char *optarg;
26 extern int optind;
28 static fstring host, workgroup, share, password, username, myname;
29 static int max_protocol = PROTOCOL_NT1;
30 static const char *sockops="TCP_NODELAY";
31 static int nprocs=1;
32 static int port_to_use=0;
33 int torture_numops=100;
34 int torture_blocksize=1024*1024;
35 static int procnum; /* records process count number when forking */
36 static struct cli_state *current_cli;
37 static fstring randomfname;
38 static bool use_oplocks;
39 static bool use_level_II_oplocks;
40 static const char *client_txt = "client_oplocks.txt";
41 static bool use_kerberos;
42 static fstring multishare_conn_fname;
43 static bool use_multishare_conn = False;
44 static bool do_encrypt;
45 static const char *local_path = NULL;
47 bool torture_showall = False;
49 static double create_procs(bool (*fn)(int), bool *result);
52 /* return a pointer to a anonymous shared memory segment of size "size"
53 which will persist across fork() but will disappear when all processes
54 exit
56 The memory is not zeroed
58 This function uses system5 shared memory. It takes advantage of a property
59 that the memory is not destroyed if it is attached when the id is removed
61 void *shm_setup(int size)
63 int shmid;
64 void *ret;
66 #ifdef __QNXNTO__
67 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
68 if (shmid == -1) {
69 printf("can't get shared memory\n");
70 exit(1);
72 shm_unlink("private");
73 if (ftruncate(shmid, size) == -1) {
74 printf("can't set shared memory size\n");
75 exit(1);
77 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
78 if (ret == MAP_FAILED) {
79 printf("can't map shared memory\n");
80 exit(1);
82 #else
83 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
84 if (shmid == -1) {
85 printf("can't get shared memory\n");
86 exit(1);
88 ret = (void *)shmat(shmid, 0, 0);
89 if (!ret || ret == (void *)-1) {
90 printf("can't attach to shared memory\n");
91 return NULL;
93 /* the following releases the ipc, but note that this process
94 and all its children will still have access to the memory, its
95 just that the shmid is no longer valid for other shm calls. This
96 means we don't leave behind lots of shm segments after we exit
98 See Stevens "advanced programming in unix env" for details
100 shmctl(shmid, IPC_RMID, 0);
101 #endif
103 return ret;
106 /********************************************************************
107 Ensure a connection is encrypted.
108 ********************************************************************/
110 static bool force_cli_encryption(struct cli_state *c,
111 const char *sharename)
113 uint16 major, minor;
114 uint32 caplow, caphigh;
115 NTSTATUS status;
117 if (!SERVER_HAS_UNIX_CIFS(c)) {
118 d_printf("Encryption required and "
119 "server that doesn't support "
120 "UNIX extensions - failing connect\n");
121 return false;
124 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
125 &caphigh);
126 if (!NT_STATUS_IS_OK(status)) {
127 d_printf("Encryption required and "
128 "can't get UNIX CIFS extensions "
129 "version from server: %s\n", nt_errstr(status));
130 return false;
133 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
134 d_printf("Encryption required and "
135 "share %s doesn't support "
136 "encryption.\n", sharename);
137 return false;
140 if (c->use_kerberos) {
141 status = cli_gss_smb_encryption_start(c);
142 } else {
143 status = cli_raw_ntlm_smb_encryption_start(c,
144 username,
145 password,
146 workgroup);
149 if (!NT_STATUS_IS_OK(status)) {
150 d_printf("Encryption required and "
151 "setup failed with error %s.\n",
152 nt_errstr(status));
153 return false;
156 return true;
160 static struct cli_state *open_nbt_connection(void)
162 struct nmb_name called, calling;
163 struct sockaddr_storage ss;
164 struct cli_state *c;
165 NTSTATUS status;
167 make_nmb_name(&calling, myname, 0x0);
168 make_nmb_name(&called , host, 0x20);
170 zero_sockaddr(&ss);
172 if (!(c = cli_initialise())) {
173 printf("Failed initialize cli_struct to connect with %s\n", host);
174 return NULL;
177 c->port = port_to_use;
179 status = cli_connect(c, host, &ss);
180 if (!NT_STATUS_IS_OK(status)) {
181 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
182 return NULL;
185 c->use_kerberos = use_kerberos;
187 c->timeout = 120000; /* set a really long timeout (2 minutes) */
188 if (use_oplocks) c->use_oplocks = True;
189 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
191 if (!cli_session_request(c, &calling, &called)) {
193 * Well, that failed, try *SMBSERVER ...
194 * However, we must reconnect as well ...
196 status = cli_connect(c, host, &ss);
197 if (!NT_STATUS_IS_OK(status)) {
198 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
199 return NULL;
202 make_nmb_name(&called, "*SMBSERVER", 0x20);
203 if (!cli_session_request(c, &calling, &called)) {
204 printf("%s rejected the session\n",host);
205 printf("We tried with a called name of %s & %s\n",
206 host, "*SMBSERVER");
207 cli_shutdown(c);
208 return NULL;
212 return c;
215 /* Insert a NULL at the first separator of the given path and return a pointer
216 * to the remainder of the string.
218 static char *
219 terminate_path_at_separator(char * path)
221 char * p;
223 if (!path) {
224 return NULL;
227 if ((p = strchr_m(path, '/'))) {
228 *p = '\0';
229 return p + 1;
232 if ((p = strchr_m(path, '\\'))) {
233 *p = '\0';
234 return p + 1;
237 /* No separator. */
238 return NULL;
242 parse a //server/share type UNC name
244 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
245 char **hostname, char **sharename)
247 char *p;
249 *hostname = *sharename = NULL;
251 if (strncmp(unc_name, "\\\\", 2) &&
252 strncmp(unc_name, "//", 2)) {
253 return False;
256 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
257 p = terminate_path_at_separator(*hostname);
259 if (p && *p) {
260 *sharename = talloc_strdup(mem_ctx, p);
261 terminate_path_at_separator(*sharename);
264 if (*hostname && *sharename) {
265 return True;
268 TALLOC_FREE(*hostname);
269 TALLOC_FREE(*sharename);
270 return False;
273 static bool torture_open_connection_share(struct cli_state **c,
274 const char *hostname,
275 const char *sharename)
277 bool retry;
278 int flags = 0;
279 NTSTATUS status;
281 if (use_kerberos)
282 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
283 if (use_oplocks)
284 flags |= CLI_FULL_CONNECTION_OPLOCKS;
285 if (use_level_II_oplocks)
286 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
288 status = cli_full_connection(c, myname,
289 hostname, NULL, port_to_use,
290 sharename, "?????",
291 username, workgroup,
292 password, flags, Undefined, &retry);
293 if (!NT_STATUS_IS_OK(status)) {
294 printf("failed to open share connection: //%s/%s port:%d - %s\n",
295 hostname, sharename, port_to_use, nt_errstr(status));
296 return False;
299 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
301 if (do_encrypt) {
302 return force_cli_encryption(*c,
303 sharename);
305 return True;
308 bool torture_open_connection(struct cli_state **c, int conn_index)
310 char **unc_list = NULL;
311 int num_unc_names = 0;
312 bool result;
314 if (use_multishare_conn==True) {
315 char *h, *s;
316 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
317 if (!unc_list || num_unc_names <= 0) {
318 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
319 exit(1);
322 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
323 NULL, &h, &s)) {
324 printf("Failed to parse UNC name %s\n",
325 unc_list[conn_index % num_unc_names]);
326 TALLOC_FREE(unc_list);
327 exit(1);
330 result = torture_open_connection_share(c, h, s);
332 /* h, s were copied earlier */
333 TALLOC_FREE(unc_list);
334 return result;
337 return torture_open_connection_share(c, host, share);
340 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
342 uint16 old_vuid = cli->vuid;
343 fstring old_user_name;
344 size_t passlen = strlen(password);
345 NTSTATUS status;
346 bool ret;
348 fstrcpy(old_user_name, cli->user_name);
349 cli->vuid = 0;
350 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
351 password, passlen,
352 password, passlen,
353 workgroup));
354 *new_vuid = cli->vuid;
355 cli->vuid = old_vuid;
356 status = cli_set_username(cli, old_user_name);
357 if (!NT_STATUS_IS_OK(status)) {
358 return false;
360 return ret;
364 bool torture_close_connection(struct cli_state *c)
366 bool ret = True;
367 NTSTATUS status;
369 status = cli_tdis(c);
370 if (!NT_STATUS_IS_OK(status)) {
371 printf("tdis failed (%s)\n", nt_errstr(status));
372 ret = False;
375 cli_shutdown(c);
377 return ret;
381 /* check if the server produced the expected error code */
382 static bool check_error(int line, struct cli_state *c,
383 uint8 eclass, uint32 ecode, NTSTATUS nterr)
385 if (cli_is_dos_error(c)) {
386 uint8 cclass;
387 uint32 num;
389 /* Check DOS error */
391 cli_dos_error(c, &cclass, &num);
393 if (eclass != cclass || ecode != num) {
394 printf("unexpected error code class=%d code=%d\n",
395 (int)cclass, (int)num);
396 printf(" expected %d/%d %s (line=%d)\n",
397 (int)eclass, (int)ecode, nt_errstr(nterr), line);
398 return False;
401 } else {
402 NTSTATUS status;
404 /* Check NT error */
406 status = cli_nt_error(c);
408 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
409 printf("unexpected error code %s\n", nt_errstr(status));
410 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
411 return False;
415 return True;
419 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
421 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
422 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
424 return True;
428 static bool rw_torture(struct cli_state *c)
430 const char *lockfname = "\\torture.lck";
431 fstring fname;
432 uint16_t fnum;
433 uint16_t fnum2;
434 pid_t pid2, pid = getpid();
435 int i, j;
436 char buf[1024];
437 bool correct = True;
438 NTSTATUS status;
440 memset(buf, '\0', sizeof(buf));
442 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
443 DENY_NONE, &fnum2);
444 if (!NT_STATUS_IS_OK(status)) {
445 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
447 if (!NT_STATUS_IS_OK(status)) {
448 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
449 return False;
452 for (i=0;i<torture_numops;i++) {
453 unsigned n = (unsigned)sys_random()%10;
454 if (i % 10 == 0) {
455 printf("%d\r", i); fflush(stdout);
457 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
459 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
460 return False;
463 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
464 printf("open failed (%s)\n", cli_errstr(c));
465 correct = False;
466 break;
469 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
470 printf("write failed (%s)\n", cli_errstr(c));
471 correct = False;
474 for (j=0;j<50;j++) {
475 if (cli_write(c, fnum, 0, (char *)buf,
476 sizeof(pid)+(j*sizeof(buf)),
477 sizeof(buf)) != sizeof(buf)) {
478 printf("write failed (%s)\n", cli_errstr(c));
479 correct = False;
483 pid2 = 0;
485 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
486 printf("read failed (%s)\n", cli_errstr(c));
487 correct = False;
490 if (pid2 != pid) {
491 printf("data corruption!\n");
492 correct = False;
495 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
496 printf("close failed (%s)\n", cli_errstr(c));
497 correct = False;
500 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
501 printf("unlink failed (%s)\n", cli_errstr(c));
502 correct = False;
505 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
506 printf("unlock failed (%s)\n", cli_errstr(c));
507 correct = False;
511 cli_close(c, fnum2);
512 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
514 printf("%d\n", i);
516 return correct;
519 static bool run_torture(int dummy)
521 struct cli_state *cli;
522 bool ret;
524 cli = current_cli;
526 cli_sockopt(cli, sockops);
528 ret = rw_torture(cli);
530 if (!torture_close_connection(cli)) {
531 ret = False;
534 return ret;
537 static bool rw_torture3(struct cli_state *c, char *lockfname)
539 uint16_t fnum = (uint16_t)-1;
540 unsigned int i = 0;
541 char buf[131072];
542 char buf_rd[131072];
543 unsigned count;
544 unsigned countprev = 0;
545 ssize_t sent = 0;
546 bool correct = True;
547 NTSTATUS status;
549 srandom(1);
550 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
552 SIVAL(buf, i, sys_random());
555 if (procnum == 0)
557 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
558 DENY_NONE, &fnum))) {
559 printf("first open read/write of %s failed (%s)\n",
560 lockfname, cli_errstr(c));
561 return False;
564 else
566 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
568 status = cli_open(c, lockfname, O_RDONLY,
569 DENY_NONE, &fnum);
570 if (!NT_STATUS_IS_OK(status)) {
571 break;
573 smb_msleep(10);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("second open read-only of %s failed (%s)\n",
577 lockfname, cli_errstr(c));
578 return False;
582 i = 0;
583 for (count = 0; count < sizeof(buf); count += sent)
585 if (count >= countprev) {
586 printf("%d %8d\r", i, count);
587 fflush(stdout);
588 i++;
589 countprev += (sizeof(buf) / 20);
592 if (procnum == 0)
594 sent = ((unsigned)sys_random()%(20))+ 1;
595 if (sent > sizeof(buf) - count)
597 sent = sizeof(buf) - count;
600 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
601 printf("write failed (%s)\n", cli_errstr(c));
602 correct = False;
605 else
607 sent = cli_read(c, fnum, buf_rd+count, count,
608 sizeof(buf)-count);
609 if (sent < 0)
611 printf("read failed offset:%d size:%ld (%s)\n",
612 count, (unsigned long)sizeof(buf)-count,
613 cli_errstr(c));
614 correct = False;
615 sent = 0;
617 if (sent > 0)
619 if (memcmp(buf_rd+count, buf+count, sent) != 0)
621 printf("read/write compare failed\n");
622 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
623 correct = False;
624 break;
631 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
632 printf("close failed (%s)\n", cli_errstr(c));
633 correct = False;
636 return correct;
639 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
641 const char *lockfname = "\\torture2.lck";
642 uint16_t fnum1;
643 uint16_t fnum2;
644 int i;
645 char buf[131072];
646 char buf_rd[131072];
647 bool correct = True;
648 ssize_t bytes_read;
650 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
651 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
654 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
655 DENY_NONE, &fnum1))) {
656 printf("first open read/write of %s failed (%s)\n",
657 lockfname, cli_errstr(c1));
658 return False;
660 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
661 DENY_NONE, &fnum2))) {
662 printf("second open read-only of %s failed (%s)\n",
663 lockfname, cli_errstr(c2));
664 cli_close(c1, fnum1);
665 return False;
668 for (i=0;i<torture_numops;i++)
670 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
671 if (i % 10 == 0) {
672 printf("%d\r", i); fflush(stdout);
675 generate_random_buffer((unsigned char *)buf, buf_size);
677 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
678 printf("write failed (%s)\n", cli_errstr(c1));
679 correct = False;
680 break;
683 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
684 printf("read failed (%s)\n", cli_errstr(c2));
685 printf("read %d, expected %ld\n", (int)bytes_read,
686 (unsigned long)buf_size);
687 correct = False;
688 break;
691 if (memcmp(buf_rd, buf, buf_size) != 0)
693 printf("read/write compare failed\n");
694 correct = False;
695 break;
699 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
700 printf("close failed (%s)\n", cli_errstr(c2));
701 correct = False;
703 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
704 printf("close failed (%s)\n", cli_errstr(c1));
705 correct = False;
708 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
709 printf("unlink failed (%s)\n", cli_errstr(c1));
710 correct = False;
713 return correct;
716 static bool run_readwritetest(int dummy)
718 struct cli_state *cli1, *cli2;
719 bool test1, test2 = False;
721 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
722 return False;
724 cli_sockopt(cli1, sockops);
725 cli_sockopt(cli2, sockops);
727 printf("starting readwritetest\n");
729 test1 = rw_torture2(cli1, cli2);
730 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
732 if (test1) {
733 test2 = rw_torture2(cli1, cli1);
734 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
737 if (!torture_close_connection(cli1)) {
738 test1 = False;
741 if (!torture_close_connection(cli2)) {
742 test2 = False;
745 return (test1 && test2);
748 static bool run_readwritemulti(int dummy)
750 struct cli_state *cli;
751 bool test;
753 cli = current_cli;
755 cli_sockopt(cli, sockops);
757 printf("run_readwritemulti: fname %s\n", randomfname);
758 test = rw_torture3(cli, randomfname);
760 if (!torture_close_connection(cli)) {
761 test = False;
764 return test;
767 static bool run_readwritelarge(int dummy)
769 static struct cli_state *cli1;
770 uint16_t fnum1;
771 const char *lockfname = "\\large.dat";
772 SMB_OFF_T fsize;
773 char buf[126*1024];
774 bool correct = True;
776 if (!torture_open_connection(&cli1, 0)) {
777 return False;
779 cli_sockopt(cli1, sockops);
780 memset(buf,'\0',sizeof(buf));
782 cli1->max_xmit = 128*1024;
784 printf("starting readwritelarge\n");
786 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
788 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
789 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
790 return False;
793 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
795 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
796 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
797 correct = False;
800 if (fsize == sizeof(buf))
801 printf("readwritelarge test 1 succeeded (size = %lx)\n",
802 (unsigned long)fsize);
803 else {
804 printf("readwritelarge test 1 failed (size = %lx)\n",
805 (unsigned long)fsize);
806 correct = False;
809 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
810 printf("close failed (%s)\n", cli_errstr(cli1));
811 correct = False;
814 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
815 printf("unlink failed (%s)\n", cli_errstr(cli1));
816 correct = False;
819 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
820 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
821 return False;
824 cli1->max_xmit = 4*1024;
826 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
828 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
829 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
830 correct = False;
833 if (fsize == sizeof(buf))
834 printf("readwritelarge test 2 succeeded (size = %lx)\n",
835 (unsigned long)fsize);
836 else {
837 printf("readwritelarge test 2 failed (size = %lx)\n",
838 (unsigned long)fsize);
839 correct = False;
842 #if 0
843 /* ToDo - set allocation. JRA */
844 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
845 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
846 return False;
848 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
849 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
850 correct = False;
852 if (fsize != 0)
853 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
854 #endif
856 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
857 printf("close failed (%s)\n", cli_errstr(cli1));
858 correct = False;
861 if (!torture_close_connection(cli1)) {
862 correct = False;
864 return correct;
867 int line_count = 0;
868 int nbio_id;
870 #define ival(s) strtol(s, NULL, 0)
872 /* run a test that simulates an approximate netbench client load */
873 static bool run_netbench(int client)
875 struct cli_state *cli;
876 int i;
877 char line[1024];
878 char cname[20];
879 FILE *f;
880 const char *params[20];
881 bool correct = True;
883 cli = current_cli;
885 nbio_id = client;
887 cli_sockopt(cli, sockops);
889 nb_setup(cli);
891 slprintf(cname,sizeof(cname)-1, "client%d", client);
893 f = fopen(client_txt, "r");
895 if (!f) {
896 perror(client_txt);
897 return False;
900 while (fgets(line, sizeof(line)-1, f)) {
901 char *saveptr;
902 line_count++;
904 line[strlen(line)-1] = 0;
906 /* printf("[%d] %s\n", line_count, line); */
908 all_string_sub(line,"client1", cname, sizeof(line));
910 /* parse the command parameters */
911 params[0] = strtok_r(line, " ", &saveptr);
912 i = 0;
913 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
915 params[i] = "";
917 if (i < 2) continue;
919 if (!strncmp(params[0],"SMB", 3)) {
920 printf("ERROR: You are using a dbench 1 load file\n");
921 exit(1);
924 if (!strcmp(params[0],"NTCreateX")) {
925 nb_createx(params[1], ival(params[2]), ival(params[3]),
926 ival(params[4]));
927 } else if (!strcmp(params[0],"Close")) {
928 nb_close(ival(params[1]));
929 } else if (!strcmp(params[0],"Rename")) {
930 nb_rename(params[1], params[2]);
931 } else if (!strcmp(params[0],"Unlink")) {
932 nb_unlink(params[1]);
933 } else if (!strcmp(params[0],"Deltree")) {
934 nb_deltree(params[1]);
935 } else if (!strcmp(params[0],"Rmdir")) {
936 nb_rmdir(params[1]);
937 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
938 nb_qpathinfo(params[1]);
939 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
940 nb_qfileinfo(ival(params[1]));
941 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
942 nb_qfsinfo(ival(params[1]));
943 } else if (!strcmp(params[0],"FIND_FIRST")) {
944 nb_findfirst(params[1]);
945 } else if (!strcmp(params[0],"WriteX")) {
946 nb_writex(ival(params[1]),
947 ival(params[2]), ival(params[3]), ival(params[4]));
948 } else if (!strcmp(params[0],"ReadX")) {
949 nb_readx(ival(params[1]),
950 ival(params[2]), ival(params[3]), ival(params[4]));
951 } else if (!strcmp(params[0],"Flush")) {
952 nb_flush(ival(params[1]));
953 } else {
954 printf("Unknown operation %s\n", params[0]);
955 exit(1);
958 fclose(f);
960 nb_cleanup();
962 if (!torture_close_connection(cli)) {
963 correct = False;
966 return correct;
970 /* run a test that simulates an approximate netbench client load */
971 static bool run_nbench(int dummy)
973 double t;
974 bool correct = True;
976 nbio_shmem(nprocs);
978 nbio_id = -1;
980 signal(SIGALRM, nb_alarm);
981 alarm(1);
982 t = create_procs(run_netbench, &correct);
983 alarm(0);
985 printf("\nThroughput %g MB/sec\n",
986 1.0e-6 * nbio_total() / t);
987 return correct;
992 This test checks for two things:
994 1) correct support for retaining locks over a close (ie. the server
995 must not use posix semantics)
996 2) support for lock timeouts
998 static bool run_locktest1(int dummy)
1000 struct cli_state *cli1, *cli2;
1001 const char *fname = "\\lockt1.lck";
1002 uint16_t fnum1, fnum2, fnum3;
1003 time_t t1, t2;
1004 unsigned lock_timeout;
1006 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1007 return False;
1009 cli_sockopt(cli1, sockops);
1010 cli_sockopt(cli2, sockops);
1012 printf("starting locktest1\n");
1014 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1016 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1017 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1018 return False;
1020 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1021 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1022 return False;
1024 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1025 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1026 return False;
1029 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1030 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1031 return False;
1035 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1036 printf("lock2 succeeded! This is a locking bug\n");
1037 return False;
1038 } else {
1039 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1040 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1044 lock_timeout = (1 + (random() % 20));
1045 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1046 t1 = time(NULL);
1047 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1048 printf("lock3 succeeded! This is a locking bug\n");
1049 return False;
1050 } else {
1051 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1052 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1054 t2 = time(NULL);
1056 if (ABS(t2 - t1) < lock_timeout-1) {
1057 printf("error: This server appears not to support timed lock requests\n");
1060 printf("server slept for %u seconds for a %u second timeout\n",
1061 (unsigned int)(t2-t1), lock_timeout);
1063 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1064 printf("close1 failed (%s)\n", cli_errstr(cli1));
1065 return False;
1068 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1069 printf("lock4 succeeded! This is a locking bug\n");
1070 return False;
1071 } else {
1072 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1073 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1076 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1077 printf("close2 failed (%s)\n", cli_errstr(cli1));
1078 return False;
1081 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1082 printf("close3 failed (%s)\n", cli_errstr(cli2));
1083 return False;
1086 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1087 printf("unlink failed (%s)\n", cli_errstr(cli1));
1088 return False;
1092 if (!torture_close_connection(cli1)) {
1093 return False;
1096 if (!torture_close_connection(cli2)) {
1097 return False;
1100 printf("Passed locktest1\n");
1101 return True;
1105 this checks to see if a secondary tconx can use open files from an
1106 earlier tconx
1108 static bool run_tcon_test(int dummy)
1110 static struct cli_state *cli;
1111 const char *fname = "\\tcontest.tmp";
1112 uint16 fnum1;
1113 uint16 cnum1, cnum2, cnum3;
1114 uint16 vuid1, vuid2;
1115 char buf[4];
1116 bool ret = True;
1117 NTSTATUS status;
1119 memset(buf, '\0', sizeof(buf));
1121 if (!torture_open_connection(&cli, 0)) {
1122 return False;
1124 cli_sockopt(cli, sockops);
1126 printf("starting tcontest\n");
1128 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1130 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1131 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1132 return False;
1135 cnum1 = cli->cnum;
1136 vuid1 = cli->vuid;
1138 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1139 printf("initial write failed (%s)", cli_errstr(cli));
1140 return False;
1143 status = cli_tcon_andx(cli, share, "?????",
1144 password, strlen(password)+1);
1145 if (!NT_STATUS_IS_OK(status)) {
1146 printf("%s refused 2nd tree connect (%s)\n", host,
1147 nt_errstr(status));
1148 cli_shutdown(cli);
1149 return False;
1152 cnum2 = cli->cnum;
1153 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1154 vuid2 = cli->vuid + 1;
1156 /* try a write with the wrong tid */
1157 cli->cnum = cnum2;
1159 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1160 printf("* server allows write with wrong TID\n");
1161 ret = False;
1162 } else {
1163 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1167 /* try a write with an invalid tid */
1168 cli->cnum = cnum3;
1170 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1171 printf("* server allows write with invalid TID\n");
1172 ret = False;
1173 } else {
1174 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1177 /* try a write with an invalid vuid */
1178 cli->vuid = vuid2;
1179 cli->cnum = cnum1;
1181 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1182 printf("* server allows write with invalid VUID\n");
1183 ret = False;
1184 } else {
1185 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1188 cli->cnum = cnum1;
1189 cli->vuid = vuid1;
1191 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1192 printf("close failed (%s)\n", cli_errstr(cli));
1193 return False;
1196 cli->cnum = cnum2;
1198 status = cli_tdis(cli);
1199 if (!NT_STATUS_IS_OK(status)) {
1200 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1201 return False;
1204 cli->cnum = cnum1;
1206 if (!torture_close_connection(cli)) {
1207 return False;
1210 return ret;
1215 checks for old style tcon support
1217 static bool run_tcon2_test(int dummy)
1219 static struct cli_state *cli;
1220 uint16 cnum, max_xmit;
1221 char *service;
1222 NTSTATUS status;
1224 if (!torture_open_connection(&cli, 0)) {
1225 return False;
1227 cli_sockopt(cli, sockops);
1229 printf("starting tcon2 test\n");
1231 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1232 return false;
1235 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 printf("tcon2 failed : %s\n", cli_errstr(cli));
1239 } else {
1240 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1241 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1244 if (!torture_close_connection(cli)) {
1245 return False;
1248 printf("Passed tcon2 test\n");
1249 return True;
1252 static bool tcon_devtest(struct cli_state *cli,
1253 const char *myshare, const char *devtype,
1254 const char *return_devtype,
1255 NTSTATUS expected_error)
1257 NTSTATUS status;
1258 bool ret;
1260 status = cli_tcon_andx(cli, myshare, devtype,
1261 password, strlen(password)+1);
1263 if (NT_STATUS_IS_OK(expected_error)) {
1264 if (NT_STATUS_IS_OK(status)) {
1265 if (strcmp(cli->dev, return_devtype) == 0) {
1266 ret = True;
1267 } else {
1268 printf("tconX to share %s with type %s "
1269 "succeeded but returned the wrong "
1270 "device type (got [%s] but should have got [%s])\n",
1271 myshare, devtype, cli->dev, return_devtype);
1272 ret = False;
1274 } else {
1275 printf("tconX to share %s with type %s "
1276 "should have succeeded but failed\n",
1277 myshare, devtype);
1278 ret = False;
1280 cli_tdis(cli);
1281 } else {
1282 if (NT_STATUS_IS_OK(status)) {
1283 printf("tconx to share %s with type %s "
1284 "should have failed but succeeded\n",
1285 myshare, devtype);
1286 ret = False;
1287 } else {
1288 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1289 expected_error)) {
1290 ret = True;
1291 } else {
1292 printf("Returned unexpected error\n");
1293 ret = False;
1297 return ret;
1301 checks for correct tconX support
1303 static bool run_tcon_devtype_test(int dummy)
1305 static struct cli_state *cli1 = NULL;
1306 bool retry;
1307 int flags = 0;
1308 NTSTATUS status;
1309 bool ret = True;
1311 status = cli_full_connection(&cli1, myname,
1312 host, NULL, port_to_use,
1313 NULL, NULL,
1314 username, workgroup,
1315 password, flags, Undefined, &retry);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("could not open connection\n");
1319 return False;
1322 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1323 ret = False;
1325 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1326 ret = False;
1328 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1329 ret = False;
1331 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1332 ret = False;
1334 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1335 ret = False;
1337 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1338 ret = False;
1340 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1341 ret = False;
1343 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1344 ret = False;
1346 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1347 ret = False;
1349 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1350 ret = False;
1352 cli_shutdown(cli1);
1354 if (ret)
1355 printf("Passed tcondevtest\n");
1357 return ret;
1362 This test checks that
1364 1) the server supports multiple locking contexts on the one SMB
1365 connection, distinguished by PID.
1367 2) the server correctly fails overlapping locks made by the same PID (this
1368 goes against POSIX behaviour, which is why it is tricky to implement)
1370 3) the server denies unlock requests by an incorrect client PID
1372 static bool run_locktest2(int dummy)
1374 static struct cli_state *cli;
1375 const char *fname = "\\lockt2.lck";
1376 uint16_t fnum1, fnum2, fnum3;
1377 bool correct = True;
1379 if (!torture_open_connection(&cli, 0)) {
1380 return False;
1383 cli_sockopt(cli, sockops);
1385 printf("starting locktest2\n");
1387 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1389 cli_setpid(cli, 1);
1391 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1392 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1393 return False;
1396 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1397 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1398 return False;
1401 cli_setpid(cli, 2);
1403 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1404 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1405 return False;
1408 cli_setpid(cli, 1);
1410 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1411 printf("lock1 failed (%s)\n", cli_errstr(cli));
1412 return False;
1415 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1416 printf("WRITE lock1 succeeded! This is a locking bug\n");
1417 correct = False;
1418 } else {
1419 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1420 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1423 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1424 printf("WRITE lock2 succeeded! This is a locking bug\n");
1425 correct = False;
1426 } else {
1427 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1428 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1431 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1432 printf("READ lock2 succeeded! This is a locking bug\n");
1433 correct = False;
1434 } else {
1435 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1436 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1439 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1440 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1442 cli_setpid(cli, 2);
1443 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1444 printf("unlock at 100 succeeded! This is a locking bug\n");
1445 correct = False;
1448 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1449 printf("unlock1 succeeded! This is a locking bug\n");
1450 correct = False;
1451 } else {
1452 if (!check_error(__LINE__, cli,
1453 ERRDOS, ERRlock,
1454 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1457 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1458 printf("unlock2 succeeded! This is a locking bug\n");
1459 correct = False;
1460 } else {
1461 if (!check_error(__LINE__, cli,
1462 ERRDOS, ERRlock,
1463 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1466 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1467 printf("lock3 succeeded! This is a locking bug\n");
1468 correct = False;
1469 } else {
1470 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1473 cli_setpid(cli, 1);
1475 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1476 printf("close1 failed (%s)\n", cli_errstr(cli));
1477 return False;
1480 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1481 printf("close2 failed (%s)\n", cli_errstr(cli));
1482 return False;
1485 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1486 printf("close3 failed (%s)\n", cli_errstr(cli));
1487 return False;
1490 if (!torture_close_connection(cli)) {
1491 correct = False;
1494 printf("locktest2 finished\n");
1496 return correct;
1501 This test checks that
1503 1) the server supports the full offset range in lock requests
1505 static bool run_locktest3(int dummy)
1507 static struct cli_state *cli1, *cli2;
1508 const char *fname = "\\lockt3.lck";
1509 uint16_t fnum1, fnum2;
1510 int i;
1511 uint32 offset;
1512 bool correct = True;
1514 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1516 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1517 return False;
1519 cli_sockopt(cli1, sockops);
1520 cli_sockopt(cli2, sockops);
1522 printf("starting locktest3\n");
1524 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1526 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1527 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1528 return False;
1530 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1531 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1532 return False;
1535 for (offset=i=0;i<torture_numops;i++) {
1536 NEXT_OFFSET;
1537 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1538 printf("lock1 %d failed (%s)\n",
1540 cli_errstr(cli1));
1541 return False;
1544 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1545 printf("lock2 %d failed (%s)\n",
1547 cli_errstr(cli1));
1548 return False;
1552 for (offset=i=0;i<torture_numops;i++) {
1553 NEXT_OFFSET;
1555 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1556 printf("error: lock1 %d succeeded!\n", i);
1557 return False;
1560 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1561 printf("error: lock2 %d succeeded!\n", i);
1562 return False;
1565 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1566 printf("error: lock3 %d succeeded!\n", i);
1567 return False;
1570 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1571 printf("error: lock4 %d succeeded!\n", i);
1572 return False;
1576 for (offset=i=0;i<torture_numops;i++) {
1577 NEXT_OFFSET;
1579 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1580 printf("unlock1 %d failed (%s)\n",
1582 cli_errstr(cli1));
1583 return False;
1586 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1587 printf("unlock2 %d failed (%s)\n",
1589 cli_errstr(cli1));
1590 return False;
1594 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1595 printf("close1 failed (%s)\n", cli_errstr(cli1));
1596 return False;
1599 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1600 printf("close2 failed (%s)\n", cli_errstr(cli2));
1601 return False;
1604 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1605 printf("unlink failed (%s)\n", cli_errstr(cli1));
1606 return False;
1609 if (!torture_close_connection(cli1)) {
1610 correct = False;
1613 if (!torture_close_connection(cli2)) {
1614 correct = False;
1617 printf("finished locktest3\n");
1619 return correct;
1622 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1623 printf("** "); correct = False; \
1627 looks at overlapping locks
1629 static bool run_locktest4(int dummy)
1631 static struct cli_state *cli1, *cli2;
1632 const char *fname = "\\lockt4.lck";
1633 uint16_t fnum1, fnum2, f;
1634 bool ret;
1635 char buf[1000];
1636 bool correct = True;
1638 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1639 return False;
1642 cli_sockopt(cli1, sockops);
1643 cli_sockopt(cli2, sockops);
1645 printf("starting locktest4\n");
1647 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1649 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1650 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1652 memset(buf, 0, sizeof(buf));
1654 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1655 printf("Failed to create file\n");
1656 correct = False;
1657 goto fail;
1660 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1661 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1662 EXPECTED(ret, False);
1663 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1665 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1666 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1667 EXPECTED(ret, True);
1668 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1670 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1671 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1672 EXPECTED(ret, False);
1673 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1675 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1676 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1677 EXPECTED(ret, True);
1678 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1680 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1681 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1682 EXPECTED(ret, False);
1683 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1685 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1686 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1687 EXPECTED(ret, True);
1688 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1690 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1691 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1692 EXPECTED(ret, True);
1693 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1695 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1696 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1697 EXPECTED(ret, False);
1698 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1700 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1701 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1702 EXPECTED(ret, False);
1703 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1705 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1706 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1707 EXPECTED(ret, True);
1708 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1710 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1711 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1712 EXPECTED(ret, False);
1713 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1715 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1716 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1717 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1718 EXPECTED(ret, False);
1719 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1722 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1723 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1724 EXPECTED(ret, False);
1725 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1727 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1728 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1729 EXPECTED(ret, False);
1730 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1733 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1734 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1735 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1736 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1737 EXPECTED(ret, True);
1738 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1741 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1742 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1743 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1744 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1745 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1746 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1747 EXPECTED(ret, True);
1748 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1750 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1751 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1752 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1753 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1754 EXPECTED(ret, True);
1755 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1757 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1758 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1759 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1760 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1761 EXPECTED(ret, True);
1762 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1764 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1765 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1766 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1767 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1768 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1769 EXPECTED(ret, True);
1770 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1772 cli_close(cli1, fnum1);
1773 cli_close(cli2, fnum2);
1774 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1775 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1776 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1777 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1778 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1779 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1780 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1781 cli_close(cli1, f);
1782 cli_close(cli1, fnum1);
1783 EXPECTED(ret, True);
1784 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1786 fail:
1787 cli_close(cli1, fnum1);
1788 cli_close(cli2, fnum2);
1789 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1790 torture_close_connection(cli1);
1791 torture_close_connection(cli2);
1793 printf("finished locktest4\n");
1794 return correct;
1798 looks at lock upgrade/downgrade.
1800 static bool run_locktest5(int dummy)
1802 static struct cli_state *cli1, *cli2;
1803 const char *fname = "\\lockt5.lck";
1804 uint16_t fnum1, fnum2, fnum3;
1805 bool ret;
1806 char buf[1000];
1807 bool correct = True;
1809 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1810 return False;
1813 cli_sockopt(cli1, sockops);
1814 cli_sockopt(cli2, sockops);
1816 printf("starting locktest5\n");
1818 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1820 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1821 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1822 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1824 memset(buf, 0, sizeof(buf));
1826 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1827 printf("Failed to create file\n");
1828 correct = False;
1829 goto fail;
1832 /* Check for NT bug... */
1833 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1834 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1835 cli_close(cli1, fnum1);
1836 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1837 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1838 EXPECTED(ret, True);
1839 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1840 cli_close(cli1, fnum1);
1841 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1842 cli_unlock(cli1, fnum3, 0, 1);
1844 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1845 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1846 EXPECTED(ret, True);
1847 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1849 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1850 EXPECTED(ret, False);
1852 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1854 /* Unlock the process 2 lock. */
1855 cli_unlock(cli2, fnum2, 0, 4);
1857 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1858 EXPECTED(ret, False);
1860 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1862 /* Unlock the process 1 fnum3 lock. */
1863 cli_unlock(cli1, fnum3, 0, 4);
1865 /* Stack 2 more locks here. */
1866 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1867 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1869 EXPECTED(ret, True);
1870 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1872 /* Unlock the first process lock, then check this was the WRITE lock that was
1873 removed. */
1875 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1876 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1878 EXPECTED(ret, True);
1879 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1881 /* Unlock the process 2 lock. */
1882 cli_unlock(cli2, fnum2, 0, 4);
1884 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1886 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1887 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1888 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1890 EXPECTED(ret, True);
1891 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1893 /* Ensure the next unlock fails. */
1894 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1895 EXPECTED(ret, False);
1896 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1898 /* Ensure connection 2 can get a write lock. */
1899 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1900 EXPECTED(ret, True);
1902 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1905 fail:
1906 cli_close(cli1, fnum1);
1907 cli_close(cli2, fnum2);
1908 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1909 if (!torture_close_connection(cli1)) {
1910 correct = False;
1912 if (!torture_close_connection(cli2)) {
1913 correct = False;
1916 printf("finished locktest5\n");
1918 return correct;
1922 tries the unusual lockingX locktype bits
1924 static bool run_locktest6(int dummy)
1926 static struct cli_state *cli;
1927 const char *fname[1] = { "\\lock6.txt" };
1928 int i;
1929 uint16_t fnum;
1930 NTSTATUS status;
1932 if (!torture_open_connection(&cli, 0)) {
1933 return False;
1936 cli_sockopt(cli, sockops);
1938 printf("starting locktest6\n");
1940 for (i=0;i<1;i++) {
1941 printf("Testing %s\n", fname[i]);
1943 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1945 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1946 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1947 cli_close(cli, fnum);
1948 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1950 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1951 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1952 cli_close(cli, fnum);
1953 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1955 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1958 torture_close_connection(cli);
1960 printf("finished locktest6\n");
1961 return True;
1964 static bool run_locktest7(int dummy)
1966 struct cli_state *cli1;
1967 const char *fname = "\\lockt7.lck";
1968 uint16_t fnum1;
1969 char buf[200];
1970 bool correct = False;
1972 if (!torture_open_connection(&cli1, 0)) {
1973 return False;
1976 cli_sockopt(cli1, sockops);
1978 printf("starting locktest7\n");
1980 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1982 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1984 memset(buf, 0, sizeof(buf));
1986 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1987 printf("Failed to create file\n");
1988 goto fail;
1991 cli_setpid(cli1, 1);
1993 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1994 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1995 goto fail;
1996 } else {
1997 printf("pid1 successfully locked range 130:4 for READ\n");
2000 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2001 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2002 goto fail;
2003 } else {
2004 printf("pid1 successfully read the range 130:4\n");
2007 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2008 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2009 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2010 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2011 goto fail;
2013 } else {
2014 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2015 goto fail;
2018 cli_setpid(cli1, 2);
2020 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2021 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2022 } else {
2023 printf("pid2 successfully read the range 130:4\n");
2026 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2027 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2028 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2029 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2030 goto fail;
2032 } else {
2033 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2034 goto fail;
2037 cli_setpid(cli1, 1);
2038 cli_unlock(cli1, fnum1, 130, 4);
2040 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2041 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2042 goto fail;
2043 } else {
2044 printf("pid1 successfully locked range 130:4 for WRITE\n");
2047 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2048 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2049 goto fail;
2050 } else {
2051 printf("pid1 successfully read the range 130:4\n");
2054 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2055 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2056 goto fail;
2057 } else {
2058 printf("pid1 successfully wrote to the range 130:4\n");
2061 cli_setpid(cli1, 2);
2063 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2064 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2065 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2066 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2067 goto fail;
2069 } else {
2070 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2071 goto fail;
2074 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2075 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2076 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2077 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2078 goto fail;
2080 } else {
2081 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2082 goto fail;
2085 cli_unlock(cli1, fnum1, 130, 0);
2086 correct = True;
2088 fail:
2089 cli_close(cli1, fnum1);
2090 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2091 torture_close_connection(cli1);
2093 printf("finished locktest7\n");
2094 return correct;
2098 * This demonstrates a problem with our use of GPFS share modes: A file
2099 * descriptor sitting in the pending close queue holding a GPFS share mode
2100 * blocks opening a file another time. Happens with Word 2007 temp files.
2101 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2102 * open is denied with NT_STATUS_SHARING_VIOLATION.
2105 static bool run_locktest8(int dummy)
2107 struct cli_state *cli1;
2108 const char *fname = "\\lockt8.lck";
2109 uint16_t fnum1, fnum2;
2110 char buf[200];
2111 bool correct = False;
2112 NTSTATUS status;
2114 if (!torture_open_connection(&cli1, 0)) {
2115 return False;
2118 cli_sockopt(cli1, sockops);
2120 printf("starting locktest8\n");
2122 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2124 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2125 &fnum1);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2128 return false;
2131 memset(buf, 0, sizeof(buf));
2133 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2134 if (!NT_STATUS_IS_OK(status)) {
2135 d_fprintf(stderr, "cli_open second time returned %s\n",
2136 cli_errstr(cli1));
2137 goto fail;
2140 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2141 printf("Unable to apply read lock on range 1:1, error was "
2142 "%s\n", cli_errstr(cli1));
2143 goto fail;
2146 status = cli_close(cli1, fnum1);
2147 if (!NT_STATUS_IS_OK(status)) {
2148 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2149 goto fail;
2152 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2153 if (!NT_STATUS_IS_OK(status)) {
2154 d_fprintf(stderr, "cli_open third time returned %s\n",
2155 cli_errstr(cli1));
2156 goto fail;
2159 correct = true;
2161 fail:
2162 cli_close(cli1, fnum1);
2163 cli_close(cli1, fnum2);
2164 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2165 torture_close_connection(cli1);
2167 printf("finished locktest8\n");
2168 return correct;
2172 * This test is designed to be run in conjunction with
2173 * external NFS or POSIX locks taken in the filesystem.
2174 * It checks that the smbd server will block until the
2175 * lock is released and then acquire it. JRA.
2178 static bool got_alarm;
2179 static int alarm_fd;
2181 static void alarm_handler(int dummy)
2183 got_alarm = True;
2186 static void alarm_handler_parent(int dummy)
2188 close(alarm_fd);
2191 static void do_local_lock(int read_fd, int write_fd)
2193 int fd;
2194 char c = '\0';
2195 struct flock lock;
2196 const char *local_pathname = NULL;
2197 int ret;
2199 local_pathname = talloc_asprintf(talloc_tos(),
2200 "%s/lockt9.lck", local_path);
2201 if (!local_pathname) {
2202 printf("child: alloc fail\n");
2203 exit(1);
2206 unlink(local_pathname);
2207 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2208 if (fd == -1) {
2209 printf("child: open of %s failed %s.\n",
2210 local_pathname, strerror(errno));
2211 exit(1);
2214 /* Now take a fcntl lock. */
2215 lock.l_type = F_WRLCK;
2216 lock.l_whence = SEEK_SET;
2217 lock.l_start = 0;
2218 lock.l_len = 4;
2219 lock.l_pid = getpid();
2221 ret = fcntl(fd,F_SETLK,&lock);
2222 if (ret == -1) {
2223 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2224 local_pathname, strerror(errno));
2225 exit(1);
2226 } else {
2227 printf("child: got lock 0:4 on file %s.\n",
2228 local_pathname );
2229 fflush(stdout);
2232 CatchSignal(SIGALRM, alarm_handler);
2233 alarm(5);
2234 /* Signal the parent. */
2235 if (write(write_fd, &c, 1) != 1) {
2236 printf("child: start signal fail %s.\n",
2237 strerror(errno));
2238 exit(1);
2240 alarm(0);
2242 alarm(10);
2243 /* Wait for the parent to be ready. */
2244 if (read(read_fd, &c, 1) != 1) {
2245 printf("child: reply signal fail %s.\n",
2246 strerror(errno));
2247 exit(1);
2249 alarm(0);
2251 sleep(5);
2252 close(fd);
2253 printf("child: released lock 0:4 on file %s.\n",
2254 local_pathname );
2255 fflush(stdout);
2256 exit(0);
2259 static bool run_locktest9(int dummy)
2261 struct cli_state *cli1;
2262 const char *fname = "\\lockt9.lck";
2263 uint16_t fnum;
2264 bool correct = False;
2265 int pipe_in[2], pipe_out[2];
2266 pid_t child_pid;
2267 char c = '\0';
2268 int ret;
2269 struct timeval start;
2270 double seconds;
2271 NTSTATUS status;
2273 printf("starting locktest9\n");
2275 if (local_path == NULL) {
2276 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2277 return false;
2280 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2281 return false;
2284 child_pid = fork();
2285 if (child_pid == -1) {
2286 return false;
2289 if (child_pid == 0) {
2290 /* Child. */
2291 do_local_lock(pipe_out[0], pipe_in[1]);
2292 exit(0);
2295 close(pipe_out[0]);
2296 close(pipe_in[1]);
2297 pipe_out[0] = -1;
2298 pipe_in[1] = -1;
2300 /* Parent. */
2301 ret = read(pipe_in[0], &c, 1);
2302 if (ret != 1) {
2303 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2304 strerror(errno));
2305 return false;
2308 if (!torture_open_connection(&cli1, 0)) {
2309 return false;
2312 cli_sockopt(cli1, sockops);
2314 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2315 &fnum);
2316 if (!NT_STATUS_IS_OK(status)) {
2317 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2318 return false;
2321 /* Ensure the child has the lock. */
2322 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2323 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2324 goto fail;
2325 } else {
2326 d_printf("Child has the lock.\n");
2329 /* Tell the child to wait 5 seconds then exit. */
2330 ret = write(pipe_out[1], &c, 1);
2331 if (ret != 1) {
2332 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2333 strerror(errno));
2334 goto fail;
2337 /* Wait 20 seconds for the lock. */
2338 alarm_fd = cli1->fd;
2339 CatchSignal(SIGALRM, alarm_handler_parent);
2340 alarm(20);
2342 start = timeval_current();
2344 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2345 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2346 "%s\n", cli_errstr(cli1));
2347 goto fail_nofd;
2349 alarm(0);
2351 seconds = timeval_elapsed(&start);
2353 printf("Parent got the lock after %.2f seconds.\n",
2354 seconds);
2356 status = cli_close(cli1, fnum);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2359 goto fail;
2362 correct = true;
2364 fail:
2365 cli_close(cli1, fnum);
2366 torture_close_connection(cli1);
2368 fail_nofd:
2370 printf("finished locktest9\n");
2371 return correct;
2375 test whether fnums and tids open on one VC are available on another (a major
2376 security hole)
2378 static bool run_fdpasstest(int dummy)
2380 struct cli_state *cli1, *cli2;
2381 const char *fname = "\\fdpass.tst";
2382 uint16_t fnum1;
2383 char buf[1024];
2385 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2386 return False;
2388 cli_sockopt(cli1, sockops);
2389 cli_sockopt(cli2, sockops);
2391 printf("starting fdpasstest\n");
2393 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2395 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2396 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2397 return False;
2400 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2401 printf("write failed (%s)\n", cli_errstr(cli1));
2402 return False;
2405 cli2->vuid = cli1->vuid;
2406 cli2->cnum = cli1->cnum;
2407 cli2->pid = cli1->pid;
2409 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2410 printf("read succeeded! nasty security hole [%s]\n",
2411 buf);
2412 return False;
2415 cli_close(cli1, fnum1);
2416 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2418 torture_close_connection(cli1);
2419 torture_close_connection(cli2);
2421 printf("finished fdpasstest\n");
2422 return True;
2425 static bool run_fdsesstest(int dummy)
2427 struct cli_state *cli;
2428 uint16 new_vuid;
2429 uint16 saved_vuid;
2430 uint16 new_cnum;
2431 uint16 saved_cnum;
2432 const char *fname = "\\fdsess.tst";
2433 const char *fname1 = "\\fdsess1.tst";
2434 uint16_t fnum1;
2435 uint16_t fnum2;
2436 char buf[1024];
2437 bool ret = True;
2439 if (!torture_open_connection(&cli, 0))
2440 return False;
2441 cli_sockopt(cli, sockops);
2443 if (!torture_cli_session_setup2(cli, &new_vuid))
2444 return False;
2446 saved_cnum = cli->cnum;
2447 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2448 return False;
2449 new_cnum = cli->cnum;
2450 cli->cnum = saved_cnum;
2452 printf("starting fdsesstest\n");
2454 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2455 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2457 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2458 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2459 return False;
2462 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2463 printf("write failed (%s)\n", cli_errstr(cli));
2464 return False;
2467 saved_vuid = cli->vuid;
2468 cli->vuid = new_vuid;
2470 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2471 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2472 buf);
2473 ret = False;
2475 /* Try to open a file with different vuid, samba cnum. */
2476 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2477 printf("create with different vuid, same cnum succeeded.\n");
2478 cli_close(cli, fnum2);
2479 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2480 } else {
2481 printf("create with different vuid, same cnum failed.\n");
2482 printf("This will cause problems with service clients.\n");
2483 ret = False;
2486 cli->vuid = saved_vuid;
2488 /* Try with same vuid, different cnum. */
2489 cli->cnum = new_cnum;
2491 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2492 printf("read succeeded with different cnum![%s]\n",
2493 buf);
2494 ret = False;
2497 cli->cnum = saved_cnum;
2498 cli_close(cli, fnum1);
2499 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2501 torture_close_connection(cli);
2503 printf("finished fdsesstest\n");
2504 return ret;
2508 This test checks that
2510 1) the server does not allow an unlink on a file that is open
2512 static bool run_unlinktest(int dummy)
2514 struct cli_state *cli;
2515 const char *fname = "\\unlink.tst";
2516 uint16_t fnum;
2517 bool correct = True;
2519 if (!torture_open_connection(&cli, 0)) {
2520 return False;
2523 cli_sockopt(cli, sockops);
2525 printf("starting unlink test\n");
2527 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2529 cli_setpid(cli, 1);
2531 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2532 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2533 return False;
2536 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2537 printf("error: server allowed unlink on an open file\n");
2538 correct = False;
2539 } else {
2540 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2541 NT_STATUS_SHARING_VIOLATION);
2544 cli_close(cli, fnum);
2545 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2547 if (!torture_close_connection(cli)) {
2548 correct = False;
2551 printf("unlink test finished\n");
2553 return correct;
2558 test how many open files this server supports on the one socket
2560 static bool run_maxfidtest(int dummy)
2562 struct cli_state *cli;
2563 const char *ftemplate = "\\maxfid.%d.%d";
2564 fstring fname;
2565 uint16_t fnums[0x11000];
2566 int i;
2567 int retries=4;
2568 bool correct = True;
2570 cli = current_cli;
2572 if (retries <= 0) {
2573 printf("failed to connect\n");
2574 return False;
2577 cli_sockopt(cli, sockops);
2579 for (i=0; i<0x11000; i++) {
2580 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2581 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2582 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2583 printf("open of %s failed (%s)\n",
2584 fname, cli_errstr(cli));
2585 printf("maximum fnum is %d\n", i);
2586 break;
2588 printf("%6d\r", i);
2590 printf("%6d\n", i);
2591 i--;
2593 printf("cleaning up\n");
2594 for (;i>=0;i--) {
2595 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2596 cli_close(cli, fnums[i]);
2597 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2598 printf("unlink of %s failed (%s)\n",
2599 fname, cli_errstr(cli));
2600 correct = False;
2602 printf("%6d\r", i);
2604 printf("%6d\n", 0);
2606 printf("maxfid test finished\n");
2607 if (!torture_close_connection(cli)) {
2608 correct = False;
2610 return correct;
2613 /* generate a random buffer */
2614 static void rand_buf(char *buf, int len)
2616 while (len--) {
2617 *buf = (char)sys_random();
2618 buf++;
2622 /* send smb negprot commands, not reading the response */
2623 static bool run_negprot_nowait(int dummy)
2625 int i;
2626 static struct cli_state *cli;
2627 bool correct = True;
2629 printf("starting negprot nowait test\n");
2631 if (!(cli = open_nbt_connection())) {
2632 return False;
2635 for (i=0;i<50000;i++) {
2636 cli_negprot_sendsync(cli);
2639 if (!torture_close_connection(cli)) {
2640 correct = False;
2643 printf("finished negprot nowait test\n");
2645 return correct;
2649 /* send random IPC commands */
2650 static bool run_randomipc(int dummy)
2652 char *rparam = NULL;
2653 char *rdata = NULL;
2654 unsigned int rdrcnt,rprcnt;
2655 char param[1024];
2656 int api, param_len, i;
2657 struct cli_state *cli;
2658 bool correct = True;
2659 int count = 50000;
2661 printf("starting random ipc test\n");
2663 if (!torture_open_connection(&cli, 0)) {
2664 return False;
2667 for (i=0;i<count;i++) {
2668 api = sys_random() % 500;
2669 param_len = (sys_random() % 64);
2671 rand_buf(param, param_len);
2673 SSVAL(param,0,api);
2675 cli_api(cli,
2676 param, param_len, 8,
2677 NULL, 0, BUFFER_SIZE,
2678 &rparam, &rprcnt,
2679 &rdata, &rdrcnt);
2680 if (i % 100 == 0) {
2681 printf("%d/%d\r", i,count);
2684 printf("%d/%d\n", i, count);
2686 if (!torture_close_connection(cli)) {
2687 correct = False;
2690 printf("finished random ipc test\n");
2692 return correct;
2697 static void browse_callback(const char *sname, uint32 stype,
2698 const char *comment, void *state)
2700 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2706 This test checks the browse list code
2709 static bool run_browsetest(int dummy)
2711 static struct cli_state *cli;
2712 bool correct = True;
2714 printf("starting browse test\n");
2716 if (!torture_open_connection(&cli, 0)) {
2717 return False;
2720 printf("domain list:\n");
2721 cli_NetServerEnum(cli, cli->server_domain,
2722 SV_TYPE_DOMAIN_ENUM,
2723 browse_callback, NULL);
2725 printf("machine list:\n");
2726 cli_NetServerEnum(cli, cli->server_domain,
2727 SV_TYPE_ALL,
2728 browse_callback, NULL);
2730 if (!torture_close_connection(cli)) {
2731 correct = False;
2734 printf("browse test finished\n");
2736 return correct;
2742 This checks how the getatr calls works
2744 static bool run_attrtest(int dummy)
2746 struct cli_state *cli;
2747 uint16_t fnum;
2748 time_t t, t2;
2749 const char *fname = "\\attrib123456789.tst";
2750 bool correct = True;
2752 printf("starting attrib test\n");
2754 if (!torture_open_connection(&cli, 0)) {
2755 return False;
2758 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2759 cli_open(cli, fname,
2760 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2761 cli_close(cli, fnum);
2762 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2763 printf("getatr failed (%s)\n", cli_errstr(cli));
2764 correct = False;
2767 if (abs(t - time(NULL)) > 60*60*24*10) {
2768 printf("ERROR: SMBgetatr bug. time is %s",
2769 ctime(&t));
2770 t = time(NULL);
2771 correct = True;
2774 t2 = t-60*60*24; /* 1 day ago */
2776 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2777 printf("setatr failed (%s)\n", cli_errstr(cli));
2778 correct = True;
2781 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2782 printf("getatr failed (%s)\n", cli_errstr(cli));
2783 correct = True;
2786 if (t != t2) {
2787 printf("ERROR: getatr/setatr bug. times are\n%s",
2788 ctime(&t));
2789 printf("%s", ctime(&t2));
2790 correct = True;
2793 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2795 if (!torture_close_connection(cli)) {
2796 correct = False;
2799 printf("attrib test finished\n");
2801 return correct;
2806 This checks a couple of trans2 calls
2808 static bool run_trans2test(int dummy)
2810 struct cli_state *cli;
2811 uint16_t fnum;
2812 SMB_OFF_T size;
2813 time_t c_time, a_time, m_time;
2814 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2815 const char *fname = "\\trans2.tst";
2816 const char *dname = "\\trans2";
2817 const char *fname2 = "\\trans2\\trans2.tst";
2818 char pname[1024];
2819 bool correct = True;
2820 NTSTATUS status;
2821 uint32_t fs_attr;
2823 printf("starting trans2 test\n");
2825 if (!torture_open_connection(&cli, 0)) {
2826 return False;
2829 status = cli_get_fs_attr_info(cli, &fs_attr);
2830 if (!NT_STATUS_IS_OK(status)) {
2831 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2832 nt_errstr(status));
2833 correct = false;
2836 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2837 cli_open(cli, fname,
2838 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2839 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2840 &m_time_ts, NULL)) {
2841 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2842 correct = False;
2845 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2846 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2847 correct = False;
2850 if (strcmp(pname, fname)) {
2851 printf("qfilename gave different name? [%s] [%s]\n",
2852 fname, pname);
2853 correct = False;
2856 cli_close(cli, fnum);
2858 sleep(2);
2860 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2861 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2862 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2863 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2864 return False;
2866 cli_close(cli, fnum);
2868 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2869 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2870 correct = False;
2871 } else {
2872 if (c_time != m_time) {
2873 printf("create time=%s", ctime(&c_time));
2874 printf("modify time=%s", ctime(&m_time));
2875 printf("This system appears to have sticky create times\n");
2877 if (a_time % (60*60) == 0) {
2878 printf("access time=%s", ctime(&a_time));
2879 printf("This system appears to set a midnight access time\n");
2880 correct = False;
2883 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2884 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2885 correct = False;
2890 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2891 cli_open(cli, fname,
2892 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2893 cli_close(cli, fnum);
2894 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2895 &m_time_ts, &size, NULL, NULL)) {
2896 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2897 correct = False;
2898 } else {
2899 if (w_time_ts.tv_sec < 60*60*24*2) {
2900 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2901 printf("This system appears to set a initial 0 write time\n");
2902 correct = False;
2906 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2909 /* check if the server updates the directory modification time
2910 when creating a new file */
2911 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2912 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2913 correct = False;
2915 sleep(3);
2916 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2917 &m_time_ts, &size, NULL, NULL)) {
2918 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2919 correct = False;
2922 cli_open(cli, fname2,
2923 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2924 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2925 cli_close(cli, fnum);
2926 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2927 &m_time2_ts, &size, NULL, NULL)) {
2928 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2929 correct = False;
2930 } else {
2931 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2932 == 0) {
2933 printf("This system does not update directory modification times\n");
2934 correct = False;
2937 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2938 cli_rmdir(cli, dname);
2940 if (!torture_close_connection(cli)) {
2941 correct = False;
2944 printf("trans2 test finished\n");
2946 return correct;
2950 This checks new W2K calls.
2953 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2955 char *buf = NULL;
2956 uint32 len;
2957 bool correct = True;
2959 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2960 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2961 correct = False;
2962 } else {
2963 printf("qfileinfo: level %d, len = %u\n", level, len);
2964 dump_data(0, (uint8 *)buf, len);
2965 printf("\n");
2967 SAFE_FREE(buf);
2968 return correct;
2971 static bool run_w2ktest(int dummy)
2973 struct cli_state *cli;
2974 uint16_t fnum;
2975 const char *fname = "\\w2ktest\\w2k.tst";
2976 int level;
2977 bool correct = True;
2979 printf("starting w2k test\n");
2981 if (!torture_open_connection(&cli, 0)) {
2982 return False;
2985 cli_open(cli, fname,
2986 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2988 for (level = 1004; level < 1040; level++) {
2989 new_trans(cli, fnum, level);
2992 cli_close(cli, fnum);
2994 if (!torture_close_connection(cli)) {
2995 correct = False;
2998 printf("w2k test finished\n");
3000 return correct;
3005 this is a harness for some oplock tests
3007 static bool run_oplock1(int dummy)
3009 struct cli_state *cli1;
3010 const char *fname = "\\lockt1.lck";
3011 uint16_t fnum1;
3012 bool correct = True;
3014 printf("starting oplock test 1\n");
3016 if (!torture_open_connection(&cli1, 0)) {
3017 return False;
3020 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3022 cli_sockopt(cli1, sockops);
3024 cli1->use_oplocks = True;
3026 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3027 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3028 return False;
3031 cli1->use_oplocks = False;
3033 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3034 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3036 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3037 printf("close2 failed (%s)\n", cli_errstr(cli1));
3038 return False;
3041 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3042 printf("unlink failed (%s)\n", cli_errstr(cli1));
3043 return False;
3046 if (!torture_close_connection(cli1)) {
3047 correct = False;
3050 printf("finished oplock test 1\n");
3052 return correct;
3055 static bool run_oplock2(int dummy)
3057 struct cli_state *cli1, *cli2;
3058 const char *fname = "\\lockt2.lck";
3059 uint16_t fnum1, fnum2;
3060 int saved_use_oplocks = use_oplocks;
3061 char buf[4];
3062 bool correct = True;
3063 volatile bool *shared_correct;
3065 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3066 *shared_correct = True;
3068 use_level_II_oplocks = True;
3069 use_oplocks = True;
3071 printf("starting oplock test 2\n");
3073 if (!torture_open_connection(&cli1, 0)) {
3074 use_level_II_oplocks = False;
3075 use_oplocks = saved_use_oplocks;
3076 return False;
3079 cli1->use_oplocks = True;
3080 cli1->use_level_II_oplocks = True;
3082 if (!torture_open_connection(&cli2, 1)) {
3083 use_level_II_oplocks = False;
3084 use_oplocks = saved_use_oplocks;
3085 return False;
3088 cli2->use_oplocks = True;
3089 cli2->use_level_II_oplocks = True;
3091 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3093 cli_sockopt(cli1, sockops);
3094 cli_sockopt(cli2, sockops);
3096 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3097 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3098 return False;
3101 /* Don't need the globals any more. */
3102 use_level_II_oplocks = False;
3103 use_oplocks = saved_use_oplocks;
3105 if (fork() == 0) {
3106 /* Child code */
3107 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3108 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3109 *shared_correct = False;
3110 exit(0);
3113 sleep(2);
3115 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3116 printf("close2 failed (%s)\n", cli_errstr(cli1));
3117 *shared_correct = False;
3120 exit(0);
3123 sleep(2);
3125 /* Ensure cli1 processes the break. Empty file should always return 0
3126 * bytes. */
3128 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3129 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3130 correct = False;
3133 /* Should now be at level II. */
3134 /* Test if sending a write locks causes a break to none. */
3136 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3137 printf("lock failed (%s)\n", cli_errstr(cli1));
3138 correct = False;
3141 cli_unlock(cli1, fnum1, 0, 4);
3143 sleep(2);
3145 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3146 printf("lock failed (%s)\n", cli_errstr(cli1));
3147 correct = False;
3150 cli_unlock(cli1, fnum1, 0, 4);
3152 sleep(2);
3154 cli_read(cli1, fnum1, buf, 0, 4);
3156 #if 0
3157 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3158 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3159 correct = False;
3161 #endif
3163 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3164 printf("close1 failed (%s)\n", cli_errstr(cli1));
3165 correct = False;
3168 sleep(4);
3170 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3171 printf("unlink failed (%s)\n", cli_errstr(cli1));
3172 correct = False;
3175 if (!torture_close_connection(cli1)) {
3176 correct = False;
3179 if (!*shared_correct) {
3180 correct = False;
3183 printf("finished oplock test 2\n");
3185 return correct;
3188 /* handler for oplock 3 tests */
3189 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3191 printf("got oplock break fnum=%d level=%d\n",
3192 fnum, level);
3193 return cli_oplock_ack(cli, fnum, level);
3196 static bool run_oplock3(int dummy)
3198 struct cli_state *cli;
3199 const char *fname = "\\oplockt3.dat";
3200 uint16_t fnum;
3201 char buf[4] = "abcd";
3202 bool correct = True;
3203 volatile bool *shared_correct;
3205 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3206 *shared_correct = True;
3208 printf("starting oplock test 3\n");
3210 if (fork() == 0) {
3211 /* Child code */
3212 use_oplocks = True;
3213 use_level_II_oplocks = True;
3214 if (!torture_open_connection(&cli, 0)) {
3215 *shared_correct = False;
3216 exit(0);
3218 sleep(2);
3219 /* try to trigger a oplock break in parent */
3220 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3221 cli_write(cli, fnum, 0, buf, 0, 4);
3222 exit(0);
3225 /* parent code */
3226 use_oplocks = True;
3227 use_level_II_oplocks = True;
3228 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3229 return False;
3231 cli_oplock_handler(cli, oplock3_handler);
3232 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3233 cli_write(cli, fnum, 0, buf, 0, 4);
3234 cli_close(cli, fnum);
3235 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3236 cli->timeout = 20000;
3237 cli_receive_smb(cli);
3238 printf("finished oplock test 3\n");
3240 return (correct && *shared_correct);
3242 /* What are we looking for here? What's sucess and what's FAILURE? */
3248 Test delete on close semantics.
3250 static bool run_deletetest(int dummy)
3252 struct cli_state *cli1 = NULL;
3253 struct cli_state *cli2 = NULL;
3254 const char *fname = "\\delete.file";
3255 uint16_t fnum1 = (uint16_t)-1;
3256 uint16_t fnum2 = (uint16_t)-1;
3257 bool correct = True;
3259 printf("starting delete test\n");
3261 if (!torture_open_connection(&cli1, 0)) {
3262 return False;
3265 cli_sockopt(cli1, sockops);
3267 /* Test 1 - this should delete the file on close. */
3269 cli_setatr(cli1, fname, 0, 0);
3270 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3272 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3273 0, FILE_OVERWRITE_IF,
3274 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3275 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3276 correct = False;
3277 goto fail;
3280 #if 0 /* JRATEST */
3282 uint32 *accinfo = NULL;
3283 uint32 len;
3284 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3285 if (accinfo)
3286 printf("access mode = 0x%lx\n", *accinfo);
3287 SAFE_FREE(accinfo);
3289 #endif
3291 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3292 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3293 correct = False;
3294 goto fail;
3297 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3298 printf("[1] open of %s succeeded (should fail)\n", fname);
3299 correct = False;
3300 goto fail;
3303 printf("first delete on close test succeeded.\n");
3305 /* Test 2 - this should delete the file on close. */
3307 cli_setatr(cli1, fname, 0, 0);
3308 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3310 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3311 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3312 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3313 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3314 correct = False;
3315 goto fail;
3318 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3319 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3320 correct = False;
3321 goto fail;
3324 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3325 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3326 correct = False;
3327 goto fail;
3330 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3331 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3332 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3333 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3334 correct = False;
3335 goto fail;
3337 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3338 } else
3339 printf("second delete on close test succeeded.\n");
3341 /* Test 3 - ... */
3342 cli_setatr(cli1, fname, 0, 0);
3343 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3345 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3346 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3347 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3348 correct = False;
3349 goto fail;
3352 /* This should fail with a sharing violation - open for delete is only compatible
3353 with SHARE_DELETE. */
3355 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3356 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3357 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3358 correct = False;
3359 goto fail;
3362 /* This should succeed. */
3364 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3365 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3366 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3367 correct = False;
3368 goto fail;
3371 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3372 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3373 correct = False;
3374 goto fail;
3377 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3378 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3379 correct = False;
3380 goto fail;
3383 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3384 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3385 correct = False;
3386 goto fail;
3389 /* This should fail - file should no longer be there. */
3391 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3392 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3393 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3394 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3396 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3397 correct = False;
3398 goto fail;
3399 } else
3400 printf("third delete on close test succeeded.\n");
3402 /* Test 4 ... */
3403 cli_setatr(cli1, fname, 0, 0);
3404 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3406 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3407 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3408 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3409 correct = False;
3410 goto fail;
3413 /* This should succeed. */
3414 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3415 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3416 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3417 correct = False;
3418 goto fail;
3421 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3422 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3423 correct = False;
3424 goto fail;
3427 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3428 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3429 correct = False;
3430 goto fail;
3433 /* This should fail - no more opens once delete on close set. */
3434 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3435 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3436 FILE_OPEN, 0, 0, &fnum2))) {
3437 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3438 correct = False;
3439 goto fail;
3440 } else
3441 printf("fourth delete on close test succeeded.\n");
3443 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3444 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3445 correct = False;
3446 goto fail;
3449 /* Test 5 ... */
3450 cli_setatr(cli1, fname, 0, 0);
3451 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3453 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3454 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3455 correct = False;
3456 goto fail;
3459 /* This should fail - only allowed on NT opens with DELETE access. */
3461 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3462 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3463 correct = False;
3464 goto fail;
3467 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3468 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3469 correct = False;
3470 goto fail;
3473 printf("fifth delete on close test succeeded.\n");
3475 /* Test 6 ... */
3476 cli_setatr(cli1, fname, 0, 0);
3477 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3479 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3480 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3481 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3482 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3483 correct = False;
3484 goto fail;
3487 /* This should fail - only allowed on NT opens with DELETE access. */
3489 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3490 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3491 correct = False;
3492 goto fail;
3495 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3496 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3497 correct = False;
3498 goto fail;
3501 printf("sixth delete on close test succeeded.\n");
3503 /* Test 7 ... */
3504 cli_setatr(cli1, fname, 0, 0);
3505 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3507 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3508 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3509 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3510 correct = False;
3511 goto fail;
3514 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3515 printf("[7] setting delete_on_close on file failed !\n");
3516 correct = False;
3517 goto fail;
3520 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3521 printf("[7] unsetting delete_on_close on file failed !\n");
3522 correct = False;
3523 goto fail;
3526 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3527 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3528 correct = False;
3529 goto fail;
3532 /* This next open should succeed - we reset the flag. */
3534 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3535 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3536 correct = False;
3537 goto fail;
3540 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3541 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3542 correct = False;
3543 goto fail;
3546 printf("seventh delete on close test succeeded.\n");
3548 /* Test 7 ... */
3549 cli_setatr(cli1, fname, 0, 0);
3550 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3552 if (!torture_open_connection(&cli2, 1)) {
3553 printf("[8] failed to open second connection.\n");
3554 correct = False;
3555 goto fail;
3558 cli_sockopt(cli1, sockops);
3560 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3561 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3562 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3563 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3564 correct = False;
3565 goto fail;
3568 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3569 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3570 FILE_OPEN, 0, 0, &fnum2))) {
3571 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3572 correct = False;
3573 goto fail;
3576 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3577 printf("[8] setting delete_on_close on file failed !\n");
3578 correct = False;
3579 goto fail;
3582 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3583 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3584 correct = False;
3585 goto fail;
3588 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3589 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3590 correct = False;
3591 goto fail;
3594 /* This should fail.. */
3595 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3596 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3597 goto fail;
3598 correct = False;
3599 } else
3600 printf("eighth delete on close test succeeded.\n");
3602 /* This should fail - we need to set DELETE_ACCESS. */
3603 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3604 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3605 printf("[9] open of %s succeeded should have failed!\n", fname);
3606 correct = False;
3607 goto fail;
3610 printf("ninth delete on close test succeeded.\n");
3612 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3613 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3614 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3615 correct = False;
3616 goto fail;
3619 /* This should delete the file. */
3620 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3621 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3622 correct = False;
3623 goto fail;
3626 /* This should fail.. */
3627 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3628 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3629 goto fail;
3630 correct = False;
3631 } else
3632 printf("tenth delete on close test succeeded.\n");
3634 cli_setatr(cli1, fname, 0, 0);
3635 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3637 /* What error do we get when attempting to open a read-only file with
3638 delete access ? */
3640 /* Create a readonly file. */
3641 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3642 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3643 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3644 correct = False;
3645 goto fail;
3648 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3649 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3650 correct = False;
3651 goto fail;
3654 /* Now try open for delete access. */
3655 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3656 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3657 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3658 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3659 cli_close(cli1, fnum1);
3660 goto fail;
3661 correct = False;
3662 } else {
3663 NTSTATUS nterr = cli_nt_error(cli1);
3664 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3665 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3666 goto fail;
3667 correct = False;
3668 } else {
3669 printf("eleventh delete on close test succeeded.\n");
3673 printf("finished delete test\n");
3675 fail:
3676 /* FIXME: This will crash if we aborted before cli2 got
3677 * intialized, because these functions don't handle
3678 * uninitialized connections. */
3680 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3681 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3682 cli_setatr(cli1, fname, 0, 0);
3683 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3685 if (cli1 && !torture_close_connection(cli1)) {
3686 correct = False;
3688 if (cli2 && !torture_close_connection(cli2)) {
3689 correct = False;
3691 return correct;
3696 print out server properties
3698 static bool run_properties(int dummy)
3700 struct cli_state *cli;
3701 bool correct = True;
3703 printf("starting properties test\n");
3705 ZERO_STRUCT(cli);
3707 if (!torture_open_connection(&cli, 0)) {
3708 return False;
3711 cli_sockopt(cli, sockops);
3713 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3715 if (!torture_close_connection(cli)) {
3716 correct = False;
3719 return correct;
3724 /* FIRST_DESIRED_ACCESS 0xf019f */
3725 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3726 FILE_READ_EA| /* 0xf */ \
3727 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3728 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3729 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3730 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3731 /* SECOND_DESIRED_ACCESS 0xe0080 */
3732 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3733 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3734 WRITE_OWNER_ACCESS /* 0xe0000 */
3736 #if 0
3737 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3738 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3739 FILE_READ_DATA|\
3740 WRITE_OWNER_ACCESS /* */
3741 #endif
3744 Test ntcreate calls made by xcopy
3746 static bool run_xcopy(int dummy)
3748 static struct cli_state *cli1;
3749 const char *fname = "\\test.txt";
3750 bool correct = True;
3751 uint16_t fnum1, fnum2;
3753 printf("starting xcopy test\n");
3755 if (!torture_open_connection(&cli1, 0)) {
3756 return False;
3759 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3760 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3761 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3762 0x4044, 0, &fnum1))) {
3763 printf("First open failed - %s\n", cli_errstr(cli1));
3764 return False;
3767 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3768 SECOND_DESIRED_ACCESS, 0,
3769 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3770 0x200000, 0, &fnum2))) {
3771 printf("second open failed - %s\n", cli_errstr(cli1));
3772 return False;
3775 if (!torture_close_connection(cli1)) {
3776 correct = False;
3779 return correct;
3783 Test rename on files open with share delete and no share delete.
3785 static bool run_rename(int dummy)
3787 static struct cli_state *cli1;
3788 const char *fname = "\\test.txt";
3789 const char *fname1 = "\\test1.txt";
3790 bool correct = True;
3791 uint16_t fnum1;
3792 NTSTATUS status;
3794 printf("starting rename test\n");
3796 if (!torture_open_connection(&cli1, 0)) {
3797 return False;
3800 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3801 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3802 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3803 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3804 printf("First open failed - %s\n", cli_errstr(cli1));
3805 return False;
3808 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3809 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3810 } else {
3811 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3812 correct = False;
3815 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3816 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3817 return False;
3820 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3821 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3822 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3823 #if 0
3824 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3825 #else
3826 FILE_SHARE_DELETE|FILE_SHARE_READ,
3827 #endif
3828 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3829 if (!NT_STATUS_IS_OK(status)) {
3830 printf("Second open failed - %s\n", cli_errstr(cli1));
3831 return False;
3834 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3835 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3836 correct = False;
3837 } else {
3838 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3841 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3842 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3843 return False;
3846 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3847 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3849 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3850 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3851 printf("Third open failed - %s\n", cli_errstr(cli1));
3852 return False;
3856 #if 0
3858 uint16_t fnum2;
3860 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3861 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3862 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3863 return False;
3865 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3866 printf("[8] setting delete_on_close on file failed !\n");
3867 return False;
3870 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3871 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3872 return False;
3875 #endif
3877 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3878 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3879 correct = False;
3880 } else {
3881 printf("Third rename succeeded (SHARE_NONE)\n");
3884 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3885 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3886 return False;
3889 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3890 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3892 /*----*/
3894 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3895 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3896 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3897 return False;
3900 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3901 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3902 } else {
3903 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3904 correct = False;
3907 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3908 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3909 return False;
3912 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3913 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3915 /*--*/
3917 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3918 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3919 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3920 return False;
3923 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3924 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3925 cli_errstr(cli1));
3926 correct = False;
3927 } else {
3928 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3932 * Now check if the first name still exists ...
3935 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3937 printf("Opening original file after rename of open file fails: %s\n",
3938 cli_errstr(cli1));
3940 else {
3941 printf("Opening original file after rename of open file works ...\n");
3942 (void)cli_close(cli1, fnum2);
3943 } */
3945 /*--*/
3948 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3949 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3950 return False;
3953 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3954 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3956 if (!torture_close_connection(cli1)) {
3957 correct = False;
3960 return correct;
3963 static bool run_pipe_number(int dummy)
3965 struct cli_state *cli1;
3966 const char *pipe_name = "\\SPOOLSS";
3967 uint16_t fnum;
3968 int num_pipes = 0;
3970 printf("starting pipenumber test\n");
3971 if (!torture_open_connection(&cli1, 0)) {
3972 return False;
3975 cli_sockopt(cli1, sockops);
3976 while(1) {
3977 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3978 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
3979 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3980 break;
3982 num_pipes++;
3983 printf("\r%6d", num_pipes);
3986 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3987 torture_close_connection(cli1);
3988 return True;
3992 Test open mode returns on read-only files.
3994 static bool run_opentest(int dummy)
3996 static struct cli_state *cli1;
3997 static struct cli_state *cli2;
3998 const char *fname = "\\readonly.file";
3999 uint16_t fnum1, fnum2;
4000 char buf[20];
4001 SMB_OFF_T fsize;
4002 bool correct = True;
4003 char *tmp_path;
4005 printf("starting open test\n");
4007 if (!torture_open_connection(&cli1, 0)) {
4008 return False;
4011 cli_setatr(cli1, fname, 0, 0);
4012 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4014 cli_sockopt(cli1, sockops);
4016 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4017 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4018 return False;
4021 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4022 printf("close2 failed (%s)\n", cli_errstr(cli1));
4023 return False;
4026 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4027 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4028 return False;
4031 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4032 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4033 return False;
4036 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4037 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4039 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4040 NT_STATUS_ACCESS_DENIED)) {
4041 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4044 printf("finished open test 1\n");
4046 cli_close(cli1, fnum1);
4048 /* Now try not readonly and ensure ERRbadshare is returned. */
4050 cli_setatr(cli1, fname, 0, 0);
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 ERRshare. */
4058 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4060 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4061 NT_STATUS_SHARING_VIOLATION)) {
4062 printf("correct error code ERRDOS/ERRbadshare returned\n");
4065 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4066 printf("close2 failed (%s)\n", cli_errstr(cli1));
4067 return False;
4070 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4072 printf("finished open test 2\n");
4074 /* Test truncate open disposition on file opened for read. */
4076 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4077 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4078 return False;
4081 /* write 20 bytes. */
4083 memset(buf, '\0', 20);
4085 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4086 printf("write failed (%s)\n", cli_errstr(cli1));
4087 correct = False;
4090 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4091 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4092 return False;
4095 /* Ensure size == 20. */
4096 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4097 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4098 return False;
4101 if (fsize != 20) {
4102 printf("(3) file size != 20\n");
4103 return False;
4106 /* Now test if we can truncate a file opened for readonly. */
4108 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4109 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4110 return False;
4113 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4114 printf("close2 failed (%s)\n", cli_errstr(cli1));
4115 return False;
4118 /* Ensure size == 0. */
4119 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4120 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4121 return False;
4124 if (fsize != 0) {
4125 printf("(3) file size != 0\n");
4126 return False;
4128 printf("finished open test 3\n");
4130 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4133 printf("testing ctemp\n");
4134 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4135 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4136 return False;
4138 printf("ctemp gave path %s\n", tmp_path);
4139 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4140 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4142 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4143 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4146 /* Test the non-io opens... */
4148 if (!torture_open_connection(&cli2, 1)) {
4149 return False;
4152 cli_setatr(cli2, fname, 0, 0);
4153 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4155 cli_sockopt(cli2, sockops);
4157 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4159 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4160 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4161 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4162 return False;
4165 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4166 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4167 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4168 return False;
4171 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4172 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4173 return False;
4175 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4176 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4177 return False;
4180 printf("non-io open test #1 passed.\n");
4182 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4184 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4186 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4187 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4188 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4189 return False;
4192 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4193 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4194 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4195 return False;
4198 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4199 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4200 return False;
4202 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4203 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4204 return False;
4207 printf("non-io open test #2 passed.\n");
4209 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4211 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4213 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4214 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4215 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4216 return False;
4219 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4220 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4221 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4222 return False;
4225 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4226 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4227 return False;
4229 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4230 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4231 return False;
4234 printf("non-io open test #3 passed.\n");
4236 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4238 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4240 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4241 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4242 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4243 return False;
4246 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4247 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4248 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4249 return False;
4252 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4254 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4255 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4256 return False;
4259 printf("non-io open test #4 passed.\n");
4261 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4263 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4265 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4266 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4267 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4268 return False;
4271 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4272 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4273 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4274 return False;
4277 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4278 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4279 return False;
4282 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4283 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4284 return False;
4287 printf("non-io open test #5 passed.\n");
4289 printf("TEST #6 testing 1 non-io open, one io open\n");
4291 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4295 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4296 return False;
4299 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4300 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4301 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4302 return False;
4305 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4306 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4307 return False;
4310 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4311 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4312 return False;
4315 printf("non-io open test #6 passed.\n");
4317 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4319 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4321 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4322 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4323 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4324 return False;
4327 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4328 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4329 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4330 return False;
4333 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4335 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4336 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4337 return False;
4340 printf("non-io open test #7 passed.\n");
4342 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4344 if (!torture_close_connection(cli1)) {
4345 correct = False;
4347 if (!torture_close_connection(cli2)) {
4348 correct = False;
4351 return correct;
4354 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4356 uint16 major, minor;
4357 uint32 caplow, caphigh;
4358 NTSTATUS status;
4360 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4361 printf("Server doesn't support UNIX CIFS extensions.\n");
4362 return NT_STATUS_NOT_SUPPORTED;
4365 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4366 &caphigh);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 printf("Server didn't return UNIX CIFS extensions: %s\n",
4369 nt_errstr(status));
4370 return status;
4373 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4374 caplow, caphigh);
4375 if (!NT_STATUS_IS_OK(status)) {
4376 printf("Server doesn't support setting UNIX CIFS extensions: "
4377 "%s.\n", nt_errstr(status));
4378 return status;
4381 return NT_STATUS_OK;
4385 Test POSIX open /mkdir calls.
4387 static bool run_simple_posix_open_test(int dummy)
4389 static struct cli_state *cli1;
4390 const char *fname = "posix:file";
4391 const char *hname = "posix:hlink";
4392 const char *sname = "posix:symlink";
4393 const char *dname = "posix:dir";
4394 char buf[10];
4395 char namebuf[11];
4396 uint16_t fnum1 = (uint16_t)-1;
4397 SMB_STRUCT_STAT sbuf;
4398 bool correct = false;
4399 NTSTATUS status;
4401 printf("Starting simple POSIX open test\n");
4403 if (!torture_open_connection(&cli1, 0)) {
4404 return false;
4407 cli_sockopt(cli1, sockops);
4409 status = torture_setup_unix_extensions(cli1);
4410 if (!NT_STATUS_IS_OK(status)) {
4411 return false;
4414 cli_setatr(cli1, fname, 0, 0);
4415 cli_posix_unlink(cli1, fname);
4416 cli_setatr(cli1, dname, 0, 0);
4417 cli_posix_rmdir(cli1, dname);
4418 cli_setatr(cli1, hname, 0, 0);
4419 cli_posix_unlink(cli1, hname);
4420 cli_setatr(cli1, sname, 0, 0);
4421 cli_posix_unlink(cli1, sname);
4423 /* Create a directory. */
4424 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4425 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4426 goto out;
4429 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4430 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4431 goto out;
4434 /* Test ftruncate - set file size. */
4435 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4436 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4437 goto out;
4440 /* Ensure st_size == 1000 */
4441 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4442 printf("stat failed (%s)\n", cli_errstr(cli1));
4443 goto out;
4446 if (sbuf.st_ex_size != 1000) {
4447 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4448 goto out;
4451 /* Test ftruncate - set file size back to zero. */
4452 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4453 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4454 goto out;
4457 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4458 printf("close failed (%s)\n", cli_errstr(cli1));
4459 goto out;
4462 /* Now open the file again for read only. */
4463 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4464 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4465 goto out;
4468 /* Now unlink while open. */
4469 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4470 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4471 goto out;
4474 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4475 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4476 goto out;
4479 /* Ensure the file has gone. */
4480 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4481 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4482 goto out;
4485 /* What happens when we try and POSIX open a directory ? */
4486 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4487 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4488 goto out;
4489 } else {
4490 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4491 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4492 goto out;
4496 /* Create the file. */
4497 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4498 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4499 goto out;
4502 /* Write some data into it. */
4503 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4504 printf("cli_write failed: %s\n", cli_errstr(cli1));
4505 goto out;
4508 cli_close(cli1, fnum1);
4510 /* Now create a hardlink. */
4511 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4512 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4513 goto out;
4516 /* Now create a symlink. */
4517 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4518 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4519 goto out;
4522 /* Open the hardlink for read. */
4523 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4524 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4525 goto out;
4528 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4529 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4530 goto out;
4533 if (memcmp(buf, "TEST DATA\n", 10)) {
4534 printf("invalid data read from hardlink\n");
4535 goto out;
4538 /* Do a POSIX lock/unlock. */
4539 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4540 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4541 goto out;
4544 /* Punch a hole in the locked area. */
4545 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4546 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4547 goto out;
4550 cli_close(cli1, fnum1);
4552 /* Open the symlink for read - this should fail. A POSIX
4553 client should not be doing opens on a symlink. */
4554 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4555 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4556 goto out;
4557 } else {
4558 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4559 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4560 printf("POSIX open of %s should have failed "
4561 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4562 "failed with %s instead.\n",
4563 sname, cli_errstr(cli1));
4564 goto out;
4568 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4569 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4570 goto out;
4573 if (strcmp(namebuf, fname) != 0) {
4574 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4575 sname, fname, namebuf);
4576 goto out;
4579 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4580 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4581 goto out;
4584 printf("Simple POSIX open test passed\n");
4585 correct = true;
4587 out:
4589 if (fnum1 != (uint16_t)-1) {
4590 cli_close(cli1, fnum1);
4591 fnum1 = (uint16_t)-1;
4594 cli_setatr(cli1, sname, 0, 0);
4595 cli_posix_unlink(cli1, sname);
4596 cli_setatr(cli1, hname, 0, 0);
4597 cli_posix_unlink(cli1, hname);
4598 cli_setatr(cli1, fname, 0, 0);
4599 cli_posix_unlink(cli1, fname);
4600 cli_setatr(cli1, dname, 0, 0);
4601 cli_posix_rmdir(cli1, dname);
4603 if (!torture_close_connection(cli1)) {
4604 correct = false;
4607 return correct;
4611 static uint32 open_attrs_table[] = {
4612 FILE_ATTRIBUTE_NORMAL,
4613 FILE_ATTRIBUTE_ARCHIVE,
4614 FILE_ATTRIBUTE_READONLY,
4615 FILE_ATTRIBUTE_HIDDEN,
4616 FILE_ATTRIBUTE_SYSTEM,
4618 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4619 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4620 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4621 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4622 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4623 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4625 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4626 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4627 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4628 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4631 struct trunc_open_results {
4632 unsigned int num;
4633 uint32 init_attr;
4634 uint32 trunc_attr;
4635 uint32 result_attr;
4638 static struct trunc_open_results attr_results[] = {
4639 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4640 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4641 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4642 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4643 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4644 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4645 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4646 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4647 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4648 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4649 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4650 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4651 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4652 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4653 { 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 },
4654 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4655 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4656 { 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 },
4657 { 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 },
4658 { 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 },
4659 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4660 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4661 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4662 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4663 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4664 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4667 static bool run_openattrtest(int dummy)
4669 static struct cli_state *cli1;
4670 const char *fname = "\\openattr.file";
4671 uint16_t fnum1;
4672 bool correct = True;
4673 uint16 attr;
4674 unsigned int i, j, k, l;
4676 printf("starting open attr test\n");
4678 if (!torture_open_connection(&cli1, 0)) {
4679 return False;
4682 cli_sockopt(cli1, sockops);
4684 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4685 cli_setatr(cli1, fname, 0, 0);
4686 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4687 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4688 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4689 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4690 return False;
4693 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4694 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4695 return False;
4698 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4699 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4700 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4701 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4702 if (attr_results[l].num == k) {
4703 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4704 k, open_attrs_table[i],
4705 open_attrs_table[j],
4706 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4707 correct = False;
4710 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4711 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4712 k, open_attrs_table[i], open_attrs_table[j],
4713 cli_errstr(cli1));
4714 correct = False;
4716 #if 0
4717 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4718 #endif
4719 k++;
4720 continue;
4723 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4724 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4725 return False;
4728 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4729 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4730 return False;
4733 #if 0
4734 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4735 k, open_attrs_table[i], open_attrs_table[j], attr );
4736 #endif
4738 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4739 if (attr_results[l].num == k) {
4740 if (attr != attr_results[l].result_attr ||
4741 open_attrs_table[i] != attr_results[l].init_attr ||
4742 open_attrs_table[j] != attr_results[l].trunc_attr) {
4743 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4744 open_attrs_table[i],
4745 open_attrs_table[j],
4746 (unsigned int)attr,
4747 attr_results[l].result_attr);
4748 correct = False;
4750 break;
4753 k++;
4757 cli_setatr(cli1, fname, 0, 0);
4758 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4760 printf("open attr test %s.\n", correct ? "passed" : "failed");
4762 if (!torture_close_connection(cli1)) {
4763 correct = False;
4765 return correct;
4768 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4774 test directory listing speed
4776 static bool run_dirtest(int dummy)
4778 int i;
4779 static struct cli_state *cli;
4780 uint16_t fnum;
4781 struct timeval core_start;
4782 bool correct = True;
4784 printf("starting directory test\n");
4786 if (!torture_open_connection(&cli, 0)) {
4787 return False;
4790 cli_sockopt(cli, sockops);
4792 srandom(0);
4793 for (i=0;i<torture_numops;i++) {
4794 fstring fname;
4795 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4796 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4797 fprintf(stderr,"Failed to open %s\n", fname);
4798 return False;
4800 cli_close(cli, fnum);
4803 core_start = timeval_current();
4805 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4806 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4807 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4809 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4811 srandom(0);
4812 for (i=0;i<torture_numops;i++) {
4813 fstring fname;
4814 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4815 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4818 if (!torture_close_connection(cli)) {
4819 correct = False;
4822 printf("finished dirtest\n");
4824 return correct;
4827 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4829 struct cli_state *pcli = (struct cli_state *)state;
4830 fstring fname;
4831 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4833 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4834 return;
4836 if (finfo->mode & aDIR) {
4837 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4838 printf("del_fn: failed to rmdir %s\n,", fname );
4839 } else {
4840 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4841 printf("del_fn: failed to unlink %s\n,", fname );
4847 sees what IOCTLs are supported
4849 bool torture_ioctl_test(int dummy)
4851 static struct cli_state *cli;
4852 uint16_t device, function;
4853 uint16_t fnum;
4854 const char *fname = "\\ioctl.dat";
4855 DATA_BLOB blob;
4856 NTSTATUS status;
4858 if (!torture_open_connection(&cli, 0)) {
4859 return False;
4862 printf("starting ioctl test\n");
4864 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4866 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4867 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4868 return False;
4871 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4872 printf("ioctl device info: %s\n", cli_errstr(cli));
4874 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4875 printf("ioctl job info: %s\n", cli_errstr(cli));
4877 for (device=0;device<0x100;device++) {
4878 printf("testing device=0x%x\n", device);
4879 for (function=0;function<0x100;function++) {
4880 uint32 code = (device<<16) | function;
4882 status = cli_raw_ioctl(cli, fnum, code, &blob);
4884 if (NT_STATUS_IS_OK(status)) {
4885 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4886 (int)blob.length);
4887 data_blob_free(&blob);
4892 if (!torture_close_connection(cli)) {
4893 return False;
4896 return True;
4901 tries varients of chkpath
4903 bool torture_chkpath_test(int dummy)
4905 static struct cli_state *cli;
4906 uint16_t fnum;
4907 bool ret;
4909 if (!torture_open_connection(&cli, 0)) {
4910 return False;
4913 printf("starting chkpath test\n");
4915 /* cleanup from an old run */
4916 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4917 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4918 cli_rmdir(cli, "\\chkpath.dir");
4920 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4921 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4922 return False;
4925 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4926 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4927 return False;
4930 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4931 printf("open1 failed (%s)\n", cli_errstr(cli));
4932 return False;
4934 cli_close(cli, fnum);
4936 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4937 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4938 ret = False;
4941 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4942 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4943 ret = False;
4946 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4947 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4948 NT_STATUS_NOT_A_DIRECTORY);
4949 } else {
4950 printf("* chkpath on a file should fail\n");
4951 ret = False;
4954 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4955 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4956 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4957 } else {
4958 printf("* chkpath on a non existant file should fail\n");
4959 ret = False;
4962 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4963 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4964 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4965 } else {
4966 printf("* chkpath on a non existent component should fail\n");
4967 ret = False;
4970 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4971 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4972 cli_rmdir(cli, "\\chkpath.dir");
4974 if (!torture_close_connection(cli)) {
4975 return False;
4978 return ret;
4981 static bool run_eatest(int dummy)
4983 static struct cli_state *cli;
4984 const char *fname = "\\eatest.txt";
4985 bool correct = True;
4986 uint16_t fnum;
4987 int i;
4988 size_t num_eas;
4989 struct ea_struct *ea_list = NULL;
4990 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4992 printf("starting eatest\n");
4994 if (!torture_open_connection(&cli, 0)) {
4995 talloc_destroy(mem_ctx);
4996 return False;
4999 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5000 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5001 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5002 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5003 0x4044, 0, &fnum))) {
5004 printf("open failed - %s\n", cli_errstr(cli));
5005 talloc_destroy(mem_ctx);
5006 return False;
5009 for (i = 0; i < 10; i++) {
5010 fstring ea_name, ea_val;
5012 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5013 memset(ea_val, (char)i+1, i+1);
5014 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5015 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5016 talloc_destroy(mem_ctx);
5017 return False;
5021 cli_close(cli, fnum);
5022 for (i = 0; i < 10; i++) {
5023 fstring ea_name, ea_val;
5025 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5026 memset(ea_val, (char)i+1, i+1);
5027 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5028 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5029 talloc_destroy(mem_ctx);
5030 return False;
5034 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5035 printf("ea_get list failed - %s\n", cli_errstr(cli));
5036 correct = False;
5039 printf("num_eas = %d\n", (int)num_eas);
5041 if (num_eas != 20) {
5042 printf("Should be 20 EA's stored... failing.\n");
5043 correct = False;
5046 for (i = 0; i < num_eas; i++) {
5047 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5048 dump_data(0, ea_list[i].value.data,
5049 ea_list[i].value.length);
5052 /* Setting EA's to zero length deletes them. Test this */
5053 printf("Now deleting all EA's - case indepenent....\n");
5055 #if 1
5056 cli_set_ea_path(cli, fname, "", "", 0);
5057 #else
5058 for (i = 0; i < 20; i++) {
5059 fstring ea_name;
5060 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5061 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5062 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5063 talloc_destroy(mem_ctx);
5064 return False;
5067 #endif
5069 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5070 printf("ea_get list failed - %s\n", cli_errstr(cli));
5071 correct = False;
5074 printf("num_eas = %d\n", (int)num_eas);
5075 for (i = 0; i < num_eas; i++) {
5076 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5077 dump_data(0, ea_list[i].value.data,
5078 ea_list[i].value.length);
5081 if (num_eas != 0) {
5082 printf("deleting EA's failed.\n");
5083 correct = False;
5086 /* Try and delete a non existant EA. */
5087 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5088 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5089 correct = False;
5092 talloc_destroy(mem_ctx);
5093 if (!torture_close_connection(cli)) {
5094 correct = False;
5097 return correct;
5100 static bool run_dirtest1(int dummy)
5102 int i;
5103 static struct cli_state *cli;
5104 uint16_t fnum;
5105 int num_seen;
5106 bool correct = True;
5108 printf("starting directory test\n");
5110 if (!torture_open_connection(&cli, 0)) {
5111 return False;
5114 cli_sockopt(cli, sockops);
5116 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5117 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5118 cli_rmdir(cli, "\\LISTDIR");
5119 cli_mkdir(cli, "\\LISTDIR");
5121 /* Create 1000 files and 1000 directories. */
5122 for (i=0;i<1000;i++) {
5123 fstring fname;
5124 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5125 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5126 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5127 fprintf(stderr,"Failed to open %s\n", fname);
5128 return False;
5130 cli_close(cli, fnum);
5132 for (i=0;i<1000;i++) {
5133 fstring fname;
5134 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5135 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5136 fprintf(stderr,"Failed to open %s\n", fname);
5137 return False;
5141 /* Now ensure that doing an old list sees both files and directories. */
5142 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5143 printf("num_seen = %d\n", num_seen );
5144 /* We should see 100 files + 1000 directories + . and .. */
5145 if (num_seen != 2002)
5146 correct = False;
5148 /* Ensure if we have the "must have" bits we only see the
5149 * relevent entries.
5151 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5152 printf("num_seen = %d\n", num_seen );
5153 if (num_seen != 1002)
5154 correct = False;
5156 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5157 printf("num_seen = %d\n", num_seen );
5158 if (num_seen != 1000)
5159 correct = False;
5161 /* Delete everything. */
5162 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5163 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5164 cli_rmdir(cli, "\\LISTDIR");
5166 #if 0
5167 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5168 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5169 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5170 #endif
5172 if (!torture_close_connection(cli)) {
5173 correct = False;
5176 printf("finished dirtest1\n");
5178 return correct;
5181 static bool run_error_map_extract(int dummy) {
5183 static struct cli_state *c_dos;
5184 static struct cli_state *c_nt;
5185 NTSTATUS status;
5187 uint32 error;
5189 uint32 flgs2, errnum;
5190 uint8 errclass;
5192 NTSTATUS nt_status;
5194 fstring user;
5196 /* NT-Error connection */
5198 if (!(c_nt = open_nbt_connection())) {
5199 return False;
5202 c_nt->use_spnego = False;
5204 status = cli_negprot(c_nt);
5206 if (!NT_STATUS_IS_OK(status)) {
5207 printf("%s rejected the NT-error negprot (%s)\n", host,
5208 nt_errstr(status));
5209 cli_shutdown(c_nt);
5210 return False;
5213 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5214 workgroup))) {
5215 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5216 return False;
5219 /* DOS-Error connection */
5221 if (!(c_dos = open_nbt_connection())) {
5222 return False;
5225 c_dos->use_spnego = False;
5226 c_dos->force_dos_errors = True;
5228 status = cli_negprot(c_dos);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("%s rejected the DOS-error negprot (%s)\n", host,
5231 nt_errstr(status));
5232 cli_shutdown(c_dos);
5233 return False;
5236 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5237 workgroup))) {
5238 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5239 return False;
5242 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5243 fstr_sprintf(user, "%X", error);
5245 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5246 password, strlen(password),
5247 password, strlen(password),
5248 workgroup))) {
5249 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5252 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5254 /* Case #1: 32-bit NT errors */
5255 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5256 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5257 } else {
5258 printf("/** Dos error on NT connection! (%s) */\n",
5259 cli_errstr(c_nt));
5260 nt_status = NT_STATUS(0xc0000000);
5263 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5264 password, strlen(password),
5265 password, strlen(password),
5266 workgroup))) {
5267 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5269 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5271 /* Case #1: 32-bit NT errors */
5272 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5273 printf("/** NT error on DOS connection! (%s) */\n",
5274 cli_errstr(c_nt));
5275 errnum = errclass = 0;
5276 } else {
5277 cli_dos_error(c_dos, &errclass, &errnum);
5280 if (NT_STATUS_V(nt_status) != error) {
5281 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5282 get_nt_error_c_code(NT_STATUS(error)),
5283 get_nt_error_c_code(nt_status));
5286 printf("\t{%s,\t%s,\t%s},\n",
5287 smb_dos_err_class(errclass),
5288 smb_dos_err_name(errclass, errnum),
5289 get_nt_error_c_code(NT_STATUS(error)));
5291 return True;
5294 static bool run_sesssetup_bench(int dummy)
5296 static struct cli_state *c;
5297 const char *fname = "\\file.dat";
5298 uint16_t fnum;
5299 NTSTATUS status;
5300 int i;
5302 if (!torture_open_connection(&c, 0)) {
5303 return false;
5306 if (!NT_STATUS_IS_OK(cli_ntcreate(
5307 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5308 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5309 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5310 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5311 return false;
5314 for (i=0; i<torture_numops; i++) {
5315 status = cli_session_setup(
5316 c, username,
5317 password, strlen(password),
5318 password, strlen(password),
5319 workgroup);
5320 if (!NT_STATUS_IS_OK(status)) {
5321 d_printf("(%s) cli_session_setup failed: %s\n",
5322 __location__, nt_errstr(status));
5323 return false;
5326 d_printf("\r%d ", (int)c->vuid);
5328 status = cli_ulogoff(c);
5329 if (!NT_STATUS_IS_OK(status)) {
5330 d_printf("(%s) cli_ulogoff failed: %s\n",
5331 __location__, nt_errstr(status));
5332 return false;
5334 c->vuid = 0;
5337 return true;
5340 static bool subst_test(const char *str, const char *user, const char *domain,
5341 uid_t uid, gid_t gid, const char *expected)
5343 char *subst;
5344 bool result = true;
5346 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5348 if (strcmp(subst, expected) != 0) {
5349 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5350 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5351 expected);
5352 result = false;
5355 TALLOC_FREE(subst);
5356 return result;
5359 static void chain1_open_completion(struct tevent_req *req)
5361 uint16_t fnum;
5362 NTSTATUS status;
5363 status = cli_open_recv(req, &fnum);
5364 TALLOC_FREE(req);
5366 d_printf("cli_open_recv returned %s: %d\n",
5367 nt_errstr(status),
5368 NT_STATUS_IS_OK(status) ? fnum : -1);
5371 static void chain1_write_completion(struct tevent_req *req)
5373 size_t written;
5374 NTSTATUS status;
5375 status = cli_write_andx_recv(req, &written);
5376 TALLOC_FREE(req);
5378 d_printf("cli_write_andx_recv returned %s: %d\n",
5379 nt_errstr(status),
5380 NT_STATUS_IS_OK(status) ? (int)written : -1);
5383 static void chain1_close_completion(struct tevent_req *req)
5385 NTSTATUS status;
5386 bool *done = (bool *)tevent_req_callback_data_void(req);
5388 status = cli_close_recv(req);
5389 *done = true;
5391 TALLOC_FREE(req);
5393 d_printf("cli_close returned %s\n", nt_errstr(status));
5396 static bool run_chain1(int dummy)
5398 struct cli_state *cli1;
5399 struct event_context *evt = event_context_init(NULL);
5400 struct tevent_req *reqs[3], *smbreqs[3];
5401 bool done = false;
5402 const char *str = "foobar";
5403 NTSTATUS status;
5405 printf("starting chain1 test\n");
5406 if (!torture_open_connection(&cli1, 0)) {
5407 return False;
5410 cli_sockopt(cli1, sockops);
5412 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5413 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5414 if (reqs[0] == NULL) return false;
5415 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5418 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5419 (uint8_t *)str, 0, strlen(str)+1,
5420 smbreqs, 1, &smbreqs[1]);
5421 if (reqs[1] == NULL) return false;
5422 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5424 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5425 if (reqs[2] == NULL) return false;
5426 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5428 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5429 if (!NT_STATUS_IS_OK(status)) {
5430 return false;
5433 while (!done) {
5434 event_loop_once(evt);
5437 torture_close_connection(cli1);
5438 return True;
5441 static void chain2_sesssetup_completion(struct tevent_req *req)
5443 NTSTATUS status;
5444 status = cli_session_setup_guest_recv(req);
5445 d_printf("sesssetup returned %s\n", nt_errstr(status));
5448 static void chain2_tcon_completion(struct tevent_req *req)
5450 bool *done = (bool *)tevent_req_callback_data_void(req);
5451 NTSTATUS status;
5452 status = cli_tcon_andx_recv(req);
5453 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5454 *done = true;
5457 static bool run_chain2(int dummy)
5459 struct cli_state *cli1;
5460 struct event_context *evt = event_context_init(NULL);
5461 struct tevent_req *reqs[2], *smbreqs[2];
5462 bool done = false;
5463 NTSTATUS status;
5465 printf("starting chain2 test\n");
5466 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5467 port_to_use, Undefined, 0, NULL);
5468 if (!NT_STATUS_IS_OK(status)) {
5469 return False;
5472 cli_sockopt(cli1, sockops);
5474 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5475 &smbreqs[0]);
5476 if (reqs[0] == NULL) return false;
5477 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5479 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5480 "?????", NULL, 0, &smbreqs[1]);
5481 if (reqs[1] == NULL) return false;
5482 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5484 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5485 if (!NT_STATUS_IS_OK(status)) {
5486 return false;
5489 while (!done) {
5490 event_loop_once(evt);
5493 torture_close_connection(cli1);
5494 return True;
5498 struct torture_createdel_state {
5499 struct tevent_context *ev;
5500 struct cli_state *cli;
5503 static void torture_createdel_created(struct tevent_req *subreq);
5504 static void torture_createdel_closed(struct tevent_req *subreq);
5506 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5507 struct tevent_context *ev,
5508 struct cli_state *cli,
5509 const char *name)
5511 struct tevent_req *req, *subreq;
5512 struct torture_createdel_state *state;
5514 req = tevent_req_create(mem_ctx, &state,
5515 struct torture_createdel_state);
5516 if (req == NULL) {
5517 return NULL;
5519 state->ev = ev;
5520 state->cli = cli;
5522 subreq = cli_ntcreate_send(
5523 state, ev, cli, name, 0,
5524 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5525 FILE_ATTRIBUTE_NORMAL,
5526 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5527 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5529 if (tevent_req_nomem(subreq, req)) {
5530 return tevent_req_post(req, ev);
5532 tevent_req_set_callback(subreq, torture_createdel_created, req);
5533 return req;
5536 static void torture_createdel_created(struct tevent_req *subreq)
5538 struct tevent_req *req = tevent_req_callback_data(
5539 subreq, struct tevent_req);
5540 struct torture_createdel_state *state = tevent_req_data(
5541 req, struct torture_createdel_state);
5542 NTSTATUS status;
5543 uint16_t fnum;
5545 status = cli_ntcreate_recv(subreq, &fnum);
5546 TALLOC_FREE(subreq);
5547 if (!NT_STATUS_IS_OK(status)) {
5548 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5549 nt_errstr(status)));
5550 tevent_req_nterror(req, status);
5551 return;
5554 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5555 if (tevent_req_nomem(subreq, req)) {
5556 return;
5558 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5561 static void torture_createdel_closed(struct tevent_req *subreq)
5563 struct tevent_req *req = tevent_req_callback_data(
5564 subreq, struct tevent_req);
5565 NTSTATUS status;
5567 status = cli_close_recv(subreq);
5568 if (!NT_STATUS_IS_OK(status)) {
5569 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5570 tevent_req_nterror(req, status);
5571 return;
5573 tevent_req_done(req);
5576 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5578 return tevent_req_simple_recv_ntstatus(req);
5581 struct torture_createdels_state {
5582 struct tevent_context *ev;
5583 struct cli_state *cli;
5584 const char *base_name;
5585 int sent;
5586 int received;
5587 int num_files;
5588 struct tevent_req **reqs;
5591 static void torture_createdels_done(struct tevent_req *subreq);
5593 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5594 struct tevent_context *ev,
5595 struct cli_state *cli,
5596 const char *base_name,
5597 int num_parallel,
5598 int num_files)
5600 struct tevent_req *req;
5601 struct torture_createdels_state *state;
5602 int i;
5604 req = tevent_req_create(mem_ctx, &state,
5605 struct torture_createdels_state);
5606 if (req == NULL) {
5607 return NULL;
5609 state->ev = ev;
5610 state->cli = cli;
5611 state->base_name = talloc_strdup(state, base_name);
5612 if (tevent_req_nomem(state->base_name, req)) {
5613 return tevent_req_post(req, ev);
5615 state->num_files = MAX(num_parallel, num_files);
5616 state->sent = 0;
5617 state->received = 0;
5619 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5620 if (tevent_req_nomem(state->reqs, req)) {
5621 return tevent_req_post(req, ev);
5624 for (i=0; i<num_parallel; i++) {
5625 char *name;
5627 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5628 state->sent);
5629 if (tevent_req_nomem(name, req)) {
5630 return tevent_req_post(req, ev);
5632 state->reqs[i] = torture_createdel_send(
5633 state->reqs, state->ev, state->cli, name);
5634 if (tevent_req_nomem(state->reqs[i], req)) {
5635 return tevent_req_post(req, ev);
5637 name = talloc_move(state->reqs[i], &name);
5638 tevent_req_set_callback(state->reqs[i],
5639 torture_createdels_done, req);
5640 state->sent += 1;
5642 return req;
5645 static void torture_createdels_done(struct tevent_req *subreq)
5647 struct tevent_req *req = tevent_req_callback_data(
5648 subreq, struct tevent_req);
5649 struct torture_createdels_state *state = tevent_req_data(
5650 req, struct torture_createdels_state);
5651 size_t num_parallel = talloc_array_length(state->reqs);
5652 NTSTATUS status;
5653 char *name;
5654 int i;
5656 status = torture_createdel_recv(subreq);
5657 if (!NT_STATUS_IS_OK(status)){
5658 DEBUG(10, ("torture_createdel_recv returned %s\n",
5659 nt_errstr(status)));
5660 TALLOC_FREE(subreq);
5661 tevent_req_nterror(req, status);
5662 return;
5665 for (i=0; i<num_parallel; i++) {
5666 if (subreq == state->reqs[i]) {
5667 break;
5670 if (i == num_parallel) {
5671 DEBUG(10, ("received something we did not send\n"));
5672 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5673 return;
5675 TALLOC_FREE(state->reqs[i]);
5677 if (state->sent >= state->num_files) {
5678 tevent_req_done(req);
5679 return;
5682 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5683 state->sent);
5684 if (tevent_req_nomem(name, req)) {
5685 return;
5687 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5688 state->cli, name);
5689 if (tevent_req_nomem(state->reqs[i], req)) {
5690 return;
5692 name = talloc_move(state->reqs[i], &name);
5693 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5694 state->sent += 1;
5697 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5699 return tevent_req_simple_recv_ntstatus(req);
5702 struct swallow_notify_state {
5703 struct tevent_context *ev;
5704 struct cli_state *cli;
5705 uint16_t fnum;
5706 uint32_t completion_filter;
5707 bool recursive;
5708 bool (*fn)(uint32_t action, const char *name, void *priv);
5709 void *priv;
5712 static void swallow_notify_done(struct tevent_req *subreq);
5714 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5715 struct tevent_context *ev,
5716 struct cli_state *cli,
5717 uint16_t fnum,
5718 uint32_t completion_filter,
5719 bool recursive,
5720 bool (*fn)(uint32_t action,
5721 const char *name,
5722 void *priv),
5723 void *priv)
5725 struct tevent_req *req, *subreq;
5726 struct swallow_notify_state *state;
5728 req = tevent_req_create(mem_ctx, &state,
5729 struct swallow_notify_state);
5730 if (req == NULL) {
5731 return NULL;
5733 state->ev = ev;
5734 state->cli = cli;
5735 state->fnum = fnum;
5736 state->completion_filter = completion_filter;
5737 state->recursive = recursive;
5738 state->fn = fn;
5739 state->priv = priv;
5741 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5742 0xffff, state->completion_filter,
5743 state->recursive);
5744 if (tevent_req_nomem(subreq, req)) {
5745 return tevent_req_post(req, ev);
5747 tevent_req_set_callback(subreq, swallow_notify_done, req);
5748 return req;
5751 static void swallow_notify_done(struct tevent_req *subreq)
5753 struct tevent_req *req = tevent_req_callback_data(
5754 subreq, struct tevent_req);
5755 struct swallow_notify_state *state = tevent_req_data(
5756 req, struct swallow_notify_state);
5757 NTSTATUS status;
5758 uint32_t i, num_changes;
5759 struct notify_change *changes;
5761 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5762 TALLOC_FREE(subreq);
5763 if (!NT_STATUS_IS_OK(status)) {
5764 DEBUG(10, ("cli_notify_recv returned %s\n",
5765 nt_errstr(status)));
5766 tevent_req_nterror(req, status);
5767 return;
5770 for (i=0; i<num_changes; i++) {
5771 state->fn(changes[i].action, changes[i].name, state->priv);
5773 TALLOC_FREE(changes);
5775 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5776 0xffff, state->completion_filter,
5777 state->recursive);
5778 if (tevent_req_nomem(subreq, req)) {
5779 return;
5781 tevent_req_set_callback(subreq, swallow_notify_done, req);
5784 static bool print_notifies(uint32_t action, const char *name, void *priv)
5786 if (DEBUGLEVEL > 5) {
5787 d_printf("%d %s\n", (int)action, name);
5789 return true;
5792 static void notify_bench_done(struct tevent_req *req)
5794 int *num_finished = (int *)tevent_req_callback_data_void(req);
5795 *num_finished += 1;
5798 static bool run_notify_bench(int dummy)
5800 const char *dname = "\\notify-bench";
5801 struct tevent_context *ev;
5802 NTSTATUS status;
5803 uint16_t dnum;
5804 struct tevent_req *req1;
5805 struct tevent_req *req2 = NULL;
5806 int i, num_unc_names;
5807 int num_finished = 0;
5809 printf("starting notify-bench test\n");
5811 if (use_multishare_conn) {
5812 char **unc_list;
5813 unc_list = file_lines_load(multishare_conn_fname,
5814 &num_unc_names, 0, NULL);
5815 if (!unc_list || num_unc_names <= 0) {
5816 d_printf("Failed to load unc names list from '%s'\n",
5817 multishare_conn_fname);
5818 return false;
5820 TALLOC_FREE(unc_list);
5821 } else {
5822 num_unc_names = 1;
5825 ev = tevent_context_init(talloc_tos());
5826 if (ev == NULL) {
5827 d_printf("tevent_context_init failed\n");
5828 return false;
5831 for (i=0; i<num_unc_names; i++) {
5832 struct cli_state *cli;
5833 char *base_fname;
5835 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5836 dname, i);
5837 if (base_fname == NULL) {
5838 return false;
5841 if (!torture_open_connection(&cli, i)) {
5842 return false;
5845 status = cli_ntcreate(cli, dname, 0,
5846 MAXIMUM_ALLOWED_ACCESS,
5847 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5848 FILE_SHARE_DELETE,
5849 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5850 &dnum);
5852 if (!NT_STATUS_IS_OK(status)) {
5853 d_printf("Could not create %s: %s\n", dname,
5854 nt_errstr(status));
5855 return false;
5858 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5859 FILE_NOTIFY_CHANGE_FILE_NAME |
5860 FILE_NOTIFY_CHANGE_DIR_NAME |
5861 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5862 FILE_NOTIFY_CHANGE_LAST_WRITE,
5863 false, print_notifies, NULL);
5864 if (req1 == NULL) {
5865 d_printf("Could not create notify request\n");
5866 return false;
5869 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5870 base_fname, 10, torture_numops);
5871 if (req2 == NULL) {
5872 d_printf("Could not create createdels request\n");
5873 return false;
5875 TALLOC_FREE(base_fname);
5877 tevent_req_set_callback(req2, notify_bench_done,
5878 &num_finished);
5881 while (num_finished < num_unc_names) {
5882 int ret;
5883 ret = tevent_loop_once(ev);
5884 if (ret != 0) {
5885 d_printf("tevent_loop_once failed\n");
5886 return false;
5890 if (!tevent_req_poll(req2, ev)) {
5891 d_printf("tevent_req_poll failed\n");
5894 status = torture_createdels_recv(req2);
5895 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5897 return true;
5900 static bool run_mangle1(int dummy)
5902 struct cli_state *cli;
5903 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5904 uint16_t fnum;
5905 fstring alt_name;
5906 NTSTATUS status;
5907 time_t change_time, access_time, write_time;
5908 SMB_OFF_T size;
5909 uint16_t mode;
5911 printf("starting mangle1 test\n");
5912 if (!torture_open_connection(&cli, 0)) {
5913 return False;
5916 cli_sockopt(cli, sockops);
5918 if (!NT_STATUS_IS_OK(cli_ntcreate(
5919 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5920 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5921 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5922 return false;
5924 cli_close(cli, fnum);
5926 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5927 if (!NT_STATUS_IS_OK(status)) {
5928 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5929 nt_errstr(status));
5930 return false;
5932 d_printf("alt_name: %s\n", alt_name);
5934 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5935 d_printf("cli_open(%s) failed: %s\n", alt_name,
5936 cli_errstr(cli));
5937 return false;
5939 cli_close(cli, fnum);
5941 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5942 &write_time, &size, &mode)) {
5943 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5944 cli_errstr(cli));
5945 return false;
5948 return true;
5951 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5953 size_t *to_pull = (size_t *)priv;
5954 size_t thistime = *to_pull;
5956 thistime = MIN(thistime, n);
5957 if (thistime == 0) {
5958 return 0;
5961 memset(buf, 0, thistime);
5962 *to_pull -= thistime;
5963 return thistime;
5966 static bool run_windows_write(int dummy)
5968 struct cli_state *cli1;
5969 uint16_t fnum;
5970 int i;
5971 bool ret = false;
5972 const char *fname = "\\writetest.txt";
5973 struct timeval start_time;
5974 double seconds;
5975 double kbytes;
5977 printf("starting windows_write test\n");
5978 if (!torture_open_connection(&cli1, 0)) {
5979 return False;
5982 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5983 printf("open failed (%s)\n", cli_errstr(cli1));
5984 return False;
5987 cli_sockopt(cli1, sockops);
5989 start_time = timeval_current();
5991 for (i=0; i<torture_numops; i++) {
5992 char c = 0;
5993 off_t start = i * torture_blocksize;
5994 NTSTATUS status;
5995 size_t to_pull = torture_blocksize - 1;
5997 if (cli_write(cli1, fnum, 0, &c,
5998 start + torture_blocksize - 1, 1) != 1) {
5999 printf("cli_write failed: %s\n", cli_errstr(cli1));
6000 goto fail;
6003 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6004 null_source, &to_pull);
6005 if (!NT_STATUS_IS_OK(status)) {
6006 printf("cli_push returned: %s\n", nt_errstr(status));
6007 goto fail;
6011 seconds = timeval_elapsed(&start_time);
6012 kbytes = (double)torture_blocksize * torture_numops;
6013 kbytes /= 1024;
6015 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6016 (double)seconds, (int)(kbytes/seconds));
6018 ret = true;
6019 fail:
6020 cli_close(cli1, fnum);
6021 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6022 torture_close_connection(cli1);
6023 return ret;
6026 static bool run_cli_echo(int dummy)
6028 struct cli_state *cli;
6029 NTSTATUS status;
6031 printf("starting cli_echo test\n");
6032 if (!torture_open_connection(&cli, 0)) {
6033 return false;
6035 cli_sockopt(cli, sockops);
6037 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6039 d_printf("cli_echo returned %s\n", nt_errstr(status));
6041 torture_close_connection(cli);
6042 return NT_STATUS_IS_OK(status);
6045 static bool run_uid_regression_test(int dummy)
6047 static struct cli_state *cli;
6048 int16_t old_vuid;
6049 int16_t old_cnum;
6050 bool correct = True;
6051 NTSTATUS status;
6053 printf("starting uid regression test\n");
6055 if (!torture_open_connection(&cli, 0)) {
6056 return False;
6059 cli_sockopt(cli, sockops);
6061 /* Ok - now save then logoff our current user. */
6062 old_vuid = cli->vuid;
6064 status = cli_ulogoff(cli);
6065 if (!NT_STATUS_IS_OK(status)) {
6066 d_printf("(%s) cli_ulogoff failed: %s\n",
6067 __location__, nt_errstr(status));
6068 correct = false;
6069 goto out;
6072 cli->vuid = old_vuid;
6074 /* Try an operation. */
6075 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6076 /* We expect bad uid. */
6077 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6078 NT_STATUS_NO_SUCH_USER)) {
6079 return False;
6083 old_cnum = cli->cnum;
6085 /* Now try a SMBtdis with the invald vuid set to zero. */
6086 cli->vuid = 0;
6088 /* This should succeed. */
6089 status = cli_tdis(cli);
6091 if (NT_STATUS_IS_OK(status)) {
6092 printf("First tdis with invalid vuid should succeed.\n");
6093 } else {
6094 printf("First tdis failed (%s)\n", nt_errstr(status));
6097 cli->vuid = old_vuid;
6098 cli->cnum = old_cnum;
6100 /* This should fail. */
6101 status = cli_tdis(cli);
6102 if (NT_STATUS_IS_OK(status)) {
6103 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6104 } else {
6105 /* Should be bad tid. */
6106 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6107 NT_STATUS_NETWORK_NAME_DELETED)) {
6108 return False;
6112 cli_rmdir(cli, "\\uid_reg_test");
6114 out:
6116 cli_shutdown(cli);
6117 return correct;
6121 static const char *illegal_chars = "*\\/?<>|\":";
6122 static char force_shortname_chars[] = " +,.[];=\177";
6124 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
6126 struct cli_state *pcli = (struct cli_state *)state;
6127 fstring fname;
6128 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6130 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6131 return;
6133 if (finfo->mode & aDIR) {
6134 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6135 printf("del_fn: failed to rmdir %s\n,", fname );
6136 } else {
6137 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6138 printf("del_fn: failed to unlink %s\n,", fname );
6142 struct sn_state {
6143 int i;
6144 bool val;
6147 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
6149 struct sn_state *s = (struct sn_state *)state;
6150 int i = s->i;
6152 #if 0
6153 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6154 i, finfo->name, finfo->short_name);
6155 #endif
6157 if (strchr(force_shortname_chars, i)) {
6158 if (!finfo->short_name[0]) {
6159 /* Shortname not created when it should be. */
6160 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6161 __location__, finfo->name, i);
6162 s->val = true;
6164 } else if (finfo->short_name[0]){
6165 /* Shortname created when it should not be. */
6166 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6167 __location__, finfo->short_name, finfo->name);
6168 s->val = true;
6172 static bool run_shortname_test(int dummy)
6174 static struct cli_state *cli;
6175 bool correct = True;
6176 int i;
6177 struct sn_state s;
6178 char fname[20];
6180 printf("starting shortname test\n");
6182 if (!torture_open_connection(&cli, 0)) {
6183 return False;
6186 cli_sockopt(cli, sockops);
6188 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6189 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6190 cli_rmdir(cli, "\\shortname");
6192 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6193 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6194 __location__, cli_errstr(cli));
6195 correct = false;
6196 goto out;
6199 strlcpy(fname, "\\shortname\\", sizeof(fname));
6200 strlcat(fname, "test .txt", sizeof(fname));
6202 s.val = false;
6204 for (i = 32; i < 128; i++) {
6205 NTSTATUS status;
6206 uint16_t fnum = (uint16_t)-1;
6208 s.i = i;
6210 if (strchr(illegal_chars, i)) {
6211 continue;
6213 fname[15] = i;
6215 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6216 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6217 if (!NT_STATUS_IS_OK(status)) {
6218 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6219 __location__, fname, cli_errstr(cli));
6220 correct = false;
6221 goto out;
6223 cli_close(cli, fnum);
6224 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
6225 d_printf("(%s) failed to list %s: %s\n",
6226 __location__, fname, cli_errstr(cli));
6227 correct = false;
6228 goto out;
6230 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6231 d_printf("(%s) failed to delete %s: %s\n",
6232 __location__, fname, cli_errstr(cli));
6233 correct = false;
6234 goto out;
6237 if (s.val) {
6238 correct = false;
6239 goto out;
6243 out:
6245 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6246 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6247 cli_rmdir(cli, "\\shortname");
6248 torture_close_connection(cli);
6249 return correct;
6252 static void pagedsearch_cb(struct tevent_req *req)
6254 int rc;
6255 struct tldap_message *msg;
6256 char *dn;
6258 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6259 if (rc != TLDAP_SUCCESS) {
6260 d_printf("tldap_search_paged_recv failed: %s\n",
6261 tldap_err2string(rc));
6262 return;
6264 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6265 TALLOC_FREE(msg);
6266 return;
6268 if (!tldap_entry_dn(msg, &dn)) {
6269 d_printf("tldap_entry_dn failed\n");
6270 return;
6272 d_printf("%s\n", dn);
6273 TALLOC_FREE(msg);
6276 static bool run_tldap(int dummy)
6278 struct tldap_context *ld;
6279 int fd, rc;
6280 NTSTATUS status;
6281 struct sockaddr_storage addr;
6282 struct tevent_context *ev;
6283 struct tevent_req *req;
6284 char *basedn;
6286 if (!resolve_name(host, &addr, 0, false)) {
6287 d_printf("could not find host %s\n", host);
6288 return false;
6290 status = open_socket_out(&addr, 389, 9999, &fd);
6291 if (!NT_STATUS_IS_OK(status)) {
6292 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6293 return false;
6296 ld = tldap_context_create(talloc_tos(), fd);
6297 if (ld == NULL) {
6298 close(fd);
6299 d_printf("tldap_context_create failed\n");
6300 return false;
6303 rc = tldap_fetch_rootdse(ld);
6304 if (rc != TLDAP_SUCCESS) {
6305 d_printf("tldap_fetch_rootdse failed: %s\n",
6306 tldap_errstr(talloc_tos(), ld, rc));
6307 return false;
6310 basedn = tldap_talloc_single_attribute(
6311 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6312 if (basedn == NULL) {
6313 d_printf("no defaultNamingContext\n");
6314 return false;
6316 d_printf("defaultNamingContext: %s\n", basedn);
6318 ev = tevent_context_init(talloc_tos());
6319 if (ev == NULL) {
6320 d_printf("tevent_context_init failed\n");
6321 return false;
6324 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6325 TLDAP_SCOPE_SUB, "(objectclass=*)",
6326 NULL, 0, 0,
6327 NULL, 0, NULL, 0, 0, 0, 0, 5);
6328 if (req == NULL) {
6329 d_printf("tldap_search_paged_send failed\n");
6330 return false;
6332 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6334 tevent_req_poll(req, ev);
6336 TALLOC_FREE(req);
6338 TALLOC_FREE(ld);
6339 return true;
6342 static bool run_streamerror(int dummy)
6344 struct cli_state *cli;
6345 const char *dname = "\\testdir";
6346 const char *streamname =
6347 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6348 NTSTATUS status;
6349 time_t change_time, access_time, write_time;
6350 SMB_OFF_T size;
6351 uint16_t mode, fnum;
6352 bool ret = true;
6354 if (!torture_open_connection(&cli, 0)) {
6355 return false;
6358 cli_rmdir(cli, dname);
6360 status = cli_mkdir(cli, dname);
6361 if (!NT_STATUS_IS_OK(status)) {
6362 printf("mkdir failed: %s\n", nt_errstr(status));
6363 return false;
6366 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
6367 &size, &mode);
6368 status = cli_nt_error(cli);
6370 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6371 printf("pathinfo returned %s, expected "
6372 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6373 nt_errstr(status));
6374 ret = false;
6377 status = cli_ntcreate(cli, streamname, 0x16,
6378 FILE_READ_DATA|FILE_READ_EA|
6379 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6380 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6381 FILE_OPEN, 0, 0, &fnum);
6383 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6384 printf("ntcreate returned %s, expected "
6385 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6386 nt_errstr(status));
6387 ret = false;
6391 cli_rmdir(cli, dname);
6392 return ret;
6395 static bool run_local_substitute(int dummy)
6397 bool ok = true;
6399 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6400 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6401 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6402 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6403 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6404 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6405 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6406 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6408 /* Different captialization rules in sub_basic... */
6410 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6411 "blaDOM") == 0);
6413 return ok;
6416 static bool run_local_base64(int dummy)
6418 int i;
6419 bool ret = true;
6421 for (i=1; i<2000; i++) {
6422 DATA_BLOB blob1, blob2;
6423 char *b64;
6425 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6426 blob1.length = i;
6427 generate_random_buffer(blob1.data, blob1.length);
6429 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6430 if (b64 == NULL) {
6431 d_fprintf(stderr, "base64_encode_data_blob failed "
6432 "for %d bytes\n", i);
6433 ret = false;
6435 blob2 = base64_decode_data_blob(b64);
6436 TALLOC_FREE(b64);
6438 if (data_blob_cmp(&blob1, &blob2)) {
6439 d_fprintf(stderr, "data_blob_cmp failed for %d "
6440 "bytes\n", i);
6441 ret = false;
6443 TALLOC_FREE(blob1.data);
6444 data_blob_free(&blob2);
6446 return ret;
6449 static bool run_local_gencache(int dummy)
6451 char *val;
6452 time_t tm;
6453 DATA_BLOB blob;
6455 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6456 d_printf("%s: gencache_set() failed\n", __location__);
6457 return False;
6460 if (!gencache_get("foo", NULL, NULL)) {
6461 d_printf("%s: gencache_get() failed\n", __location__);
6462 return False;
6465 if (!gencache_get("foo", &val, &tm)) {
6466 d_printf("%s: gencache_get() failed\n", __location__);
6467 return False;
6470 if (strcmp(val, "bar") != 0) {
6471 d_printf("%s: gencache_get() returned %s, expected %s\n",
6472 __location__, val, "bar");
6473 SAFE_FREE(val);
6474 return False;
6477 SAFE_FREE(val);
6479 if (!gencache_del("foo")) {
6480 d_printf("%s: gencache_del() failed\n", __location__);
6481 return False;
6483 if (gencache_del("foo")) {
6484 d_printf("%s: second gencache_del() succeeded\n",
6485 __location__);
6486 return False;
6489 if (gencache_get("foo", &val, &tm)) {
6490 d_printf("%s: gencache_get() on deleted entry "
6491 "succeeded\n", __location__);
6492 return False;
6495 blob = data_blob_string_const_null("bar");
6496 tm = time(NULL) + 60;
6498 if (!gencache_set_data_blob("foo", &blob, tm)) {
6499 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6500 return False;
6503 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6504 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6505 return False;
6508 if (strcmp((const char *)blob.data, "bar") != 0) {
6509 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6510 __location__, (const char *)blob.data, "bar");
6511 data_blob_free(&blob);
6512 return False;
6515 data_blob_free(&blob);
6517 if (!gencache_del("foo")) {
6518 d_printf("%s: gencache_del() failed\n", __location__);
6519 return False;
6521 if (gencache_del("foo")) {
6522 d_printf("%s: second gencache_del() succeeded\n",
6523 __location__);
6524 return False;
6527 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6528 d_printf("%s: gencache_get_data_blob() on deleted entry "
6529 "succeeded\n", __location__);
6530 return False;
6533 return True;
6536 static bool rbt_testval(struct db_context *db, const char *key,
6537 const char *value)
6539 struct db_record *rec;
6540 TDB_DATA data = string_tdb_data(value);
6541 bool ret = false;
6542 NTSTATUS status;
6544 rec = db->fetch_locked(db, db, string_tdb_data(key));
6545 if (rec == NULL) {
6546 d_fprintf(stderr, "fetch_locked failed\n");
6547 goto done;
6549 status = rec->store(rec, data, 0);
6550 if (!NT_STATUS_IS_OK(status)) {
6551 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6552 goto done;
6554 TALLOC_FREE(rec);
6556 rec = db->fetch_locked(db, db, string_tdb_data(key));
6557 if (rec == NULL) {
6558 d_fprintf(stderr, "second fetch_locked failed\n");
6559 goto done;
6561 if ((rec->value.dsize != data.dsize)
6562 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6563 d_fprintf(stderr, "Got wrong data back\n");
6564 goto done;
6567 ret = true;
6568 done:
6569 TALLOC_FREE(rec);
6570 return ret;
6573 static bool run_local_rbtree(int dummy)
6575 struct db_context *db;
6576 bool ret = false;
6577 int i;
6579 db = db_open_rbt(NULL);
6581 if (db == NULL) {
6582 d_fprintf(stderr, "db_open_rbt failed\n");
6583 return false;
6586 for (i=0; i<1000; i++) {
6587 char *key, *value;
6589 if (asprintf(&key, "key%ld", random()) == -1) {
6590 goto done;
6592 if (asprintf(&value, "value%ld", random()) == -1) {
6593 SAFE_FREE(key);
6594 goto done;
6597 if (!rbt_testval(db, key, value)) {
6598 SAFE_FREE(key);
6599 SAFE_FREE(value);
6600 goto done;
6603 SAFE_FREE(value);
6604 if (asprintf(&value, "value%ld", random()) == -1) {
6605 SAFE_FREE(key);
6606 goto done;
6609 if (!rbt_testval(db, key, value)) {
6610 SAFE_FREE(key);
6611 SAFE_FREE(value);
6612 goto done;
6615 SAFE_FREE(key);
6616 SAFE_FREE(value);
6619 ret = true;
6621 done:
6622 TALLOC_FREE(db);
6623 return ret;
6626 struct talloc_dict_test {
6627 int content;
6630 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6632 int *count = (int *)priv;
6633 *count += 1;
6634 return 0;
6637 static bool run_local_talloc_dict(int dummy)
6639 struct talloc_dict *dict;
6640 struct talloc_dict_test *t;
6641 int key, count;
6643 dict = talloc_dict_init(talloc_tos());
6644 if (dict == NULL) {
6645 return false;
6648 t = talloc(talloc_tos(), struct talloc_dict_test);
6649 if (t == NULL) {
6650 return false;
6653 key = 1;
6654 t->content = 1;
6655 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6656 return false;
6659 count = 0;
6660 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6661 return false;
6664 if (count != 1) {
6665 return false;
6668 TALLOC_FREE(dict);
6670 return true;
6673 /* Split a path name into filename and stream name components. Canonicalise
6674 * such that an implicit $DATA token is always explicit.
6676 * The "specification" of this function can be found in the
6677 * run_local_stream_name() function in torture.c, I've tried those
6678 * combinations against a W2k3 server.
6681 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6682 char **pbase, char **pstream)
6684 char *base = NULL;
6685 char *stream = NULL;
6686 char *sname; /* stream name */
6687 const char *stype; /* stream type */
6689 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6691 sname = strchr_m(fname, ':');
6693 if (lp_posix_pathnames() || (sname == NULL)) {
6694 if (pbase != NULL) {
6695 base = talloc_strdup(mem_ctx, fname);
6696 NT_STATUS_HAVE_NO_MEMORY(base);
6698 goto done;
6701 if (pbase != NULL) {
6702 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6703 NT_STATUS_HAVE_NO_MEMORY(base);
6706 sname += 1;
6708 stype = strchr_m(sname, ':');
6710 if (stype == NULL) {
6711 sname = talloc_strdup(mem_ctx, sname);
6712 stype = "$DATA";
6714 else {
6715 if (StrCaseCmp(stype, ":$DATA") != 0) {
6717 * If there is an explicit stream type, so far we only
6718 * allow $DATA. Is there anything else allowed? -- vl
6720 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6721 TALLOC_FREE(base);
6722 return NT_STATUS_OBJECT_NAME_INVALID;
6724 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6725 stype += 1;
6728 if (sname == NULL) {
6729 TALLOC_FREE(base);
6730 return NT_STATUS_NO_MEMORY;
6733 if (sname[0] == '\0') {
6735 * no stream name, so no stream
6737 goto done;
6740 if (pstream != NULL) {
6741 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6742 if (stream == NULL) {
6743 TALLOC_FREE(sname);
6744 TALLOC_FREE(base);
6745 return NT_STATUS_NO_MEMORY;
6748 * upper-case the type field
6750 strupper_m(strchr_m(stream, ':')+1);
6753 done:
6754 if (pbase != NULL) {
6755 *pbase = base;
6757 if (pstream != NULL) {
6758 *pstream = stream;
6760 return NT_STATUS_OK;
6763 static bool test_stream_name(const char *fname, const char *expected_base,
6764 const char *expected_stream,
6765 NTSTATUS expected_status)
6767 NTSTATUS status;
6768 char *base = NULL;
6769 char *stream = NULL;
6771 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6772 if (!NT_STATUS_EQUAL(status, expected_status)) {
6773 goto error;
6776 if (!NT_STATUS_IS_OK(status)) {
6777 return true;
6780 if (base == NULL) goto error;
6782 if (strcmp(expected_base, base) != 0) goto error;
6784 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6785 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6787 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6788 goto error;
6790 TALLOC_FREE(base);
6791 TALLOC_FREE(stream);
6792 return true;
6794 error:
6795 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6796 fname, expected_base ? expected_base : "<NULL>",
6797 expected_stream ? expected_stream : "<NULL>",
6798 nt_errstr(expected_status));
6799 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6800 base ? base : "<NULL>", stream ? stream : "<NULL>",
6801 nt_errstr(status));
6802 TALLOC_FREE(base);
6803 TALLOC_FREE(stream);
6804 return false;
6807 static bool run_local_stream_name(int dummy)
6809 bool ret = true;
6811 ret &= test_stream_name(
6812 "bla", "bla", NULL, NT_STATUS_OK);
6813 ret &= test_stream_name(
6814 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6815 ret &= test_stream_name(
6816 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6817 ret &= test_stream_name(
6818 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6819 ret &= test_stream_name(
6820 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6821 ret &= test_stream_name(
6822 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6823 ret &= test_stream_name(
6824 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6825 ret &= test_stream_name(
6826 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6828 return ret;
6831 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6833 if (a.length != b.length) {
6834 printf("a.length=%d != b.length=%d\n",
6835 (int)a.length, (int)b.length);
6836 return false;
6838 if (memcmp(a.data, b.data, a.length) != 0) {
6839 printf("a.data and b.data differ\n");
6840 return false;
6842 return true;
6845 static bool run_local_memcache(int dummy)
6847 struct memcache *cache;
6848 DATA_BLOB k1, k2;
6849 DATA_BLOB d1, d2, d3;
6850 DATA_BLOB v1, v2, v3;
6852 TALLOC_CTX *mem_ctx;
6853 char *str1, *str2;
6854 size_t size1, size2;
6855 bool ret = false;
6857 cache = memcache_init(NULL, 100);
6859 if (cache == NULL) {
6860 printf("memcache_init failed\n");
6861 return false;
6864 d1 = data_blob_const("d1", 2);
6865 d2 = data_blob_const("d2", 2);
6866 d3 = data_blob_const("d3", 2);
6868 k1 = data_blob_const("d1", 2);
6869 k2 = data_blob_const("d2", 2);
6871 memcache_add(cache, STAT_CACHE, k1, d1);
6872 memcache_add(cache, GETWD_CACHE, k2, d2);
6874 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6875 printf("could not find k1\n");
6876 return false;
6878 if (!data_blob_equal(d1, v1)) {
6879 return false;
6882 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6883 printf("could not find k2\n");
6884 return false;
6886 if (!data_blob_equal(d2, v2)) {
6887 return false;
6890 memcache_add(cache, STAT_CACHE, k1, d3);
6892 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
6893 printf("could not find replaced k1\n");
6894 return false;
6896 if (!data_blob_equal(d3, v3)) {
6897 return false;
6900 memcache_add(cache, GETWD_CACHE, k1, d1);
6902 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6903 printf("Did find k2, should have been purged\n");
6904 return false;
6907 TALLOC_FREE(cache);
6909 cache = memcache_init(NULL, 0);
6911 mem_ctx = talloc_init("foo");
6913 str1 = talloc_strdup(mem_ctx, "string1");
6914 str2 = talloc_strdup(mem_ctx, "string2");
6916 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6917 data_blob_string_const("torture"), &str1);
6918 size1 = talloc_total_size(cache);
6920 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6921 data_blob_string_const("torture"), &str2);
6922 size2 = talloc_total_size(cache);
6924 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
6926 if (size2 > size1) {
6927 printf("memcache leaks memory!\n");
6928 goto fail;
6931 ret = true;
6932 fail:
6933 TALLOC_FREE(cache);
6934 return ret;
6937 static void wbclient_done(struct tevent_req *req)
6939 wbcErr wbc_err;
6940 struct winbindd_response *wb_resp;
6941 int *i = (int *)tevent_req_callback_data_void(req);
6943 wbc_err = wb_trans_recv(req, req, &wb_resp);
6944 TALLOC_FREE(req);
6945 *i += 1;
6946 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
6949 static bool run_local_wbclient(int dummy)
6951 struct event_context *ev;
6952 struct wb_context **wb_ctx;
6953 struct winbindd_request wb_req;
6954 bool result = false;
6955 int i, j;
6957 BlockSignals(True, SIGPIPE);
6959 ev = tevent_context_init_byname(talloc_tos(), "epoll");
6960 if (ev == NULL) {
6961 goto fail;
6964 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
6965 if (wb_ctx == NULL) {
6966 goto fail;
6969 ZERO_STRUCT(wb_req);
6970 wb_req.cmd = WINBINDD_PING;
6972 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
6974 for (i=0; i<nprocs; i++) {
6975 wb_ctx[i] = wb_context_init(ev, NULL);
6976 if (wb_ctx[i] == NULL) {
6977 goto fail;
6979 for (j=0; j<torture_numops; j++) {
6980 struct tevent_req *req;
6981 req = wb_trans_send(ev, ev, wb_ctx[i],
6982 (j % 2) == 0, &wb_req);
6983 if (req == NULL) {
6984 goto fail;
6986 tevent_req_set_callback(req, wbclient_done, &i);
6990 i = 0;
6992 while (i < nprocs * torture_numops) {
6993 event_loop_once(ev);
6996 result = true;
6997 fail:
6998 TALLOC_FREE(ev);
6999 return result;
7002 static void getaddrinfo_finished(struct tevent_req *req)
7004 char *name = (char *)tevent_req_callback_data_void(req);
7005 struct addrinfo *ainfo;
7006 int res;
7008 res = getaddrinfo_recv(req, &ainfo);
7009 if (res != 0) {
7010 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7011 return;
7013 d_printf("gai(%s) succeeded\n", name);
7014 freeaddrinfo(ainfo);
7017 static bool run_getaddrinfo_send(int dummy)
7019 TALLOC_CTX *frame = talloc_stackframe();
7020 struct fncall_context *ctx;
7021 struct tevent_context *ev;
7022 bool result = false;
7023 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7024 "www.slashdot.org", "heise.de" };
7025 struct tevent_req *reqs[4];
7026 int i;
7028 ev = event_context_init(frame);
7029 if (ev == NULL) {
7030 goto fail;
7033 ctx = fncall_context_init(frame, 4);
7035 for (i=0; i<ARRAY_SIZE(names); i++) {
7036 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7037 NULL);
7038 if (reqs[i] == NULL) {
7039 goto fail;
7041 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7042 (void *)names[i]);
7045 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7046 tevent_loop_once(ev);
7049 result = true;
7050 fail:
7051 TALLOC_FREE(frame);
7052 return result;
7056 static double create_procs(bool (*fn)(int), bool *result)
7058 int i, status;
7059 volatile pid_t *child_status;
7060 volatile bool *child_status_out;
7061 int synccount;
7062 int tries = 8;
7063 struct timeval start;
7065 synccount = 0;
7067 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7068 if (!child_status) {
7069 printf("Failed to setup shared memory\n");
7070 return -1;
7073 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7074 if (!child_status_out) {
7075 printf("Failed to setup result status shared memory\n");
7076 return -1;
7079 for (i = 0; i < nprocs; i++) {
7080 child_status[i] = 0;
7081 child_status_out[i] = True;
7084 start = timeval_current();
7086 for (i=0;i<nprocs;i++) {
7087 procnum = i;
7088 if (fork() == 0) {
7089 pid_t mypid = getpid();
7090 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7092 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7094 while (1) {
7095 if (torture_open_connection(&current_cli, i)) break;
7096 if (tries-- == 0) {
7097 printf("pid %d failed to start\n", (int)getpid());
7098 _exit(1);
7100 smb_msleep(10);
7103 child_status[i] = getpid();
7105 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7107 child_status_out[i] = fn(i);
7108 _exit(0);
7112 do {
7113 synccount = 0;
7114 for (i=0;i<nprocs;i++) {
7115 if (child_status[i]) synccount++;
7117 if (synccount == nprocs) break;
7118 smb_msleep(10);
7119 } while (timeval_elapsed(&start) < 30);
7121 if (synccount != nprocs) {
7122 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7123 *result = False;
7124 return timeval_elapsed(&start);
7127 /* start the client load */
7128 start = timeval_current();
7130 for (i=0;i<nprocs;i++) {
7131 child_status[i] = 0;
7134 printf("%d clients started\n", nprocs);
7136 for (i=0;i<nprocs;i++) {
7137 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7140 printf("\n");
7142 for (i=0;i<nprocs;i++) {
7143 if (!child_status_out[i]) {
7144 *result = False;
7147 return timeval_elapsed(&start);
7150 #define FLAG_MULTIPROC 1
7152 static struct {
7153 const char *name;
7154 bool (*fn)(int);
7155 unsigned flags;
7156 } torture_ops[] = {
7157 {"FDPASS", run_fdpasstest, 0},
7158 {"LOCK1", run_locktest1, 0},
7159 {"LOCK2", run_locktest2, 0},
7160 {"LOCK3", run_locktest3, 0},
7161 {"LOCK4", run_locktest4, 0},
7162 {"LOCK5", run_locktest5, 0},
7163 {"LOCK6", run_locktest6, 0},
7164 {"LOCK7", run_locktest7, 0},
7165 {"LOCK8", run_locktest8, 0},
7166 {"LOCK9", run_locktest9, 0},
7167 {"UNLINK", run_unlinktest, 0},
7168 {"BROWSE", run_browsetest, 0},
7169 {"ATTR", run_attrtest, 0},
7170 {"TRANS2", run_trans2test, 0},
7171 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7172 {"TORTURE",run_torture, FLAG_MULTIPROC},
7173 {"RANDOMIPC", run_randomipc, 0},
7174 {"NEGNOWAIT", run_negprot_nowait, 0},
7175 {"NBENCH", run_nbench, 0},
7176 {"OPLOCK1", run_oplock1, 0},
7177 {"OPLOCK2", run_oplock2, 0},
7178 {"OPLOCK3", run_oplock3, 0},
7179 {"DIR", run_dirtest, 0},
7180 {"DIR1", run_dirtest1, 0},
7181 {"DENY1", torture_denytest1, 0},
7182 {"DENY2", torture_denytest2, 0},
7183 {"TCON", run_tcon_test, 0},
7184 {"TCONDEV", run_tcon_devtype_test, 0},
7185 {"RW1", run_readwritetest, 0},
7186 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7187 {"RW3", run_readwritelarge, 0},
7188 {"OPEN", run_opentest, 0},
7189 {"POSIX", run_simple_posix_open_test, 0},
7190 {"POSIX-APPEND", run_posix_append, 0},
7191 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7192 { "SHORTNAME-TEST", run_shortname_test, 0},
7193 #if 1
7194 {"OPENATTR", run_openattrtest, 0},
7195 #endif
7196 {"XCOPY", run_xcopy, 0},
7197 {"RENAME", run_rename, 0},
7198 {"DELETE", run_deletetest, 0},
7199 {"PROPERTIES", run_properties, 0},
7200 {"MANGLE", torture_mangle, 0},
7201 {"MANGLE1", run_mangle1, 0},
7202 {"W2K", run_w2ktest, 0},
7203 {"TRANS2SCAN", torture_trans2_scan, 0},
7204 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7205 {"UTABLE", torture_utable, 0},
7206 {"CASETABLE", torture_casetable, 0},
7207 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7208 {"PIPE_NUMBER", run_pipe_number, 0},
7209 {"TCON2", run_tcon2_test, 0},
7210 {"IOCTL", torture_ioctl_test, 0},
7211 {"CHKPATH", torture_chkpath_test, 0},
7212 {"FDSESS", run_fdsesstest, 0},
7213 { "EATEST", run_eatest, 0},
7214 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7215 { "CHAIN1", run_chain1, 0},
7216 { "CHAIN2", run_chain2, 0},
7217 { "WINDOWS-WRITE", run_windows_write, 0},
7218 { "CLI_ECHO", run_cli_echo, 0},
7219 { "GETADDRINFO", run_getaddrinfo_send, 0},
7220 { "TLDAP", run_tldap },
7221 { "STREAMERROR", run_streamerror },
7222 { "NOTIFY-BENCH", run_notify_bench },
7223 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7224 { "LOCAL-GENCACHE", run_local_gencache, 0},
7225 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7226 { "LOCAL-BASE64", run_local_base64, 0},
7227 { "LOCAL-RBTREE", run_local_rbtree, 0},
7228 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7229 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7230 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7231 {NULL, NULL, 0}};
7235 /****************************************************************************
7236 run a specified test or "ALL"
7237 ****************************************************************************/
7238 static bool run_test(const char *name)
7240 bool ret = True;
7241 bool result = True;
7242 bool found = False;
7243 int i;
7244 double t;
7245 if (strequal(name,"ALL")) {
7246 for (i=0;torture_ops[i].name;i++) {
7247 run_test(torture_ops[i].name);
7249 found = True;
7252 for (i=0;torture_ops[i].name;i++) {
7253 fstr_sprintf(randomfname, "\\XX%x",
7254 (unsigned)random());
7256 if (strequal(name, torture_ops[i].name)) {
7257 found = True;
7258 printf("Running %s\n", name);
7259 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7260 t = create_procs(torture_ops[i].fn, &result);
7261 if (!result) {
7262 ret = False;
7263 printf("TEST %s FAILED!\n", name);
7265 } else {
7266 struct timeval start;
7267 start = timeval_current();
7268 if (!torture_ops[i].fn(0)) {
7269 ret = False;
7270 printf("TEST %s FAILED!\n", name);
7272 t = timeval_elapsed(&start);
7274 printf("%s took %g secs\n\n", name, t);
7278 if (!found) {
7279 printf("Did not find a test named %s\n", name);
7280 ret = False;
7283 return ret;
7287 static void usage(void)
7289 int i;
7291 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7292 printf("Please use samba4 torture.\n\n");
7294 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7296 printf("\t-d debuglevel\n");
7297 printf("\t-U user%%pass\n");
7298 printf("\t-k use kerberos\n");
7299 printf("\t-N numprocs\n");
7300 printf("\t-n my_netbios_name\n");
7301 printf("\t-W workgroup\n");
7302 printf("\t-o num_operations\n");
7303 printf("\t-O socket_options\n");
7304 printf("\t-m maximum protocol\n");
7305 printf("\t-L use oplocks\n");
7306 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7307 printf("\t-A showall\n");
7308 printf("\t-p port\n");
7309 printf("\t-s seed\n");
7310 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7311 printf("\n\n");
7313 printf("tests are:");
7314 for (i=0;torture_ops[i].name;i++) {
7315 printf(" %s", torture_ops[i].name);
7317 printf("\n");
7319 printf("default test is ALL\n");
7321 exit(1);
7324 /****************************************************************************
7325 main program
7326 ****************************************************************************/
7327 int main(int argc,char *argv[])
7329 int opt, i;
7330 char *p;
7331 int gotuser = 0;
7332 int gotpass = 0;
7333 bool correct = True;
7334 TALLOC_CTX *frame = talloc_stackframe();
7335 int seed = time(NULL);
7337 dbf = x_stdout;
7339 #ifdef HAVE_SETBUFFER
7340 setbuffer(stdout, NULL, 0);
7341 #endif
7343 load_case_tables();
7345 if (is_default_dyn_CONFIGFILE()) {
7346 if(getenv("SMB_CONF_PATH")) {
7347 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7350 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7351 load_interfaces();
7353 if (argc < 2) {
7354 usage();
7357 for(p = argv[1]; *p; p++)
7358 if(*p == '\\')
7359 *p = '/';
7361 if (strncmp(argv[1], "//", 2)) {
7362 usage();
7365 fstrcpy(host, &argv[1][2]);
7366 p = strchr_m(&host[2],'/');
7367 if (!p) {
7368 usage();
7370 *p = 0;
7371 fstrcpy(share, p+1);
7373 fstrcpy(myname, get_myname(talloc_tos()));
7374 if (!*myname) {
7375 fprintf(stderr, "Failed to get my hostname.\n");
7376 return 1;
7379 if (*username == 0 && getenv("LOGNAME")) {
7380 fstrcpy(username,getenv("LOGNAME"));
7383 argc--;
7384 argv++;
7386 fstrcpy(workgroup, lp_workgroup());
7388 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7389 switch (opt) {
7390 case 'p':
7391 port_to_use = atoi(optarg);
7392 break;
7393 case 's':
7394 seed = atoi(optarg);
7395 break;
7396 case 'W':
7397 fstrcpy(workgroup,optarg);
7398 break;
7399 case 'm':
7400 max_protocol = interpret_protocol(optarg, max_protocol);
7401 break;
7402 case 'N':
7403 nprocs = atoi(optarg);
7404 break;
7405 case 'o':
7406 torture_numops = atoi(optarg);
7407 break;
7408 case 'd':
7409 DEBUGLEVEL = atoi(optarg);
7410 break;
7411 case 'O':
7412 sockops = optarg;
7413 break;
7414 case 'L':
7415 use_oplocks = True;
7416 break;
7417 case 'l':
7418 local_path = optarg;
7419 break;
7420 case 'A':
7421 torture_showall = True;
7422 break;
7423 case 'n':
7424 fstrcpy(myname, optarg);
7425 break;
7426 case 'c':
7427 client_txt = optarg;
7428 break;
7429 case 'e':
7430 do_encrypt = true;
7431 break;
7432 case 'k':
7433 #ifdef HAVE_KRB5
7434 use_kerberos = True;
7435 #else
7436 d_printf("No kerberos support compiled in\n");
7437 exit(1);
7438 #endif
7439 break;
7440 case 'U':
7441 gotuser = 1;
7442 fstrcpy(username,optarg);
7443 p = strchr_m(username,'%');
7444 if (p) {
7445 *p = 0;
7446 fstrcpy(password, p+1);
7447 gotpass = 1;
7449 break;
7450 case 'b':
7451 fstrcpy(multishare_conn_fname, optarg);
7452 use_multishare_conn = True;
7453 break;
7454 case 'B':
7455 torture_blocksize = atoi(optarg);
7456 break;
7457 default:
7458 printf("Unknown option %c (%d)\n", (char)opt, opt);
7459 usage();
7463 d_printf("using seed %d\n", seed);
7465 srandom(seed);
7467 if(use_kerberos && !gotuser) gotpass = True;
7469 while (!gotpass) {
7470 p = getpass("Password:");
7471 if (p) {
7472 fstrcpy(password, p);
7473 gotpass = 1;
7477 printf("host=%s share=%s user=%s myname=%s\n",
7478 host, share, username, myname);
7480 if (argc == optind) {
7481 correct = run_test("ALL");
7482 } else {
7483 for (i=optind;i<argc;i++) {
7484 if (!run_test(argv[i])) {
7485 correct = False;
7490 TALLOC_FREE(frame);
7492 if (correct) {
7493 return(0);
7494 } else {
7495 return(1);