s3:torture: use timeval_current/timeval_elapsed instead of start_timer/end_timer
[Samba/fernandojvsilva.git] / source3 / torture / torture.c
blob39f555906696d2b3ac828f3fb261c1515581366a
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 if (!cli_tdis(c)) {
368 printf("tdis failed (%s)\n", cli_errstr(c));
369 ret = False;
372 cli_shutdown(c);
374 return ret;
378 /* check if the server produced the expected error code */
379 static bool check_error(int line, struct cli_state *c,
380 uint8 eclass, uint32 ecode, NTSTATUS nterr)
382 if (cli_is_dos_error(c)) {
383 uint8 cclass;
384 uint32 num;
386 /* Check DOS error */
388 cli_dos_error(c, &cclass, &num);
390 if (eclass != cclass || ecode != num) {
391 printf("unexpected error code class=%d code=%d\n",
392 (int)cclass, (int)num);
393 printf(" expected %d/%d %s (line=%d)\n",
394 (int)eclass, (int)ecode, nt_errstr(nterr), line);
395 return False;
398 } else {
399 NTSTATUS status;
401 /* Check NT error */
403 status = cli_nt_error(c);
405 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
406 printf("unexpected error code %s\n", nt_errstr(status));
407 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
408 return False;
412 return True;
416 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
418 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
419 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
421 return True;
425 static bool rw_torture(struct cli_state *c)
427 const char *lockfname = "\\torture.lck";
428 fstring fname;
429 uint16_t fnum;
430 uint16_t fnum2;
431 pid_t pid2, pid = getpid();
432 int i, j;
433 char buf[1024];
434 bool correct = True;
435 NTSTATUS status;
437 memset(buf, '\0', sizeof(buf));
439 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
440 DENY_NONE, &fnum2);
441 if (!NT_STATUS_IS_OK(status)) {
442 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
444 if (!NT_STATUS_IS_OK(status)) {
445 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
446 return False;
449 for (i=0;i<torture_numops;i++) {
450 unsigned n = (unsigned)sys_random()%10;
451 if (i % 10 == 0) {
452 printf("%d\r", i); fflush(stdout);
454 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
456 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
457 return False;
460 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
461 printf("open failed (%s)\n", cli_errstr(c));
462 correct = False;
463 break;
466 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
467 printf("write failed (%s)\n", cli_errstr(c));
468 correct = False;
471 for (j=0;j<50;j++) {
472 if (cli_write(c, fnum, 0, (char *)buf,
473 sizeof(pid)+(j*sizeof(buf)),
474 sizeof(buf)) != sizeof(buf)) {
475 printf("write failed (%s)\n", cli_errstr(c));
476 correct = False;
480 pid2 = 0;
482 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
483 printf("read failed (%s)\n", cli_errstr(c));
484 correct = False;
487 if (pid2 != pid) {
488 printf("data corruption!\n");
489 correct = False;
492 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
493 printf("close failed (%s)\n", cli_errstr(c));
494 correct = False;
497 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
498 printf("unlink failed (%s)\n", cli_errstr(c));
499 correct = False;
502 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
503 printf("unlock failed (%s)\n", cli_errstr(c));
504 correct = False;
508 cli_close(c, fnum2);
509 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
511 printf("%d\n", i);
513 return correct;
516 static bool run_torture(int dummy)
518 struct cli_state *cli;
519 bool ret;
521 cli = current_cli;
523 cli_sockopt(cli, sockops);
525 ret = rw_torture(cli);
527 if (!torture_close_connection(cli)) {
528 ret = False;
531 return ret;
534 static bool rw_torture3(struct cli_state *c, char *lockfname)
536 uint16_t fnum = (uint16_t)-1;
537 unsigned int i = 0;
538 char buf[131072];
539 char buf_rd[131072];
540 unsigned count;
541 unsigned countprev = 0;
542 ssize_t sent = 0;
543 bool correct = True;
544 NTSTATUS status;
546 srandom(1);
547 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
549 SIVAL(buf, i, sys_random());
552 if (procnum == 0)
554 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
555 DENY_NONE, &fnum))) {
556 printf("first open read/write of %s failed (%s)\n",
557 lockfname, cli_errstr(c));
558 return False;
561 else
563 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
565 status = cli_open(c, lockfname, O_RDONLY,
566 DENY_NONE, &fnum);
567 if (!NT_STATUS_IS_OK(status)) {
568 break;
570 smb_msleep(10);
572 if (!NT_STATUS_IS_OK(status)) {
573 printf("second open read-only of %s failed (%s)\n",
574 lockfname, cli_errstr(c));
575 return False;
579 i = 0;
580 for (count = 0; count < sizeof(buf); count += sent)
582 if (count >= countprev) {
583 printf("%d %8d\r", i, count);
584 fflush(stdout);
585 i++;
586 countprev += (sizeof(buf) / 20);
589 if (procnum == 0)
591 sent = ((unsigned)sys_random()%(20))+ 1;
592 if (sent > sizeof(buf) - count)
594 sent = sizeof(buf) - count;
597 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
598 printf("write failed (%s)\n", cli_errstr(c));
599 correct = False;
602 else
604 sent = cli_read(c, fnum, buf_rd+count, count,
605 sizeof(buf)-count);
606 if (sent < 0)
608 printf("read failed offset:%d size:%ld (%s)\n",
609 count, (unsigned long)sizeof(buf)-count,
610 cli_errstr(c));
611 correct = False;
612 sent = 0;
614 if (sent > 0)
616 if (memcmp(buf_rd+count, buf+count, sent) != 0)
618 printf("read/write compare failed\n");
619 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
620 correct = False;
621 break;
628 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
629 printf("close failed (%s)\n", cli_errstr(c));
630 correct = False;
633 return correct;
636 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
638 const char *lockfname = "\\torture2.lck";
639 uint16_t fnum1;
640 uint16_t fnum2;
641 int i;
642 char buf[131072];
643 char buf_rd[131072];
644 bool correct = True;
645 ssize_t bytes_read;
647 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
648 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
651 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
652 DENY_NONE, &fnum1))) {
653 printf("first open read/write of %s failed (%s)\n",
654 lockfname, cli_errstr(c1));
655 return False;
657 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
658 DENY_NONE, &fnum2))) {
659 printf("second open read-only of %s failed (%s)\n",
660 lockfname, cli_errstr(c2));
661 cli_close(c1, fnum1);
662 return False;
665 for (i=0;i<torture_numops;i++)
667 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
668 if (i % 10 == 0) {
669 printf("%d\r", i); fflush(stdout);
672 generate_random_buffer((unsigned char *)buf, buf_size);
674 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
675 printf("write failed (%s)\n", cli_errstr(c1));
676 correct = False;
677 break;
680 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
681 printf("read failed (%s)\n", cli_errstr(c2));
682 printf("read %d, expected %ld\n", (int)bytes_read,
683 (unsigned long)buf_size);
684 correct = False;
685 break;
688 if (memcmp(buf_rd, buf, buf_size) != 0)
690 printf("read/write compare failed\n");
691 correct = False;
692 break;
696 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
697 printf("close failed (%s)\n", cli_errstr(c2));
698 correct = False;
700 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
701 printf("close failed (%s)\n", cli_errstr(c1));
702 correct = False;
705 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
706 printf("unlink failed (%s)\n", cli_errstr(c1));
707 correct = False;
710 return correct;
713 static bool run_readwritetest(int dummy)
715 struct cli_state *cli1, *cli2;
716 bool test1, test2 = False;
718 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
719 return False;
721 cli_sockopt(cli1, sockops);
722 cli_sockopt(cli2, sockops);
724 printf("starting readwritetest\n");
726 test1 = rw_torture2(cli1, cli2);
727 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
729 if (test1) {
730 test2 = rw_torture2(cli1, cli1);
731 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
734 if (!torture_close_connection(cli1)) {
735 test1 = False;
738 if (!torture_close_connection(cli2)) {
739 test2 = False;
742 return (test1 && test2);
745 static bool run_readwritemulti(int dummy)
747 struct cli_state *cli;
748 bool test;
750 cli = current_cli;
752 cli_sockopt(cli, sockops);
754 printf("run_readwritemulti: fname %s\n", randomfname);
755 test = rw_torture3(cli, randomfname);
757 if (!torture_close_connection(cli)) {
758 test = False;
761 return test;
764 static bool run_readwritelarge(int dummy)
766 static struct cli_state *cli1;
767 uint16_t fnum1;
768 const char *lockfname = "\\large.dat";
769 SMB_OFF_T fsize;
770 char buf[126*1024];
771 bool correct = True;
773 if (!torture_open_connection(&cli1, 0)) {
774 return False;
776 cli_sockopt(cli1, sockops);
777 memset(buf,'\0',sizeof(buf));
779 cli1->max_xmit = 128*1024;
781 printf("starting readwritelarge\n");
783 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
785 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
786 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
787 return False;
790 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
792 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
793 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
794 correct = False;
797 if (fsize == sizeof(buf))
798 printf("readwritelarge test 1 succeeded (size = %lx)\n",
799 (unsigned long)fsize);
800 else {
801 printf("readwritelarge test 1 failed (size = %lx)\n",
802 (unsigned long)fsize);
803 correct = False;
806 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
807 printf("close failed (%s)\n", cli_errstr(cli1));
808 correct = False;
811 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
812 printf("unlink failed (%s)\n", cli_errstr(cli1));
813 correct = False;
816 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
817 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
818 return False;
821 cli1->max_xmit = 4*1024;
823 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
825 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
826 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
827 correct = False;
830 if (fsize == sizeof(buf))
831 printf("readwritelarge test 2 succeeded (size = %lx)\n",
832 (unsigned long)fsize);
833 else {
834 printf("readwritelarge test 2 failed (size = %lx)\n",
835 (unsigned long)fsize);
836 correct = False;
839 #if 0
840 /* ToDo - set allocation. JRA */
841 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
842 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
843 return False;
845 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
846 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
847 correct = False;
849 if (fsize != 0)
850 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
851 #endif
853 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
854 printf("close failed (%s)\n", cli_errstr(cli1));
855 correct = False;
858 if (!torture_close_connection(cli1)) {
859 correct = False;
861 return correct;
864 int line_count = 0;
865 int nbio_id;
867 #define ival(s) strtol(s, NULL, 0)
869 /* run a test that simulates an approximate netbench client load */
870 static bool run_netbench(int client)
872 struct cli_state *cli;
873 int i;
874 char line[1024];
875 char cname[20];
876 FILE *f;
877 const char *params[20];
878 bool correct = True;
880 cli = current_cli;
882 nbio_id = client;
884 cli_sockopt(cli, sockops);
886 nb_setup(cli);
888 slprintf(cname,sizeof(cname)-1, "client%d", client);
890 f = fopen(client_txt, "r");
892 if (!f) {
893 perror(client_txt);
894 return False;
897 while (fgets(line, sizeof(line)-1, f)) {
898 char *saveptr;
899 line_count++;
901 line[strlen(line)-1] = 0;
903 /* printf("[%d] %s\n", line_count, line); */
905 all_string_sub(line,"client1", cname, sizeof(line));
907 /* parse the command parameters */
908 params[0] = strtok_r(line, " ", &saveptr);
909 i = 0;
910 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
912 params[i] = "";
914 if (i < 2) continue;
916 if (!strncmp(params[0],"SMB", 3)) {
917 printf("ERROR: You are using a dbench 1 load file\n");
918 exit(1);
921 if (!strcmp(params[0],"NTCreateX")) {
922 nb_createx(params[1], ival(params[2]), ival(params[3]),
923 ival(params[4]));
924 } else if (!strcmp(params[0],"Close")) {
925 nb_close(ival(params[1]));
926 } else if (!strcmp(params[0],"Rename")) {
927 nb_rename(params[1], params[2]);
928 } else if (!strcmp(params[0],"Unlink")) {
929 nb_unlink(params[1]);
930 } else if (!strcmp(params[0],"Deltree")) {
931 nb_deltree(params[1]);
932 } else if (!strcmp(params[0],"Rmdir")) {
933 nb_rmdir(params[1]);
934 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
935 nb_qpathinfo(params[1]);
936 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
937 nb_qfileinfo(ival(params[1]));
938 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
939 nb_qfsinfo(ival(params[1]));
940 } else if (!strcmp(params[0],"FIND_FIRST")) {
941 nb_findfirst(params[1]);
942 } else if (!strcmp(params[0],"WriteX")) {
943 nb_writex(ival(params[1]),
944 ival(params[2]), ival(params[3]), ival(params[4]));
945 } else if (!strcmp(params[0],"ReadX")) {
946 nb_readx(ival(params[1]),
947 ival(params[2]), ival(params[3]), ival(params[4]));
948 } else if (!strcmp(params[0],"Flush")) {
949 nb_flush(ival(params[1]));
950 } else {
951 printf("Unknown operation %s\n", params[0]);
952 exit(1);
955 fclose(f);
957 nb_cleanup();
959 if (!torture_close_connection(cli)) {
960 correct = False;
963 return correct;
967 /* run a test that simulates an approximate netbench client load */
968 static bool run_nbench(int dummy)
970 double t;
971 bool correct = True;
973 nbio_shmem(nprocs);
975 nbio_id = -1;
977 signal(SIGALRM, nb_alarm);
978 alarm(1);
979 t = create_procs(run_netbench, &correct);
980 alarm(0);
982 printf("\nThroughput %g MB/sec\n",
983 1.0e-6 * nbio_total() / t);
984 return correct;
989 This test checks for two things:
991 1) correct support for retaining locks over a close (ie. the server
992 must not use posix semantics)
993 2) support for lock timeouts
995 static bool run_locktest1(int dummy)
997 struct cli_state *cli1, *cli2;
998 const char *fname = "\\lockt1.lck";
999 uint16_t fnum1, fnum2, fnum3;
1000 time_t t1, t2;
1001 unsigned lock_timeout;
1003 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1004 return False;
1006 cli_sockopt(cli1, sockops);
1007 cli_sockopt(cli2, sockops);
1009 printf("starting locktest1\n");
1011 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1013 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1014 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1015 return False;
1017 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1018 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1019 return False;
1021 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1022 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1023 return False;
1026 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1027 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1028 return False;
1032 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1033 printf("lock2 succeeded! This is a locking bug\n");
1034 return False;
1035 } else {
1036 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1037 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1041 lock_timeout = (1 + (random() % 20));
1042 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1043 t1 = time(NULL);
1044 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1045 printf("lock3 succeeded! This is a locking bug\n");
1046 return False;
1047 } else {
1048 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1049 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1051 t2 = time(NULL);
1053 if (ABS(t2 - t1) < lock_timeout-1) {
1054 printf("error: This server appears not to support timed lock requests\n");
1057 printf("server slept for %u seconds for a %u second timeout\n",
1058 (unsigned int)(t2-t1), lock_timeout);
1060 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1061 printf("close1 failed (%s)\n", cli_errstr(cli1));
1062 return False;
1065 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1066 printf("lock4 succeeded! This is a locking bug\n");
1067 return False;
1068 } else {
1069 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1070 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1073 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1074 printf("close2 failed (%s)\n", cli_errstr(cli1));
1075 return False;
1078 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1079 printf("close3 failed (%s)\n", cli_errstr(cli2));
1080 return False;
1083 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1084 printf("unlink failed (%s)\n", cli_errstr(cli1));
1085 return False;
1089 if (!torture_close_connection(cli1)) {
1090 return False;
1093 if (!torture_close_connection(cli2)) {
1094 return False;
1097 printf("Passed locktest1\n");
1098 return True;
1102 this checks to see if a secondary tconx can use open files from an
1103 earlier tconx
1105 static bool run_tcon_test(int dummy)
1107 static struct cli_state *cli;
1108 const char *fname = "\\tcontest.tmp";
1109 uint16 fnum1;
1110 uint16 cnum1, cnum2, cnum3;
1111 uint16 vuid1, vuid2;
1112 char buf[4];
1113 bool ret = True;
1114 NTSTATUS status;
1116 memset(buf, '\0', sizeof(buf));
1118 if (!torture_open_connection(&cli, 0)) {
1119 return False;
1121 cli_sockopt(cli, sockops);
1123 printf("starting tcontest\n");
1125 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1127 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1128 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1129 return False;
1132 cnum1 = cli->cnum;
1133 vuid1 = cli->vuid;
1135 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1136 printf("initial write failed (%s)", cli_errstr(cli));
1137 return False;
1140 status = cli_tcon_andx(cli, share, "?????",
1141 password, strlen(password)+1);
1142 if (!NT_STATUS_IS_OK(status)) {
1143 printf("%s refused 2nd tree connect (%s)\n", host,
1144 nt_errstr(status));
1145 cli_shutdown(cli);
1146 return False;
1149 cnum2 = cli->cnum;
1150 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1151 vuid2 = cli->vuid + 1;
1153 /* try a write with the wrong tid */
1154 cli->cnum = cnum2;
1156 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1157 printf("* server allows write with wrong TID\n");
1158 ret = False;
1159 } else {
1160 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1164 /* try a write with an invalid tid */
1165 cli->cnum = cnum3;
1167 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168 printf("* server allows write with invalid TID\n");
1169 ret = False;
1170 } else {
1171 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1174 /* try a write with an invalid vuid */
1175 cli->vuid = vuid2;
1176 cli->cnum = cnum1;
1178 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1179 printf("* server allows write with invalid VUID\n");
1180 ret = False;
1181 } else {
1182 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1185 cli->cnum = cnum1;
1186 cli->vuid = vuid1;
1188 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1189 printf("close failed (%s)\n", cli_errstr(cli));
1190 return False;
1193 cli->cnum = cnum2;
1195 if (!cli_tdis(cli)) {
1196 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1197 return False;
1200 cli->cnum = cnum1;
1202 if (!torture_close_connection(cli)) {
1203 return False;
1206 return ret;
1211 checks for old style tcon support
1213 static bool run_tcon2_test(int dummy)
1215 static struct cli_state *cli;
1216 uint16 cnum, max_xmit;
1217 char *service;
1218 NTSTATUS status;
1220 if (!torture_open_connection(&cli, 0)) {
1221 return False;
1223 cli_sockopt(cli, sockops);
1225 printf("starting tcon2 test\n");
1227 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1228 return false;
1231 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 printf("tcon2 failed : %s\n", cli_errstr(cli));
1235 } else {
1236 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1237 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1240 if (!torture_close_connection(cli)) {
1241 return False;
1244 printf("Passed tcon2 test\n");
1245 return True;
1248 static bool tcon_devtest(struct cli_state *cli,
1249 const char *myshare, const char *devtype,
1250 const char *return_devtype,
1251 NTSTATUS expected_error)
1253 NTSTATUS status;
1254 bool ret;
1256 status = cli_tcon_andx(cli, myshare, devtype,
1257 password, strlen(password)+1);
1259 if (NT_STATUS_IS_OK(expected_error)) {
1260 if (NT_STATUS_IS_OK(status)) {
1261 if (strcmp(cli->dev, return_devtype) == 0) {
1262 ret = True;
1263 } else {
1264 printf("tconX to share %s with type %s "
1265 "succeeded but returned the wrong "
1266 "device type (got [%s] but should have got [%s])\n",
1267 myshare, devtype, cli->dev, return_devtype);
1268 ret = False;
1270 } else {
1271 printf("tconX to share %s with type %s "
1272 "should have succeeded but failed\n",
1273 myshare, devtype);
1274 ret = False;
1276 cli_tdis(cli);
1277 } else {
1278 if (NT_STATUS_IS_OK(status)) {
1279 printf("tconx to share %s with type %s "
1280 "should have failed but succeeded\n",
1281 myshare, devtype);
1282 ret = False;
1283 } else {
1284 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1285 expected_error)) {
1286 ret = True;
1287 } else {
1288 printf("Returned unexpected error\n");
1289 ret = False;
1293 return ret;
1297 checks for correct tconX support
1299 static bool run_tcon_devtype_test(int dummy)
1301 static struct cli_state *cli1 = NULL;
1302 bool retry;
1303 int flags = 0;
1304 NTSTATUS status;
1305 bool ret = True;
1307 status = cli_full_connection(&cli1, myname,
1308 host, NULL, port_to_use,
1309 NULL, NULL,
1310 username, workgroup,
1311 password, flags, Undefined, &retry);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 printf("could not open connection\n");
1315 return False;
1318 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1319 ret = False;
1321 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1322 ret = False;
1324 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1325 ret = False;
1327 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1328 ret = False;
1330 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1331 ret = False;
1333 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1334 ret = False;
1336 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1337 ret = False;
1339 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1340 ret = False;
1342 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1343 ret = False;
1345 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1346 ret = False;
1348 cli_shutdown(cli1);
1350 if (ret)
1351 printf("Passed tcondevtest\n");
1353 return ret;
1358 This test checks that
1360 1) the server supports multiple locking contexts on the one SMB
1361 connection, distinguished by PID.
1363 2) the server correctly fails overlapping locks made by the same PID (this
1364 goes against POSIX behaviour, which is why it is tricky to implement)
1366 3) the server denies unlock requests by an incorrect client PID
1368 static bool run_locktest2(int dummy)
1370 static struct cli_state *cli;
1371 const char *fname = "\\lockt2.lck";
1372 uint16_t fnum1, fnum2, fnum3;
1373 bool correct = True;
1375 if (!torture_open_connection(&cli, 0)) {
1376 return False;
1379 cli_sockopt(cli, sockops);
1381 printf("starting locktest2\n");
1383 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1385 cli_setpid(cli, 1);
1387 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1388 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1389 return False;
1392 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1393 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1394 return False;
1397 cli_setpid(cli, 2);
1399 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1400 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1401 return False;
1404 cli_setpid(cli, 1);
1406 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1407 printf("lock1 failed (%s)\n", cli_errstr(cli));
1408 return False;
1411 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1412 printf("WRITE lock1 succeeded! This is a locking bug\n");
1413 correct = False;
1414 } else {
1415 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1416 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1419 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1420 printf("WRITE lock2 succeeded! This is a locking bug\n");
1421 correct = False;
1422 } else {
1423 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1424 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1427 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1428 printf("READ lock2 succeeded! This is a locking bug\n");
1429 correct = False;
1430 } else {
1431 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1432 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1435 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1436 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1438 cli_setpid(cli, 2);
1439 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1440 printf("unlock at 100 succeeded! This is a locking bug\n");
1441 correct = False;
1444 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1445 printf("unlock1 succeeded! This is a locking bug\n");
1446 correct = False;
1447 } else {
1448 if (!check_error(__LINE__, cli,
1449 ERRDOS, ERRlock,
1450 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1453 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1454 printf("unlock2 succeeded! This is a locking bug\n");
1455 correct = False;
1456 } else {
1457 if (!check_error(__LINE__, cli,
1458 ERRDOS, ERRlock,
1459 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1462 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1463 printf("lock3 succeeded! This is a locking bug\n");
1464 correct = False;
1465 } else {
1466 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1469 cli_setpid(cli, 1);
1471 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1472 printf("close1 failed (%s)\n", cli_errstr(cli));
1473 return False;
1476 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1477 printf("close2 failed (%s)\n", cli_errstr(cli));
1478 return False;
1481 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1482 printf("close3 failed (%s)\n", cli_errstr(cli));
1483 return False;
1486 if (!torture_close_connection(cli)) {
1487 correct = False;
1490 printf("locktest2 finished\n");
1492 return correct;
1497 This test checks that
1499 1) the server supports the full offset range in lock requests
1501 static bool run_locktest3(int dummy)
1503 static struct cli_state *cli1, *cli2;
1504 const char *fname = "\\lockt3.lck";
1505 uint16_t fnum1, fnum2;
1506 int i;
1507 uint32 offset;
1508 bool correct = True;
1510 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1512 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1513 return False;
1515 cli_sockopt(cli1, sockops);
1516 cli_sockopt(cli2, sockops);
1518 printf("starting locktest3\n");
1520 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1522 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1523 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1524 return False;
1526 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1527 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1528 return False;
1531 for (offset=i=0;i<torture_numops;i++) {
1532 NEXT_OFFSET;
1533 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1534 printf("lock1 %d failed (%s)\n",
1536 cli_errstr(cli1));
1537 return False;
1540 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1541 printf("lock2 %d failed (%s)\n",
1543 cli_errstr(cli1));
1544 return False;
1548 for (offset=i=0;i<torture_numops;i++) {
1549 NEXT_OFFSET;
1551 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1552 printf("error: lock1 %d succeeded!\n", i);
1553 return False;
1556 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1557 printf("error: lock2 %d succeeded!\n", i);
1558 return False;
1561 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1562 printf("error: lock3 %d succeeded!\n", i);
1563 return False;
1566 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1567 printf("error: lock4 %d succeeded!\n", i);
1568 return False;
1572 for (offset=i=0;i<torture_numops;i++) {
1573 NEXT_OFFSET;
1575 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1576 printf("unlock1 %d failed (%s)\n",
1578 cli_errstr(cli1));
1579 return False;
1582 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1583 printf("unlock2 %d failed (%s)\n",
1585 cli_errstr(cli1));
1586 return False;
1590 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1591 printf("close1 failed (%s)\n", cli_errstr(cli1));
1592 return False;
1595 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1596 printf("close2 failed (%s)\n", cli_errstr(cli2));
1597 return False;
1600 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1601 printf("unlink failed (%s)\n", cli_errstr(cli1));
1602 return False;
1605 if (!torture_close_connection(cli1)) {
1606 correct = False;
1609 if (!torture_close_connection(cli2)) {
1610 correct = False;
1613 printf("finished locktest3\n");
1615 return correct;
1618 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1619 printf("** "); correct = False; \
1623 looks at overlapping locks
1625 static bool run_locktest4(int dummy)
1627 static struct cli_state *cli1, *cli2;
1628 const char *fname = "\\lockt4.lck";
1629 uint16_t fnum1, fnum2, f;
1630 bool ret;
1631 char buf[1000];
1632 bool correct = True;
1634 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1635 return False;
1638 cli_sockopt(cli1, sockops);
1639 cli_sockopt(cli2, sockops);
1641 printf("starting locktest4\n");
1643 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1645 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1646 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1648 memset(buf, 0, sizeof(buf));
1650 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1651 printf("Failed to create file\n");
1652 correct = False;
1653 goto fail;
1656 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1657 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1658 EXPECTED(ret, False);
1659 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1661 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1662 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1663 EXPECTED(ret, True);
1664 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1666 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1667 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1668 EXPECTED(ret, False);
1669 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1671 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1672 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1673 EXPECTED(ret, True);
1674 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1676 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1677 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1678 EXPECTED(ret, False);
1679 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1681 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1682 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1683 EXPECTED(ret, True);
1684 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1686 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1687 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1688 EXPECTED(ret, True);
1689 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1691 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1692 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1693 EXPECTED(ret, False);
1694 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1696 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1697 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1698 EXPECTED(ret, False);
1699 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1701 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1702 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1703 EXPECTED(ret, True);
1704 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1706 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1707 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1708 EXPECTED(ret, False);
1709 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1711 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1712 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1713 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1714 EXPECTED(ret, False);
1715 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1718 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1719 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1720 EXPECTED(ret, False);
1721 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1723 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1724 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1725 EXPECTED(ret, False);
1726 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1729 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1730 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1731 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1732 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1733 EXPECTED(ret, True);
1734 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1737 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1738 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1739 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1740 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1741 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1742 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1743 EXPECTED(ret, True);
1744 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1746 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1747 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1748 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1749 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1750 EXPECTED(ret, True);
1751 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1753 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1754 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1755 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1756 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1757 EXPECTED(ret, True);
1758 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1760 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1761 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1762 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1763 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1764 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1765 EXPECTED(ret, True);
1766 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1768 cli_close(cli1, fnum1);
1769 cli_close(cli2, fnum2);
1770 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1771 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1772 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1773 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1774 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1775 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1776 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1777 cli_close(cli1, f);
1778 cli_close(cli1, fnum1);
1779 EXPECTED(ret, True);
1780 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1782 fail:
1783 cli_close(cli1, fnum1);
1784 cli_close(cli2, fnum2);
1785 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1786 torture_close_connection(cli1);
1787 torture_close_connection(cli2);
1789 printf("finished locktest4\n");
1790 return correct;
1794 looks at lock upgrade/downgrade.
1796 static bool run_locktest5(int dummy)
1798 static struct cli_state *cli1, *cli2;
1799 const char *fname = "\\lockt5.lck";
1800 uint16_t fnum1, fnum2, fnum3;
1801 bool ret;
1802 char buf[1000];
1803 bool correct = True;
1805 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1806 return False;
1809 cli_sockopt(cli1, sockops);
1810 cli_sockopt(cli2, sockops);
1812 printf("starting locktest5\n");
1814 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1816 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1817 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1818 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1820 memset(buf, 0, sizeof(buf));
1822 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1823 printf("Failed to create file\n");
1824 correct = False;
1825 goto fail;
1828 /* Check for NT bug... */
1829 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1830 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1831 cli_close(cli1, fnum1);
1832 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1833 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1834 EXPECTED(ret, True);
1835 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1836 cli_close(cli1, fnum1);
1837 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1838 cli_unlock(cli1, fnum3, 0, 1);
1840 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1841 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1842 EXPECTED(ret, True);
1843 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1845 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1846 EXPECTED(ret, False);
1848 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1850 /* Unlock the process 2 lock. */
1851 cli_unlock(cli2, fnum2, 0, 4);
1853 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1854 EXPECTED(ret, False);
1856 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1858 /* Unlock the process 1 fnum3 lock. */
1859 cli_unlock(cli1, fnum3, 0, 4);
1861 /* Stack 2 more locks here. */
1862 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1863 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1865 EXPECTED(ret, True);
1866 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1868 /* Unlock the first process lock, then check this was the WRITE lock that was
1869 removed. */
1871 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1872 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1874 EXPECTED(ret, True);
1875 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1877 /* Unlock the process 2 lock. */
1878 cli_unlock(cli2, fnum2, 0, 4);
1880 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1882 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1883 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1884 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1886 EXPECTED(ret, True);
1887 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1889 /* Ensure the next unlock fails. */
1890 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1891 EXPECTED(ret, False);
1892 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1894 /* Ensure connection 2 can get a write lock. */
1895 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1896 EXPECTED(ret, True);
1898 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1901 fail:
1902 cli_close(cli1, fnum1);
1903 cli_close(cli2, fnum2);
1904 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1905 if (!torture_close_connection(cli1)) {
1906 correct = False;
1908 if (!torture_close_connection(cli2)) {
1909 correct = False;
1912 printf("finished locktest5\n");
1914 return correct;
1918 tries the unusual lockingX locktype bits
1920 static bool run_locktest6(int dummy)
1922 static struct cli_state *cli;
1923 const char *fname[1] = { "\\lock6.txt" };
1924 int i;
1925 uint16_t fnum;
1926 NTSTATUS status;
1928 if (!torture_open_connection(&cli, 0)) {
1929 return False;
1932 cli_sockopt(cli, sockops);
1934 printf("starting locktest6\n");
1936 for (i=0;i<1;i++) {
1937 printf("Testing %s\n", fname[i]);
1939 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1941 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1942 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1943 cli_close(cli, fnum);
1944 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1946 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1947 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1948 cli_close(cli, fnum);
1949 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1951 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1954 torture_close_connection(cli);
1956 printf("finished locktest6\n");
1957 return True;
1960 static bool run_locktest7(int dummy)
1962 struct cli_state *cli1;
1963 const char *fname = "\\lockt7.lck";
1964 uint16_t fnum1;
1965 char buf[200];
1966 bool correct = False;
1968 if (!torture_open_connection(&cli1, 0)) {
1969 return False;
1972 cli_sockopt(cli1, sockops);
1974 printf("starting locktest7\n");
1976 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1978 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1980 memset(buf, 0, sizeof(buf));
1982 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1983 printf("Failed to create file\n");
1984 goto fail;
1987 cli_setpid(cli1, 1);
1989 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1990 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1991 goto fail;
1992 } else {
1993 printf("pid1 successfully locked range 130:4 for READ\n");
1996 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1997 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1998 goto fail;
1999 } else {
2000 printf("pid1 successfully read the range 130:4\n");
2003 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2004 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2005 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2006 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2007 goto fail;
2009 } else {
2010 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2011 goto fail;
2014 cli_setpid(cli1, 2);
2016 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2017 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2018 } else {
2019 printf("pid2 successfully read the range 130:4\n");
2022 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2023 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2024 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2025 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2026 goto fail;
2028 } else {
2029 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2030 goto fail;
2033 cli_setpid(cli1, 1);
2034 cli_unlock(cli1, fnum1, 130, 4);
2036 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2037 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2038 goto fail;
2039 } else {
2040 printf("pid1 successfully locked range 130:4 for WRITE\n");
2043 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2044 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2045 goto fail;
2046 } else {
2047 printf("pid1 successfully read the range 130:4\n");
2050 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2051 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2052 goto fail;
2053 } else {
2054 printf("pid1 successfully wrote to the range 130:4\n");
2057 cli_setpid(cli1, 2);
2059 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2060 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2061 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2062 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2063 goto fail;
2065 } else {
2066 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2067 goto fail;
2070 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2071 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2072 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2073 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2074 goto fail;
2076 } else {
2077 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2078 goto fail;
2081 cli_unlock(cli1, fnum1, 130, 0);
2082 correct = True;
2084 fail:
2085 cli_close(cli1, fnum1);
2086 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2087 torture_close_connection(cli1);
2089 printf("finished locktest7\n");
2090 return correct;
2094 * This demonstrates a problem with our use of GPFS share modes: A file
2095 * descriptor sitting in the pending close queue holding a GPFS share mode
2096 * blocks opening a file another time. Happens with Word 2007 temp files.
2097 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2098 * open is denied with NT_STATUS_SHARING_VIOLATION.
2101 static bool run_locktest8(int dummy)
2103 struct cli_state *cli1;
2104 const char *fname = "\\lockt8.lck";
2105 uint16_t fnum1, fnum2;
2106 char buf[200];
2107 bool correct = False;
2108 NTSTATUS status;
2110 if (!torture_open_connection(&cli1, 0)) {
2111 return False;
2114 cli_sockopt(cli1, sockops);
2116 printf("starting locktest8\n");
2118 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2120 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2121 &fnum1);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2124 return false;
2127 memset(buf, 0, sizeof(buf));
2129 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 d_fprintf(stderr, "cli_open second time returned %s\n",
2132 cli_errstr(cli1));
2133 goto fail;
2136 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2137 printf("Unable to apply read lock on range 1:1, error was "
2138 "%s\n", cli_errstr(cli1));
2139 goto fail;
2142 status = cli_close(cli1, fnum1);
2143 if (!NT_STATUS_IS_OK(status)) {
2144 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2145 goto fail;
2148 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2149 if (!NT_STATUS_IS_OK(status)) {
2150 d_fprintf(stderr, "cli_open third time returned %s\n",
2151 cli_errstr(cli1));
2152 goto fail;
2155 correct = true;
2157 fail:
2158 cli_close(cli1, fnum1);
2159 cli_close(cli1, fnum2);
2160 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2161 torture_close_connection(cli1);
2163 printf("finished locktest8\n");
2164 return correct;
2168 * This test is designed to be run in conjunction with
2169 * external NFS or POSIX locks taken in the filesystem.
2170 * It checks that the smbd server will block until the
2171 * lock is released and then acquire it. JRA.
2174 static bool got_alarm;
2175 static int alarm_fd;
2177 static void alarm_handler(int dummy)
2179 got_alarm = True;
2182 static void alarm_handler_parent(int dummy)
2184 close(alarm_fd);
2187 static void do_local_lock(int read_fd, int write_fd)
2189 int fd;
2190 char c = '\0';
2191 struct flock lock;
2192 const char *local_pathname = NULL;
2193 int ret;
2195 local_pathname = talloc_asprintf(talloc_tos(),
2196 "%s/lockt9.lck", local_path);
2197 if (!local_pathname) {
2198 printf("child: alloc fail\n");
2199 exit(1);
2202 unlink(local_pathname);
2203 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2204 if (fd == -1) {
2205 printf("child: open of %s failed %s.\n",
2206 local_pathname, strerror(errno));
2207 exit(1);
2210 /* Now take a fcntl lock. */
2211 lock.l_type = F_WRLCK;
2212 lock.l_whence = SEEK_SET;
2213 lock.l_start = 0;
2214 lock.l_len = 4;
2215 lock.l_pid = getpid();
2217 ret = fcntl(fd,F_SETLK,&lock);
2218 if (ret == -1) {
2219 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2220 local_pathname, strerror(errno));
2221 exit(1);
2222 } else {
2223 printf("child: got lock 0:4 on file %s.\n",
2224 local_pathname );
2225 fflush(stdout);
2228 CatchSignal(SIGALRM, alarm_handler);
2229 alarm(5);
2230 /* Signal the parent. */
2231 if (write(write_fd, &c, 1) != 1) {
2232 printf("child: start signal fail %s.\n",
2233 strerror(errno));
2234 exit(1);
2236 alarm(0);
2238 alarm(10);
2239 /* Wait for the parent to be ready. */
2240 if (read(read_fd, &c, 1) != 1) {
2241 printf("child: reply signal fail %s.\n",
2242 strerror(errno));
2243 exit(1);
2245 alarm(0);
2247 sleep(5);
2248 close(fd);
2249 printf("child: released lock 0:4 on file %s.\n",
2250 local_pathname );
2251 fflush(stdout);
2252 exit(0);
2255 static bool run_locktest9(int dummy)
2257 struct cli_state *cli1;
2258 const char *fname = "\\lockt9.lck";
2259 uint16_t fnum;
2260 bool correct = False;
2261 int pipe_in[2], pipe_out[2];
2262 pid_t child_pid;
2263 char c = '\0';
2264 int ret;
2265 struct timeval start;
2266 double seconds;
2267 NTSTATUS status;
2269 printf("starting locktest9\n");
2271 if (local_path == NULL) {
2272 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2273 return false;
2276 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2277 return false;
2280 child_pid = fork();
2281 if (child_pid == -1) {
2282 return false;
2285 if (child_pid == 0) {
2286 /* Child. */
2287 do_local_lock(pipe_out[0], pipe_in[1]);
2288 exit(0);
2291 close(pipe_out[0]);
2292 close(pipe_in[1]);
2293 pipe_out[0] = -1;
2294 pipe_in[1] = -1;
2296 /* Parent. */
2297 ret = read(pipe_in[0], &c, 1);
2298 if (ret != 1) {
2299 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2300 strerror(errno));
2301 return false;
2304 if (!torture_open_connection(&cli1, 0)) {
2305 return false;
2308 cli_sockopt(cli1, sockops);
2310 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2311 &fnum);
2312 if (!NT_STATUS_IS_OK(status)) {
2313 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2314 return false;
2317 /* Ensure the child has the lock. */
2318 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2319 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2320 goto fail;
2321 } else {
2322 d_printf("Child has the lock.\n");
2325 /* Tell the child to wait 5 seconds then exit. */
2326 ret = write(pipe_out[1], &c, 1);
2327 if (ret != 1) {
2328 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2329 strerror(errno));
2330 goto fail;
2333 /* Wait 20 seconds for the lock. */
2334 alarm_fd = cli1->fd;
2335 CatchSignal(SIGALRM, alarm_handler_parent);
2336 alarm(20);
2338 start = timeval_current();
2340 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2341 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2342 "%s\n", cli_errstr(cli1));
2343 goto fail_nofd;
2345 alarm(0);
2347 seconds = timeval_elapsed(&start);
2349 printf("Parent got the lock after %.2f seconds.\n",
2350 seconds);
2352 status = cli_close(cli1, fnum);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2355 goto fail;
2358 correct = true;
2360 fail:
2361 cli_close(cli1, fnum);
2362 torture_close_connection(cli1);
2364 fail_nofd:
2366 printf("finished locktest9\n");
2367 return correct;
2371 test whether fnums and tids open on one VC are available on another (a major
2372 security hole)
2374 static bool run_fdpasstest(int dummy)
2376 struct cli_state *cli1, *cli2;
2377 const char *fname = "\\fdpass.tst";
2378 uint16_t fnum1;
2379 char buf[1024];
2381 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2382 return False;
2384 cli_sockopt(cli1, sockops);
2385 cli_sockopt(cli2, sockops);
2387 printf("starting fdpasstest\n");
2389 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2391 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2392 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2393 return False;
2396 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2397 printf("write failed (%s)\n", cli_errstr(cli1));
2398 return False;
2401 cli2->vuid = cli1->vuid;
2402 cli2->cnum = cli1->cnum;
2403 cli2->pid = cli1->pid;
2405 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2406 printf("read succeeded! nasty security hole [%s]\n",
2407 buf);
2408 return False;
2411 cli_close(cli1, fnum1);
2412 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2414 torture_close_connection(cli1);
2415 torture_close_connection(cli2);
2417 printf("finished fdpasstest\n");
2418 return True;
2421 static bool run_fdsesstest(int dummy)
2423 struct cli_state *cli;
2424 uint16 new_vuid;
2425 uint16 saved_vuid;
2426 uint16 new_cnum;
2427 uint16 saved_cnum;
2428 const char *fname = "\\fdsess.tst";
2429 const char *fname1 = "\\fdsess1.tst";
2430 uint16_t fnum1;
2431 uint16_t fnum2;
2432 char buf[1024];
2433 bool ret = True;
2435 if (!torture_open_connection(&cli, 0))
2436 return False;
2437 cli_sockopt(cli, sockops);
2439 if (!torture_cli_session_setup2(cli, &new_vuid))
2440 return False;
2442 saved_cnum = cli->cnum;
2443 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2444 return False;
2445 new_cnum = cli->cnum;
2446 cli->cnum = saved_cnum;
2448 printf("starting fdsesstest\n");
2450 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2451 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2453 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2454 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2455 return False;
2458 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2459 printf("write failed (%s)\n", cli_errstr(cli));
2460 return False;
2463 saved_vuid = cli->vuid;
2464 cli->vuid = new_vuid;
2466 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2467 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2468 buf);
2469 ret = False;
2471 /* Try to open a file with different vuid, samba cnum. */
2472 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2473 printf("create with different vuid, same cnum succeeded.\n");
2474 cli_close(cli, fnum2);
2475 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2476 } else {
2477 printf("create with different vuid, same cnum failed.\n");
2478 printf("This will cause problems with service clients.\n");
2479 ret = False;
2482 cli->vuid = saved_vuid;
2484 /* Try with same vuid, different cnum. */
2485 cli->cnum = new_cnum;
2487 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2488 printf("read succeeded with different cnum![%s]\n",
2489 buf);
2490 ret = False;
2493 cli->cnum = saved_cnum;
2494 cli_close(cli, fnum1);
2495 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2497 torture_close_connection(cli);
2499 printf("finished fdsesstest\n");
2500 return ret;
2504 This test checks that
2506 1) the server does not allow an unlink on a file that is open
2508 static bool run_unlinktest(int dummy)
2510 struct cli_state *cli;
2511 const char *fname = "\\unlink.tst";
2512 uint16_t fnum;
2513 bool correct = True;
2515 if (!torture_open_connection(&cli, 0)) {
2516 return False;
2519 cli_sockopt(cli, sockops);
2521 printf("starting unlink test\n");
2523 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2525 cli_setpid(cli, 1);
2527 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2528 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2529 return False;
2532 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2533 printf("error: server allowed unlink on an open file\n");
2534 correct = False;
2535 } else {
2536 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2537 NT_STATUS_SHARING_VIOLATION);
2540 cli_close(cli, fnum);
2541 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2543 if (!torture_close_connection(cli)) {
2544 correct = False;
2547 printf("unlink test finished\n");
2549 return correct;
2554 test how many open files this server supports on the one socket
2556 static bool run_maxfidtest(int dummy)
2558 struct cli_state *cli;
2559 const char *ftemplate = "\\maxfid.%d.%d";
2560 fstring fname;
2561 uint16_t fnums[0x11000];
2562 int i;
2563 int retries=4;
2564 bool correct = True;
2566 cli = current_cli;
2568 if (retries <= 0) {
2569 printf("failed to connect\n");
2570 return False;
2573 cli_sockopt(cli, sockops);
2575 for (i=0; i<0x11000; i++) {
2576 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2577 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2578 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2579 printf("open of %s failed (%s)\n",
2580 fname, cli_errstr(cli));
2581 printf("maximum fnum is %d\n", i);
2582 break;
2584 printf("%6d\r", i);
2586 printf("%6d\n", i);
2587 i--;
2589 printf("cleaning up\n");
2590 for (;i>=0;i--) {
2591 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2592 cli_close(cli, fnums[i]);
2593 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2594 printf("unlink of %s failed (%s)\n",
2595 fname, cli_errstr(cli));
2596 correct = False;
2598 printf("%6d\r", i);
2600 printf("%6d\n", 0);
2602 printf("maxfid test finished\n");
2603 if (!torture_close_connection(cli)) {
2604 correct = False;
2606 return correct;
2609 /* generate a random buffer */
2610 static void rand_buf(char *buf, int len)
2612 while (len--) {
2613 *buf = (char)sys_random();
2614 buf++;
2618 /* send smb negprot commands, not reading the response */
2619 static bool run_negprot_nowait(int dummy)
2621 int i;
2622 static struct cli_state *cli;
2623 bool correct = True;
2625 printf("starting negprot nowait test\n");
2627 if (!(cli = open_nbt_connection())) {
2628 return False;
2631 for (i=0;i<50000;i++) {
2632 cli_negprot_sendsync(cli);
2635 if (!torture_close_connection(cli)) {
2636 correct = False;
2639 printf("finished negprot nowait test\n");
2641 return correct;
2645 /* send random IPC commands */
2646 static bool run_randomipc(int dummy)
2648 char *rparam = NULL;
2649 char *rdata = NULL;
2650 unsigned int rdrcnt,rprcnt;
2651 char param[1024];
2652 int api, param_len, i;
2653 struct cli_state *cli;
2654 bool correct = True;
2655 int count = 50000;
2657 printf("starting random ipc test\n");
2659 if (!torture_open_connection(&cli, 0)) {
2660 return False;
2663 for (i=0;i<count;i++) {
2664 api = sys_random() % 500;
2665 param_len = (sys_random() % 64);
2667 rand_buf(param, param_len);
2669 SSVAL(param,0,api);
2671 cli_api(cli,
2672 param, param_len, 8,
2673 NULL, 0, BUFFER_SIZE,
2674 &rparam, &rprcnt,
2675 &rdata, &rdrcnt);
2676 if (i % 100 == 0) {
2677 printf("%d/%d\r", i,count);
2680 printf("%d/%d\n", i, count);
2682 if (!torture_close_connection(cli)) {
2683 correct = False;
2686 printf("finished random ipc test\n");
2688 return correct;
2693 static void browse_callback(const char *sname, uint32 stype,
2694 const char *comment, void *state)
2696 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2702 This test checks the browse list code
2705 static bool run_browsetest(int dummy)
2707 static struct cli_state *cli;
2708 bool correct = True;
2710 printf("starting browse test\n");
2712 if (!torture_open_connection(&cli, 0)) {
2713 return False;
2716 printf("domain list:\n");
2717 cli_NetServerEnum(cli, cli->server_domain,
2718 SV_TYPE_DOMAIN_ENUM,
2719 browse_callback, NULL);
2721 printf("machine list:\n");
2722 cli_NetServerEnum(cli, cli->server_domain,
2723 SV_TYPE_ALL,
2724 browse_callback, NULL);
2726 if (!torture_close_connection(cli)) {
2727 correct = False;
2730 printf("browse test finished\n");
2732 return correct;
2738 This checks how the getatr calls works
2740 static bool run_attrtest(int dummy)
2742 struct cli_state *cli;
2743 uint16_t fnum;
2744 time_t t, t2;
2745 const char *fname = "\\attrib123456789.tst";
2746 bool correct = True;
2748 printf("starting attrib test\n");
2750 if (!torture_open_connection(&cli, 0)) {
2751 return False;
2754 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2755 cli_open(cli, fname,
2756 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2757 cli_close(cli, fnum);
2758 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2759 printf("getatr failed (%s)\n", cli_errstr(cli));
2760 correct = False;
2763 if (abs(t - time(NULL)) > 60*60*24*10) {
2764 printf("ERROR: SMBgetatr bug. time is %s",
2765 ctime(&t));
2766 t = time(NULL);
2767 correct = True;
2770 t2 = t-60*60*24; /* 1 day ago */
2772 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2773 printf("setatr failed (%s)\n", cli_errstr(cli));
2774 correct = True;
2777 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2778 printf("getatr failed (%s)\n", cli_errstr(cli));
2779 correct = True;
2782 if (t != t2) {
2783 printf("ERROR: getatr/setatr bug. times are\n%s",
2784 ctime(&t));
2785 printf("%s", ctime(&t2));
2786 correct = True;
2789 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2791 if (!torture_close_connection(cli)) {
2792 correct = False;
2795 printf("attrib test finished\n");
2797 return correct;
2802 This checks a couple of trans2 calls
2804 static bool run_trans2test(int dummy)
2806 struct cli_state *cli;
2807 uint16_t fnum;
2808 SMB_OFF_T size;
2809 time_t c_time, a_time, m_time;
2810 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2811 const char *fname = "\\trans2.tst";
2812 const char *dname = "\\trans2";
2813 const char *fname2 = "\\trans2\\trans2.tst";
2814 char pname[1024];
2815 bool correct = True;
2816 NTSTATUS status;
2817 uint32_t fs_attr;
2819 printf("starting trans2 test\n");
2821 if (!torture_open_connection(&cli, 0)) {
2822 return False;
2825 status = cli_get_fs_attr_info(cli, &fs_attr);
2826 if (!NT_STATUS_IS_OK(status)) {
2827 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2828 nt_errstr(status));
2829 correct = false;
2832 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2833 cli_open(cli, fname,
2834 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2835 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2836 &m_time_ts, NULL)) {
2837 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2838 correct = False;
2841 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2842 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2843 correct = False;
2846 if (strcmp(pname, fname)) {
2847 printf("qfilename gave different name? [%s] [%s]\n",
2848 fname, pname);
2849 correct = False;
2852 cli_close(cli, fnum);
2854 sleep(2);
2856 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2857 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2858 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2859 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2860 return False;
2862 cli_close(cli, fnum);
2864 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2865 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2866 correct = False;
2867 } else {
2868 if (c_time != m_time) {
2869 printf("create time=%s", ctime(&c_time));
2870 printf("modify time=%s", ctime(&m_time));
2871 printf("This system appears to have sticky create times\n");
2873 if (a_time % (60*60) == 0) {
2874 printf("access time=%s", ctime(&a_time));
2875 printf("This system appears to set a midnight access time\n");
2876 correct = False;
2879 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2880 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2881 correct = False;
2886 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2887 cli_open(cli, fname,
2888 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2889 cli_close(cli, fnum);
2890 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2891 &m_time_ts, &size, NULL, NULL)) {
2892 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2893 correct = False;
2894 } else {
2895 if (w_time_ts.tv_sec < 60*60*24*2) {
2896 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2897 printf("This system appears to set a initial 0 write time\n");
2898 correct = False;
2902 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2905 /* check if the server updates the directory modification time
2906 when creating a new file */
2907 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2908 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2909 correct = False;
2911 sleep(3);
2912 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2913 &m_time_ts, &size, NULL, NULL)) {
2914 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2915 correct = False;
2918 cli_open(cli, fname2,
2919 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2920 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2921 cli_close(cli, fnum);
2922 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2923 &m_time2_ts, &size, NULL, NULL)) {
2924 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2925 correct = False;
2926 } else {
2927 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2928 == 0) {
2929 printf("This system does not update directory modification times\n");
2930 correct = False;
2933 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2934 cli_rmdir(cli, dname);
2936 if (!torture_close_connection(cli)) {
2937 correct = False;
2940 printf("trans2 test finished\n");
2942 return correct;
2946 This checks new W2K calls.
2949 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2951 char *buf = NULL;
2952 uint32 len;
2953 bool correct = True;
2955 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2956 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2957 correct = False;
2958 } else {
2959 printf("qfileinfo: level %d, len = %u\n", level, len);
2960 dump_data(0, (uint8 *)buf, len);
2961 printf("\n");
2963 SAFE_FREE(buf);
2964 return correct;
2967 static bool run_w2ktest(int dummy)
2969 struct cli_state *cli;
2970 uint16_t fnum;
2971 const char *fname = "\\w2ktest\\w2k.tst";
2972 int level;
2973 bool correct = True;
2975 printf("starting w2k test\n");
2977 if (!torture_open_connection(&cli, 0)) {
2978 return False;
2981 cli_open(cli, fname,
2982 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2984 for (level = 1004; level < 1040; level++) {
2985 new_trans(cli, fnum, level);
2988 cli_close(cli, fnum);
2990 if (!torture_close_connection(cli)) {
2991 correct = False;
2994 printf("w2k test finished\n");
2996 return correct;
3001 this is a harness for some oplock tests
3003 static bool run_oplock1(int dummy)
3005 struct cli_state *cli1;
3006 const char *fname = "\\lockt1.lck";
3007 uint16_t fnum1;
3008 bool correct = True;
3010 printf("starting oplock test 1\n");
3012 if (!torture_open_connection(&cli1, 0)) {
3013 return False;
3016 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3018 cli_sockopt(cli1, sockops);
3020 cli1->use_oplocks = True;
3022 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3023 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3024 return False;
3027 cli1->use_oplocks = False;
3029 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3030 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3032 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3033 printf("close2 failed (%s)\n", cli_errstr(cli1));
3034 return False;
3037 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3038 printf("unlink failed (%s)\n", cli_errstr(cli1));
3039 return False;
3042 if (!torture_close_connection(cli1)) {
3043 correct = False;
3046 printf("finished oplock test 1\n");
3048 return correct;
3051 static bool run_oplock2(int dummy)
3053 struct cli_state *cli1, *cli2;
3054 const char *fname = "\\lockt2.lck";
3055 uint16_t fnum1, fnum2;
3056 int saved_use_oplocks = use_oplocks;
3057 char buf[4];
3058 bool correct = True;
3059 volatile bool *shared_correct;
3061 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3062 *shared_correct = True;
3064 use_level_II_oplocks = True;
3065 use_oplocks = True;
3067 printf("starting oplock test 2\n");
3069 if (!torture_open_connection(&cli1, 0)) {
3070 use_level_II_oplocks = False;
3071 use_oplocks = saved_use_oplocks;
3072 return False;
3075 cli1->use_oplocks = True;
3076 cli1->use_level_II_oplocks = True;
3078 if (!torture_open_connection(&cli2, 1)) {
3079 use_level_II_oplocks = False;
3080 use_oplocks = saved_use_oplocks;
3081 return False;
3084 cli2->use_oplocks = True;
3085 cli2->use_level_II_oplocks = True;
3087 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3089 cli_sockopt(cli1, sockops);
3090 cli_sockopt(cli2, sockops);
3092 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3093 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3094 return False;
3097 /* Don't need the globals any more. */
3098 use_level_II_oplocks = False;
3099 use_oplocks = saved_use_oplocks;
3101 if (fork() == 0) {
3102 /* Child code */
3103 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3104 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3105 *shared_correct = False;
3106 exit(0);
3109 sleep(2);
3111 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3112 printf("close2 failed (%s)\n", cli_errstr(cli1));
3113 *shared_correct = False;
3116 exit(0);
3119 sleep(2);
3121 /* Ensure cli1 processes the break. Empty file should always return 0
3122 * bytes. */
3124 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3125 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3126 correct = False;
3129 /* Should now be at level II. */
3130 /* Test if sending a write locks causes a break to none. */
3132 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3133 printf("lock failed (%s)\n", cli_errstr(cli1));
3134 correct = False;
3137 cli_unlock(cli1, fnum1, 0, 4);
3139 sleep(2);
3141 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3142 printf("lock failed (%s)\n", cli_errstr(cli1));
3143 correct = False;
3146 cli_unlock(cli1, fnum1, 0, 4);
3148 sleep(2);
3150 cli_read(cli1, fnum1, buf, 0, 4);
3152 #if 0
3153 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3154 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3155 correct = False;
3157 #endif
3159 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3160 printf("close1 failed (%s)\n", cli_errstr(cli1));
3161 correct = False;
3164 sleep(4);
3166 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3167 printf("unlink failed (%s)\n", cli_errstr(cli1));
3168 correct = False;
3171 if (!torture_close_connection(cli1)) {
3172 correct = False;
3175 if (!*shared_correct) {
3176 correct = False;
3179 printf("finished oplock test 2\n");
3181 return correct;
3184 /* handler for oplock 3 tests */
3185 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3187 printf("got oplock break fnum=%d level=%d\n",
3188 fnum, level);
3189 return cli_oplock_ack(cli, fnum, level);
3192 static bool run_oplock3(int dummy)
3194 struct cli_state *cli;
3195 const char *fname = "\\oplockt3.dat";
3196 uint16_t fnum;
3197 char buf[4] = "abcd";
3198 bool correct = True;
3199 volatile bool *shared_correct;
3201 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3202 *shared_correct = True;
3204 printf("starting oplock test 3\n");
3206 if (fork() == 0) {
3207 /* Child code */
3208 use_oplocks = True;
3209 use_level_II_oplocks = True;
3210 if (!torture_open_connection(&cli, 0)) {
3211 *shared_correct = False;
3212 exit(0);
3214 sleep(2);
3215 /* try to trigger a oplock break in parent */
3216 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3217 cli_write(cli, fnum, 0, buf, 0, 4);
3218 exit(0);
3221 /* parent code */
3222 use_oplocks = True;
3223 use_level_II_oplocks = True;
3224 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3225 return False;
3227 cli_oplock_handler(cli, oplock3_handler);
3228 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3229 cli_write(cli, fnum, 0, buf, 0, 4);
3230 cli_close(cli, fnum);
3231 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3232 cli->timeout = 20000;
3233 cli_receive_smb(cli);
3234 printf("finished oplock test 3\n");
3236 return (correct && *shared_correct);
3238 /* What are we looking for here? What's sucess and what's FAILURE? */
3244 Test delete on close semantics.
3246 static bool run_deletetest(int dummy)
3248 struct cli_state *cli1 = NULL;
3249 struct cli_state *cli2 = NULL;
3250 const char *fname = "\\delete.file";
3251 uint16_t fnum1 = (uint16_t)-1;
3252 uint16_t fnum2 = (uint16_t)-1;
3253 bool correct = True;
3255 printf("starting delete test\n");
3257 if (!torture_open_connection(&cli1, 0)) {
3258 return False;
3261 cli_sockopt(cli1, sockops);
3263 /* Test 1 - this should delete the file on close. */
3265 cli_setatr(cli1, fname, 0, 0);
3266 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3268 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3269 0, FILE_OVERWRITE_IF,
3270 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3271 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3272 correct = False;
3273 goto fail;
3276 #if 0 /* JRATEST */
3278 uint32 *accinfo = NULL;
3279 uint32 len;
3280 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3281 if (accinfo)
3282 printf("access mode = 0x%lx\n", *accinfo);
3283 SAFE_FREE(accinfo);
3285 #endif
3287 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3288 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3289 correct = False;
3290 goto fail;
3293 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3294 printf("[1] open of %s succeeded (should fail)\n", fname);
3295 correct = False;
3296 goto fail;
3299 printf("first delete on close test succeeded.\n");
3301 /* Test 2 - this should delete the file on close. */
3303 cli_setatr(cli1, fname, 0, 0);
3304 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3306 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3307 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3308 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3309 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3310 correct = False;
3311 goto fail;
3314 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3315 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3316 correct = False;
3317 goto fail;
3320 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3321 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3322 correct = False;
3323 goto fail;
3326 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3327 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3328 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3329 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3330 correct = False;
3331 goto fail;
3333 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3334 } else
3335 printf("second delete on close test succeeded.\n");
3337 /* Test 3 - ... */
3338 cli_setatr(cli1, fname, 0, 0);
3339 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3341 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3342 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3343 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3344 correct = False;
3345 goto fail;
3348 /* This should fail with a sharing violation - open for delete is only compatible
3349 with SHARE_DELETE. */
3351 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3352 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3353 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3354 correct = False;
3355 goto fail;
3358 /* This should succeed. */
3360 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3361 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3362 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3363 correct = False;
3364 goto fail;
3367 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3368 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3369 correct = False;
3370 goto fail;
3373 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3374 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3375 correct = False;
3376 goto fail;
3379 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3380 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3381 correct = False;
3382 goto fail;
3385 /* This should fail - file should no longer be there. */
3387 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3388 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3389 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3390 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3392 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3393 correct = False;
3394 goto fail;
3395 } else
3396 printf("third delete on close test succeeded.\n");
3398 /* Test 4 ... */
3399 cli_setatr(cli1, fname, 0, 0);
3400 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3402 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3403 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3404 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3405 correct = False;
3406 goto fail;
3409 /* This should succeed. */
3410 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3411 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3412 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3413 correct = False;
3414 goto fail;
3417 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3418 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3419 correct = False;
3420 goto fail;
3423 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3424 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3425 correct = False;
3426 goto fail;
3429 /* This should fail - no more opens once delete on close set. */
3430 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3431 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3432 FILE_OPEN, 0, 0, &fnum2))) {
3433 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3434 correct = False;
3435 goto fail;
3436 } else
3437 printf("fourth delete on close test succeeded.\n");
3439 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3440 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3441 correct = False;
3442 goto fail;
3445 /* Test 5 ... */
3446 cli_setatr(cli1, fname, 0, 0);
3447 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3449 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3450 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3451 correct = False;
3452 goto fail;
3455 /* This should fail - only allowed on NT opens with DELETE access. */
3457 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3458 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3459 correct = False;
3460 goto fail;
3463 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3464 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3465 correct = False;
3466 goto fail;
3469 printf("fifth delete on close test succeeded.\n");
3471 /* Test 6 ... */
3472 cli_setatr(cli1, fname, 0, 0);
3473 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3475 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3476 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3477 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3478 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3479 correct = False;
3480 goto fail;
3483 /* This should fail - only allowed on NT opens with DELETE access. */
3485 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3486 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3487 correct = False;
3488 goto fail;
3491 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3492 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3493 correct = False;
3494 goto fail;
3497 printf("sixth delete on close test succeeded.\n");
3499 /* Test 7 ... */
3500 cli_setatr(cli1, fname, 0, 0);
3501 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3503 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3504 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3505 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3506 correct = False;
3507 goto fail;
3510 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3511 printf("[7] setting delete_on_close on file failed !\n");
3512 correct = False;
3513 goto fail;
3516 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3517 printf("[7] unsetting delete_on_close on file failed !\n");
3518 correct = False;
3519 goto fail;
3522 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3523 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3524 correct = False;
3525 goto fail;
3528 /* This next open should succeed - we reset the flag. */
3530 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3531 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3532 correct = False;
3533 goto fail;
3536 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3537 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3538 correct = False;
3539 goto fail;
3542 printf("seventh delete on close test succeeded.\n");
3544 /* Test 7 ... */
3545 cli_setatr(cli1, fname, 0, 0);
3546 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3548 if (!torture_open_connection(&cli2, 1)) {
3549 printf("[8] failed to open second connection.\n");
3550 correct = False;
3551 goto fail;
3554 cli_sockopt(cli1, sockops);
3556 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3557 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3558 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3559 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3560 correct = False;
3561 goto fail;
3564 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3565 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3566 FILE_OPEN, 0, 0, &fnum2))) {
3567 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3568 correct = False;
3569 goto fail;
3572 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3573 printf("[8] setting delete_on_close on file failed !\n");
3574 correct = False;
3575 goto fail;
3578 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3579 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3580 correct = False;
3581 goto fail;
3584 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3585 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3586 correct = False;
3587 goto fail;
3590 /* This should fail.. */
3591 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3592 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3593 goto fail;
3594 correct = False;
3595 } else
3596 printf("eighth delete on close test succeeded.\n");
3598 /* This should fail - we need to set DELETE_ACCESS. */
3599 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3600 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3601 printf("[9] open of %s succeeded should have failed!\n", fname);
3602 correct = False;
3603 goto fail;
3606 printf("ninth delete on close test succeeded.\n");
3608 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3609 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3610 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3611 correct = False;
3612 goto fail;
3615 /* This should delete the file. */
3616 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3617 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3618 correct = False;
3619 goto fail;
3622 /* This should fail.. */
3623 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3624 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3625 goto fail;
3626 correct = False;
3627 } else
3628 printf("tenth delete on close test succeeded.\n");
3630 cli_setatr(cli1, fname, 0, 0);
3631 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3633 /* What error do we get when attempting to open a read-only file with
3634 delete access ? */
3636 /* Create a readonly file. */
3637 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3638 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3639 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3640 correct = False;
3641 goto fail;
3644 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3645 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3646 correct = False;
3647 goto fail;
3650 /* Now try open for delete access. */
3651 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3652 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3653 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3654 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3655 cli_close(cli1, fnum1);
3656 goto fail;
3657 correct = False;
3658 } else {
3659 NTSTATUS nterr = cli_nt_error(cli1);
3660 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3661 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3662 goto fail;
3663 correct = False;
3664 } else {
3665 printf("eleventh delete on close test succeeded.\n");
3669 printf("finished delete test\n");
3671 fail:
3672 /* FIXME: This will crash if we aborted before cli2 got
3673 * intialized, because these functions don't handle
3674 * uninitialized connections. */
3676 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3677 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3678 cli_setatr(cli1, fname, 0, 0);
3679 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3681 if (cli1 && !torture_close_connection(cli1)) {
3682 correct = False;
3684 if (cli2 && !torture_close_connection(cli2)) {
3685 correct = False;
3687 return correct;
3692 print out server properties
3694 static bool run_properties(int dummy)
3696 struct cli_state *cli;
3697 bool correct = True;
3699 printf("starting properties test\n");
3701 ZERO_STRUCT(cli);
3703 if (!torture_open_connection(&cli, 0)) {
3704 return False;
3707 cli_sockopt(cli, sockops);
3709 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3711 if (!torture_close_connection(cli)) {
3712 correct = False;
3715 return correct;
3720 /* FIRST_DESIRED_ACCESS 0xf019f */
3721 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3722 FILE_READ_EA| /* 0xf */ \
3723 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3724 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3725 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3726 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3727 /* SECOND_DESIRED_ACCESS 0xe0080 */
3728 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3729 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3730 WRITE_OWNER_ACCESS /* 0xe0000 */
3732 #if 0
3733 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3734 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3735 FILE_READ_DATA|\
3736 WRITE_OWNER_ACCESS /* */
3737 #endif
3740 Test ntcreate calls made by xcopy
3742 static bool run_xcopy(int dummy)
3744 static struct cli_state *cli1;
3745 const char *fname = "\\test.txt";
3746 bool correct = True;
3747 uint16_t fnum1, fnum2;
3749 printf("starting xcopy test\n");
3751 if (!torture_open_connection(&cli1, 0)) {
3752 return False;
3755 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3756 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3757 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3758 0x4044, 0, &fnum1))) {
3759 printf("First open failed - %s\n", cli_errstr(cli1));
3760 return False;
3763 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3764 SECOND_DESIRED_ACCESS, 0,
3765 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3766 0x200000, 0, &fnum2))) {
3767 printf("second open failed - %s\n", cli_errstr(cli1));
3768 return False;
3771 if (!torture_close_connection(cli1)) {
3772 correct = False;
3775 return correct;
3779 Test rename on files open with share delete and no share delete.
3781 static bool run_rename(int dummy)
3783 static struct cli_state *cli1;
3784 const char *fname = "\\test.txt";
3785 const char *fname1 = "\\test1.txt";
3786 bool correct = True;
3787 uint16_t fnum1;
3788 NTSTATUS status;
3790 printf("starting rename test\n");
3792 if (!torture_open_connection(&cli1, 0)) {
3793 return False;
3796 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3797 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3798 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3799 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3800 printf("First open failed - %s\n", cli_errstr(cli1));
3801 return False;
3804 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3805 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3806 } else {
3807 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3808 correct = False;
3811 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3812 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3813 return False;
3816 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3817 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3818 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3819 #if 0
3820 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3821 #else
3822 FILE_SHARE_DELETE|FILE_SHARE_READ,
3823 #endif
3824 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3825 if (!NT_STATUS_IS_OK(status)) {
3826 printf("Second open failed - %s\n", cli_errstr(cli1));
3827 return False;
3830 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3831 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3832 correct = False;
3833 } else {
3834 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3837 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3838 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3839 return False;
3842 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3843 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3845 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3846 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3847 printf("Third open failed - %s\n", cli_errstr(cli1));
3848 return False;
3852 #if 0
3854 uint16_t fnum2;
3856 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3857 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3858 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3859 return False;
3861 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3862 printf("[8] setting delete_on_close on file failed !\n");
3863 return False;
3866 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3867 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3868 return False;
3871 #endif
3873 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3874 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3875 correct = False;
3876 } else {
3877 printf("Third rename succeeded (SHARE_NONE)\n");
3880 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3881 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3882 return False;
3885 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3886 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3888 /*----*/
3890 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3891 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3892 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3893 return False;
3896 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3897 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3898 } else {
3899 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3900 correct = False;
3903 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3904 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3905 return False;
3908 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3909 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3911 /*--*/
3913 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3914 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3915 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3916 return False;
3919 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3920 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3921 cli_errstr(cli1));
3922 correct = False;
3923 } else {
3924 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3928 * Now check if the first name still exists ...
3931 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3932 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3933 printf("Opening original file after rename of open file fails: %s\n",
3934 cli_errstr(cli1));
3936 else {
3937 printf("Opening original file after rename of open file works ...\n");
3938 (void)cli_close(cli1, fnum2);
3939 } */
3941 /*--*/
3944 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3945 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3946 return False;
3949 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3950 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3952 if (!torture_close_connection(cli1)) {
3953 correct = False;
3956 return correct;
3959 static bool run_pipe_number(int dummy)
3961 struct cli_state *cli1;
3962 const char *pipe_name = "\\SPOOLSS";
3963 uint16_t fnum;
3964 int num_pipes = 0;
3966 printf("starting pipenumber test\n");
3967 if (!torture_open_connection(&cli1, 0)) {
3968 return False;
3971 cli_sockopt(cli1, sockops);
3972 while(1) {
3973 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3974 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
3975 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3976 break;
3978 num_pipes++;
3979 printf("\r%6d", num_pipes);
3982 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3983 torture_close_connection(cli1);
3984 return True;
3988 Test open mode returns on read-only files.
3990 static bool run_opentest(int dummy)
3992 static struct cli_state *cli1;
3993 static struct cli_state *cli2;
3994 const char *fname = "\\readonly.file";
3995 uint16_t fnum1, fnum2;
3996 char buf[20];
3997 SMB_OFF_T fsize;
3998 bool correct = True;
3999 char *tmp_path;
4001 printf("starting open test\n");
4003 if (!torture_open_connection(&cli1, 0)) {
4004 return False;
4007 cli_setatr(cli1, fname, 0, 0);
4008 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4010 cli_sockopt(cli1, sockops);
4012 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4013 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4014 return False;
4017 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4018 printf("close2 failed (%s)\n", cli_errstr(cli1));
4019 return False;
4022 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4023 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4024 return False;
4027 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4028 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4029 return False;
4032 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4033 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4035 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4036 NT_STATUS_ACCESS_DENIED)) {
4037 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4040 printf("finished open test 1\n");
4042 cli_close(cli1, fnum1);
4044 /* Now try not readonly and ensure ERRbadshare is returned. */
4046 cli_setatr(cli1, fname, 0, 0);
4048 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4049 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4050 return False;
4053 /* This will fail - but the error should be ERRshare. */
4054 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4056 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4057 NT_STATUS_SHARING_VIOLATION)) {
4058 printf("correct error code ERRDOS/ERRbadshare returned\n");
4061 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4062 printf("close2 failed (%s)\n", cli_errstr(cli1));
4063 return False;
4066 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4068 printf("finished open test 2\n");
4070 /* Test truncate open disposition on file opened for read. */
4072 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4073 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4074 return False;
4077 /* write 20 bytes. */
4079 memset(buf, '\0', 20);
4081 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4082 printf("write failed (%s)\n", cli_errstr(cli1));
4083 correct = False;
4086 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4087 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4088 return False;
4091 /* Ensure size == 20. */
4092 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4093 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4094 return False;
4097 if (fsize != 20) {
4098 printf("(3) file size != 20\n");
4099 return False;
4102 /* Now test if we can truncate a file opened for readonly. */
4104 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4105 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4106 return False;
4109 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4110 printf("close2 failed (%s)\n", cli_errstr(cli1));
4111 return False;
4114 /* Ensure size == 0. */
4115 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4116 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4117 return False;
4120 if (fsize != 0) {
4121 printf("(3) file size != 0\n");
4122 return False;
4124 printf("finished open test 3\n");
4126 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4129 printf("testing ctemp\n");
4130 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4131 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4132 return False;
4134 printf("ctemp gave path %s\n", tmp_path);
4135 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4136 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4138 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4139 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4142 /* Test the non-io opens... */
4144 if (!torture_open_connection(&cli2, 1)) {
4145 return False;
4148 cli_setatr(cli2, fname, 0, 0);
4149 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4151 cli_sockopt(cli2, sockops);
4153 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4155 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4156 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4157 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4158 return False;
4161 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4162 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4163 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4164 return False;
4167 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4168 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4169 return False;
4171 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4172 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4173 return False;
4176 printf("non-io open test #1 passed.\n");
4178 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4180 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4182 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4183 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4184 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4185 return False;
4188 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4189 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4190 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4191 return False;
4194 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4195 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4196 return False;
4198 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4199 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4200 return False;
4203 printf("non-io open test #2 passed.\n");
4205 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4207 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4209 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4210 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4211 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4212 return False;
4215 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4216 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4217 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4218 return False;
4221 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4222 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4223 return False;
4225 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4226 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4227 return False;
4230 printf("non-io open test #3 passed.\n");
4232 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4234 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4236 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4237 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4238 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4239 return False;
4242 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4243 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4244 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4245 return False;
4248 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4250 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4251 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4252 return False;
4255 printf("non-io open test #4 passed.\n");
4257 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4259 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4261 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4262 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4263 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4264 return False;
4267 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4268 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4269 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4270 return False;
4273 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4274 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4275 return False;
4278 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4279 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4280 return False;
4283 printf("non-io open test #5 passed.\n");
4285 printf("TEST #6 testing 1 non-io open, one io open\n");
4287 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4289 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4290 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4291 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4292 return False;
4295 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4296 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4297 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4298 return False;
4301 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4302 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4303 return False;
4306 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4307 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4308 return False;
4311 printf("non-io open test #6 passed.\n");
4313 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4315 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4317 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4318 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4319 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4320 return False;
4323 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4324 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4325 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4326 return False;
4329 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4331 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4332 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4333 return False;
4336 printf("non-io open test #7 passed.\n");
4338 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4340 if (!torture_close_connection(cli1)) {
4341 correct = False;
4343 if (!torture_close_connection(cli2)) {
4344 correct = False;
4347 return correct;
4351 Test POSIX open /mkdir calls.
4353 static bool run_simple_posix_open_test(int dummy)
4355 static struct cli_state *cli1;
4356 const char *fname = "posix:file";
4357 const char *hname = "posix:hlink";
4358 const char *sname = "posix:symlink";
4359 const char *dname = "posix:dir";
4360 char buf[10];
4361 char namebuf[11];
4362 uint16 major, minor;
4363 uint32 caplow, caphigh;
4364 uint16_t fnum1 = (uint16_t)-1;
4365 SMB_STRUCT_STAT sbuf;
4366 bool correct = false;
4367 NTSTATUS status;
4369 printf("Starting simple POSIX open test\n");
4371 if (!torture_open_connection(&cli1, 0)) {
4372 return false;
4375 cli_sockopt(cli1, sockops);
4377 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4378 printf("Server doesn't support UNIX CIFS extensions.\n");
4379 return false;
4382 status = cli_unix_extensions_version(cli1, &major, &minor, &caplow,
4383 &caphigh);
4384 if (!NT_STATUS_IS_OK(status)) {
4385 printf("Server didn't return UNIX CIFS extensions: %s\n",
4386 nt_errstr(status));
4387 return false;
4390 status = cli_set_unix_extensions_capabilities(cli1, major, minor,
4391 caplow, caphigh);
4392 if (!NT_STATUS_IS_OK(status)) {
4393 printf("Server doesn't support setting UNIX CIFS extensions: "
4394 "%s.\n", nt_errstr(status));
4395 return false;
4398 cli_setatr(cli1, fname, 0, 0);
4399 cli_posix_unlink(cli1, fname);
4400 cli_setatr(cli1, dname, 0, 0);
4401 cli_posix_rmdir(cli1, dname);
4402 cli_setatr(cli1, hname, 0, 0);
4403 cli_posix_unlink(cli1, hname);
4404 cli_setatr(cli1, sname, 0, 0);
4405 cli_posix_unlink(cli1, sname);
4407 /* Create a directory. */
4408 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4409 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4410 goto out;
4413 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4414 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4415 goto out;
4418 /* Test ftruncate - set file size. */
4419 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4420 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4421 goto out;
4424 /* Ensure st_size == 1000 */
4425 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4426 printf("stat failed (%s)\n", cli_errstr(cli1));
4427 goto out;
4430 if (sbuf.st_ex_size != 1000) {
4431 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4432 goto out;
4435 /* Test ftruncate - set file size back to zero. */
4436 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4437 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4438 goto out;
4441 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4442 printf("close failed (%s)\n", cli_errstr(cli1));
4443 goto out;
4446 /* Now open the file again for read only. */
4447 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4448 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4449 goto out;
4452 /* Now unlink while open. */
4453 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4454 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4455 goto out;
4458 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4459 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4460 goto out;
4463 /* Ensure the file has gone. */
4464 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4465 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4466 goto out;
4469 /* What happens when we try and POSIX open a directory ? */
4470 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4471 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4472 goto out;
4473 } else {
4474 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4475 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4476 goto out;
4480 /* Create the file. */
4481 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4482 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4483 goto out;
4486 /* Write some data into it. */
4487 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4488 printf("cli_write failed: %s\n", cli_errstr(cli1));
4489 goto out;
4492 cli_close(cli1, fnum1);
4494 /* Now create a hardlink. */
4495 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4496 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4497 goto out;
4500 /* Now create a symlink. */
4501 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4502 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4503 goto out;
4506 /* Open the hardlink for read. */
4507 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4508 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4509 goto out;
4512 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4513 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4514 goto out;
4517 if (memcmp(buf, "TEST DATA\n", 10)) {
4518 printf("invalid data read from hardlink\n");
4519 goto out;
4522 /* Do a POSIX lock/unlock. */
4523 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4524 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4525 goto out;
4528 /* Punch a hole in the locked area. */
4529 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4530 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4531 goto out;
4534 cli_close(cli1, fnum1);
4536 /* Open the symlink for read - this should fail. A POSIX
4537 client should not be doing opens on a symlink. */
4538 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4539 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4540 goto out;
4541 } else {
4542 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4543 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4544 printf("POSIX open of %s should have failed "
4545 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4546 "failed with %s instead.\n",
4547 sname, cli_errstr(cli1));
4548 goto out;
4552 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4553 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4554 goto out;
4557 if (strcmp(namebuf, fname) != 0) {
4558 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4559 sname, fname, namebuf);
4560 goto out;
4563 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4564 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4565 goto out;
4568 printf("Simple POSIX open test passed\n");
4569 correct = true;
4571 out:
4573 if (fnum1 != (uint16_t)-1) {
4574 cli_close(cli1, fnum1);
4575 fnum1 = (uint16_t)-1;
4578 cli_setatr(cli1, sname, 0, 0);
4579 cli_posix_unlink(cli1, sname);
4580 cli_setatr(cli1, hname, 0, 0);
4581 cli_posix_unlink(cli1, hname);
4582 cli_setatr(cli1, fname, 0, 0);
4583 cli_posix_unlink(cli1, fname);
4584 cli_setatr(cli1, dname, 0, 0);
4585 cli_posix_rmdir(cli1, dname);
4587 if (!torture_close_connection(cli1)) {
4588 correct = false;
4591 return correct;
4595 static uint32 open_attrs_table[] = {
4596 FILE_ATTRIBUTE_NORMAL,
4597 FILE_ATTRIBUTE_ARCHIVE,
4598 FILE_ATTRIBUTE_READONLY,
4599 FILE_ATTRIBUTE_HIDDEN,
4600 FILE_ATTRIBUTE_SYSTEM,
4602 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4603 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4604 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4605 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4606 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4607 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4609 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4610 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4611 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4612 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4615 struct trunc_open_results {
4616 unsigned int num;
4617 uint32 init_attr;
4618 uint32 trunc_attr;
4619 uint32 result_attr;
4622 static struct trunc_open_results attr_results[] = {
4623 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4624 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4625 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4626 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4627 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4628 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4629 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4630 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4631 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4632 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4633 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4634 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4635 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4636 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4637 { 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 },
4638 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4639 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4640 { 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 },
4641 { 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 },
4642 { 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 },
4643 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4644 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4645 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4646 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4647 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4648 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4651 static bool run_openattrtest(int dummy)
4653 static struct cli_state *cli1;
4654 const char *fname = "\\openattr.file";
4655 uint16_t fnum1;
4656 bool correct = True;
4657 uint16 attr;
4658 unsigned int i, j, k, l;
4660 printf("starting open attr test\n");
4662 if (!torture_open_connection(&cli1, 0)) {
4663 return False;
4666 cli_sockopt(cli1, sockops);
4668 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4669 cli_setatr(cli1, fname, 0, 0);
4670 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4671 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4672 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4673 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4674 return False;
4677 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4678 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4679 return False;
4682 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4683 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4684 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4685 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4686 if (attr_results[l].num == k) {
4687 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4688 k, open_attrs_table[i],
4689 open_attrs_table[j],
4690 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4691 correct = False;
4694 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4695 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4696 k, open_attrs_table[i], open_attrs_table[j],
4697 cli_errstr(cli1));
4698 correct = False;
4700 #if 0
4701 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4702 #endif
4703 k++;
4704 continue;
4707 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4708 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4709 return False;
4712 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4713 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4714 return False;
4717 #if 0
4718 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4719 k, open_attrs_table[i], open_attrs_table[j], attr );
4720 #endif
4722 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4723 if (attr_results[l].num == k) {
4724 if (attr != attr_results[l].result_attr ||
4725 open_attrs_table[i] != attr_results[l].init_attr ||
4726 open_attrs_table[j] != attr_results[l].trunc_attr) {
4727 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4728 open_attrs_table[i],
4729 open_attrs_table[j],
4730 (unsigned int)attr,
4731 attr_results[l].result_attr);
4732 correct = False;
4734 break;
4737 k++;
4741 cli_setatr(cli1, fname, 0, 0);
4742 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4744 printf("open attr test %s.\n", correct ? "passed" : "failed");
4746 if (!torture_close_connection(cli1)) {
4747 correct = False;
4749 return correct;
4752 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4758 test directory listing speed
4760 static bool run_dirtest(int dummy)
4762 int i;
4763 static struct cli_state *cli;
4764 uint16_t fnum;
4765 struct timeval core_start;
4766 bool correct = True;
4768 printf("starting directory test\n");
4770 if (!torture_open_connection(&cli, 0)) {
4771 return False;
4774 cli_sockopt(cli, sockops);
4776 srandom(0);
4777 for (i=0;i<torture_numops;i++) {
4778 fstring fname;
4779 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4780 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4781 fprintf(stderr,"Failed to open %s\n", fname);
4782 return False;
4784 cli_close(cli, fnum);
4787 core_start = timeval_current();
4789 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4790 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4791 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4793 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4795 srandom(0);
4796 for (i=0;i<torture_numops;i++) {
4797 fstring fname;
4798 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4799 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4802 if (!torture_close_connection(cli)) {
4803 correct = False;
4806 printf("finished dirtest\n");
4808 return correct;
4811 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4813 struct cli_state *pcli = (struct cli_state *)state;
4814 fstring fname;
4815 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4817 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4818 return;
4820 if (finfo->mode & aDIR) {
4821 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4822 printf("del_fn: failed to rmdir %s\n,", fname );
4823 } else {
4824 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4825 printf("del_fn: failed to unlink %s\n,", fname );
4831 sees what IOCTLs are supported
4833 bool torture_ioctl_test(int dummy)
4835 static struct cli_state *cli;
4836 uint16_t device, function;
4837 uint16_t fnum;
4838 const char *fname = "\\ioctl.dat";
4839 DATA_BLOB blob;
4840 NTSTATUS status;
4842 if (!torture_open_connection(&cli, 0)) {
4843 return False;
4846 printf("starting ioctl test\n");
4848 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4850 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4851 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4852 return False;
4855 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4856 printf("ioctl device info: %s\n", cli_errstr(cli));
4858 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4859 printf("ioctl job info: %s\n", cli_errstr(cli));
4861 for (device=0;device<0x100;device++) {
4862 printf("testing device=0x%x\n", device);
4863 for (function=0;function<0x100;function++) {
4864 uint32 code = (device<<16) | function;
4866 status = cli_raw_ioctl(cli, fnum, code, &blob);
4868 if (NT_STATUS_IS_OK(status)) {
4869 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4870 (int)blob.length);
4871 data_blob_free(&blob);
4876 if (!torture_close_connection(cli)) {
4877 return False;
4880 return True;
4885 tries varients of chkpath
4887 bool torture_chkpath_test(int dummy)
4889 static struct cli_state *cli;
4890 uint16_t fnum;
4891 bool ret;
4893 if (!torture_open_connection(&cli, 0)) {
4894 return False;
4897 printf("starting chkpath test\n");
4899 /* cleanup from an old run */
4900 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4901 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4902 cli_rmdir(cli, "\\chkpath.dir");
4904 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4905 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4906 return False;
4909 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4910 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4911 return False;
4914 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4915 printf("open1 failed (%s)\n", cli_errstr(cli));
4916 return False;
4918 cli_close(cli, fnum);
4920 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4921 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4922 ret = False;
4925 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4926 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4927 ret = False;
4930 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4931 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4932 NT_STATUS_NOT_A_DIRECTORY);
4933 } else {
4934 printf("* chkpath on a file should fail\n");
4935 ret = False;
4938 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4939 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4940 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4941 } else {
4942 printf("* chkpath on a non existant file should fail\n");
4943 ret = False;
4946 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4947 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4948 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4949 } else {
4950 printf("* chkpath on a non existent component should fail\n");
4951 ret = False;
4954 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4955 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4956 cli_rmdir(cli, "\\chkpath.dir");
4958 if (!torture_close_connection(cli)) {
4959 return False;
4962 return ret;
4965 static bool run_eatest(int dummy)
4967 static struct cli_state *cli;
4968 const char *fname = "\\eatest.txt";
4969 bool correct = True;
4970 uint16_t fnum;
4971 int i;
4972 size_t num_eas;
4973 struct ea_struct *ea_list = NULL;
4974 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4976 printf("starting eatest\n");
4978 if (!torture_open_connection(&cli, 0)) {
4979 talloc_destroy(mem_ctx);
4980 return False;
4983 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4984 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
4985 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4986 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4987 0x4044, 0, &fnum))) {
4988 printf("open failed - %s\n", cli_errstr(cli));
4989 talloc_destroy(mem_ctx);
4990 return False;
4993 for (i = 0; i < 10; i++) {
4994 fstring ea_name, ea_val;
4996 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4997 memset(ea_val, (char)i+1, i+1);
4998 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4999 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5000 talloc_destroy(mem_ctx);
5001 return False;
5005 cli_close(cli, fnum);
5006 for (i = 0; i < 10; i++) {
5007 fstring ea_name, ea_val;
5009 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5010 memset(ea_val, (char)i+1, i+1);
5011 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5012 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5013 talloc_destroy(mem_ctx);
5014 return False;
5018 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5019 printf("ea_get list failed - %s\n", cli_errstr(cli));
5020 correct = False;
5023 printf("num_eas = %d\n", (int)num_eas);
5025 if (num_eas != 20) {
5026 printf("Should be 20 EA's stored... failing.\n");
5027 correct = False;
5030 for (i = 0; i < num_eas; i++) {
5031 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5032 dump_data(0, ea_list[i].value.data,
5033 ea_list[i].value.length);
5036 /* Setting EA's to zero length deletes them. Test this */
5037 printf("Now deleting all EA's - case indepenent....\n");
5039 #if 1
5040 cli_set_ea_path(cli, fname, "", "", 0);
5041 #else
5042 for (i = 0; i < 20; i++) {
5043 fstring ea_name;
5044 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5045 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5046 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5047 talloc_destroy(mem_ctx);
5048 return False;
5051 #endif
5053 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5054 printf("ea_get list failed - %s\n", cli_errstr(cli));
5055 correct = False;
5058 printf("num_eas = %d\n", (int)num_eas);
5059 for (i = 0; i < num_eas; i++) {
5060 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5061 dump_data(0, ea_list[i].value.data,
5062 ea_list[i].value.length);
5065 if (num_eas != 0) {
5066 printf("deleting EA's failed.\n");
5067 correct = False;
5070 /* Try and delete a non existant EA. */
5071 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5072 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5073 correct = False;
5076 talloc_destroy(mem_ctx);
5077 if (!torture_close_connection(cli)) {
5078 correct = False;
5081 return correct;
5084 static bool run_dirtest1(int dummy)
5086 int i;
5087 static struct cli_state *cli;
5088 uint16_t fnum;
5089 int num_seen;
5090 bool correct = True;
5092 printf("starting directory test\n");
5094 if (!torture_open_connection(&cli, 0)) {
5095 return False;
5098 cli_sockopt(cli, sockops);
5100 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5101 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5102 cli_rmdir(cli, "\\LISTDIR");
5103 cli_mkdir(cli, "\\LISTDIR");
5105 /* Create 1000 files and 1000 directories. */
5106 for (i=0;i<1000;i++) {
5107 fstring fname;
5108 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5109 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5110 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5111 fprintf(stderr,"Failed to open %s\n", fname);
5112 return False;
5114 cli_close(cli, fnum);
5116 for (i=0;i<1000;i++) {
5117 fstring fname;
5118 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5119 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5120 fprintf(stderr,"Failed to open %s\n", fname);
5121 return False;
5125 /* Now ensure that doing an old list sees both files and directories. */
5126 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5127 printf("num_seen = %d\n", num_seen );
5128 /* We should see 100 files + 1000 directories + . and .. */
5129 if (num_seen != 2002)
5130 correct = False;
5132 /* Ensure if we have the "must have" bits we only see the
5133 * relevent entries.
5135 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5136 printf("num_seen = %d\n", num_seen );
5137 if (num_seen != 1002)
5138 correct = False;
5140 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5141 printf("num_seen = %d\n", num_seen );
5142 if (num_seen != 1000)
5143 correct = False;
5145 /* Delete everything. */
5146 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5147 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5148 cli_rmdir(cli, "\\LISTDIR");
5150 #if 0
5151 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5152 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5153 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5154 #endif
5156 if (!torture_close_connection(cli)) {
5157 correct = False;
5160 printf("finished dirtest1\n");
5162 return correct;
5165 static bool run_error_map_extract(int dummy) {
5167 static struct cli_state *c_dos;
5168 static struct cli_state *c_nt;
5169 NTSTATUS status;
5171 uint32 error;
5173 uint32 flgs2, errnum;
5174 uint8 errclass;
5176 NTSTATUS nt_status;
5178 fstring user;
5180 /* NT-Error connection */
5182 if (!(c_nt = open_nbt_connection())) {
5183 return False;
5186 c_nt->use_spnego = False;
5188 status = cli_negprot(c_nt);
5190 if (!NT_STATUS_IS_OK(status)) {
5191 printf("%s rejected the NT-error negprot (%s)\n", host,
5192 nt_errstr(status));
5193 cli_shutdown(c_nt);
5194 return False;
5197 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5198 workgroup))) {
5199 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5200 return False;
5203 /* DOS-Error connection */
5205 if (!(c_dos = open_nbt_connection())) {
5206 return False;
5209 c_dos->use_spnego = False;
5210 c_dos->force_dos_errors = True;
5212 status = cli_negprot(c_dos);
5213 if (!NT_STATUS_IS_OK(status)) {
5214 printf("%s rejected the DOS-error negprot (%s)\n", host,
5215 nt_errstr(status));
5216 cli_shutdown(c_dos);
5217 return False;
5220 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5221 workgroup))) {
5222 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5223 return False;
5226 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5227 fstr_sprintf(user, "%X", error);
5229 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5230 password, strlen(password),
5231 password, strlen(password),
5232 workgroup))) {
5233 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5236 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5238 /* Case #1: 32-bit NT errors */
5239 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5240 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5241 } else {
5242 printf("/** Dos error on NT connection! (%s) */\n",
5243 cli_errstr(c_nt));
5244 nt_status = NT_STATUS(0xc0000000);
5247 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5248 password, strlen(password),
5249 password, strlen(password),
5250 workgroup))) {
5251 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5253 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5255 /* Case #1: 32-bit NT errors */
5256 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5257 printf("/** NT error on DOS connection! (%s) */\n",
5258 cli_errstr(c_nt));
5259 errnum = errclass = 0;
5260 } else {
5261 cli_dos_error(c_dos, &errclass, &errnum);
5264 if (NT_STATUS_V(nt_status) != error) {
5265 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5266 get_nt_error_c_code(NT_STATUS(error)),
5267 get_nt_error_c_code(nt_status));
5270 printf("\t{%s,\t%s,\t%s},\n",
5271 smb_dos_err_class(errclass),
5272 smb_dos_err_name(errclass, errnum),
5273 get_nt_error_c_code(NT_STATUS(error)));
5275 return True;
5278 static bool run_sesssetup_bench(int dummy)
5280 static struct cli_state *c;
5281 const char *fname = "\\file.dat";
5282 uint16_t fnum;
5283 NTSTATUS status;
5284 int i;
5286 if (!torture_open_connection(&c, 0)) {
5287 return false;
5290 if (!NT_STATUS_IS_OK(cli_ntcreate(
5291 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5292 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5293 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5294 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5295 return false;
5298 for (i=0; i<torture_numops; i++) {
5299 status = cli_session_setup(
5300 c, username,
5301 password, strlen(password),
5302 password, strlen(password),
5303 workgroup);
5304 if (!NT_STATUS_IS_OK(status)) {
5305 d_printf("(%s) cli_session_setup failed: %s\n",
5306 __location__, nt_errstr(status));
5307 return false;
5310 d_printf("\r%d ", (int)c->vuid);
5312 if (!cli_ulogoff(c)) {
5313 d_printf("(%s) cli_ulogoff failed: %s\n",
5314 __location__, cli_errstr(c));
5315 return false;
5317 c->vuid = 0;
5320 return true;
5323 static bool subst_test(const char *str, const char *user, const char *domain,
5324 uid_t uid, gid_t gid, const char *expected)
5326 char *subst;
5327 bool result = true;
5329 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5331 if (strcmp(subst, expected) != 0) {
5332 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5333 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5334 expected);
5335 result = false;
5338 TALLOC_FREE(subst);
5339 return result;
5342 static void chain1_open_completion(struct tevent_req *req)
5344 uint16_t fnum;
5345 NTSTATUS status;
5346 status = cli_open_recv(req, &fnum);
5347 TALLOC_FREE(req);
5349 d_printf("cli_open_recv returned %s: %d\n",
5350 nt_errstr(status),
5351 NT_STATUS_IS_OK(status) ? fnum : -1);
5354 static void chain1_write_completion(struct tevent_req *req)
5356 size_t written;
5357 NTSTATUS status;
5358 status = cli_write_andx_recv(req, &written);
5359 TALLOC_FREE(req);
5361 d_printf("cli_write_andx_recv returned %s: %d\n",
5362 nt_errstr(status),
5363 NT_STATUS_IS_OK(status) ? (int)written : -1);
5366 static void chain1_close_completion(struct tevent_req *req)
5368 NTSTATUS status;
5369 bool *done = (bool *)tevent_req_callback_data_void(req);
5371 status = cli_close_recv(req);
5372 *done = true;
5374 TALLOC_FREE(req);
5376 d_printf("cli_close returned %s\n", nt_errstr(status));
5379 static bool run_chain1(int dummy)
5381 struct cli_state *cli1;
5382 struct event_context *evt = event_context_init(NULL);
5383 struct tevent_req *reqs[3], *smbreqs[3];
5384 bool done = false;
5385 const char *str = "foobar";
5386 NTSTATUS status;
5388 printf("starting chain1 test\n");
5389 if (!torture_open_connection(&cli1, 0)) {
5390 return False;
5393 cli_sockopt(cli1, sockops);
5395 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5396 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5397 if (reqs[0] == NULL) return false;
5398 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5401 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5402 (uint8_t *)str, 0, strlen(str)+1,
5403 smbreqs, 1, &smbreqs[1]);
5404 if (reqs[1] == NULL) return false;
5405 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5407 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5408 if (reqs[2] == NULL) return false;
5409 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5411 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5412 if (!NT_STATUS_IS_OK(status)) {
5413 return false;
5416 while (!done) {
5417 event_loop_once(evt);
5420 torture_close_connection(cli1);
5421 return True;
5424 static void chain2_sesssetup_completion(struct tevent_req *req)
5426 NTSTATUS status;
5427 status = cli_session_setup_guest_recv(req);
5428 d_printf("sesssetup returned %s\n", nt_errstr(status));
5431 static void chain2_tcon_completion(struct tevent_req *req)
5433 bool *done = (bool *)tevent_req_callback_data_void(req);
5434 NTSTATUS status;
5435 status = cli_tcon_andx_recv(req);
5436 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5437 *done = true;
5440 static bool run_chain2(int dummy)
5442 struct cli_state *cli1;
5443 struct event_context *evt = event_context_init(NULL);
5444 struct tevent_req *reqs[2], *smbreqs[2];
5445 bool done = false;
5446 NTSTATUS status;
5448 printf("starting chain2 test\n");
5449 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5450 port_to_use, Undefined, 0, NULL);
5451 if (!NT_STATUS_IS_OK(status)) {
5452 return False;
5455 cli_sockopt(cli1, sockops);
5457 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5458 &smbreqs[0]);
5459 if (reqs[0] == NULL) return false;
5460 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5462 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5463 "?????", NULL, 0, &smbreqs[1]);
5464 if (reqs[1] == NULL) return false;
5465 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5467 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5468 if (!NT_STATUS_IS_OK(status)) {
5469 return false;
5472 while (!done) {
5473 event_loop_once(evt);
5476 torture_close_connection(cli1);
5477 return True;
5481 struct torture_createdel_state {
5482 struct tevent_context *ev;
5483 struct cli_state *cli;
5486 static void torture_createdel_created(struct tevent_req *subreq);
5487 static void torture_createdel_closed(struct tevent_req *subreq);
5489 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5490 struct tevent_context *ev,
5491 struct cli_state *cli,
5492 const char *name)
5494 struct tevent_req *req, *subreq;
5495 struct torture_createdel_state *state;
5497 req = tevent_req_create(mem_ctx, &state,
5498 struct torture_createdel_state);
5499 if (req == NULL) {
5500 return NULL;
5502 state->ev = ev;
5503 state->cli = cli;
5505 subreq = cli_ntcreate_send(
5506 state, ev, cli, name, 0,
5507 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5508 FILE_ATTRIBUTE_NORMAL,
5509 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5510 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5512 if (tevent_req_nomem(subreq, req)) {
5513 return tevent_req_post(req, ev);
5515 tevent_req_set_callback(subreq, torture_createdel_created, req);
5516 return req;
5519 static void torture_createdel_created(struct tevent_req *subreq)
5521 struct tevent_req *req = tevent_req_callback_data(
5522 subreq, struct tevent_req);
5523 struct torture_createdel_state *state = tevent_req_data(
5524 req, struct torture_createdel_state);
5525 NTSTATUS status;
5526 uint16_t fnum;
5528 status = cli_ntcreate_recv(subreq, &fnum);
5529 TALLOC_FREE(subreq);
5530 if (!NT_STATUS_IS_OK(status)) {
5531 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5532 nt_errstr(status)));
5533 tevent_req_nterror(req, status);
5534 return;
5537 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5538 if (tevent_req_nomem(subreq, req)) {
5539 return;
5541 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5544 static void torture_createdel_closed(struct tevent_req *subreq)
5546 struct tevent_req *req = tevent_req_callback_data(
5547 subreq, struct tevent_req);
5548 NTSTATUS status;
5550 status = cli_close_recv(subreq);
5551 if (!NT_STATUS_IS_OK(status)) {
5552 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5553 tevent_req_nterror(req, status);
5554 return;
5556 tevent_req_done(req);
5559 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5561 return tevent_req_simple_recv_ntstatus(req);
5564 struct torture_createdels_state {
5565 struct tevent_context *ev;
5566 struct cli_state *cli;
5567 const char *base_name;
5568 int sent;
5569 int received;
5570 int num_files;
5571 struct tevent_req **reqs;
5574 static void torture_createdels_done(struct tevent_req *subreq);
5576 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5577 struct tevent_context *ev,
5578 struct cli_state *cli,
5579 const char *base_name,
5580 int num_parallel,
5581 int num_files)
5583 struct tevent_req *req;
5584 struct torture_createdels_state *state;
5585 int i;
5587 req = tevent_req_create(mem_ctx, &state,
5588 struct torture_createdels_state);
5589 if (req == NULL) {
5590 return NULL;
5592 state->ev = ev;
5593 state->cli = cli;
5594 state->base_name = talloc_strdup(state, base_name);
5595 if (tevent_req_nomem(state->base_name, req)) {
5596 return tevent_req_post(req, ev);
5598 state->num_files = MAX(num_parallel, num_files);
5599 state->sent = 0;
5600 state->received = 0;
5602 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5603 if (tevent_req_nomem(state->reqs, req)) {
5604 return tevent_req_post(req, ev);
5607 for (i=0; i<num_parallel; i++) {
5608 char *name;
5610 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5611 state->sent);
5612 if (tevent_req_nomem(name, req)) {
5613 return tevent_req_post(req, ev);
5615 state->reqs[i] = torture_createdel_send(
5616 state->reqs, state->ev, state->cli, name);
5617 if (tevent_req_nomem(state->reqs[i], req)) {
5618 return tevent_req_post(req, ev);
5620 name = talloc_move(state->reqs[i], &name);
5621 tevent_req_set_callback(state->reqs[i],
5622 torture_createdels_done, req);
5623 state->sent += 1;
5625 return req;
5628 static void torture_createdels_done(struct tevent_req *subreq)
5630 struct tevent_req *req = tevent_req_callback_data(
5631 subreq, struct tevent_req);
5632 struct torture_createdels_state *state = tevent_req_data(
5633 req, struct torture_createdels_state);
5634 size_t num_parallel = talloc_array_length(state->reqs);
5635 NTSTATUS status;
5636 char *name;
5637 int i;
5639 status = torture_createdel_recv(subreq);
5640 if (!NT_STATUS_IS_OK(status)){
5641 DEBUG(10, ("torture_createdel_recv returned %s\n",
5642 nt_errstr(status)));
5643 TALLOC_FREE(subreq);
5644 tevent_req_nterror(req, status);
5645 return;
5648 for (i=0; i<num_parallel; i++) {
5649 if (subreq == state->reqs[i]) {
5650 break;
5653 if (i == num_parallel) {
5654 DEBUG(10, ("received something we did not send\n"));
5655 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5656 return;
5658 TALLOC_FREE(state->reqs[i]);
5660 if (state->sent >= state->num_files) {
5661 tevent_req_done(req);
5662 return;
5665 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5666 state->sent);
5667 if (tevent_req_nomem(name, req)) {
5668 return;
5670 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5671 state->cli, name);
5672 if (tevent_req_nomem(state->reqs[i], req)) {
5673 return;
5675 name = talloc_move(state->reqs[i], &name);
5676 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5677 state->sent += 1;
5680 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5682 return tevent_req_simple_recv_ntstatus(req);
5685 struct swallow_notify_state {
5686 struct tevent_context *ev;
5687 struct cli_state *cli;
5688 uint16_t fnum;
5689 uint32_t completion_filter;
5690 bool recursive;
5691 bool (*fn)(uint32_t action, const char *name, void *priv);
5692 void *priv;
5695 static void swallow_notify_done(struct tevent_req *subreq);
5697 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5698 struct tevent_context *ev,
5699 struct cli_state *cli,
5700 uint16_t fnum,
5701 uint32_t completion_filter,
5702 bool recursive,
5703 bool (*fn)(uint32_t action,
5704 const char *name,
5705 void *priv),
5706 void *priv)
5708 struct tevent_req *req, *subreq;
5709 struct swallow_notify_state *state;
5711 req = tevent_req_create(mem_ctx, &state,
5712 struct swallow_notify_state);
5713 if (req == NULL) {
5714 return NULL;
5716 state->ev = ev;
5717 state->cli = cli;
5718 state->fnum = fnum;
5719 state->completion_filter = completion_filter;
5720 state->recursive = recursive;
5721 state->fn = fn;
5722 state->priv = priv;
5724 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5725 0xffff, state->completion_filter,
5726 state->recursive);
5727 if (tevent_req_nomem(subreq, req)) {
5728 return tevent_req_post(req, ev);
5730 tevent_req_set_callback(subreq, swallow_notify_done, req);
5731 return req;
5734 static void swallow_notify_done(struct tevent_req *subreq)
5736 struct tevent_req *req = tevent_req_callback_data(
5737 subreq, struct tevent_req);
5738 struct swallow_notify_state *state = tevent_req_data(
5739 req, struct swallow_notify_state);
5740 NTSTATUS status;
5741 uint32_t i, num_changes;
5742 struct notify_change *changes;
5744 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5745 TALLOC_FREE(subreq);
5746 if (!NT_STATUS_IS_OK(status)) {
5747 DEBUG(10, ("cli_notify_recv returned %s\n",
5748 nt_errstr(status)));
5749 tevent_req_nterror(req, status);
5750 return;
5753 for (i=0; i<num_changes; i++) {
5754 state->fn(changes[i].action, changes[i].name, state->priv);
5756 TALLOC_FREE(changes);
5758 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5759 0xffff, state->completion_filter,
5760 state->recursive);
5761 if (tevent_req_nomem(subreq, req)) {
5762 return;
5764 tevent_req_set_callback(subreq, swallow_notify_done, req);
5767 static bool print_notifies(uint32_t action, const char *name, void *priv)
5769 if (DEBUGLEVEL > 5) {
5770 d_printf("%d %s\n", (int)action, name);
5772 return true;
5775 static void notify_bench_done(struct tevent_req *req)
5777 int *num_finished = (int *)tevent_req_callback_data_void(req);
5778 *num_finished += 1;
5781 static bool run_notify_bench(int dummy)
5783 const char *dname = "\\notify-bench";
5784 struct tevent_context *ev;
5785 NTSTATUS status;
5786 uint16_t dnum;
5787 struct tevent_req *req1, *req2;
5788 int i, num_unc_names;
5789 int num_finished = 0;
5791 printf("starting notify-bench test\n");
5793 if (use_multishare_conn) {
5794 char **unc_list;
5795 unc_list = file_lines_load(multishare_conn_fname,
5796 &num_unc_names, 0, NULL);
5797 if (!unc_list || num_unc_names <= 0) {
5798 d_printf("Failed to load unc names list from '%s'\n",
5799 multishare_conn_fname);
5800 return false;
5802 TALLOC_FREE(unc_list);
5803 } else {
5804 num_unc_names = 1;
5807 ev = tevent_context_init(talloc_tos());
5808 if (ev == NULL) {
5809 d_printf("tevent_context_init failed\n");
5810 return false;
5813 for (i=0; i<num_unc_names; i++) {
5814 struct cli_state *cli;
5815 char *base_fname;
5817 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5818 dname, i);
5819 if (base_fname == NULL) {
5820 return false;
5823 if (!torture_open_connection(&cli, i)) {
5824 return false;
5827 status = cli_ntcreate(cli, dname, 0,
5828 MAXIMUM_ALLOWED_ACCESS,
5829 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5830 FILE_SHARE_DELETE,
5831 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5832 &dnum);
5834 if (!NT_STATUS_IS_OK(status)) {
5835 d_printf("Could not create %s: %s\n", dname,
5836 nt_errstr(status));
5837 return false;
5840 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5841 FILE_NOTIFY_CHANGE_FILE_NAME |
5842 FILE_NOTIFY_CHANGE_DIR_NAME |
5843 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5844 FILE_NOTIFY_CHANGE_LAST_WRITE,
5845 false, print_notifies, NULL);
5846 if (req1 == NULL) {
5847 d_printf("Could not create notify request\n");
5848 return false;
5851 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5852 base_fname, 10, torture_numops);
5853 if (req2 == NULL) {
5854 d_printf("Could not create createdels request\n");
5855 return false;
5857 TALLOC_FREE(base_fname);
5859 tevent_req_set_callback(req2, notify_bench_done,
5860 &num_finished);
5863 while (num_finished < num_unc_names) {
5864 int ret;
5865 ret = tevent_loop_once(ev);
5866 if (ret != 0) {
5867 d_printf("tevent_loop_once failed\n");
5868 return false;
5872 if (!tevent_req_poll(req2, ev)) {
5873 d_printf("tevent_req_poll failed\n");
5876 status = torture_createdels_recv(req2);
5877 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5879 return true;
5882 static bool run_mangle1(int dummy)
5884 struct cli_state *cli;
5885 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5886 uint16_t fnum;
5887 fstring alt_name;
5888 NTSTATUS status;
5889 time_t change_time, access_time, write_time;
5890 SMB_OFF_T size;
5891 uint16_t mode;
5893 printf("starting mangle1 test\n");
5894 if (!torture_open_connection(&cli, 0)) {
5895 return False;
5898 cli_sockopt(cli, sockops);
5900 if (!NT_STATUS_IS_OK(cli_ntcreate(
5901 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5902 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5903 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5904 return false;
5906 cli_close(cli, fnum);
5908 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5909 if (!NT_STATUS_IS_OK(status)) {
5910 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5911 nt_errstr(status));
5912 return false;
5914 d_printf("alt_name: %s\n", alt_name);
5916 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5917 d_printf("cli_open(%s) failed: %s\n", alt_name,
5918 cli_errstr(cli));
5919 return false;
5921 cli_close(cli, fnum);
5923 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5924 &write_time, &size, &mode)) {
5925 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5926 cli_errstr(cli));
5927 return false;
5930 return true;
5933 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5935 size_t *to_pull = (size_t *)priv;
5936 size_t thistime = *to_pull;
5938 thistime = MIN(thistime, n);
5939 if (thistime == 0) {
5940 return 0;
5943 memset(buf, 0, thistime);
5944 *to_pull -= thistime;
5945 return thistime;
5948 static bool run_windows_write(int dummy)
5950 struct cli_state *cli1;
5951 uint16_t fnum;
5952 int i;
5953 bool ret = false;
5954 const char *fname = "\\writetest.txt";
5955 struct timeval start;
5956 double seconds;
5957 double kbytes;
5959 printf("starting windows_write test\n");
5960 if (!torture_open_connection(&cli1, 0)) {
5961 return False;
5964 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5965 printf("open failed (%s)\n", cli_errstr(cli1));
5966 return False;
5969 cli_sockopt(cli1, sockops);
5971 start = timeval_current();
5973 for (i=0; i<torture_numops; i++) {
5974 char c = 0;
5975 off_t start = i * torture_blocksize;
5976 NTSTATUS status;
5977 size_t to_pull = torture_blocksize - 1;
5979 if (cli_write(cli1, fnum, 0, &c,
5980 start + torture_blocksize - 1, 1) != 1) {
5981 printf("cli_write failed: %s\n", cli_errstr(cli1));
5982 goto fail;
5985 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5986 null_source, &to_pull);
5987 if (!NT_STATUS_IS_OK(status)) {
5988 printf("cli_push returned: %s\n", nt_errstr(status));
5989 goto fail;
5993 seconds = timeval_elapsed(&start);
5994 kbytes = (double)torture_blocksize * torture_numops;
5995 kbytes /= 1024;
5997 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5998 (double)seconds, (int)(kbytes/seconds));
6000 ret = true;
6001 fail:
6002 cli_close(cli1, fnum);
6003 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6004 torture_close_connection(cli1);
6005 return ret;
6008 static bool run_cli_echo(int dummy)
6010 struct cli_state *cli;
6011 NTSTATUS status;
6013 printf("starting cli_echo test\n");
6014 if (!torture_open_connection(&cli, 0)) {
6015 return false;
6017 cli_sockopt(cli, sockops);
6019 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6021 d_printf("cli_echo returned %s\n", nt_errstr(status));
6023 torture_close_connection(cli);
6024 return NT_STATUS_IS_OK(status);
6027 static bool run_uid_regression_test(int dummy)
6029 static struct cli_state *cli;
6030 int16_t old_vuid;
6031 int16_t old_cnum;
6032 bool correct = True;
6034 printf("starting uid regression test\n");
6036 if (!torture_open_connection(&cli, 0)) {
6037 return False;
6040 cli_sockopt(cli, sockops);
6042 /* Ok - now save then logoff our current user. */
6043 old_vuid = cli->vuid;
6045 if (!cli_ulogoff(cli)) {
6046 d_printf("(%s) cli_ulogoff failed: %s\n",
6047 __location__, cli_errstr(cli));
6048 correct = false;
6049 goto out;
6052 cli->vuid = old_vuid;
6054 /* Try an operation. */
6055 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6056 /* We expect bad uid. */
6057 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6058 NT_STATUS_NO_SUCH_USER)) {
6059 return False;
6063 old_cnum = cli->cnum;
6065 /* Now try a SMBtdis with the invald vuid set to zero. */
6066 cli->vuid = 0;
6068 /* This should succeed. */
6069 if (cli_tdis(cli)) {
6070 printf("First tdis with invalid vuid should succeed.\n");
6071 } else {
6072 printf("First tdis failed (%s)\n", cli_errstr(cli));
6075 cli->vuid = old_vuid;
6076 cli->cnum = old_cnum;
6078 /* This should fail. */
6079 if (cli_tdis(cli)) {
6080 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6081 } else {
6082 /* Should be bad tid. */
6083 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6084 NT_STATUS_NETWORK_NAME_DELETED)) {
6085 return False;
6089 cli_rmdir(cli, "\\uid_reg_test");
6091 out:
6093 cli_shutdown(cli);
6094 return correct;
6098 static const char *illegal_chars = "*\\/?<>|\":";
6099 static char force_shortname_chars[] = " +,.[];=\177";
6101 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
6103 struct cli_state *pcli = (struct cli_state *)state;
6104 fstring fname;
6105 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6107 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6108 return;
6110 if (finfo->mode & aDIR) {
6111 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6112 printf("del_fn: failed to rmdir %s\n,", fname );
6113 } else {
6114 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6115 printf("del_fn: failed to unlink %s\n,", fname );
6119 struct sn_state {
6120 int i;
6121 bool val;
6124 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
6126 struct sn_state *s = (struct sn_state *)state;
6127 int i = s->i;
6129 #if 0
6130 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6131 i, finfo->name, finfo->short_name);
6132 #endif
6134 if (strchr(force_shortname_chars, i)) {
6135 if (!finfo->short_name[0]) {
6136 /* Shortname not created when it should be. */
6137 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6138 __location__, finfo->name, i);
6139 s->val = true;
6141 } else if (finfo->short_name[0]){
6142 /* Shortname created when it should not be. */
6143 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6144 __location__, finfo->short_name, finfo->name);
6145 s->val = true;
6149 static bool run_shortname_test(int dummy)
6151 static struct cli_state *cli;
6152 bool correct = True;
6153 int i;
6154 struct sn_state s;
6155 char fname[20];
6157 printf("starting shortname test\n");
6159 if (!torture_open_connection(&cli, 0)) {
6160 return False;
6163 cli_sockopt(cli, sockops);
6165 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6166 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6167 cli_rmdir(cli, "\\shortname");
6169 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6170 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6171 __location__, cli_errstr(cli));
6172 correct = false;
6173 goto out;
6176 strlcpy(fname, "\\shortname\\", sizeof(fname));
6177 strlcat(fname, "test .txt", sizeof(fname));
6179 s.val = false;
6181 for (i = 32; i < 128; i++) {
6182 NTSTATUS status;
6183 uint16_t fnum = (uint16_t)-1;
6185 s.i = i;
6187 if (strchr(illegal_chars, i)) {
6188 continue;
6190 fname[15] = i;
6192 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6193 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6194 if (!NT_STATUS_IS_OK(status)) {
6195 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6196 __location__, fname, cli_errstr(cli));
6197 correct = false;
6198 goto out;
6200 cli_close(cli, fnum);
6201 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
6202 d_printf("(%s) failed to list %s: %s\n",
6203 __location__, fname, cli_errstr(cli));
6204 correct = false;
6205 goto out;
6207 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6208 d_printf("(%s) failed to delete %s: %s\n",
6209 __location__, fname, cli_errstr(cli));
6210 correct = false;
6211 goto out;
6214 if (s.val) {
6215 correct = false;
6216 goto out;
6220 out:
6222 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6223 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6224 cli_rmdir(cli, "\\shortname");
6225 torture_close_connection(cli);
6226 return correct;
6229 static void pagedsearch_cb(struct tevent_req *req)
6231 int rc;
6232 struct tldap_message *msg;
6233 char *dn;
6235 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6236 if (rc != TLDAP_SUCCESS) {
6237 d_printf("tldap_search_paged_recv failed: %s\n",
6238 tldap_err2string(rc));
6239 return;
6241 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6242 TALLOC_FREE(msg);
6243 return;
6245 if (!tldap_entry_dn(msg, &dn)) {
6246 d_printf("tldap_entry_dn failed\n");
6247 return;
6249 d_printf("%s\n", dn);
6250 TALLOC_FREE(msg);
6253 static bool run_tldap(int dummy)
6255 struct tldap_context *ld;
6256 int fd, rc;
6257 NTSTATUS status;
6258 struct sockaddr_storage addr;
6259 struct tevent_context *ev;
6260 struct tevent_req *req;
6261 char *basedn;
6263 if (!resolve_name(host, &addr, 0, false)) {
6264 d_printf("could not find host %s\n", host);
6265 return false;
6267 status = open_socket_out(&addr, 389, 9999, &fd);
6268 if (!NT_STATUS_IS_OK(status)) {
6269 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6270 return false;
6273 ld = tldap_context_create(talloc_tos(), fd);
6274 if (ld == NULL) {
6275 close(fd);
6276 d_printf("tldap_context_create failed\n");
6277 return false;
6280 rc = tldap_fetch_rootdse(ld);
6281 if (rc != TLDAP_SUCCESS) {
6282 d_printf("tldap_fetch_rootdse failed: %s\n",
6283 tldap_errstr(talloc_tos(), ld, rc));
6284 return false;
6287 basedn = tldap_talloc_single_attribute(
6288 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6289 if (basedn == NULL) {
6290 d_printf("no defaultNamingContext\n");
6291 return false;
6293 d_printf("defaultNamingContext: %s\n", basedn);
6295 ev = tevent_context_init(talloc_tos());
6296 if (ev == NULL) {
6297 d_printf("tevent_context_init failed\n");
6298 return false;
6301 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6302 TLDAP_SCOPE_SUB, "(objectclass=*)",
6303 NULL, 0, 0,
6304 NULL, 0, NULL, 0, 0, 0, 0, 5);
6305 if (req == NULL) {
6306 d_printf("tldap_search_paged_send failed\n");
6307 return false;
6309 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6311 tevent_req_poll(req, ev);
6313 TALLOC_FREE(req);
6315 TALLOC_FREE(ld);
6316 return true;
6319 static bool run_streamerror(int dummy)
6321 struct cli_state *cli;
6322 const char *dname = "\\testdir";
6323 const char *streamname =
6324 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6325 NTSTATUS status;
6326 time_t change_time, access_time, write_time;
6327 SMB_OFF_T size;
6328 uint16_t mode, fnum;
6329 bool ret = true;
6331 if (!torture_open_connection(&cli, 0)) {
6332 return false;
6335 cli_rmdir(cli, dname);
6337 status = cli_mkdir(cli, dname);
6338 if (!NT_STATUS_IS_OK(status)) {
6339 printf("mkdir failed: %s\n", nt_errstr(status));
6340 return false;
6343 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
6344 &size, &mode);
6345 status = cli_nt_error(cli);
6347 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6348 printf("pathinfo returned %s, expected "
6349 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6350 nt_errstr(status));
6351 ret = false;
6354 status = cli_ntcreate(cli, streamname, 0x16,
6355 FILE_READ_DATA|FILE_READ_EA|
6356 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6357 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6358 FILE_OPEN, 0, 0, &fnum);
6360 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6361 printf("ntcreate returned %s, expected "
6362 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6363 nt_errstr(status));
6364 ret = false;
6368 cli_rmdir(cli, dname);
6369 return ret;
6372 static bool run_local_substitute(int dummy)
6374 bool ok = true;
6376 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6377 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6378 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6379 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6380 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6381 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6382 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6383 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6385 /* Different captialization rules in sub_basic... */
6387 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6388 "blaDOM") == 0);
6390 return ok;
6393 static bool run_local_base64(int dummy)
6395 int i;
6396 bool ret = true;
6398 for (i=1; i<2000; i++) {
6399 DATA_BLOB blob1, blob2;
6400 char *b64;
6402 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6403 blob1.length = i;
6404 generate_random_buffer(blob1.data, blob1.length);
6406 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6407 if (b64 == NULL) {
6408 d_fprintf(stderr, "base64_encode_data_blob failed "
6409 "for %d bytes\n", i);
6410 ret = false;
6412 blob2 = base64_decode_data_blob(b64);
6413 TALLOC_FREE(b64);
6415 if (data_blob_cmp(&blob1, &blob2)) {
6416 d_fprintf(stderr, "data_blob_cmp failed for %d "
6417 "bytes\n", i);
6418 ret = false;
6420 TALLOC_FREE(blob1.data);
6421 data_blob_free(&blob2);
6423 return ret;
6426 static bool run_local_gencache(int dummy)
6428 char *val;
6429 time_t tm;
6430 DATA_BLOB blob;
6432 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6433 d_printf("%s: gencache_set() failed\n", __location__);
6434 return False;
6437 if (!gencache_get("foo", NULL, NULL)) {
6438 d_printf("%s: gencache_get() failed\n", __location__);
6439 return False;
6442 if (!gencache_get("foo", &val, &tm)) {
6443 d_printf("%s: gencache_get() failed\n", __location__);
6444 return False;
6447 if (strcmp(val, "bar") != 0) {
6448 d_printf("%s: gencache_get() returned %s, expected %s\n",
6449 __location__, val, "bar");
6450 SAFE_FREE(val);
6451 return False;
6454 SAFE_FREE(val);
6456 if (!gencache_del("foo")) {
6457 d_printf("%s: gencache_del() failed\n", __location__);
6458 return False;
6460 if (gencache_del("foo")) {
6461 d_printf("%s: second gencache_del() succeeded\n",
6462 __location__);
6463 return False;
6466 if (gencache_get("foo", &val, &tm)) {
6467 d_printf("%s: gencache_get() on deleted entry "
6468 "succeeded\n", __location__);
6469 return False;
6472 blob = data_blob_string_const_null("bar");
6473 tm = time(NULL) + 60;
6475 if (!gencache_set_data_blob("foo", &blob, tm)) {
6476 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6477 return False;
6480 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6481 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6482 return False;
6485 if (strcmp((const char *)blob.data, "bar") != 0) {
6486 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6487 __location__, (const char *)blob.data, "bar");
6488 data_blob_free(&blob);
6489 return False;
6492 data_blob_free(&blob);
6494 if (!gencache_del("foo")) {
6495 d_printf("%s: gencache_del() failed\n", __location__);
6496 return False;
6498 if (gencache_del("foo")) {
6499 d_printf("%s: second gencache_del() succeeded\n",
6500 __location__);
6501 return False;
6504 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6505 d_printf("%s: gencache_get_data_blob() on deleted entry "
6506 "succeeded\n", __location__);
6507 return False;
6510 return True;
6513 static bool rbt_testval(struct db_context *db, const char *key,
6514 const char *value)
6516 struct db_record *rec;
6517 TDB_DATA data = string_tdb_data(value);
6518 bool ret = false;
6519 NTSTATUS status;
6521 rec = db->fetch_locked(db, db, string_tdb_data(key));
6522 if (rec == NULL) {
6523 d_fprintf(stderr, "fetch_locked failed\n");
6524 goto done;
6526 status = rec->store(rec, data, 0);
6527 if (!NT_STATUS_IS_OK(status)) {
6528 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6529 goto done;
6531 TALLOC_FREE(rec);
6533 rec = db->fetch_locked(db, db, string_tdb_data(key));
6534 if (rec == NULL) {
6535 d_fprintf(stderr, "second fetch_locked failed\n");
6536 goto done;
6538 if ((rec->value.dsize != data.dsize)
6539 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6540 d_fprintf(stderr, "Got wrong data back\n");
6541 goto done;
6544 ret = true;
6545 done:
6546 TALLOC_FREE(rec);
6547 return ret;
6550 static bool run_local_rbtree(int dummy)
6552 struct db_context *db;
6553 bool ret = false;
6554 int i;
6556 db = db_open_rbt(NULL);
6558 if (db == NULL) {
6559 d_fprintf(stderr, "db_open_rbt failed\n");
6560 return false;
6563 for (i=0; i<1000; i++) {
6564 char *key, *value;
6566 if (asprintf(&key, "key%ld", random()) == -1) {
6567 goto done;
6569 if (asprintf(&value, "value%ld", random()) == -1) {
6570 SAFE_FREE(key);
6571 goto done;
6574 if (!rbt_testval(db, key, value)) {
6575 SAFE_FREE(key);
6576 SAFE_FREE(value);
6577 goto done;
6580 SAFE_FREE(value);
6581 if (asprintf(&value, "value%ld", random()) == -1) {
6582 SAFE_FREE(key);
6583 goto done;
6586 if (!rbt_testval(db, key, value)) {
6587 SAFE_FREE(key);
6588 SAFE_FREE(value);
6589 goto done;
6592 SAFE_FREE(key);
6593 SAFE_FREE(value);
6596 ret = true;
6598 done:
6599 TALLOC_FREE(db);
6600 return ret;
6603 struct talloc_dict_test {
6604 int content;
6607 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6609 int *count = (int *)priv;
6610 *count += 1;
6611 return 0;
6614 static bool run_local_talloc_dict(int dummy)
6616 struct talloc_dict *dict;
6617 struct talloc_dict_test *t;
6618 int key, count;
6620 dict = talloc_dict_init(talloc_tos());
6621 if (dict == NULL) {
6622 return false;
6625 t = talloc(talloc_tos(), struct talloc_dict_test);
6626 if (t == NULL) {
6627 return false;
6630 key = 1;
6631 t->content = 1;
6632 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6633 return false;
6636 count = 0;
6637 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6638 return false;
6641 if (count != 1) {
6642 return false;
6645 TALLOC_FREE(dict);
6647 return true;
6650 /* Split a path name into filename and stream name components. Canonicalise
6651 * such that an implicit $DATA token is always explicit.
6653 * The "specification" of this function can be found in the
6654 * run_local_stream_name() function in torture.c, I've tried those
6655 * combinations against a W2k3 server.
6658 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6659 char **pbase, char **pstream)
6661 char *base = NULL;
6662 char *stream = NULL;
6663 char *sname; /* stream name */
6664 const char *stype; /* stream type */
6666 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6668 sname = strchr_m(fname, ':');
6670 if (lp_posix_pathnames() || (sname == NULL)) {
6671 if (pbase != NULL) {
6672 base = talloc_strdup(mem_ctx, fname);
6673 NT_STATUS_HAVE_NO_MEMORY(base);
6675 goto done;
6678 if (pbase != NULL) {
6679 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6680 NT_STATUS_HAVE_NO_MEMORY(base);
6683 sname += 1;
6685 stype = strchr_m(sname, ':');
6687 if (stype == NULL) {
6688 sname = talloc_strdup(mem_ctx, sname);
6689 stype = "$DATA";
6691 else {
6692 if (StrCaseCmp(stype, ":$DATA") != 0) {
6694 * If there is an explicit stream type, so far we only
6695 * allow $DATA. Is there anything else allowed? -- vl
6697 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6698 TALLOC_FREE(base);
6699 return NT_STATUS_OBJECT_NAME_INVALID;
6701 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6702 stype += 1;
6705 if (sname == NULL) {
6706 TALLOC_FREE(base);
6707 return NT_STATUS_NO_MEMORY;
6710 if (sname[0] == '\0') {
6712 * no stream name, so no stream
6714 goto done;
6717 if (pstream != NULL) {
6718 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6719 if (stream == NULL) {
6720 TALLOC_FREE(sname);
6721 TALLOC_FREE(base);
6722 return NT_STATUS_NO_MEMORY;
6725 * upper-case the type field
6727 strupper_m(strchr_m(stream, ':')+1);
6730 done:
6731 if (pbase != NULL) {
6732 *pbase = base;
6734 if (pstream != NULL) {
6735 *pstream = stream;
6737 return NT_STATUS_OK;
6740 static bool test_stream_name(const char *fname, const char *expected_base,
6741 const char *expected_stream,
6742 NTSTATUS expected_status)
6744 NTSTATUS status;
6745 char *base = NULL;
6746 char *stream = NULL;
6748 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6749 if (!NT_STATUS_EQUAL(status, expected_status)) {
6750 goto error;
6753 if (!NT_STATUS_IS_OK(status)) {
6754 return true;
6757 if (base == NULL) goto error;
6759 if (strcmp(expected_base, base) != 0) goto error;
6761 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6762 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6764 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6765 goto error;
6767 TALLOC_FREE(base);
6768 TALLOC_FREE(stream);
6769 return true;
6771 error:
6772 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6773 fname, expected_base ? expected_base : "<NULL>",
6774 expected_stream ? expected_stream : "<NULL>",
6775 nt_errstr(expected_status));
6776 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6777 base ? base : "<NULL>", stream ? stream : "<NULL>",
6778 nt_errstr(status));
6779 TALLOC_FREE(base);
6780 TALLOC_FREE(stream);
6781 return false;
6784 static bool run_local_stream_name(int dummy)
6786 bool ret = true;
6788 ret &= test_stream_name(
6789 "bla", "bla", NULL, NT_STATUS_OK);
6790 ret &= test_stream_name(
6791 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6792 ret &= test_stream_name(
6793 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6794 ret &= test_stream_name(
6795 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6796 ret &= test_stream_name(
6797 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6798 ret &= test_stream_name(
6799 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6800 ret &= test_stream_name(
6801 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6802 ret &= test_stream_name(
6803 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6805 return ret;
6808 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6810 if (a.length != b.length) {
6811 printf("a.length=%d != b.length=%d\n",
6812 (int)a.length, (int)b.length);
6813 return false;
6815 if (memcmp(a.data, b.data, a.length) != 0) {
6816 printf("a.data and b.data differ\n");
6817 return false;
6819 return true;
6822 static bool run_local_memcache(int dummy)
6824 struct memcache *cache;
6825 DATA_BLOB k1, k2;
6826 DATA_BLOB d1, d2, d3;
6827 DATA_BLOB v1, v2, v3;
6829 TALLOC_CTX *mem_ctx;
6830 char *str1, *str2;
6831 size_t size1, size2;
6832 bool ret = false;
6834 cache = memcache_init(NULL, 100);
6836 if (cache == NULL) {
6837 printf("memcache_init failed\n");
6838 return false;
6841 d1 = data_blob_const("d1", 2);
6842 d2 = data_blob_const("d2", 2);
6843 d3 = data_blob_const("d3", 2);
6845 k1 = data_blob_const("d1", 2);
6846 k2 = data_blob_const("d2", 2);
6848 memcache_add(cache, STAT_CACHE, k1, d1);
6849 memcache_add(cache, GETWD_CACHE, k2, d2);
6851 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6852 printf("could not find k1\n");
6853 return false;
6855 if (!data_blob_equal(d1, v1)) {
6856 return false;
6859 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6860 printf("could not find k2\n");
6861 return false;
6863 if (!data_blob_equal(d2, v2)) {
6864 return false;
6867 memcache_add(cache, STAT_CACHE, k1, d3);
6869 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
6870 printf("could not find replaced k1\n");
6871 return false;
6873 if (!data_blob_equal(d3, v3)) {
6874 return false;
6877 memcache_add(cache, GETWD_CACHE, k1, d1);
6879 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6880 printf("Did find k2, should have been purged\n");
6881 return false;
6884 TALLOC_FREE(cache);
6886 cache = memcache_init(NULL, 0);
6888 mem_ctx = talloc_init("foo");
6890 str1 = talloc_strdup(mem_ctx, "string1");
6891 str2 = talloc_strdup(mem_ctx, "string2");
6893 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6894 data_blob_string_const("torture"), &str1);
6895 size1 = talloc_total_size(cache);
6897 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6898 data_blob_string_const("torture"), &str2);
6899 size2 = talloc_total_size(cache);
6901 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
6903 if (size2 > size1) {
6904 printf("memcache leaks memory!\n");
6905 goto fail;
6908 ret = true;
6909 fail:
6910 TALLOC_FREE(cache);
6911 return ret;
6914 static void wbclient_done(struct tevent_req *req)
6916 wbcErr wbc_err;
6917 struct winbindd_response *wb_resp;
6918 int *i = (int *)tevent_req_callback_data_void(req);
6920 wbc_err = wb_trans_recv(req, req, &wb_resp);
6921 TALLOC_FREE(req);
6922 *i += 1;
6923 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
6926 static bool run_local_wbclient(int dummy)
6928 struct event_context *ev;
6929 struct wb_context **wb_ctx;
6930 struct winbindd_request wb_req;
6931 bool result = false;
6932 int i, j;
6934 BlockSignals(True, SIGPIPE);
6936 ev = tevent_context_init_byname(talloc_tos(), "epoll");
6937 if (ev == NULL) {
6938 goto fail;
6941 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
6942 if (wb_ctx == NULL) {
6943 goto fail;
6946 ZERO_STRUCT(wb_req);
6947 wb_req.cmd = WINBINDD_PING;
6949 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
6951 for (i=0; i<nprocs; i++) {
6952 wb_ctx[i] = wb_context_init(ev, NULL);
6953 if (wb_ctx[i] == NULL) {
6954 goto fail;
6956 for (j=0; j<torture_numops; j++) {
6957 struct tevent_req *req;
6958 req = wb_trans_send(ev, ev, wb_ctx[i],
6959 (j % 2) == 0, &wb_req);
6960 if (req == NULL) {
6961 goto fail;
6963 tevent_req_set_callback(req, wbclient_done, &i);
6967 i = 0;
6969 while (i < nprocs * torture_numops) {
6970 event_loop_once(ev);
6973 result = true;
6974 fail:
6975 TALLOC_FREE(ev);
6976 return result;
6979 static void getaddrinfo_finished(struct tevent_req *req)
6981 char *name = (char *)tevent_req_callback_data_void(req);
6982 struct addrinfo *ainfo;
6983 int res;
6985 res = getaddrinfo_recv(req, &ainfo);
6986 if (res != 0) {
6987 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
6988 return;
6990 d_printf("gai(%s) succeeded\n", name);
6991 freeaddrinfo(ainfo);
6994 static bool run_getaddrinfo_send(int dummy)
6996 TALLOC_CTX *frame = talloc_stackframe();
6997 struct fncall_context *ctx;
6998 struct tevent_context *ev;
6999 bool result = false;
7000 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7001 "www.slashdot.org", "heise.de" };
7002 struct tevent_req *reqs[4];
7003 int i;
7005 ev = event_context_init(frame);
7006 if (ev == NULL) {
7007 goto fail;
7010 ctx = fncall_context_init(frame, 4);
7012 for (i=0; i<ARRAY_SIZE(names); i++) {
7013 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7014 NULL);
7015 if (reqs[i] == NULL) {
7016 goto fail;
7018 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7019 (void *)names[i]);
7022 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7023 tevent_loop_once(ev);
7026 result = true;
7027 fail:
7028 TALLOC_FREE(frame);
7029 return result;
7033 static double create_procs(bool (*fn)(int), bool *result)
7035 int i, status;
7036 volatile pid_t *child_status;
7037 volatile bool *child_status_out;
7038 int synccount;
7039 int tries = 8;
7040 struct timeval start;
7042 synccount = 0;
7044 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7045 if (!child_status) {
7046 printf("Failed to setup shared memory\n");
7047 return -1;
7050 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7051 if (!child_status_out) {
7052 printf("Failed to setup result status shared memory\n");
7053 return -1;
7056 for (i = 0; i < nprocs; i++) {
7057 child_status[i] = 0;
7058 child_status_out[i] = True;
7061 start = timeval_current();
7063 for (i=0;i<nprocs;i++) {
7064 procnum = i;
7065 if (fork() == 0) {
7066 pid_t mypid = getpid();
7067 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7069 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7071 while (1) {
7072 if (torture_open_connection(&current_cli, i)) break;
7073 if (tries-- == 0) {
7074 printf("pid %d failed to start\n", (int)getpid());
7075 _exit(1);
7077 smb_msleep(10);
7080 child_status[i] = getpid();
7082 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7084 child_status_out[i] = fn(i);
7085 _exit(0);
7089 do {
7090 synccount = 0;
7091 for (i=0;i<nprocs;i++) {
7092 if (child_status[i]) synccount++;
7094 if (synccount == nprocs) break;
7095 smb_msleep(10);
7096 } while (timeval_elapsed(&start) < 30);
7098 if (synccount != nprocs) {
7099 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7100 *result = False;
7101 return timeval_elapsed(&start);
7104 /* start the client load */
7105 start = timeval_current();
7107 for (i=0;i<nprocs;i++) {
7108 child_status[i] = 0;
7111 printf("%d clients started\n", nprocs);
7113 for (i=0;i<nprocs;i++) {
7114 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7117 printf("\n");
7119 for (i=0;i<nprocs;i++) {
7120 if (!child_status_out[i]) {
7121 *result = False;
7124 return timeval_elapsed(&start);
7127 #define FLAG_MULTIPROC 1
7129 static struct {
7130 const char *name;
7131 bool (*fn)(int);
7132 unsigned flags;
7133 } torture_ops[] = {
7134 {"FDPASS", run_fdpasstest, 0},
7135 {"LOCK1", run_locktest1, 0},
7136 {"LOCK2", run_locktest2, 0},
7137 {"LOCK3", run_locktest3, 0},
7138 {"LOCK4", run_locktest4, 0},
7139 {"LOCK5", run_locktest5, 0},
7140 {"LOCK6", run_locktest6, 0},
7141 {"LOCK7", run_locktest7, 0},
7142 {"LOCK8", run_locktest8, 0},
7143 {"LOCK9", run_locktest9, 0},
7144 {"UNLINK", run_unlinktest, 0},
7145 {"BROWSE", run_browsetest, 0},
7146 {"ATTR", run_attrtest, 0},
7147 {"TRANS2", run_trans2test, 0},
7148 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7149 {"TORTURE",run_torture, FLAG_MULTIPROC},
7150 {"RANDOMIPC", run_randomipc, 0},
7151 {"NEGNOWAIT", run_negprot_nowait, 0},
7152 {"NBENCH", run_nbench, 0},
7153 {"OPLOCK1", run_oplock1, 0},
7154 {"OPLOCK2", run_oplock2, 0},
7155 {"OPLOCK3", run_oplock3, 0},
7156 {"DIR", run_dirtest, 0},
7157 {"DIR1", run_dirtest1, 0},
7158 {"DENY1", torture_denytest1, 0},
7159 {"DENY2", torture_denytest2, 0},
7160 {"TCON", run_tcon_test, 0},
7161 {"TCONDEV", run_tcon_devtype_test, 0},
7162 {"RW1", run_readwritetest, 0},
7163 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7164 {"RW3", run_readwritelarge, 0},
7165 {"OPEN", run_opentest, 0},
7166 {"POSIX", run_simple_posix_open_test, 0},
7167 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7168 { "SHORTNAME-TEST", run_shortname_test, 0},
7169 #if 1
7170 {"OPENATTR", run_openattrtest, 0},
7171 #endif
7172 {"XCOPY", run_xcopy, 0},
7173 {"RENAME", run_rename, 0},
7174 {"DELETE", run_deletetest, 0},
7175 {"PROPERTIES", run_properties, 0},
7176 {"MANGLE", torture_mangle, 0},
7177 {"MANGLE1", run_mangle1, 0},
7178 {"W2K", run_w2ktest, 0},
7179 {"TRANS2SCAN", torture_trans2_scan, 0},
7180 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7181 {"UTABLE", torture_utable, 0},
7182 {"CASETABLE", torture_casetable, 0},
7183 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7184 {"PIPE_NUMBER", run_pipe_number, 0},
7185 {"TCON2", run_tcon2_test, 0},
7186 {"IOCTL", torture_ioctl_test, 0},
7187 {"CHKPATH", torture_chkpath_test, 0},
7188 {"FDSESS", run_fdsesstest, 0},
7189 { "EATEST", run_eatest, 0},
7190 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7191 { "CHAIN1", run_chain1, 0},
7192 { "CHAIN2", run_chain2, 0},
7193 { "WINDOWS-WRITE", run_windows_write, 0},
7194 { "CLI_ECHO", run_cli_echo, 0},
7195 { "GETADDRINFO", run_getaddrinfo_send, 0},
7196 { "TLDAP", run_tldap },
7197 { "STREAMERROR", run_streamerror },
7198 { "NOTIFY-BENCH", run_notify_bench },
7199 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7200 { "LOCAL-GENCACHE", run_local_gencache, 0},
7201 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7202 { "LOCAL-BASE64", run_local_base64, 0},
7203 { "LOCAL-RBTREE", run_local_rbtree, 0},
7204 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7205 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7206 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7207 {NULL, NULL, 0}};
7211 /****************************************************************************
7212 run a specified test or "ALL"
7213 ****************************************************************************/
7214 static bool run_test(const char *name)
7216 bool ret = True;
7217 bool result = True;
7218 bool found = False;
7219 int i;
7220 double t;
7221 if (strequal(name,"ALL")) {
7222 for (i=0;torture_ops[i].name;i++) {
7223 run_test(torture_ops[i].name);
7225 found = True;
7228 for (i=0;torture_ops[i].name;i++) {
7229 fstr_sprintf(randomfname, "\\XX%x",
7230 (unsigned)random());
7232 if (strequal(name, torture_ops[i].name)) {
7233 found = True;
7234 printf("Running %s\n", name);
7235 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7236 t = create_procs(torture_ops[i].fn, &result);
7237 if (!result) {
7238 ret = False;
7239 printf("TEST %s FAILED!\n", name);
7241 } else {
7242 struct timeval start;
7243 start = timeval_current();
7244 if (!torture_ops[i].fn(0)) {
7245 ret = False;
7246 printf("TEST %s FAILED!\n", name);
7248 t = timeval_elapsed(&start);
7250 printf("%s took %g secs\n\n", name, t);
7254 if (!found) {
7255 printf("Did not find a test named %s\n", name);
7256 ret = False;
7259 return ret;
7263 static void usage(void)
7265 int i;
7267 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7268 printf("Please use samba4 torture.\n\n");
7270 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7272 printf("\t-d debuglevel\n");
7273 printf("\t-U user%%pass\n");
7274 printf("\t-k use kerberos\n");
7275 printf("\t-N numprocs\n");
7276 printf("\t-n my_netbios_name\n");
7277 printf("\t-W workgroup\n");
7278 printf("\t-o num_operations\n");
7279 printf("\t-O socket_options\n");
7280 printf("\t-m maximum protocol\n");
7281 printf("\t-L use oplocks\n");
7282 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7283 printf("\t-A showall\n");
7284 printf("\t-p port\n");
7285 printf("\t-s seed\n");
7286 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7287 printf("\n\n");
7289 printf("tests are:");
7290 for (i=0;torture_ops[i].name;i++) {
7291 printf(" %s", torture_ops[i].name);
7293 printf("\n");
7295 printf("default test is ALL\n");
7297 exit(1);
7300 /****************************************************************************
7301 main program
7302 ****************************************************************************/
7303 int main(int argc,char *argv[])
7305 int opt, i;
7306 char *p;
7307 int gotuser = 0;
7308 int gotpass = 0;
7309 bool correct = True;
7310 TALLOC_CTX *frame = talloc_stackframe();
7311 int seed = time(NULL);
7313 dbf = x_stdout;
7315 #ifdef HAVE_SETBUFFER
7316 setbuffer(stdout, NULL, 0);
7317 #endif
7319 load_case_tables();
7321 if (is_default_dyn_CONFIGFILE()) {
7322 if(getenv("SMB_CONF_PATH")) {
7323 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7326 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7327 load_interfaces();
7329 if (argc < 2) {
7330 usage();
7333 for(p = argv[1]; *p; p++)
7334 if(*p == '\\')
7335 *p = '/';
7337 if (strncmp(argv[1], "//", 2)) {
7338 usage();
7341 fstrcpy(host, &argv[1][2]);
7342 p = strchr_m(&host[2],'/');
7343 if (!p) {
7344 usage();
7346 *p = 0;
7347 fstrcpy(share, p+1);
7349 fstrcpy(myname, get_myname(talloc_tos()));
7350 if (!*myname) {
7351 fprintf(stderr, "Failed to get my hostname.\n");
7352 return 1;
7355 if (*username == 0 && getenv("LOGNAME")) {
7356 fstrcpy(username,getenv("LOGNAME"));
7359 argc--;
7360 argv++;
7362 fstrcpy(workgroup, lp_workgroup());
7364 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7365 switch (opt) {
7366 case 'p':
7367 port_to_use = atoi(optarg);
7368 break;
7369 case 's':
7370 seed = atoi(optarg);
7371 break;
7372 case 'W':
7373 fstrcpy(workgroup,optarg);
7374 break;
7375 case 'm':
7376 max_protocol = interpret_protocol(optarg, max_protocol);
7377 break;
7378 case 'N':
7379 nprocs = atoi(optarg);
7380 break;
7381 case 'o':
7382 torture_numops = atoi(optarg);
7383 break;
7384 case 'd':
7385 DEBUGLEVEL = atoi(optarg);
7386 break;
7387 case 'O':
7388 sockops = optarg;
7389 break;
7390 case 'L':
7391 use_oplocks = True;
7392 break;
7393 case 'l':
7394 local_path = optarg;
7395 break;
7396 case 'A':
7397 torture_showall = True;
7398 break;
7399 case 'n':
7400 fstrcpy(myname, optarg);
7401 break;
7402 case 'c':
7403 client_txt = optarg;
7404 break;
7405 case 'e':
7406 do_encrypt = true;
7407 break;
7408 case 'k':
7409 #ifdef HAVE_KRB5
7410 use_kerberos = True;
7411 #else
7412 d_printf("No kerberos support compiled in\n");
7413 exit(1);
7414 #endif
7415 break;
7416 case 'U':
7417 gotuser = 1;
7418 fstrcpy(username,optarg);
7419 p = strchr_m(username,'%');
7420 if (p) {
7421 *p = 0;
7422 fstrcpy(password, p+1);
7423 gotpass = 1;
7425 break;
7426 case 'b':
7427 fstrcpy(multishare_conn_fname, optarg);
7428 use_multishare_conn = True;
7429 break;
7430 case 'B':
7431 torture_blocksize = atoi(optarg);
7432 break;
7433 default:
7434 printf("Unknown option %c (%d)\n", (char)opt, opt);
7435 usage();
7439 d_printf("using seed %d\n", seed);
7441 srandom(seed);
7443 if(use_kerberos && !gotuser) gotpass = True;
7445 while (!gotpass) {
7446 p = getpass("Password:");
7447 if (p) {
7448 fstrcpy(password, p);
7449 gotpass = 1;
7453 printf("host=%s share=%s user=%s myname=%s\n",
7454 host, share, username, myname);
7456 if (argc == optind) {
7457 correct = run_test("ALL");
7458 } else {
7459 for (i=optind;i<argc;i++) {
7460 if (!run_test(argv[i])) {
7461 correct = False;
7466 TALLOC_FREE(frame);
7468 if (correct) {
7469 return(0);
7470 } else {
7471 return(1);