s3: Use the status from cli_raw_ioctl in torture_ioctl_test
[Samba/kamenim.git] / source3 / torture / torture.c
blob5ed27f926f5e8e019621a56134a297163844a5cb
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
26 extern char *optarg;
27 extern int optind;
29 static fstring host, workgroup, share, password, username, myname;
30 static int max_protocol = PROTOCOL_NT1;
31 static const char *sockops="TCP_NODELAY";
32 static int nprocs=1;
33 static int port_to_use=0;
34 int torture_numops=100;
35 int torture_blocksize=1024*1024;
36 static int procnum; /* records process count number when forking */
37 static struct cli_state *current_cli;
38 static fstring randomfname;
39 static bool use_oplocks;
40 static bool use_level_II_oplocks;
41 static const char *client_txt = "client_oplocks.txt";
42 static bool use_kerberos;
43 static fstring multishare_conn_fname;
44 static bool use_multishare_conn = False;
45 static bool do_encrypt;
46 static const char *local_path = NULL;
48 bool torture_showall = False;
50 static double create_procs(bool (*fn)(int), bool *result);
53 /* return a pointer to a anonymous shared memory segment of size "size"
54 which will persist across fork() but will disappear when all processes
55 exit
57 The memory is not zeroed
59 This function uses system5 shared memory. It takes advantage of a property
60 that the memory is not destroyed if it is attached when the id is removed
62 void *shm_setup(int size)
64 int shmid;
65 void *ret;
67 #ifdef __QNXNTO__
68 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
69 if (shmid == -1) {
70 printf("can't get shared memory\n");
71 exit(1);
73 shm_unlink("private");
74 if (ftruncate(shmid, size) == -1) {
75 printf("can't set shared memory size\n");
76 exit(1);
78 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
79 if (ret == MAP_FAILED) {
80 printf("can't map shared memory\n");
81 exit(1);
83 #else
84 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
85 if (shmid == -1) {
86 printf("can't get shared memory\n");
87 exit(1);
89 ret = (void *)shmat(shmid, 0, 0);
90 if (!ret || ret == (void *)-1) {
91 printf("can't attach to shared memory\n");
92 return NULL;
94 /* the following releases the ipc, but note that this process
95 and all its children will still have access to the memory, its
96 just that the shmid is no longer valid for other shm calls. This
97 means we don't leave behind lots of shm segments after we exit
99 See Stevens "advanced programming in unix env" for details
101 shmctl(shmid, IPC_RMID, 0);
102 #endif
104 return ret;
107 /********************************************************************
108 Ensure a connection is encrypted.
109 ********************************************************************/
111 static bool force_cli_encryption(struct cli_state *c,
112 const char *sharename)
114 uint16 major, minor;
115 uint32 caplow, caphigh;
116 NTSTATUS status;
118 if (!SERVER_HAS_UNIX_CIFS(c)) {
119 d_printf("Encryption required and "
120 "server that doesn't support "
121 "UNIX extensions - failing connect\n");
122 return false;
125 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
126 &caphigh);
127 if (!NT_STATUS_IS_OK(status)) {
128 d_printf("Encryption required and "
129 "can't get UNIX CIFS extensions "
130 "version from server: %s\n", nt_errstr(status));
131 return false;
134 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
135 d_printf("Encryption required and "
136 "share %s doesn't support "
137 "encryption.\n", sharename);
138 return false;
141 if (c->use_kerberos) {
142 status = cli_gss_smb_encryption_start(c);
143 } else {
144 status = cli_raw_ntlm_smb_encryption_start(c,
145 username,
146 password,
147 workgroup);
150 if (!NT_STATUS_IS_OK(status)) {
151 d_printf("Encryption required and "
152 "setup failed with error %s.\n",
153 nt_errstr(status));
154 return false;
157 return true;
161 static struct cli_state *open_nbt_connection(void)
163 struct nmb_name called, calling;
164 struct sockaddr_storage ss;
165 struct cli_state *c;
166 NTSTATUS status;
168 make_nmb_name(&calling, myname, 0x0);
169 make_nmb_name(&called , host, 0x20);
171 zero_sockaddr(&ss);
173 if (!(c = cli_initialise())) {
174 printf("Failed initialize cli_struct to connect with %s\n", host);
175 return NULL;
178 c->port = port_to_use;
180 status = cli_connect(c, host, &ss);
181 if (!NT_STATUS_IS_OK(status)) {
182 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
183 return NULL;
186 c->use_kerberos = use_kerberos;
188 c->timeout = 120000; /* set a really long timeout (2 minutes) */
189 if (use_oplocks) c->use_oplocks = True;
190 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
192 if (!cli_session_request(c, &calling, &called)) {
194 * Well, that failed, try *SMBSERVER ...
195 * However, we must reconnect as well ...
197 status = cli_connect(c, host, &ss);
198 if (!NT_STATUS_IS_OK(status)) {
199 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
200 return NULL;
203 make_nmb_name(&called, "*SMBSERVER", 0x20);
204 if (!cli_session_request(c, &calling, &called)) {
205 printf("%s rejected the session\n",host);
206 printf("We tried with a called name of %s & %s\n",
207 host, "*SMBSERVER");
208 cli_shutdown(c);
209 return NULL;
213 return c;
216 /* Insert a NULL at the first separator of the given path and return a pointer
217 * to the remainder of the string.
219 static char *
220 terminate_path_at_separator(char * path)
222 char * p;
224 if (!path) {
225 return NULL;
228 if ((p = strchr_m(path, '/'))) {
229 *p = '\0';
230 return p + 1;
233 if ((p = strchr_m(path, '\\'))) {
234 *p = '\0';
235 return p + 1;
238 /* No separator. */
239 return NULL;
243 parse a //server/share type UNC name
245 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
246 char **hostname, char **sharename)
248 char *p;
250 *hostname = *sharename = NULL;
252 if (strncmp(unc_name, "\\\\", 2) &&
253 strncmp(unc_name, "//", 2)) {
254 return False;
257 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
258 p = terminate_path_at_separator(*hostname);
260 if (p && *p) {
261 *sharename = talloc_strdup(mem_ctx, p);
262 terminate_path_at_separator(*sharename);
265 if (*hostname && *sharename) {
266 return True;
269 TALLOC_FREE(*hostname);
270 TALLOC_FREE(*sharename);
271 return False;
274 static bool torture_open_connection_share(struct cli_state **c,
275 const char *hostname,
276 const char *sharename)
278 bool retry;
279 int flags = 0;
280 NTSTATUS status;
282 if (use_kerberos)
283 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
284 if (use_oplocks)
285 flags |= CLI_FULL_CONNECTION_OPLOCKS;
286 if (use_level_II_oplocks)
287 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
289 status = cli_full_connection(c, myname,
290 hostname, NULL, port_to_use,
291 sharename, "?????",
292 username, workgroup,
293 password, flags, Undefined, &retry);
294 if (!NT_STATUS_IS_OK(status)) {
295 printf("failed to open share connection: //%s/%s port:%d - %s\n",
296 hostname, sharename, port_to_use, nt_errstr(status));
297 return False;
300 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
302 if (do_encrypt) {
303 return force_cli_encryption(*c,
304 sharename);
306 return True;
309 bool torture_open_connection(struct cli_state **c, int conn_index)
311 char **unc_list = NULL;
312 int num_unc_names = 0;
313 bool result;
315 if (use_multishare_conn==True) {
316 char *h, *s;
317 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
318 if (!unc_list || num_unc_names <= 0) {
319 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
320 exit(1);
323 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
324 NULL, &h, &s)) {
325 printf("Failed to parse UNC name %s\n",
326 unc_list[conn_index % num_unc_names]);
327 TALLOC_FREE(unc_list);
328 exit(1);
331 result = torture_open_connection_share(c, h, s);
333 /* h, s were copied earlier */
334 TALLOC_FREE(unc_list);
335 return result;
338 return torture_open_connection_share(c, host, share);
341 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
343 uint16 old_vuid = cli->vuid;
344 fstring old_user_name;
345 size_t passlen = strlen(password);
346 NTSTATUS status;
347 bool ret;
349 fstrcpy(old_user_name, cli->user_name);
350 cli->vuid = 0;
351 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
352 password, passlen,
353 password, passlen,
354 workgroup));
355 *new_vuid = cli->vuid;
356 cli->vuid = old_vuid;
357 status = cli_set_username(cli, old_user_name);
358 if (!NT_STATUS_IS_OK(status)) {
359 return false;
361 return ret;
365 bool torture_close_connection(struct cli_state *c)
367 bool ret = True;
368 NTSTATUS status;
370 status = cli_tdis(c);
371 if (!NT_STATUS_IS_OK(status)) {
372 printf("tdis failed (%s)\n", nt_errstr(status));
373 ret = False;
376 cli_shutdown(c);
378 return ret;
382 /* check if the server produced the expected error code */
383 static bool check_error(int line, struct cli_state *c,
384 uint8 eclass, uint32 ecode, NTSTATUS nterr)
386 if (cli_is_dos_error(c)) {
387 uint8 cclass;
388 uint32 num;
390 /* Check DOS error */
392 cli_dos_error(c, &cclass, &num);
394 if (eclass != cclass || ecode != num) {
395 printf("unexpected error code class=%d code=%d\n",
396 (int)cclass, (int)num);
397 printf(" expected %d/%d %s (line=%d)\n",
398 (int)eclass, (int)ecode, nt_errstr(nterr), line);
399 return False;
402 } else {
403 NTSTATUS status;
405 /* Check NT error */
407 status = cli_nt_error(c);
409 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
410 printf("unexpected error code %s\n", nt_errstr(status));
411 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
412 return False;
416 return True;
420 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
422 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
423 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
425 return True;
429 static bool rw_torture(struct cli_state *c)
431 const char *lockfname = "\\torture.lck";
432 fstring fname;
433 uint16_t fnum;
434 uint16_t fnum2;
435 pid_t pid2, pid = getpid();
436 int i, j;
437 char buf[1024];
438 bool correct = True;
439 NTSTATUS status;
441 memset(buf, '\0', sizeof(buf));
443 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
444 DENY_NONE, &fnum2);
445 if (!NT_STATUS_IS_OK(status)) {
446 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
448 if (!NT_STATUS_IS_OK(status)) {
449 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
450 return False;
453 for (i=0;i<torture_numops;i++) {
454 unsigned n = (unsigned)sys_random()%10;
455 if (i % 10 == 0) {
456 printf("%d\r", i); fflush(stdout);
458 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
460 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
461 return False;
464 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
465 printf("open failed (%s)\n", cli_errstr(c));
466 correct = False;
467 break;
470 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
471 printf("write failed (%s)\n", cli_errstr(c));
472 correct = False;
475 for (j=0;j<50;j++) {
476 if (cli_write(c, fnum, 0, (char *)buf,
477 sizeof(pid)+(j*sizeof(buf)),
478 sizeof(buf)) != sizeof(buf)) {
479 printf("write failed (%s)\n", cli_errstr(c));
480 correct = False;
484 pid2 = 0;
486 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
487 printf("read failed (%s)\n", cli_errstr(c));
488 correct = False;
491 if (pid2 != pid) {
492 printf("data corruption!\n");
493 correct = False;
496 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
497 printf("close failed (%s)\n", cli_errstr(c));
498 correct = False;
501 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
502 printf("unlink failed (%s)\n", cli_errstr(c));
503 correct = False;
506 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
507 printf("unlock failed (%s)\n", cli_errstr(c));
508 correct = False;
512 cli_close(c, fnum2);
513 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
515 printf("%d\n", i);
517 return correct;
520 static bool run_torture(int dummy)
522 struct cli_state *cli;
523 bool ret;
525 cli = current_cli;
527 cli_sockopt(cli, sockops);
529 ret = rw_torture(cli);
531 if (!torture_close_connection(cli)) {
532 ret = False;
535 return ret;
538 static bool rw_torture3(struct cli_state *c, char *lockfname)
540 uint16_t fnum = (uint16_t)-1;
541 unsigned int i = 0;
542 char buf[131072];
543 char buf_rd[131072];
544 unsigned count;
545 unsigned countprev = 0;
546 ssize_t sent = 0;
547 bool correct = True;
548 NTSTATUS status;
550 srandom(1);
551 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
553 SIVAL(buf, i, sys_random());
556 if (procnum == 0)
558 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
559 DENY_NONE, &fnum))) {
560 printf("first open read/write of %s failed (%s)\n",
561 lockfname, cli_errstr(c));
562 return False;
565 else
567 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
569 status = cli_open(c, lockfname, O_RDONLY,
570 DENY_NONE, &fnum);
571 if (!NT_STATUS_IS_OK(status)) {
572 break;
574 smb_msleep(10);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("second open read-only of %s failed (%s)\n",
578 lockfname, cli_errstr(c));
579 return False;
583 i = 0;
584 for (count = 0; count < sizeof(buf); count += sent)
586 if (count >= countprev) {
587 printf("%d %8d\r", i, count);
588 fflush(stdout);
589 i++;
590 countprev += (sizeof(buf) / 20);
593 if (procnum == 0)
595 sent = ((unsigned)sys_random()%(20))+ 1;
596 if (sent > sizeof(buf) - count)
598 sent = sizeof(buf) - count;
601 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
602 printf("write failed (%s)\n", cli_errstr(c));
603 correct = False;
606 else
608 sent = cli_read(c, fnum, buf_rd+count, count,
609 sizeof(buf)-count);
610 if (sent < 0)
612 printf("read failed offset:%d size:%ld (%s)\n",
613 count, (unsigned long)sizeof(buf)-count,
614 cli_errstr(c));
615 correct = False;
616 sent = 0;
618 if (sent > 0)
620 if (memcmp(buf_rd+count, buf+count, sent) != 0)
622 printf("read/write compare failed\n");
623 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
624 correct = False;
625 break;
632 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
633 printf("close failed (%s)\n", cli_errstr(c));
634 correct = False;
637 return correct;
640 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
642 const char *lockfname = "\\torture2.lck";
643 uint16_t fnum1;
644 uint16_t fnum2;
645 int i;
646 char buf[131072];
647 char buf_rd[131072];
648 bool correct = True;
649 ssize_t bytes_read;
651 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
652 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
655 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
656 DENY_NONE, &fnum1))) {
657 printf("first open read/write of %s failed (%s)\n",
658 lockfname, cli_errstr(c1));
659 return False;
661 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
662 DENY_NONE, &fnum2))) {
663 printf("second open read-only of %s failed (%s)\n",
664 lockfname, cli_errstr(c2));
665 cli_close(c1, fnum1);
666 return False;
669 for (i=0;i<torture_numops;i++)
671 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
672 if (i % 10 == 0) {
673 printf("%d\r", i); fflush(stdout);
676 generate_random_buffer((unsigned char *)buf, buf_size);
678 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
679 printf("write failed (%s)\n", cli_errstr(c1));
680 correct = False;
681 break;
684 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
685 printf("read failed (%s)\n", cli_errstr(c2));
686 printf("read %d, expected %ld\n", (int)bytes_read,
687 (unsigned long)buf_size);
688 correct = False;
689 break;
692 if (memcmp(buf_rd, buf, buf_size) != 0)
694 printf("read/write compare failed\n");
695 correct = False;
696 break;
700 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
701 printf("close failed (%s)\n", cli_errstr(c2));
702 correct = False;
704 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
705 printf("close failed (%s)\n", cli_errstr(c1));
706 correct = False;
709 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
710 printf("unlink failed (%s)\n", cli_errstr(c1));
711 correct = False;
714 return correct;
717 static bool run_readwritetest(int dummy)
719 struct cli_state *cli1, *cli2;
720 bool test1, test2 = False;
722 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
723 return False;
725 cli_sockopt(cli1, sockops);
726 cli_sockopt(cli2, sockops);
728 printf("starting readwritetest\n");
730 test1 = rw_torture2(cli1, cli2);
731 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
733 if (test1) {
734 test2 = rw_torture2(cli1, cli1);
735 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
738 if (!torture_close_connection(cli1)) {
739 test1 = False;
742 if (!torture_close_connection(cli2)) {
743 test2 = False;
746 return (test1 && test2);
749 static bool run_readwritemulti(int dummy)
751 struct cli_state *cli;
752 bool test;
754 cli = current_cli;
756 cli_sockopt(cli, sockops);
758 printf("run_readwritemulti: fname %s\n", randomfname);
759 test = rw_torture3(cli, randomfname);
761 if (!torture_close_connection(cli)) {
762 test = False;
765 return test;
768 static bool run_readwritelarge(int dummy)
770 static struct cli_state *cli1;
771 uint16_t fnum1;
772 const char *lockfname = "\\large.dat";
773 SMB_OFF_T fsize;
774 char buf[126*1024];
775 bool correct = True;
777 if (!torture_open_connection(&cli1, 0)) {
778 return False;
780 cli_sockopt(cli1, sockops);
781 memset(buf,'\0',sizeof(buf));
783 cli1->max_xmit = 128*1024;
785 printf("starting readwritelarge\n");
787 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
789 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
790 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
791 return False;
794 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
796 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
797 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
798 correct = False;
801 if (fsize == sizeof(buf))
802 printf("readwritelarge test 1 succeeded (size = %lx)\n",
803 (unsigned long)fsize);
804 else {
805 printf("readwritelarge test 1 failed (size = %lx)\n",
806 (unsigned long)fsize);
807 correct = False;
810 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
811 printf("close failed (%s)\n", cli_errstr(cli1));
812 correct = False;
815 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
816 printf("unlink failed (%s)\n", cli_errstr(cli1));
817 correct = False;
820 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
821 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
822 return False;
825 cli1->max_xmit = 4*1024;
827 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
829 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
830 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
831 correct = False;
834 if (fsize == sizeof(buf))
835 printf("readwritelarge test 2 succeeded (size = %lx)\n",
836 (unsigned long)fsize);
837 else {
838 printf("readwritelarge test 2 failed (size = %lx)\n",
839 (unsigned long)fsize);
840 correct = False;
843 #if 0
844 /* ToDo - set allocation. JRA */
845 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
846 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
847 return False;
849 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
850 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
851 correct = False;
853 if (fsize != 0)
854 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
855 #endif
857 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
858 printf("close failed (%s)\n", cli_errstr(cli1));
859 correct = False;
862 if (!torture_close_connection(cli1)) {
863 correct = False;
865 return correct;
868 int line_count = 0;
869 int nbio_id;
871 #define ival(s) strtol(s, NULL, 0)
873 /* run a test that simulates an approximate netbench client load */
874 static bool run_netbench(int client)
876 struct cli_state *cli;
877 int i;
878 char line[1024];
879 char cname[20];
880 FILE *f;
881 const char *params[20];
882 bool correct = True;
884 cli = current_cli;
886 nbio_id = client;
888 cli_sockopt(cli, sockops);
890 nb_setup(cli);
892 slprintf(cname,sizeof(cname)-1, "client%d", client);
894 f = fopen(client_txt, "r");
896 if (!f) {
897 perror(client_txt);
898 return False;
901 while (fgets(line, sizeof(line)-1, f)) {
902 char *saveptr;
903 line_count++;
905 line[strlen(line)-1] = 0;
907 /* printf("[%d] %s\n", line_count, line); */
909 all_string_sub(line,"client1", cname, sizeof(line));
911 /* parse the command parameters */
912 params[0] = strtok_r(line, " ", &saveptr);
913 i = 0;
914 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
916 params[i] = "";
918 if (i < 2) continue;
920 if (!strncmp(params[0],"SMB", 3)) {
921 printf("ERROR: You are using a dbench 1 load file\n");
922 exit(1);
925 if (!strcmp(params[0],"NTCreateX")) {
926 nb_createx(params[1], ival(params[2]), ival(params[3]),
927 ival(params[4]));
928 } else if (!strcmp(params[0],"Close")) {
929 nb_close(ival(params[1]));
930 } else if (!strcmp(params[0],"Rename")) {
931 nb_rename(params[1], params[2]);
932 } else if (!strcmp(params[0],"Unlink")) {
933 nb_unlink(params[1]);
934 } else if (!strcmp(params[0],"Deltree")) {
935 nb_deltree(params[1]);
936 } else if (!strcmp(params[0],"Rmdir")) {
937 nb_rmdir(params[1]);
938 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
939 nb_qpathinfo(params[1]);
940 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
941 nb_qfileinfo(ival(params[1]));
942 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
943 nb_qfsinfo(ival(params[1]));
944 } else if (!strcmp(params[0],"FIND_FIRST")) {
945 nb_findfirst(params[1]);
946 } else if (!strcmp(params[0],"WriteX")) {
947 nb_writex(ival(params[1]),
948 ival(params[2]), ival(params[3]), ival(params[4]));
949 } else if (!strcmp(params[0],"ReadX")) {
950 nb_readx(ival(params[1]),
951 ival(params[2]), ival(params[3]), ival(params[4]));
952 } else if (!strcmp(params[0],"Flush")) {
953 nb_flush(ival(params[1]));
954 } else {
955 printf("Unknown operation %s\n", params[0]);
956 exit(1);
959 fclose(f);
961 nb_cleanup();
963 if (!torture_close_connection(cli)) {
964 correct = False;
967 return correct;
971 /* run a test that simulates an approximate netbench client load */
972 static bool run_nbench(int dummy)
974 double t;
975 bool correct = True;
977 nbio_shmem(nprocs);
979 nbio_id = -1;
981 signal(SIGALRM, nb_alarm);
982 alarm(1);
983 t = create_procs(run_netbench, &correct);
984 alarm(0);
986 printf("\nThroughput %g MB/sec\n",
987 1.0e-6 * nbio_total() / t);
988 return correct;
993 This test checks for two things:
995 1) correct support for retaining locks over a close (ie. the server
996 must not use posix semantics)
997 2) support for lock timeouts
999 static bool run_locktest1(int dummy)
1001 struct cli_state *cli1, *cli2;
1002 const char *fname = "\\lockt1.lck";
1003 uint16_t fnum1, fnum2, fnum3;
1004 time_t t1, t2;
1005 unsigned lock_timeout;
1007 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1008 return False;
1010 cli_sockopt(cli1, sockops);
1011 cli_sockopt(cli2, sockops);
1013 printf("starting locktest1\n");
1015 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1017 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1018 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1019 return False;
1021 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1022 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1023 return False;
1025 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1026 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1027 return False;
1030 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1031 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1032 return False;
1036 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1037 printf("lock2 succeeded! This is a locking bug\n");
1038 return False;
1039 } else {
1040 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1041 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1045 lock_timeout = (1 + (random() % 20));
1046 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1047 t1 = time(NULL);
1048 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1049 printf("lock3 succeeded! This is a locking bug\n");
1050 return False;
1051 } else {
1052 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1053 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1055 t2 = time(NULL);
1057 if (ABS(t2 - t1) < lock_timeout-1) {
1058 printf("error: This server appears not to support timed lock requests\n");
1061 printf("server slept for %u seconds for a %u second timeout\n",
1062 (unsigned int)(t2-t1), lock_timeout);
1064 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1065 printf("close1 failed (%s)\n", cli_errstr(cli1));
1066 return False;
1069 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1070 printf("lock4 succeeded! This is a locking bug\n");
1071 return False;
1072 } else {
1073 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1074 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1077 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1078 printf("close2 failed (%s)\n", cli_errstr(cli1));
1079 return False;
1082 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1083 printf("close3 failed (%s)\n", cli_errstr(cli2));
1084 return False;
1087 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1088 printf("unlink failed (%s)\n", cli_errstr(cli1));
1089 return False;
1093 if (!torture_close_connection(cli1)) {
1094 return False;
1097 if (!torture_close_connection(cli2)) {
1098 return False;
1101 printf("Passed locktest1\n");
1102 return True;
1106 this checks to see if a secondary tconx can use open files from an
1107 earlier tconx
1109 static bool run_tcon_test(int dummy)
1111 static struct cli_state *cli;
1112 const char *fname = "\\tcontest.tmp";
1113 uint16 fnum1;
1114 uint16 cnum1, cnum2, cnum3;
1115 uint16 vuid1, vuid2;
1116 char buf[4];
1117 bool ret = True;
1118 NTSTATUS status;
1120 memset(buf, '\0', sizeof(buf));
1122 if (!torture_open_connection(&cli, 0)) {
1123 return False;
1125 cli_sockopt(cli, sockops);
1127 printf("starting tcontest\n");
1129 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1131 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1132 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1133 return False;
1136 cnum1 = cli->cnum;
1137 vuid1 = cli->vuid;
1139 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1140 printf("initial write failed (%s)", cli_errstr(cli));
1141 return False;
1144 status = cli_tcon_andx(cli, share, "?????",
1145 password, strlen(password)+1);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 printf("%s refused 2nd tree connect (%s)\n", host,
1148 nt_errstr(status));
1149 cli_shutdown(cli);
1150 return False;
1153 cnum2 = cli->cnum;
1154 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1155 vuid2 = cli->vuid + 1;
1157 /* try a write with the wrong tid */
1158 cli->cnum = cnum2;
1160 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1161 printf("* server allows write with wrong TID\n");
1162 ret = False;
1163 } else {
1164 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1168 /* try a write with an invalid tid */
1169 cli->cnum = cnum3;
1171 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1172 printf("* server allows write with invalid TID\n");
1173 ret = False;
1174 } else {
1175 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1178 /* try a write with an invalid vuid */
1179 cli->vuid = vuid2;
1180 cli->cnum = cnum1;
1182 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1183 printf("* server allows write with invalid VUID\n");
1184 ret = False;
1185 } else {
1186 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1189 cli->cnum = cnum1;
1190 cli->vuid = vuid1;
1192 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1193 printf("close failed (%s)\n", cli_errstr(cli));
1194 return False;
1197 cli->cnum = cnum2;
1199 status = cli_tdis(cli);
1200 if (!NT_STATUS_IS_OK(status)) {
1201 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1202 return False;
1205 cli->cnum = cnum1;
1207 if (!torture_close_connection(cli)) {
1208 return False;
1211 return ret;
1216 checks for old style tcon support
1218 static bool run_tcon2_test(int dummy)
1220 static struct cli_state *cli;
1221 uint16 cnum, max_xmit;
1222 char *service;
1223 NTSTATUS status;
1225 if (!torture_open_connection(&cli, 0)) {
1226 return False;
1228 cli_sockopt(cli, sockops);
1230 printf("starting tcon2 test\n");
1232 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1233 return false;
1236 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1238 if (!NT_STATUS_IS_OK(status)) {
1239 printf("tcon2 failed : %s\n", cli_errstr(cli));
1240 } else {
1241 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1242 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1245 if (!torture_close_connection(cli)) {
1246 return False;
1249 printf("Passed tcon2 test\n");
1250 return True;
1253 static bool tcon_devtest(struct cli_state *cli,
1254 const char *myshare, const char *devtype,
1255 const char *return_devtype,
1256 NTSTATUS expected_error)
1258 NTSTATUS status;
1259 bool ret;
1261 status = cli_tcon_andx(cli, myshare, devtype,
1262 password, strlen(password)+1);
1264 if (NT_STATUS_IS_OK(expected_error)) {
1265 if (NT_STATUS_IS_OK(status)) {
1266 if (strcmp(cli->dev, return_devtype) == 0) {
1267 ret = True;
1268 } else {
1269 printf("tconX to share %s with type %s "
1270 "succeeded but returned the wrong "
1271 "device type (got [%s] but should have got [%s])\n",
1272 myshare, devtype, cli->dev, return_devtype);
1273 ret = False;
1275 } else {
1276 printf("tconX to share %s with type %s "
1277 "should have succeeded but failed\n",
1278 myshare, devtype);
1279 ret = False;
1281 cli_tdis(cli);
1282 } else {
1283 if (NT_STATUS_IS_OK(status)) {
1284 printf("tconx to share %s with type %s "
1285 "should have failed but succeeded\n",
1286 myshare, devtype);
1287 ret = False;
1288 } else {
1289 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1290 expected_error)) {
1291 ret = True;
1292 } else {
1293 printf("Returned unexpected error\n");
1294 ret = False;
1298 return ret;
1302 checks for correct tconX support
1304 static bool run_tcon_devtype_test(int dummy)
1306 static struct cli_state *cli1 = NULL;
1307 bool retry;
1308 int flags = 0;
1309 NTSTATUS status;
1310 bool ret = True;
1312 status = cli_full_connection(&cli1, myname,
1313 host, NULL, port_to_use,
1314 NULL, NULL,
1315 username, workgroup,
1316 password, flags, Undefined, &retry);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 printf("could not open connection\n");
1320 return False;
1323 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1324 ret = False;
1326 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1327 ret = False;
1329 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1330 ret = False;
1332 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1333 ret = False;
1335 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1336 ret = False;
1338 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1339 ret = False;
1341 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1342 ret = False;
1344 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1345 ret = False;
1347 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1348 ret = False;
1350 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1351 ret = False;
1353 cli_shutdown(cli1);
1355 if (ret)
1356 printf("Passed tcondevtest\n");
1358 return ret;
1363 This test checks that
1365 1) the server supports multiple locking contexts on the one SMB
1366 connection, distinguished by PID.
1368 2) the server correctly fails overlapping locks made by the same PID (this
1369 goes against POSIX behaviour, which is why it is tricky to implement)
1371 3) the server denies unlock requests by an incorrect client PID
1373 static bool run_locktest2(int dummy)
1375 static struct cli_state *cli;
1376 const char *fname = "\\lockt2.lck";
1377 uint16_t fnum1, fnum2, fnum3;
1378 bool correct = True;
1380 if (!torture_open_connection(&cli, 0)) {
1381 return False;
1384 cli_sockopt(cli, sockops);
1386 printf("starting locktest2\n");
1388 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1390 cli_setpid(cli, 1);
1392 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1393 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1394 return False;
1397 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1398 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1399 return False;
1402 cli_setpid(cli, 2);
1404 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1405 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1406 return False;
1409 cli_setpid(cli, 1);
1411 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1412 printf("lock1 failed (%s)\n", cli_errstr(cli));
1413 return False;
1416 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1417 printf("WRITE lock1 succeeded! This is a locking bug\n");
1418 correct = False;
1419 } else {
1420 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1421 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1424 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1425 printf("WRITE lock2 succeeded! This is a locking bug\n");
1426 correct = False;
1427 } else {
1428 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1429 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1432 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1433 printf("READ lock2 succeeded! This is a locking bug\n");
1434 correct = False;
1435 } else {
1436 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1437 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1440 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1441 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1443 cli_setpid(cli, 2);
1444 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1445 printf("unlock at 100 succeeded! This is a locking bug\n");
1446 correct = False;
1449 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1450 printf("unlock1 succeeded! This is a locking bug\n");
1451 correct = False;
1452 } else {
1453 if (!check_error(__LINE__, cli,
1454 ERRDOS, ERRlock,
1455 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1458 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1459 printf("unlock2 succeeded! This is a locking bug\n");
1460 correct = False;
1461 } else {
1462 if (!check_error(__LINE__, cli,
1463 ERRDOS, ERRlock,
1464 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1467 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1468 printf("lock3 succeeded! This is a locking bug\n");
1469 correct = False;
1470 } else {
1471 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1474 cli_setpid(cli, 1);
1476 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1477 printf("close1 failed (%s)\n", cli_errstr(cli));
1478 return False;
1481 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1482 printf("close2 failed (%s)\n", cli_errstr(cli));
1483 return False;
1486 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1487 printf("close3 failed (%s)\n", cli_errstr(cli));
1488 return False;
1491 if (!torture_close_connection(cli)) {
1492 correct = False;
1495 printf("locktest2 finished\n");
1497 return correct;
1502 This test checks that
1504 1) the server supports the full offset range in lock requests
1506 static bool run_locktest3(int dummy)
1508 static struct cli_state *cli1, *cli2;
1509 const char *fname = "\\lockt3.lck";
1510 uint16_t fnum1, fnum2;
1511 int i;
1512 uint32 offset;
1513 bool correct = True;
1515 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1517 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1518 return False;
1520 cli_sockopt(cli1, sockops);
1521 cli_sockopt(cli2, sockops);
1523 printf("starting locktest3\n");
1525 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1527 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1528 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1529 return False;
1531 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1532 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1533 return False;
1536 for (offset=i=0;i<torture_numops;i++) {
1537 NEXT_OFFSET;
1538 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1539 printf("lock1 %d failed (%s)\n",
1541 cli_errstr(cli1));
1542 return False;
1545 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1546 printf("lock2 %d failed (%s)\n",
1548 cli_errstr(cli1));
1549 return False;
1553 for (offset=i=0;i<torture_numops;i++) {
1554 NEXT_OFFSET;
1556 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1557 printf("error: lock1 %d succeeded!\n", i);
1558 return False;
1561 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1562 printf("error: lock2 %d succeeded!\n", i);
1563 return False;
1566 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1567 printf("error: lock3 %d succeeded!\n", i);
1568 return False;
1571 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1572 printf("error: lock4 %d succeeded!\n", i);
1573 return False;
1577 for (offset=i=0;i<torture_numops;i++) {
1578 NEXT_OFFSET;
1580 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1581 printf("unlock1 %d failed (%s)\n",
1583 cli_errstr(cli1));
1584 return False;
1587 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1588 printf("unlock2 %d failed (%s)\n",
1590 cli_errstr(cli1));
1591 return False;
1595 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1596 printf("close1 failed (%s)\n", cli_errstr(cli1));
1597 return False;
1600 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1601 printf("close2 failed (%s)\n", cli_errstr(cli2));
1602 return False;
1605 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1606 printf("unlink failed (%s)\n", cli_errstr(cli1));
1607 return False;
1610 if (!torture_close_connection(cli1)) {
1611 correct = False;
1614 if (!torture_close_connection(cli2)) {
1615 correct = False;
1618 printf("finished locktest3\n");
1620 return correct;
1623 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1624 printf("** "); correct = False; \
1628 looks at overlapping locks
1630 static bool run_locktest4(int dummy)
1632 static struct cli_state *cli1, *cli2;
1633 const char *fname = "\\lockt4.lck";
1634 uint16_t fnum1, fnum2, f;
1635 bool ret;
1636 char buf[1000];
1637 bool correct = True;
1639 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1640 return False;
1643 cli_sockopt(cli1, sockops);
1644 cli_sockopt(cli2, sockops);
1646 printf("starting locktest4\n");
1648 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1650 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1651 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1653 memset(buf, 0, sizeof(buf));
1655 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1656 printf("Failed to create file\n");
1657 correct = False;
1658 goto fail;
1661 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1662 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1663 EXPECTED(ret, False);
1664 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1666 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1667 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1668 EXPECTED(ret, True);
1669 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1671 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1672 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1673 EXPECTED(ret, False);
1674 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1676 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1677 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1678 EXPECTED(ret, True);
1679 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1681 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1682 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1683 EXPECTED(ret, False);
1684 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1686 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1687 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1688 EXPECTED(ret, True);
1689 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1691 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1692 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1693 EXPECTED(ret, True);
1694 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1696 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1697 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1698 EXPECTED(ret, False);
1699 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1701 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1702 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1703 EXPECTED(ret, False);
1704 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1706 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1707 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1708 EXPECTED(ret, True);
1709 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1711 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1712 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1713 EXPECTED(ret, False);
1714 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1716 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1717 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1718 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1719 EXPECTED(ret, False);
1720 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1723 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1724 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1725 EXPECTED(ret, False);
1726 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1728 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1729 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1730 EXPECTED(ret, False);
1731 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1734 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1735 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1736 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1737 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1738 EXPECTED(ret, True);
1739 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1742 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1743 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1744 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1745 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1746 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1747 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1748 EXPECTED(ret, True);
1749 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1751 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1752 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1753 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1754 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1755 EXPECTED(ret, True);
1756 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1758 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1759 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1760 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1761 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1762 EXPECTED(ret, True);
1763 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1765 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1766 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1767 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1768 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1769 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1770 EXPECTED(ret, True);
1771 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1773 cli_close(cli1, fnum1);
1774 cli_close(cli2, fnum2);
1775 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1776 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1777 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1778 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1779 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1780 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1781 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1782 cli_close(cli1, f);
1783 cli_close(cli1, fnum1);
1784 EXPECTED(ret, True);
1785 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1787 fail:
1788 cli_close(cli1, fnum1);
1789 cli_close(cli2, fnum2);
1790 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1791 torture_close_connection(cli1);
1792 torture_close_connection(cli2);
1794 printf("finished locktest4\n");
1795 return correct;
1799 looks at lock upgrade/downgrade.
1801 static bool run_locktest5(int dummy)
1803 static struct cli_state *cli1, *cli2;
1804 const char *fname = "\\lockt5.lck";
1805 uint16_t fnum1, fnum2, fnum3;
1806 bool ret;
1807 char buf[1000];
1808 bool correct = True;
1810 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1811 return False;
1814 cli_sockopt(cli1, sockops);
1815 cli_sockopt(cli2, sockops);
1817 printf("starting locktest5\n");
1819 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1821 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1822 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1823 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1825 memset(buf, 0, sizeof(buf));
1827 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1828 printf("Failed to create file\n");
1829 correct = False;
1830 goto fail;
1833 /* Check for NT bug... */
1834 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1835 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1836 cli_close(cli1, fnum1);
1837 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1838 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1839 EXPECTED(ret, True);
1840 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1841 cli_close(cli1, fnum1);
1842 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1843 cli_unlock(cli1, fnum3, 0, 1);
1845 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1846 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1847 EXPECTED(ret, True);
1848 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1850 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1851 EXPECTED(ret, False);
1853 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1855 /* Unlock the process 2 lock. */
1856 cli_unlock(cli2, fnum2, 0, 4);
1858 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1859 EXPECTED(ret, False);
1861 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1863 /* Unlock the process 1 fnum3 lock. */
1864 cli_unlock(cli1, fnum3, 0, 4);
1866 /* Stack 2 more locks here. */
1867 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1868 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1870 EXPECTED(ret, True);
1871 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1873 /* Unlock the first process lock, then check this was the WRITE lock that was
1874 removed. */
1876 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1877 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1879 EXPECTED(ret, True);
1880 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1882 /* Unlock the process 2 lock. */
1883 cli_unlock(cli2, fnum2, 0, 4);
1885 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1887 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1888 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1889 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1891 EXPECTED(ret, True);
1892 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1894 /* Ensure the next unlock fails. */
1895 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1896 EXPECTED(ret, False);
1897 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1899 /* Ensure connection 2 can get a write lock. */
1900 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1901 EXPECTED(ret, True);
1903 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1906 fail:
1907 cli_close(cli1, fnum1);
1908 cli_close(cli2, fnum2);
1909 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1910 if (!torture_close_connection(cli1)) {
1911 correct = False;
1913 if (!torture_close_connection(cli2)) {
1914 correct = False;
1917 printf("finished locktest5\n");
1919 return correct;
1923 tries the unusual lockingX locktype bits
1925 static bool run_locktest6(int dummy)
1927 static struct cli_state *cli;
1928 const char *fname[1] = { "\\lock6.txt" };
1929 int i;
1930 uint16_t fnum;
1931 NTSTATUS status;
1933 if (!torture_open_connection(&cli, 0)) {
1934 return False;
1937 cli_sockopt(cli, sockops);
1939 printf("starting locktest6\n");
1941 for (i=0;i<1;i++) {
1942 printf("Testing %s\n", fname[i]);
1944 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1946 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1947 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1948 cli_close(cli, fnum);
1949 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1951 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1952 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1953 cli_close(cli, fnum);
1954 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1956 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1959 torture_close_connection(cli);
1961 printf("finished locktest6\n");
1962 return True;
1965 static bool run_locktest7(int dummy)
1967 struct cli_state *cli1;
1968 const char *fname = "\\lockt7.lck";
1969 uint16_t fnum1;
1970 char buf[200];
1971 bool correct = False;
1973 if (!torture_open_connection(&cli1, 0)) {
1974 return False;
1977 cli_sockopt(cli1, sockops);
1979 printf("starting locktest7\n");
1981 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1983 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1985 memset(buf, 0, sizeof(buf));
1987 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1988 printf("Failed to create file\n");
1989 goto fail;
1992 cli_setpid(cli1, 1);
1994 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1995 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1996 goto fail;
1997 } else {
1998 printf("pid1 successfully locked range 130:4 for READ\n");
2001 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2002 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2003 goto fail;
2004 } else {
2005 printf("pid1 successfully read the range 130:4\n");
2008 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2009 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2010 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2011 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2012 goto fail;
2014 } else {
2015 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2016 goto fail;
2019 cli_setpid(cli1, 2);
2021 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2022 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2023 } else {
2024 printf("pid2 successfully read the range 130:4\n");
2027 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2028 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2029 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2030 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2031 goto fail;
2033 } else {
2034 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2035 goto fail;
2038 cli_setpid(cli1, 1);
2039 cli_unlock(cli1, fnum1, 130, 4);
2041 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2042 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2043 goto fail;
2044 } else {
2045 printf("pid1 successfully locked range 130:4 for WRITE\n");
2048 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2049 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2050 goto fail;
2051 } else {
2052 printf("pid1 successfully read the range 130:4\n");
2055 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2056 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2057 goto fail;
2058 } else {
2059 printf("pid1 successfully wrote to the range 130:4\n");
2062 cli_setpid(cli1, 2);
2064 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2065 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2066 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2067 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2068 goto fail;
2070 } else {
2071 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2072 goto fail;
2075 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2076 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2077 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2078 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2079 goto fail;
2081 } else {
2082 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2083 goto fail;
2086 cli_unlock(cli1, fnum1, 130, 0);
2087 correct = True;
2089 fail:
2090 cli_close(cli1, fnum1);
2091 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2092 torture_close_connection(cli1);
2094 printf("finished locktest7\n");
2095 return correct;
2099 * This demonstrates a problem with our use of GPFS share modes: A file
2100 * descriptor sitting in the pending close queue holding a GPFS share mode
2101 * blocks opening a file another time. Happens with Word 2007 temp files.
2102 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2103 * open is denied with NT_STATUS_SHARING_VIOLATION.
2106 static bool run_locktest8(int dummy)
2108 struct cli_state *cli1;
2109 const char *fname = "\\lockt8.lck";
2110 uint16_t fnum1, fnum2;
2111 char buf[200];
2112 bool correct = False;
2113 NTSTATUS status;
2115 if (!torture_open_connection(&cli1, 0)) {
2116 return False;
2119 cli_sockopt(cli1, sockops);
2121 printf("starting locktest8\n");
2123 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2125 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2126 &fnum1);
2127 if (!NT_STATUS_IS_OK(status)) {
2128 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2129 return false;
2132 memset(buf, 0, sizeof(buf));
2134 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2135 if (!NT_STATUS_IS_OK(status)) {
2136 d_fprintf(stderr, "cli_open second time returned %s\n",
2137 cli_errstr(cli1));
2138 goto fail;
2141 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2142 printf("Unable to apply read lock on range 1:1, error was "
2143 "%s\n", cli_errstr(cli1));
2144 goto fail;
2147 status = cli_close(cli1, fnum1);
2148 if (!NT_STATUS_IS_OK(status)) {
2149 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2150 goto fail;
2153 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2154 if (!NT_STATUS_IS_OK(status)) {
2155 d_fprintf(stderr, "cli_open third time returned %s\n",
2156 cli_errstr(cli1));
2157 goto fail;
2160 correct = true;
2162 fail:
2163 cli_close(cli1, fnum1);
2164 cli_close(cli1, fnum2);
2165 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2166 torture_close_connection(cli1);
2168 printf("finished locktest8\n");
2169 return correct;
2173 * This test is designed to be run in conjunction with
2174 * external NFS or POSIX locks taken in the filesystem.
2175 * It checks that the smbd server will block until the
2176 * lock is released and then acquire it. JRA.
2179 static bool got_alarm;
2180 static int alarm_fd;
2182 static void alarm_handler(int dummy)
2184 got_alarm = True;
2187 static void alarm_handler_parent(int dummy)
2189 close(alarm_fd);
2192 static void do_local_lock(int read_fd, int write_fd)
2194 int fd;
2195 char c = '\0';
2196 struct flock lock;
2197 const char *local_pathname = NULL;
2198 int ret;
2200 local_pathname = talloc_asprintf(talloc_tos(),
2201 "%s/lockt9.lck", local_path);
2202 if (!local_pathname) {
2203 printf("child: alloc fail\n");
2204 exit(1);
2207 unlink(local_pathname);
2208 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2209 if (fd == -1) {
2210 printf("child: open of %s failed %s.\n",
2211 local_pathname, strerror(errno));
2212 exit(1);
2215 /* Now take a fcntl lock. */
2216 lock.l_type = F_WRLCK;
2217 lock.l_whence = SEEK_SET;
2218 lock.l_start = 0;
2219 lock.l_len = 4;
2220 lock.l_pid = getpid();
2222 ret = fcntl(fd,F_SETLK,&lock);
2223 if (ret == -1) {
2224 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2225 local_pathname, strerror(errno));
2226 exit(1);
2227 } else {
2228 printf("child: got lock 0:4 on file %s.\n",
2229 local_pathname );
2230 fflush(stdout);
2233 CatchSignal(SIGALRM, alarm_handler);
2234 alarm(5);
2235 /* Signal the parent. */
2236 if (write(write_fd, &c, 1) != 1) {
2237 printf("child: start signal fail %s.\n",
2238 strerror(errno));
2239 exit(1);
2241 alarm(0);
2243 alarm(10);
2244 /* Wait for the parent to be ready. */
2245 if (read(read_fd, &c, 1) != 1) {
2246 printf("child: reply signal fail %s.\n",
2247 strerror(errno));
2248 exit(1);
2250 alarm(0);
2252 sleep(5);
2253 close(fd);
2254 printf("child: released lock 0:4 on file %s.\n",
2255 local_pathname );
2256 fflush(stdout);
2257 exit(0);
2260 static bool run_locktest9(int dummy)
2262 struct cli_state *cli1;
2263 const char *fname = "\\lockt9.lck";
2264 uint16_t fnum;
2265 bool correct = False;
2266 int pipe_in[2], pipe_out[2];
2267 pid_t child_pid;
2268 char c = '\0';
2269 int ret;
2270 struct timeval start;
2271 double seconds;
2272 NTSTATUS status;
2274 printf("starting locktest9\n");
2276 if (local_path == NULL) {
2277 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2278 return false;
2281 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2282 return false;
2285 child_pid = fork();
2286 if (child_pid == -1) {
2287 return false;
2290 if (child_pid == 0) {
2291 /* Child. */
2292 do_local_lock(pipe_out[0], pipe_in[1]);
2293 exit(0);
2296 close(pipe_out[0]);
2297 close(pipe_in[1]);
2298 pipe_out[0] = -1;
2299 pipe_in[1] = -1;
2301 /* Parent. */
2302 ret = read(pipe_in[0], &c, 1);
2303 if (ret != 1) {
2304 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2305 strerror(errno));
2306 return false;
2309 if (!torture_open_connection(&cli1, 0)) {
2310 return false;
2313 cli_sockopt(cli1, sockops);
2315 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2316 &fnum);
2317 if (!NT_STATUS_IS_OK(status)) {
2318 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2319 return false;
2322 /* Ensure the child has the lock. */
2323 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2324 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2325 goto fail;
2326 } else {
2327 d_printf("Child has the lock.\n");
2330 /* Tell the child to wait 5 seconds then exit. */
2331 ret = write(pipe_out[1], &c, 1);
2332 if (ret != 1) {
2333 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2334 strerror(errno));
2335 goto fail;
2338 /* Wait 20 seconds for the lock. */
2339 alarm_fd = cli1->fd;
2340 CatchSignal(SIGALRM, alarm_handler_parent);
2341 alarm(20);
2343 start = timeval_current();
2345 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2346 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2347 "%s\n", cli_errstr(cli1));
2348 goto fail_nofd;
2350 alarm(0);
2352 seconds = timeval_elapsed(&start);
2354 printf("Parent got the lock after %.2f seconds.\n",
2355 seconds);
2357 status = cli_close(cli1, fnum);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2360 goto fail;
2363 correct = true;
2365 fail:
2366 cli_close(cli1, fnum);
2367 torture_close_connection(cli1);
2369 fail_nofd:
2371 printf("finished locktest9\n");
2372 return correct;
2376 test whether fnums and tids open on one VC are available on another (a major
2377 security hole)
2379 static bool run_fdpasstest(int dummy)
2381 struct cli_state *cli1, *cli2;
2382 const char *fname = "\\fdpass.tst";
2383 uint16_t fnum1;
2384 char buf[1024];
2386 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2387 return False;
2389 cli_sockopt(cli1, sockops);
2390 cli_sockopt(cli2, sockops);
2392 printf("starting fdpasstest\n");
2394 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2396 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2397 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2398 return False;
2401 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2402 printf("write failed (%s)\n", cli_errstr(cli1));
2403 return False;
2406 cli2->vuid = cli1->vuid;
2407 cli2->cnum = cli1->cnum;
2408 cli2->pid = cli1->pid;
2410 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2411 printf("read succeeded! nasty security hole [%s]\n",
2412 buf);
2413 return False;
2416 cli_close(cli1, fnum1);
2417 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2419 torture_close_connection(cli1);
2420 torture_close_connection(cli2);
2422 printf("finished fdpasstest\n");
2423 return True;
2426 static bool run_fdsesstest(int dummy)
2428 struct cli_state *cli;
2429 uint16 new_vuid;
2430 uint16 saved_vuid;
2431 uint16 new_cnum;
2432 uint16 saved_cnum;
2433 const char *fname = "\\fdsess.tst";
2434 const char *fname1 = "\\fdsess1.tst";
2435 uint16_t fnum1;
2436 uint16_t fnum2;
2437 char buf[1024];
2438 bool ret = True;
2440 if (!torture_open_connection(&cli, 0))
2441 return False;
2442 cli_sockopt(cli, sockops);
2444 if (!torture_cli_session_setup2(cli, &new_vuid))
2445 return False;
2447 saved_cnum = cli->cnum;
2448 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2449 return False;
2450 new_cnum = cli->cnum;
2451 cli->cnum = saved_cnum;
2453 printf("starting fdsesstest\n");
2455 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2456 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2458 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2459 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2460 return False;
2463 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2464 printf("write failed (%s)\n", cli_errstr(cli));
2465 return False;
2468 saved_vuid = cli->vuid;
2469 cli->vuid = new_vuid;
2471 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2472 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2473 buf);
2474 ret = False;
2476 /* Try to open a file with different vuid, samba cnum. */
2477 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2478 printf("create with different vuid, same cnum succeeded.\n");
2479 cli_close(cli, fnum2);
2480 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2481 } else {
2482 printf("create with different vuid, same cnum failed.\n");
2483 printf("This will cause problems with service clients.\n");
2484 ret = False;
2487 cli->vuid = saved_vuid;
2489 /* Try with same vuid, different cnum. */
2490 cli->cnum = new_cnum;
2492 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2493 printf("read succeeded with different cnum![%s]\n",
2494 buf);
2495 ret = False;
2498 cli->cnum = saved_cnum;
2499 cli_close(cli, fnum1);
2500 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2502 torture_close_connection(cli);
2504 printf("finished fdsesstest\n");
2505 return ret;
2509 This test checks that
2511 1) the server does not allow an unlink on a file that is open
2513 static bool run_unlinktest(int dummy)
2515 struct cli_state *cli;
2516 const char *fname = "\\unlink.tst";
2517 uint16_t fnum;
2518 bool correct = True;
2520 if (!torture_open_connection(&cli, 0)) {
2521 return False;
2524 cli_sockopt(cli, sockops);
2526 printf("starting unlink test\n");
2528 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2530 cli_setpid(cli, 1);
2532 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2533 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2534 return False;
2537 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2538 printf("error: server allowed unlink on an open file\n");
2539 correct = False;
2540 } else {
2541 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2542 NT_STATUS_SHARING_VIOLATION);
2545 cli_close(cli, fnum);
2546 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2548 if (!torture_close_connection(cli)) {
2549 correct = False;
2552 printf("unlink test finished\n");
2554 return correct;
2559 test how many open files this server supports on the one socket
2561 static bool run_maxfidtest(int dummy)
2563 struct cli_state *cli;
2564 const char *ftemplate = "\\maxfid.%d.%d";
2565 fstring fname;
2566 uint16_t fnums[0x11000];
2567 int i;
2568 int retries=4;
2569 bool correct = True;
2571 cli = current_cli;
2573 if (retries <= 0) {
2574 printf("failed to connect\n");
2575 return False;
2578 cli_sockopt(cli, sockops);
2580 for (i=0; i<0x11000; i++) {
2581 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2582 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2583 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2584 printf("open of %s failed (%s)\n",
2585 fname, cli_errstr(cli));
2586 printf("maximum fnum is %d\n", i);
2587 break;
2589 printf("%6d\r", i);
2591 printf("%6d\n", i);
2592 i--;
2594 printf("cleaning up\n");
2595 for (;i>=0;i--) {
2596 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2597 cli_close(cli, fnums[i]);
2598 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2599 printf("unlink of %s failed (%s)\n",
2600 fname, cli_errstr(cli));
2601 correct = False;
2603 printf("%6d\r", i);
2605 printf("%6d\n", 0);
2607 printf("maxfid test finished\n");
2608 if (!torture_close_connection(cli)) {
2609 correct = False;
2611 return correct;
2614 /* generate a random buffer */
2615 static void rand_buf(char *buf, int len)
2617 while (len--) {
2618 *buf = (char)sys_random();
2619 buf++;
2623 /* send smb negprot commands, not reading the response */
2624 static bool run_negprot_nowait(int dummy)
2626 int i;
2627 static struct cli_state *cli;
2628 bool correct = True;
2630 printf("starting negprot nowait test\n");
2632 if (!(cli = open_nbt_connection())) {
2633 return False;
2636 for (i=0;i<50000;i++) {
2637 cli_negprot_sendsync(cli);
2640 if (!torture_close_connection(cli)) {
2641 correct = False;
2644 printf("finished negprot nowait test\n");
2646 return correct;
2650 /* send random IPC commands */
2651 static bool run_randomipc(int dummy)
2653 char *rparam = NULL;
2654 char *rdata = NULL;
2655 unsigned int rdrcnt,rprcnt;
2656 char param[1024];
2657 int api, param_len, i;
2658 struct cli_state *cli;
2659 bool correct = True;
2660 int count = 50000;
2662 printf("starting random ipc test\n");
2664 if (!torture_open_connection(&cli, 0)) {
2665 return False;
2668 for (i=0;i<count;i++) {
2669 api = sys_random() % 500;
2670 param_len = (sys_random() % 64);
2672 rand_buf(param, param_len);
2674 SSVAL(param,0,api);
2676 cli_api(cli,
2677 param, param_len, 8,
2678 NULL, 0, BUFFER_SIZE,
2679 &rparam, &rprcnt,
2680 &rdata, &rdrcnt);
2681 if (i % 100 == 0) {
2682 printf("%d/%d\r", i,count);
2685 printf("%d/%d\n", i, count);
2687 if (!torture_close_connection(cli)) {
2688 correct = False;
2691 printf("finished random ipc test\n");
2693 return correct;
2698 static void browse_callback(const char *sname, uint32 stype,
2699 const char *comment, void *state)
2701 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2707 This test checks the browse list code
2710 static bool run_browsetest(int dummy)
2712 static struct cli_state *cli;
2713 bool correct = True;
2715 printf("starting browse test\n");
2717 if (!torture_open_connection(&cli, 0)) {
2718 return False;
2721 printf("domain list:\n");
2722 cli_NetServerEnum(cli, cli->server_domain,
2723 SV_TYPE_DOMAIN_ENUM,
2724 browse_callback, NULL);
2726 printf("machine list:\n");
2727 cli_NetServerEnum(cli, cli->server_domain,
2728 SV_TYPE_ALL,
2729 browse_callback, NULL);
2731 if (!torture_close_connection(cli)) {
2732 correct = False;
2735 printf("browse test finished\n");
2737 return correct;
2743 This checks how the getatr calls works
2745 static bool run_attrtest(int dummy)
2747 struct cli_state *cli;
2748 uint16_t fnum;
2749 time_t t, t2;
2750 const char *fname = "\\attrib123456789.tst";
2751 bool correct = True;
2753 printf("starting attrib test\n");
2755 if (!torture_open_connection(&cli, 0)) {
2756 return False;
2759 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2760 cli_open(cli, fname,
2761 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2762 cli_close(cli, fnum);
2763 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2764 printf("getatr failed (%s)\n", cli_errstr(cli));
2765 correct = False;
2768 if (abs(t - time(NULL)) > 60*60*24*10) {
2769 printf("ERROR: SMBgetatr bug. time is %s",
2770 ctime(&t));
2771 t = time(NULL);
2772 correct = True;
2775 t2 = t-60*60*24; /* 1 day ago */
2777 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2778 printf("setatr failed (%s)\n", cli_errstr(cli));
2779 correct = True;
2782 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2783 printf("getatr failed (%s)\n", cli_errstr(cli));
2784 correct = True;
2787 if (t != t2) {
2788 printf("ERROR: getatr/setatr bug. times are\n%s",
2789 ctime(&t));
2790 printf("%s", ctime(&t2));
2791 correct = True;
2794 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2796 if (!torture_close_connection(cli)) {
2797 correct = False;
2800 printf("attrib test finished\n");
2802 return correct;
2807 This checks a couple of trans2 calls
2809 static bool run_trans2test(int dummy)
2811 struct cli_state *cli;
2812 uint16_t fnum;
2813 SMB_OFF_T size;
2814 time_t c_time, a_time, m_time;
2815 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2816 const char *fname = "\\trans2.tst";
2817 const char *dname = "\\trans2";
2818 const char *fname2 = "\\trans2\\trans2.tst";
2819 char pname[1024];
2820 bool correct = True;
2821 NTSTATUS status;
2822 uint32_t fs_attr;
2824 printf("starting trans2 test\n");
2826 if (!torture_open_connection(&cli, 0)) {
2827 return False;
2830 status = cli_get_fs_attr_info(cli, &fs_attr);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2833 nt_errstr(status));
2834 correct = 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;
4355 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4357 uint16 major, minor;
4358 uint32 caplow, caphigh;
4359 NTSTATUS status;
4361 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4362 printf("Server doesn't support UNIX CIFS extensions.\n");
4363 return NT_STATUS_NOT_SUPPORTED;
4366 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4367 &caphigh);
4368 if (!NT_STATUS_IS_OK(status)) {
4369 printf("Server didn't return UNIX CIFS extensions: %s\n",
4370 nt_errstr(status));
4371 return status;
4374 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4375 caplow, caphigh);
4376 if (!NT_STATUS_IS_OK(status)) {
4377 printf("Server doesn't support setting UNIX CIFS extensions: "
4378 "%s.\n", nt_errstr(status));
4379 return status;
4382 return NT_STATUS_OK;
4386 Test POSIX open /mkdir calls.
4388 static bool run_simple_posix_open_test(int dummy)
4390 static struct cli_state *cli1;
4391 const char *fname = "posix:file";
4392 const char *hname = "posix:hlink";
4393 const char *sname = "posix:symlink";
4394 const char *dname = "posix:dir";
4395 char buf[10];
4396 char namebuf[11];
4397 uint16_t fnum1 = (uint16_t)-1;
4398 SMB_STRUCT_STAT sbuf;
4399 bool correct = false;
4400 NTSTATUS status;
4402 printf("Starting simple POSIX open test\n");
4404 if (!torture_open_connection(&cli1, 0)) {
4405 return false;
4408 cli_sockopt(cli1, sockops);
4410 status = torture_setup_unix_extensions(cli1);
4411 if (!NT_STATUS_IS_OK(status)) {
4412 return false;
4415 cli_setatr(cli1, fname, 0, 0);
4416 cli_posix_unlink(cli1, fname);
4417 cli_setatr(cli1, dname, 0, 0);
4418 cli_posix_rmdir(cli1, dname);
4419 cli_setatr(cli1, hname, 0, 0);
4420 cli_posix_unlink(cli1, hname);
4421 cli_setatr(cli1, sname, 0, 0);
4422 cli_posix_unlink(cli1, sname);
4424 /* Create a directory. */
4425 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4426 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4427 goto out;
4430 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4431 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4432 goto out;
4435 /* Test ftruncate - set file size. */
4436 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4437 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4438 goto out;
4441 /* Ensure st_size == 1000 */
4442 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4443 printf("stat failed (%s)\n", cli_errstr(cli1));
4444 goto out;
4447 if (sbuf.st_ex_size != 1000) {
4448 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4449 goto out;
4452 /* Test ftruncate - set file size back to zero. */
4453 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4454 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4455 goto out;
4458 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4459 printf("close failed (%s)\n", cli_errstr(cli1));
4460 goto out;
4463 /* Now open the file again for read only. */
4464 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4465 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4466 goto out;
4469 /* Now unlink while open. */
4470 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4471 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4472 goto out;
4475 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4476 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4477 goto out;
4480 /* Ensure the file has gone. */
4481 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4482 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4483 goto out;
4486 /* What happens when we try and POSIX open a directory ? */
4487 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4488 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4489 goto out;
4490 } else {
4491 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4492 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4493 goto out;
4497 /* Create the file. */
4498 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4499 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4500 goto out;
4503 /* Write some data into it. */
4504 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4505 printf("cli_write failed: %s\n", cli_errstr(cli1));
4506 goto out;
4509 cli_close(cli1, fnum1);
4511 /* Now create a hardlink. */
4512 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4513 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4514 goto out;
4517 /* Now create a symlink. */
4518 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4519 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4520 goto out;
4523 /* Open the hardlink for read. */
4524 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4525 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4526 goto out;
4529 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4530 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4531 goto out;
4534 if (memcmp(buf, "TEST DATA\n", 10)) {
4535 printf("invalid data read from hardlink\n");
4536 goto out;
4539 /* Do a POSIX lock/unlock. */
4540 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4541 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4542 goto out;
4545 /* Punch a hole in the locked area. */
4546 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4547 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4548 goto out;
4551 cli_close(cli1, fnum1);
4553 /* Open the symlink for read - this should fail. A POSIX
4554 client should not be doing opens on a symlink. */
4555 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4556 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4557 goto out;
4558 } else {
4559 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4560 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4561 printf("POSIX open of %s should have failed "
4562 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4563 "failed with %s instead.\n",
4564 sname, cli_errstr(cli1));
4565 goto out;
4569 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4570 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4571 goto out;
4574 if (strcmp(namebuf, fname) != 0) {
4575 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4576 sname, fname, namebuf);
4577 goto out;
4580 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4581 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4582 goto out;
4585 printf("Simple POSIX open test passed\n");
4586 correct = true;
4588 out:
4590 if (fnum1 != (uint16_t)-1) {
4591 cli_close(cli1, fnum1);
4592 fnum1 = (uint16_t)-1;
4595 cli_setatr(cli1, sname, 0, 0);
4596 cli_posix_unlink(cli1, sname);
4597 cli_setatr(cli1, hname, 0, 0);
4598 cli_posix_unlink(cli1, hname);
4599 cli_setatr(cli1, fname, 0, 0);
4600 cli_posix_unlink(cli1, fname);
4601 cli_setatr(cli1, dname, 0, 0);
4602 cli_posix_rmdir(cli1, dname);
4604 if (!torture_close_connection(cli1)) {
4605 correct = false;
4608 return correct;
4612 static uint32 open_attrs_table[] = {
4613 FILE_ATTRIBUTE_NORMAL,
4614 FILE_ATTRIBUTE_ARCHIVE,
4615 FILE_ATTRIBUTE_READONLY,
4616 FILE_ATTRIBUTE_HIDDEN,
4617 FILE_ATTRIBUTE_SYSTEM,
4619 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4620 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4621 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4622 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4623 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4624 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4626 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4627 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4628 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4629 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4632 struct trunc_open_results {
4633 unsigned int num;
4634 uint32 init_attr;
4635 uint32 trunc_attr;
4636 uint32 result_attr;
4639 static struct trunc_open_results attr_results[] = {
4640 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4641 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4642 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4643 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4644 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4645 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4646 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4647 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4648 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4649 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4650 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4651 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4652 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4653 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4654 { 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 },
4655 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4656 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4657 { 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 },
4658 { 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 },
4659 { 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 },
4660 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4661 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4662 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4663 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4664 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4665 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4668 static bool run_openattrtest(int dummy)
4670 static struct cli_state *cli1;
4671 const char *fname = "\\openattr.file";
4672 uint16_t fnum1;
4673 bool correct = True;
4674 uint16 attr;
4675 unsigned int i, j, k, l;
4677 printf("starting open attr test\n");
4679 if (!torture_open_connection(&cli1, 0)) {
4680 return False;
4683 cli_sockopt(cli1, sockops);
4685 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4686 cli_setatr(cli1, fname, 0, 0);
4687 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4688 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4689 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4690 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4691 return False;
4694 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4695 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4696 return False;
4699 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4701 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4702 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4703 if (attr_results[l].num == k) {
4704 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4705 k, open_attrs_table[i],
4706 open_attrs_table[j],
4707 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4708 correct = False;
4711 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4712 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4713 k, open_attrs_table[i], open_attrs_table[j],
4714 cli_errstr(cli1));
4715 correct = False;
4717 #if 0
4718 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4719 #endif
4720 k++;
4721 continue;
4724 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4725 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4726 return False;
4729 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4730 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4731 return False;
4734 #if 0
4735 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4736 k, open_attrs_table[i], open_attrs_table[j], attr );
4737 #endif
4739 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4740 if (attr_results[l].num == k) {
4741 if (attr != attr_results[l].result_attr ||
4742 open_attrs_table[i] != attr_results[l].init_attr ||
4743 open_attrs_table[j] != attr_results[l].trunc_attr) {
4744 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4745 open_attrs_table[i],
4746 open_attrs_table[j],
4747 (unsigned int)attr,
4748 attr_results[l].result_attr);
4749 correct = False;
4751 break;
4754 k++;
4758 cli_setatr(cli1, fname, 0, 0);
4759 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4761 printf("open attr test %s.\n", correct ? "passed" : "failed");
4763 if (!torture_close_connection(cli1)) {
4764 correct = False;
4766 return correct;
4769 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4775 test directory listing speed
4777 static bool run_dirtest(int dummy)
4779 int i;
4780 static struct cli_state *cli;
4781 uint16_t fnum;
4782 struct timeval core_start;
4783 bool correct = True;
4785 printf("starting directory test\n");
4787 if (!torture_open_connection(&cli, 0)) {
4788 return False;
4791 cli_sockopt(cli, sockops);
4793 srandom(0);
4794 for (i=0;i<torture_numops;i++) {
4795 fstring fname;
4796 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4797 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4798 fprintf(stderr,"Failed to open %s\n", fname);
4799 return False;
4801 cli_close(cli, fnum);
4804 core_start = timeval_current();
4806 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4807 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4808 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4810 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4812 srandom(0);
4813 for (i=0;i<torture_numops;i++) {
4814 fstring fname;
4815 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4816 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4819 if (!torture_close_connection(cli)) {
4820 correct = False;
4823 printf("finished dirtest\n");
4825 return correct;
4828 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4830 struct cli_state *pcli = (struct cli_state *)state;
4831 fstring fname;
4832 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4834 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4835 return;
4837 if (finfo->mode & aDIR) {
4838 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4839 printf("del_fn: failed to rmdir %s\n,", fname );
4840 } else {
4841 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4842 printf("del_fn: failed to unlink %s\n,", fname );
4848 sees what IOCTLs are supported
4850 bool torture_ioctl_test(int dummy)
4852 static struct cli_state *cli;
4853 uint16_t device, function;
4854 uint16_t fnum;
4855 const char *fname = "\\ioctl.dat";
4856 DATA_BLOB blob;
4857 NTSTATUS status;
4859 if (!torture_open_connection(&cli, 0)) {
4860 return False;
4863 printf("starting ioctl test\n");
4865 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4867 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4868 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4869 return False;
4872 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4873 printf("ioctl device info: %s\n", nt_errstr(status));
4875 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4876 printf("ioctl job info: %s\n", nt_errstr(status));
4878 for (device=0;device<0x100;device++) {
4879 printf("testing device=0x%x\n", device);
4880 for (function=0;function<0x100;function++) {
4881 uint32 code = (device<<16) | function;
4883 status = cli_raw_ioctl(cli, fnum, code, &blob);
4885 if (NT_STATUS_IS_OK(status)) {
4886 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4887 (int)blob.length);
4888 data_blob_free(&blob);
4893 if (!torture_close_connection(cli)) {
4894 return False;
4897 return True;
4902 tries varients of chkpath
4904 bool torture_chkpath_test(int dummy)
4906 static struct cli_state *cli;
4907 uint16_t fnum;
4908 bool ret;
4910 if (!torture_open_connection(&cli, 0)) {
4911 return False;
4914 printf("starting chkpath test\n");
4916 /* cleanup from an old run */
4917 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4918 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4919 cli_rmdir(cli, "\\chkpath.dir");
4921 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4922 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4923 return False;
4926 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4927 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4928 return False;
4931 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4932 printf("open1 failed (%s)\n", cli_errstr(cli));
4933 return False;
4935 cli_close(cli, fnum);
4937 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4938 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4939 ret = False;
4942 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4943 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4944 ret = False;
4947 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4948 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4949 NT_STATUS_NOT_A_DIRECTORY);
4950 } else {
4951 printf("* chkpath on a file should fail\n");
4952 ret = False;
4955 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4956 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4957 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4958 } else {
4959 printf("* chkpath on a non existant file should fail\n");
4960 ret = False;
4963 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4964 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4965 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4966 } else {
4967 printf("* chkpath on a non existent component should fail\n");
4968 ret = False;
4971 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4972 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4973 cli_rmdir(cli, "\\chkpath.dir");
4975 if (!torture_close_connection(cli)) {
4976 return False;
4979 return ret;
4982 static bool run_eatest(int dummy)
4984 static struct cli_state *cli;
4985 const char *fname = "\\eatest.txt";
4986 bool correct = True;
4987 uint16_t fnum;
4988 int i;
4989 size_t num_eas;
4990 struct ea_struct *ea_list = NULL;
4991 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4993 printf("starting eatest\n");
4995 if (!torture_open_connection(&cli, 0)) {
4996 talloc_destroy(mem_ctx);
4997 return False;
5000 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5001 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5002 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5003 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5004 0x4044, 0, &fnum))) {
5005 printf("open failed - %s\n", cli_errstr(cli));
5006 talloc_destroy(mem_ctx);
5007 return False;
5010 for (i = 0; i < 10; i++) {
5011 fstring ea_name, ea_val;
5013 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5014 memset(ea_val, (char)i+1, i+1);
5015 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5016 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5017 talloc_destroy(mem_ctx);
5018 return False;
5022 cli_close(cli, fnum);
5023 for (i = 0; i < 10; i++) {
5024 fstring ea_name, ea_val;
5026 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5027 memset(ea_val, (char)i+1, i+1);
5028 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5029 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5030 talloc_destroy(mem_ctx);
5031 return False;
5035 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5036 printf("ea_get list failed - %s\n", cli_errstr(cli));
5037 correct = False;
5040 printf("num_eas = %d\n", (int)num_eas);
5042 if (num_eas != 20) {
5043 printf("Should be 20 EA's stored... failing.\n");
5044 correct = False;
5047 for (i = 0; i < num_eas; i++) {
5048 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5049 dump_data(0, ea_list[i].value.data,
5050 ea_list[i].value.length);
5053 /* Setting EA's to zero length deletes them. Test this */
5054 printf("Now deleting all EA's - case indepenent....\n");
5056 #if 1
5057 cli_set_ea_path(cli, fname, "", "", 0);
5058 #else
5059 for (i = 0; i < 20; i++) {
5060 fstring ea_name;
5061 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5062 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5063 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5064 talloc_destroy(mem_ctx);
5065 return False;
5068 #endif
5070 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
5071 printf("ea_get list failed - %s\n", cli_errstr(cli));
5072 correct = False;
5075 printf("num_eas = %d\n", (int)num_eas);
5076 for (i = 0; i < num_eas; i++) {
5077 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5078 dump_data(0, ea_list[i].value.data,
5079 ea_list[i].value.length);
5082 if (num_eas != 0) {
5083 printf("deleting EA's failed.\n");
5084 correct = False;
5087 /* Try and delete a non existant EA. */
5088 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5089 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5090 correct = False;
5093 talloc_destroy(mem_ctx);
5094 if (!torture_close_connection(cli)) {
5095 correct = False;
5098 return correct;
5101 static bool run_dirtest1(int dummy)
5103 int i;
5104 static struct cli_state *cli;
5105 uint16_t fnum;
5106 int num_seen;
5107 bool correct = True;
5109 printf("starting directory test\n");
5111 if (!torture_open_connection(&cli, 0)) {
5112 return False;
5115 cli_sockopt(cli, sockops);
5117 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5118 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5119 cli_rmdir(cli, "\\LISTDIR");
5120 cli_mkdir(cli, "\\LISTDIR");
5122 /* Create 1000 files and 1000 directories. */
5123 for (i=0;i<1000;i++) {
5124 fstring fname;
5125 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5126 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5127 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5128 fprintf(stderr,"Failed to open %s\n", fname);
5129 return False;
5131 cli_close(cli, fnum);
5133 for (i=0;i<1000;i++) {
5134 fstring fname;
5135 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5136 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5137 fprintf(stderr,"Failed to open %s\n", fname);
5138 return False;
5142 /* Now ensure that doing an old list sees both files and directories. */
5143 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5144 printf("num_seen = %d\n", num_seen );
5145 /* We should see 100 files + 1000 directories + . and .. */
5146 if (num_seen != 2002)
5147 correct = False;
5149 /* Ensure if we have the "must have" bits we only see the
5150 * relevent entries.
5152 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5153 printf("num_seen = %d\n", num_seen );
5154 if (num_seen != 1002)
5155 correct = False;
5157 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5158 printf("num_seen = %d\n", num_seen );
5159 if (num_seen != 1000)
5160 correct = False;
5162 /* Delete everything. */
5163 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5164 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5165 cli_rmdir(cli, "\\LISTDIR");
5167 #if 0
5168 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5169 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5170 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5171 #endif
5173 if (!torture_close_connection(cli)) {
5174 correct = False;
5177 printf("finished dirtest1\n");
5179 return correct;
5182 static bool run_error_map_extract(int dummy) {
5184 static struct cli_state *c_dos;
5185 static struct cli_state *c_nt;
5186 NTSTATUS status;
5188 uint32 error;
5190 uint32 flgs2, errnum;
5191 uint8 errclass;
5193 NTSTATUS nt_status;
5195 fstring user;
5197 /* NT-Error connection */
5199 if (!(c_nt = open_nbt_connection())) {
5200 return False;
5203 c_nt->use_spnego = False;
5205 status = cli_negprot(c_nt);
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("%s rejected the NT-error negprot (%s)\n", host,
5209 nt_errstr(status));
5210 cli_shutdown(c_nt);
5211 return False;
5214 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5215 workgroup))) {
5216 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5217 return False;
5220 /* DOS-Error connection */
5222 if (!(c_dos = open_nbt_connection())) {
5223 return False;
5226 c_dos->use_spnego = False;
5227 c_dos->force_dos_errors = True;
5229 status = cli_negprot(c_dos);
5230 if (!NT_STATUS_IS_OK(status)) {
5231 printf("%s rejected the DOS-error negprot (%s)\n", host,
5232 nt_errstr(status));
5233 cli_shutdown(c_dos);
5234 return False;
5237 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5238 workgroup))) {
5239 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5240 return False;
5243 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5244 fstr_sprintf(user, "%X", error);
5246 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5247 password, strlen(password),
5248 password, strlen(password),
5249 workgroup))) {
5250 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5253 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5255 /* Case #1: 32-bit NT errors */
5256 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5257 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5258 } else {
5259 printf("/** Dos error on NT connection! (%s) */\n",
5260 cli_errstr(c_nt));
5261 nt_status = NT_STATUS(0xc0000000);
5264 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5265 password, strlen(password),
5266 password, strlen(password),
5267 workgroup))) {
5268 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5270 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5272 /* Case #1: 32-bit NT errors */
5273 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5274 printf("/** NT error on DOS connection! (%s) */\n",
5275 cli_errstr(c_nt));
5276 errnum = errclass = 0;
5277 } else {
5278 cli_dos_error(c_dos, &errclass, &errnum);
5281 if (NT_STATUS_V(nt_status) != error) {
5282 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5283 get_nt_error_c_code(NT_STATUS(error)),
5284 get_nt_error_c_code(nt_status));
5287 printf("\t{%s,\t%s,\t%s},\n",
5288 smb_dos_err_class(errclass),
5289 smb_dos_err_name(errclass, errnum),
5290 get_nt_error_c_code(NT_STATUS(error)));
5292 return True;
5295 static bool run_sesssetup_bench(int dummy)
5297 static struct cli_state *c;
5298 const char *fname = "\\file.dat";
5299 uint16_t fnum;
5300 NTSTATUS status;
5301 int i;
5303 if (!torture_open_connection(&c, 0)) {
5304 return false;
5307 if (!NT_STATUS_IS_OK(cli_ntcreate(
5308 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5309 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5310 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5311 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5312 return false;
5315 for (i=0; i<torture_numops; i++) {
5316 status = cli_session_setup(
5317 c, username,
5318 password, strlen(password),
5319 password, strlen(password),
5320 workgroup);
5321 if (!NT_STATUS_IS_OK(status)) {
5322 d_printf("(%s) cli_session_setup failed: %s\n",
5323 __location__, nt_errstr(status));
5324 return false;
5327 d_printf("\r%d ", (int)c->vuid);
5329 status = cli_ulogoff(c);
5330 if (!NT_STATUS_IS_OK(status)) {
5331 d_printf("(%s) cli_ulogoff failed: %s\n",
5332 __location__, nt_errstr(status));
5333 return false;
5335 c->vuid = 0;
5338 return true;
5341 static bool subst_test(const char *str, const char *user, const char *domain,
5342 uid_t uid, gid_t gid, const char *expected)
5344 char *subst;
5345 bool result = true;
5347 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5349 if (strcmp(subst, expected) != 0) {
5350 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5351 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5352 expected);
5353 result = false;
5356 TALLOC_FREE(subst);
5357 return result;
5360 static void chain1_open_completion(struct tevent_req *req)
5362 uint16_t fnum;
5363 NTSTATUS status;
5364 status = cli_open_recv(req, &fnum);
5365 TALLOC_FREE(req);
5367 d_printf("cli_open_recv returned %s: %d\n",
5368 nt_errstr(status),
5369 NT_STATUS_IS_OK(status) ? fnum : -1);
5372 static void chain1_write_completion(struct tevent_req *req)
5374 size_t written;
5375 NTSTATUS status;
5376 status = cli_write_andx_recv(req, &written);
5377 TALLOC_FREE(req);
5379 d_printf("cli_write_andx_recv returned %s: %d\n",
5380 nt_errstr(status),
5381 NT_STATUS_IS_OK(status) ? (int)written : -1);
5384 static void chain1_close_completion(struct tevent_req *req)
5386 NTSTATUS status;
5387 bool *done = (bool *)tevent_req_callback_data_void(req);
5389 status = cli_close_recv(req);
5390 *done = true;
5392 TALLOC_FREE(req);
5394 d_printf("cli_close returned %s\n", nt_errstr(status));
5397 static bool run_chain1(int dummy)
5399 struct cli_state *cli1;
5400 struct event_context *evt = event_context_init(NULL);
5401 struct tevent_req *reqs[3], *smbreqs[3];
5402 bool done = false;
5403 const char *str = "foobar";
5404 NTSTATUS status;
5406 printf("starting chain1 test\n");
5407 if (!torture_open_connection(&cli1, 0)) {
5408 return False;
5411 cli_sockopt(cli1, sockops);
5413 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5414 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5415 if (reqs[0] == NULL) return false;
5416 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5419 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5420 (uint8_t *)str, 0, strlen(str)+1,
5421 smbreqs, 1, &smbreqs[1]);
5422 if (reqs[1] == NULL) return false;
5423 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5425 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5426 if (reqs[2] == NULL) return false;
5427 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5429 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5430 if (!NT_STATUS_IS_OK(status)) {
5431 return false;
5434 while (!done) {
5435 event_loop_once(evt);
5438 torture_close_connection(cli1);
5439 return True;
5442 static void chain2_sesssetup_completion(struct tevent_req *req)
5444 NTSTATUS status;
5445 status = cli_session_setup_guest_recv(req);
5446 d_printf("sesssetup returned %s\n", nt_errstr(status));
5449 static void chain2_tcon_completion(struct tevent_req *req)
5451 bool *done = (bool *)tevent_req_callback_data_void(req);
5452 NTSTATUS status;
5453 status = cli_tcon_andx_recv(req);
5454 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5455 *done = true;
5458 static bool run_chain2(int dummy)
5460 struct cli_state *cli1;
5461 struct event_context *evt = event_context_init(NULL);
5462 struct tevent_req *reqs[2], *smbreqs[2];
5463 bool done = false;
5464 NTSTATUS status;
5466 printf("starting chain2 test\n");
5467 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5468 port_to_use, Undefined, 0, NULL);
5469 if (!NT_STATUS_IS_OK(status)) {
5470 return False;
5473 cli_sockopt(cli1, sockops);
5475 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5476 &smbreqs[0]);
5477 if (reqs[0] == NULL) return false;
5478 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5480 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5481 "?????", NULL, 0, &smbreqs[1]);
5482 if (reqs[1] == NULL) return false;
5483 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5485 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5486 if (!NT_STATUS_IS_OK(status)) {
5487 return false;
5490 while (!done) {
5491 event_loop_once(evt);
5494 torture_close_connection(cli1);
5495 return True;
5499 struct torture_createdel_state {
5500 struct tevent_context *ev;
5501 struct cli_state *cli;
5504 static void torture_createdel_created(struct tevent_req *subreq);
5505 static void torture_createdel_closed(struct tevent_req *subreq);
5507 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5508 struct tevent_context *ev,
5509 struct cli_state *cli,
5510 const char *name)
5512 struct tevent_req *req, *subreq;
5513 struct torture_createdel_state *state;
5515 req = tevent_req_create(mem_ctx, &state,
5516 struct torture_createdel_state);
5517 if (req == NULL) {
5518 return NULL;
5520 state->ev = ev;
5521 state->cli = cli;
5523 subreq = cli_ntcreate_send(
5524 state, ev, cli, name, 0,
5525 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5526 FILE_ATTRIBUTE_NORMAL,
5527 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5528 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5530 if (tevent_req_nomem(subreq, req)) {
5531 return tevent_req_post(req, ev);
5533 tevent_req_set_callback(subreq, torture_createdel_created, req);
5534 return req;
5537 static void torture_createdel_created(struct tevent_req *subreq)
5539 struct tevent_req *req = tevent_req_callback_data(
5540 subreq, struct tevent_req);
5541 struct torture_createdel_state *state = tevent_req_data(
5542 req, struct torture_createdel_state);
5543 NTSTATUS status;
5544 uint16_t fnum;
5546 status = cli_ntcreate_recv(subreq, &fnum);
5547 TALLOC_FREE(subreq);
5548 if (!NT_STATUS_IS_OK(status)) {
5549 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5550 nt_errstr(status)));
5551 tevent_req_nterror(req, status);
5552 return;
5555 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5556 if (tevent_req_nomem(subreq, req)) {
5557 return;
5559 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5562 static void torture_createdel_closed(struct tevent_req *subreq)
5564 struct tevent_req *req = tevent_req_callback_data(
5565 subreq, struct tevent_req);
5566 NTSTATUS status;
5568 status = cli_close_recv(subreq);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5571 tevent_req_nterror(req, status);
5572 return;
5574 tevent_req_done(req);
5577 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5579 return tevent_req_simple_recv_ntstatus(req);
5582 struct torture_createdels_state {
5583 struct tevent_context *ev;
5584 struct cli_state *cli;
5585 const char *base_name;
5586 int sent;
5587 int received;
5588 int num_files;
5589 struct tevent_req **reqs;
5592 static void torture_createdels_done(struct tevent_req *subreq);
5594 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5595 struct tevent_context *ev,
5596 struct cli_state *cli,
5597 const char *base_name,
5598 int num_parallel,
5599 int num_files)
5601 struct tevent_req *req;
5602 struct torture_createdels_state *state;
5603 int i;
5605 req = tevent_req_create(mem_ctx, &state,
5606 struct torture_createdels_state);
5607 if (req == NULL) {
5608 return NULL;
5610 state->ev = ev;
5611 state->cli = cli;
5612 state->base_name = talloc_strdup(state, base_name);
5613 if (tevent_req_nomem(state->base_name, req)) {
5614 return tevent_req_post(req, ev);
5616 state->num_files = MAX(num_parallel, num_files);
5617 state->sent = 0;
5618 state->received = 0;
5620 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5621 if (tevent_req_nomem(state->reqs, req)) {
5622 return tevent_req_post(req, ev);
5625 for (i=0; i<num_parallel; i++) {
5626 char *name;
5628 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5629 state->sent);
5630 if (tevent_req_nomem(name, req)) {
5631 return tevent_req_post(req, ev);
5633 state->reqs[i] = torture_createdel_send(
5634 state->reqs, state->ev, state->cli, name);
5635 if (tevent_req_nomem(state->reqs[i], req)) {
5636 return tevent_req_post(req, ev);
5638 name = talloc_move(state->reqs[i], &name);
5639 tevent_req_set_callback(state->reqs[i],
5640 torture_createdels_done, req);
5641 state->sent += 1;
5643 return req;
5646 static void torture_createdels_done(struct tevent_req *subreq)
5648 struct tevent_req *req = tevent_req_callback_data(
5649 subreq, struct tevent_req);
5650 struct torture_createdels_state *state = tevent_req_data(
5651 req, struct torture_createdels_state);
5652 size_t num_parallel = talloc_array_length(state->reqs);
5653 NTSTATUS status;
5654 char *name;
5655 int i;
5657 status = torture_createdel_recv(subreq);
5658 if (!NT_STATUS_IS_OK(status)){
5659 DEBUG(10, ("torture_createdel_recv returned %s\n",
5660 nt_errstr(status)));
5661 TALLOC_FREE(subreq);
5662 tevent_req_nterror(req, status);
5663 return;
5666 for (i=0; i<num_parallel; i++) {
5667 if (subreq == state->reqs[i]) {
5668 break;
5671 if (i == num_parallel) {
5672 DEBUG(10, ("received something we did not send\n"));
5673 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5674 return;
5676 TALLOC_FREE(state->reqs[i]);
5678 if (state->sent >= state->num_files) {
5679 tevent_req_done(req);
5680 return;
5683 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5684 state->sent);
5685 if (tevent_req_nomem(name, req)) {
5686 return;
5688 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5689 state->cli, name);
5690 if (tevent_req_nomem(state->reqs[i], req)) {
5691 return;
5693 name = talloc_move(state->reqs[i], &name);
5694 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5695 state->sent += 1;
5698 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5700 return tevent_req_simple_recv_ntstatus(req);
5703 struct swallow_notify_state {
5704 struct tevent_context *ev;
5705 struct cli_state *cli;
5706 uint16_t fnum;
5707 uint32_t completion_filter;
5708 bool recursive;
5709 bool (*fn)(uint32_t action, const char *name, void *priv);
5710 void *priv;
5713 static void swallow_notify_done(struct tevent_req *subreq);
5715 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5716 struct tevent_context *ev,
5717 struct cli_state *cli,
5718 uint16_t fnum,
5719 uint32_t completion_filter,
5720 bool recursive,
5721 bool (*fn)(uint32_t action,
5722 const char *name,
5723 void *priv),
5724 void *priv)
5726 struct tevent_req *req, *subreq;
5727 struct swallow_notify_state *state;
5729 req = tevent_req_create(mem_ctx, &state,
5730 struct swallow_notify_state);
5731 if (req == NULL) {
5732 return NULL;
5734 state->ev = ev;
5735 state->cli = cli;
5736 state->fnum = fnum;
5737 state->completion_filter = completion_filter;
5738 state->recursive = recursive;
5739 state->fn = fn;
5740 state->priv = priv;
5742 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5743 0xffff, state->completion_filter,
5744 state->recursive);
5745 if (tevent_req_nomem(subreq, req)) {
5746 return tevent_req_post(req, ev);
5748 tevent_req_set_callback(subreq, swallow_notify_done, req);
5749 return req;
5752 static void swallow_notify_done(struct tevent_req *subreq)
5754 struct tevent_req *req = tevent_req_callback_data(
5755 subreq, struct tevent_req);
5756 struct swallow_notify_state *state = tevent_req_data(
5757 req, struct swallow_notify_state);
5758 NTSTATUS status;
5759 uint32_t i, num_changes;
5760 struct notify_change *changes;
5762 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5763 TALLOC_FREE(subreq);
5764 if (!NT_STATUS_IS_OK(status)) {
5765 DEBUG(10, ("cli_notify_recv returned %s\n",
5766 nt_errstr(status)));
5767 tevent_req_nterror(req, status);
5768 return;
5771 for (i=0; i<num_changes; i++) {
5772 state->fn(changes[i].action, changes[i].name, state->priv);
5774 TALLOC_FREE(changes);
5776 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5777 0xffff, state->completion_filter,
5778 state->recursive);
5779 if (tevent_req_nomem(subreq, req)) {
5780 return;
5782 tevent_req_set_callback(subreq, swallow_notify_done, req);
5785 static bool print_notifies(uint32_t action, const char *name, void *priv)
5787 if (DEBUGLEVEL > 5) {
5788 d_printf("%d %s\n", (int)action, name);
5790 return true;
5793 static void notify_bench_done(struct tevent_req *req)
5795 int *num_finished = (int *)tevent_req_callback_data_void(req);
5796 *num_finished += 1;
5799 static bool run_notify_bench(int dummy)
5801 const char *dname = "\\notify-bench";
5802 struct tevent_context *ev;
5803 NTSTATUS status;
5804 uint16_t dnum;
5805 struct tevent_req *req1;
5806 struct tevent_req *req2 = NULL;
5807 int i, num_unc_names;
5808 int num_finished = 0;
5810 printf("starting notify-bench test\n");
5812 if (use_multishare_conn) {
5813 char **unc_list;
5814 unc_list = file_lines_load(multishare_conn_fname,
5815 &num_unc_names, 0, NULL);
5816 if (!unc_list || num_unc_names <= 0) {
5817 d_printf("Failed to load unc names list from '%s'\n",
5818 multishare_conn_fname);
5819 return false;
5821 TALLOC_FREE(unc_list);
5822 } else {
5823 num_unc_names = 1;
5826 ev = tevent_context_init(talloc_tos());
5827 if (ev == NULL) {
5828 d_printf("tevent_context_init failed\n");
5829 return false;
5832 for (i=0; i<num_unc_names; i++) {
5833 struct cli_state *cli;
5834 char *base_fname;
5836 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5837 dname, i);
5838 if (base_fname == NULL) {
5839 return false;
5842 if (!torture_open_connection(&cli, i)) {
5843 return false;
5846 status = cli_ntcreate(cli, dname, 0,
5847 MAXIMUM_ALLOWED_ACCESS,
5848 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5849 FILE_SHARE_DELETE,
5850 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5851 &dnum);
5853 if (!NT_STATUS_IS_OK(status)) {
5854 d_printf("Could not create %s: %s\n", dname,
5855 nt_errstr(status));
5856 return false;
5859 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5860 FILE_NOTIFY_CHANGE_FILE_NAME |
5861 FILE_NOTIFY_CHANGE_DIR_NAME |
5862 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5863 FILE_NOTIFY_CHANGE_LAST_WRITE,
5864 false, print_notifies, NULL);
5865 if (req1 == NULL) {
5866 d_printf("Could not create notify request\n");
5867 return false;
5870 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5871 base_fname, 10, torture_numops);
5872 if (req2 == NULL) {
5873 d_printf("Could not create createdels request\n");
5874 return false;
5876 TALLOC_FREE(base_fname);
5878 tevent_req_set_callback(req2, notify_bench_done,
5879 &num_finished);
5882 while (num_finished < num_unc_names) {
5883 int ret;
5884 ret = tevent_loop_once(ev);
5885 if (ret != 0) {
5886 d_printf("tevent_loop_once failed\n");
5887 return false;
5891 if (!tevent_req_poll(req2, ev)) {
5892 d_printf("tevent_req_poll failed\n");
5895 status = torture_createdels_recv(req2);
5896 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5898 return true;
5901 static bool run_mangle1(int dummy)
5903 struct cli_state *cli;
5904 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5905 uint16_t fnum;
5906 fstring alt_name;
5907 NTSTATUS status;
5908 time_t change_time, access_time, write_time;
5909 SMB_OFF_T size;
5910 uint16_t mode;
5912 printf("starting mangle1 test\n");
5913 if (!torture_open_connection(&cli, 0)) {
5914 return False;
5917 cli_sockopt(cli, sockops);
5919 if (!NT_STATUS_IS_OK(cli_ntcreate(
5920 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5921 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5922 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5923 return false;
5925 cli_close(cli, fnum);
5927 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5928 if (!NT_STATUS_IS_OK(status)) {
5929 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5930 nt_errstr(status));
5931 return false;
5933 d_printf("alt_name: %s\n", alt_name);
5935 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5936 d_printf("cli_open(%s) failed: %s\n", alt_name,
5937 cli_errstr(cli));
5938 return false;
5940 cli_close(cli, fnum);
5942 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5943 &write_time, &size, &mode)) {
5944 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5945 cli_errstr(cli));
5946 return false;
5949 return true;
5952 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5954 size_t *to_pull = (size_t *)priv;
5955 size_t thistime = *to_pull;
5957 thistime = MIN(thistime, n);
5958 if (thistime == 0) {
5959 return 0;
5962 memset(buf, 0, thistime);
5963 *to_pull -= thistime;
5964 return thistime;
5967 static bool run_windows_write(int dummy)
5969 struct cli_state *cli1;
5970 uint16_t fnum;
5971 int i;
5972 bool ret = false;
5973 const char *fname = "\\writetest.txt";
5974 struct timeval start_time;
5975 double seconds;
5976 double kbytes;
5978 printf("starting windows_write test\n");
5979 if (!torture_open_connection(&cli1, 0)) {
5980 return False;
5983 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5984 printf("open failed (%s)\n", cli_errstr(cli1));
5985 return False;
5988 cli_sockopt(cli1, sockops);
5990 start_time = timeval_current();
5992 for (i=0; i<torture_numops; i++) {
5993 char c = 0;
5994 off_t start = i * torture_blocksize;
5995 NTSTATUS status;
5996 size_t to_pull = torture_blocksize - 1;
5998 if (cli_write(cli1, fnum, 0, &c,
5999 start + torture_blocksize - 1, 1) != 1) {
6000 printf("cli_write failed: %s\n", cli_errstr(cli1));
6001 goto fail;
6004 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6005 null_source, &to_pull);
6006 if (!NT_STATUS_IS_OK(status)) {
6007 printf("cli_push returned: %s\n", nt_errstr(status));
6008 goto fail;
6012 seconds = timeval_elapsed(&start_time);
6013 kbytes = (double)torture_blocksize * torture_numops;
6014 kbytes /= 1024;
6016 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6017 (double)seconds, (int)(kbytes/seconds));
6019 ret = true;
6020 fail:
6021 cli_close(cli1, fnum);
6022 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6023 torture_close_connection(cli1);
6024 return ret;
6027 static bool run_cli_echo(int dummy)
6029 struct cli_state *cli;
6030 NTSTATUS status;
6032 printf("starting cli_echo test\n");
6033 if (!torture_open_connection(&cli, 0)) {
6034 return false;
6036 cli_sockopt(cli, sockops);
6038 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6040 d_printf("cli_echo returned %s\n", nt_errstr(status));
6042 torture_close_connection(cli);
6043 return NT_STATUS_IS_OK(status);
6046 static bool run_uid_regression_test(int dummy)
6048 static struct cli_state *cli;
6049 int16_t old_vuid;
6050 int16_t old_cnum;
6051 bool correct = True;
6052 NTSTATUS status;
6054 printf("starting uid regression test\n");
6056 if (!torture_open_connection(&cli, 0)) {
6057 return False;
6060 cli_sockopt(cli, sockops);
6062 /* Ok - now save then logoff our current user. */
6063 old_vuid = cli->vuid;
6065 status = cli_ulogoff(cli);
6066 if (!NT_STATUS_IS_OK(status)) {
6067 d_printf("(%s) cli_ulogoff failed: %s\n",
6068 __location__, nt_errstr(status));
6069 correct = false;
6070 goto out;
6073 cli->vuid = old_vuid;
6075 /* Try an operation. */
6076 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6077 /* We expect bad uid. */
6078 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6079 NT_STATUS_NO_SUCH_USER)) {
6080 return False;
6084 old_cnum = cli->cnum;
6086 /* Now try a SMBtdis with the invald vuid set to zero. */
6087 cli->vuid = 0;
6089 /* This should succeed. */
6090 status = cli_tdis(cli);
6092 if (NT_STATUS_IS_OK(status)) {
6093 printf("First tdis with invalid vuid should succeed.\n");
6094 } else {
6095 printf("First tdis failed (%s)\n", nt_errstr(status));
6098 cli->vuid = old_vuid;
6099 cli->cnum = old_cnum;
6101 /* This should fail. */
6102 status = cli_tdis(cli);
6103 if (NT_STATUS_IS_OK(status)) {
6104 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6105 } else {
6106 /* Should be bad tid. */
6107 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6108 NT_STATUS_NETWORK_NAME_DELETED)) {
6109 return False;
6113 cli_rmdir(cli, "\\uid_reg_test");
6115 out:
6117 cli_shutdown(cli);
6118 return correct;
6122 static const char *illegal_chars = "*\\/?<>|\":";
6123 static char force_shortname_chars[] = " +,.[];=\177";
6125 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
6127 struct cli_state *pcli = (struct cli_state *)state;
6128 fstring fname;
6129 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6131 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6132 return;
6134 if (finfo->mode & aDIR) {
6135 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6136 printf("del_fn: failed to rmdir %s\n,", fname );
6137 } else {
6138 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6139 printf("del_fn: failed to unlink %s\n,", fname );
6143 struct sn_state {
6144 int i;
6145 bool val;
6148 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
6150 struct sn_state *s = (struct sn_state *)state;
6151 int i = s->i;
6153 #if 0
6154 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6155 i, finfo->name, finfo->short_name);
6156 #endif
6158 if (strchr(force_shortname_chars, i)) {
6159 if (!finfo->short_name[0]) {
6160 /* Shortname not created when it should be. */
6161 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6162 __location__, finfo->name, i);
6163 s->val = true;
6165 } else if (finfo->short_name[0]){
6166 /* Shortname created when it should not be. */
6167 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6168 __location__, finfo->short_name, finfo->name);
6169 s->val = true;
6173 static bool run_shortname_test(int dummy)
6175 static struct cli_state *cli;
6176 bool correct = True;
6177 int i;
6178 struct sn_state s;
6179 char fname[20];
6181 printf("starting shortname test\n");
6183 if (!torture_open_connection(&cli, 0)) {
6184 return False;
6187 cli_sockopt(cli, sockops);
6189 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6190 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6191 cli_rmdir(cli, "\\shortname");
6193 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6194 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6195 __location__, cli_errstr(cli));
6196 correct = false;
6197 goto out;
6200 strlcpy(fname, "\\shortname\\", sizeof(fname));
6201 strlcat(fname, "test .txt", sizeof(fname));
6203 s.val = false;
6205 for (i = 32; i < 128; i++) {
6206 NTSTATUS status;
6207 uint16_t fnum = (uint16_t)-1;
6209 s.i = i;
6211 if (strchr(illegal_chars, i)) {
6212 continue;
6214 fname[15] = i;
6216 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6217 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6220 __location__, fname, cli_errstr(cli));
6221 correct = false;
6222 goto out;
6224 cli_close(cli, fnum);
6225 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
6226 d_printf("(%s) failed to list %s: %s\n",
6227 __location__, fname, cli_errstr(cli));
6228 correct = false;
6229 goto out;
6231 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6232 d_printf("(%s) failed to delete %s: %s\n",
6233 __location__, fname, cli_errstr(cli));
6234 correct = false;
6235 goto out;
6238 if (s.val) {
6239 correct = false;
6240 goto out;
6244 out:
6246 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6247 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6248 cli_rmdir(cli, "\\shortname");
6249 torture_close_connection(cli);
6250 return correct;
6253 static void pagedsearch_cb(struct tevent_req *req)
6255 int rc;
6256 struct tldap_message *msg;
6257 char *dn;
6259 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6260 if (rc != TLDAP_SUCCESS) {
6261 d_printf("tldap_search_paged_recv failed: %s\n",
6262 tldap_err2string(rc));
6263 return;
6265 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6266 TALLOC_FREE(msg);
6267 return;
6269 if (!tldap_entry_dn(msg, &dn)) {
6270 d_printf("tldap_entry_dn failed\n");
6271 return;
6273 d_printf("%s\n", dn);
6274 TALLOC_FREE(msg);
6277 static bool run_tldap(int dummy)
6279 struct tldap_context *ld;
6280 int fd, rc;
6281 NTSTATUS status;
6282 struct sockaddr_storage addr;
6283 struct tevent_context *ev;
6284 struct tevent_req *req;
6285 char *basedn;
6287 if (!resolve_name(host, &addr, 0, false)) {
6288 d_printf("could not find host %s\n", host);
6289 return false;
6291 status = open_socket_out(&addr, 389, 9999, &fd);
6292 if (!NT_STATUS_IS_OK(status)) {
6293 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6294 return false;
6297 ld = tldap_context_create(talloc_tos(), fd);
6298 if (ld == NULL) {
6299 close(fd);
6300 d_printf("tldap_context_create failed\n");
6301 return false;
6304 rc = tldap_fetch_rootdse(ld);
6305 if (rc != TLDAP_SUCCESS) {
6306 d_printf("tldap_fetch_rootdse failed: %s\n",
6307 tldap_errstr(talloc_tos(), ld, rc));
6308 return false;
6311 basedn = tldap_talloc_single_attribute(
6312 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6313 if (basedn == NULL) {
6314 d_printf("no defaultNamingContext\n");
6315 return false;
6317 d_printf("defaultNamingContext: %s\n", basedn);
6319 ev = tevent_context_init(talloc_tos());
6320 if (ev == NULL) {
6321 d_printf("tevent_context_init failed\n");
6322 return false;
6325 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6326 TLDAP_SCOPE_SUB, "(objectclass=*)",
6327 NULL, 0, 0,
6328 NULL, 0, NULL, 0, 0, 0, 0, 5);
6329 if (req == NULL) {
6330 d_printf("tldap_search_paged_send failed\n");
6331 return false;
6333 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6335 tevent_req_poll(req, ev);
6337 TALLOC_FREE(req);
6339 TALLOC_FREE(ld);
6340 return true;
6343 /* Torture test to ensure no regression of :
6344 https://bugzilla.samba.org/show_bug.cgi?id=7084
6347 static bool run_dir_createtime(int dummy)
6349 struct cli_state *cli;
6350 const char *dname = "\\testdir";
6351 const char *fname = "\\testdir\\testfile";
6352 NTSTATUS status;
6353 struct timespec create_time;
6354 struct timespec create_time1;
6355 uint16_t fnum;
6356 bool ret = false;
6358 if (!torture_open_connection(&cli, 0)) {
6359 return false;
6362 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6363 cli_rmdir(cli, dname);
6365 status = cli_mkdir(cli, dname);
6366 if (!NT_STATUS_IS_OK(status)) {
6367 printf("mkdir failed: %s\n", nt_errstr(status));
6368 goto out;
6371 if (!cli_qpathinfo2(cli,
6372 dname,
6373 &create_time,
6374 NULL,
6375 NULL,
6376 NULL,
6377 NULL,
6378 NULL,
6379 NULL)) {
6380 status = cli_nt_error(cli);
6381 printf("cli_qpathinfo2 returned %s\n",
6382 nt_errstr(status));
6383 goto out;
6386 /* Sleep 3 seconds, then create a file. */
6387 sleep(3);
6389 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6390 DENY_NONE, &fnum);
6391 if (!NT_STATUS_IS_OK(status)) {
6392 printf("cli_open failed: %s\n", nt_errstr(status));
6393 goto out;
6396 if (!cli_qpathinfo2(cli,
6397 dname,
6398 &create_time1,
6399 NULL,
6400 NULL,
6401 NULL,
6402 NULL,
6403 NULL,
6404 NULL)) {
6405 status = cli_nt_error(cli);
6406 printf("cli_qpathinfo2 (2) returned %s\n",
6407 nt_errstr(status));
6408 goto out;
6411 if (timespec_compare(&create_time1, &create_time)) {
6412 printf("run_dir_createtime: create time was updated (error)\n");
6413 } else {
6414 printf("run_dir_createtime: create time was not updated (correct)\n");
6415 ret = true;
6418 out:
6420 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6421 cli_rmdir(cli, dname);
6422 if (!torture_close_connection(cli)) {
6423 ret = false;
6425 return ret;
6429 static bool run_streamerror(int dummy)
6431 struct cli_state *cli;
6432 const char *dname = "\\testdir";
6433 const char *streamname =
6434 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6435 NTSTATUS status;
6436 time_t change_time, access_time, write_time;
6437 SMB_OFF_T size;
6438 uint16_t mode, fnum;
6439 bool ret = true;
6441 if (!torture_open_connection(&cli, 0)) {
6442 return false;
6445 cli_rmdir(cli, dname);
6447 status = cli_mkdir(cli, dname);
6448 if (!NT_STATUS_IS_OK(status)) {
6449 printf("mkdir failed: %s\n", nt_errstr(status));
6450 return false;
6453 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
6454 &size, &mode);
6455 status = cli_nt_error(cli);
6457 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6458 printf("pathinfo returned %s, expected "
6459 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6460 nt_errstr(status));
6461 ret = false;
6464 status = cli_ntcreate(cli, streamname, 0x16,
6465 FILE_READ_DATA|FILE_READ_EA|
6466 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6467 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6468 FILE_OPEN, 0, 0, &fnum);
6470 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6471 printf("ntcreate returned %s, expected "
6472 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6473 nt_errstr(status));
6474 ret = false;
6478 cli_rmdir(cli, dname);
6479 return ret;
6482 static bool run_local_substitute(int dummy)
6484 bool ok = true;
6486 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6487 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6488 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6489 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6490 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6491 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6492 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6493 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6495 /* Different captialization rules in sub_basic... */
6497 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6498 "blaDOM") == 0);
6500 return ok;
6503 static bool run_local_base64(int dummy)
6505 int i;
6506 bool ret = true;
6508 for (i=1; i<2000; i++) {
6509 DATA_BLOB blob1, blob2;
6510 char *b64;
6512 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6513 blob1.length = i;
6514 generate_random_buffer(blob1.data, blob1.length);
6516 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6517 if (b64 == NULL) {
6518 d_fprintf(stderr, "base64_encode_data_blob failed "
6519 "for %d bytes\n", i);
6520 ret = false;
6522 blob2 = base64_decode_data_blob(b64);
6523 TALLOC_FREE(b64);
6525 if (data_blob_cmp(&blob1, &blob2)) {
6526 d_fprintf(stderr, "data_blob_cmp failed for %d "
6527 "bytes\n", i);
6528 ret = false;
6530 TALLOC_FREE(blob1.data);
6531 data_blob_free(&blob2);
6533 return ret;
6536 static bool run_local_gencache(int dummy)
6538 char *val;
6539 time_t tm;
6540 DATA_BLOB blob;
6542 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6543 d_printf("%s: gencache_set() failed\n", __location__);
6544 return False;
6547 if (!gencache_get("foo", NULL, NULL)) {
6548 d_printf("%s: gencache_get() failed\n", __location__);
6549 return False;
6552 if (!gencache_get("foo", &val, &tm)) {
6553 d_printf("%s: gencache_get() failed\n", __location__);
6554 return False;
6557 if (strcmp(val, "bar") != 0) {
6558 d_printf("%s: gencache_get() returned %s, expected %s\n",
6559 __location__, val, "bar");
6560 SAFE_FREE(val);
6561 return False;
6564 SAFE_FREE(val);
6566 if (!gencache_del("foo")) {
6567 d_printf("%s: gencache_del() failed\n", __location__);
6568 return False;
6570 if (gencache_del("foo")) {
6571 d_printf("%s: second gencache_del() succeeded\n",
6572 __location__);
6573 return False;
6576 if (gencache_get("foo", &val, &tm)) {
6577 d_printf("%s: gencache_get() on deleted entry "
6578 "succeeded\n", __location__);
6579 return False;
6582 blob = data_blob_string_const_null("bar");
6583 tm = time(NULL) + 60;
6585 if (!gencache_set_data_blob("foo", &blob, tm)) {
6586 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6587 return False;
6590 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6591 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6592 return False;
6595 if (strcmp((const char *)blob.data, "bar") != 0) {
6596 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6597 __location__, (const char *)blob.data, "bar");
6598 data_blob_free(&blob);
6599 return False;
6602 data_blob_free(&blob);
6604 if (!gencache_del("foo")) {
6605 d_printf("%s: gencache_del() failed\n", __location__);
6606 return False;
6608 if (gencache_del("foo")) {
6609 d_printf("%s: second gencache_del() succeeded\n",
6610 __location__);
6611 return False;
6614 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6615 d_printf("%s: gencache_get_data_blob() on deleted entry "
6616 "succeeded\n", __location__);
6617 return False;
6620 return True;
6623 static bool rbt_testval(struct db_context *db, const char *key,
6624 const char *value)
6626 struct db_record *rec;
6627 TDB_DATA data = string_tdb_data(value);
6628 bool ret = false;
6629 NTSTATUS status;
6631 rec = db->fetch_locked(db, db, string_tdb_data(key));
6632 if (rec == NULL) {
6633 d_fprintf(stderr, "fetch_locked failed\n");
6634 goto done;
6636 status = rec->store(rec, data, 0);
6637 if (!NT_STATUS_IS_OK(status)) {
6638 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6639 goto done;
6641 TALLOC_FREE(rec);
6643 rec = db->fetch_locked(db, db, string_tdb_data(key));
6644 if (rec == NULL) {
6645 d_fprintf(stderr, "second fetch_locked failed\n");
6646 goto done;
6648 if ((rec->value.dsize != data.dsize)
6649 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6650 d_fprintf(stderr, "Got wrong data back\n");
6651 goto done;
6654 ret = true;
6655 done:
6656 TALLOC_FREE(rec);
6657 return ret;
6660 static bool run_local_rbtree(int dummy)
6662 struct db_context *db;
6663 bool ret = false;
6664 int i;
6666 db = db_open_rbt(NULL);
6668 if (db == NULL) {
6669 d_fprintf(stderr, "db_open_rbt failed\n");
6670 return false;
6673 for (i=0; i<1000; i++) {
6674 char *key, *value;
6676 if (asprintf(&key, "key%ld", random()) == -1) {
6677 goto done;
6679 if (asprintf(&value, "value%ld", random()) == -1) {
6680 SAFE_FREE(key);
6681 goto done;
6684 if (!rbt_testval(db, key, value)) {
6685 SAFE_FREE(key);
6686 SAFE_FREE(value);
6687 goto done;
6690 SAFE_FREE(value);
6691 if (asprintf(&value, "value%ld", random()) == -1) {
6692 SAFE_FREE(key);
6693 goto done;
6696 if (!rbt_testval(db, key, value)) {
6697 SAFE_FREE(key);
6698 SAFE_FREE(value);
6699 goto done;
6702 SAFE_FREE(key);
6703 SAFE_FREE(value);
6706 ret = true;
6708 done:
6709 TALLOC_FREE(db);
6710 return ret;
6713 struct talloc_dict_test {
6714 int content;
6717 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6719 int *count = (int *)priv;
6720 *count += 1;
6721 return 0;
6724 static bool run_local_talloc_dict(int dummy)
6726 struct talloc_dict *dict;
6727 struct talloc_dict_test *t;
6728 int key, count;
6730 dict = talloc_dict_init(talloc_tos());
6731 if (dict == NULL) {
6732 return false;
6735 t = talloc(talloc_tos(), struct talloc_dict_test);
6736 if (t == NULL) {
6737 return false;
6740 key = 1;
6741 t->content = 1;
6742 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6743 return false;
6746 count = 0;
6747 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6748 return false;
6751 if (count != 1) {
6752 return false;
6755 TALLOC_FREE(dict);
6757 return true;
6760 static bool run_local_string_to_sid(int dummy) {
6761 struct dom_sid sid;
6763 if (string_to_sid(&sid, "S--1-5-32-545")) {
6764 printf("allowing S--1-5-32-545\n");
6765 return false;
6767 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6768 printf("allowing S-1-5-32-+545\n");
6769 return false;
6771 if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6772 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6773 return false;
6775 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6776 printf("allowing S-1-5-32-545-abc\n");
6777 return false;
6779 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6780 printf("could not parse S-1-5-32-545\n");
6781 return false;
6783 if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6784 printf("mis-parsed S-1-5-32-545 as %s\n",
6785 sid_string_tos(&sid));
6786 return false;
6788 return true;
6791 /* Split a path name into filename and stream name components. Canonicalise
6792 * such that an implicit $DATA token is always explicit.
6794 * The "specification" of this function can be found in the
6795 * run_local_stream_name() function in torture.c, I've tried those
6796 * combinations against a W2k3 server.
6799 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6800 char **pbase, char **pstream)
6802 char *base = NULL;
6803 char *stream = NULL;
6804 char *sname; /* stream name */
6805 const char *stype; /* stream type */
6807 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6809 sname = strchr_m(fname, ':');
6811 if (lp_posix_pathnames() || (sname == NULL)) {
6812 if (pbase != NULL) {
6813 base = talloc_strdup(mem_ctx, fname);
6814 NT_STATUS_HAVE_NO_MEMORY(base);
6816 goto done;
6819 if (pbase != NULL) {
6820 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6821 NT_STATUS_HAVE_NO_MEMORY(base);
6824 sname += 1;
6826 stype = strchr_m(sname, ':');
6828 if (stype == NULL) {
6829 sname = talloc_strdup(mem_ctx, sname);
6830 stype = "$DATA";
6832 else {
6833 if (StrCaseCmp(stype, ":$DATA") != 0) {
6835 * If there is an explicit stream type, so far we only
6836 * allow $DATA. Is there anything else allowed? -- vl
6838 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6839 TALLOC_FREE(base);
6840 return NT_STATUS_OBJECT_NAME_INVALID;
6842 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6843 stype += 1;
6846 if (sname == NULL) {
6847 TALLOC_FREE(base);
6848 return NT_STATUS_NO_MEMORY;
6851 if (sname[0] == '\0') {
6853 * no stream name, so no stream
6855 goto done;
6858 if (pstream != NULL) {
6859 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6860 if (stream == NULL) {
6861 TALLOC_FREE(sname);
6862 TALLOC_FREE(base);
6863 return NT_STATUS_NO_MEMORY;
6866 * upper-case the type field
6868 strupper_m(strchr_m(stream, ':')+1);
6871 done:
6872 if (pbase != NULL) {
6873 *pbase = base;
6875 if (pstream != NULL) {
6876 *pstream = stream;
6878 return NT_STATUS_OK;
6881 static bool test_stream_name(const char *fname, const char *expected_base,
6882 const char *expected_stream,
6883 NTSTATUS expected_status)
6885 NTSTATUS status;
6886 char *base = NULL;
6887 char *stream = NULL;
6889 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6890 if (!NT_STATUS_EQUAL(status, expected_status)) {
6891 goto error;
6894 if (!NT_STATUS_IS_OK(status)) {
6895 return true;
6898 if (base == NULL) goto error;
6900 if (strcmp(expected_base, base) != 0) goto error;
6902 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6903 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6905 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6906 goto error;
6908 TALLOC_FREE(base);
6909 TALLOC_FREE(stream);
6910 return true;
6912 error:
6913 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6914 fname, expected_base ? expected_base : "<NULL>",
6915 expected_stream ? expected_stream : "<NULL>",
6916 nt_errstr(expected_status));
6917 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6918 base ? base : "<NULL>", stream ? stream : "<NULL>",
6919 nt_errstr(status));
6920 TALLOC_FREE(base);
6921 TALLOC_FREE(stream);
6922 return false;
6925 static bool run_local_stream_name(int dummy)
6927 bool ret = true;
6929 ret &= test_stream_name(
6930 "bla", "bla", NULL, NT_STATUS_OK);
6931 ret &= test_stream_name(
6932 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6933 ret &= test_stream_name(
6934 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6935 ret &= test_stream_name(
6936 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6937 ret &= test_stream_name(
6938 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6939 ret &= test_stream_name(
6940 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6941 ret &= test_stream_name(
6942 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6943 ret &= test_stream_name(
6944 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6946 return ret;
6949 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6951 if (a.length != b.length) {
6952 printf("a.length=%d != b.length=%d\n",
6953 (int)a.length, (int)b.length);
6954 return false;
6956 if (memcmp(a.data, b.data, a.length) != 0) {
6957 printf("a.data and b.data differ\n");
6958 return false;
6960 return true;
6963 static bool run_local_memcache(int dummy)
6965 struct memcache *cache;
6966 DATA_BLOB k1, k2;
6967 DATA_BLOB d1, d2, d3;
6968 DATA_BLOB v1, v2, v3;
6970 TALLOC_CTX *mem_ctx;
6971 char *str1, *str2;
6972 size_t size1, size2;
6973 bool ret = false;
6975 cache = memcache_init(NULL, 100);
6977 if (cache == NULL) {
6978 printf("memcache_init failed\n");
6979 return false;
6982 d1 = data_blob_const("d1", 2);
6983 d2 = data_blob_const("d2", 2);
6984 d3 = data_blob_const("d3", 2);
6986 k1 = data_blob_const("d1", 2);
6987 k2 = data_blob_const("d2", 2);
6989 memcache_add(cache, STAT_CACHE, k1, d1);
6990 memcache_add(cache, GETWD_CACHE, k2, d2);
6992 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6993 printf("could not find k1\n");
6994 return false;
6996 if (!data_blob_equal(d1, v1)) {
6997 return false;
7000 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7001 printf("could not find k2\n");
7002 return false;
7004 if (!data_blob_equal(d2, v2)) {
7005 return false;
7008 memcache_add(cache, STAT_CACHE, k1, d3);
7010 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7011 printf("could not find replaced k1\n");
7012 return false;
7014 if (!data_blob_equal(d3, v3)) {
7015 return false;
7018 memcache_add(cache, GETWD_CACHE, k1, d1);
7020 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7021 printf("Did find k2, should have been purged\n");
7022 return false;
7025 TALLOC_FREE(cache);
7027 cache = memcache_init(NULL, 0);
7029 mem_ctx = talloc_init("foo");
7031 str1 = talloc_strdup(mem_ctx, "string1");
7032 str2 = talloc_strdup(mem_ctx, "string2");
7034 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7035 data_blob_string_const("torture"), &str1);
7036 size1 = talloc_total_size(cache);
7038 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7039 data_blob_string_const("torture"), &str2);
7040 size2 = talloc_total_size(cache);
7042 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7044 if (size2 > size1) {
7045 printf("memcache leaks memory!\n");
7046 goto fail;
7049 ret = true;
7050 fail:
7051 TALLOC_FREE(cache);
7052 return ret;
7055 static void wbclient_done(struct tevent_req *req)
7057 wbcErr wbc_err;
7058 struct winbindd_response *wb_resp;
7059 int *i = (int *)tevent_req_callback_data_void(req);
7061 wbc_err = wb_trans_recv(req, req, &wb_resp);
7062 TALLOC_FREE(req);
7063 *i += 1;
7064 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7067 static bool run_local_wbclient(int dummy)
7069 struct event_context *ev;
7070 struct wb_context **wb_ctx;
7071 struct winbindd_request wb_req;
7072 bool result = false;
7073 int i, j;
7075 BlockSignals(True, SIGPIPE);
7077 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7078 if (ev == NULL) {
7079 goto fail;
7082 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7083 if (wb_ctx == NULL) {
7084 goto fail;
7087 ZERO_STRUCT(wb_req);
7088 wb_req.cmd = WINBINDD_PING;
7090 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7092 for (i=0; i<nprocs; i++) {
7093 wb_ctx[i] = wb_context_init(ev, NULL);
7094 if (wb_ctx[i] == NULL) {
7095 goto fail;
7097 for (j=0; j<torture_numops; j++) {
7098 struct tevent_req *req;
7099 req = wb_trans_send(ev, ev, wb_ctx[i],
7100 (j % 2) == 0, &wb_req);
7101 if (req == NULL) {
7102 goto fail;
7104 tevent_req_set_callback(req, wbclient_done, &i);
7108 i = 0;
7110 while (i < nprocs * torture_numops) {
7111 event_loop_once(ev);
7114 result = true;
7115 fail:
7116 TALLOC_FREE(ev);
7117 return result;
7120 static void getaddrinfo_finished(struct tevent_req *req)
7122 char *name = (char *)tevent_req_callback_data_void(req);
7123 struct addrinfo *ainfo;
7124 int res;
7126 res = getaddrinfo_recv(req, &ainfo);
7127 if (res != 0) {
7128 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7129 return;
7131 d_printf("gai(%s) succeeded\n", name);
7132 freeaddrinfo(ainfo);
7135 static bool run_getaddrinfo_send(int dummy)
7137 TALLOC_CTX *frame = talloc_stackframe();
7138 struct fncall_context *ctx;
7139 struct tevent_context *ev;
7140 bool result = false;
7141 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7142 "www.slashdot.org", "heise.de" };
7143 struct tevent_req *reqs[4];
7144 int i;
7146 ev = event_context_init(frame);
7147 if (ev == NULL) {
7148 goto fail;
7151 ctx = fncall_context_init(frame, 4);
7153 for (i=0; i<ARRAY_SIZE(names); i++) {
7154 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7155 NULL);
7156 if (reqs[i] == NULL) {
7157 goto fail;
7159 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7160 (void *)names[i]);
7163 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7164 tevent_loop_once(ev);
7167 result = true;
7168 fail:
7169 TALLOC_FREE(frame);
7170 return result;
7173 static bool dbtrans_inc(struct db_context *db)
7175 struct db_record *rec;
7176 uint32_t *val;
7177 bool ret = false;
7178 NTSTATUS status;
7180 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7181 if (rec == NULL) {
7182 printf(__location__ "fetch_lock failed\n");
7183 return false;
7186 if (rec->value.dsize != sizeof(uint32_t)) {
7187 printf(__location__ "value.dsize = %d\n",
7188 (int)rec->value.dsize);
7189 goto fail;
7192 val = (uint32_t *)rec->value.dptr;
7193 *val += 1;
7195 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7196 sizeof(uint32_t)),
7198 if (!NT_STATUS_IS_OK(status)) {
7199 printf(__location__ "store failed: %s\n",
7200 nt_errstr(status));
7201 goto fail;
7204 ret = true;
7205 fail:
7206 TALLOC_FREE(rec);
7207 return ret;
7210 static bool run_local_dbtrans(int dummy)
7212 struct db_context *db;
7213 struct db_record *rec;
7214 NTSTATUS status;
7215 uint32_t initial;
7216 int res;
7218 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7219 O_RDWR|O_CREAT, 0600);
7220 if (db == NULL) {
7221 printf("Could not open transtest.db\n");
7222 return false;
7225 res = db->transaction_start(db);
7226 if (res == -1) {
7227 printf(__location__ "transaction_start failed\n");
7228 return false;
7231 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7232 if (rec == NULL) {
7233 printf(__location__ "fetch_lock failed\n");
7234 return false;
7237 if (rec->value.dptr == NULL) {
7238 initial = 0;
7239 status = rec->store(
7240 rec, make_tdb_data((uint8_t *)&initial,
7241 sizeof(initial)),
7243 if (!NT_STATUS_IS_OK(status)) {
7244 printf(__location__ "store returned %s\n",
7245 nt_errstr(status));
7246 return false;
7250 TALLOC_FREE(rec);
7252 res = db->transaction_commit(db);
7253 if (res == -1) {
7254 printf(__location__ "transaction_commit failed\n");
7255 return false;
7258 while (true) {
7259 uint32_t val, val2;
7260 int i;
7262 res = db->transaction_start(db);
7263 if (res == -1) {
7264 printf(__location__ "transaction_start failed\n");
7265 break;
7268 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7269 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7270 break;
7273 for (i=0; i<10; i++) {
7274 if (!dbtrans_inc(db)) {
7275 return false;
7279 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7280 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7281 break;
7284 if (val2 != val + 10) {
7285 printf(__location__ "val=%d, val2=%d\n",
7286 (int)val, (int)val2);
7287 break;
7290 printf("val2=%d\r", val2);
7292 res = db->transaction_commit(db);
7293 if (res == -1) {
7294 printf(__location__ "transaction_commit failed\n");
7295 break;
7299 TALLOC_FREE(db);
7300 return true;
7303 static double create_procs(bool (*fn)(int), bool *result)
7305 int i, status;
7306 volatile pid_t *child_status;
7307 volatile bool *child_status_out;
7308 int synccount;
7309 int tries = 8;
7310 struct timeval start;
7312 synccount = 0;
7314 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7315 if (!child_status) {
7316 printf("Failed to setup shared memory\n");
7317 return -1;
7320 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7321 if (!child_status_out) {
7322 printf("Failed to setup result status shared memory\n");
7323 return -1;
7326 for (i = 0; i < nprocs; i++) {
7327 child_status[i] = 0;
7328 child_status_out[i] = True;
7331 start = timeval_current();
7333 for (i=0;i<nprocs;i++) {
7334 procnum = i;
7335 if (fork() == 0) {
7336 pid_t mypid = getpid();
7337 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7339 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7341 while (1) {
7342 if (torture_open_connection(&current_cli, i)) break;
7343 if (tries-- == 0) {
7344 printf("pid %d failed to start\n", (int)getpid());
7345 _exit(1);
7347 smb_msleep(10);
7350 child_status[i] = getpid();
7352 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7354 child_status_out[i] = fn(i);
7355 _exit(0);
7359 do {
7360 synccount = 0;
7361 for (i=0;i<nprocs;i++) {
7362 if (child_status[i]) synccount++;
7364 if (synccount == nprocs) break;
7365 smb_msleep(10);
7366 } while (timeval_elapsed(&start) < 30);
7368 if (synccount != nprocs) {
7369 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7370 *result = False;
7371 return timeval_elapsed(&start);
7374 /* start the client load */
7375 start = timeval_current();
7377 for (i=0;i<nprocs;i++) {
7378 child_status[i] = 0;
7381 printf("%d clients started\n", nprocs);
7383 for (i=0;i<nprocs;i++) {
7384 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7387 printf("\n");
7389 for (i=0;i<nprocs;i++) {
7390 if (!child_status_out[i]) {
7391 *result = False;
7394 return timeval_elapsed(&start);
7397 #define FLAG_MULTIPROC 1
7399 static struct {
7400 const char *name;
7401 bool (*fn)(int);
7402 unsigned flags;
7403 } torture_ops[] = {
7404 {"FDPASS", run_fdpasstest, 0},
7405 {"LOCK1", run_locktest1, 0},
7406 {"LOCK2", run_locktest2, 0},
7407 {"LOCK3", run_locktest3, 0},
7408 {"LOCK4", run_locktest4, 0},
7409 {"LOCK5", run_locktest5, 0},
7410 {"LOCK6", run_locktest6, 0},
7411 {"LOCK7", run_locktest7, 0},
7412 {"LOCK8", run_locktest8, 0},
7413 {"LOCK9", run_locktest9, 0},
7414 {"UNLINK", run_unlinktest, 0},
7415 {"BROWSE", run_browsetest, 0},
7416 {"ATTR", run_attrtest, 0},
7417 {"TRANS2", run_trans2test, 0},
7418 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7419 {"TORTURE",run_torture, FLAG_MULTIPROC},
7420 {"RANDOMIPC", run_randomipc, 0},
7421 {"NEGNOWAIT", run_negprot_nowait, 0},
7422 {"NBENCH", run_nbench, 0},
7423 {"OPLOCK1", run_oplock1, 0},
7424 {"OPLOCK2", run_oplock2, 0},
7425 {"OPLOCK3", run_oplock3, 0},
7426 {"DIR", run_dirtest, 0},
7427 {"DIR1", run_dirtest1, 0},
7428 {"DIR-CREATETIME", run_dir_createtime, 0},
7429 {"DENY1", torture_denytest1, 0},
7430 {"DENY2", torture_denytest2, 0},
7431 {"TCON", run_tcon_test, 0},
7432 {"TCONDEV", run_tcon_devtype_test, 0},
7433 {"RW1", run_readwritetest, 0},
7434 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7435 {"RW3", run_readwritelarge, 0},
7436 {"OPEN", run_opentest, 0},
7437 {"POSIX", run_simple_posix_open_test, 0},
7438 {"POSIX-APPEND", run_posix_append, 0},
7439 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7440 { "SHORTNAME-TEST", run_shortname_test, 0},
7441 #if 1
7442 {"OPENATTR", run_openattrtest, 0},
7443 #endif
7444 {"XCOPY", run_xcopy, 0},
7445 {"RENAME", run_rename, 0},
7446 {"DELETE", run_deletetest, 0},
7447 {"PROPERTIES", run_properties, 0},
7448 {"MANGLE", torture_mangle, 0},
7449 {"MANGLE1", run_mangle1, 0},
7450 {"W2K", run_w2ktest, 0},
7451 {"TRANS2SCAN", torture_trans2_scan, 0},
7452 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7453 {"UTABLE", torture_utable, 0},
7454 {"CASETABLE", torture_casetable, 0},
7455 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7456 {"PIPE_NUMBER", run_pipe_number, 0},
7457 {"TCON2", run_tcon2_test, 0},
7458 {"IOCTL", torture_ioctl_test, 0},
7459 {"CHKPATH", torture_chkpath_test, 0},
7460 {"FDSESS", run_fdsesstest, 0},
7461 { "EATEST", run_eatest, 0},
7462 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7463 { "CHAIN1", run_chain1, 0},
7464 { "CHAIN2", run_chain2, 0},
7465 { "WINDOWS-WRITE", run_windows_write, 0},
7466 { "CLI_ECHO", run_cli_echo, 0},
7467 { "GETADDRINFO", run_getaddrinfo_send, 0},
7468 { "TLDAP", run_tldap },
7469 { "STREAMERROR", run_streamerror },
7470 { "NOTIFY-BENCH", run_notify_bench },
7471 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7472 { "LOCAL-GENCACHE", run_local_gencache, 0},
7473 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7474 { "LOCAL-BASE64", run_local_base64, 0},
7475 { "LOCAL-RBTREE", run_local_rbtree, 0},
7476 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7477 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7478 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7479 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7480 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7481 {NULL, NULL, 0}};
7485 /****************************************************************************
7486 run a specified test or "ALL"
7487 ****************************************************************************/
7488 static bool run_test(const char *name)
7490 bool ret = True;
7491 bool result = True;
7492 bool found = False;
7493 int i;
7494 double t;
7495 if (strequal(name,"ALL")) {
7496 for (i=0;torture_ops[i].name;i++) {
7497 run_test(torture_ops[i].name);
7499 found = True;
7502 for (i=0;torture_ops[i].name;i++) {
7503 fstr_sprintf(randomfname, "\\XX%x",
7504 (unsigned)random());
7506 if (strequal(name, torture_ops[i].name)) {
7507 found = True;
7508 printf("Running %s\n", name);
7509 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7510 t = create_procs(torture_ops[i].fn, &result);
7511 if (!result) {
7512 ret = False;
7513 printf("TEST %s FAILED!\n", name);
7515 } else {
7516 struct timeval start;
7517 start = timeval_current();
7518 if (!torture_ops[i].fn(0)) {
7519 ret = False;
7520 printf("TEST %s FAILED!\n", name);
7522 t = timeval_elapsed(&start);
7524 printf("%s took %g secs\n\n", name, t);
7528 if (!found) {
7529 printf("Did not find a test named %s\n", name);
7530 ret = False;
7533 return ret;
7537 static void usage(void)
7539 int i;
7541 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7542 printf("Please use samba4 torture.\n\n");
7544 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7546 printf("\t-d debuglevel\n");
7547 printf("\t-U user%%pass\n");
7548 printf("\t-k use kerberos\n");
7549 printf("\t-N numprocs\n");
7550 printf("\t-n my_netbios_name\n");
7551 printf("\t-W workgroup\n");
7552 printf("\t-o num_operations\n");
7553 printf("\t-O socket_options\n");
7554 printf("\t-m maximum protocol\n");
7555 printf("\t-L use oplocks\n");
7556 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7557 printf("\t-A showall\n");
7558 printf("\t-p port\n");
7559 printf("\t-s seed\n");
7560 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7561 printf("\n\n");
7563 printf("tests are:");
7564 for (i=0;torture_ops[i].name;i++) {
7565 printf(" %s", torture_ops[i].name);
7567 printf("\n");
7569 printf("default test is ALL\n");
7571 exit(1);
7574 /****************************************************************************
7575 main program
7576 ****************************************************************************/
7577 int main(int argc,char *argv[])
7579 int opt, i;
7580 char *p;
7581 int gotuser = 0;
7582 int gotpass = 0;
7583 bool correct = True;
7584 TALLOC_CTX *frame = talloc_stackframe();
7585 int seed = time(NULL);
7587 dbf = x_stdout;
7589 #ifdef HAVE_SETBUFFER
7590 setbuffer(stdout, NULL, 0);
7591 #endif
7593 load_case_tables();
7595 setup_logging("smbtorture", true);
7597 if (is_default_dyn_CONFIGFILE()) {
7598 if(getenv("SMB_CONF_PATH")) {
7599 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7602 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7603 load_interfaces();
7605 if (argc < 2) {
7606 usage();
7609 for(p = argv[1]; *p; p++)
7610 if(*p == '\\')
7611 *p = '/';
7613 if (strncmp(argv[1], "//", 2)) {
7614 usage();
7617 fstrcpy(host, &argv[1][2]);
7618 p = strchr_m(&host[2],'/');
7619 if (!p) {
7620 usage();
7622 *p = 0;
7623 fstrcpy(share, p+1);
7625 fstrcpy(myname, get_myname(talloc_tos()));
7626 if (!*myname) {
7627 fprintf(stderr, "Failed to get my hostname.\n");
7628 return 1;
7631 if (*username == 0 && getenv("LOGNAME")) {
7632 fstrcpy(username,getenv("LOGNAME"));
7635 argc--;
7636 argv++;
7638 fstrcpy(workgroup, lp_workgroup());
7640 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7641 switch (opt) {
7642 case 'p':
7643 port_to_use = atoi(optarg);
7644 break;
7645 case 's':
7646 seed = atoi(optarg);
7647 break;
7648 case 'W':
7649 fstrcpy(workgroup,optarg);
7650 break;
7651 case 'm':
7652 max_protocol = interpret_protocol(optarg, max_protocol);
7653 break;
7654 case 'N':
7655 nprocs = atoi(optarg);
7656 break;
7657 case 'o':
7658 torture_numops = atoi(optarg);
7659 break;
7660 case 'd':
7661 DEBUGLEVEL = atoi(optarg);
7662 break;
7663 case 'O':
7664 sockops = optarg;
7665 break;
7666 case 'L':
7667 use_oplocks = True;
7668 break;
7669 case 'l':
7670 local_path = optarg;
7671 break;
7672 case 'A':
7673 torture_showall = True;
7674 break;
7675 case 'n':
7676 fstrcpy(myname, optarg);
7677 break;
7678 case 'c':
7679 client_txt = optarg;
7680 break;
7681 case 'e':
7682 do_encrypt = true;
7683 break;
7684 case 'k':
7685 #ifdef HAVE_KRB5
7686 use_kerberos = True;
7687 #else
7688 d_printf("No kerberos support compiled in\n");
7689 exit(1);
7690 #endif
7691 break;
7692 case 'U':
7693 gotuser = 1;
7694 fstrcpy(username,optarg);
7695 p = strchr_m(username,'%');
7696 if (p) {
7697 *p = 0;
7698 fstrcpy(password, p+1);
7699 gotpass = 1;
7701 break;
7702 case 'b':
7703 fstrcpy(multishare_conn_fname, optarg);
7704 use_multishare_conn = True;
7705 break;
7706 case 'B':
7707 torture_blocksize = atoi(optarg);
7708 break;
7709 default:
7710 printf("Unknown option %c (%d)\n", (char)opt, opt);
7711 usage();
7715 d_printf("using seed %d\n", seed);
7717 srandom(seed);
7719 if(use_kerberos && !gotuser) gotpass = True;
7721 while (!gotpass) {
7722 p = getpass("Password:");
7723 if (p) {
7724 fstrcpy(password, p);
7725 gotpass = 1;
7729 printf("host=%s share=%s user=%s myname=%s\n",
7730 host, share, username, myname);
7732 if (argc == optind) {
7733 correct = run_test("ALL");
7734 } else {
7735 for (i=optind;i<argc;i++) {
7736 if (!run_test(argv[i])) {
7737 correct = False;
7742 TALLOC_FREE(frame);
7744 if (correct) {
7745 return(0);
7746 } else {
7747 return(1);