s3-selftest: enable RPC-WINREG against s3.
[Samba.git] / source3 / torture / torture.c
blobfe5bbf30d1e08ee7c1cae7b89244d5197f354deb
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"
24 extern char *optarg;
25 extern int optind;
27 static fstring host, workgroup, share, password, username, myname;
28 static int max_protocol = PROTOCOL_NT1;
29 static const char *sockops="TCP_NODELAY";
30 static int nprocs=1;
31 static int port_to_use=0;
32 int torture_numops=100;
33 int torture_blocksize=1024*1024;
34 static int procnum; /* records process count number when forking */
35 static struct cli_state *current_cli;
36 static fstring randomfname;
37 static bool use_oplocks;
38 static bool use_level_II_oplocks;
39 static const char *client_txt = "client_oplocks.txt";
40 static bool use_kerberos;
41 static fstring multishare_conn_fname;
42 static bool use_multishare_conn = False;
43 static bool do_encrypt;
44 static const char *local_path = NULL;
46 bool torture_showall = False;
48 static double create_procs(bool (*fn)(int), bool *result);
51 static struct timeval tp1,tp2;
54 void start_timer(void)
56 GetTimeOfDay(&tp1);
59 double end_timer(void)
61 GetTimeOfDay(&tp2);
62 return((tp2.tv_sec - tp1.tv_sec) +
63 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
67 /* return a pointer to a anonymous shared memory segment of size "size"
68 which will persist across fork() but will disappear when all processes
69 exit
71 The memory is not zeroed
73 This function uses system5 shared memory. It takes advantage of a property
74 that the memory is not destroyed if it is attached when the id is removed
76 void *shm_setup(int size)
78 int shmid;
79 void *ret;
81 #ifdef __QNXNTO__
82 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
83 if (shmid == -1) {
84 printf("can't get shared memory\n");
85 exit(1);
87 shm_unlink("private");
88 if (ftruncate(shmid, size) == -1) {
89 printf("can't set shared memory size\n");
90 exit(1);
92 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
93 if (ret == MAP_FAILED) {
94 printf("can't map shared memory\n");
95 exit(1);
97 #else
98 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
99 if (shmid == -1) {
100 printf("can't get shared memory\n");
101 exit(1);
103 ret = (void *)shmat(shmid, 0, 0);
104 if (!ret || ret == (void *)-1) {
105 printf("can't attach to shared memory\n");
106 return NULL;
108 /* the following releases the ipc, but note that this process
109 and all its children will still have access to the memory, its
110 just that the shmid is no longer valid for other shm calls. This
111 means we don't leave behind lots of shm segments after we exit
113 See Stevens "advanced programming in unix env" for details
115 shmctl(shmid, IPC_RMID, 0);
116 #endif
118 return ret;
121 /********************************************************************
122 Ensure a connection is encrypted.
123 ********************************************************************/
125 static bool force_cli_encryption(struct cli_state *c,
126 const char *sharename)
128 uint16 major, minor;
129 uint32 caplow, caphigh;
130 NTSTATUS status;
132 if (!SERVER_HAS_UNIX_CIFS(c)) {
133 d_printf("Encryption required and "
134 "server that doesn't support "
135 "UNIX extensions - failing connect\n");
136 return false;
139 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
140 &caphigh);
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "can't get UNIX CIFS extensions "
144 "version from server: %s\n", nt_errstr(status));
145 return false;
148 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
149 d_printf("Encryption required and "
150 "share %s doesn't support "
151 "encryption.\n", sharename);
152 return false;
155 if (c->use_kerberos) {
156 status = cli_gss_smb_encryption_start(c);
157 } else {
158 status = cli_raw_ntlm_smb_encryption_start(c,
159 username,
160 password,
161 workgroup);
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("Encryption required and "
166 "setup failed with error %s.\n",
167 nt_errstr(status));
168 return false;
171 return true;
175 static struct cli_state *open_nbt_connection(void)
177 struct nmb_name called, calling;
178 struct sockaddr_storage ss;
179 struct cli_state *c;
180 NTSTATUS status;
182 make_nmb_name(&calling, myname, 0x0);
183 make_nmb_name(&called , host, 0x20);
185 zero_sockaddr(&ss);
187 if (!(c = cli_initialise())) {
188 printf("Failed initialize cli_struct to connect with %s\n", host);
189 return NULL;
192 c->port = port_to_use;
194 status = cli_connect(c, host, &ss);
195 if (!NT_STATUS_IS_OK(status)) {
196 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
197 return NULL;
200 c->use_kerberos = use_kerberos;
202 c->timeout = 120000; /* set a really long timeout (2 minutes) */
203 if (use_oplocks) c->use_oplocks = True;
204 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
206 if (!cli_session_request(c, &calling, &called)) {
208 * Well, that failed, try *SMBSERVER ...
209 * However, we must reconnect as well ...
211 status = cli_connect(c, host, &ss);
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
214 return NULL;
217 make_nmb_name(&called, "*SMBSERVER", 0x20);
218 if (!cli_session_request(c, &calling, &called)) {
219 printf("%s rejected the session\n",host);
220 printf("We tried with a called name of %s & %s\n",
221 host, "*SMBSERVER");
222 cli_shutdown(c);
223 return NULL;
227 return c;
230 /* Insert a NULL at the first separator of the given path and return a pointer
231 * to the remainder of the string.
233 static char *
234 terminate_path_at_separator(char * path)
236 char * p;
238 if (!path) {
239 return NULL;
242 if ((p = strchr_m(path, '/'))) {
243 *p = '\0';
244 return p + 1;
247 if ((p = strchr_m(path, '\\'))) {
248 *p = '\0';
249 return p + 1;
252 /* No separator. */
253 return NULL;
257 parse a //server/share type UNC name
259 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
260 char **hostname, char **sharename)
262 char *p;
264 *hostname = *sharename = NULL;
266 if (strncmp(unc_name, "\\\\", 2) &&
267 strncmp(unc_name, "//", 2)) {
268 return False;
271 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
272 p = terminate_path_at_separator(*hostname);
274 if (p && *p) {
275 *sharename = talloc_strdup(mem_ctx, p);
276 terminate_path_at_separator(*sharename);
279 if (*hostname && *sharename) {
280 return True;
283 TALLOC_FREE(*hostname);
284 TALLOC_FREE(*sharename);
285 return False;
288 static bool torture_open_connection_share(struct cli_state **c,
289 const char *hostname,
290 const char *sharename)
292 bool retry;
293 int flags = 0;
294 NTSTATUS status;
296 if (use_kerberos)
297 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
298 if (use_oplocks)
299 flags |= CLI_FULL_CONNECTION_OPLOCKS;
300 if (use_level_II_oplocks)
301 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
303 status = cli_full_connection(c, myname,
304 hostname, NULL, port_to_use,
305 sharename, "?????",
306 username, workgroup,
307 password, flags, Undefined, &retry);
308 if (!NT_STATUS_IS_OK(status)) {
309 printf("failed to open share connection: //%s/%s port:%d - %s\n",
310 hostname, sharename, port_to_use, nt_errstr(status));
311 return False;
314 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
316 if (do_encrypt) {
317 return force_cli_encryption(*c,
318 sharename);
320 return True;
323 bool torture_open_connection(struct cli_state **c, int conn_index)
325 char **unc_list = NULL;
326 int num_unc_names = 0;
327 bool result;
329 if (use_multishare_conn==True) {
330 char *h, *s;
331 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
332 if (!unc_list || num_unc_names <= 0) {
333 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
334 exit(1);
337 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
338 NULL, &h, &s)) {
339 printf("Failed to parse UNC name %s\n",
340 unc_list[conn_index % num_unc_names]);
341 TALLOC_FREE(unc_list);
342 exit(1);
345 result = torture_open_connection_share(c, h, s);
347 /* h, s were copied earlier */
348 TALLOC_FREE(unc_list);
349 return result;
352 return torture_open_connection_share(c, host, share);
355 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
357 uint16 old_vuid = cli->vuid;
358 fstring old_user_name;
359 size_t passlen = strlen(password);
360 NTSTATUS status;
361 bool ret;
363 fstrcpy(old_user_name, cli->user_name);
364 cli->vuid = 0;
365 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
366 password, passlen,
367 password, passlen,
368 workgroup));
369 *new_vuid = cli->vuid;
370 cli->vuid = old_vuid;
371 status = cli_set_username(cli, old_user_name);
372 if (!NT_STATUS_IS_OK(status)) {
373 return false;
375 return ret;
379 bool torture_close_connection(struct cli_state *c)
381 bool ret = True;
382 if (!cli_tdis(c)) {
383 printf("tdis failed (%s)\n", cli_errstr(c));
384 ret = False;
387 cli_shutdown(c);
389 return ret;
393 /* check if the server produced the expected error code */
394 static bool check_error(int line, struct cli_state *c,
395 uint8 eclass, uint32 ecode, NTSTATUS nterr)
397 if (cli_is_dos_error(c)) {
398 uint8 cclass;
399 uint32 num;
401 /* Check DOS error */
403 cli_dos_error(c, &cclass, &num);
405 if (eclass != cclass || ecode != num) {
406 printf("unexpected error code class=%d code=%d\n",
407 (int)cclass, (int)num);
408 printf(" expected %d/%d %s (line=%d)\n",
409 (int)eclass, (int)ecode, nt_errstr(nterr), line);
410 return False;
413 } else {
414 NTSTATUS status;
416 /* Check NT error */
418 status = cli_nt_error(c);
420 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
421 printf("unexpected error code %s\n", nt_errstr(status));
422 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
423 return False;
427 return True;
431 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
433 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
434 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
436 return True;
440 static bool rw_torture(struct cli_state *c)
442 const char *lockfname = "\\torture.lck";
443 fstring fname;
444 uint16_t fnum;
445 uint16_t fnum2;
446 pid_t pid2, pid = getpid();
447 int i, j;
448 char buf[1024];
449 bool correct = True;
450 NTSTATUS status;
452 memset(buf, '\0', sizeof(buf));
454 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
455 DENY_NONE, &fnum2);
456 if (!NT_STATUS_IS_OK(status)) {
457 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
459 if (!NT_STATUS_IS_OK(status)) {
460 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
461 return False;
464 for (i=0;i<torture_numops;i++) {
465 unsigned n = (unsigned)sys_random()%10;
466 if (i % 10 == 0) {
467 printf("%d\r", i); fflush(stdout);
469 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
471 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
472 return False;
475 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
476 printf("open failed (%s)\n", cli_errstr(c));
477 correct = False;
478 break;
481 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
482 printf("write failed (%s)\n", cli_errstr(c));
483 correct = False;
486 for (j=0;j<50;j++) {
487 if (cli_write(c, fnum, 0, (char *)buf,
488 sizeof(pid)+(j*sizeof(buf)),
489 sizeof(buf)) != sizeof(buf)) {
490 printf("write failed (%s)\n", cli_errstr(c));
491 correct = False;
495 pid2 = 0;
497 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
498 printf("read failed (%s)\n", cli_errstr(c));
499 correct = False;
502 if (pid2 != pid) {
503 printf("data corruption!\n");
504 correct = False;
507 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
508 printf("close failed (%s)\n", cli_errstr(c));
509 correct = False;
512 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
513 printf("unlink failed (%s)\n", cli_errstr(c));
514 correct = False;
517 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
518 printf("unlock failed (%s)\n", cli_errstr(c));
519 correct = False;
523 cli_close(c, fnum2);
524 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
526 printf("%d\n", i);
528 return correct;
531 static bool run_torture(int dummy)
533 struct cli_state *cli;
534 bool ret;
536 cli = current_cli;
538 cli_sockopt(cli, sockops);
540 ret = rw_torture(cli);
542 if (!torture_close_connection(cli)) {
543 ret = False;
546 return ret;
549 static bool rw_torture3(struct cli_state *c, char *lockfname)
551 uint16_t fnum = (uint16_t)-1;
552 unsigned int i = 0;
553 char buf[131072];
554 char buf_rd[131072];
555 unsigned count;
556 unsigned countprev = 0;
557 ssize_t sent = 0;
558 bool correct = True;
559 NTSTATUS status;
561 srandom(1);
562 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
564 SIVAL(buf, i, sys_random());
567 if (procnum == 0)
569 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
570 DENY_NONE, &fnum))) {
571 printf("first open read/write of %s failed (%s)\n",
572 lockfname, cli_errstr(c));
573 return False;
576 else
578 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
580 status = cli_open(c, lockfname, O_RDONLY,
581 DENY_NONE, &fnum);
582 if (!NT_STATUS_IS_OK(status)) {
583 break;
585 smb_msleep(10);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("second open read-only of %s failed (%s)\n",
589 lockfname, cli_errstr(c));
590 return False;
594 i = 0;
595 for (count = 0; count < sizeof(buf); count += sent)
597 if (count >= countprev) {
598 printf("%d %8d\r", i, count);
599 fflush(stdout);
600 i++;
601 countprev += (sizeof(buf) / 20);
604 if (procnum == 0)
606 sent = ((unsigned)sys_random()%(20))+ 1;
607 if (sent > sizeof(buf) - count)
609 sent = sizeof(buf) - count;
612 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
613 printf("write failed (%s)\n", cli_errstr(c));
614 correct = False;
617 else
619 sent = cli_read(c, fnum, buf_rd+count, count,
620 sizeof(buf)-count);
621 if (sent < 0)
623 printf("read failed offset:%d size:%ld (%s)\n",
624 count, (unsigned long)sizeof(buf)-count,
625 cli_errstr(c));
626 correct = False;
627 sent = 0;
629 if (sent > 0)
631 if (memcmp(buf_rd+count, buf+count, sent) != 0)
633 printf("read/write compare failed\n");
634 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
635 correct = False;
636 break;
643 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
644 printf("close failed (%s)\n", cli_errstr(c));
645 correct = False;
648 return correct;
651 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
653 const char *lockfname = "\\torture2.lck";
654 uint16_t fnum1;
655 uint16_t fnum2;
656 int i;
657 char buf[131072];
658 char buf_rd[131072];
659 bool correct = True;
660 ssize_t bytes_read;
662 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
663 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
666 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
667 DENY_NONE, &fnum1))) {
668 printf("first open read/write of %s failed (%s)\n",
669 lockfname, cli_errstr(c1));
670 return False;
672 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
673 DENY_NONE, &fnum2))) {
674 printf("second open read-only of %s failed (%s)\n",
675 lockfname, cli_errstr(c2));
676 cli_close(c1, fnum1);
677 return False;
680 for (i=0;i<torture_numops;i++)
682 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
683 if (i % 10 == 0) {
684 printf("%d\r", i); fflush(stdout);
687 generate_random_buffer((unsigned char *)buf, buf_size);
689 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
690 printf("write failed (%s)\n", cli_errstr(c1));
691 correct = False;
692 break;
695 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
696 printf("read failed (%s)\n", cli_errstr(c2));
697 printf("read %d, expected %ld\n", (int)bytes_read,
698 (unsigned long)buf_size);
699 correct = False;
700 break;
703 if (memcmp(buf_rd, buf, buf_size) != 0)
705 printf("read/write compare failed\n");
706 correct = False;
707 break;
711 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
712 printf("close failed (%s)\n", cli_errstr(c2));
713 correct = False;
715 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
716 printf("close failed (%s)\n", cli_errstr(c1));
717 correct = False;
720 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
721 printf("unlink failed (%s)\n", cli_errstr(c1));
722 correct = False;
725 return correct;
728 static bool run_readwritetest(int dummy)
730 struct cli_state *cli1, *cli2;
731 bool test1, test2 = False;
733 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
734 return False;
736 cli_sockopt(cli1, sockops);
737 cli_sockopt(cli2, sockops);
739 printf("starting readwritetest\n");
741 test1 = rw_torture2(cli1, cli2);
742 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
744 if (test1) {
745 test2 = rw_torture2(cli1, cli1);
746 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
749 if (!torture_close_connection(cli1)) {
750 test1 = False;
753 if (!torture_close_connection(cli2)) {
754 test2 = False;
757 return (test1 && test2);
760 static bool run_readwritemulti(int dummy)
762 struct cli_state *cli;
763 bool test;
765 cli = current_cli;
767 cli_sockopt(cli, sockops);
769 printf("run_readwritemulti: fname %s\n", randomfname);
770 test = rw_torture3(cli, randomfname);
772 if (!torture_close_connection(cli)) {
773 test = False;
776 return test;
779 static bool run_readwritelarge(int dummy)
781 static struct cli_state *cli1;
782 uint16_t fnum1;
783 const char *lockfname = "\\large.dat";
784 SMB_OFF_T fsize;
785 char buf[126*1024];
786 bool correct = True;
788 if (!torture_open_connection(&cli1, 0)) {
789 return False;
791 cli_sockopt(cli1, sockops);
792 memset(buf,'\0',sizeof(buf));
794 cli1->max_xmit = 128*1024;
796 printf("starting readwritelarge\n");
798 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
800 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
801 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
802 return False;
805 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
807 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
808 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
809 correct = False;
812 if (fsize == sizeof(buf))
813 printf("readwritelarge test 1 succeeded (size = %lx)\n",
814 (unsigned long)fsize);
815 else {
816 printf("readwritelarge test 1 failed (size = %lx)\n",
817 (unsigned long)fsize);
818 correct = False;
821 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
822 printf("close failed (%s)\n", cli_errstr(cli1));
823 correct = False;
826 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
827 printf("unlink failed (%s)\n", cli_errstr(cli1));
828 correct = False;
831 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
832 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
833 return False;
836 cli1->max_xmit = 4*1024;
838 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
840 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
841 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
842 correct = False;
845 if (fsize == sizeof(buf))
846 printf("readwritelarge test 2 succeeded (size = %lx)\n",
847 (unsigned long)fsize);
848 else {
849 printf("readwritelarge test 2 failed (size = %lx)\n",
850 (unsigned long)fsize);
851 correct = False;
854 #if 0
855 /* ToDo - set allocation. JRA */
856 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
857 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
858 return False;
860 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
861 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
862 correct = False;
864 if (fsize != 0)
865 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
866 #endif
868 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
869 printf("close failed (%s)\n", cli_errstr(cli1));
870 correct = False;
873 if (!torture_close_connection(cli1)) {
874 correct = False;
876 return correct;
879 int line_count = 0;
880 int nbio_id;
882 #define ival(s) strtol(s, NULL, 0)
884 /* run a test that simulates an approximate netbench client load */
885 static bool run_netbench(int client)
887 struct cli_state *cli;
888 int i;
889 char line[1024];
890 char cname[20];
891 FILE *f;
892 const char *params[20];
893 bool correct = True;
895 cli = current_cli;
897 nbio_id = client;
899 cli_sockopt(cli, sockops);
901 nb_setup(cli);
903 slprintf(cname,sizeof(cname)-1, "client%d", client);
905 f = fopen(client_txt, "r");
907 if (!f) {
908 perror(client_txt);
909 return False;
912 while (fgets(line, sizeof(line)-1, f)) {
913 char *saveptr;
914 line_count++;
916 line[strlen(line)-1] = 0;
918 /* printf("[%d] %s\n", line_count, line); */
920 all_string_sub(line,"client1", cname, sizeof(line));
922 /* parse the command parameters */
923 params[0] = strtok_r(line, " ", &saveptr);
924 i = 0;
925 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
927 params[i] = "";
929 if (i < 2) continue;
931 if (!strncmp(params[0],"SMB", 3)) {
932 printf("ERROR: You are using a dbench 1 load file\n");
933 exit(1);
936 if (!strcmp(params[0],"NTCreateX")) {
937 nb_createx(params[1], ival(params[2]), ival(params[3]),
938 ival(params[4]));
939 } else if (!strcmp(params[0],"Close")) {
940 nb_close(ival(params[1]));
941 } else if (!strcmp(params[0],"Rename")) {
942 nb_rename(params[1], params[2]);
943 } else if (!strcmp(params[0],"Unlink")) {
944 nb_unlink(params[1]);
945 } else if (!strcmp(params[0],"Deltree")) {
946 nb_deltree(params[1]);
947 } else if (!strcmp(params[0],"Rmdir")) {
948 nb_rmdir(params[1]);
949 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
950 nb_qpathinfo(params[1]);
951 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
952 nb_qfileinfo(ival(params[1]));
953 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
954 nb_qfsinfo(ival(params[1]));
955 } else if (!strcmp(params[0],"FIND_FIRST")) {
956 nb_findfirst(params[1]);
957 } else if (!strcmp(params[0],"WriteX")) {
958 nb_writex(ival(params[1]),
959 ival(params[2]), ival(params[3]), ival(params[4]));
960 } else if (!strcmp(params[0],"ReadX")) {
961 nb_readx(ival(params[1]),
962 ival(params[2]), ival(params[3]), ival(params[4]));
963 } else if (!strcmp(params[0],"Flush")) {
964 nb_flush(ival(params[1]));
965 } else {
966 printf("Unknown operation %s\n", params[0]);
967 exit(1);
970 fclose(f);
972 nb_cleanup();
974 if (!torture_close_connection(cli)) {
975 correct = False;
978 return correct;
982 /* run a test that simulates an approximate netbench client load */
983 static bool run_nbench(int dummy)
985 double t;
986 bool correct = True;
988 nbio_shmem(nprocs);
990 nbio_id = -1;
992 signal(SIGALRM, nb_alarm);
993 alarm(1);
994 t = create_procs(run_netbench, &correct);
995 alarm(0);
997 printf("\nThroughput %g MB/sec\n",
998 1.0e-6 * nbio_total() / t);
999 return correct;
1004 This test checks for two things:
1006 1) correct support for retaining locks over a close (ie. the server
1007 must not use posix semantics)
1008 2) support for lock timeouts
1010 static bool run_locktest1(int dummy)
1012 struct cli_state *cli1, *cli2;
1013 const char *fname = "\\lockt1.lck";
1014 uint16_t fnum1, fnum2, fnum3;
1015 time_t t1, t2;
1016 unsigned lock_timeout;
1018 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1019 return False;
1021 cli_sockopt(cli1, sockops);
1022 cli_sockopt(cli2, sockops);
1024 printf("starting locktest1\n");
1026 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1028 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1029 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1030 return False;
1032 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1033 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1034 return False;
1036 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1037 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1038 return False;
1041 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1042 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1043 return False;
1047 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1048 printf("lock2 succeeded! This is a locking bug\n");
1049 return False;
1050 } else {
1051 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1052 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1056 lock_timeout = (1 + (random() % 20));
1057 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1058 t1 = time(NULL);
1059 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1060 printf("lock3 succeeded! This is a locking bug\n");
1061 return False;
1062 } else {
1063 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1064 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1066 t2 = time(NULL);
1068 if (ABS(t2 - t1) < lock_timeout-1) {
1069 printf("error: This server appears not to support timed lock requests\n");
1072 printf("server slept for %u seconds for a %u second timeout\n",
1073 (unsigned int)(t2-t1), lock_timeout);
1075 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1076 printf("close1 failed (%s)\n", cli_errstr(cli1));
1077 return False;
1080 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1081 printf("lock4 succeeded! This is a locking bug\n");
1082 return False;
1083 } else {
1084 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1085 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1088 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1089 printf("close2 failed (%s)\n", cli_errstr(cli1));
1090 return False;
1093 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1094 printf("close3 failed (%s)\n", cli_errstr(cli2));
1095 return False;
1098 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1099 printf("unlink failed (%s)\n", cli_errstr(cli1));
1100 return False;
1104 if (!torture_close_connection(cli1)) {
1105 return False;
1108 if (!torture_close_connection(cli2)) {
1109 return False;
1112 printf("Passed locktest1\n");
1113 return True;
1117 this checks to see if a secondary tconx can use open files from an
1118 earlier tconx
1120 static bool run_tcon_test(int dummy)
1122 static struct cli_state *cli;
1123 const char *fname = "\\tcontest.tmp";
1124 uint16 fnum1;
1125 uint16 cnum1, cnum2, cnum3;
1126 uint16 vuid1, vuid2;
1127 char buf[4];
1128 bool ret = True;
1129 NTSTATUS status;
1131 memset(buf, '\0', sizeof(buf));
1133 if (!torture_open_connection(&cli, 0)) {
1134 return False;
1136 cli_sockopt(cli, sockops);
1138 printf("starting tcontest\n");
1140 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1142 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1143 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1144 return False;
1147 cnum1 = cli->cnum;
1148 vuid1 = cli->vuid;
1150 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1151 printf("initial write failed (%s)", cli_errstr(cli));
1152 return False;
1155 status = cli_tcon_andx(cli, share, "?????",
1156 password, strlen(password)+1);
1157 if (!NT_STATUS_IS_OK(status)) {
1158 printf("%s refused 2nd tree connect (%s)\n", host,
1159 nt_errstr(status));
1160 cli_shutdown(cli);
1161 return False;
1164 cnum2 = cli->cnum;
1165 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1166 vuid2 = cli->vuid + 1;
1168 /* try a write with the wrong tid */
1169 cli->cnum = cnum2;
1171 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1172 printf("* server allows write with wrong TID\n");
1173 ret = False;
1174 } else {
1175 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1179 /* try a write with an invalid tid */
1180 cli->cnum = cnum3;
1182 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1183 printf("* server allows write with invalid TID\n");
1184 ret = False;
1185 } else {
1186 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1189 /* try a write with an invalid vuid */
1190 cli->vuid = vuid2;
1191 cli->cnum = cnum1;
1193 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1194 printf("* server allows write with invalid VUID\n");
1195 ret = False;
1196 } else {
1197 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1200 cli->cnum = cnum1;
1201 cli->vuid = vuid1;
1203 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1204 printf("close failed (%s)\n", cli_errstr(cli));
1205 return False;
1208 cli->cnum = cnum2;
1210 if (!cli_tdis(cli)) {
1211 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1212 return False;
1215 cli->cnum = cnum1;
1217 if (!torture_close_connection(cli)) {
1218 return False;
1221 return ret;
1226 checks for old style tcon support
1228 static bool run_tcon2_test(int dummy)
1230 static struct cli_state *cli;
1231 uint16 cnum, max_xmit;
1232 char *service;
1233 NTSTATUS status;
1235 if (!torture_open_connection(&cli, 0)) {
1236 return False;
1238 cli_sockopt(cli, sockops);
1240 printf("starting tcon2 test\n");
1242 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1243 return false;
1246 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 printf("tcon2 failed : %s\n", cli_errstr(cli));
1250 } else {
1251 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1252 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1255 if (!torture_close_connection(cli)) {
1256 return False;
1259 printf("Passed tcon2 test\n");
1260 return True;
1263 static bool tcon_devtest(struct cli_state *cli,
1264 const char *myshare, const char *devtype,
1265 const char *return_devtype,
1266 NTSTATUS expected_error)
1268 NTSTATUS status;
1269 bool ret;
1271 status = cli_tcon_andx(cli, myshare, devtype,
1272 password, strlen(password)+1);
1274 if (NT_STATUS_IS_OK(expected_error)) {
1275 if (NT_STATUS_IS_OK(status)) {
1276 if (strcmp(cli->dev, return_devtype) == 0) {
1277 ret = True;
1278 } else {
1279 printf("tconX to share %s with type %s "
1280 "succeeded but returned the wrong "
1281 "device type (got [%s] but should have got [%s])\n",
1282 myshare, devtype, cli->dev, return_devtype);
1283 ret = False;
1285 } else {
1286 printf("tconX to share %s with type %s "
1287 "should have succeeded but failed\n",
1288 myshare, devtype);
1289 ret = False;
1291 cli_tdis(cli);
1292 } else {
1293 if (NT_STATUS_IS_OK(status)) {
1294 printf("tconx to share %s with type %s "
1295 "should have failed but succeeded\n",
1296 myshare, devtype);
1297 ret = False;
1298 } else {
1299 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1300 expected_error)) {
1301 ret = True;
1302 } else {
1303 printf("Returned unexpected error\n");
1304 ret = False;
1308 return ret;
1312 checks for correct tconX support
1314 static bool run_tcon_devtype_test(int dummy)
1316 static struct cli_state *cli1 = NULL;
1317 bool retry;
1318 int flags = 0;
1319 NTSTATUS status;
1320 bool ret = True;
1322 status = cli_full_connection(&cli1, myname,
1323 host, NULL, port_to_use,
1324 NULL, NULL,
1325 username, workgroup,
1326 password, flags, Undefined, &retry);
1328 if (!NT_STATUS_IS_OK(status)) {
1329 printf("could not open connection\n");
1330 return False;
1333 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1334 ret = False;
1336 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1337 ret = False;
1339 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1340 ret = False;
1342 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1343 ret = False;
1345 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1346 ret = False;
1348 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1349 ret = False;
1351 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1352 ret = False;
1354 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1355 ret = False;
1357 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1358 ret = False;
1360 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1361 ret = False;
1363 cli_shutdown(cli1);
1365 if (ret)
1366 printf("Passed tcondevtest\n");
1368 return ret;
1373 This test checks that
1375 1) the server supports multiple locking contexts on the one SMB
1376 connection, distinguished by PID.
1378 2) the server correctly fails overlapping locks made by the same PID (this
1379 goes against POSIX behaviour, which is why it is tricky to implement)
1381 3) the server denies unlock requests by an incorrect client PID
1383 static bool run_locktest2(int dummy)
1385 static struct cli_state *cli;
1386 const char *fname = "\\lockt2.lck";
1387 uint16_t fnum1, fnum2, fnum3;
1388 bool correct = True;
1390 if (!torture_open_connection(&cli, 0)) {
1391 return False;
1394 cli_sockopt(cli, sockops);
1396 printf("starting locktest2\n");
1398 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1400 cli_setpid(cli, 1);
1402 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1403 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1404 return False;
1407 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1408 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1409 return False;
1412 cli_setpid(cli, 2);
1414 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1415 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1416 return False;
1419 cli_setpid(cli, 1);
1421 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1422 printf("lock1 failed (%s)\n", cli_errstr(cli));
1423 return False;
1426 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1427 printf("WRITE lock1 succeeded! This is a locking bug\n");
1428 correct = False;
1429 } else {
1430 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1431 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1434 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1435 printf("WRITE lock2 succeeded! This is a locking bug\n");
1436 correct = False;
1437 } else {
1438 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1439 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1442 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1443 printf("READ lock2 succeeded! This is a locking bug\n");
1444 correct = False;
1445 } else {
1446 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1447 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1450 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1451 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1453 cli_setpid(cli, 2);
1454 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1455 printf("unlock at 100 succeeded! This is a locking bug\n");
1456 correct = False;
1459 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1460 printf("unlock1 succeeded! This is a locking bug\n");
1461 correct = False;
1462 } else {
1463 if (!check_error(__LINE__, cli,
1464 ERRDOS, ERRlock,
1465 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1468 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1469 printf("unlock2 succeeded! This is a locking bug\n");
1470 correct = False;
1471 } else {
1472 if (!check_error(__LINE__, cli,
1473 ERRDOS, ERRlock,
1474 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1477 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1478 printf("lock3 succeeded! This is a locking bug\n");
1479 correct = False;
1480 } else {
1481 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1484 cli_setpid(cli, 1);
1486 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1487 printf("close1 failed (%s)\n", cli_errstr(cli));
1488 return False;
1491 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1492 printf("close2 failed (%s)\n", cli_errstr(cli));
1493 return False;
1496 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1497 printf("close3 failed (%s)\n", cli_errstr(cli));
1498 return False;
1501 if (!torture_close_connection(cli)) {
1502 correct = False;
1505 printf("locktest2 finished\n");
1507 return correct;
1512 This test checks that
1514 1) the server supports the full offset range in lock requests
1516 static bool run_locktest3(int dummy)
1518 static struct cli_state *cli1, *cli2;
1519 const char *fname = "\\lockt3.lck";
1520 uint16_t fnum1, fnum2;
1521 int i;
1522 uint32 offset;
1523 bool correct = True;
1525 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1527 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1528 return False;
1530 cli_sockopt(cli1, sockops);
1531 cli_sockopt(cli2, sockops);
1533 printf("starting locktest3\n");
1535 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1538 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1539 return False;
1541 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1542 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1543 return False;
1546 for (offset=i=0;i<torture_numops;i++) {
1547 NEXT_OFFSET;
1548 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1549 printf("lock1 %d failed (%s)\n",
1551 cli_errstr(cli1));
1552 return False;
1555 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1556 printf("lock2 %d failed (%s)\n",
1558 cli_errstr(cli1));
1559 return False;
1563 for (offset=i=0;i<torture_numops;i++) {
1564 NEXT_OFFSET;
1566 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1567 printf("error: lock1 %d succeeded!\n", i);
1568 return False;
1571 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1572 printf("error: lock2 %d succeeded!\n", i);
1573 return False;
1576 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1577 printf("error: lock3 %d succeeded!\n", i);
1578 return False;
1581 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1582 printf("error: lock4 %d succeeded!\n", i);
1583 return False;
1587 for (offset=i=0;i<torture_numops;i++) {
1588 NEXT_OFFSET;
1590 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1591 printf("unlock1 %d failed (%s)\n",
1593 cli_errstr(cli1));
1594 return False;
1597 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1598 printf("unlock2 %d failed (%s)\n",
1600 cli_errstr(cli1));
1601 return False;
1605 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1606 printf("close1 failed (%s)\n", cli_errstr(cli1));
1607 return False;
1610 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1611 printf("close2 failed (%s)\n", cli_errstr(cli2));
1612 return False;
1615 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1616 printf("unlink failed (%s)\n", cli_errstr(cli1));
1617 return False;
1620 if (!torture_close_connection(cli1)) {
1621 correct = False;
1624 if (!torture_close_connection(cli2)) {
1625 correct = False;
1628 printf("finished locktest3\n");
1630 return correct;
1633 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1634 printf("** "); correct = False; \
1638 looks at overlapping locks
1640 static bool run_locktest4(int dummy)
1642 static struct cli_state *cli1, *cli2;
1643 const char *fname = "\\lockt4.lck";
1644 uint16_t fnum1, fnum2, f;
1645 bool ret;
1646 char buf[1000];
1647 bool correct = True;
1649 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1650 return False;
1653 cli_sockopt(cli1, sockops);
1654 cli_sockopt(cli2, sockops);
1656 printf("starting locktest4\n");
1658 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1660 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1661 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1663 memset(buf, 0, sizeof(buf));
1665 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1666 printf("Failed to create file\n");
1667 correct = False;
1668 goto fail;
1671 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1672 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1673 EXPECTED(ret, False);
1674 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1676 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1677 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1678 EXPECTED(ret, True);
1679 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1681 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1682 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1683 EXPECTED(ret, False);
1684 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1686 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1687 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1688 EXPECTED(ret, True);
1689 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1691 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1692 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1693 EXPECTED(ret, False);
1694 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1696 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1697 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1698 EXPECTED(ret, True);
1699 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1701 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1702 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1703 EXPECTED(ret, True);
1704 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1706 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1707 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1708 EXPECTED(ret, False);
1709 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1711 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1712 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1713 EXPECTED(ret, False);
1714 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1716 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1717 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1718 EXPECTED(ret, True);
1719 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1721 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1722 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1723 EXPECTED(ret, False);
1724 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1726 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1727 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1728 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1729 EXPECTED(ret, False);
1730 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1733 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1734 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1735 EXPECTED(ret, False);
1736 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1738 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1739 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1740 EXPECTED(ret, False);
1741 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1744 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1745 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1746 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1747 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1748 EXPECTED(ret, True);
1749 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1752 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1753 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1754 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1755 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1756 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1757 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1758 EXPECTED(ret, True);
1759 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1761 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1762 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1763 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1764 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1765 EXPECTED(ret, True);
1766 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1768 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1769 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1770 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1771 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1772 EXPECTED(ret, True);
1773 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1775 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1776 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1777 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1778 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1779 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1780 EXPECTED(ret, True);
1781 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1783 cli_close(cli1, fnum1);
1784 cli_close(cli2, fnum2);
1785 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1786 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1787 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1788 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1789 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1790 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1791 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1792 cli_close(cli1, f);
1793 cli_close(cli1, fnum1);
1794 EXPECTED(ret, True);
1795 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1797 fail:
1798 cli_close(cli1, fnum1);
1799 cli_close(cli2, fnum2);
1800 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1801 torture_close_connection(cli1);
1802 torture_close_connection(cli2);
1804 printf("finished locktest4\n");
1805 return correct;
1809 looks at lock upgrade/downgrade.
1811 static bool run_locktest5(int dummy)
1813 static struct cli_state *cli1, *cli2;
1814 const char *fname = "\\lockt5.lck";
1815 uint16_t fnum1, fnum2, fnum3;
1816 bool ret;
1817 char buf[1000];
1818 bool correct = True;
1820 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1821 return False;
1824 cli_sockopt(cli1, sockops);
1825 cli_sockopt(cli2, sockops);
1827 printf("starting locktest5\n");
1829 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1831 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1832 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1833 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1835 memset(buf, 0, sizeof(buf));
1837 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1838 printf("Failed to create file\n");
1839 correct = False;
1840 goto fail;
1843 /* Check for NT bug... */
1844 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1845 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1846 cli_close(cli1, fnum1);
1847 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1848 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1849 EXPECTED(ret, True);
1850 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1851 cli_close(cli1, fnum1);
1852 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1853 cli_unlock(cli1, fnum3, 0, 1);
1855 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1856 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1857 EXPECTED(ret, True);
1858 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1860 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1861 EXPECTED(ret, False);
1863 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1865 /* Unlock the process 2 lock. */
1866 cli_unlock(cli2, fnum2, 0, 4);
1868 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1869 EXPECTED(ret, False);
1871 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1873 /* Unlock the process 1 fnum3 lock. */
1874 cli_unlock(cli1, fnum3, 0, 4);
1876 /* Stack 2 more locks here. */
1877 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1878 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1880 EXPECTED(ret, True);
1881 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1883 /* Unlock the first process lock, then check this was the WRITE lock that was
1884 removed. */
1886 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1887 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1889 EXPECTED(ret, True);
1890 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1892 /* Unlock the process 2 lock. */
1893 cli_unlock(cli2, fnum2, 0, 4);
1895 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1897 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1898 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1899 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1901 EXPECTED(ret, True);
1902 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1904 /* Ensure the next unlock fails. */
1905 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1906 EXPECTED(ret, False);
1907 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1909 /* Ensure connection 2 can get a write lock. */
1910 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1911 EXPECTED(ret, True);
1913 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1916 fail:
1917 cli_close(cli1, fnum1);
1918 cli_close(cli2, fnum2);
1919 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1920 if (!torture_close_connection(cli1)) {
1921 correct = False;
1923 if (!torture_close_connection(cli2)) {
1924 correct = False;
1927 printf("finished locktest5\n");
1929 return correct;
1933 tries the unusual lockingX locktype bits
1935 static bool run_locktest6(int dummy)
1937 static struct cli_state *cli;
1938 const char *fname[1] = { "\\lock6.txt" };
1939 int i;
1940 uint16_t fnum;
1941 NTSTATUS status;
1943 if (!torture_open_connection(&cli, 0)) {
1944 return False;
1947 cli_sockopt(cli, sockops);
1949 printf("starting locktest6\n");
1951 for (i=0;i<1;i++) {
1952 printf("Testing %s\n", fname[i]);
1954 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1956 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1957 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1958 cli_close(cli, fnum);
1959 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1961 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1962 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1963 cli_close(cli, fnum);
1964 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1966 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1969 torture_close_connection(cli);
1971 printf("finished locktest6\n");
1972 return True;
1975 static bool run_locktest7(int dummy)
1977 struct cli_state *cli1;
1978 const char *fname = "\\lockt7.lck";
1979 uint16_t fnum1;
1980 char buf[200];
1981 bool correct = False;
1983 if (!torture_open_connection(&cli1, 0)) {
1984 return False;
1987 cli_sockopt(cli1, sockops);
1989 printf("starting locktest7\n");
1991 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1993 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1995 memset(buf, 0, sizeof(buf));
1997 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1998 printf("Failed to create file\n");
1999 goto fail;
2002 cli_setpid(cli1, 1);
2004 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2005 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2006 goto fail;
2007 } else {
2008 printf("pid1 successfully locked range 130:4 for READ\n");
2011 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2012 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2013 goto fail;
2014 } else {
2015 printf("pid1 successfully read the range 130:4\n");
2018 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2019 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2020 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2021 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2022 goto fail;
2024 } else {
2025 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2026 goto fail;
2029 cli_setpid(cli1, 2);
2031 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2032 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2033 } else {
2034 printf("pid2 successfully read the range 130:4\n");
2037 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2038 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2039 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2040 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2041 goto fail;
2043 } else {
2044 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2045 goto fail;
2048 cli_setpid(cli1, 1);
2049 cli_unlock(cli1, fnum1, 130, 4);
2051 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2052 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2053 goto fail;
2054 } else {
2055 printf("pid1 successfully locked range 130:4 for WRITE\n");
2058 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2059 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2060 goto fail;
2061 } else {
2062 printf("pid1 successfully read the range 130:4\n");
2065 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2066 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2067 goto fail;
2068 } else {
2069 printf("pid1 successfully wrote to the range 130:4\n");
2072 cli_setpid(cli1, 2);
2074 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2075 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2076 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2077 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2078 goto fail;
2080 } else {
2081 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2082 goto fail;
2085 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2086 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2087 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2088 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2089 goto fail;
2091 } else {
2092 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2093 goto fail;
2096 cli_unlock(cli1, fnum1, 130, 0);
2097 correct = True;
2099 fail:
2100 cli_close(cli1, fnum1);
2101 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2102 torture_close_connection(cli1);
2104 printf("finished locktest7\n");
2105 return correct;
2109 * This demonstrates a problem with our use of GPFS share modes: A file
2110 * descriptor sitting in the pending close queue holding a GPFS share mode
2111 * blocks opening a file another time. Happens with Word 2007 temp files.
2112 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2113 * open is denied with NT_STATUS_SHARING_VIOLATION.
2116 static bool run_locktest8(int dummy)
2118 struct cli_state *cli1;
2119 const char *fname = "\\lockt8.lck";
2120 uint16_t fnum1, fnum2;
2121 char buf[200];
2122 bool correct = False;
2123 NTSTATUS status;
2125 if (!torture_open_connection(&cli1, 0)) {
2126 return False;
2129 cli_sockopt(cli1, sockops);
2131 printf("starting locktest8\n");
2133 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2135 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2136 &fnum1);
2137 if (!NT_STATUS_IS_OK(status)) {
2138 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2139 return false;
2142 memset(buf, 0, sizeof(buf));
2144 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2145 if (!NT_STATUS_IS_OK(status)) {
2146 d_fprintf(stderr, "cli_open second time returned %s\n",
2147 cli_errstr(cli1));
2148 goto fail;
2151 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2152 printf("Unable to apply read lock on range 1:1, error was "
2153 "%s\n", cli_errstr(cli1));
2154 goto fail;
2157 status = cli_close(cli1, fnum1);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2160 goto fail;
2163 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2164 if (!NT_STATUS_IS_OK(status)) {
2165 d_fprintf(stderr, "cli_open third time returned %s\n",
2166 cli_errstr(cli1));
2167 goto fail;
2170 correct = true;
2172 fail:
2173 cli_close(cli1, fnum1);
2174 cli_close(cli1, fnum2);
2175 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2176 torture_close_connection(cli1);
2178 printf("finished locktest8\n");
2179 return correct;
2183 * This test is designed to be run in conjunction with
2184 * external NFS or POSIX locks taken in the filesystem.
2185 * It checks that the smbd server will block until the
2186 * lock is released and then acquire it. JRA.
2189 static bool got_alarm;
2190 static int alarm_fd;
2192 static void alarm_handler(int dummy)
2194 got_alarm = True;
2197 static void alarm_handler_parent(int dummy)
2199 close(alarm_fd);
2202 static void do_local_lock(int read_fd, int write_fd)
2204 int fd;
2205 char c = '\0';
2206 struct flock lock;
2207 const char *local_pathname = NULL;
2208 int ret;
2210 local_pathname = talloc_asprintf(talloc_tos(),
2211 "%s/lockt9.lck", local_path);
2212 if (!local_pathname) {
2213 printf("child: alloc fail\n");
2214 exit(1);
2217 unlink(local_pathname);
2218 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2219 if (fd == -1) {
2220 printf("child: open of %s failed %s.\n",
2221 local_pathname, strerror(errno));
2222 exit(1);
2225 /* Now take a fcntl lock. */
2226 lock.l_type = F_WRLCK;
2227 lock.l_whence = SEEK_SET;
2228 lock.l_start = 0;
2229 lock.l_len = 4;
2230 lock.l_pid = getpid();
2232 ret = fcntl(fd,F_SETLK,&lock);
2233 if (ret == -1) {
2234 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2235 local_pathname, strerror(errno));
2236 exit(1);
2237 } else {
2238 printf("child: got lock 0:4 on file %s.\n",
2239 local_pathname );
2240 fflush(stdout);
2243 CatchSignal(SIGALRM, alarm_handler);
2244 alarm(5);
2245 /* Signal the parent. */
2246 if (write(write_fd, &c, 1) != 1) {
2247 printf("child: start signal fail %s.\n",
2248 strerror(errno));
2249 exit(1);
2251 alarm(0);
2253 alarm(10);
2254 /* Wait for the parent to be ready. */
2255 if (read(read_fd, &c, 1) != 1) {
2256 printf("child: reply signal fail %s.\n",
2257 strerror(errno));
2258 exit(1);
2260 alarm(0);
2262 sleep(5);
2263 close(fd);
2264 printf("child: released lock 0:4 on file %s.\n",
2265 local_pathname );
2266 fflush(stdout);
2267 exit(0);
2270 static bool run_locktest9(int dummy)
2272 struct cli_state *cli1;
2273 const char *fname = "\\lockt9.lck";
2274 uint16_t fnum;
2275 bool correct = False;
2276 int pipe_in[2], pipe_out[2];
2277 pid_t child_pid;
2278 char c = '\0';
2279 int ret;
2280 double seconds;
2281 NTSTATUS status;
2283 printf("starting locktest9\n");
2285 if (local_path == NULL) {
2286 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2287 return false;
2290 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2291 return false;
2294 child_pid = fork();
2295 if (child_pid == -1) {
2296 return false;
2299 if (child_pid == 0) {
2300 /* Child. */
2301 do_local_lock(pipe_out[0], pipe_in[1]);
2302 exit(0);
2305 close(pipe_out[0]);
2306 close(pipe_in[1]);
2307 pipe_out[0] = -1;
2308 pipe_in[1] = -1;
2310 /* Parent. */
2311 ret = read(pipe_in[0], &c, 1);
2312 if (ret != 1) {
2313 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2314 strerror(errno));
2315 return false;
2318 if (!torture_open_connection(&cli1, 0)) {
2319 return false;
2322 cli_sockopt(cli1, sockops);
2324 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2325 &fnum);
2326 if (!NT_STATUS_IS_OK(status)) {
2327 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2328 return false;
2331 /* Ensure the child has the lock. */
2332 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2333 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2334 goto fail;
2335 } else {
2336 d_printf("Child has the lock.\n");
2339 /* Tell the child to wait 5 seconds then exit. */
2340 ret = write(pipe_out[1], &c, 1);
2341 if (ret != 1) {
2342 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2343 strerror(errno));
2344 goto fail;
2347 /* Wait 20 seconds for the lock. */
2348 alarm_fd = cli1->fd;
2349 CatchSignal(SIGALRM, alarm_handler_parent);
2350 alarm(20);
2352 start_timer();
2354 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2355 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2356 "%s\n", cli_errstr(cli1));
2357 goto fail_nofd;
2359 alarm(0);
2361 seconds = end_timer();
2363 printf("Parent got the lock after %.2f seconds.\n",
2364 seconds);
2366 status = cli_close(cli1, fnum);
2367 if (!NT_STATUS_IS_OK(status)) {
2368 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2369 goto fail;
2372 correct = true;
2374 fail:
2375 cli_close(cli1, fnum);
2376 torture_close_connection(cli1);
2378 fail_nofd:
2380 printf("finished locktest9\n");
2381 return correct;
2385 test whether fnums and tids open on one VC are available on another (a major
2386 security hole)
2388 static bool run_fdpasstest(int dummy)
2390 struct cli_state *cli1, *cli2;
2391 const char *fname = "\\fdpass.tst";
2392 uint16_t fnum1;
2393 char buf[1024];
2395 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2396 return False;
2398 cli_sockopt(cli1, sockops);
2399 cli_sockopt(cli2, sockops);
2401 printf("starting fdpasstest\n");
2403 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2405 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2406 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2407 return False;
2410 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2411 printf("write failed (%s)\n", cli_errstr(cli1));
2412 return False;
2415 cli2->vuid = cli1->vuid;
2416 cli2->cnum = cli1->cnum;
2417 cli2->pid = cli1->pid;
2419 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2420 printf("read succeeded! nasty security hole [%s]\n",
2421 buf);
2422 return False;
2425 cli_close(cli1, fnum1);
2426 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2428 torture_close_connection(cli1);
2429 torture_close_connection(cli2);
2431 printf("finished fdpasstest\n");
2432 return True;
2435 static bool run_fdsesstest(int dummy)
2437 struct cli_state *cli;
2438 uint16 new_vuid;
2439 uint16 saved_vuid;
2440 uint16 new_cnum;
2441 uint16 saved_cnum;
2442 const char *fname = "\\fdsess.tst";
2443 const char *fname1 = "\\fdsess1.tst";
2444 uint16_t fnum1;
2445 uint16_t fnum2;
2446 char buf[1024];
2447 bool ret = True;
2449 if (!torture_open_connection(&cli, 0))
2450 return False;
2451 cli_sockopt(cli, sockops);
2453 if (!torture_cli_session_setup2(cli, &new_vuid))
2454 return False;
2456 saved_cnum = cli->cnum;
2457 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2458 return False;
2459 new_cnum = cli->cnum;
2460 cli->cnum = saved_cnum;
2462 printf("starting fdsesstest\n");
2464 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2465 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2467 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2468 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2469 return False;
2472 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2473 printf("write failed (%s)\n", cli_errstr(cli));
2474 return False;
2477 saved_vuid = cli->vuid;
2478 cli->vuid = new_vuid;
2480 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2481 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2482 buf);
2483 ret = False;
2485 /* Try to open a file with different vuid, samba cnum. */
2486 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2487 printf("create with different vuid, same cnum succeeded.\n");
2488 cli_close(cli, fnum2);
2489 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2490 } else {
2491 printf("create with different vuid, same cnum failed.\n");
2492 printf("This will cause problems with service clients.\n");
2493 ret = False;
2496 cli->vuid = saved_vuid;
2498 /* Try with same vuid, different cnum. */
2499 cli->cnum = new_cnum;
2501 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2502 printf("read succeeded with different cnum![%s]\n",
2503 buf);
2504 ret = False;
2507 cli->cnum = saved_cnum;
2508 cli_close(cli, fnum1);
2509 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2511 torture_close_connection(cli);
2513 printf("finished fdsesstest\n");
2514 return ret;
2518 This test checks that
2520 1) the server does not allow an unlink on a file that is open
2522 static bool run_unlinktest(int dummy)
2524 struct cli_state *cli;
2525 const char *fname = "\\unlink.tst";
2526 uint16_t fnum;
2527 bool correct = True;
2529 if (!torture_open_connection(&cli, 0)) {
2530 return False;
2533 cli_sockopt(cli, sockops);
2535 printf("starting unlink test\n");
2537 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2539 cli_setpid(cli, 1);
2541 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2542 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2543 return False;
2546 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2547 printf("error: server allowed unlink on an open file\n");
2548 correct = False;
2549 } else {
2550 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2551 NT_STATUS_SHARING_VIOLATION);
2554 cli_close(cli, fnum);
2555 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2557 if (!torture_close_connection(cli)) {
2558 correct = False;
2561 printf("unlink test finished\n");
2563 return correct;
2568 test how many open files this server supports on the one socket
2570 static bool run_maxfidtest(int dummy)
2572 struct cli_state *cli;
2573 const char *ftemplate = "\\maxfid.%d.%d";
2574 fstring fname;
2575 uint16_t fnums[0x11000];
2576 int i;
2577 int retries=4;
2578 bool correct = True;
2580 cli = current_cli;
2582 if (retries <= 0) {
2583 printf("failed to connect\n");
2584 return False;
2587 cli_sockopt(cli, sockops);
2589 for (i=0; i<0x11000; i++) {
2590 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2591 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2592 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2593 printf("open of %s failed (%s)\n",
2594 fname, cli_errstr(cli));
2595 printf("maximum fnum is %d\n", i);
2596 break;
2598 printf("%6d\r", i);
2600 printf("%6d\n", i);
2601 i--;
2603 printf("cleaning up\n");
2604 for (;i>=0;i--) {
2605 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2606 cli_close(cli, fnums[i]);
2607 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2608 printf("unlink of %s failed (%s)\n",
2609 fname, cli_errstr(cli));
2610 correct = False;
2612 printf("%6d\r", i);
2614 printf("%6d\n", 0);
2616 printf("maxfid test finished\n");
2617 if (!torture_close_connection(cli)) {
2618 correct = False;
2620 return correct;
2623 /* generate a random buffer */
2624 static void rand_buf(char *buf, int len)
2626 while (len--) {
2627 *buf = (char)sys_random();
2628 buf++;
2632 /* send smb negprot commands, not reading the response */
2633 static bool run_negprot_nowait(int dummy)
2635 int i;
2636 static struct cli_state *cli;
2637 bool correct = True;
2639 printf("starting negprot nowait test\n");
2641 if (!(cli = open_nbt_connection())) {
2642 return False;
2645 for (i=0;i<50000;i++) {
2646 cli_negprot_sendsync(cli);
2649 if (!torture_close_connection(cli)) {
2650 correct = False;
2653 printf("finished negprot nowait test\n");
2655 return correct;
2659 /* send random IPC commands */
2660 static bool run_randomipc(int dummy)
2662 char *rparam = NULL;
2663 char *rdata = NULL;
2664 unsigned int rdrcnt,rprcnt;
2665 char param[1024];
2666 int api, param_len, i;
2667 struct cli_state *cli;
2668 bool correct = True;
2669 int count = 50000;
2671 printf("starting random ipc test\n");
2673 if (!torture_open_connection(&cli, 0)) {
2674 return False;
2677 for (i=0;i<count;i++) {
2678 api = sys_random() % 500;
2679 param_len = (sys_random() % 64);
2681 rand_buf(param, param_len);
2683 SSVAL(param,0,api);
2685 cli_api(cli,
2686 param, param_len, 8,
2687 NULL, 0, BUFFER_SIZE,
2688 &rparam, &rprcnt,
2689 &rdata, &rdrcnt);
2690 if (i % 100 == 0) {
2691 printf("%d/%d\r", i,count);
2694 printf("%d/%d\n", i, count);
2696 if (!torture_close_connection(cli)) {
2697 correct = False;
2700 printf("finished random ipc test\n");
2702 return correct;
2707 static void browse_callback(const char *sname, uint32 stype,
2708 const char *comment, void *state)
2710 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2716 This test checks the browse list code
2719 static bool run_browsetest(int dummy)
2721 static struct cli_state *cli;
2722 bool correct = True;
2724 printf("starting browse test\n");
2726 if (!torture_open_connection(&cli, 0)) {
2727 return False;
2730 printf("domain list:\n");
2731 cli_NetServerEnum(cli, cli->server_domain,
2732 SV_TYPE_DOMAIN_ENUM,
2733 browse_callback, NULL);
2735 printf("machine list:\n");
2736 cli_NetServerEnum(cli, cli->server_domain,
2737 SV_TYPE_ALL,
2738 browse_callback, NULL);
2740 if (!torture_close_connection(cli)) {
2741 correct = False;
2744 printf("browse test finished\n");
2746 return correct;
2752 This checks how the getatr calls works
2754 static bool run_attrtest(int dummy)
2756 struct cli_state *cli;
2757 uint16_t fnum;
2758 time_t t, t2;
2759 const char *fname = "\\attrib123456789.tst";
2760 bool correct = True;
2762 printf("starting attrib test\n");
2764 if (!torture_open_connection(&cli, 0)) {
2765 return False;
2768 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2769 cli_open(cli, fname,
2770 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2771 cli_close(cli, fnum);
2772 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2773 printf("getatr failed (%s)\n", cli_errstr(cli));
2774 correct = False;
2777 if (abs(t - time(NULL)) > 60*60*24*10) {
2778 printf("ERROR: SMBgetatr bug. time is %s",
2779 ctime(&t));
2780 t = time(NULL);
2781 correct = True;
2784 t2 = t-60*60*24; /* 1 day ago */
2786 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2787 printf("setatr failed (%s)\n", cli_errstr(cli));
2788 correct = True;
2791 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2792 printf("getatr failed (%s)\n", cli_errstr(cli));
2793 correct = True;
2796 if (t != t2) {
2797 printf("ERROR: getatr/setatr bug. times are\n%s",
2798 ctime(&t));
2799 printf("%s", ctime(&t2));
2800 correct = True;
2803 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2805 if (!torture_close_connection(cli)) {
2806 correct = False;
2809 printf("attrib test finished\n");
2811 return correct;
2816 This checks a couple of trans2 calls
2818 static bool run_trans2test(int dummy)
2820 struct cli_state *cli;
2821 uint16_t fnum;
2822 SMB_OFF_T size;
2823 time_t c_time, a_time, m_time;
2824 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2825 const char *fname = "\\trans2.tst";
2826 const char *dname = "\\trans2";
2827 const char *fname2 = "\\trans2\\trans2.tst";
2828 char pname[1024];
2829 bool correct = True;
2831 printf("starting trans2 test\n");
2833 if (!torture_open_connection(&cli, 0)) {
2834 return False;
2837 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2838 cli_open(cli, fname,
2839 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2840 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2841 &m_time_ts, NULL)) {
2842 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2843 correct = False;
2846 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2847 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2848 correct = False;
2851 if (strcmp(pname, fname)) {
2852 printf("qfilename gave different name? [%s] [%s]\n",
2853 fname, pname);
2854 correct = False;
2857 cli_close(cli, fnum);
2859 sleep(2);
2861 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2862 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2863 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2864 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2865 return False;
2867 cli_close(cli, fnum);
2869 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2870 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2871 correct = False;
2872 } else {
2873 if (c_time != m_time) {
2874 printf("create time=%s", ctime(&c_time));
2875 printf("modify time=%s", ctime(&m_time));
2876 printf("This system appears to have sticky create times\n");
2878 if (a_time % (60*60) == 0) {
2879 printf("access time=%s", ctime(&a_time));
2880 printf("This system appears to set a midnight access time\n");
2881 correct = False;
2884 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2885 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2886 correct = False;
2891 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2892 cli_open(cli, fname,
2893 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2894 cli_close(cli, fnum);
2895 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2896 &m_time_ts, &size, NULL, NULL)) {
2897 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2898 correct = False;
2899 } else {
2900 if (w_time_ts.tv_sec < 60*60*24*2) {
2901 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2902 printf("This system appears to set a initial 0 write time\n");
2903 correct = False;
2907 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2910 /* check if the server updates the directory modification time
2911 when creating a new file */
2912 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2913 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2914 correct = False;
2916 sleep(3);
2917 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2918 &m_time_ts, &size, NULL, NULL)) {
2919 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2920 correct = False;
2923 cli_open(cli, fname2,
2924 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2925 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2926 cli_close(cli, fnum);
2927 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2928 &m_time2_ts, &size, NULL, NULL)) {
2929 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2930 correct = False;
2931 } else {
2932 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2933 == 0) {
2934 printf("This system does not update directory modification times\n");
2935 correct = False;
2938 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2939 cli_rmdir(cli, dname);
2941 if (!torture_close_connection(cli)) {
2942 correct = False;
2945 printf("trans2 test finished\n");
2947 return correct;
2951 This checks new W2K calls.
2954 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2956 char *buf = NULL;
2957 uint32 len;
2958 bool correct = True;
2960 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2961 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2962 correct = False;
2963 } else {
2964 printf("qfileinfo: level %d, len = %u\n", level, len);
2965 dump_data(0, (uint8 *)buf, len);
2966 printf("\n");
2968 SAFE_FREE(buf);
2969 return correct;
2972 static bool run_w2ktest(int dummy)
2974 struct cli_state *cli;
2975 uint16_t fnum;
2976 const char *fname = "\\w2ktest\\w2k.tst";
2977 int level;
2978 bool correct = True;
2980 printf("starting w2k test\n");
2982 if (!torture_open_connection(&cli, 0)) {
2983 return False;
2986 cli_open(cli, fname,
2987 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2989 for (level = 1004; level < 1040; level++) {
2990 new_trans(cli, fnum, level);
2993 cli_close(cli, fnum);
2995 if (!torture_close_connection(cli)) {
2996 correct = False;
2999 printf("w2k test finished\n");
3001 return correct;
3006 this is a harness for some oplock tests
3008 static bool run_oplock1(int dummy)
3010 struct cli_state *cli1;
3011 const char *fname = "\\lockt1.lck";
3012 uint16_t fnum1;
3013 bool correct = True;
3015 printf("starting oplock test 1\n");
3017 if (!torture_open_connection(&cli1, 0)) {
3018 return False;
3021 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3023 cli_sockopt(cli1, sockops);
3025 cli1->use_oplocks = True;
3027 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3028 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3029 return False;
3032 cli1->use_oplocks = False;
3034 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3035 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3037 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3038 printf("close2 failed (%s)\n", cli_errstr(cli1));
3039 return False;
3042 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3043 printf("unlink failed (%s)\n", cli_errstr(cli1));
3044 return False;
3047 if (!torture_close_connection(cli1)) {
3048 correct = False;
3051 printf("finished oplock test 1\n");
3053 return correct;
3056 static bool run_oplock2(int dummy)
3058 struct cli_state *cli1, *cli2;
3059 const char *fname = "\\lockt2.lck";
3060 uint16_t fnum1, fnum2;
3061 int saved_use_oplocks = use_oplocks;
3062 char buf[4];
3063 bool correct = True;
3064 volatile bool *shared_correct;
3066 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3067 *shared_correct = True;
3069 use_level_II_oplocks = True;
3070 use_oplocks = True;
3072 printf("starting oplock test 2\n");
3074 if (!torture_open_connection(&cli1, 0)) {
3075 use_level_II_oplocks = False;
3076 use_oplocks = saved_use_oplocks;
3077 return False;
3080 cli1->use_oplocks = True;
3081 cli1->use_level_II_oplocks = True;
3083 if (!torture_open_connection(&cli2, 1)) {
3084 use_level_II_oplocks = False;
3085 use_oplocks = saved_use_oplocks;
3086 return False;
3089 cli2->use_oplocks = True;
3090 cli2->use_level_II_oplocks = True;
3092 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3094 cli_sockopt(cli1, sockops);
3095 cli_sockopt(cli2, sockops);
3097 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3098 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3099 return False;
3102 /* Don't need the globals any more. */
3103 use_level_II_oplocks = False;
3104 use_oplocks = saved_use_oplocks;
3106 if (fork() == 0) {
3107 /* Child code */
3108 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3109 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3110 *shared_correct = False;
3111 exit(0);
3114 sleep(2);
3116 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3117 printf("close2 failed (%s)\n", cli_errstr(cli1));
3118 *shared_correct = False;
3121 exit(0);
3124 sleep(2);
3126 /* Ensure cli1 processes the break. Empty file should always return 0
3127 * bytes. */
3129 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3130 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3131 correct = False;
3134 /* Should now be at level II. */
3135 /* Test if sending a write locks causes a break to none. */
3137 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3138 printf("lock failed (%s)\n", cli_errstr(cli1));
3139 correct = False;
3142 cli_unlock(cli1, fnum1, 0, 4);
3144 sleep(2);
3146 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3147 printf("lock failed (%s)\n", cli_errstr(cli1));
3148 correct = False;
3151 cli_unlock(cli1, fnum1, 0, 4);
3153 sleep(2);
3155 cli_read(cli1, fnum1, buf, 0, 4);
3157 #if 0
3158 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3159 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3160 correct = False;
3162 #endif
3164 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3165 printf("close1 failed (%s)\n", cli_errstr(cli1));
3166 correct = False;
3169 sleep(4);
3171 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3172 printf("unlink failed (%s)\n", cli_errstr(cli1));
3173 correct = False;
3176 if (!torture_close_connection(cli1)) {
3177 correct = False;
3180 if (!*shared_correct) {
3181 correct = False;
3184 printf("finished oplock test 2\n");
3186 return correct;
3189 /* handler for oplock 3 tests */
3190 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3192 printf("got oplock break fnum=%d level=%d\n",
3193 fnum, level);
3194 return cli_oplock_ack(cli, fnum, level);
3197 static bool run_oplock3(int dummy)
3199 struct cli_state *cli;
3200 const char *fname = "\\oplockt3.dat";
3201 uint16_t fnum;
3202 char buf[4] = "abcd";
3203 bool correct = True;
3204 volatile bool *shared_correct;
3206 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3207 *shared_correct = True;
3209 printf("starting oplock test 3\n");
3211 if (fork() == 0) {
3212 /* Child code */
3213 use_oplocks = True;
3214 use_level_II_oplocks = True;
3215 if (!torture_open_connection(&cli, 0)) {
3216 *shared_correct = False;
3217 exit(0);
3219 sleep(2);
3220 /* try to trigger a oplock break in parent */
3221 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3222 cli_write(cli, fnum, 0, buf, 0, 4);
3223 exit(0);
3226 /* parent code */
3227 use_oplocks = True;
3228 use_level_II_oplocks = True;
3229 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3230 return False;
3232 cli_oplock_handler(cli, oplock3_handler);
3233 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3234 cli_write(cli, fnum, 0, buf, 0, 4);
3235 cli_close(cli, fnum);
3236 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3237 cli->timeout = 20000;
3238 cli_receive_smb(cli);
3239 printf("finished oplock test 3\n");
3241 return (correct && *shared_correct);
3243 /* What are we looking for here? What's sucess and what's FAILURE? */
3249 Test delete on close semantics.
3251 static bool run_deletetest(int dummy)
3253 struct cli_state *cli1 = NULL;
3254 struct cli_state *cli2 = NULL;
3255 const char *fname = "\\delete.file";
3256 uint16_t fnum1 = (uint16_t)-1;
3257 uint16_t fnum2 = (uint16_t)-1;
3258 bool correct = True;
3260 printf("starting delete test\n");
3262 if (!torture_open_connection(&cli1, 0)) {
3263 return False;
3266 cli_sockopt(cli1, sockops);
3268 /* Test 1 - this should delete the file on close. */
3270 cli_setatr(cli1, fname, 0, 0);
3271 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3273 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3274 0, FILE_OVERWRITE_IF,
3275 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3276 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3277 correct = False;
3278 goto fail;
3281 #if 0 /* JRATEST */
3283 uint32 *accinfo = NULL;
3284 uint32 len;
3285 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3286 if (accinfo)
3287 printf("access mode = 0x%lx\n", *accinfo);
3288 SAFE_FREE(accinfo);
3290 #endif
3292 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3293 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3294 correct = False;
3295 goto fail;
3298 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3299 printf("[1] open of %s succeeded (should fail)\n", fname);
3300 correct = False;
3301 goto fail;
3304 printf("first delete on close test succeeded.\n");
3306 /* Test 2 - this should delete the file on close. */
3308 cli_setatr(cli1, fname, 0, 0);
3309 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3311 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3312 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3313 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3314 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3315 correct = False;
3316 goto fail;
3319 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3320 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3321 correct = False;
3322 goto fail;
3325 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3326 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3327 correct = False;
3328 goto fail;
3331 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3332 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3333 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3334 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3335 correct = False;
3336 goto fail;
3338 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3339 } else
3340 printf("second delete on close test succeeded.\n");
3342 /* Test 3 - ... */
3343 cli_setatr(cli1, fname, 0, 0);
3344 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3346 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3347 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3348 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3349 correct = False;
3350 goto fail;
3353 /* This should fail with a sharing violation - open for delete is only compatible
3354 with SHARE_DELETE. */
3356 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3357 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3358 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3359 correct = False;
3360 goto fail;
3363 /* This should succeed. */
3365 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3366 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3367 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3368 correct = False;
3369 goto fail;
3372 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3373 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3374 correct = False;
3375 goto fail;
3378 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3379 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3380 correct = False;
3381 goto fail;
3384 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3385 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3386 correct = False;
3387 goto fail;
3390 /* This should fail - file should no longer be there. */
3392 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3393 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3394 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3395 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3397 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3398 correct = False;
3399 goto fail;
3400 } else
3401 printf("third delete on close test succeeded.\n");
3403 /* Test 4 ... */
3404 cli_setatr(cli1, fname, 0, 0);
3405 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3407 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3408 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3409 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3410 correct = False;
3411 goto fail;
3414 /* This should succeed. */
3415 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3416 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3417 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3418 correct = False;
3419 goto fail;
3422 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3423 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3424 correct = False;
3425 goto fail;
3428 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3429 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3430 correct = False;
3431 goto fail;
3434 /* This should fail - no more opens once delete on close set. */
3435 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3436 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3437 FILE_OPEN, 0, 0, &fnum2))) {
3438 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3439 correct = False;
3440 goto fail;
3441 } else
3442 printf("fourth delete on close test succeeded.\n");
3444 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3445 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3446 correct = False;
3447 goto fail;
3450 /* Test 5 ... */
3451 cli_setatr(cli1, fname, 0, 0);
3452 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3454 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3455 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3456 correct = False;
3457 goto fail;
3460 /* This should fail - only allowed on NT opens with DELETE access. */
3462 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3463 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3464 correct = False;
3465 goto fail;
3468 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3469 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3470 correct = False;
3471 goto fail;
3474 printf("fifth delete on close test succeeded.\n");
3476 /* Test 6 ... */
3477 cli_setatr(cli1, fname, 0, 0);
3478 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3480 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3481 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3482 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3483 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3484 correct = False;
3485 goto fail;
3488 /* This should fail - only allowed on NT opens with DELETE access. */
3490 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3491 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3492 correct = False;
3493 goto fail;
3496 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3497 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3498 correct = False;
3499 goto fail;
3502 printf("sixth delete on close test succeeded.\n");
3504 /* Test 7 ... */
3505 cli_setatr(cli1, fname, 0, 0);
3506 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3508 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3509 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3510 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3511 correct = False;
3512 goto fail;
3515 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3516 printf("[7] setting delete_on_close on file failed !\n");
3517 correct = False;
3518 goto fail;
3521 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3522 printf("[7] unsetting delete_on_close on file failed !\n");
3523 correct = False;
3524 goto fail;
3527 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3528 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3529 correct = False;
3530 goto fail;
3533 /* This next open should succeed - we reset the flag. */
3535 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3536 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3537 correct = False;
3538 goto fail;
3541 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3542 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3543 correct = False;
3544 goto fail;
3547 printf("seventh delete on close test succeeded.\n");
3549 /* Test 7 ... */
3550 cli_setatr(cli1, fname, 0, 0);
3551 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3553 if (!torture_open_connection(&cli2, 1)) {
3554 printf("[8] failed to open second connection.\n");
3555 correct = False;
3556 goto fail;
3559 cli_sockopt(cli1, sockops);
3561 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3562 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3563 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3564 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3565 correct = False;
3566 goto fail;
3569 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3570 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3571 FILE_OPEN, 0, 0, &fnum2))) {
3572 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3573 correct = False;
3574 goto fail;
3577 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3578 printf("[8] setting delete_on_close on file failed !\n");
3579 correct = False;
3580 goto fail;
3583 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3584 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3585 correct = False;
3586 goto fail;
3589 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3590 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3591 correct = False;
3592 goto fail;
3595 /* This should fail.. */
3596 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3597 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3598 goto fail;
3599 correct = False;
3600 } else
3601 printf("eighth delete on close test succeeded.\n");
3603 /* This should fail - we need to set DELETE_ACCESS. */
3604 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3605 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3606 printf("[9] open of %s succeeded should have failed!\n", fname);
3607 correct = False;
3608 goto fail;
3611 printf("ninth delete on close test succeeded.\n");
3613 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3614 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3615 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3616 correct = False;
3617 goto fail;
3620 /* This should delete the file. */
3621 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3622 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3623 correct = False;
3624 goto fail;
3627 /* This should fail.. */
3628 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3629 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3630 goto fail;
3631 correct = False;
3632 } else
3633 printf("tenth delete on close test succeeded.\n");
3635 cli_setatr(cli1, fname, 0, 0);
3636 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3638 /* What error do we get when attempting to open a read-only file with
3639 delete access ? */
3641 /* Create a readonly file. */
3642 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3643 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3644 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3645 correct = False;
3646 goto fail;
3649 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3650 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3651 correct = False;
3652 goto fail;
3655 /* Now try open for delete access. */
3656 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3657 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3658 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3659 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3660 cli_close(cli1, fnum1);
3661 goto fail;
3662 correct = False;
3663 } else {
3664 NTSTATUS nterr = cli_nt_error(cli1);
3665 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3666 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3667 goto fail;
3668 correct = False;
3669 } else {
3670 printf("eleventh delete on close test succeeded.\n");
3674 printf("finished delete test\n");
3676 fail:
3677 /* FIXME: This will crash if we aborted before cli2 got
3678 * intialized, because these functions don't handle
3679 * uninitialized connections. */
3681 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3682 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3683 cli_setatr(cli1, fname, 0, 0);
3684 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3686 if (cli1 && !torture_close_connection(cli1)) {
3687 correct = False;
3689 if (cli2 && !torture_close_connection(cli2)) {
3690 correct = False;
3692 return correct;
3697 print out server properties
3699 static bool run_properties(int dummy)
3701 struct cli_state *cli;
3702 bool correct = True;
3704 printf("starting properties test\n");
3706 ZERO_STRUCT(cli);
3708 if (!torture_open_connection(&cli, 0)) {
3709 return False;
3712 cli_sockopt(cli, sockops);
3714 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3716 if (!torture_close_connection(cli)) {
3717 correct = False;
3720 return correct;
3725 /* FIRST_DESIRED_ACCESS 0xf019f */
3726 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3727 FILE_READ_EA| /* 0xf */ \
3728 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3729 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3730 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3731 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3732 /* SECOND_DESIRED_ACCESS 0xe0080 */
3733 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3734 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3735 WRITE_OWNER_ACCESS /* 0xe0000 */
3737 #if 0
3738 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3739 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3740 FILE_READ_DATA|\
3741 WRITE_OWNER_ACCESS /* */
3742 #endif
3745 Test ntcreate calls made by xcopy
3747 static bool run_xcopy(int dummy)
3749 static struct cli_state *cli1;
3750 const char *fname = "\\test.txt";
3751 bool correct = True;
3752 uint16_t fnum1, fnum2;
3754 printf("starting xcopy test\n");
3756 if (!torture_open_connection(&cli1, 0)) {
3757 return False;
3760 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3761 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3762 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3763 0x4044, 0, &fnum1))) {
3764 printf("First open failed - %s\n", cli_errstr(cli1));
3765 return False;
3768 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3769 SECOND_DESIRED_ACCESS, 0,
3770 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3771 0x200000, 0, &fnum2))) {
3772 printf("second open failed - %s\n", cli_errstr(cli1));
3773 return False;
3776 if (!torture_close_connection(cli1)) {
3777 correct = False;
3780 return correct;
3784 Test rename on files open with share delete and no share delete.
3786 static bool run_rename(int dummy)
3788 static struct cli_state *cli1;
3789 const char *fname = "\\test.txt";
3790 const char *fname1 = "\\test1.txt";
3791 bool correct = True;
3792 uint16_t fnum1;
3793 NTSTATUS status;
3795 printf("starting rename test\n");
3797 if (!torture_open_connection(&cli1, 0)) {
3798 return False;
3801 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3802 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3803 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3804 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3805 printf("First open failed - %s\n", cli_errstr(cli1));
3806 return False;
3809 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3810 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3811 } else {
3812 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3813 correct = False;
3816 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3817 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3818 return False;
3821 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3822 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3823 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3824 #if 0
3825 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3826 #else
3827 FILE_SHARE_DELETE|FILE_SHARE_READ,
3828 #endif
3829 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 printf("Second open failed - %s\n", cli_errstr(cli1));
3832 return False;
3835 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3836 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3837 correct = False;
3838 } else {
3839 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3842 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3843 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3844 return False;
3847 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3848 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3850 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3851 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3852 printf("Third open failed - %s\n", cli_errstr(cli1));
3853 return False;
3857 #if 0
3859 uint16_t fnum2;
3861 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3862 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3863 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3864 return False;
3866 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3867 printf("[8] setting delete_on_close on file failed !\n");
3868 return False;
3871 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3872 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3873 return False;
3876 #endif
3878 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3879 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3880 correct = False;
3881 } else {
3882 printf("Third rename succeeded (SHARE_NONE)\n");
3885 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3886 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3887 return False;
3890 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3891 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3893 /*----*/
3895 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3896 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3897 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3898 return False;
3901 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3902 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3903 } else {
3904 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3905 correct = False;
3908 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3909 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3910 return False;
3913 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3914 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3916 /*--*/
3918 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3919 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3920 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3921 return False;
3924 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3925 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3926 cli_errstr(cli1));
3927 correct = False;
3928 } else {
3929 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3933 * Now check if the first name still exists ...
3936 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3937 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3938 printf("Opening original file after rename of open file fails: %s\n",
3939 cli_errstr(cli1));
3941 else {
3942 printf("Opening original file after rename of open file works ...\n");
3943 (void)cli_close(cli1, fnum2);
3944 } */
3946 /*--*/
3949 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3950 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3951 return False;
3954 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3955 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3957 if (!torture_close_connection(cli1)) {
3958 correct = False;
3961 return correct;
3964 static bool run_pipe_number(int dummy)
3966 struct cli_state *cli1;
3967 const char *pipe_name = "\\SPOOLSS";
3968 uint16_t fnum;
3969 int num_pipes = 0;
3971 printf("starting pipenumber test\n");
3972 if (!torture_open_connection(&cli1, 0)) {
3973 return False;
3976 cli_sockopt(cli1, sockops);
3977 while(1) {
3978 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3979 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
3980 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3981 break;
3983 num_pipes++;
3984 printf("\r%6d", num_pipes);
3987 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3988 torture_close_connection(cli1);
3989 return True;
3993 Test open mode returns on read-only files.
3995 static bool run_opentest(int dummy)
3997 static struct cli_state *cli1;
3998 static struct cli_state *cli2;
3999 const char *fname = "\\readonly.file";
4000 uint16_t fnum1, fnum2;
4001 char buf[20];
4002 SMB_OFF_T fsize;
4003 bool correct = True;
4004 char *tmp_path;
4006 printf("starting open test\n");
4008 if (!torture_open_connection(&cli1, 0)) {
4009 return False;
4012 cli_setatr(cli1, fname, 0, 0);
4013 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4015 cli_sockopt(cli1, sockops);
4017 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4018 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4019 return False;
4022 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4023 printf("close2 failed (%s)\n", cli_errstr(cli1));
4024 return False;
4027 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4028 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4029 return False;
4032 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4033 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4034 return False;
4037 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4038 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4040 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4041 NT_STATUS_ACCESS_DENIED)) {
4042 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4045 printf("finished open test 1\n");
4047 cli_close(cli1, fnum1);
4049 /* Now try not readonly and ensure ERRbadshare is returned. */
4051 cli_setatr(cli1, fname, 0, 0);
4053 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4054 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4055 return False;
4058 /* This will fail - but the error should be ERRshare. */
4059 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4061 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4062 NT_STATUS_SHARING_VIOLATION)) {
4063 printf("correct error code ERRDOS/ERRbadshare returned\n");
4066 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4067 printf("close2 failed (%s)\n", cli_errstr(cli1));
4068 return False;
4071 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4073 printf("finished open test 2\n");
4075 /* Test truncate open disposition on file opened for read. */
4077 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4078 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4079 return False;
4082 /* write 20 bytes. */
4084 memset(buf, '\0', 20);
4086 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4087 printf("write failed (%s)\n", cli_errstr(cli1));
4088 correct = False;
4091 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4092 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4093 return False;
4096 /* Ensure size == 20. */
4097 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4098 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4099 return False;
4102 if (fsize != 20) {
4103 printf("(3) file size != 20\n");
4104 return False;
4107 /* Now test if we can truncate a file opened for readonly. */
4109 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4110 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4111 return False;
4114 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4115 printf("close2 failed (%s)\n", cli_errstr(cli1));
4116 return False;
4119 /* Ensure size == 0. */
4120 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4121 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4122 return False;
4125 if (fsize != 0) {
4126 printf("(3) file size != 0\n");
4127 return False;
4129 printf("finished open test 3\n");
4131 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4134 printf("testing ctemp\n");
4135 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4136 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4137 return False;
4139 printf("ctemp gave path %s\n", tmp_path);
4140 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4141 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4143 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4144 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4147 /* Test the non-io opens... */
4149 if (!torture_open_connection(&cli2, 1)) {
4150 return False;
4153 cli_setatr(cli2, fname, 0, 0);
4154 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4156 cli_sockopt(cli2, sockops);
4158 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4160 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4161 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4162 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4163 return False;
4166 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4167 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4168 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4169 return False;
4172 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4173 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4174 return False;
4176 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4177 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4178 return False;
4181 printf("non-io open test #1 passed.\n");
4183 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4185 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4187 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4188 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4189 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4190 return False;
4193 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4194 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4195 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4196 return False;
4199 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4200 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4201 return False;
4203 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4204 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4205 return False;
4208 printf("non-io open test #2 passed.\n");
4210 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4212 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4214 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4215 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4216 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4217 return False;
4220 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4221 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4222 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4223 return False;
4226 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4227 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4228 return False;
4230 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4231 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4232 return False;
4235 printf("non-io open test #3 passed.\n");
4237 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4239 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4241 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4242 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4243 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4244 return False;
4247 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4248 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4249 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4250 return False;
4253 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4255 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4256 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4257 return False;
4260 printf("non-io open test #4 passed.\n");
4262 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4264 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4266 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4267 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4268 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4269 return False;
4272 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4273 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4274 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4275 return False;
4278 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4279 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4280 return False;
4283 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4284 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4285 return False;
4288 printf("non-io open test #5 passed.\n");
4290 printf("TEST #6 testing 1 non-io open, one io open\n");
4292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4294 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4295 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4296 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4297 return False;
4300 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4301 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4302 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4303 return False;
4306 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4307 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4308 return False;
4311 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4312 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4313 return False;
4316 printf("non-io open test #6 passed.\n");
4318 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4320 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4322 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4323 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4324 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4325 return False;
4328 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4329 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4330 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4331 return False;
4334 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4336 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4337 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4338 return False;
4341 printf("non-io open test #7 passed.\n");
4343 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4345 if (!torture_close_connection(cli1)) {
4346 correct = False;
4348 if (!torture_close_connection(cli2)) {
4349 correct = False;
4352 return correct;
4356 Test POSIX open /mkdir calls.
4358 static bool run_simple_posix_open_test(int dummy)
4360 static struct cli_state *cli1;
4361 const char *fname = "posix:file";
4362 const char *hname = "posix:hlink";
4363 const char *sname = "posix:symlink";
4364 const char *dname = "posix:dir";
4365 char buf[10];
4366 char namebuf[11];
4367 uint16 major, minor;
4368 uint32 caplow, caphigh;
4369 uint16_t fnum1 = (uint16_t)-1;
4370 SMB_STRUCT_STAT sbuf;
4371 bool correct = false;
4372 NTSTATUS status;
4374 printf("Starting simple POSIX open test\n");
4376 if (!torture_open_connection(&cli1, 0)) {
4377 return false;
4380 cli_sockopt(cli1, sockops);
4382 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4383 printf("Server doesn't support UNIX CIFS extensions.\n");
4384 return false;
4387 status = cli_unix_extensions_version(cli1, &major, &minor, &caplow,
4388 &caphigh);
4389 if (!NT_STATUS_IS_OK(status)) {
4390 printf("Server didn't return UNIX CIFS extensions: %s\n",
4391 nt_errstr(status));
4392 return false;
4395 if (!cli_set_unix_extensions_capabilities(cli1,
4396 major, minor, caplow, caphigh)) {
4397 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4398 return false;
4401 cli_setatr(cli1, fname, 0, 0);
4402 cli_posix_unlink(cli1, fname);
4403 cli_setatr(cli1, dname, 0, 0);
4404 cli_posix_rmdir(cli1, dname);
4405 cli_setatr(cli1, hname, 0, 0);
4406 cli_posix_unlink(cli1, hname);
4407 cli_setatr(cli1, sname, 0, 0);
4408 cli_posix_unlink(cli1, sname);
4410 /* Create a directory. */
4411 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4412 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4413 goto out;
4416 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4417 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4418 goto out;
4421 /* Test ftruncate - set file size. */
4422 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4423 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4424 goto out;
4427 /* Ensure st_size == 1000 */
4428 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4429 printf("stat failed (%s)\n", cli_errstr(cli1));
4430 goto out;
4433 if (sbuf.st_ex_size != 1000) {
4434 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4435 goto out;
4438 /* Test ftruncate - set file size back to zero. */
4439 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4440 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4441 goto out;
4444 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4445 printf("close failed (%s)\n", cli_errstr(cli1));
4446 goto out;
4449 /* Now open the file again for read only. */
4450 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4451 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4452 goto out;
4455 /* Now unlink while open. */
4456 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4457 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4458 goto out;
4461 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4462 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4463 goto out;
4466 /* Ensure the file has gone. */
4467 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4468 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4469 goto out;
4472 /* What happens when we try and POSIX open a directory ? */
4473 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4474 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4475 goto out;
4476 } else {
4477 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4478 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4479 goto out;
4483 /* Create the file. */
4484 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4485 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4486 goto out;
4489 /* Write some data into it. */
4490 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4491 printf("cli_write failed: %s\n", cli_errstr(cli1));
4492 goto out;
4495 cli_close(cli1, fnum1);
4497 /* Now create a hardlink. */
4498 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4499 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4500 goto out;
4503 /* Now create a symlink. */
4504 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4505 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4506 goto out;
4509 /* Open the hardlink for read. */
4510 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4511 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4512 goto out;
4515 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4516 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4517 goto out;
4520 if (memcmp(buf, "TEST DATA\n", 10)) {
4521 printf("invalid data read from hardlink\n");
4522 goto out;
4525 /* Do a POSIX lock/unlock. */
4526 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4527 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4528 goto out;
4531 /* Punch a hole in the locked area. */
4532 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4533 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4534 goto out;
4537 cli_close(cli1, fnum1);
4539 /* Open the symlink for read - this should fail. A POSIX
4540 client should not be doing opens on a symlink. */
4541 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4542 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4543 goto out;
4544 } else {
4545 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4546 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4547 printf("POSIX open of %s should have failed "
4548 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4549 "failed with %s instead.\n",
4550 sname, cli_errstr(cli1));
4551 goto out;
4555 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4556 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4557 goto out;
4560 if (strcmp(namebuf, fname) != 0) {
4561 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4562 sname, fname, namebuf);
4563 goto out;
4566 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4567 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4568 goto out;
4571 printf("Simple POSIX open test passed\n");
4572 correct = true;
4574 out:
4576 if (fnum1 != (uint16_t)-1) {
4577 cli_close(cli1, fnum1);
4578 fnum1 = (uint16_t)-1;
4581 cli_setatr(cli1, sname, 0, 0);
4582 cli_posix_unlink(cli1, sname);
4583 cli_setatr(cli1, hname, 0, 0);
4584 cli_posix_unlink(cli1, hname);
4585 cli_setatr(cli1, fname, 0, 0);
4586 cli_posix_unlink(cli1, fname);
4587 cli_setatr(cli1, dname, 0, 0);
4588 cli_posix_rmdir(cli1, dname);
4590 if (!torture_close_connection(cli1)) {
4591 correct = false;
4594 return correct;
4598 static uint32 open_attrs_table[] = {
4599 FILE_ATTRIBUTE_NORMAL,
4600 FILE_ATTRIBUTE_ARCHIVE,
4601 FILE_ATTRIBUTE_READONLY,
4602 FILE_ATTRIBUTE_HIDDEN,
4603 FILE_ATTRIBUTE_SYSTEM,
4605 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4606 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4607 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4608 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4609 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4610 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4612 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4613 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4614 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4615 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4618 struct trunc_open_results {
4619 unsigned int num;
4620 uint32 init_attr;
4621 uint32 trunc_attr;
4622 uint32 result_attr;
4625 static struct trunc_open_results attr_results[] = {
4626 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4627 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4628 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4629 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4630 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4631 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4632 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4633 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4634 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4635 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4636 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4637 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4638 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4639 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4640 { 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 },
4641 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4642 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4643 { 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 },
4644 { 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 },
4645 { 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 },
4646 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4647 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4648 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4649 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4650 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4651 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4654 static bool run_openattrtest(int dummy)
4656 static struct cli_state *cli1;
4657 const char *fname = "\\openattr.file";
4658 uint16_t fnum1;
4659 bool correct = True;
4660 uint16 attr;
4661 unsigned int i, j, k, l;
4663 printf("starting open attr test\n");
4665 if (!torture_open_connection(&cli1, 0)) {
4666 return False;
4669 cli_sockopt(cli1, sockops);
4671 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4672 cli_setatr(cli1, fname, 0, 0);
4673 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4675 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4676 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4677 return False;
4680 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4681 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4682 return False;
4685 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4686 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4687 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4688 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4689 if (attr_results[l].num == k) {
4690 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4691 k, open_attrs_table[i],
4692 open_attrs_table[j],
4693 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4694 correct = False;
4697 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4698 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4699 k, open_attrs_table[i], open_attrs_table[j],
4700 cli_errstr(cli1));
4701 correct = False;
4703 #if 0
4704 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4705 #endif
4706 k++;
4707 continue;
4710 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4711 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4712 return False;
4715 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4716 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4717 return False;
4720 #if 0
4721 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4722 k, open_attrs_table[i], open_attrs_table[j], attr );
4723 #endif
4725 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4726 if (attr_results[l].num == k) {
4727 if (attr != attr_results[l].result_attr ||
4728 open_attrs_table[i] != attr_results[l].init_attr ||
4729 open_attrs_table[j] != attr_results[l].trunc_attr) {
4730 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4731 open_attrs_table[i],
4732 open_attrs_table[j],
4733 (unsigned int)attr,
4734 attr_results[l].result_attr);
4735 correct = False;
4737 break;
4740 k++;
4744 cli_setatr(cli1, fname, 0, 0);
4745 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4747 printf("open attr test %s.\n", correct ? "passed" : "failed");
4749 if (!torture_close_connection(cli1)) {
4750 correct = False;
4752 return correct;
4755 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4761 test directory listing speed
4763 static bool run_dirtest(int dummy)
4765 int i;
4766 static struct cli_state *cli;
4767 uint16_t fnum;
4768 double t1;
4769 bool correct = True;
4771 printf("starting directory test\n");
4773 if (!torture_open_connection(&cli, 0)) {
4774 return False;
4777 cli_sockopt(cli, sockops);
4779 srandom(0);
4780 for (i=0;i<torture_numops;i++) {
4781 fstring fname;
4782 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4783 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4784 fprintf(stderr,"Failed to open %s\n", fname);
4785 return False;
4787 cli_close(cli, fnum);
4790 t1 = end_timer();
4792 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4793 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4794 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4796 printf("dirtest core %g seconds\n", end_timer() - t1);
4798 srandom(0);
4799 for (i=0;i<torture_numops;i++) {
4800 fstring fname;
4801 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4802 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4805 if (!torture_close_connection(cli)) {
4806 correct = False;
4809 printf("finished dirtest\n");
4811 return correct;
4814 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4816 struct cli_state *pcli = (struct cli_state *)state;
4817 fstring fname;
4818 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4820 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4821 return;
4823 if (finfo->mode & aDIR) {
4824 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4825 printf("del_fn: failed to rmdir %s\n,", fname );
4826 } else {
4827 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4828 printf("del_fn: failed to unlink %s\n,", fname );
4834 sees what IOCTLs are supported
4836 bool torture_ioctl_test(int dummy)
4838 static struct cli_state *cli;
4839 uint16_t device, function;
4840 uint16_t fnum;
4841 const char *fname = "\\ioctl.dat";
4842 DATA_BLOB blob;
4843 NTSTATUS status;
4845 if (!torture_open_connection(&cli, 0)) {
4846 return False;
4849 printf("starting ioctl test\n");
4851 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4853 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4854 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4855 return False;
4858 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4859 printf("ioctl device info: %s\n", cli_errstr(cli));
4861 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4862 printf("ioctl job info: %s\n", cli_errstr(cli));
4864 for (device=0;device<0x100;device++) {
4865 printf("testing device=0x%x\n", device);
4866 for (function=0;function<0x100;function++) {
4867 uint32 code = (device<<16) | function;
4869 status = cli_raw_ioctl(cli, fnum, code, &blob);
4871 if (NT_STATUS_IS_OK(status)) {
4872 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4873 (int)blob.length);
4874 data_blob_free(&blob);
4879 if (!torture_close_connection(cli)) {
4880 return False;
4883 return True;
4888 tries varients of chkpath
4890 bool torture_chkpath_test(int dummy)
4892 static struct cli_state *cli;
4893 uint16_t fnum;
4894 bool ret;
4896 if (!torture_open_connection(&cli, 0)) {
4897 return False;
4900 printf("starting chkpath test\n");
4902 /* cleanup from an old run */
4903 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4904 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4905 cli_rmdir(cli, "\\chkpath.dir");
4907 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4908 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4909 return False;
4912 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4913 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4914 return False;
4917 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4918 printf("open1 failed (%s)\n", cli_errstr(cli));
4919 return False;
4921 cli_close(cli, fnum);
4923 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4924 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4925 ret = False;
4928 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4929 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4930 ret = False;
4933 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4934 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4935 NT_STATUS_NOT_A_DIRECTORY);
4936 } else {
4937 printf("* chkpath on a file should fail\n");
4938 ret = False;
4941 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4942 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4943 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4944 } else {
4945 printf("* chkpath on a non existant file should fail\n");
4946 ret = False;
4949 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4950 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4951 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4952 } else {
4953 printf("* chkpath on a non existent component should fail\n");
4954 ret = False;
4957 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4958 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4959 cli_rmdir(cli, "\\chkpath.dir");
4961 if (!torture_close_connection(cli)) {
4962 return False;
4965 return ret;
4968 static bool run_eatest(int dummy)
4970 static struct cli_state *cli;
4971 const char *fname = "\\eatest.txt";
4972 bool correct = True;
4973 uint16_t fnum;
4974 int i;
4975 size_t num_eas;
4976 struct ea_struct *ea_list = NULL;
4977 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4979 printf("starting eatest\n");
4981 if (!torture_open_connection(&cli, 0)) {
4982 talloc_destroy(mem_ctx);
4983 return False;
4986 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4987 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
4988 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4989 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4990 0x4044, 0, &fnum))) {
4991 printf("open failed - %s\n", cli_errstr(cli));
4992 talloc_destroy(mem_ctx);
4993 return False;
4996 for (i = 0; i < 10; i++) {
4997 fstring ea_name, ea_val;
4999 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5000 memset(ea_val, (char)i+1, i+1);
5001 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5002 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5003 talloc_destroy(mem_ctx);
5004 return False;
5008 cli_close(cli, fnum);
5009 for (i = 0; i < 10; i++) {
5010 fstring ea_name, ea_val;
5012 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5013 memset(ea_val, (char)i+1, i+1);
5014 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5015 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5016 talloc_destroy(mem_ctx);
5017 return False;
5021 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5022 printf("ea_get list failed - %s\n", cli_errstr(cli));
5023 correct = False;
5026 printf("num_eas = %d\n", (int)num_eas);
5028 if (num_eas != 20) {
5029 printf("Should be 20 EA's stored... failing.\n");
5030 correct = False;
5033 for (i = 0; i < num_eas; i++) {
5034 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5035 dump_data(0, ea_list[i].value.data,
5036 ea_list[i].value.length);
5039 /* Setting EA's to zero length deletes them. Test this */
5040 printf("Now deleting all EA's - case indepenent....\n");
5042 #if 1
5043 cli_set_ea_path(cli, fname, "", "", 0);
5044 #else
5045 for (i = 0; i < 20; i++) {
5046 fstring ea_name;
5047 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5048 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5049 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5050 talloc_destroy(mem_ctx);
5051 return False;
5054 #endif
5056 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5057 printf("ea_get list failed - %s\n", cli_errstr(cli));
5058 correct = False;
5061 printf("num_eas = %d\n", (int)num_eas);
5062 for (i = 0; i < num_eas; i++) {
5063 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5064 dump_data(0, ea_list[i].value.data,
5065 ea_list[i].value.length);
5068 if (num_eas != 0) {
5069 printf("deleting EA's failed.\n");
5070 correct = False;
5073 /* Try and delete a non existant EA. */
5074 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5075 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5076 correct = False;
5079 talloc_destroy(mem_ctx);
5080 if (!torture_close_connection(cli)) {
5081 correct = False;
5084 return correct;
5087 static bool run_dirtest1(int dummy)
5089 int i;
5090 static struct cli_state *cli;
5091 uint16_t fnum;
5092 int num_seen;
5093 bool correct = True;
5095 printf("starting directory test\n");
5097 if (!torture_open_connection(&cli, 0)) {
5098 return False;
5101 cli_sockopt(cli, sockops);
5103 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5104 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5105 cli_rmdir(cli, "\\LISTDIR");
5106 cli_mkdir(cli, "\\LISTDIR");
5108 /* Create 1000 files and 1000 directories. */
5109 for (i=0;i<1000;i++) {
5110 fstring fname;
5111 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5112 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5113 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5114 fprintf(stderr,"Failed to open %s\n", fname);
5115 return False;
5117 cli_close(cli, fnum);
5119 for (i=0;i<1000;i++) {
5120 fstring fname;
5121 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5122 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5123 fprintf(stderr,"Failed to open %s\n", fname);
5124 return False;
5128 /* Now ensure that doing an old list sees both files and directories. */
5129 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5130 printf("num_seen = %d\n", num_seen );
5131 /* We should see 100 files + 1000 directories + . and .. */
5132 if (num_seen != 2002)
5133 correct = False;
5135 /* Ensure if we have the "must have" bits we only see the
5136 * relevent entries.
5138 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5139 printf("num_seen = %d\n", num_seen );
5140 if (num_seen != 1002)
5141 correct = False;
5143 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5144 printf("num_seen = %d\n", num_seen );
5145 if (num_seen != 1000)
5146 correct = False;
5148 /* Delete everything. */
5149 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5150 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5151 cli_rmdir(cli, "\\LISTDIR");
5153 #if 0
5154 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5155 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5156 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5157 #endif
5159 if (!torture_close_connection(cli)) {
5160 correct = False;
5163 printf("finished dirtest1\n");
5165 return correct;
5168 static bool run_error_map_extract(int dummy) {
5170 static struct cli_state *c_dos;
5171 static struct cli_state *c_nt;
5172 NTSTATUS status;
5174 uint32 error;
5176 uint32 flgs2, errnum;
5177 uint8 errclass;
5179 NTSTATUS nt_status;
5181 fstring user;
5183 /* NT-Error connection */
5185 if (!(c_nt = open_nbt_connection())) {
5186 return False;
5189 c_nt->use_spnego = False;
5191 status = cli_negprot(c_nt);
5193 if (!NT_STATUS_IS_OK(status)) {
5194 printf("%s rejected the NT-error negprot (%s)\n", host,
5195 nt_errstr(status));
5196 cli_shutdown(c_nt);
5197 return False;
5200 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5201 workgroup))) {
5202 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5203 return False;
5206 /* DOS-Error connection */
5208 if (!(c_dos = open_nbt_connection())) {
5209 return False;
5212 c_dos->use_spnego = False;
5213 c_dos->force_dos_errors = True;
5215 status = cli_negprot(c_dos);
5216 if (!NT_STATUS_IS_OK(status)) {
5217 printf("%s rejected the DOS-error negprot (%s)\n", host,
5218 nt_errstr(status));
5219 cli_shutdown(c_dos);
5220 return False;
5223 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5224 workgroup))) {
5225 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5226 return False;
5229 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5230 fstr_sprintf(user, "%X", error);
5232 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5233 password, strlen(password),
5234 password, strlen(password),
5235 workgroup))) {
5236 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5239 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5241 /* Case #1: 32-bit NT errors */
5242 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5243 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5244 } else {
5245 printf("/** Dos error on NT connection! (%s) */\n",
5246 cli_errstr(c_nt));
5247 nt_status = NT_STATUS(0xc0000000);
5250 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5251 password, strlen(password),
5252 password, strlen(password),
5253 workgroup))) {
5254 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5256 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5258 /* Case #1: 32-bit NT errors */
5259 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5260 printf("/** NT error on DOS connection! (%s) */\n",
5261 cli_errstr(c_nt));
5262 errnum = errclass = 0;
5263 } else {
5264 cli_dos_error(c_dos, &errclass, &errnum);
5267 if (NT_STATUS_V(nt_status) != error) {
5268 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5269 get_nt_error_c_code(NT_STATUS(error)),
5270 get_nt_error_c_code(nt_status));
5273 printf("\t{%s,\t%s,\t%s},\n",
5274 smb_dos_err_class(errclass),
5275 smb_dos_err_name(errclass, errnum),
5276 get_nt_error_c_code(NT_STATUS(error)));
5278 return True;
5281 static bool run_sesssetup_bench(int dummy)
5283 static struct cli_state *c;
5284 const char *fname = "\\file.dat";
5285 uint16_t fnum;
5286 NTSTATUS status;
5287 int i;
5289 if (!torture_open_connection(&c, 0)) {
5290 return false;
5293 if (!NT_STATUS_IS_OK(cli_ntcreate(
5294 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5295 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5296 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5297 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5298 return false;
5301 for (i=0; i<torture_numops; i++) {
5302 status = cli_session_setup(
5303 c, username,
5304 password, strlen(password),
5305 password, strlen(password),
5306 workgroup);
5307 if (!NT_STATUS_IS_OK(status)) {
5308 d_printf("(%s) cli_session_setup failed: %s\n",
5309 __location__, nt_errstr(status));
5310 return false;
5313 d_printf("\r%d ", (int)c->vuid);
5315 if (!cli_ulogoff(c)) {
5316 d_printf("(%s) cli_ulogoff failed: %s\n",
5317 __location__, cli_errstr(c));
5318 return false;
5320 c->vuid = 0;
5323 return true;
5326 static bool subst_test(const char *str, const char *user, const char *domain,
5327 uid_t uid, gid_t gid, const char *expected)
5329 char *subst;
5330 bool result = true;
5332 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5334 if (strcmp(subst, expected) != 0) {
5335 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5336 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5337 expected);
5338 result = false;
5341 TALLOC_FREE(subst);
5342 return result;
5345 static void chain1_open_completion(struct tevent_req *req)
5347 uint16_t fnum;
5348 NTSTATUS status;
5349 status = cli_open_recv(req, &fnum);
5350 TALLOC_FREE(req);
5352 d_printf("cli_open_recv returned %s: %d\n",
5353 nt_errstr(status),
5354 NT_STATUS_IS_OK(status) ? fnum : -1);
5357 static void chain1_write_completion(struct tevent_req *req)
5359 size_t written;
5360 NTSTATUS status;
5361 status = cli_write_andx_recv(req, &written);
5362 TALLOC_FREE(req);
5364 d_printf("cli_write_andx_recv returned %s: %d\n",
5365 nt_errstr(status),
5366 NT_STATUS_IS_OK(status) ? (int)written : -1);
5369 static void chain1_close_completion(struct tevent_req *req)
5371 NTSTATUS status;
5372 bool *done = (bool *)tevent_req_callback_data_void(req);
5374 status = cli_close_recv(req);
5375 *done = true;
5377 TALLOC_FREE(req);
5379 d_printf("cli_close returned %s\n", nt_errstr(status));
5382 static bool run_chain1(int dummy)
5384 struct cli_state *cli1;
5385 struct event_context *evt = event_context_init(NULL);
5386 struct tevent_req *reqs[3], *smbreqs[3];
5387 bool done = false;
5388 const char *str = "foobar";
5389 NTSTATUS status;
5391 printf("starting chain1 test\n");
5392 if (!torture_open_connection(&cli1, 0)) {
5393 return False;
5396 cli_sockopt(cli1, sockops);
5398 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5399 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5400 if (reqs[0] == NULL) return false;
5401 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5404 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5405 (uint8_t *)str, 0, strlen(str)+1,
5406 smbreqs, 1, &smbreqs[1]);
5407 if (reqs[1] == NULL) return false;
5408 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5410 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5411 if (reqs[2] == NULL) return false;
5412 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5414 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5415 if (!NT_STATUS_IS_OK(status)) {
5416 return false;
5419 while (!done) {
5420 event_loop_once(evt);
5423 torture_close_connection(cli1);
5424 return True;
5427 static void chain2_sesssetup_completion(struct tevent_req *req)
5429 NTSTATUS status;
5430 status = cli_session_setup_guest_recv(req);
5431 d_printf("sesssetup returned %s\n", nt_errstr(status));
5434 static void chain2_tcon_completion(struct tevent_req *req)
5436 bool *done = (bool *)tevent_req_callback_data_void(req);
5437 NTSTATUS status;
5438 status = cli_tcon_andx_recv(req);
5439 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5440 *done = true;
5443 static bool run_chain2(int dummy)
5445 struct cli_state *cli1;
5446 struct event_context *evt = event_context_init(NULL);
5447 struct tevent_req *reqs[2], *smbreqs[2];
5448 bool done = false;
5449 NTSTATUS status;
5451 printf("starting chain2 test\n");
5452 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5453 port_to_use, Undefined, 0, NULL);
5454 if (!NT_STATUS_IS_OK(status)) {
5455 return False;
5458 cli_sockopt(cli1, sockops);
5460 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5461 &smbreqs[0]);
5462 if (reqs[0] == NULL) return false;
5463 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5465 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5466 "?????", NULL, 0, &smbreqs[1]);
5467 if (reqs[1] == NULL) return false;
5468 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5470 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5471 if (!NT_STATUS_IS_OK(status)) {
5472 return false;
5475 while (!done) {
5476 event_loop_once(evt);
5479 torture_close_connection(cli1);
5480 return True;
5484 struct torture_createdel_state {
5485 struct tevent_context *ev;
5486 struct cli_state *cli;
5489 static void torture_createdel_created(struct tevent_req *subreq);
5490 static void torture_createdel_closed(struct tevent_req *subreq);
5492 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5493 struct tevent_context *ev,
5494 struct cli_state *cli,
5495 const char *name)
5497 struct tevent_req *req, *subreq;
5498 struct torture_createdel_state *state;
5500 req = tevent_req_create(mem_ctx, &state,
5501 struct torture_createdel_state);
5502 if (req == NULL) {
5503 return NULL;
5505 state->ev = ev;
5506 state->cli = cli;
5508 subreq = cli_ntcreate_send(
5509 state, ev, cli, name, 0,
5510 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5511 FILE_ATTRIBUTE_NORMAL,
5512 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5513 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5515 if (tevent_req_nomem(subreq, req)) {
5516 return tevent_req_post(req, ev);
5518 tevent_req_set_callback(subreq, torture_createdel_created, req);
5519 return req;
5522 static void torture_createdel_created(struct tevent_req *subreq)
5524 struct tevent_req *req = tevent_req_callback_data(
5525 subreq, struct tevent_req);
5526 struct torture_createdel_state *state = tevent_req_data(
5527 req, struct torture_createdel_state);
5528 NTSTATUS status;
5529 uint16_t fnum;
5531 status = cli_ntcreate_recv(subreq, &fnum);
5532 TALLOC_FREE(subreq);
5533 if (!NT_STATUS_IS_OK(status)) {
5534 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5535 nt_errstr(status)));
5536 tevent_req_nterror(req, status);
5537 return;
5540 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5541 if (tevent_req_nomem(subreq, req)) {
5542 return;
5544 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5547 static void torture_createdel_closed(struct tevent_req *subreq)
5549 struct tevent_req *req = tevent_req_callback_data(
5550 subreq, struct tevent_req);
5551 NTSTATUS status;
5553 status = cli_close_recv(subreq);
5554 if (!NT_STATUS_IS_OK(status)) {
5555 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5556 tevent_req_nterror(req, status);
5557 return;
5559 tevent_req_done(req);
5562 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5564 return tevent_req_simple_recv_ntstatus(req);
5567 struct torture_createdels_state {
5568 struct tevent_context *ev;
5569 struct cli_state *cli;
5570 const char *base_name;
5571 int sent;
5572 int received;
5573 int num_files;
5574 struct tevent_req **reqs;
5577 static void torture_createdels_done(struct tevent_req *subreq);
5579 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5580 struct tevent_context *ev,
5581 struct cli_state *cli,
5582 const char *base_name,
5583 int num_parallel,
5584 int num_files)
5586 struct tevent_req *req;
5587 struct torture_createdels_state *state;
5588 int i;
5590 req = tevent_req_create(mem_ctx, &state,
5591 struct torture_createdels_state);
5592 if (req == NULL) {
5593 return NULL;
5595 state->ev = ev;
5596 state->cli = cli;
5597 state->base_name = talloc_strdup(state, base_name);
5598 if (tevent_req_nomem(state->base_name, req)) {
5599 return tevent_req_post(req, ev);
5601 state->num_files = MAX(num_parallel, num_files);
5602 state->sent = 0;
5603 state->received = 0;
5605 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5606 if (tevent_req_nomem(state->reqs, req)) {
5607 return tevent_req_post(req, ev);
5610 for (i=0; i<num_parallel; i++) {
5611 char *name;
5613 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5614 state->sent);
5615 if (tevent_req_nomem(name, req)) {
5616 return tevent_req_post(req, ev);
5618 state->reqs[i] = torture_createdel_send(
5619 state->reqs, state->ev, state->cli, name);
5620 if (tevent_req_nomem(state->reqs[i], req)) {
5621 return tevent_req_post(req, ev);
5623 name = talloc_move(state->reqs[i], &name);
5624 tevent_req_set_callback(state->reqs[i],
5625 torture_createdels_done, req);
5626 state->sent += 1;
5628 return req;
5631 static void torture_createdels_done(struct tevent_req *subreq)
5633 struct tevent_req *req = tevent_req_callback_data(
5634 subreq, struct tevent_req);
5635 struct torture_createdels_state *state = tevent_req_data(
5636 req, struct torture_createdels_state);
5637 size_t num_parallel = talloc_array_length(state->reqs);
5638 NTSTATUS status;
5639 char *name;
5640 int i;
5642 status = torture_createdel_recv(subreq);
5643 if (!NT_STATUS_IS_OK(status)){
5644 DEBUG(10, ("torture_createdel_recv returned %s\n",
5645 nt_errstr(status)));
5646 TALLOC_FREE(subreq);
5647 tevent_req_nterror(req, status);
5648 return;
5651 for (i=0; i<num_parallel; i++) {
5652 if (subreq == state->reqs[i]) {
5653 break;
5656 if (i == num_parallel) {
5657 DEBUG(10, ("received something we did not send\n"));
5658 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5659 return;
5661 TALLOC_FREE(state->reqs[i]);
5663 if (state->sent >= state->num_files) {
5664 tevent_req_done(req);
5665 return;
5668 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5669 state->sent);
5670 if (tevent_req_nomem(name, req)) {
5671 return;
5673 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5674 state->cli, name);
5675 if (tevent_req_nomem(state->reqs[i], req)) {
5676 return;
5678 name = talloc_move(state->reqs[i], &name);
5679 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5680 state->sent += 1;
5683 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5685 return tevent_req_simple_recv_ntstatus(req);
5688 struct swallow_notify_state {
5689 struct tevent_context *ev;
5690 struct cli_state *cli;
5691 uint16_t fnum;
5692 uint32_t completion_filter;
5693 bool recursive;
5694 bool (*fn)(uint32_t action, const char *name, void *priv);
5695 void *priv;
5698 static void swallow_notify_done(struct tevent_req *subreq);
5700 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5701 struct tevent_context *ev,
5702 struct cli_state *cli,
5703 uint16_t fnum,
5704 uint32_t completion_filter,
5705 bool recursive,
5706 bool (*fn)(uint32_t action,
5707 const char *name,
5708 void *priv),
5709 void *priv)
5711 struct tevent_req *req, *subreq;
5712 struct swallow_notify_state *state;
5714 req = tevent_req_create(mem_ctx, &state,
5715 struct swallow_notify_state);
5716 if (req == NULL) {
5717 return NULL;
5719 state->ev = ev;
5720 state->cli = cli;
5721 state->fnum = fnum;
5722 state->completion_filter = completion_filter;
5723 state->recursive = recursive;
5724 state->fn = fn;
5725 state->priv = priv;
5727 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5728 0xffff, state->completion_filter,
5729 state->recursive);
5730 if (tevent_req_nomem(subreq, req)) {
5731 return tevent_req_post(req, ev);
5733 tevent_req_set_callback(subreq, swallow_notify_done, req);
5734 return req;
5737 static void swallow_notify_done(struct tevent_req *subreq)
5739 struct tevent_req *req = tevent_req_callback_data(
5740 subreq, struct tevent_req);
5741 struct swallow_notify_state *state = tevent_req_data(
5742 req, struct swallow_notify_state);
5743 NTSTATUS status;
5744 uint32_t i, num_changes;
5745 struct notify_change *changes;
5747 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5748 TALLOC_FREE(subreq);
5749 if (!NT_STATUS_IS_OK(status)) {
5750 DEBUG(10, ("cli_notify_recv returned %s\n",
5751 nt_errstr(status)));
5752 tevent_req_nterror(req, status);
5753 return;
5756 for (i=0; i<num_changes; i++) {
5757 state->fn(changes[i].action, changes[i].name, state->priv);
5759 TALLOC_FREE(changes);
5761 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5762 0xffff, state->completion_filter,
5763 state->recursive);
5764 if (tevent_req_nomem(subreq, req)) {
5765 return;
5767 tevent_req_set_callback(subreq, swallow_notify_done, req);
5770 static bool print_notifies(uint32_t action, const char *name, void *priv)
5772 if (DEBUGLEVEL > 5) {
5773 d_printf("%d %s\n", (int)action, name);
5775 return true;
5778 static void notify_bench_done(struct tevent_req *req)
5780 int *num_finished = (int *)tevent_req_callback_data_void(req);
5781 *num_finished += 1;
5784 static bool run_notify_bench(int dummy)
5786 const char *dname = "\\notify-bench";
5787 struct tevent_context *ev;
5788 NTSTATUS status;
5789 uint16_t dnum;
5790 struct tevent_req *req1, *req2;
5791 int i, num_unc_names;
5792 int num_finished = 0;
5794 printf("starting notify-bench test\n");
5796 if (use_multishare_conn) {
5797 char **unc_list;
5798 unc_list = file_lines_load(multishare_conn_fname,
5799 &num_unc_names, 0, NULL);
5800 if (!unc_list || num_unc_names <= 0) {
5801 d_printf("Failed to load unc names list from '%s'\n",
5802 multishare_conn_fname);
5803 return false;
5805 TALLOC_FREE(unc_list);
5806 } else {
5807 num_unc_names = 1;
5810 ev = tevent_context_init(talloc_tos());
5811 if (ev == NULL) {
5812 d_printf("tevent_context_init failed\n");
5813 return false;
5816 for (i=0; i<num_unc_names; i++) {
5817 struct cli_state *cli;
5818 char *base_fname;
5820 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5821 dname, i);
5822 if (base_fname == NULL) {
5823 return false;
5826 if (!torture_open_connection(&cli, i)) {
5827 return false;
5830 status = cli_ntcreate(cli, dname, 0,
5831 MAXIMUM_ALLOWED_ACCESS,
5832 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5833 FILE_SHARE_DELETE,
5834 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5835 &dnum);
5837 if (!NT_STATUS_IS_OK(status)) {
5838 d_printf("Could not create %s: %s\n", dname,
5839 nt_errstr(status));
5840 return false;
5843 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5844 FILE_NOTIFY_CHANGE_FILE_NAME |
5845 FILE_NOTIFY_CHANGE_DIR_NAME |
5846 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5847 FILE_NOTIFY_CHANGE_LAST_WRITE,
5848 false, print_notifies, NULL);
5849 if (req1 == NULL) {
5850 d_printf("Could not create notify request\n");
5851 return false;
5854 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5855 base_fname, 10, torture_numops);
5856 if (req2 == NULL) {
5857 d_printf("Could not create createdels request\n");
5858 return false;
5860 TALLOC_FREE(base_fname);
5862 tevent_req_set_callback(req2, notify_bench_done,
5863 &num_finished);
5866 while (num_finished < num_unc_names) {
5867 int ret;
5868 ret = tevent_loop_once(ev);
5869 if (ret != 0) {
5870 d_printf("tevent_loop_once failed\n");
5871 return false;
5875 if (!tevent_req_poll(req2, ev)) {
5876 d_printf("tevent_req_poll failed\n");
5879 status = torture_createdels_recv(req2);
5880 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5882 return true;
5885 static bool run_mangle1(int dummy)
5887 struct cli_state *cli;
5888 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5889 uint16_t fnum;
5890 fstring alt_name;
5891 NTSTATUS status;
5892 time_t change_time, access_time, write_time;
5893 SMB_OFF_T size;
5894 uint16_t mode;
5896 printf("starting mangle1 test\n");
5897 if (!torture_open_connection(&cli, 0)) {
5898 return False;
5901 cli_sockopt(cli, sockops);
5903 if (!NT_STATUS_IS_OK(cli_ntcreate(
5904 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5905 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5906 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5907 return false;
5909 cli_close(cli, fnum);
5911 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5912 if (!NT_STATUS_IS_OK(status)) {
5913 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5914 nt_errstr(status));
5915 return false;
5917 d_printf("alt_name: %s\n", alt_name);
5919 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5920 d_printf("cli_open(%s) failed: %s\n", alt_name,
5921 cli_errstr(cli));
5922 return false;
5924 cli_close(cli, fnum);
5926 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5927 &write_time, &size, &mode)) {
5928 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5929 cli_errstr(cli));
5930 return false;
5933 return true;
5936 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5938 size_t *to_pull = (size_t *)priv;
5939 size_t thistime = *to_pull;
5941 thistime = MIN(thistime, n);
5942 if (thistime == 0) {
5943 return 0;
5946 memset(buf, 0, thistime);
5947 *to_pull -= thistime;
5948 return thistime;
5951 static bool run_windows_write(int dummy)
5953 struct cli_state *cli1;
5954 uint16_t fnum;
5955 int i;
5956 bool ret = false;
5957 const char *fname = "\\writetest.txt";
5958 double seconds;
5959 double kbytes;
5961 printf("starting windows_write test\n");
5962 if (!torture_open_connection(&cli1, 0)) {
5963 return False;
5966 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5967 printf("open failed (%s)\n", cli_errstr(cli1));
5968 return False;
5971 cli_sockopt(cli1, sockops);
5973 start_timer();
5975 for (i=0; i<torture_numops; i++) {
5976 char c = 0;
5977 off_t start = i * torture_blocksize;
5978 NTSTATUS status;
5979 size_t to_pull = torture_blocksize - 1;
5981 if (cli_write(cli1, fnum, 0, &c,
5982 start + torture_blocksize - 1, 1) != 1) {
5983 printf("cli_write failed: %s\n", cli_errstr(cli1));
5984 goto fail;
5987 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5988 null_source, &to_pull);
5989 if (!NT_STATUS_IS_OK(status)) {
5990 printf("cli_push returned: %s\n", nt_errstr(status));
5991 goto fail;
5995 seconds = end_timer();
5996 kbytes = (double)torture_blocksize * torture_numops;
5997 kbytes /= 1024;
5999 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6000 (double)seconds, (int)(kbytes/seconds));
6002 ret = true;
6003 fail:
6004 cli_close(cli1, fnum);
6005 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6006 torture_close_connection(cli1);
6007 return ret;
6010 static bool run_cli_echo(int dummy)
6012 struct cli_state *cli;
6013 NTSTATUS status;
6015 printf("starting cli_echo test\n");
6016 if (!torture_open_connection(&cli, 0)) {
6017 return false;
6019 cli_sockopt(cli, sockops);
6021 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6023 d_printf("cli_echo returned %s\n", nt_errstr(status));
6025 torture_close_connection(cli);
6026 return NT_STATUS_IS_OK(status);
6029 static bool run_uid_regression_test(int dummy)
6031 static struct cli_state *cli;
6032 int16_t old_vuid;
6033 int16_t old_cnum;
6034 bool correct = True;
6036 printf("starting uid regression test\n");
6038 if (!torture_open_connection(&cli, 0)) {
6039 return False;
6042 cli_sockopt(cli, sockops);
6044 /* Ok - now save then logoff our current user. */
6045 old_vuid = cli->vuid;
6047 if (!cli_ulogoff(cli)) {
6048 d_printf("(%s) cli_ulogoff failed: %s\n",
6049 __location__, cli_errstr(cli));
6050 correct = false;
6051 goto out;
6054 cli->vuid = old_vuid;
6056 /* Try an operation. */
6057 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6058 /* We expect bad uid. */
6059 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6060 NT_STATUS_NO_SUCH_USER)) {
6061 return False;
6065 old_cnum = cli->cnum;
6067 /* Now try a SMBtdis with the invald vuid set to zero. */
6068 cli->vuid = 0;
6070 /* This should succeed. */
6071 if (cli_tdis(cli)) {
6072 printf("First tdis with invalid vuid should succeed.\n");
6073 } else {
6074 printf("First tdis failed (%s)\n", cli_errstr(cli));
6077 cli->vuid = old_vuid;
6078 cli->cnum = old_cnum;
6080 /* This should fail. */
6081 if (cli_tdis(cli)) {
6082 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6083 } else {
6084 /* Should be bad tid. */
6085 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6086 NT_STATUS_NETWORK_NAME_DELETED)) {
6087 return False;
6091 cli_rmdir(cli, "\\uid_reg_test");
6093 out:
6095 cli_shutdown(cli);
6096 return correct;
6100 static const char *illegal_chars = "*\\/?<>|\":";
6101 static char force_shortname_chars[] = " +,.[];=\177";
6103 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
6105 struct cli_state *pcli = (struct cli_state *)state;
6106 fstring fname;
6107 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6109 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6110 return;
6112 if (finfo->mode & aDIR) {
6113 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6114 printf("del_fn: failed to rmdir %s\n,", fname );
6115 } else {
6116 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6117 printf("del_fn: failed to unlink %s\n,", fname );
6121 struct sn_state {
6122 int i;
6123 bool val;
6126 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
6128 struct sn_state *s = (struct sn_state *)state;
6129 int i = s->i;
6131 #if 0
6132 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6133 i, finfo->name, finfo->short_name);
6134 #endif
6136 if (strchr(force_shortname_chars, i)) {
6137 if (!finfo->short_name[0]) {
6138 /* Shortname not created when it should be. */
6139 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6140 __location__, finfo->name, i);
6141 s->val = true;
6143 } else if (finfo->short_name[0]){
6144 /* Shortname created when it should not be. */
6145 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6146 __location__, finfo->short_name, finfo->name);
6147 s->val = true;
6151 static bool run_shortname_test(int dummy)
6153 static struct cli_state *cli;
6154 bool correct = True;
6155 int i;
6156 struct sn_state s;
6157 char fname[20];
6159 printf("starting shortname test\n");
6161 if (!torture_open_connection(&cli, 0)) {
6162 return False;
6165 cli_sockopt(cli, sockops);
6167 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6168 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6169 cli_rmdir(cli, "\\shortname");
6171 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6172 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6173 __location__, cli_errstr(cli));
6174 correct = false;
6175 goto out;
6178 strlcpy(fname, "\\shortname\\", sizeof(fname));
6179 strlcat(fname, "test .txt", sizeof(fname));
6181 s.val = false;
6183 for (i = 32; i < 128; i++) {
6184 NTSTATUS status;
6185 uint16_t fnum = (uint16_t)-1;
6187 s.i = i;
6189 if (strchr(illegal_chars, i)) {
6190 continue;
6192 fname[15] = i;
6194 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6195 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6196 if (!NT_STATUS_IS_OK(status)) {
6197 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6198 __location__, fname, cli_errstr(cli));
6199 correct = false;
6200 goto out;
6202 cli_close(cli, fnum);
6203 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
6204 d_printf("(%s) failed to list %s: %s\n",
6205 __location__, fname, cli_errstr(cli));
6206 correct = false;
6207 goto out;
6209 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6210 d_printf("(%s) failed to delete %s: %s\n",
6211 __location__, fname, cli_errstr(cli));
6212 correct = false;
6213 goto out;
6216 if (s.val) {
6217 correct = false;
6218 goto out;
6222 out:
6224 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6225 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6226 cli_rmdir(cli, "\\shortname");
6227 torture_close_connection(cli);
6228 return correct;
6231 static void pagedsearch_cb(struct tevent_req *req)
6233 int rc;
6234 struct tldap_message *msg;
6235 char *dn;
6237 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6238 if (rc != TLDAP_SUCCESS) {
6239 d_printf("tldap_search_paged_recv failed: %s\n",
6240 tldap_err2string(rc));
6241 return;
6243 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6244 TALLOC_FREE(msg);
6245 return;
6247 if (!tldap_entry_dn(msg, &dn)) {
6248 d_printf("tldap_entry_dn failed\n");
6249 return;
6251 d_printf("%s\n", dn);
6252 TALLOC_FREE(msg);
6255 static bool run_tldap(int dummy)
6257 struct tldap_context *ld;
6258 int fd, rc;
6259 NTSTATUS status;
6260 struct sockaddr_storage addr;
6261 struct tevent_context *ev;
6262 struct tevent_req *req;
6263 char *basedn;
6265 if (!resolve_name(host, &addr, 0, false)) {
6266 d_printf("could not find host %s\n", host);
6267 return false;
6269 status = open_socket_out(&addr, 389, 9999, &fd);
6270 if (!NT_STATUS_IS_OK(status)) {
6271 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6272 return false;
6275 ld = tldap_context_create(talloc_tos(), fd);
6276 if (ld == NULL) {
6277 close(fd);
6278 d_printf("tldap_context_create failed\n");
6279 return false;
6282 rc = tldap_fetch_rootdse(ld);
6283 if (rc != TLDAP_SUCCESS) {
6284 d_printf("tldap_fetch_rootdse failed: %s\n",
6285 tldap_errstr(talloc_tos(), ld, rc));
6286 return false;
6289 basedn = tldap_talloc_single_attribute(
6290 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6291 if (basedn == NULL) {
6292 d_printf("no defaultNamingContext\n");
6293 return false;
6295 d_printf("defaultNamingContext: %s\n", basedn);
6297 ev = tevent_context_init(talloc_tos());
6298 if (ev == NULL) {
6299 d_printf("tevent_context_init failed\n");
6300 return false;
6303 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6304 TLDAP_SCOPE_SUB, "(objectclass=*)",
6305 NULL, 0, 0,
6306 NULL, 0, NULL, 0, 0, 0, 0, 5);
6307 if (req == NULL) {
6308 d_printf("tldap_search_paged_send failed\n");
6309 return false;
6311 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6313 tevent_req_poll(req, ev);
6315 TALLOC_FREE(req);
6317 TALLOC_FREE(ld);
6318 return true;
6321 static bool run_streamerror(int dummy)
6323 struct cli_state *cli;
6324 const char *dname = "\\testdir";
6325 const char *streamname =
6326 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6327 NTSTATUS status;
6328 time_t change_time, access_time, write_time;
6329 SMB_OFF_T size;
6330 uint16_t mode, fnum;
6331 bool ret = true;
6333 if (!torture_open_connection(&cli, 0)) {
6334 return false;
6337 cli_rmdir(cli, dname);
6339 status = cli_mkdir(cli, dname);
6340 if (!NT_STATUS_IS_OK(status)) {
6341 printf("mkdir failed: %s\n", nt_errstr(status));
6342 return false;
6345 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
6346 &size, &mode);
6347 status = cli_nt_error(cli);
6349 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6350 printf("pathinfo returned %s, expected "
6351 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6352 nt_errstr(status));
6353 ret = false;
6356 status = cli_ntcreate(cli, streamname, 0x16,
6357 FILE_READ_DATA|FILE_READ_EA|
6358 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6359 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6360 FILE_OPEN, 0, 0, &fnum);
6362 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6363 printf("ntcreate returned %s, expected "
6364 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6365 nt_errstr(status));
6366 ret = false;
6370 cli_rmdir(cli, dname);
6371 return ret;
6374 static bool run_local_substitute(int dummy)
6376 bool ok = true;
6378 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6379 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6380 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6381 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6382 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6383 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6384 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6385 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6387 /* Different captialization rules in sub_basic... */
6389 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6390 "blaDOM") == 0);
6392 return ok;
6395 static bool run_local_base64(int dummy)
6397 int i;
6398 bool ret = true;
6400 for (i=1; i<2000; i++) {
6401 DATA_BLOB blob1, blob2;
6402 char *b64;
6404 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6405 blob1.length = i;
6406 generate_random_buffer(blob1.data, blob1.length);
6408 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6409 if (b64 == NULL) {
6410 d_fprintf(stderr, "base64_encode_data_blob failed "
6411 "for %d bytes\n", i);
6412 ret = false;
6414 blob2 = base64_decode_data_blob(b64);
6415 TALLOC_FREE(b64);
6417 if (data_blob_cmp(&blob1, &blob2)) {
6418 d_fprintf(stderr, "data_blob_cmp failed for %d "
6419 "bytes\n", i);
6420 ret = false;
6422 TALLOC_FREE(blob1.data);
6423 data_blob_free(&blob2);
6425 return ret;
6428 static bool run_local_gencache(int dummy)
6430 char *val;
6431 time_t tm;
6432 DATA_BLOB blob;
6434 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6435 d_printf("%s: gencache_set() failed\n", __location__);
6436 return False;
6439 if (!gencache_get("foo", NULL, NULL)) {
6440 d_printf("%s: gencache_get() failed\n", __location__);
6441 return False;
6444 if (!gencache_get("foo", &val, &tm)) {
6445 d_printf("%s: gencache_get() failed\n", __location__);
6446 return False;
6449 if (strcmp(val, "bar") != 0) {
6450 d_printf("%s: gencache_get() returned %s, expected %s\n",
6451 __location__, val, "bar");
6452 SAFE_FREE(val);
6453 return False;
6456 SAFE_FREE(val);
6458 if (!gencache_del("foo")) {
6459 d_printf("%s: gencache_del() failed\n", __location__);
6460 return False;
6462 if (gencache_del("foo")) {
6463 d_printf("%s: second gencache_del() succeeded\n",
6464 __location__);
6465 return False;
6468 if (gencache_get("foo", &val, &tm)) {
6469 d_printf("%s: gencache_get() on deleted entry "
6470 "succeeded\n", __location__);
6471 return False;
6474 blob = data_blob_string_const_null("bar");
6475 tm = time(NULL) + 60;
6477 if (!gencache_set_data_blob("foo", &blob, tm)) {
6478 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6479 return False;
6482 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6483 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6484 return False;
6487 if (strcmp((const char *)blob.data, "bar") != 0) {
6488 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6489 __location__, (const char *)blob.data, "bar");
6490 data_blob_free(&blob);
6491 return False;
6494 data_blob_free(&blob);
6496 if (!gencache_del("foo")) {
6497 d_printf("%s: gencache_del() failed\n", __location__);
6498 return False;
6500 if (gencache_del("foo")) {
6501 d_printf("%s: second gencache_del() succeeded\n",
6502 __location__);
6503 return False;
6506 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6507 d_printf("%s: gencache_get_data_blob() on deleted entry "
6508 "succeeded\n", __location__);
6509 return False;
6512 return True;
6515 static bool rbt_testval(struct db_context *db, const char *key,
6516 const char *value)
6518 struct db_record *rec;
6519 TDB_DATA data = string_tdb_data(value);
6520 bool ret = false;
6521 NTSTATUS status;
6523 rec = db->fetch_locked(db, db, string_tdb_data(key));
6524 if (rec == NULL) {
6525 d_fprintf(stderr, "fetch_locked failed\n");
6526 goto done;
6528 status = rec->store(rec, data, 0);
6529 if (!NT_STATUS_IS_OK(status)) {
6530 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6531 goto done;
6533 TALLOC_FREE(rec);
6535 rec = db->fetch_locked(db, db, string_tdb_data(key));
6536 if (rec == NULL) {
6537 d_fprintf(stderr, "second fetch_locked failed\n");
6538 goto done;
6540 if ((rec->value.dsize != data.dsize)
6541 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6542 d_fprintf(stderr, "Got wrong data back\n");
6543 goto done;
6546 ret = true;
6547 done:
6548 TALLOC_FREE(rec);
6549 return ret;
6552 static bool run_local_rbtree(int dummy)
6554 struct db_context *db;
6555 bool ret = false;
6556 int i;
6558 db = db_open_rbt(NULL);
6560 if (db == NULL) {
6561 d_fprintf(stderr, "db_open_rbt failed\n");
6562 return false;
6565 for (i=0; i<1000; i++) {
6566 char *key, *value;
6568 if (asprintf(&key, "key%ld", random()) == -1) {
6569 goto done;
6571 if (asprintf(&value, "value%ld", random()) == -1) {
6572 SAFE_FREE(key);
6573 goto done;
6576 if (!rbt_testval(db, key, value)) {
6577 SAFE_FREE(key);
6578 SAFE_FREE(value);
6579 goto done;
6582 SAFE_FREE(value);
6583 if (asprintf(&value, "value%ld", random()) == -1) {
6584 SAFE_FREE(key);
6585 goto done;
6588 if (!rbt_testval(db, key, value)) {
6589 SAFE_FREE(key);
6590 SAFE_FREE(value);
6591 goto done;
6594 SAFE_FREE(key);
6595 SAFE_FREE(value);
6598 ret = true;
6600 done:
6601 TALLOC_FREE(db);
6602 return ret;
6605 struct talloc_dict_test {
6606 int content;
6609 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6611 int *count = (int *)priv;
6612 *count += 1;
6613 return 0;
6616 static bool run_local_talloc_dict(int dummy)
6618 struct talloc_dict *dict;
6619 struct talloc_dict_test *t;
6620 int key, count;
6622 dict = talloc_dict_init(talloc_tos());
6623 if (dict == NULL) {
6624 return false;
6627 t = talloc(talloc_tos(), struct talloc_dict_test);
6628 if (t == NULL) {
6629 return false;
6632 key = 1;
6633 t->content = 1;
6634 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6635 return false;
6638 count = 0;
6639 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6640 return false;
6643 if (count != 1) {
6644 return false;
6647 TALLOC_FREE(dict);
6649 return true;
6652 /* Split a path name into filename and stream name components. Canonicalise
6653 * such that an implicit $DATA token is always explicit.
6655 * The "specification" of this function can be found in the
6656 * run_local_stream_name() function in torture.c, I've tried those
6657 * combinations against a W2k3 server.
6660 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6661 char **pbase, char **pstream)
6663 char *base = NULL;
6664 char *stream = NULL;
6665 char *sname; /* stream name */
6666 const char *stype; /* stream type */
6668 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6670 sname = strchr_m(fname, ':');
6672 if (lp_posix_pathnames() || (sname == NULL)) {
6673 if (pbase != NULL) {
6674 base = talloc_strdup(mem_ctx, fname);
6675 NT_STATUS_HAVE_NO_MEMORY(base);
6677 goto done;
6680 if (pbase != NULL) {
6681 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6682 NT_STATUS_HAVE_NO_MEMORY(base);
6685 sname += 1;
6687 stype = strchr_m(sname, ':');
6689 if (stype == NULL) {
6690 sname = talloc_strdup(mem_ctx, sname);
6691 stype = "$DATA";
6693 else {
6694 if (StrCaseCmp(stype, ":$DATA") != 0) {
6696 * If there is an explicit stream type, so far we only
6697 * allow $DATA. Is there anything else allowed? -- vl
6699 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6700 TALLOC_FREE(base);
6701 return NT_STATUS_OBJECT_NAME_INVALID;
6703 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6704 stype += 1;
6707 if (sname == NULL) {
6708 TALLOC_FREE(base);
6709 return NT_STATUS_NO_MEMORY;
6712 if (sname[0] == '\0') {
6714 * no stream name, so no stream
6716 goto done;
6719 if (pstream != NULL) {
6720 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6721 if (stream == NULL) {
6722 TALLOC_FREE(sname);
6723 TALLOC_FREE(base);
6724 return NT_STATUS_NO_MEMORY;
6727 * upper-case the type field
6729 strupper_m(strchr_m(stream, ':')+1);
6732 done:
6733 if (pbase != NULL) {
6734 *pbase = base;
6736 if (pstream != NULL) {
6737 *pstream = stream;
6739 return NT_STATUS_OK;
6742 static bool test_stream_name(const char *fname, const char *expected_base,
6743 const char *expected_stream,
6744 NTSTATUS expected_status)
6746 NTSTATUS status;
6747 char *base = NULL;
6748 char *stream = NULL;
6750 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6751 if (!NT_STATUS_EQUAL(status, expected_status)) {
6752 goto error;
6755 if (!NT_STATUS_IS_OK(status)) {
6756 return true;
6759 if (base == NULL) goto error;
6761 if (strcmp(expected_base, base) != 0) goto error;
6763 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6764 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6766 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6767 goto error;
6769 TALLOC_FREE(base);
6770 TALLOC_FREE(stream);
6771 return true;
6773 error:
6774 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6775 fname, expected_base ? expected_base : "<NULL>",
6776 expected_stream ? expected_stream : "<NULL>",
6777 nt_errstr(expected_status));
6778 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6779 base ? base : "<NULL>", stream ? stream : "<NULL>",
6780 nt_errstr(status));
6781 TALLOC_FREE(base);
6782 TALLOC_FREE(stream);
6783 return false;
6786 static bool run_local_stream_name(int dummy)
6788 bool ret = true;
6790 ret &= test_stream_name(
6791 "bla", "bla", NULL, NT_STATUS_OK);
6792 ret &= test_stream_name(
6793 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6794 ret &= test_stream_name(
6795 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6796 ret &= test_stream_name(
6797 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6798 ret &= test_stream_name(
6799 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6800 ret &= test_stream_name(
6801 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6802 ret &= test_stream_name(
6803 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6804 ret &= test_stream_name(
6805 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6807 return ret;
6810 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6812 if (a.length != b.length) {
6813 printf("a.length=%d != b.length=%d\n",
6814 (int)a.length, (int)b.length);
6815 return false;
6817 if (memcmp(a.data, b.data, a.length) != 0) {
6818 printf("a.data and b.data differ\n");
6819 return false;
6821 return true;
6824 static bool run_local_memcache(int dummy)
6826 struct memcache *cache;
6827 DATA_BLOB k1, k2;
6828 DATA_BLOB d1, d2, d3;
6829 DATA_BLOB v1, v2, v3;
6831 TALLOC_CTX *mem_ctx;
6832 char *str1, *str2;
6833 size_t size1, size2;
6834 bool ret = false;
6836 cache = memcache_init(NULL, 100);
6838 if (cache == NULL) {
6839 printf("memcache_init failed\n");
6840 return false;
6843 d1 = data_blob_const("d1", 2);
6844 d2 = data_blob_const("d2", 2);
6845 d3 = data_blob_const("d3", 2);
6847 k1 = data_blob_const("d1", 2);
6848 k2 = data_blob_const("d2", 2);
6850 memcache_add(cache, STAT_CACHE, k1, d1);
6851 memcache_add(cache, GETWD_CACHE, k2, d2);
6853 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6854 printf("could not find k1\n");
6855 return false;
6857 if (!data_blob_equal(d1, v1)) {
6858 return false;
6861 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6862 printf("could not find k2\n");
6863 return false;
6865 if (!data_blob_equal(d2, v2)) {
6866 return false;
6869 memcache_add(cache, STAT_CACHE, k1, d3);
6871 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
6872 printf("could not find replaced k1\n");
6873 return false;
6875 if (!data_blob_equal(d3, v3)) {
6876 return false;
6879 memcache_add(cache, GETWD_CACHE, k1, d1);
6881 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6882 printf("Did find k2, should have been purged\n");
6883 return false;
6886 TALLOC_FREE(cache);
6888 cache = memcache_init(NULL, 0);
6890 mem_ctx = talloc_init("foo");
6892 str1 = talloc_strdup(mem_ctx, "string1");
6893 str2 = talloc_strdup(mem_ctx, "string2");
6895 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6896 data_blob_string_const("torture"), &str1);
6897 size1 = talloc_total_size(cache);
6899 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6900 data_blob_string_const("torture"), &str2);
6901 size2 = talloc_total_size(cache);
6903 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
6905 if (size2 > size1) {
6906 printf("memcache leaks memory!\n");
6907 goto fail;
6910 ret = true;
6911 fail:
6912 TALLOC_FREE(cache);
6913 return ret;
6916 static void wbclient_done(struct tevent_req *req)
6918 wbcErr wbc_err;
6919 struct winbindd_response *wb_resp;
6920 int *i = (int *)tevent_req_callback_data_void(req);
6922 wbc_err = wb_trans_recv(req, req, &wb_resp);
6923 TALLOC_FREE(req);
6924 *i += 1;
6925 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
6928 static bool run_local_wbclient(int dummy)
6930 struct event_context *ev;
6931 struct wb_context **wb_ctx;
6932 struct winbindd_request wb_req;
6933 bool result = false;
6934 int i, j;
6936 BlockSignals(True, SIGPIPE);
6938 ev = tevent_context_init_byname(talloc_tos(), "epoll");
6939 if (ev == NULL) {
6940 goto fail;
6943 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
6944 if (wb_ctx == NULL) {
6945 goto fail;
6948 ZERO_STRUCT(wb_req);
6949 wb_req.cmd = WINBINDD_PING;
6951 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
6953 for (i=0; i<nprocs; i++) {
6954 wb_ctx[i] = wb_context_init(ev, NULL);
6955 if (wb_ctx[i] == NULL) {
6956 goto fail;
6958 for (j=0; j<torture_numops; j++) {
6959 struct tevent_req *req;
6960 req = wb_trans_send(ev, ev, wb_ctx[i],
6961 (j % 2) == 0, &wb_req);
6962 if (req == NULL) {
6963 goto fail;
6965 tevent_req_set_callback(req, wbclient_done, &i);
6969 i = 0;
6971 while (i < nprocs * torture_numops) {
6972 event_loop_once(ev);
6975 result = true;
6976 fail:
6977 TALLOC_FREE(ev);
6978 return result;
6981 static void getaddrinfo_finished(struct tevent_req *req)
6983 char *name = (char *)tevent_req_callback_data_void(req);
6984 struct addrinfo *ainfo;
6985 int res;
6987 res = getaddrinfo_recv(req, &ainfo);
6988 if (res != 0) {
6989 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
6990 return;
6992 d_printf("gai(%s) succeeded\n", name);
6993 freeaddrinfo(ainfo);
6996 static bool run_getaddrinfo_send(int dummy)
6998 TALLOC_CTX *frame = talloc_stackframe();
6999 struct fncall_context *ctx;
7000 struct tevent_context *ev;
7001 bool result = false;
7002 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7003 "www.slashdot.org", "heise.de" };
7004 struct tevent_req *reqs[4];
7005 int i;
7007 ev = event_context_init(frame);
7008 if (ev == NULL) {
7009 goto fail;
7012 ctx = fncall_context_init(frame, 4);
7014 for (i=0; i<ARRAY_SIZE(names); i++) {
7015 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7016 NULL);
7017 if (reqs[i] == NULL) {
7018 goto fail;
7020 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7021 (void *)names[i]);
7024 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7025 tevent_loop_once(ev);
7028 result = true;
7029 fail:
7030 TALLOC_FREE(frame);
7031 return result;
7034 static bool dbtrans_inc(struct db_context *db)
7036 struct db_record *rec;
7037 uint32_t *val;
7038 bool ret = false;
7039 NTSTATUS status;
7041 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7042 if (rec == NULL) {
7043 printf(__location__ "fetch_lock failed\n");
7044 return false;
7047 if (rec->value.dsize != sizeof(uint32_t)) {
7048 printf(__location__ "value.dsize = %d\n",
7049 (int)rec->value.dsize);
7050 goto fail;
7053 val = (uint32_t *)rec->value.dptr;
7054 *val += 1;
7056 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7057 sizeof(uint32_t)),
7059 if (!NT_STATUS_IS_OK(status)) {
7060 printf(__location__ "store failed: %s\n",
7061 nt_errstr(status));
7062 goto fail;
7065 ret = true;
7066 fail:
7067 TALLOC_FREE(rec);
7068 return ret;
7071 static bool run_local_dbtrans(int dummy)
7073 struct db_context *db;
7074 struct db_record *rec;
7075 NTSTATUS status;
7076 uint32_t initial;
7077 int res;
7079 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7080 O_RDWR|O_CREAT, 0600);
7081 if (db == NULL) {
7082 printf("Could not open transtest.db\n");
7083 return false;
7086 res = db->transaction_start(db);
7087 if (res == -1) {
7088 printf(__location__ "transaction_start failed\n");
7089 return false;
7092 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7093 if (rec == NULL) {
7094 printf(__location__ "fetch_lock failed\n");
7095 return false;
7098 if (rec->value.dptr == NULL) {
7099 initial = 0;
7100 status = rec->store(
7101 rec, make_tdb_data((uint8_t *)&initial,
7102 sizeof(initial)),
7104 if (!NT_STATUS_IS_OK(status)) {
7105 printf(__location__ "store returned %s\n",
7106 nt_errstr(status));
7107 return false;
7111 TALLOC_FREE(rec);
7113 res = db->transaction_commit(db);
7114 if (res == -1) {
7115 printf(__location__ "transaction_commit failed\n");
7116 return false;
7119 while (true) {
7120 uint32_t val, val2;
7121 int i;
7123 res = db->transaction_start(db);
7124 if (res == -1) {
7125 printf(__location__ "transaction_start failed\n");
7126 break;
7129 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7130 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7131 break;
7134 for (i=0; i<10; i++) {
7135 if (!dbtrans_inc(db)) {
7136 return false;
7140 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7141 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7142 break;
7145 if (val2 != val + 10) {
7146 printf(__location__ "val=%d, val2=%d\n",
7147 (int)val, (int)val2);
7148 break;
7151 printf("val2=%d\r", val2);
7153 res = db->transaction_commit(db);
7154 if (res == -1) {
7155 printf(__location__ "transaction_commit failed\n");
7156 break;
7160 TALLOC_FREE(db);
7161 return true;
7164 static double create_procs(bool (*fn)(int), bool *result)
7166 int i, status;
7167 volatile pid_t *child_status;
7168 volatile bool *child_status_out;
7169 int synccount;
7170 int tries = 8;
7172 synccount = 0;
7174 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7175 if (!child_status) {
7176 printf("Failed to setup shared memory\n");
7177 return -1;
7180 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7181 if (!child_status_out) {
7182 printf("Failed to setup result status shared memory\n");
7183 return -1;
7186 for (i = 0; i < nprocs; i++) {
7187 child_status[i] = 0;
7188 child_status_out[i] = True;
7191 start_timer();
7193 for (i=0;i<nprocs;i++) {
7194 procnum = i;
7195 if (fork() == 0) {
7196 pid_t mypid = getpid();
7197 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7199 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7201 while (1) {
7202 if (torture_open_connection(&current_cli, i)) break;
7203 if (tries-- == 0) {
7204 printf("pid %d failed to start\n", (int)getpid());
7205 _exit(1);
7207 smb_msleep(10);
7210 child_status[i] = getpid();
7212 while (child_status[i] && end_timer() < 5) smb_msleep(2);
7214 child_status_out[i] = fn(i);
7215 _exit(0);
7219 do {
7220 synccount = 0;
7221 for (i=0;i<nprocs;i++) {
7222 if (child_status[i]) synccount++;
7224 if (synccount == nprocs) break;
7225 smb_msleep(10);
7226 } while (end_timer() < 30);
7228 if (synccount != nprocs) {
7229 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7230 *result = False;
7231 return end_timer();
7234 /* start the client load */
7235 start_timer();
7237 for (i=0;i<nprocs;i++) {
7238 child_status[i] = 0;
7241 printf("%d clients started\n", nprocs);
7243 for (i=0;i<nprocs;i++) {
7244 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7247 printf("\n");
7249 for (i=0;i<nprocs;i++) {
7250 if (!child_status_out[i]) {
7251 *result = False;
7254 return end_timer();
7257 #define FLAG_MULTIPROC 1
7259 static struct {
7260 const char *name;
7261 bool (*fn)(int);
7262 unsigned flags;
7263 } torture_ops[] = {
7264 {"FDPASS", run_fdpasstest, 0},
7265 {"LOCK1", run_locktest1, 0},
7266 {"LOCK2", run_locktest2, 0},
7267 {"LOCK3", run_locktest3, 0},
7268 {"LOCK4", run_locktest4, 0},
7269 {"LOCK5", run_locktest5, 0},
7270 {"LOCK6", run_locktest6, 0},
7271 {"LOCK7", run_locktest7, 0},
7272 {"LOCK8", run_locktest8, 0},
7273 {"LOCK9", run_locktest9, 0},
7274 {"UNLINK", run_unlinktest, 0},
7275 {"BROWSE", run_browsetest, 0},
7276 {"ATTR", run_attrtest, 0},
7277 {"TRANS2", run_trans2test, 0},
7278 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7279 {"TORTURE",run_torture, FLAG_MULTIPROC},
7280 {"RANDOMIPC", run_randomipc, 0},
7281 {"NEGNOWAIT", run_negprot_nowait, 0},
7282 {"NBENCH", run_nbench, 0},
7283 {"OPLOCK1", run_oplock1, 0},
7284 {"OPLOCK2", run_oplock2, 0},
7285 {"OPLOCK3", run_oplock3, 0},
7286 {"DIR", run_dirtest, 0},
7287 {"DIR1", run_dirtest1, 0},
7288 {"DENY1", torture_denytest1, 0},
7289 {"DENY2", torture_denytest2, 0},
7290 {"TCON", run_tcon_test, 0},
7291 {"TCONDEV", run_tcon_devtype_test, 0},
7292 {"RW1", run_readwritetest, 0},
7293 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7294 {"RW3", run_readwritelarge, 0},
7295 {"OPEN", run_opentest, 0},
7296 {"POSIX", run_simple_posix_open_test, 0},
7297 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7298 { "SHORTNAME-TEST", run_shortname_test, 0},
7299 #if 1
7300 {"OPENATTR", run_openattrtest, 0},
7301 #endif
7302 {"XCOPY", run_xcopy, 0},
7303 {"RENAME", run_rename, 0},
7304 {"DELETE", run_deletetest, 0},
7305 {"PROPERTIES", run_properties, 0},
7306 {"MANGLE", torture_mangle, 0},
7307 {"MANGLE1", run_mangle1, 0},
7308 {"W2K", run_w2ktest, 0},
7309 {"TRANS2SCAN", torture_trans2_scan, 0},
7310 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7311 {"UTABLE", torture_utable, 0},
7312 {"CASETABLE", torture_casetable, 0},
7313 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7314 {"PIPE_NUMBER", run_pipe_number, 0},
7315 {"TCON2", run_tcon2_test, 0},
7316 {"IOCTL", torture_ioctl_test, 0},
7317 {"CHKPATH", torture_chkpath_test, 0},
7318 {"FDSESS", run_fdsesstest, 0},
7319 { "EATEST", run_eatest, 0},
7320 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7321 { "CHAIN1", run_chain1, 0},
7322 { "CHAIN2", run_chain2, 0},
7323 { "WINDOWS-WRITE", run_windows_write, 0},
7324 { "CLI_ECHO", run_cli_echo, 0},
7325 { "GETADDRINFO", run_getaddrinfo_send, 0},
7326 { "TLDAP", run_tldap },
7327 { "STREAMERROR", run_streamerror },
7328 { "NOTIFY-BENCH", run_notify_bench },
7329 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7330 { "LOCAL-GENCACHE", run_local_gencache, 0},
7331 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7332 { "LOCAL-BASE64", run_local_base64, 0},
7333 { "LOCAL-RBTREE", run_local_rbtree, 0},
7334 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7335 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7336 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7337 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7338 {NULL, NULL, 0}};
7342 /****************************************************************************
7343 run a specified test or "ALL"
7344 ****************************************************************************/
7345 static bool run_test(const char *name)
7347 bool ret = True;
7348 bool result = True;
7349 bool found = False;
7350 int i;
7351 double t;
7352 if (strequal(name,"ALL")) {
7353 for (i=0;torture_ops[i].name;i++) {
7354 run_test(torture_ops[i].name);
7356 found = True;
7359 for (i=0;torture_ops[i].name;i++) {
7360 fstr_sprintf(randomfname, "\\XX%x",
7361 (unsigned)random());
7363 if (strequal(name, torture_ops[i].name)) {
7364 found = True;
7365 printf("Running %s\n", name);
7366 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7367 t = create_procs(torture_ops[i].fn, &result);
7368 if (!result) {
7369 ret = False;
7370 printf("TEST %s FAILED!\n", name);
7372 } else {
7373 start_timer();
7374 if (!torture_ops[i].fn(0)) {
7375 ret = False;
7376 printf("TEST %s FAILED!\n", name);
7378 t = end_timer();
7380 printf("%s took %g secs\n\n", name, t);
7384 if (!found) {
7385 printf("Did not find a test named %s\n", name);
7386 ret = False;
7389 return ret;
7393 static void usage(void)
7395 int i;
7397 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7398 printf("Please use samba4 torture.\n\n");
7400 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7402 printf("\t-d debuglevel\n");
7403 printf("\t-U user%%pass\n");
7404 printf("\t-k use kerberos\n");
7405 printf("\t-N numprocs\n");
7406 printf("\t-n my_netbios_name\n");
7407 printf("\t-W workgroup\n");
7408 printf("\t-o num_operations\n");
7409 printf("\t-O socket_options\n");
7410 printf("\t-m maximum protocol\n");
7411 printf("\t-L use oplocks\n");
7412 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7413 printf("\t-A showall\n");
7414 printf("\t-p port\n");
7415 printf("\t-s seed\n");
7416 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7417 printf("\n\n");
7419 printf("tests are:");
7420 for (i=0;torture_ops[i].name;i++) {
7421 printf(" %s", torture_ops[i].name);
7423 printf("\n");
7425 printf("default test is ALL\n");
7427 exit(1);
7430 /****************************************************************************
7431 main program
7432 ****************************************************************************/
7433 int main(int argc,char *argv[])
7435 int opt, i;
7436 char *p;
7437 int gotuser = 0;
7438 int gotpass = 0;
7439 bool correct = True;
7440 TALLOC_CTX *frame = talloc_stackframe();
7441 int seed = time(NULL);
7443 dbf = x_stdout;
7445 #ifdef HAVE_SETBUFFER
7446 setbuffer(stdout, NULL, 0);
7447 #endif
7449 load_case_tables();
7451 setup_logging("smbtorture", true);
7453 if (is_default_dyn_CONFIGFILE()) {
7454 if(getenv("SMB_CONF_PATH")) {
7455 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7458 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7459 load_interfaces();
7461 if (argc < 2) {
7462 usage();
7465 for(p = argv[1]; *p; p++)
7466 if(*p == '\\')
7467 *p = '/';
7469 if (strncmp(argv[1], "//", 2)) {
7470 usage();
7473 fstrcpy(host, &argv[1][2]);
7474 p = strchr_m(&host[2],'/');
7475 if (!p) {
7476 usage();
7478 *p = 0;
7479 fstrcpy(share, p+1);
7481 fstrcpy(myname, get_myname(talloc_tos()));
7482 if (!*myname) {
7483 fprintf(stderr, "Failed to get my hostname.\n");
7484 return 1;
7487 if (*username == 0 && getenv("LOGNAME")) {
7488 fstrcpy(username,getenv("LOGNAME"));
7491 argc--;
7492 argv++;
7494 fstrcpy(workgroup, lp_workgroup());
7496 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7497 switch (opt) {
7498 case 'p':
7499 port_to_use = atoi(optarg);
7500 break;
7501 case 's':
7502 seed = atoi(optarg);
7503 break;
7504 case 'W':
7505 fstrcpy(workgroup,optarg);
7506 break;
7507 case 'm':
7508 max_protocol = interpret_protocol(optarg, max_protocol);
7509 break;
7510 case 'N':
7511 nprocs = atoi(optarg);
7512 break;
7513 case 'o':
7514 torture_numops = atoi(optarg);
7515 break;
7516 case 'd':
7517 DEBUGLEVEL = atoi(optarg);
7518 break;
7519 case 'O':
7520 sockops = optarg;
7521 break;
7522 case 'L':
7523 use_oplocks = True;
7524 break;
7525 case 'l':
7526 local_path = optarg;
7527 break;
7528 case 'A':
7529 torture_showall = True;
7530 break;
7531 case 'n':
7532 fstrcpy(myname, optarg);
7533 break;
7534 case 'c':
7535 client_txt = optarg;
7536 break;
7537 case 'e':
7538 do_encrypt = true;
7539 break;
7540 case 'k':
7541 #ifdef HAVE_KRB5
7542 use_kerberos = True;
7543 #else
7544 d_printf("No kerberos support compiled in\n");
7545 exit(1);
7546 #endif
7547 break;
7548 case 'U':
7549 gotuser = 1;
7550 fstrcpy(username,optarg);
7551 p = strchr_m(username,'%');
7552 if (p) {
7553 *p = 0;
7554 fstrcpy(password, p+1);
7555 gotpass = 1;
7557 break;
7558 case 'b':
7559 fstrcpy(multishare_conn_fname, optarg);
7560 use_multishare_conn = True;
7561 break;
7562 case 'B':
7563 torture_blocksize = atoi(optarg);
7564 break;
7565 default:
7566 printf("Unknown option %c (%d)\n", (char)opt, opt);
7567 usage();
7571 d_printf("using seed %d\n", seed);
7573 srandom(seed);
7575 if(use_kerberos && !gotuser) gotpass = True;
7577 while (!gotpass) {
7578 p = getpass("Password:");
7579 if (p) {
7580 fstrcpy(password, p);
7581 gotpass = 1;
7585 printf("host=%s share=%s user=%s myname=%s\n",
7586 host, share, username, myname);
7588 if (argc == optind) {
7589 correct = run_test("ALL");
7590 } else {
7591 for (i=optind;i<argc;i++) {
7592 if (!run_test(argv[i])) {
7593 correct = False;
7598 TALLOC_FREE(frame);
7600 if (correct) {
7601 return(0);
7602 } else {
7603 return(1);