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;
41 struct smbcli_state *cli;
42 const char *host = lp_parm_string(-1, "torture", "host");
44 make_nmb_name(&calling, lp_netbios_name(), 0x0);
45 make_nmb_name(&called , host, 0x20);
49 cli = smbcli_state_init();
51 printf("Failed initialize smbcli_struct to connect with %s\n", host);
55 if (!smbcli_socket_connect(cli, host, &ip)) {
56 printf("Failed to connect with %s\n", host);
60 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
62 if (!smbcli_transport_establish(cli, &calling, &called)) {
64 * Well, that failed, try *SMBSERVER ...
65 * However, we must reconnect as well ...
67 if (!smbcli_socket_connect(cli, host, &ip)) {
68 printf("Failed to connect with %s\n", host);
72 make_nmb_name(&called, "*SMBSERVER", 0x20);
73 if (!smbcli_transport_establish(cli, &calling, &called)) {
74 printf("%s rejected the session\n",host);
75 printf("We tried with a called name of %s & %s\n",
85 BOOL torture_open_connection_share(struct smbcli_state **c,
87 const char *sharename)
92 const char *username = lp_parm_string(-1, "torture", "username");
93 const char *password = lp_parm_string(-1, "torture", "password");
96 flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS;
98 status = smbcli_full_connection(c, lp_netbios_name(),
101 username, username[0]?lp_workgroup():"",
102 password, flags, &retry);
103 if (!NT_STATUS_IS_OK(status)) {
104 printf("Failed to open connection - %s\n", nt_errstr(status));
108 (*c)->transport->options.use_oplocks = use_oplocks;
109 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
110 (*c)->transport->socket->timeout = 120000;
115 BOOL torture_open_connection(struct smbcli_state **c)
117 const char *host = lp_parm_string(-1, "torture", "host");
118 const char *share = lp_parm_string(-1, "torture", "share");
120 return torture_open_connection_share(c, host, share);
125 BOOL torture_close_connection(struct smbcli_state *c)
128 DEBUG(9,("torture_close_connection: smbcli_state@%p\n", c));
130 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
131 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
134 DEBUG(9,("torture_close_connection: call smbcli_shutdown\n"));
136 DEBUG(9,("torture_close_connection: exit\n"));
141 /* open a rpc connection to a named pipe */
142 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
143 const char *pipe_name,
144 const char *pipe_uuid,
145 uint32_t pipe_version)
148 const char *binding = lp_parm_string(-1, "torture", "binding");
151 printf("You must specify a ncacn binding string\n");
152 return NT_STATUS_INVALID_PARAMETER;
155 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
157 lp_parm_string(-1, "torture", "username"),
158 lp_parm_string(-1, "torture", "password"));
163 /* close a rpc connection to a named pipe */
164 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
166 dcerpc_pipe_close(p);
171 /* check if the server produced the expected error code */
172 static BOOL check_error(int line, struct smbcli_state *c,
173 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
175 if (smbcli_is_dos_error(c->tree)) {
179 /* Check DOS error */
181 smbcli_dos_error(c, &class, &num);
183 if (eclass != class || ecode != num) {
184 printf("unexpected error code class=%d code=%d\n",
185 (int)class, (int)num);
186 printf(" expected %d/%d %s (line=%d)\n",
187 (int)eclass, (int)ecode, nt_errstr(nterr), line);
196 status = smbcli_nt_error(c->tree);
198 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
199 printf("unexpected error code %s\n", nt_errstr(status));
200 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
209 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
211 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
212 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
218 static BOOL rw_torture(struct smbcli_state *c)
220 const char *lockfname = "\\torture.lck";
224 pid_t pid2, pid = getpid();
229 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
232 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
234 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
239 for (i=0;i<torture_numops;i++) {
240 uint_t n = (uint_t)sys_random()%10;
242 printf("%d\r", i); fflush(stdout);
244 asprintf(&fname, "\\torture.%u", n);
246 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
250 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
252 printf("open failed (%s)\n", smbcli_errstr(c->tree));
257 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
258 printf("write failed (%s)\n", smbcli_errstr(c->tree));
263 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
264 sizeof(pid)+(j*sizeof(buf)),
265 sizeof(buf)) != sizeof(buf)) {
266 printf("write failed (%s)\n", smbcli_errstr(c->tree));
273 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
274 printf("read failed (%s)\n", smbcli_errstr(c->tree));
279 printf("data corruption!\n");
283 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
284 printf("close failed (%s)\n", smbcli_errstr(c->tree));
288 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
289 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
294 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
300 smbcli_close(c->tree, fnum2);
301 smbcli_unlink(c->tree, lockfname);
308 static BOOL run_torture(struct smbcli_state *cli, int dummy)
312 ret = rw_torture(cli);
314 if (!torture_close_connection(cli)) {
321 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
328 uint_t countprev = 0;
333 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
335 SIVAL(buf, i, sys_random());
340 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
343 printf("first open read/write of %s failed (%s)\n",
344 lockfname, smbcli_errstr(c->tree));
350 for (i = 0; i < 500 && fnum == -1; i++)
352 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
357 printf("second open read-only of %s failed (%s)\n",
358 lockfname, smbcli_errstr(c->tree));
364 for (count = 0; count < sizeof(buf); count += sent)
366 if (count >= countprev) {
367 printf("%d %8d\r", i, count);
370 countprev += (sizeof(buf) / 20);
375 sent = ((uint_t)sys_random()%(20))+ 1;
376 if (sent > sizeof(buf) - count)
378 sent = sizeof(buf) - count;
381 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
382 printf("write failed (%s)\n", smbcli_errstr(c->tree));
388 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
392 printf("read failed offset:%d size:%d (%s)\n",
393 count, sizeof(buf)-count,
394 smbcli_errstr(c->tree));
400 if (memcmp(buf_rd+count, buf+count, sent) != 0)
402 printf("read/write compare failed\n");
403 printf("offset: %d req %d recvd %d\n",
404 count, sizeof(buf)-count, sent);
413 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
414 printf("close failed (%s)\n", smbcli_errstr(c->tree));
421 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
423 const char *lockfname = "\\torture2.lck";
428 uint8_t buf_rd[131072];
430 ssize_t bytes_read, bytes_written;
432 if (smbcli_deltree(c1->tree, lockfname) == -1) {
433 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
436 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
439 printf("first open read/write of %s failed (%s)\n",
440 lockfname, smbcli_errstr(c1->tree));
443 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
446 printf("second open read-only of %s failed (%s)\n",
447 lockfname, smbcli_errstr(c2->tree));
448 smbcli_close(c1->tree, fnum1);
452 printf("Checking data integrity over %d ops\n", torture_numops);
454 for (i=0;i<torture_numops;i++)
456 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
458 printf("%d\r", i); fflush(stdout);
461 generate_random_buffer(buf, buf_size);
463 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
464 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
465 printf("wrote %d, expected %d\n", bytes_written, buf_size);
470 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
471 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
472 printf("read %d, expected %d\n", bytes_read, buf_size);
477 if (memcmp(buf_rd, buf, buf_size) != 0)
479 printf("read/write compare failed\n");
485 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
486 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
489 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
490 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
494 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
495 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
502 static BOOL run_readwritetest(int dummy)
504 struct smbcli_state *cli1, *cli2;
505 BOOL test1, test2 = True;
507 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
511 printf("starting readwritetest\n");
513 test1 = rw_torture2(cli1, cli2);
514 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
517 test2 = rw_torture2(cli1, cli1);
518 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
521 if (!torture_close_connection(cli1)) {
525 if (!torture_close_connection(cli2)) {
529 return (test1 && test2);
532 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
536 test = rw_torture3(cli, "\\multitest.txt");
538 if (!torture_close_connection(cli)) {
547 This test checks for two things:
549 1) correct support for retaining locks over a close (ie. the server
550 must not use posix semantics)
551 2) support for lock timeouts
553 static BOOL run_locktest1(int dummy)
555 struct smbcli_state *cli1, *cli2;
556 const char *fname = "\\lockt1.lck";
557 int fnum1, fnum2, fnum3;
561 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
565 printf("starting locktest1\n");
567 smbcli_unlink(cli1->tree, fname);
569 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
571 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
574 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
576 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
579 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
581 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
585 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
586 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
591 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
592 printf("lock2 succeeded! This is a locking bug\n");
595 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
596 NT_STATUS_LOCK_NOT_GRANTED)) return False;
600 lock_timeout = (6 + (random() % 20));
601 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
603 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
604 printf("lock3 succeeded! This is a locking bug\n");
607 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
608 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
613 printf("error: This server appears not to support timed lock requests\n");
615 printf("server slept for %u seconds for a %u second timeout\n",
616 (uint_t)(t2-t1), lock_timeout);
618 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
619 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
623 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
624 printf("lock4 succeeded! This is a locking bug\n");
627 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
628 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
631 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
632 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
636 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
637 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
641 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
642 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
647 if (!torture_close_connection(cli1)) {
651 if (!torture_close_connection(cli2)) {
655 printf("Passed locktest1\n");
660 this checks to see if a secondary tconx can use open files from an
663 static BOOL run_tcon_test(int dummy)
665 struct smbcli_state *cli;
666 const char *fname = "\\tcontest.tmp";
668 uint16_t cnum1, cnum2, cnum3;
669 uint16_t vuid1, vuid2;
672 struct smbcli_tree *tree1;
673 const char *host = lp_parm_string(-1, "torture", "host");
674 const char *share = lp_parm_string(-1, "torture", "share");
675 const char *password = lp_parm_string(-1, "torture", "password");
677 if (!torture_open_connection(&cli)) {
681 printf("starting tcontest\n");
683 if (smbcli_deltree(cli->tree, fname) == -1) {
684 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
687 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
689 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
693 cnum1 = cli->tree->tid;
694 vuid1 = cli->session->vuid;
696 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
697 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
698 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
702 tree1 = cli->tree; /* save old tree connection */
703 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
704 printf("%s refused 2nd tree connect (%s)\n", host,
705 smbcli_errstr(cli->tree));
706 smbcli_shutdown(cli);
710 cnum2 = cli->tree->tid;
711 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
712 vuid2 = cli->session->vuid + 1;
714 /* try a write with the wrong tid */
715 cli->tree->tid = cnum2;
717 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
718 printf("* server allows write with wrong TID\n");
721 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
725 /* try a write with an invalid tid */
726 cli->tree->tid = cnum3;
728 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
729 printf("* server allows write with invalid TID\n");
732 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
735 /* try a write with an invalid vuid */
736 cli->session->vuid = vuid2;
737 cli->tree->tid = cnum1;
739 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
740 printf("* server allows write with invalid VUID\n");
743 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
746 cli->session->vuid = vuid1;
747 cli->tree->tid = cnum1;
749 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
750 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
754 cli->tree->tid = cnum2;
756 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
757 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
761 cli->tree = tree1; /* restore initial tree */
762 cli->tree->tid = cnum1;
764 if (!torture_close_connection(cli)) {
773 static BOOL tcon_devtest(struct smbcli_state *cli,
774 const char *myshare, const char *devtype,
775 NTSTATUS expected_error)
779 const char *password = lp_parm_string(-1, "torture", "password");
781 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
784 printf("Trying share %s with devtype %s\n", myshare, devtype);
786 if (NT_STATUS_IS_OK(expected_error)) {
790 printf("tconX to share %s with type %s "
791 "should have succeeded but failed\n",
798 printf("tconx to share %s with type %s "
799 "should have failed but succeeded\n",
803 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
807 printf("Returned unexpected error\n");
816 checks for correct tconX support
818 static BOOL run_tcon_devtype_test(int dummy)
820 struct smbcli_state *cli1 = NULL;
825 const char *host = lp_parm_string(-1, "torture", "host");
826 const char *share = lp_parm_string(-1, "torture", "share");
827 const char *username = lp_parm_string(-1, "torture", "username");
828 const char *password = lp_parm_string(-1, "torture", "password");
830 status = smbcli_full_connection(&cli1, lp_netbios_name(),
833 username, lp_workgroup(),
834 password, flags, &retry);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("could not open connection\n");
841 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
844 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
847 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
850 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
853 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
856 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
859 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
862 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
865 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
868 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
871 smbcli_shutdown(cli1);
874 printf("Passed tcondevtest\n");
881 This test checks that
883 1) the server supports multiple locking contexts on the one SMB
884 connection, distinguished by PID.
886 2) the server correctly fails overlapping locks made by the same PID (this
887 goes against POSIX behaviour, which is why it is tricky to implement)
889 3) the server denies unlock requests by an incorrect client PID
891 static BOOL run_locktest2(int dummy)
893 struct smbcli_state *cli;
894 const char *fname = "\\lockt2.lck";
895 int fnum1, fnum2, fnum3;
898 if (!torture_open_connection(&cli)) {
902 printf("starting locktest2\n");
904 smbcli_unlink(cli->tree, fname);
906 printf("Testing pid context\n");
908 cli->session->pid = 1;
910 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
912 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
916 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
918 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
922 cli->session->pid = 2;
924 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
926 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
930 cli->session->pid = 1;
932 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
933 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
937 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
938 printf("WRITE lock1 succeeded! This is a locking bug\n");
941 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
942 NT_STATUS_LOCK_NOT_GRANTED)) return False;
945 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
946 printf("WRITE lock2 succeeded! This is a locking bug\n");
949 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
950 NT_STATUS_LOCK_NOT_GRANTED)) return False;
953 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
954 printf("READ lock2 succeeded! This is a locking bug\n");
957 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
958 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
961 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
962 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
965 cli->session->pid = 2;
967 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
968 printf("unlock at 100 succeeded! This is a locking bug\n");
972 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
973 printf("unlock1 succeeded! This is a locking bug\n");
976 if (!check_error(__LINE__, cli,
978 NT_STATUS_RANGE_NOT_LOCKED)) return False;
981 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
982 printf("unlock2 succeeded! This is a locking bug\n");
985 if (!check_error(__LINE__, cli,
987 NT_STATUS_RANGE_NOT_LOCKED)) return False;
990 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
991 printf("lock3 succeeded! This is a locking bug\n");
994 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
997 cli->session->pid = 1;
999 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
1000 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1004 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1005 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1009 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1010 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1014 if (!torture_close_connection(cli)) {
1018 printf("locktest2 finished\n");
1025 This test checks that
1027 1) the server supports the full offset range in lock requests
1029 static BOOL run_locktest3(int dummy)
1031 struct smbcli_state *cli1, *cli2;
1032 const char *fname = "\\lockt3.lck";
1033 int fnum1, fnum2, i;
1035 BOOL correct = True;
1037 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1039 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1043 printf("starting locktest3\n");
1045 printf("Testing 32 bit offset ranges\n");
1047 smbcli_unlink(cli1->tree, fname);
1049 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1051 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1054 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1056 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1060 printf("Establishing %d locks\n", torture_numops);
1062 for (offset=i=0;i<torture_numops;i++) {
1064 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1065 printf("lock1 %d failed (%s)\n",
1067 smbcli_errstr(cli1->tree));
1071 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1072 printf("lock2 %d failed (%s)\n",
1074 smbcli_errstr(cli1->tree));
1079 printf("Testing %d locks\n", torture_numops);
1081 for (offset=i=0;i<torture_numops;i++) {
1084 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1085 printf("error: lock1 %d succeeded!\n", i);
1089 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1090 printf("error: lock2 %d succeeded!\n", i);
1094 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1095 printf("error: lock3 %d succeeded!\n", i);
1099 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1100 printf("error: lock4 %d succeeded!\n", i);
1105 printf("Removing %d locks\n", torture_numops);
1107 for (offset=i=0;i<torture_numops;i++) {
1110 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1111 printf("unlock1 %d failed (%s)\n",
1113 smbcli_errstr(cli1->tree));
1117 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1118 printf("unlock2 %d failed (%s)\n",
1120 smbcli_errstr(cli1->tree));
1125 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1126 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1130 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1131 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1135 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1136 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1140 if (!torture_close_connection(cli1)) {
1144 if (!torture_close_connection(cli2)) {
1148 printf("finished locktest3\n");
1153 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1154 printf("** "); correct = False; \
1158 looks at overlapping locks
1160 static BOOL run_locktest4(int dummy)
1162 struct smbcli_state *cli1, *cli2;
1163 const char *fname = "\\lockt4.lck";
1164 int fnum1, fnum2, f;
1167 BOOL correct = True;
1169 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1173 printf("starting locktest4\n");
1175 smbcli_unlink(cli1->tree, fname);
1177 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1178 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1180 memset(buf, 0, sizeof(buf));
1182 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1183 printf("Failed to create file\n");
1188 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1189 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1190 EXPECTED(ret, False);
1191 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1193 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1194 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1195 EXPECTED(ret, True);
1196 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1198 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1199 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1200 EXPECTED(ret, False);
1201 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1203 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1204 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1205 EXPECTED(ret, True);
1206 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1208 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1209 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1210 EXPECTED(ret, False);
1211 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1213 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1214 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1215 EXPECTED(ret, True);
1216 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1218 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1219 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1220 EXPECTED(ret, True);
1221 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1223 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1224 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1225 EXPECTED(ret, False);
1226 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1228 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1229 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1230 EXPECTED(ret, False);
1231 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1233 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1234 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1235 EXPECTED(ret, True);
1236 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1238 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1239 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1240 EXPECTED(ret, False);
1241 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1243 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1244 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1245 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1246 EXPECTED(ret, False);
1247 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1250 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1251 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1252 EXPECTED(ret, False);
1253 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1255 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1256 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1257 EXPECTED(ret, False);
1258 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1261 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1262 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1263 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1264 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1265 EXPECTED(ret, True);
1266 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1269 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1270 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1271 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1272 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1273 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1274 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1275 EXPECTED(ret, True);
1276 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1278 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1279 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1280 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1281 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1282 EXPECTED(ret, True);
1283 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1285 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1286 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1287 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1288 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1289 EXPECTED(ret, True);
1290 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1292 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1293 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1294 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1295 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1296 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1297 EXPECTED(ret, True);
1298 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1300 smbcli_close(cli1->tree, fnum1);
1301 smbcli_close(cli2->tree, fnum2);
1302 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1303 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1304 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1305 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1306 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1307 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1308 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1309 smbcli_close(cli1->tree, f);
1310 smbcli_close(cli1->tree, fnum1);
1311 EXPECTED(ret, True);
1312 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1315 smbcli_close(cli1->tree, fnum1);
1316 smbcli_close(cli2->tree, fnum2);
1317 smbcli_unlink(cli1->tree, fname);
1318 torture_close_connection(cli1);
1319 torture_close_connection(cli2);
1321 printf("finished locktest4\n");
1326 looks at lock upgrade/downgrade.
1328 static BOOL run_locktest5(int dummy)
1330 struct smbcli_state *cli1, *cli2;
1331 const char *fname = "\\lockt5.lck";
1332 int fnum1, fnum2, fnum3;
1335 BOOL correct = True;
1337 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1341 printf("starting locktest5\n");
1343 smbcli_unlink(cli1->tree, fname);
1345 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1346 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1347 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1349 memset(buf, 0, sizeof(buf));
1351 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1352 printf("Failed to create file\n");
1357 /* Check for NT bug... */
1358 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1359 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1360 smbcli_close(cli1->tree, fnum1);
1361 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1362 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1363 EXPECTED(ret, True);
1364 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1365 smbcli_close(cli1->tree, fnum1);
1366 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1367 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1369 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1370 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1371 EXPECTED(ret, True);
1372 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1374 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1375 EXPECTED(ret, False);
1377 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1379 /* Unlock the process 2 lock. */
1380 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1382 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1383 EXPECTED(ret, False);
1385 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1387 /* Unlock the process 1 fnum3 lock. */
1388 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1390 /* Stack 2 more locks here. */
1391 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1392 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1394 EXPECTED(ret, True);
1395 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1397 /* Unlock the first process lock, then check this was the WRITE lock that was
1400 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1401 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1403 EXPECTED(ret, True);
1404 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1406 /* Unlock the process 2 lock. */
1407 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1409 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1411 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1412 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1413 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1415 EXPECTED(ret, True);
1416 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1418 /* Ensure the next unlock fails. */
1419 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1420 EXPECTED(ret, False);
1421 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1423 /* Ensure connection 2 can get a write lock. */
1424 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1425 EXPECTED(ret, True);
1427 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1431 smbcli_close(cli1->tree, fnum1);
1432 smbcli_close(cli2->tree, fnum2);
1433 smbcli_unlink(cli1->tree, fname);
1434 if (!torture_close_connection(cli1)) {
1437 if (!torture_close_connection(cli2)) {
1441 printf("finished locktest5\n");
1447 tries the unusual lockingX locktype bits
1449 static BOOL run_locktest6(int dummy)
1451 struct smbcli_state *cli;
1452 const char *fname[1] = { "\\lock6.txt" };
1457 if (!torture_open_connection(&cli)) {
1461 printf("starting locktest6\n");
1464 printf("Testing %s\n", fname[i]);
1466 smbcli_unlink(cli->tree, fname[i]);
1468 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1469 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1470 smbcli_close(cli->tree, fnum);
1471 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1473 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1474 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1475 smbcli_close(cli->tree, fnum);
1476 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1478 smbcli_unlink(cli->tree, fname[i]);
1481 torture_close_connection(cli);
1483 printf("finished locktest6\n");
1487 static BOOL run_locktest7(int dummy)
1489 struct smbcli_state *cli1;
1490 const char *fname = "\\lockt7.lck";
1495 BOOL correct = False;
1497 if (!torture_open_connection(&cli1)) {
1501 printf("starting locktest7\n");
1503 smbcli_unlink(cli1->tree, fname);
1505 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1507 memset(buf, 0, sizeof(buf));
1509 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1510 printf("Failed to create file\n");
1514 cli1->session->pid = 1;
1516 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1517 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1520 printf("pid1 successfully locked range 130:4 for READ\n");
1523 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1524 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1527 printf("pid1 successfully read the range 130:4\n");
1530 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1531 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1532 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1533 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1537 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1541 cli1->session->pid = 2;
1543 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1544 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1546 printf("pid2 successfully read the range 130:4\n");
1549 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1550 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1551 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1552 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1556 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1560 cli1->session->pid = 1;
1561 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1563 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1564 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1567 printf("pid1 successfully locked range 130:4 for WRITE\n");
1570 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1571 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1574 printf("pid1 successfully read the range 130:4\n");
1577 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1578 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1581 printf("pid1 successfully wrote to the range 130:4\n");
1584 cli1->session->pid = 2;
1586 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1587 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1588 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1589 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1593 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1597 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1598 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1599 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1600 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1604 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1608 printf("Testing truncate of locked file.\n");
1610 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1613 printf("Unable to truncate locked file.\n");
1617 printf("Truncated locked file.\n");
1620 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1621 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1627 printf("Unable to truncate locked file. Size was %u\n", size);
1632 cli1->session->pid = 1;
1634 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1638 smbcli_close(cli1->tree, fnum1);
1639 smbcli_close(cli1->tree, fnum2);
1640 smbcli_unlink(cli1->tree, fname);
1641 torture_close_connection(cli1);
1643 printf("finished locktest7\n");
1648 test whether fnums and tids open on one VC are available on another (a major
1651 static BOOL run_fdpasstest(int dummy)
1653 struct smbcli_state *cli1, *cli2;
1654 const char *fname = "\\fdpass.tst";
1658 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1662 printf("starting fdpasstest\n");
1664 smbcli_unlink(cli1->tree, fname);
1666 printf("Opening a file on connection 1\n");
1668 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1670 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1674 printf("writing to file on connection 1\n");
1676 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1677 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1681 oldtid = cli2->tree->tid;
1682 cli2->session->vuid = cli1->session->vuid;
1683 cli2->tree->tid = cli1->tree->tid;
1684 cli2->session->pid = cli1->session->pid;
1686 printf("reading from file on connection 2\n");
1688 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1689 printf("read succeeded! nasty security hole [%s]\n",
1694 smbcli_close(cli1->tree, fnum1);
1695 smbcli_unlink(cli1->tree, fname);
1697 cli2->tree->tid = oldtid;
1699 torture_close_connection(cli1);
1700 torture_close_connection(cli2);
1702 printf("finished fdpasstest\n");
1708 This test checks that
1710 1) the server does not allow an unlink on a file that is open
1712 static BOOL run_unlinktest(int dummy)
1714 struct smbcli_state *cli;
1715 const char *fname = "\\unlink.tst";
1717 BOOL correct = True;
1719 if (!torture_open_connection(&cli)) {
1723 printf("starting unlink test\n");
1725 smbcli_unlink(cli->tree, fname);
1727 cli->session->pid = 1;
1729 printf("Opening a file\n");
1731 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1733 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1737 printf("Unlinking a open file\n");
1739 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1740 printf("error: server allowed unlink on an open file\n");
1743 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1744 NT_STATUS_SHARING_VIOLATION);
1747 smbcli_close(cli->tree, fnum);
1748 smbcli_unlink(cli->tree, fname);
1750 if (!torture_close_connection(cli)) {
1754 printf("unlink test finished\n");
1761 test the timing of deferred open requests
1763 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1765 const char *fname = "\\defer_open_test.dat";
1768 BOOL correct = True;
1771 printf("failed to connect\n");
1775 printf("Testing deferred open requests.\n");
1781 struct timeval tv_start, tv_end;
1782 GetTimeOfDay(&tv_start);
1783 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1784 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1785 NTCREATEX_DISP_OPEN_IF, 0, 0);
1789 GetTimeOfDay(&tv_end);
1790 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1791 /* Sharing violation errors need to be 1 second apart. */
1792 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1793 if (tdif < 500000 || tdif > 1500000) {
1794 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1795 tdif / (int64_t)1000000,
1796 tdif % (int64_t)1000000);
1799 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1802 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1806 printf("pid %u open %d\n", getpid(), i);
1810 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1811 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1817 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1818 /* All until the last unlink will fail with sharing violation. */
1819 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1820 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1825 printf("deferred test finished\n");
1826 if (!torture_close_connection(cli)) {
1833 test how many open files this server supports on the one socket
1835 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1837 const char *template = "\\maxfid.%d.%d";
1839 int fnums[0x11000], i;
1841 BOOL correct = True;
1844 printf("failed to connect\n");
1848 printf("Testing maximum number of open files\n");
1850 for (i=0; i<0x11000; i++) {
1851 asprintf(&fname, template, i,(int)getpid());
1852 if ((fnums[i] = smbcli_open(cli->tree, fname,
1853 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1855 printf("open of %s failed (%s)\n",
1856 fname, smbcli_errstr(cli->tree));
1857 printf("maximum fnum is %d\n", i);
1866 printf("cleaning up\n");
1868 asprintf(&fname, template, i,(int)getpid());
1869 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1870 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1872 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1873 printf("unlink of %s failed (%s)\n",
1874 fname, smbcli_errstr(cli->tree));
1882 printf("maxfid test finished\n");
1883 if (!torture_close_connection(cli)) {
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 /* crypto testers */
4216 {"CRYPT-NTLMSSP", torture_ntlmssp_self_check, 0},
4219 {"LDAP-BASIC", torture_ldap_basic, 0},
4225 /****************************************************************************
4226 run a specified test or "ALL"
4227 ****************************************************************************/
4228 static BOOL run_test(const char *name)
4232 BOOL matched = False;
4234 if (strequal(name,"ALL")) {
4235 for (i=0;torture_ops[i].name;i++) {
4236 if (!run_test(torture_ops[i].name)) {
4243 for (i=0;torture_ops[i].name;i++) {
4244 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4247 printf("Running %s\n", torture_ops[i].name);
4248 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4250 t = torture_create_procs(torture_ops[i].fn, &result);
4253 printf("TEST %s FAILED!\n", torture_ops[i].name);
4258 if (!torture_ops[i].fn(0)) {
4260 printf("TEST %s FAILED!\n", torture_ops[i].name);
4264 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4269 printf("Unknown torture operation '%s'\n", name);
4277 parse a username%password
4279 static void parse_user(const char *user)
4281 char *username, *password = NULL, *p;
4283 username = strdup(user);
4284 p = strchr_m(username,'%');
4287 password = strdup(p+1);
4290 lp_set_cmdline("torture:username", username);
4293 lp_set_cmdline("torture:password", password);
4296 if (!lp_parm_string(-1,"torture","password")) {
4297 password = getpass("password:");
4299 lp_set_cmdline("torture:password", password);
4303 static void usage(void)
4307 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4309 printf("\t-d debuglevel\n");
4310 printf("\t-U user%%pass\n");
4311 printf("\t-k use kerberos\n");
4312 printf("\t-N numprocs\n");
4313 printf("\t-n my_netbios_name\n");
4314 printf("\t-W workgroup\n");
4315 printf("\t-o num_operations\n");
4316 printf("\t-e num files(entries)\n");
4317 printf("\t-O socket_options\n");
4318 printf("\t-m maximum protocol\n");
4319 printf("\t-L use oplocks\n");
4320 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4321 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4322 printf("\t-C filename specifies file with list of UNCs for connections\n");
4323 printf("\t-A showall\n");
4324 printf("\t-p port\n");
4325 printf("\t-s seed\n");
4326 printf("\t-f max failures\n");
4327 printf("\t-X enable dangerous tests\n");
4330 printf("tests are:");
4331 for (i=0;torture_ops[i].name;i++) {
4332 printf(" %s", torture_ops[i].name);
4336 printf("default test is ALL\n");
4341 /****************************************************************************
4343 ****************************************************************************/
4344 int main(int argc,char *argv[])
4348 BOOL correct = True;
4349 char *host, *share, *username;
4351 setup_logging("smbtorture", DEBUG_STDOUT);
4353 #ifdef HAVE_SETBUFFER
4354 setbuffer(stdout, NULL, 0);
4357 lp_load(dyn_CONFIGFILE,True,False,False);
4364 for(p = argv[1]; *p; p++)
4369 /* see if its a RPC transport specifier */
4370 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4371 lp_set_cmdline("torture:binding", argv[1]);
4373 char *binding = NULL;
4375 if (!parse_unc(argv[1], &host, &share)) {
4379 lp_set_cmdline("torture:host", host);
4380 lp_set_cmdline("torture:share", share);
4381 asprintf(&binding, "ncacn_np:%s", host);
4382 lp_set_cmdline("torture:binding", binding);
4385 if (getenv("LOGNAME")) {
4386 username = strdup(getenv("LOGNAME"));
4388 lp_set_cmdline("torture:username", username);
4394 srandom(time(NULL));
4396 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4399 lp_set_cmdline("smb ports", optarg);
4402 lp_set_cmdline("workgroup", optarg);
4405 lp_set_cmdline("protocol", optarg);
4408 lp_set_cmdline("netbios name", optarg);
4411 lp_set_cmdline("debug level", optarg);
4412 setup_logging(NULL, DEBUG_STDOUT);
4415 lp_set_cmdline("socket options", optarg);
4418 srandom(atoi(optarg));
4421 torture_nprocs = atoi(optarg);
4424 torture_numops = atoi(optarg);
4427 torture_entries = atoi(optarg);
4433 torture_showall = True;
4436 lp_set_cmdline("torture:loadfile", optarg);
4439 lp_set_cmdline("torture:unclist", optarg);
4442 lp_set_cmdline("torture:timelimit", optarg);
4446 use_kerberos = True;
4448 d_printf("No kerberos support compiled in\n");
4456 torture_failures = atoi(optarg);
4460 lp_set_cmdline("torture:dangerous", "1");
4464 printf("Unknown option %c (%d)\n", (char)opt, opt);
4469 if (!lp_parm_string(-1,"torture","password")) {
4470 lp_set_cmdline("torture:password", "");
4473 if (argc == optind) {
4474 printf("You must specify a test to run, or 'ALL'\n");
4476 for (i=optind;i<argc;i++) {
4477 if (!run_test(argv[i])) {