2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 int torture_numops=100;
25 int torture_entries=1000;
26 int torture_failures=1;
27 static int procnum; /* records process count number when forking */
28 static struct smbcli_state *current_cli;
29 static BOOL use_oplocks;
30 static BOOL use_level_II_oplocks;
31 static BOOL use_kerberos;
33 BOOL torture_showall = False;
35 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
37 static struct smbcli_state *open_nbt_connection(void)
39 struct nmb_name called, calling;
40 struct smbcli_state *cli;
41 const char *host = lp_parm_string(-1, "torture", "host");
43 make_nmb_name(&calling, lp_netbios_name(), 0x0);
44 choose_called_name(&called, host, 0x20);
46 cli = smbcli_state_init();
48 printf("Failed initialize smbcli_struct to connect with %s\n", host);
52 if (!smbcli_socket_connect(cli, host)) {
53 printf("Failed to connect with %s\n", host);
57 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
59 if (!smbcli_transport_establish(cli, &calling, &called)) {
61 * Well, that failed, try *SMBSERVER ...
62 * However, we must reconnect as well ...
64 if (!smbcli_socket_connect(cli, host)) {
65 printf("Failed to connect with %s\n", host);
69 make_nmb_name(&called, "*SMBSERVER", 0x20);
70 if (!smbcli_transport_establish(cli, &calling, &called)) {
71 printf("%s rejected the session\n",host);
72 printf("We tried with a called name of %s & %s\n",
82 BOOL torture_open_connection_share(struct smbcli_state **c,
84 const char *sharename)
89 const char *username = lp_parm_string(-1, "torture", "username");
90 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
91 const char *password = lp_parm_string(-1, "torture", "password");
94 flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS;
96 status = smbcli_full_connection(c, lp_netbios_name(),
99 username, username[0]?userdomain:"",
100 password, flags, &retry);
101 if (!NT_STATUS_IS_OK(status)) {
102 printf("Failed to open connection - %s\n", nt_errstr(status));
106 (*c)->transport->options.use_oplocks = use_oplocks;
107 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
108 (*c)->transport->socket->timeout = 120000;
113 BOOL torture_open_connection(struct smbcli_state **c)
115 const char *host = lp_parm_string(-1, "torture", "host");
116 const char *share = lp_parm_string(-1, "torture", "share");
118 return torture_open_connection_share(c, host, share);
123 BOOL torture_close_connection(struct smbcli_state *c)
126 DEBUG(9,("torture_close_connection: smbcli_state@%p\n", c));
128 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
129 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
132 DEBUG(9,("torture_close_connection: call smbcli_shutdown\n"));
134 DEBUG(9,("torture_close_connection: exit\n"));
139 /* open a rpc connection to a named pipe */
140 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
141 const char *pipe_name,
142 const char *pipe_uuid,
143 uint32_t pipe_version)
146 const char *binding = lp_parm_string(-1, "torture", "binding");
149 printf("You must specify a ncacn binding string\n");
150 return NT_STATUS_INVALID_PARAMETER;
153 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
154 lp_parm_string(-1, "torture", "userdomain"),
155 lp_parm_string(-1, "torture", "username"),
156 lp_parm_string(-1, "torture", "password"));
161 /* close a rpc connection to a named pipe */
162 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
164 dcerpc_pipe_close(p);
169 /* check if the server produced the expected error code */
170 static BOOL check_error(int line, struct smbcli_state *c,
171 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
173 if (smbcli_is_dos_error(c->tree)) {
177 /* Check DOS error */
179 smbcli_dos_error(c, &class, &num);
181 if (eclass != class || ecode != num) {
182 printf("unexpected error code class=%d code=%d\n",
183 (int)class, (int)num);
184 printf(" expected %d/%d %s (line=%d)\n",
185 (int)eclass, (int)ecode, nt_errstr(nterr), line);
194 status = smbcli_nt_error(c->tree);
196 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
197 printf("unexpected error code %s\n", nt_errstr(status));
198 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
207 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
209 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
210 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
216 static BOOL rw_torture(struct smbcli_state *c)
218 const char *lockfname = "\\torture.lck";
222 pid_t pid2, pid = getpid();
227 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
230 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
232 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
237 for (i=0;i<torture_numops;i++) {
238 uint_t n = (uint_t)sys_random()%10;
240 printf("%d\r", i); fflush(stdout);
242 asprintf(&fname, "\\torture.%u", n);
244 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
248 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
250 printf("open failed (%s)\n", smbcli_errstr(c->tree));
255 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
256 printf("write failed (%s)\n", smbcli_errstr(c->tree));
261 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
262 sizeof(pid)+(j*sizeof(buf)),
263 sizeof(buf)) != sizeof(buf)) {
264 printf("write failed (%s)\n", smbcli_errstr(c->tree));
271 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
272 printf("read failed (%s)\n", smbcli_errstr(c->tree));
277 printf("data corruption!\n");
281 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
282 printf("close failed (%s)\n", smbcli_errstr(c->tree));
286 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
287 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
291 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
292 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
298 smbcli_close(c->tree, fnum2);
299 smbcli_unlink(c->tree, lockfname);
306 static BOOL run_torture(struct smbcli_state *cli, int dummy)
310 ret = rw_torture(cli);
312 if (!torture_close_connection(cli)) {
319 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
326 uint_t countprev = 0;
331 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
333 SIVAL(buf, i, sys_random());
338 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
341 printf("first open read/write of %s failed (%s)\n",
342 lockfname, smbcli_errstr(c->tree));
348 for (i = 0; i < 500 && fnum == -1; i++)
350 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
355 printf("second open read-only of %s failed (%s)\n",
356 lockfname, smbcli_errstr(c->tree));
362 for (count = 0; count < sizeof(buf); count += sent)
364 if (count >= countprev) {
365 printf("%d %8d\r", i, count);
368 countprev += (sizeof(buf) / 20);
373 sent = ((uint_t)sys_random()%(20))+ 1;
374 if (sent > sizeof(buf) - count)
376 sent = sizeof(buf) - count;
379 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
380 printf("write failed (%s)\n", smbcli_errstr(c->tree));
386 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
390 printf("read failed offset:%d size:%d (%s)\n",
391 count, sizeof(buf)-count,
392 smbcli_errstr(c->tree));
398 if (memcmp(buf_rd+count, buf+count, sent) != 0)
400 printf("read/write compare failed\n");
401 printf("offset: %d req %d recvd %d\n",
402 count, sizeof(buf)-count, sent);
411 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
412 printf("close failed (%s)\n", smbcli_errstr(c->tree));
419 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
421 const char *lockfname = "\\torture2.lck";
426 uint8_t buf_rd[131072];
428 ssize_t bytes_read, bytes_written;
430 if (smbcli_deltree(c1->tree, lockfname) == -1) {
431 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
434 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
437 printf("first open read/write of %s failed (%s)\n",
438 lockfname, smbcli_errstr(c1->tree));
441 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
444 printf("second open read-only of %s failed (%s)\n",
445 lockfname, smbcli_errstr(c2->tree));
446 smbcli_close(c1->tree, fnum1);
450 printf("Checking data integrity over %d ops\n", torture_numops);
452 for (i=0;i<torture_numops;i++)
454 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
456 printf("%d\r", i); fflush(stdout);
459 generate_random_buffer(buf, buf_size);
461 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
462 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
463 printf("wrote %d, expected %d\n", bytes_written, buf_size);
468 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
469 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
470 printf("read %d, expected %d\n", bytes_read, buf_size);
475 if (memcmp(buf_rd, buf, buf_size) != 0)
477 printf("read/write compare failed\n");
483 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
484 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
487 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
488 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
492 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
493 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
500 static BOOL run_readwritetest(int dummy)
502 struct smbcli_state *cli1, *cli2;
503 BOOL test1, test2 = True;
505 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
509 printf("starting readwritetest\n");
511 test1 = rw_torture2(cli1, cli2);
512 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
515 test2 = rw_torture2(cli1, cli1);
516 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
519 if (!torture_close_connection(cli1)) {
523 if (!torture_close_connection(cli2)) {
527 return (test1 && test2);
530 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
534 test = rw_torture3(cli, "\\multitest.txt");
536 if (!torture_close_connection(cli)) {
545 This test checks for two things:
547 1) correct support for retaining locks over a close (ie. the server
548 must not use posix semantics)
549 2) support for lock timeouts
551 static BOOL run_locktest1(int dummy)
553 struct smbcli_state *cli1, *cli2;
554 const char *fname = "\\lockt1.lck";
555 int fnum1, fnum2, fnum3;
559 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
563 printf("starting locktest1\n");
565 smbcli_unlink(cli1->tree, fname);
567 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
569 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
572 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
574 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
577 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
579 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
583 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
584 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
589 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
590 printf("lock2 succeeded! This is a locking bug\n");
593 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
594 NT_STATUS_LOCK_NOT_GRANTED)) return False;
598 lock_timeout = (6 + (random() % 20));
599 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
601 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
602 printf("lock3 succeeded! This is a locking bug\n");
605 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
606 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
611 printf("error: This server appears not to support timed lock requests\n");
613 printf("server slept for %u seconds for a %u second timeout\n",
614 (uint_t)(t2-t1), lock_timeout);
616 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
617 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
621 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
622 printf("lock4 succeeded! This is a locking bug\n");
625 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
626 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
629 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
630 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
634 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
635 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
639 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
640 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
645 if (!torture_close_connection(cli1)) {
649 if (!torture_close_connection(cli2)) {
653 printf("Passed locktest1\n");
658 this checks to see if a secondary tconx can use open files from an
661 static BOOL run_tcon_test(int dummy)
663 struct smbcli_state *cli;
664 const char *fname = "\\tcontest.tmp";
666 uint16_t cnum1, cnum2, cnum3;
667 uint16_t vuid1, vuid2;
670 struct smbcli_tree *tree1;
671 const char *host = lp_parm_string(-1, "torture", "host");
672 const char *share = lp_parm_string(-1, "torture", "share");
673 const char *password = lp_parm_string(-1, "torture", "password");
675 if (!torture_open_connection(&cli)) {
679 printf("starting tcontest\n");
681 if (smbcli_deltree(cli->tree, fname) == -1) {
682 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
685 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
687 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
691 cnum1 = cli->tree->tid;
692 vuid1 = cli->session->vuid;
694 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
695 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
696 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
700 tree1 = cli->tree; /* save old tree connection */
701 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
702 printf("%s refused 2nd tree connect (%s)\n", host,
703 smbcli_errstr(cli->tree));
704 smbcli_shutdown(cli);
708 cnum2 = cli->tree->tid;
709 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
710 vuid2 = cli->session->vuid + 1;
712 /* try a write with the wrong tid */
713 cli->tree->tid = cnum2;
715 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
716 printf("* server allows write with wrong TID\n");
719 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
723 /* try a write with an invalid tid */
724 cli->tree->tid = cnum3;
726 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
727 printf("* server allows write with invalid TID\n");
730 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
733 /* try a write with an invalid vuid */
734 cli->session->vuid = vuid2;
735 cli->tree->tid = cnum1;
737 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
738 printf("* server allows write with invalid VUID\n");
741 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
744 cli->session->vuid = vuid1;
745 cli->tree->tid = cnum1;
747 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
748 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
752 cli->tree->tid = cnum2;
754 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
755 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
759 cli->tree = tree1; /* restore initial tree */
760 cli->tree->tid = cnum1;
762 if (!torture_close_connection(cli)) {
771 static BOOL tcon_devtest(struct smbcli_state *cli,
772 const char *myshare, const char *devtype,
773 NTSTATUS expected_error)
777 const char *password = lp_parm_string(-1, "torture", "password");
779 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
782 printf("Trying share %s with devtype %s\n", myshare, devtype);
784 if (NT_STATUS_IS_OK(expected_error)) {
788 printf("tconX to share %s with type %s "
789 "should have succeeded but failed\n",
796 printf("tconx to share %s with type %s "
797 "should have failed but succeeded\n",
801 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
805 printf("Returned unexpected error\n");
814 checks for correct tconX support
816 static BOOL run_tcon_devtype_test(int dummy)
818 struct smbcli_state *cli1 = NULL;
823 const char *host = lp_parm_string(-1, "torture", "host");
824 const char *share = lp_parm_string(-1, "torture", "share");
825 const char *username = lp_parm_string(-1, "torture", "username");
826 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
827 const char *password = lp_parm_string(-1, "torture", "password");
829 status = smbcli_full_connection(&cli1, lp_netbios_name(),
832 username, userdomain,
833 password, flags, &retry);
835 if (!NT_STATUS_IS_OK(status)) {
836 printf("could not open connection\n");
840 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
843 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
846 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
849 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
852 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
855 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
858 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
861 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
864 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
867 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
870 smbcli_shutdown(cli1);
873 printf("Passed tcondevtest\n");
880 This test checks that
882 1) the server supports multiple locking contexts on the one SMB
883 connection, distinguished by PID.
885 2) the server correctly fails overlapping locks made by the same PID (this
886 goes against POSIX behaviour, which is why it is tricky to implement)
888 3) the server denies unlock requests by an incorrect client PID
890 static BOOL run_locktest2(int dummy)
892 struct smbcli_state *cli;
893 const char *fname = "\\lockt2.lck";
894 int fnum1, fnum2, fnum3;
897 if (!torture_open_connection(&cli)) {
901 printf("starting locktest2\n");
903 smbcli_unlink(cli->tree, fname);
905 printf("Testing pid context\n");
907 cli->session->pid = 1;
909 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
911 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
915 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
917 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
921 cli->session->pid = 2;
923 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
925 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
929 cli->session->pid = 1;
931 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
932 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
936 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
937 printf("WRITE lock1 succeeded! This is a locking bug\n");
940 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
941 NT_STATUS_LOCK_NOT_GRANTED)) return False;
944 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
945 printf("WRITE lock2 succeeded! This is a locking bug\n");
948 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
949 NT_STATUS_LOCK_NOT_GRANTED)) return False;
952 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
953 printf("READ lock2 succeeded! This is a locking bug\n");
956 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
957 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
960 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
961 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
964 cli->session->pid = 2;
966 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
967 printf("unlock at 100 succeeded! This is a locking bug\n");
971 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
972 printf("unlock1 succeeded! This is a locking bug\n");
975 if (!check_error(__LINE__, cli,
977 NT_STATUS_RANGE_NOT_LOCKED)) return False;
980 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
981 printf("unlock2 succeeded! This is a locking bug\n");
984 if (!check_error(__LINE__, cli,
986 NT_STATUS_RANGE_NOT_LOCKED)) return False;
989 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
990 printf("lock3 succeeded! This is a locking bug\n");
993 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
996 cli->session->pid = 1;
998 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
999 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1003 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1004 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1008 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1009 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1013 if (!torture_close_connection(cli)) {
1017 printf("locktest2 finished\n");
1024 This test checks that
1026 1) the server supports the full offset range in lock requests
1028 static BOOL run_locktest3(int dummy)
1030 struct smbcli_state *cli1, *cli2;
1031 const char *fname = "\\lockt3.lck";
1032 int fnum1, fnum2, i;
1034 BOOL correct = True;
1036 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1038 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1042 printf("starting locktest3\n");
1044 printf("Testing 32 bit offset ranges\n");
1046 smbcli_unlink(cli1->tree, fname);
1048 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1050 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1053 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1055 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1059 printf("Establishing %d locks\n", torture_numops);
1061 for (offset=i=0;i<torture_numops;i++) {
1063 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1064 printf("lock1 %d failed (%s)\n",
1066 smbcli_errstr(cli1->tree));
1070 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1071 printf("lock2 %d failed (%s)\n",
1073 smbcli_errstr(cli1->tree));
1078 printf("Testing %d locks\n", torture_numops);
1080 for (offset=i=0;i<torture_numops;i++) {
1083 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1084 printf("error: lock1 %d succeeded!\n", i);
1088 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1089 printf("error: lock2 %d succeeded!\n", i);
1093 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1094 printf("error: lock3 %d succeeded!\n", i);
1098 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1099 printf("error: lock4 %d succeeded!\n", i);
1104 printf("Removing %d locks\n", torture_numops);
1106 for (offset=i=0;i<torture_numops;i++) {
1109 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1110 printf("unlock1 %d failed (%s)\n",
1112 smbcli_errstr(cli1->tree));
1116 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1117 printf("unlock2 %d failed (%s)\n",
1119 smbcli_errstr(cli1->tree));
1124 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1125 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1129 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1130 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1134 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1135 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1139 if (!torture_close_connection(cli1)) {
1143 if (!torture_close_connection(cli2)) {
1147 printf("finished locktest3\n");
1152 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1153 printf("** "); correct = False; \
1157 looks at overlapping locks
1159 static BOOL run_locktest4(int dummy)
1161 struct smbcli_state *cli1, *cli2;
1162 const char *fname = "\\lockt4.lck";
1163 int fnum1, fnum2, f;
1166 BOOL correct = True;
1168 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1172 printf("starting locktest4\n");
1174 smbcli_unlink(cli1->tree, fname);
1176 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1177 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1179 memset(buf, 0, sizeof(buf));
1181 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1182 printf("Failed to create file\n");
1187 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1188 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1189 EXPECTED(ret, False);
1190 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1192 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1193 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1194 EXPECTED(ret, True);
1195 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1197 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1198 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1199 EXPECTED(ret, False);
1200 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1202 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1203 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1204 EXPECTED(ret, True);
1205 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1207 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1208 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1209 EXPECTED(ret, False);
1210 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1212 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1213 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1214 EXPECTED(ret, True);
1215 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1217 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1218 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1219 EXPECTED(ret, True);
1220 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1222 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1223 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1224 EXPECTED(ret, False);
1225 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1227 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1228 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1229 EXPECTED(ret, False);
1230 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1232 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1233 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1234 EXPECTED(ret, True);
1235 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1237 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1238 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1239 EXPECTED(ret, False);
1240 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1242 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1243 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1244 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1245 EXPECTED(ret, False);
1246 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1249 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1250 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1251 EXPECTED(ret, False);
1252 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1254 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1255 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1256 EXPECTED(ret, False);
1257 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1260 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1261 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1262 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1263 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1264 EXPECTED(ret, True);
1265 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1268 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1269 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1270 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1271 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1272 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1273 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1274 EXPECTED(ret, True);
1275 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1277 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1278 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1279 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1280 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1281 EXPECTED(ret, True);
1282 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1284 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1285 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1286 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1287 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1288 EXPECTED(ret, True);
1289 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1291 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1292 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1293 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1294 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1295 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1296 EXPECTED(ret, True);
1297 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1299 smbcli_close(cli1->tree, fnum1);
1300 smbcli_close(cli2->tree, fnum2);
1301 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1302 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1303 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1304 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1305 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1306 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1307 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1308 smbcli_close(cli1->tree, f);
1309 smbcli_close(cli1->tree, fnum1);
1310 EXPECTED(ret, True);
1311 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1314 smbcli_close(cli1->tree, fnum1);
1315 smbcli_close(cli2->tree, fnum2);
1316 smbcli_unlink(cli1->tree, fname);
1317 torture_close_connection(cli1);
1318 torture_close_connection(cli2);
1320 printf("finished locktest4\n");
1325 looks at lock upgrade/downgrade.
1327 static BOOL run_locktest5(int dummy)
1329 struct smbcli_state *cli1, *cli2;
1330 const char *fname = "\\lockt5.lck";
1331 int fnum1, fnum2, fnum3;
1334 BOOL correct = True;
1336 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1340 printf("starting locktest5\n");
1342 smbcli_unlink(cli1->tree, fname);
1344 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1345 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1346 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1348 memset(buf, 0, sizeof(buf));
1350 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1351 printf("Failed to create file\n");
1356 /* Check for NT bug... */
1357 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1358 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1359 smbcli_close(cli1->tree, fnum1);
1360 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1361 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1362 EXPECTED(ret, True);
1363 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1364 smbcli_close(cli1->tree, fnum1);
1365 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1366 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1368 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1369 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1370 EXPECTED(ret, True);
1371 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1373 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1374 EXPECTED(ret, False);
1376 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1378 /* Unlock the process 2 lock. */
1379 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1381 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1382 EXPECTED(ret, False);
1384 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1386 /* Unlock the process 1 fnum3 lock. */
1387 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1389 /* Stack 2 more locks here. */
1390 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1391 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1393 EXPECTED(ret, True);
1394 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1396 /* Unlock the first process lock, then check this was the WRITE lock that was
1399 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1400 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1402 EXPECTED(ret, True);
1403 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1405 /* Unlock the process 2 lock. */
1406 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1408 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1410 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1411 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1412 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1414 EXPECTED(ret, True);
1415 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1417 /* Ensure the next unlock fails. */
1418 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1419 EXPECTED(ret, False);
1420 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1422 /* Ensure connection 2 can get a write lock. */
1423 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1424 EXPECTED(ret, True);
1426 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1430 smbcli_close(cli1->tree, fnum1);
1431 smbcli_close(cli2->tree, fnum2);
1432 smbcli_unlink(cli1->tree, fname);
1433 if (!torture_close_connection(cli1)) {
1436 if (!torture_close_connection(cli2)) {
1440 printf("finished locktest5\n");
1446 tries the unusual lockingX locktype bits
1448 static BOOL run_locktest6(int dummy)
1450 struct smbcli_state *cli;
1451 const char *fname[1] = { "\\lock6.txt" };
1456 if (!torture_open_connection(&cli)) {
1460 printf("starting locktest6\n");
1463 printf("Testing %s\n", fname[i]);
1465 smbcli_unlink(cli->tree, fname[i]);
1467 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1468 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1469 smbcli_close(cli->tree, fnum);
1470 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1472 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1473 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1474 smbcli_close(cli->tree, fnum);
1475 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1477 smbcli_unlink(cli->tree, fname[i]);
1480 torture_close_connection(cli);
1482 printf("finished locktest6\n");
1486 static BOOL run_locktest7(int dummy)
1488 struct smbcli_state *cli1;
1489 const char *fname = "\\lockt7.lck";
1494 BOOL correct = False;
1496 if (!torture_open_connection(&cli1)) {
1500 printf("starting locktest7\n");
1502 smbcli_unlink(cli1->tree, fname);
1504 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1506 memset(buf, 0, sizeof(buf));
1508 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1509 printf("Failed to create file\n");
1513 cli1->session->pid = 1;
1515 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1516 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1519 printf("pid1 successfully locked range 130:4 for READ\n");
1522 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1523 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1526 printf("pid1 successfully read the range 130:4\n");
1529 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1530 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1531 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1532 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1536 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1540 cli1->session->pid = 2;
1542 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1543 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1545 printf("pid2 successfully read the range 130:4\n");
1548 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1549 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1550 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1551 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1555 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1559 cli1->session->pid = 1;
1560 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1562 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1563 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1566 printf("pid1 successfully locked range 130:4 for WRITE\n");
1569 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1570 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1573 printf("pid1 successfully read the range 130:4\n");
1576 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1577 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1580 printf("pid1 successfully wrote to the range 130:4\n");
1583 cli1->session->pid = 2;
1585 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1586 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1587 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1588 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1592 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1596 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1597 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1598 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1599 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1603 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1607 printf("Testing truncate of locked file.\n");
1609 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1612 printf("Unable to truncate locked file.\n");
1616 printf("Truncated locked file.\n");
1619 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1620 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1626 printf("Unable to truncate locked file. Size was %u\n", size);
1631 cli1->session->pid = 1;
1633 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1637 smbcli_close(cli1->tree, fnum1);
1638 smbcli_close(cli1->tree, fnum2);
1639 smbcli_unlink(cli1->tree, fname);
1640 torture_close_connection(cli1);
1642 printf("finished locktest7\n");
1647 test whether fnums and tids open on one VC are available on another (a major
1650 static BOOL run_fdpasstest(int dummy)
1652 struct smbcli_state *cli1, *cli2;
1653 const char *fname = "\\fdpass.tst";
1657 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1661 printf("starting fdpasstest\n");
1663 smbcli_unlink(cli1->tree, fname);
1665 printf("Opening a file on connection 1\n");
1667 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1669 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1673 printf("writing to file on connection 1\n");
1675 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1676 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1680 oldtid = cli2->tree->tid;
1681 cli2->session->vuid = cli1->session->vuid;
1682 cli2->tree->tid = cli1->tree->tid;
1683 cli2->session->pid = cli1->session->pid;
1685 printf("reading from file on connection 2\n");
1687 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1688 printf("read succeeded! nasty security hole [%s]\n",
1693 smbcli_close(cli1->tree, fnum1);
1694 smbcli_unlink(cli1->tree, fname);
1696 cli2->tree->tid = oldtid;
1698 torture_close_connection(cli1);
1699 torture_close_connection(cli2);
1701 printf("finished fdpasstest\n");
1707 This test checks that
1709 1) the server does not allow an unlink on a file that is open
1711 static BOOL run_unlinktest(int dummy)
1713 struct smbcli_state *cli;
1714 const char *fname = "\\unlink.tst";
1716 BOOL correct = True;
1718 if (!torture_open_connection(&cli)) {
1722 printf("starting unlink test\n");
1724 smbcli_unlink(cli->tree, fname);
1726 cli->session->pid = 1;
1728 printf("Opening a file\n");
1730 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1732 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1736 printf("Unlinking a open file\n");
1738 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1739 printf("error: server allowed unlink on an open file\n");
1742 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1743 NT_STATUS_SHARING_VIOLATION);
1746 smbcli_close(cli->tree, fnum);
1747 smbcli_unlink(cli->tree, fname);
1749 if (!torture_close_connection(cli)) {
1753 printf("unlink test finished\n");
1760 test the timing of deferred open requests
1762 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1764 const char *fname = "\\defer_open_test.dat";
1767 BOOL correct = True;
1770 printf("failed to connect\n");
1774 printf("Testing deferred open requests.\n");
1780 struct timeval tv_start, tv_end;
1781 GetTimeOfDay(&tv_start);
1782 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1783 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1784 NTCREATEX_DISP_OPEN_IF, 0, 0);
1788 GetTimeOfDay(&tv_end);
1789 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1790 /* Sharing violation errors need to be 1 second apart. */
1791 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1792 if (tdif < 500000 || tdif > 1500000) {
1793 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1794 tdif / (int64_t)1000000,
1795 tdif % (int64_t)1000000);
1798 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1801 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1805 printf("pid %u open %d\n", getpid(), i);
1809 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1810 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1816 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1817 /* All until the last unlink will fail with sharing violation. */
1818 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1819 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1824 printf("deferred test finished\n");
1825 if (!torture_close_connection(cli)) {
1832 test how many open files this server supports on the one socket
1834 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1836 #define MAXFID_TEMPLATE "\\maxfid.%d.%d"
1838 int fnums[0x11000], i;
1840 BOOL correct = True;
1843 printf("failed to connect\n");
1847 printf("Testing maximum number of open files\n");
1849 for (i=0; i<0x11000; i++) {
1850 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1851 if ((fnums[i] = smbcli_open(cli->tree, fname,
1852 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1854 printf("open of %s failed (%s)\n",
1855 fname, smbcli_errstr(cli->tree));
1856 printf("maximum fnum is %d\n", i);
1865 printf("cleaning up\n");
1867 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1868 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1869 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1871 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1872 printf("unlink of %s failed (%s)\n",
1873 fname, smbcli_errstr(cli->tree));
1881 printf("maxfid test finished\n");
1882 if (!torture_close_connection(cli)) {
1886 #undef MAXFID_TEMPLATE
1889 /* send smb negprot commands, not reading the response */
1890 static BOOL run_negprot_nowait(int dummy)
1893 struct smbcli_state *cli, *cli2;
1894 BOOL correct = True;
1896 printf("starting negprot nowait test\n");
1898 cli = open_nbt_connection();
1903 printf("Filling send buffer\n");
1905 for (i=0;i<10000;i++) {
1906 struct smbcli_request *req;
1907 time_t t1 = time(NULL);
1908 req = smb_negprot_send(cli->transport, PROTOCOL_NT1);
1909 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
1910 smbcli_transport_process(cli->transport);
1912 if (req->state == SMBCLI_REQUEST_ERROR) {
1913 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
1914 torture_close_connection(cli);
1917 if (req->state == SMBCLI_REQUEST_SEND) {
1923 printf("send buffer failed to fill\n");
1924 if (!torture_close_connection(cli)) {
1930 printf("send buffer filled after %d requests\n", i);
1932 printf("Opening secondary connection\n");
1933 if (!torture_open_connection(&cli2)) {
1937 if (!torture_close_connection(cli)) {
1941 if (!torture_close_connection(cli2)) {
1945 printf("finished negprot nowait test\n");
1952 This checks how the getatr calls works
1954 static BOOL run_attrtest(int dummy)
1956 struct smbcli_state *cli;
1959 const char *fname = "\\attrib123456789.tst";
1960 BOOL correct = True;
1962 printf("starting attrib test\n");
1964 if (!torture_open_connection(&cli)) {
1968 smbcli_unlink(cli->tree, fname);
1969 fnum = smbcli_open(cli->tree, fname,
1970 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1971 smbcli_close(cli->tree, fnum);
1973 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1974 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1978 printf("New file time is %s", ctime(&t));
1980 if (abs(t - time(NULL)) > 60*60*24*10) {
1981 printf("ERROR: SMBgetatr bug. time is %s",
1987 t2 = t-60*60*24; /* 1 day ago */
1989 printf("Setting file time to %s", ctime(&t2));
1991 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
1992 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
1996 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1997 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2001 printf("Retrieved file time as %s", ctime(&t));
2004 printf("ERROR: getatr/setatr bug. times are\n%s",
2006 printf("%s", ctime(&t2));
2010 smbcli_unlink(cli->tree, fname);
2012 if (!torture_close_connection(cli)) {
2016 printf("attrib test finished\n");
2023 This checks a couple of trans2 calls
2025 static BOOL run_trans2test(int dummy)
2027 struct smbcli_state *cli;
2030 time_t c_time, a_time, m_time, w_time, m_time2;
2031 const char *fname = "\\trans2.tst";
2032 const char *dname = "\\trans2";
2033 const char *fname2 = "\\trans2\\trans2.tst";
2035 BOOL correct = True;
2037 printf("starting trans2 test\n");
2039 if (!torture_open_connection(&cli)) {
2043 smbcli_unlink(cli->tree, fname);
2045 printf("Testing qfileinfo\n");
2047 fnum = smbcli_open(cli->tree, fname,
2048 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2049 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2051 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
2055 printf("Testing NAME_INFO\n");
2057 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
2058 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
2062 if (!pname || strcmp(pname, fname)) {
2063 printf("qfilename gave different name? [%s] [%s]\n",
2068 smbcli_close(cli->tree, fnum);
2069 smbcli_unlink(cli->tree, fname);
2071 fnum = smbcli_open(cli->tree, fname,
2072 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2074 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
2077 smbcli_close(cli->tree, fnum);
2079 printf("Checking for sticky create times\n");
2081 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2082 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
2085 if (c_time != m_time) {
2086 printf("create time=%s", ctime(&c_time));
2087 printf("modify time=%s", ctime(&m_time));
2088 printf("This system appears to have sticky create times\n");
2090 if (a_time % (60*60) == 0) {
2091 printf("access time=%s", ctime(&a_time));
2092 printf("This system appears to set a midnight access time\n");
2096 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2097 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2103 smbcli_unlink(cli->tree, fname);
2104 fnum = smbcli_open(cli->tree, fname,
2105 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2106 smbcli_close(cli->tree, fnum);
2107 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2108 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2111 if (w_time < 60*60*24*2) {
2112 printf("write time=%s", ctime(&w_time));
2113 printf("This system appears to set a initial 0 write time\n");
2118 smbcli_unlink(cli->tree, fname);
2121 /* check if the server updates the directory modification time
2122 when creating a new file */
2123 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
2124 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
2128 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2129 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2133 fnum = smbcli_open(cli->tree, fname2,
2134 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2135 smbcli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2136 smbcli_close(cli->tree, fnum);
2137 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2138 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2141 if (m_time2 == m_time) {
2142 printf("This system does not update directory modification times\n");
2146 smbcli_unlink(cli->tree, fname2);
2147 smbcli_rmdir(cli->tree, dname);
2149 if (!torture_close_connection(cli)) {
2153 printf("trans2 test finished\n");
2159 Test delete on close semantics.
2161 static BOOL run_deletetest(int dummy)
2163 struct smbcli_state *cli1;
2164 struct smbcli_state *cli2 = NULL;
2165 const char *fname = "\\delete.file";
2168 BOOL correct = True;
2170 printf("starting delete test\n");
2172 if (!torture_open_connection(&cli1)) {
2176 /* Test 1 - this should delete the file on close. */
2178 smbcli_setatr(cli1->tree, fname, 0, 0);
2179 smbcli_unlink(cli1->tree, fname);
2181 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2182 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2183 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2186 printf("[1] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2191 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2192 printf("[1] close failed (%s)\n", smbcli_errstr(cli1->tree));
2197 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2199 printf("[1] open of %s succeeded (should fail)\n", fname);
2204 printf("first delete on close test succeeded.\n");
2206 /* Test 2 - this should delete the file on close. */
2208 smbcli_setatr(cli1->tree, fname, 0, 0);
2209 smbcli_unlink(cli1->tree, fname);
2211 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2212 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2213 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2216 printf("[2] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2221 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2222 printf("[2] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2227 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2228 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2233 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2235 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2236 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2237 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2241 smbcli_unlink(cli1->tree, fname);
2243 printf("second delete on close test succeeded.\n");
2246 smbcli_setatr(cli1->tree, fname, 0, 0);
2247 smbcli_unlink(cli1->tree, fname);
2249 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2250 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2253 printf("[3] open - 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2258 /* This should fail with a sharing violation - open for delete is only compatible
2259 with SHARE_DELETE. */
2261 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2262 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2263 NTCREATEX_DISP_OPEN, 0, 0);
2266 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2271 /* This should succeed. */
2273 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2274 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2277 printf("[3] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2282 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2283 printf("[3] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2288 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2289 printf("[3] close 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2294 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2295 printf("[3] close 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2300 /* This should fail - file should no longer be there. */
2302 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2304 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2305 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2306 printf("[3] close failed (%s)\n", smbcli_errstr(cli1->tree));
2308 smbcli_unlink(cli1->tree, fname);
2312 printf("third delete on close test succeeded.\n");
2315 smbcli_setatr(cli1->tree, fname, 0, 0);
2316 smbcli_unlink(cli1->tree, fname);
2318 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2319 SA_RIGHT_FILE_READ_DATA |
2320 SA_RIGHT_FILE_WRITE_DATA |
2321 STD_RIGHT_DELETE_ACCESS,
2322 FILE_ATTRIBUTE_NORMAL,
2323 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2324 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2327 printf("[4] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2332 /* This should succeed. */
2333 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2334 FILE_ATTRIBUTE_NORMAL,
2335 NTCREATEX_SHARE_ACCESS_READ |
2336 NTCREATEX_SHARE_ACCESS_WRITE |
2337 NTCREATEX_SHARE_ACCESS_DELETE,
2338 NTCREATEX_DISP_OPEN, 0, 0);
2340 printf("[4] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2345 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2346 printf("[4] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2351 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2352 printf("[4] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2357 /* This should fail - no more opens once delete on close set. */
2358 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2359 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2360 NTCREATEX_DISP_OPEN, 0, 0);
2362 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2366 printf("fourth delete on close test succeeded.\n");
2368 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2369 printf("[4] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2375 smbcli_setatr(cli1->tree, fname, 0, 0);
2376 smbcli_unlink(cli1->tree, fname);
2378 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2380 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2385 /* This should fail - only allowed on NT opens with DELETE access. */
2387 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2388 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2393 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2394 printf("[5] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2399 printf("fifth delete on close test succeeded.\n");
2402 smbcli_setatr(cli1->tree, fname, 0, 0);
2403 smbcli_unlink(cli1->tree, fname);
2405 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2406 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2407 FILE_ATTRIBUTE_NORMAL,
2408 NTCREATEX_SHARE_ACCESS_READ |
2409 NTCREATEX_SHARE_ACCESS_WRITE |
2410 NTCREATEX_SHARE_ACCESS_DELETE,
2411 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2414 printf("[6] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2419 /* This should fail - only allowed on NT opens with DELETE access. */
2421 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2422 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2427 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2428 printf("[6] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2433 printf("sixth delete on close test succeeded.\n");
2436 smbcli_setatr(cli1->tree, fname, 0, 0);
2437 smbcli_unlink(cli1->tree, fname);
2439 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2440 SA_RIGHT_FILE_READ_DATA |
2441 SA_RIGHT_FILE_WRITE_DATA |
2442 STD_RIGHT_DELETE_ACCESS,
2443 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2446 printf("[7] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2451 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2452 printf("[7] setting delete_on_close on file failed !\n");
2457 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2458 printf("[7] unsetting delete_on_close on file failed !\n");
2463 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2464 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2469 /* This next open should succeed - we reset the flag. */
2471 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2473 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2478 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2479 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2484 printf("seventh delete on close test succeeded.\n");
2487 smbcli_setatr(cli1->tree, fname, 0, 0);
2488 smbcli_unlink(cli1->tree, fname);
2490 if (!torture_open_connection(&cli2)) {
2491 printf("[8] failed to open second connection.\n");
2496 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2497 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2498 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2501 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2506 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2507 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2508 NTCREATEX_DISP_OPEN, 0, 0);
2511 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2516 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2517 printf("[8] setting delete_on_close on file failed !\n");
2522 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2523 printf("[8] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2528 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
2529 printf("[8] close - 2 failed (%s)\n", smbcli_errstr(cli2->tree));
2534 /* This should fail.. */
2535 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2537 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2541 printf("eighth delete on close test succeeded.\n");
2543 /* This should fail - we need to set DELETE_ACCESS. */
2544 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2545 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2548 printf("[9] open of %s succeeded should have failed!\n", fname);
2553 printf("ninth delete on close test succeeded.\n");
2555 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2556 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2558 printf("[10] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2563 /* This should delete the file. */
2564 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2565 printf("[10] close failed (%s)\n", smbcli_errstr(cli1->tree));
2570 /* This should fail.. */
2571 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2573 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2577 printf("tenth delete on close test succeeded.\n");
2578 printf("finished delete test\n");
2581 /* FIXME: This will crash if we aborted before cli2 got
2582 * intialized, because these functions don't handle
2583 * uninitialized connections. */
2585 smbcli_close(cli1->tree, fnum1);
2586 smbcli_close(cli1->tree, fnum2);
2587 smbcli_setatr(cli1->tree, fname, 0, 0);
2588 smbcli_unlink(cli1->tree, fname);
2590 if (!torture_close_connection(cli1)) {
2593 if (!torture_close_connection(cli2)) {
2601 print out server properties
2603 static BOOL run_properties(int dummy)
2605 struct smbcli_state *cli;
2606 BOOL correct = True;
2608 printf("starting properties test\n");
2612 if (!torture_open_connection(&cli)) {
2616 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2618 if (!torture_close_connection(cli)) {
2627 /* FIRST_DESIRED_ACCESS 0xf019f */
2628 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2629 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2630 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2631 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2632 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2633 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2634 /* SECOND_DESIRED_ACCESS 0xe0080 */
2635 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2636 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2637 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2640 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2641 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2642 SA_RIGHT_FILE_READ_DATA|\
2643 WRITE_OWNER_ACCESS /* */
2647 Test ntcreate calls made by xcopy
2649 static BOOL run_xcopy(int dummy)
2651 struct smbcli_state *cli1;
2652 const char *fname = "\\test.txt";
2653 BOOL correct = True;
2656 printf("starting xcopy test\n");
2658 if (!torture_open_connection(&cli1)) {
2662 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2663 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2664 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2668 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2672 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
2673 SECOND_DESIRED_ACCESS, 0,
2674 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2677 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
2681 if (!torture_close_connection(cli1)) {
2689 Test rename on files open with share delete and no share delete.
2691 static BOOL run_rename(int dummy)
2693 struct smbcli_state *cli1;
2694 const char *fname = "\\test.txt";
2695 const char *fname1 = "\\test1.txt";
2696 BOOL correct = True;
2699 printf("starting rename test\n");
2701 if (!torture_open_connection(&cli1)) {
2705 smbcli_unlink(cli1->tree, fname);
2706 smbcli_unlink(cli1->tree, fname1);
2707 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2708 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2711 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2715 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2716 printf("First rename failed (this is correct) - %s\n", smbcli_errstr(cli1->tree));
2718 printf("First rename succeeded - this should have failed !\n");
2722 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2723 printf("close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2727 smbcli_unlink(cli1->tree, fname);
2728 smbcli_unlink(cli1->tree, fname1);
2729 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2730 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2733 printf("Second open failed - %s\n", smbcli_errstr(cli1->tree));
2737 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2738 printf("Second rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2741 printf("Second rename succeeded\n");
2744 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2745 printf("close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2749 smbcli_unlink(cli1->tree, fname);
2750 smbcli_unlink(cli1->tree, fname1);
2752 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2753 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2756 printf("Third open failed - %s\n", smbcli_errstr(cli1->tree));
2761 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2762 printf("Third rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2765 printf("Third rename succeeded\n");
2768 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2769 printf("close - 3 failed (%s)\n", smbcli_errstr(cli1->tree));
2773 smbcli_unlink(cli1->tree, fname);
2774 smbcli_unlink(cli1->tree, fname1);
2776 if (!torture_close_connection(cli1)) {
2785 see how many RPC pipes we can open at once
2787 static BOOL run_pipe_number(int dummy)
2789 struct smbcli_state *cli1;
2790 const char *pipe_name = "\\WKSSVC";
2794 printf("starting pipenumber test\n");
2795 if (!torture_open_connection(&cli1)) {
2800 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2801 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2804 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
2808 printf("%d\r", num_pipes);
2812 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2813 torture_close_connection(cli1);
2821 open N connections to the server and just hold them open
2822 used for testing performance when there are N idle users
2825 static BOOL torture_holdcon(int dummy)
2828 struct smbcli_state **cli;
2831 printf("Opening %d connections\n", torture_numops);
2833 cli = malloc(sizeof(struct smbcli_state *) * torture_numops);
2835 for (i=0;i<torture_numops;i++) {
2836 if (!torture_open_connection(&cli[i])) {
2839 printf("opened %d connections\r", i);
2843 printf("\nStarting pings\n");
2846 for (i=0;i<torture_numops;i++) {
2849 status = smbcli_chkpath(cli[i]->tree, "\\");
2850 if (!NT_STATUS_IS_OK(status)) {
2851 printf("Connection %d is dead\n", i);
2859 if (num_dead == torture_numops) {
2860 printf("All connections dead - finishing\n");
2872 Try with a wrong vuid and check error message.
2875 static BOOL run_vuidtest(int dummy)
2877 struct smbcli_state *cli;
2878 const char *fname = "\\vuid.tst";
2881 time_t c_time, a_time, m_time;
2882 BOOL correct = True;
2887 printf("starting vuid test\n");
2889 if (!torture_open_connection(&cli)) {
2893 smbcli_unlink(cli->tree, fname);
2895 fnum = smbcli_open(cli->tree, fname,
2896 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2898 orig_vuid = cli->session->vuid;
2900 cli->session->vuid += 1234;
2902 printf("Testing qfileinfo with wrong vuid\n");
2904 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
2905 &size, &c_time, &a_time,
2906 &m_time, NULL, NULL))) {
2907 printf("ERROR: qfileinfo passed with wrong vuid\n");
2911 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2912 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2913 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2914 printf("ERROR: qfileinfo should have returned DOS error "
2915 "ERRSRV:ERRbaduid\n but returned %s\n",
2916 smbcli_errstr(cli->tree));
2920 cli->session->vuid -= 1234;
2922 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
2923 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
2927 smbcli_unlink(cli->tree, fname);
2929 if (!torture_close_connection(cli)) {
2933 printf("vuid test finished\n");
2939 Test open mode returns on read-only files.
2941 static BOOL run_opentest(int dummy)
2943 static struct smbcli_state *cli1;
2944 static struct smbcli_state *cli2;
2945 const char *fname = "\\readonly.file";
2949 BOOL correct = True;
2953 printf("starting open test\n");
2955 if (!torture_open_connection(&cli1)) {
2959 smbcli_setatr(cli1->tree, fname, 0, 0);
2960 smbcli_unlink(cli1->tree, fname);
2962 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2964 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2968 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2969 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
2973 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2974 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
2975 CHECK_MAX_FAILURES(error_test1);
2979 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2981 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2982 CHECK_MAX_FAILURES(error_test1);
2986 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2987 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2989 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2990 NT_STATUS_ACCESS_DENIED)) {
2991 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2994 printf("finished open test 1\n");
2996 smbcli_close(cli1->tree, fnum1);
2998 /* Now try not readonly and ensure ERRbadshare is returned. */
3000 smbcli_setatr(cli1->tree, fname, 0, 0);
3002 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3004 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3008 /* This will fail - but the error should be ERRshare. */
3009 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3011 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3012 NT_STATUS_SHARING_VIOLATION)) {
3013 printf("correct error code ERRDOS/ERRbadshare returned\n");
3016 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3017 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3021 smbcli_unlink(cli1->tree, fname);
3023 printf("finished open test 2\n");
3025 /* Test truncate open disposition on file opened for read. */
3027 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3029 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3033 /* write 20 bytes. */
3035 memset(buf, '\0', 20);
3037 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3038 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
3042 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3043 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3047 /* Ensure size == 20. */
3048 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3049 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3050 CHECK_MAX_FAILURES(error_test3);
3055 printf("(3) file size != 20\n");
3056 CHECK_MAX_FAILURES(error_test3);
3060 /* Now test if we can truncate a file opened for readonly. */
3062 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3064 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3065 CHECK_MAX_FAILURES(error_test3);
3069 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3070 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3074 /* Ensure size == 0. */
3075 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3076 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3077 CHECK_MAX_FAILURES(error_test3);
3082 printf("(3) file size != 0\n");
3083 CHECK_MAX_FAILURES(error_test3);
3086 printf("finished open test 3\n");
3088 smbcli_unlink(cli1->tree, fname);
3091 printf("testing ctemp\n");
3092 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
3094 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
3095 CHECK_MAX_FAILURES(error_test4);
3098 printf("ctemp gave path %s\n", tmp_path);
3099 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3100 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3102 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
3103 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3106 /* Test the non-io opens... */
3108 if (!torture_open_connection(&cli2)) {
3112 smbcli_setatr(cli2->tree, fname, 0, 0);
3113 smbcli_unlink(cli2->tree, fname);
3115 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3117 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3118 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3121 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3122 CHECK_MAX_FAILURES(error_test10);
3126 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3127 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3129 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3130 CHECK_MAX_FAILURES(error_test10);
3134 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3135 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3138 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3139 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3143 printf("non-io open test #1 passed.\n");
3145 smbcli_unlink(cli1->tree, fname);
3147 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3149 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3150 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3153 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3154 CHECK_MAX_FAILURES(error_test20);
3158 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3159 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3162 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3163 CHECK_MAX_FAILURES(error_test20);
3167 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3168 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3171 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3172 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3176 printf("non-io open test #2 passed.\n");
3178 smbcli_unlink(cli1->tree, fname);
3180 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3182 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3183 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3186 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3187 CHECK_MAX_FAILURES(error_test30);
3191 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3192 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3195 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3196 CHECK_MAX_FAILURES(error_test30);
3200 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3201 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3204 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3205 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3209 printf("non-io open test #3 passed.\n");
3211 smbcli_unlink(cli1->tree, fname);
3213 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3215 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3216 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3219 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3220 CHECK_MAX_FAILURES(error_test40);
3224 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3225 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3228 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3229 CHECK_MAX_FAILURES(error_test40);
3233 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3235 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3236 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3240 printf("non-io open test #4 passed.\n");
3242 smbcli_unlink(cli1->tree, fname);
3244 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3246 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3247 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3250 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3251 CHECK_MAX_FAILURES(error_test50);
3255 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3256 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3259 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3260 CHECK_MAX_FAILURES(error_test50);
3264 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3265 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3269 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3270 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3274 printf("non-io open test #5 passed.\n");
3276 printf("TEST #6 testing 1 non-io open, one io open\n");
3278 smbcli_unlink(cli1->tree, fname);
3280 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3281 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3284 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3285 CHECK_MAX_FAILURES(error_test60);
3289 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3290 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3293 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3294 CHECK_MAX_FAILURES(error_test60);
3298 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3299 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3303 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3304 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3308 printf("non-io open test #6 passed.\n");
3310 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3312 smbcli_unlink(cli1->tree, fname);
3314 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3315 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3318 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3319 CHECK_MAX_FAILURES(error_test70);
3323 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3324 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3327 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3328 CHECK_MAX_FAILURES(error_test70);
3332 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3334 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3335 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3339 printf("non-io open test #7 passed.\n");
3343 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3345 smbcli_unlink(cli1->tree, fname);
3347 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3349 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3353 /* write 20 bytes. */
3355 memset(buf, '\0', 20);
3357 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3358 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
3362 /* Ensure size == 20. */
3363 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3364 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
3365 CHECK_MAX_FAILURES(error_test80);
3370 printf("(8) file size != 20\n");
3371 CHECK_MAX_FAILURES(error_test80);
3375 /* Get an exclusive lock on the open file. */
3376 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3377 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
3378 CHECK_MAX_FAILURES(error_test80);
3382 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3384 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3388 /* Ensure size == 0. */
3389 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3390 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
3391 CHECK_MAX_FAILURES(error_test80);
3396 printf("(8) file size != 0\n");
3397 CHECK_MAX_FAILURES(error_test80);
3401 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3402 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3406 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
3407 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3413 printf("open test #8 passed.\n");
3415 smbcli_unlink(cli1->tree, fname);
3417 if (!torture_close_connection(cli1)) {
3420 if (!torture_close_connection(cli2)) {
3428 static uint32_t open_attrs_table[] = {
3429 FILE_ATTRIBUTE_NORMAL,
3430 FILE_ATTRIBUTE_ARCHIVE,
3431 FILE_ATTRIBUTE_READONLY,
3432 FILE_ATTRIBUTE_HIDDEN,
3433 FILE_ATTRIBUTE_SYSTEM,
3435 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3436 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3437 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3438 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3439 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3440 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3442 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3443 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3444 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3445 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3448 struct trunc_open_results {
3451 uint32_t trunc_attr;
3452 uint32_t result_attr;
3455 static struct trunc_open_results attr_results[] = {
3456 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3457 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3458 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3459 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3460 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3461 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3462 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3463 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3464 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3465 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3466 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3467 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3468 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3469 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3470 { 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 },
3471 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3472 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3473 { 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 },
3474 { 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 },
3475 { 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 },
3476 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3477 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3478 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3479 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3480 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3481 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3484 static BOOL run_openattrtest(int dummy)
3486 struct smbcli_state *cli1;
3487 const char *fname = "\\openattr.file";
3489 BOOL correct = True;
3494 printf("starting open attr test\n");
3496 if (!torture_open_connection(&cli1)) {
3500 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3501 smbcli_setatr(cli1->tree, fname, 0, 0);
3502 smbcli_unlink(cli1->tree, fname);
3503 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3504 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3507 printf("open %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3511 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3512 printf("close %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3516 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3517 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
3518 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3519 open_attrs_table[j],
3520 NTCREATEX_SHARE_ACCESS_NONE,
3521 NTCREATEX_DISP_OVERWRITE, 0, 0);
3524 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3525 if (attr_results[l].num == k) {
3526 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3527 k, open_attrs_table[i],
3528 open_attrs_table[j],
3529 fname, NT_STATUS_V(smbcli_nt_error(cli1->tree)), smbcli_errstr(cli1->tree));
3531 CHECK_MAX_FAILURES(error_exit);
3534 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3535 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3536 k, open_attrs_table[i], open_attrs_table[j],
3537 smbcli_errstr(cli1->tree));
3539 CHECK_MAX_FAILURES(error_exit);
3542 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3548 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3549 printf("close %d (2) of %s failed (%s)\n", j, fname, smbcli_errstr(cli1->tree));
3553 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3554 printf("getatr(2) failed (%s)\n", smbcli_errstr(cli1->tree));
3559 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3560 k, open_attrs_table[i], open_attrs_table[j], attr );
3563 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3564 if (attr_results[l].num == k) {
3565 if (attr != attr_results[l].result_attr ||
3566 open_attrs_table[i] != attr_results[l].init_attr ||
3567 open_attrs_table[j] != attr_results[l].trunc_attr) {
3568 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3569 k, open_attrs_table[i],
3570 open_attrs_table[j],
3572 attr_results[l].result_attr);
3574 CHECK_MAX_FAILURES(error_exit);
3583 smbcli_setatr(cli1->tree, fname, 0, 0);
3584 smbcli_unlink(cli1->tree, fname);
3586 printf("open attr test %s.\n", correct ? "passed" : "failed");
3588 if (!torture_close_connection(cli1)) {
3594 static void list_fn(file_info *finfo, const char *name, void *state)
3600 test directory listing speed
3602 static BOOL run_dirtest(int dummy)
3605 struct smbcli_state *cli;
3608 BOOL correct = True;
3610 printf("starting directory test\n");
3612 if (!torture_open_connection(&cli)) {
3616 printf("Creating %d random filenames\n", torture_numops);
3619 for (i=0;i<torture_numops;i++) {
3621 asprintf(&fname, "\\%x", (int)random());
3622 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3624 fprintf(stderr,"Failed to open %s\n", fname);
3627 smbcli_close(cli->tree, fnum);
3633 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3634 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3635 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3637 printf("dirtest core %g seconds\n", end_timer() - t1);
3640 for (i=0;i<torture_numops;i++) {
3642 asprintf(&fname, "\\%x", (int)random());
3643 smbcli_unlink(cli->tree, fname);
3647 if (!torture_close_connection(cli)) {
3651 printf("finished dirtest\n");
3657 sees what IOCTLs are supported
3659 BOOL torture_ioctl_test(int dummy)
3661 struct smbcli_state *cli;
3662 uint16_t device, function;
3664 const char *fname = "\\ioctl.dat";
3666 union smb_ioctl parms;
3667 TALLOC_CTX *mem_ctx;
3669 if (!torture_open_connection(&cli)) {
3673 mem_ctx = talloc_init("ioctl_test");
3675 printf("starting ioctl test\n");
3677 smbcli_unlink(cli->tree, fname);
3679 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3681 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
3685 parms.ioctl.level = RAW_IOCTL_IOCTL;
3686 parms.ioctl.in.fnum = fnum;
3687 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3688 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3689 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
3691 for (device=0;device<0x100;device++) {
3692 printf("testing device=0x%x\n", device);
3693 for (function=0;function<0x100;function++) {
3694 parms.ioctl.in.request = (device << 16) | function;
3695 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3697 if (NT_STATUS_IS_OK(status)) {
3698 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3699 device, function, parms.ioctl.out.blob.length);
3704 if (!torture_close_connection(cli)) {
3713 tries variants of chkpath
3715 BOOL torture_chkpath_test(int dummy)
3717 struct smbcli_state *cli;
3721 if (!torture_open_connection(&cli)) {
3725 printf("starting chkpath test\n");
3727 printf("Testing valid and invalid paths\n");
3729 /* cleanup from an old run */
3730 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3731 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3732 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3734 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
3735 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
3739 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3740 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
3744 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3746 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
3749 smbcli_close(cli->tree, fnum);
3751 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
3752 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
3756 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3757 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
3761 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3762 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3763 NT_STATUS_NOT_A_DIRECTORY);
3765 printf("* chkpath on a file should fail\n");
3769 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3770 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3771 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3773 printf("* chkpath on a non existent file should fail\n");
3777 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3778 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3779 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3781 printf("* chkpath on a non existent component should fail\n");
3785 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3786 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3787 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3789 if (!torture_close_connection(cli)) {
3796 static BOOL run_dirtest1(int dummy)
3799 struct smbcli_state *cli;
3801 BOOL correct = True;
3803 printf("starting directory test\n");
3805 if (!torture_open_connection(&cli)) {
3809 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3810 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3813 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\LISTDIR"))) {
3814 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3818 printf("Creating %d files\n", torture_entries);
3820 /* Create torture_entries files and torture_entries directories. */
3821 for (i=0;i<torture_entries;i++) {
3823 asprintf(&fname, "\\LISTDIR\\f%d", i);
3824 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3825 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3827 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3831 smbcli_close(cli->tree, fnum);
3833 for (i=0;i<torture_entries;i++) {
3835 asprintf(&fname, "\\LISTDIR\\d%d", i);
3836 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
3837 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3843 /* Now ensure that doing an old list sees both files and directories. */
3844 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3845 printf("num_seen = %d\n", num_seen );
3846 /* We should see (torture_entries) each of files & directories + . and .. */
3847 if (num_seen != (2*torture_entries)+2) {
3849 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3850 (2*torture_entries)+2, num_seen);
3854 /* Ensure if we have the "must have" bits we only see the
3857 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3858 printf("num_seen = %d\n", num_seen );
3859 if (num_seen != torture_entries+2) {
3861 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3862 torture_entries+2, num_seen);
3865 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3866 printf("num_seen = %d\n", num_seen );
3867 if (num_seen != torture_entries) {
3869 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3870 torture_entries, num_seen);
3873 /* Delete everything. */
3874 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3875 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3880 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3881 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3882 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3885 if (!torture_close_connection(cli)) {
3889 printf("finished dirtest1\n");
3896 simple test harness for playing with deny modes
3898 static BOOL run_deny3test(int dummy)
3900 struct smbcli_state *cli1, *cli2;
3904 printf("starting deny3 test\n");
3906 printf("Testing simple deny modes\n");
3908 if (!torture_open_connection(&cli1)) {
3911 if (!torture_open_connection(&cli2)) {
3915 fname = "\\deny_dos1.dat";
3917 smbcli_unlink(cli1->tree, fname);
3918 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3919 fnum2 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3920 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3921 if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
3922 smbcli_unlink(cli1->tree, fname);
3923 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3926 fname = "\\deny_dos2.dat";
3928 smbcli_unlink(cli1->tree, fname);
3929 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3930 fnum2 = smbcli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3931 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3932 if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
3933 smbcli_unlink(cli1->tree, fname);
3934 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3937 torture_close_connection(cli1);
3938 torture_close_connection(cli2);
3944 parse a //server/share type UNC name
3946 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3950 if (strncmp(unc_name, "//", 2)) {
3954 *hostname = strdup(&unc_name[2]);
3955 p = strchr_m(&(*hostname)[2],'/');
3960 *sharename = strdup(p+1);
3967 static void sigcont(void)
3971 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
3974 volatile pid_t *child_status;
3975 volatile BOOL *child_status_out;
3978 double start_time_limit = 10 + (torture_nprocs * 1.5);
3979 char **unc_list = NULL;
3981 int num_unc_names = 0;
3985 signal(SIGCONT, sigcont);
3987 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3988 if (!child_status) {
3989 printf("Failed to setup shared memory\n");
3993 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
3994 if (!child_status_out) {
3995 printf("Failed to setup result status shared memory\n");
3999 p = lp_parm_string(-1, "torture", "unclist");
4001 unc_list = file_lines_load(p, &num_unc_names);
4002 if (!unc_list || num_unc_names <= 0) {
4003 printf("Failed to load unc names list from %s\n", p);
4008 for (i = 0; i < torture_nprocs; i++) {
4009 child_status[i] = 0;
4010 child_status_out[i] = True;
4015 for (i=0;i<torture_nprocs;i++) {
4019 char *hostname=NULL, *sharename;
4021 pid_t mypid = getpid();
4022 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4024 asprintf(&myname, "CLIENT%d", i);
4025 lp_set_cmdline("netbios name", myname);
4030 if (!parse_unc(unc_list[i % num_unc_names],
4031 &hostname, &sharename)) {
4032 printf("Failed to parse UNC name %s\n",
4033 unc_list[i % num_unc_names]);
4040 if (torture_open_connection_share(¤t_cli,
4045 } else if (torture_open_connection(¤t_cli)) {
4049 printf("pid %d failed to start\n", (int)getpid());
4055 child_status[i] = getpid();
4059 if (child_status[i]) {
4060 printf("Child %d failed to start!\n", i);
4061 child_status_out[i] = 1;
4065 child_status_out[i] = fn(current_cli, i);
4072 for (i=0;i<torture_nprocs;i++) {
4073 if (child_status[i]) synccount++;
4075 if (synccount == torture_nprocs) break;
4077 } while (end_timer() < start_time_limit);
4079 if (synccount != torture_nprocs) {
4080 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4085 printf("Starting %d clients\n", torture_nprocs);
4087 /* start the client load */
4089 for (i=0;i<torture_nprocs;i++) {
4090 child_status[i] = 0;
4094 printf("%d clients started\n", torture_nprocs);
4096 for (i=0;i<torture_nprocs;i++) {
4098 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4099 if (ret == -1 || WEXITSTATUS(status) != 0) {
4106 for (i=0;i<torture_nprocs;i++) {
4107 if (!child_status_out[i]) {
4114 #define FLAG_MULTIPROC 1
4122 {"BASE-FDPASS", run_fdpasstest, 0},
4123 {"BASE-LOCK1", run_locktest1, 0},
4124 {"BASE-LOCK2", run_locktest2, 0},
4125 {"BASE-LOCK3", run_locktest3, 0},
4126 {"BASE-LOCK4", run_locktest4, 0},
4127 {"BASE-LOCK5", run_locktest5, 0},
4128 {"BASE-LOCK6", run_locktest6, 0},
4129 {"BASE-LOCK7", run_locktest7, 0},
4130 {"BASE-UNLINK", run_unlinktest, 0},
4131 {"BASE-ATTR", run_attrtest, 0},
4132 {"BASE-TRANS2", run_trans2test, 0},
4133 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4134 {"BASE-DIR", run_dirtest, 0},
4135 {"BASE-DIR1", run_dirtest1, 0},
4136 {"BASE-DENY1", torture_denytest1, 0},
4137 {"BASE-DENY2", torture_denytest2, 0},
4138 {"BASE-TCON", run_tcon_test, 0},
4139 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4140 {"BASE-VUID", run_vuidtest, 0},
4141 {"BASE-RW1", run_readwritetest, 0},
4142 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4143 {"BASE-OPEN", run_opentest, 0},
4144 {"BASE-DENY3", run_deny3test, 0},
4145 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4146 {"BASE-XCOPY", run_xcopy, 0},
4147 {"BASE-RENAME", run_rename, 0},
4148 {"BASE-DELETE", run_deletetest, 0},
4149 {"BASE-PROPERTIES", run_properties, 0},
4150 {"BASE-MANGLE", torture_mangle, 0},
4151 {"BASE-OPENATTR", run_openattrtest, 0},
4152 {"BASE-CHARSET", torture_charset, 0},
4153 {"BASE-CHKPATH", torture_chkpath_test, 0},
4155 /* benchmarking tests */
4156 {"BENCH-HOLDCON", torture_holdcon, 0},
4157 {"BENCH-NBENCH", torture_nbench, 0},
4158 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4161 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4162 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4163 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4164 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4165 {"RAW-SEARCH", torture_raw_search, 0},
4166 {"RAW-CLOSE", torture_raw_close, 0},
4167 {"RAW-OPEN", torture_raw_open, 0},
4168 {"RAW-MKDIR", torture_raw_mkdir, 0},
4169 {"RAW-OPLOCK", torture_raw_oplock, 0},
4170 {"RAW-NOTIFY", torture_raw_notify, 0},
4171 {"RAW-MUX", torture_raw_mux, 0},
4172 {"RAW-IOCTL", torture_raw_ioctl, 0},
4173 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4174 {"RAW-UNLINK", torture_raw_unlink, 0},
4175 {"RAW-READ", torture_raw_read, 0},
4176 {"RAW-WRITE", torture_raw_write, 0},
4177 {"RAW-LOCK", torture_raw_lock, 0},
4178 {"RAW-CONTEXT", torture_raw_context, 0},
4179 {"RAW-RENAME", torture_raw_rename, 0},
4180 {"RAW-SEEK", torture_raw_seek, 0},
4181 {"RAW-RAP", torture_raw_rap, 0},
4183 /* protocol scanners */
4184 {"SCAN-TRANS2", torture_trans2_scan, 0},
4185 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4186 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4187 {"SCAN-SMB", torture_smb_scan, 0},
4188 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4189 {"SCAN-UTABLE", torture_utable, 0},
4190 {"SCAN-CASETABLE", torture_casetable, 0},
4191 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4192 {"SCAN-IOCTL", torture_ioctl_test, 0},
4195 {"RPC-LSA", torture_rpc_lsa, 0},
4196 {"RPC-ECHO", torture_rpc_echo, 0},
4197 {"RPC-DFS", torture_rpc_dfs, 0},
4198 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4199 {"RPC-SAMR", torture_rpc_samr, 0},
4200 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4201 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4202 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4203 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4204 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4205 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4206 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4207 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4208 {"RPC-WINREG", torture_rpc_winreg, 0},
4209 {"RPC-MGMT", torture_rpc_mgmt, 0},
4210 {"RPC-SCANNER", torture_rpc_scanner, 0},
4211 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4212 {"RPC-MULTIBIND", torture_multi_bind, 0},
4213 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4215 /* local (no server) testers */
4216 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
4217 {"LOCAL-ICONV", torture_local_iconv, 0},
4220 {"LDAP-BASIC", torture_ldap_basic, 0},
4226 /****************************************************************************
4227 run a specified test or "ALL"
4228 ****************************************************************************/
4229 static BOOL run_test(const char *name)
4233 BOOL matched = False;
4235 if (strequal(name,"ALL")) {
4236 for (i=0;torture_ops[i].name;i++) {
4237 if (!run_test(torture_ops[i].name)) {
4244 for (i=0;torture_ops[i].name;i++) {
4245 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4248 printf("Running %s\n", torture_ops[i].name);
4249 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4251 t = torture_create_procs(torture_ops[i].fn, &result);
4254 printf("TEST %s FAILED!\n", torture_ops[i].name);
4259 if (!torture_ops[i].fn(0)) {
4261 printf("TEST %s FAILED!\n", torture_ops[i].name);
4265 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4270 printf("Unknown torture operation '%s'\n", name);
4277 static void parse_dns(const char *dns)
4279 char *userdn, *basedn, *secret;
4282 /* retrievieng the userdn */
4283 p = strchr_m(dns, '#');
4285 lp_set_cmdline("torture:ldap_userdn", "");
4286 lp_set_cmdline("torture:ldap_basedn", "");
4287 lp_set_cmdline("torture:ldap_secret", "");
4290 userdn = strndup(dns, p - dns);
4291 lp_set_cmdline("torture:ldap_userdn", userdn);
4293 /* retrieve the basedn */
4295 p = strchr_m(d, '#');
4297 lp_set_cmdline("torture:ldap_basedn", "");
4298 lp_set_cmdline("torture:ldap_secret", "");
4301 basedn = strndup(d, p - d);
4302 lp_set_cmdline("torture:ldap_basedn", basedn);
4304 /* retrieve the secret */
4307 lp_set_cmdline("torture:ldap_secret", "");
4311 lp_set_cmdline("torture:ldap_secret", secret);
4313 printf ("%s - %s - %s\n", userdn, basedn, secret);
4317 static void usage(poptContext pc)
4322 poptPrintUsage(pc, stdout, 0);
4325 printf("tests are:");
4326 for (i=0;torture_ops[i].name;i++) {
4327 if ((i%perline)==0) {
4330 printf("%s ", torture_ops[i].name);
4334 printf("default test is ALL\n");
4339 /****************************************************************************
4341 ****************************************************************************/
4342 int main(int argc,char *argv[])
4346 BOOL correct = True;
4350 struct poptOption long_options[] = {
4352 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
4353 {"seed", 's', POPT_ARG_STRING, NULL, 0, "seed", NULL},
4354 {"num-progs", 'N', POPT_ARG_INT, &torture_nprocs, 4, "num progs", NULL},
4355 {"num-ops", 'o', POPT_ARG_INT, &torture_numops, 100, "num ops", NULL},
4356 {"entries", 'e', POPT_ARG_INT, &torture_entries, 1000, "entries", NULL},
4357 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, True, "use oplocks", NULL},
4358 {"show-all", 'A', POPT_ARG_NONE, &torture_showall, True, "show all", NULL},
4359 {"loadfile", 'c', POPT_ARG_STRING, NULL, 0, "loadfile", NULL},
4360 {"unclist", 'C', POPT_ARG_STRING, NULL, 0, "unclist", NULL},
4361 {"timelimit", 't', POPT_ARG_STRING, NULL, 0, "timelimit", NULL},
4362 {"failures", 'f', POPT_ARG_INT, &torture_failures, 1, "failures", NULL},
4363 {"parse-dns", 'D', POPT_ARG_STRING, NULL, 0, "parse-dns", NULL},
4364 {"dangerous", 'X', POPT_ARG_NONE, NULL, 0, "dangerous", NULL},
4366 POPT_COMMON_CONNECTION
4367 POPT_COMMON_CREDENTIALS
4372 setup_logging("smbtorture", DEBUG_STDOUT);
4374 #ifdef HAVE_SETBUFFER
4375 setbuffer(stdout, NULL, 0);
4378 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
4379 POPT_CONTEXT_KEEP_FIRST);
4381 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
4383 while((opt = poptGetNextOpt(pc)) != -1) {
4386 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
4389 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
4392 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
4395 parse_dns(poptGetOptArg(pc));
4399 lp_set_cmdline("torture:dangerous", "1");
4403 d_printf("Invalid option %s: %s\n",
4404 poptBadOption(pc, 0), poptStrerror(opt));
4410 lp_load(dyn_CONFIGFILE,True,False,False);
4412 srandom(time(NULL));
4414 argv_new = (const char **)poptGetArgs(pc);
4417 for (i=0; i<argc; i++) {
4418 if (argv_new[i] == NULL) {
4429 for(p = argv_new[1]; *p; p++) {
4434 /* see if its a RPC transport specifier */
4435 if (strncmp(argv_new[1], "ncacn_", 6) == 0) {
4436 lp_set_cmdline("torture:binding", argv_new[1]);
4438 char *binding = NULL;
4439 char *host = NULL, *share = NULL;
4441 if (!parse_unc(argv_new[1], &host, &share)) {
4445 lp_set_cmdline("torture:host", host);
4446 lp_set_cmdline("torture:share", share);
4447 asprintf(&binding, "ncacn_np:%s", host);
4448 lp_set_cmdline("torture:binding", binding);
4451 if (!lp_parm_string(-1,"torture","username")) {
4452 lp_set_cmdline("torture:username", cmdline_get_username());
4454 if (!lp_parm_string(-1,"torture","userdomain")) {
4456 * backward compatibility
4457 * maybe we should remove this to make this consistent
4458 * for all cmdline tools
4461 if (strequal(lp_netbios_name(),cmdline_get_userdomain())) {
4462 cmdline_set_userdomain(lp_workgroup());
4464 lp_set_cmdline("torture:userdomain", cmdline_get_userdomain());
4466 if (!lp_parm_string(-1,"torture","password")) {
4467 lp_set_cmdline("torture:password", cmdline_get_userpassword());
4470 if (argc_new == 0) {
4471 printf("You must specify a test to run, or 'ALL'\n");
4473 for (i=2;i<argc_new;i++) {
4474 if (!run_test(argv_new[i])) {