2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 int torture_numops=100;
25 int torture_entries=1000;
26 int torture_failures=1;
27 static int procnum; /* records process count number when forking */
28 static struct smbcli_state *current_cli;
29 static BOOL use_oplocks;
30 static BOOL use_level_II_oplocks;
31 static BOOL use_kerberos;
33 BOOL torture_showall = False;
35 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
37 static struct smbcli_state *open_nbt_connection(void)
39 struct nmb_name called, calling;
40 struct smbcli_state *cli;
41 const char *host = lp_parm_string(-1, "torture", "host");
43 make_nmb_name(&calling, lp_netbios_name(), 0x0);
44 choose_called_name(&called, host, 0x20);
46 cli = smbcli_state_init();
48 printf("Failed initialize smbcli_struct to connect with %s\n", host);
52 if (!smbcli_socket_connect(cli, host)) {
53 printf("Failed to connect with %s\n", host);
57 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
59 if (!smbcli_transport_establish(cli, &calling, &called)) {
61 * Well, that failed, try *SMBSERVER ...
62 * However, we must reconnect as well ...
64 if (!smbcli_socket_connect(cli, host)) {
65 printf("Failed to connect with %s\n", host);
69 make_nmb_name(&called, "*SMBSERVER", 0x20);
70 if (!smbcli_transport_establish(cli, &calling, &called)) {
71 printf("%s rejected the session\n",host);
72 printf("We tried with a called name of %s & %s\n",
82 BOOL torture_open_connection_share(struct smbcli_state **c,
84 const char *sharename)
89 const char *username = lp_parm_string(-1, "torture", "username");
90 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
91 const char *password = lp_parm_string(-1, "torture", "password");
94 flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS;
96 status = smbcli_full_connection(c, lp_netbios_name(),
99 username, username[0]?userdomain:"",
100 password, flags, &retry);
101 if (!NT_STATUS_IS_OK(status)) {
102 printf("Failed to open connection - %s\n", nt_errstr(status));
106 (*c)->transport->options.use_oplocks = use_oplocks;
107 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
108 (*c)->transport->socket->timeout = 120000;
113 BOOL torture_open_connection(struct smbcli_state **c)
115 const char *host = lp_parm_string(-1, "torture", "host");
116 const char *share = lp_parm_string(-1, "torture", "share");
118 return torture_open_connection_share(c, host, share);
123 BOOL torture_close_connection(struct smbcli_state *c)
127 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
128 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
136 /* open a rpc connection to the chosen binding string */
137 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
138 const char *pipe_name,
139 const char *pipe_uuid,
140 uint32_t pipe_version)
143 const char *binding = lp_parm_string(-1, "torture", "binding");
146 printf("You must specify a ncacn binding string\n");
147 return NT_STATUS_INVALID_PARAMETER;
150 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
151 lp_parm_string(-1, "torture", "userdomain"),
152 lp_parm_string(-1, "torture", "username"),
153 lp_parm_string(-1, "torture", "password"));
158 /* open a rpc connection to a specific transport */
159 NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
160 const char *pipe_name,
161 const char *pipe_uuid,
162 uint32_t pipe_version,
163 enum dcerpc_transport_t transport)
166 const char *binding = lp_parm_string(-1, "torture", "binding");
167 struct dcerpc_binding b;
168 TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb");
171 printf("You must specify a ncacn binding string\n");
172 return NT_STATUS_INVALID_PARAMETER;
175 status = dcerpc_parse_binding(mem_ctx, binding, &b);
176 if (!NT_STATUS_IS_OK(status)) {
177 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
178 talloc_destroy(mem_ctx);
182 b.transport = transport;
184 status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version,
185 lp_parm_string(-1, "torture", "userdomain"),
186 lp_parm_string(-1, "torture", "username"),
187 lp_parm_string(-1, "torture", "password"));
192 /* close a rpc connection to a named pipe */
193 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
195 dcerpc_pipe_close(p);
200 /* check if the server produced the expected error code */
201 static BOOL check_error(int line, struct smbcli_state *c,
202 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
204 if (smbcli_is_dos_error(c->tree)) {
208 /* Check DOS error */
210 smbcli_dos_error(c, &class, &num);
212 if (eclass != class || ecode != num) {
213 printf("unexpected error code class=%d code=%d\n",
214 (int)class, (int)num);
215 printf(" expected %d/%d %s (line=%d)\n",
216 (int)eclass, (int)ecode, nt_errstr(nterr), line);
225 status = smbcli_nt_error(c->tree);
227 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
228 printf("unexpected error code %s\n", nt_errstr(status));
229 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
238 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
240 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
241 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
247 static BOOL rw_torture(struct smbcli_state *c)
249 const char *lockfname = "\\torture.lck";
253 pid_t pid2, pid = getpid();
258 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
261 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
263 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
268 for (i=0;i<torture_numops;i++) {
269 uint_t n = (uint_t)sys_random()%10;
271 printf("%d\r", i); fflush(stdout);
273 asprintf(&fname, "\\torture.%u", n);
275 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
279 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
281 printf("open failed (%s)\n", smbcli_errstr(c->tree));
286 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
287 printf("write failed (%s)\n", smbcli_errstr(c->tree));
292 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
293 sizeof(pid)+(j*sizeof(buf)),
294 sizeof(buf)) != sizeof(buf)) {
295 printf("write failed (%s)\n", smbcli_errstr(c->tree));
302 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
303 printf("read failed (%s)\n", smbcli_errstr(c->tree));
308 printf("data corruption!\n");
312 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
313 printf("close failed (%s)\n", smbcli_errstr(c->tree));
317 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
318 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
322 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
323 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
329 smbcli_close(c->tree, fnum2);
330 smbcli_unlink(c->tree, lockfname);
337 static BOOL run_torture(struct smbcli_state *cli, int dummy)
341 ret = rw_torture(cli);
343 if (!torture_close_connection(cli)) {
350 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
357 uint_t countprev = 0;
362 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
364 SIVAL(buf, i, sys_random());
369 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
372 printf("first open read/write of %s failed (%s)\n",
373 lockfname, smbcli_errstr(c->tree));
379 for (i = 0; i < 500 && fnum == -1; i++)
381 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
386 printf("second open read-only of %s failed (%s)\n",
387 lockfname, smbcli_errstr(c->tree));
393 for (count = 0; count < sizeof(buf); count += sent)
395 if (count >= countprev) {
396 printf("%d %8d\r", i, count);
399 countprev += (sizeof(buf) / 20);
404 sent = ((uint_t)sys_random()%(20))+ 1;
405 if (sent > sizeof(buf) - count)
407 sent = sizeof(buf) - count;
410 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
411 printf("write failed (%s)\n", smbcli_errstr(c->tree));
417 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
421 printf("read failed offset:%d size:%d (%s)\n",
422 count, sizeof(buf)-count,
423 smbcli_errstr(c->tree));
429 if (memcmp(buf_rd+count, buf+count, sent) != 0)
431 printf("read/write compare failed\n");
432 printf("offset: %d req %d recvd %d\n",
433 count, sizeof(buf)-count, sent);
442 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
443 printf("close failed (%s)\n", smbcli_errstr(c->tree));
450 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
452 const char *lockfname = "\\torture2.lck";
457 uint8_t buf_rd[131072];
459 ssize_t bytes_read, bytes_written;
461 if (smbcli_deltree(c1->tree, lockfname) == -1) {
462 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
465 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
468 printf("first open read/write of %s failed (%s)\n",
469 lockfname, smbcli_errstr(c1->tree));
472 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
475 printf("second open read-only of %s failed (%s)\n",
476 lockfname, smbcli_errstr(c2->tree));
477 smbcli_close(c1->tree, fnum1);
481 printf("Checking data integrity over %d ops\n", torture_numops);
483 for (i=0;i<torture_numops;i++)
485 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
487 printf("%d\r", i); fflush(stdout);
490 generate_random_buffer(buf, buf_size);
492 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
493 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
494 printf("wrote %d, expected %d\n", bytes_written, buf_size);
499 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
500 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
501 printf("read %d, expected %d\n", bytes_read, buf_size);
506 if (memcmp(buf_rd, buf, buf_size) != 0)
508 printf("read/write compare failed\n");
514 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
515 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
518 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
519 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
523 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
524 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
531 static BOOL run_readwritetest(int dummy)
533 struct smbcli_state *cli1, *cli2;
534 BOOL test1, test2 = True;
536 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
540 printf("starting readwritetest\n");
542 test1 = rw_torture2(cli1, cli2);
543 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
546 test2 = rw_torture2(cli1, cli1);
547 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
550 if (!torture_close_connection(cli1)) {
554 if (!torture_close_connection(cli2)) {
558 return (test1 && test2);
561 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
565 test = rw_torture3(cli, "\\multitest.txt");
567 if (!torture_close_connection(cli)) {
576 This test checks for two things:
578 1) correct support for retaining locks over a close (ie. the server
579 must not use posix semantics)
580 2) support for lock timeouts
582 static BOOL run_locktest1(int dummy)
584 struct smbcli_state *cli1, *cli2;
585 const char *fname = "\\lockt1.lck";
586 int fnum1, fnum2, fnum3;
590 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
594 printf("starting locktest1\n");
596 smbcli_unlink(cli1->tree, fname);
598 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
600 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
603 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
605 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
608 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
610 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
614 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
615 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
620 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
621 printf("lock2 succeeded! This is a locking bug\n");
624 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
625 NT_STATUS_LOCK_NOT_GRANTED)) return False;
629 lock_timeout = (6 + (random() % 20));
630 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
632 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
633 printf("lock3 succeeded! This is a locking bug\n");
636 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
637 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
642 printf("error: This server appears not to support timed lock requests\n");
644 printf("server slept for %u seconds for a %u second timeout\n",
645 (uint_t)(t2-t1), lock_timeout);
647 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
648 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
652 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
653 printf("lock4 succeeded! This is a locking bug\n");
656 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
657 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
660 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
661 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
665 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
666 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
670 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
671 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
676 if (!torture_close_connection(cli1)) {
680 if (!torture_close_connection(cli2)) {
684 printf("Passed locktest1\n");
689 this checks to see if a secondary tconx can use open files from an
692 static BOOL run_tcon_test(int dummy)
694 struct smbcli_state *cli;
695 const char *fname = "\\tcontest.tmp";
697 uint16_t cnum1, cnum2, cnum3;
698 uint16_t vuid1, vuid2;
701 struct smbcli_tree *tree1;
702 const char *host = lp_parm_string(-1, "torture", "host");
703 const char *share = lp_parm_string(-1, "torture", "share");
704 const char *password = lp_parm_string(-1, "torture", "password");
706 if (!torture_open_connection(&cli)) {
710 printf("starting tcontest\n");
712 if (smbcli_deltree(cli->tree, fname) == -1) {
713 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
716 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
718 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
722 cnum1 = cli->tree->tid;
723 vuid1 = cli->session->vuid;
725 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
726 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
727 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
731 tree1 = cli->tree; /* save old tree connection */
732 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
733 printf("%s refused 2nd tree connect (%s)\n", host,
734 smbcli_errstr(cli->tree));
735 smbcli_shutdown(cli);
739 cnum2 = cli->tree->tid;
740 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
741 vuid2 = cli->session->vuid + 1;
743 /* try a write with the wrong tid */
744 cli->tree->tid = cnum2;
746 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
747 printf("* server allows write with wrong TID\n");
750 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
754 /* try a write with an invalid tid */
755 cli->tree->tid = cnum3;
757 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
758 printf("* server allows write with invalid TID\n");
761 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
764 /* try a write with an invalid vuid */
765 cli->session->vuid = vuid2;
766 cli->tree->tid = cnum1;
768 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
769 printf("* server allows write with invalid VUID\n");
772 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
775 cli->session->vuid = vuid1;
776 cli->tree->tid = cnum1;
778 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
779 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
783 cli->tree->tid = cnum2;
785 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
786 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
790 cli->tree = tree1; /* restore initial tree */
791 cli->tree->tid = cnum1;
793 if (!torture_close_connection(cli)) {
802 static BOOL tcon_devtest(struct smbcli_state *cli,
803 const char *myshare, const char *devtype,
804 NTSTATUS expected_error)
808 const char *password = lp_parm_string(-1, "torture", "password");
810 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
813 printf("Trying share %s with devtype %s\n", myshare, devtype);
815 if (NT_STATUS_IS_OK(expected_error)) {
819 printf("tconX to share %s with type %s "
820 "should have succeeded but failed\n",
827 printf("tconx to share %s with type %s "
828 "should have failed but succeeded\n",
832 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
836 printf("Returned unexpected error\n");
845 checks for correct tconX support
847 static BOOL run_tcon_devtype_test(int dummy)
849 struct smbcli_state *cli1 = NULL;
854 const char *host = lp_parm_string(-1, "torture", "host");
855 const char *share = lp_parm_string(-1, "torture", "share");
856 const char *username = lp_parm_string(-1, "torture", "username");
857 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
858 const char *password = lp_parm_string(-1, "torture", "password");
860 status = smbcli_full_connection(&cli1, lp_netbios_name(),
863 username, userdomain,
864 password, flags, &retry);
866 if (!NT_STATUS_IS_OK(status)) {
867 printf("could not open connection\n");
871 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
874 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
877 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
880 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
883 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
886 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
889 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
892 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
895 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
898 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
901 smbcli_shutdown(cli1);
904 printf("Passed tcondevtest\n");
911 This test checks that
913 1) the server supports multiple locking contexts on the one SMB
914 connection, distinguished by PID.
916 2) the server correctly fails overlapping locks made by the same PID (this
917 goes against POSIX behaviour, which is why it is tricky to implement)
919 3) the server denies unlock requests by an incorrect client PID
921 static BOOL run_locktest2(int dummy)
923 struct smbcli_state *cli;
924 const char *fname = "\\lockt2.lck";
925 int fnum1, fnum2, fnum3;
928 if (!torture_open_connection(&cli)) {
932 printf("starting locktest2\n");
934 smbcli_unlink(cli->tree, fname);
936 printf("Testing pid context\n");
938 cli->session->pid = 1;
940 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
942 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
946 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
948 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
952 cli->session->pid = 2;
954 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
956 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
960 cli->session->pid = 1;
962 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
963 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
967 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
968 printf("WRITE lock1 succeeded! This is a locking bug\n");
971 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
972 NT_STATUS_LOCK_NOT_GRANTED)) return False;
975 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
976 printf("WRITE lock2 succeeded! This is a locking bug\n");
979 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
980 NT_STATUS_LOCK_NOT_GRANTED)) return False;
983 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
984 printf("READ lock2 succeeded! This is a locking bug\n");
987 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
988 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
991 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
992 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
995 cli->session->pid = 2;
997 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
998 printf("unlock at 100 succeeded! This is a locking bug\n");
1002 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
1003 printf("unlock1 succeeded! This is a locking bug\n");
1006 if (!check_error(__LINE__, cli,
1008 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1011 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
1012 printf("unlock2 succeeded! This is a locking bug\n");
1015 if (!check_error(__LINE__, cli,
1017 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1020 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
1021 printf("lock3 succeeded! This is a locking bug\n");
1024 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1027 cli->session->pid = 1;
1029 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
1030 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1034 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1035 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1039 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1040 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1044 if (!torture_close_connection(cli)) {
1048 printf("locktest2 finished\n");
1055 This test checks that
1057 1) the server supports the full offset range in lock requests
1059 static BOOL run_locktest3(int dummy)
1061 struct smbcli_state *cli1, *cli2;
1062 const char *fname = "\\lockt3.lck";
1063 int fnum1, fnum2, i;
1065 BOOL correct = True;
1067 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1069 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1073 printf("starting locktest3\n");
1075 printf("Testing 32 bit offset ranges\n");
1077 smbcli_unlink(cli1->tree, fname);
1079 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1081 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1084 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1086 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1090 printf("Establishing %d locks\n", torture_numops);
1092 for (offset=i=0;i<torture_numops;i++) {
1094 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1095 printf("lock1 %d failed (%s)\n",
1097 smbcli_errstr(cli1->tree));
1101 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1102 printf("lock2 %d failed (%s)\n",
1104 smbcli_errstr(cli1->tree));
1109 printf("Testing %d locks\n", torture_numops);
1111 for (offset=i=0;i<torture_numops;i++) {
1114 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1115 printf("error: lock1 %d succeeded!\n", i);
1119 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1120 printf("error: lock2 %d succeeded!\n", i);
1124 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1125 printf("error: lock3 %d succeeded!\n", i);
1129 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1130 printf("error: lock4 %d succeeded!\n", i);
1135 printf("Removing %d locks\n", torture_numops);
1137 for (offset=i=0;i<torture_numops;i++) {
1140 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1141 printf("unlock1 %d failed (%s)\n",
1143 smbcli_errstr(cli1->tree));
1147 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1148 printf("unlock2 %d failed (%s)\n",
1150 smbcli_errstr(cli1->tree));
1155 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1156 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1160 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1161 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1165 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1166 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1170 if (!torture_close_connection(cli1)) {
1174 if (!torture_close_connection(cli2)) {
1178 printf("finished locktest3\n");
1183 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1184 printf("** "); correct = False; \
1188 looks at overlapping locks
1190 static BOOL run_locktest4(int dummy)
1192 struct smbcli_state *cli1, *cli2;
1193 const char *fname = "\\lockt4.lck";
1194 int fnum1, fnum2, f;
1197 BOOL correct = True;
1199 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1203 printf("starting locktest4\n");
1205 smbcli_unlink(cli1->tree, fname);
1207 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1208 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1210 memset(buf, 0, sizeof(buf));
1212 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1213 printf("Failed to create file\n");
1218 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1219 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1220 EXPECTED(ret, False);
1221 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1223 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1224 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1225 EXPECTED(ret, True);
1226 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1228 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1229 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1230 EXPECTED(ret, False);
1231 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1233 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1234 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1235 EXPECTED(ret, True);
1236 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1238 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1239 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1240 EXPECTED(ret, False);
1241 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1243 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1244 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1245 EXPECTED(ret, True);
1246 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1248 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1249 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1250 EXPECTED(ret, True);
1251 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1253 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1254 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1255 EXPECTED(ret, False);
1256 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1258 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1259 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1260 EXPECTED(ret, False);
1261 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1263 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1264 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1265 EXPECTED(ret, True);
1266 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1268 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1269 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1270 EXPECTED(ret, False);
1271 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1273 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1274 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1275 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1276 EXPECTED(ret, False);
1277 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1280 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1281 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1282 EXPECTED(ret, False);
1283 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1285 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1286 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1287 EXPECTED(ret, False);
1288 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1291 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1292 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1293 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1294 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1295 EXPECTED(ret, True);
1296 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1299 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1300 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1301 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1302 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1303 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1304 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1305 EXPECTED(ret, True);
1306 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1308 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1309 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1310 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1311 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1312 EXPECTED(ret, True);
1313 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1315 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1316 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1317 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1318 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1319 EXPECTED(ret, True);
1320 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1322 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1323 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1324 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1325 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1326 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1327 EXPECTED(ret, True);
1328 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1330 smbcli_close(cli1->tree, fnum1);
1331 smbcli_close(cli2->tree, fnum2);
1332 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1333 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1334 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1335 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1336 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1337 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1338 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1339 smbcli_close(cli1->tree, f);
1340 smbcli_close(cli1->tree, fnum1);
1341 EXPECTED(ret, True);
1342 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1345 smbcli_close(cli1->tree, fnum1);
1346 smbcli_close(cli2->tree, fnum2);
1347 smbcli_unlink(cli1->tree, fname);
1348 torture_close_connection(cli1);
1349 torture_close_connection(cli2);
1351 printf("finished locktest4\n");
1356 looks at lock upgrade/downgrade.
1358 static BOOL run_locktest5(int dummy)
1360 struct smbcli_state *cli1, *cli2;
1361 const char *fname = "\\lockt5.lck";
1362 int fnum1, fnum2, fnum3;
1365 BOOL correct = True;
1367 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1371 printf("starting locktest5\n");
1373 smbcli_unlink(cli1->tree, fname);
1375 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1376 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1377 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1379 memset(buf, 0, sizeof(buf));
1381 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1382 printf("Failed to create file\n");
1387 /* Check for NT bug... */
1388 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1389 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1390 smbcli_close(cli1->tree, fnum1);
1391 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1392 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1393 EXPECTED(ret, True);
1394 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1395 smbcli_close(cli1->tree, fnum1);
1396 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1397 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1399 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1400 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1401 EXPECTED(ret, True);
1402 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1404 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1405 EXPECTED(ret, False);
1407 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1409 /* Unlock the process 2 lock. */
1410 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1412 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1413 EXPECTED(ret, False);
1415 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1417 /* Unlock the process 1 fnum3 lock. */
1418 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1420 /* Stack 2 more locks here. */
1421 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1422 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1424 EXPECTED(ret, True);
1425 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1427 /* Unlock the first process lock, then check this was the WRITE lock that was
1430 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1431 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1433 EXPECTED(ret, True);
1434 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1436 /* Unlock the process 2 lock. */
1437 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1439 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1441 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1442 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1443 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1445 EXPECTED(ret, True);
1446 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1448 /* Ensure the next unlock fails. */
1449 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1450 EXPECTED(ret, False);
1451 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1453 /* Ensure connection 2 can get a write lock. */
1454 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1455 EXPECTED(ret, True);
1457 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1461 smbcli_close(cli1->tree, fnum1);
1462 smbcli_close(cli2->tree, fnum2);
1463 smbcli_unlink(cli1->tree, fname);
1464 if (!torture_close_connection(cli1)) {
1467 if (!torture_close_connection(cli2)) {
1471 printf("finished locktest5\n");
1477 tries the unusual lockingX locktype bits
1479 static BOOL run_locktest6(int dummy)
1481 struct smbcli_state *cli;
1482 const char *fname[1] = { "\\lock6.txt" };
1487 if (!torture_open_connection(&cli)) {
1491 printf("starting locktest6\n");
1494 printf("Testing %s\n", fname[i]);
1496 smbcli_unlink(cli->tree, fname[i]);
1498 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1499 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1500 smbcli_close(cli->tree, fnum);
1501 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1503 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1504 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1505 smbcli_close(cli->tree, fnum);
1506 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1508 smbcli_unlink(cli->tree, fname[i]);
1511 torture_close_connection(cli);
1513 printf("finished locktest6\n");
1517 static BOOL run_locktest7(int dummy)
1519 struct smbcli_state *cli1;
1520 const char *fname = "\\lockt7.lck";
1525 BOOL correct = False;
1527 if (!torture_open_connection(&cli1)) {
1531 printf("starting locktest7\n");
1533 smbcli_unlink(cli1->tree, fname);
1535 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1537 memset(buf, 0, sizeof(buf));
1539 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1540 printf("Failed to create file\n");
1544 cli1->session->pid = 1;
1546 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1547 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1550 printf("pid1 successfully locked range 130:4 for READ\n");
1553 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1554 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1557 printf("pid1 successfully read the range 130:4\n");
1560 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1561 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1562 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1563 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1567 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1571 cli1->session->pid = 2;
1573 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1574 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1576 printf("pid2 successfully read the range 130:4\n");
1579 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1580 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1581 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1582 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1586 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1590 cli1->session->pid = 1;
1591 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1593 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1594 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1597 printf("pid1 successfully locked range 130:4 for WRITE\n");
1600 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1601 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1604 printf("pid1 successfully read the range 130:4\n");
1607 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1608 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1611 printf("pid1 successfully wrote to the range 130:4\n");
1614 cli1->session->pid = 2;
1616 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1617 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1618 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1619 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1623 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1627 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1628 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1629 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1630 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1634 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1638 printf("Testing truncate of locked file.\n");
1640 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1643 printf("Unable to truncate locked file.\n");
1647 printf("Truncated locked file.\n");
1650 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1651 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1657 printf("Unable to truncate locked file. Size was %u\n", size);
1662 cli1->session->pid = 1;
1664 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1668 smbcli_close(cli1->tree, fnum1);
1669 smbcli_close(cli1->tree, fnum2);
1670 smbcli_unlink(cli1->tree, fname);
1671 torture_close_connection(cli1);
1673 printf("finished locktest7\n");
1678 test whether fnums and tids open on one VC are available on another (a major
1681 static BOOL run_fdpasstest(int dummy)
1683 struct smbcli_state *cli1, *cli2;
1684 const char *fname = "\\fdpass.tst";
1688 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1692 printf("starting fdpasstest\n");
1694 smbcli_unlink(cli1->tree, fname);
1696 printf("Opening a file on connection 1\n");
1698 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1700 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1704 printf("writing to file on connection 1\n");
1706 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1707 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1711 oldtid = cli2->tree->tid;
1712 cli2->session->vuid = cli1->session->vuid;
1713 cli2->tree->tid = cli1->tree->tid;
1714 cli2->session->pid = cli1->session->pid;
1716 printf("reading from file on connection 2\n");
1718 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1719 printf("read succeeded! nasty security hole [%s]\n",
1724 smbcli_close(cli1->tree, fnum1);
1725 smbcli_unlink(cli1->tree, fname);
1727 cli2->tree->tid = oldtid;
1729 torture_close_connection(cli1);
1730 torture_close_connection(cli2);
1732 printf("finished fdpasstest\n");
1738 This test checks that
1740 1) the server does not allow an unlink on a file that is open
1742 static BOOL run_unlinktest(int dummy)
1744 struct smbcli_state *cli;
1745 const char *fname = "\\unlink.tst";
1747 BOOL correct = True;
1749 if (!torture_open_connection(&cli)) {
1753 printf("starting unlink test\n");
1755 smbcli_unlink(cli->tree, fname);
1757 cli->session->pid = 1;
1759 printf("Opening a file\n");
1761 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1763 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1767 printf("Unlinking a open file\n");
1769 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1770 printf("error: server allowed unlink on an open file\n");
1773 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1774 NT_STATUS_SHARING_VIOLATION);
1777 smbcli_close(cli->tree, fnum);
1778 smbcli_unlink(cli->tree, fname);
1780 if (!torture_close_connection(cli)) {
1784 printf("unlink test finished\n");
1791 test the timing of deferred open requests
1793 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1795 const char *fname = "\\defer_open_test.dat";
1798 BOOL correct = True;
1801 printf("failed to connect\n");
1805 printf("Testing deferred open requests.\n");
1811 struct timeval tv_start, tv_end;
1812 GetTimeOfDay(&tv_start);
1813 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1814 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1815 NTCREATEX_DISP_OPEN_IF, 0, 0);
1819 GetTimeOfDay(&tv_end);
1820 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1821 /* Sharing violation errors need to be 1 second apart. */
1822 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1823 if (tdif < 500000 || tdif > 1500000) {
1824 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1825 tdif / (int64_t)1000000,
1826 tdif % (int64_t)1000000);
1829 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1832 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1836 printf("pid %u open %d\n", getpid(), i);
1840 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1841 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1847 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1848 /* All until the last unlink will fail with sharing violation. */
1849 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1850 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1855 printf("deferred test finished\n");
1856 if (!torture_close_connection(cli)) {
1863 test how many open files this server supports on the one socket
1865 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1867 #define MAXFID_TEMPLATE "\\maxfid.%d.%d"
1869 int fnums[0x11000], i;
1871 BOOL correct = True;
1874 printf("failed to connect\n");
1878 printf("Testing maximum number of open files\n");
1880 for (i=0; i<0x11000; i++) {
1881 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1882 if ((fnums[i] = smbcli_open(cli->tree, fname,
1883 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1885 printf("open of %s failed (%s)\n",
1886 fname, smbcli_errstr(cli->tree));
1887 printf("maximum fnum is %d\n", i);
1896 printf("cleaning up\n");
1898 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1899 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1900 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1902 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1903 printf("unlink of %s failed (%s)\n",
1904 fname, smbcli_errstr(cli->tree));
1912 printf("maxfid test finished\n");
1913 if (!torture_close_connection(cli)) {
1917 #undef MAXFID_TEMPLATE
1920 /* send smb negprot commands, not reading the response */
1921 static BOOL run_negprot_nowait(int dummy)
1924 struct smbcli_state *cli, *cli2;
1925 BOOL correct = True;
1927 printf("starting negprot nowait test\n");
1929 cli = open_nbt_connection();
1934 printf("Filling send buffer\n");
1936 for (i=0;i<10000;i++) {
1937 struct smbcli_request *req;
1938 time_t t1 = time(NULL);
1939 req = smb_negprot_send(cli->transport, PROTOCOL_NT1);
1940 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
1941 smbcli_transport_process(cli->transport);
1943 if (req->state == SMBCLI_REQUEST_ERROR) {
1944 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
1945 torture_close_connection(cli);
1948 if (req->state == SMBCLI_REQUEST_SEND) {
1954 printf("send buffer failed to fill\n");
1955 if (!torture_close_connection(cli)) {
1961 printf("send buffer filled after %d requests\n", i);
1963 printf("Opening secondary connection\n");
1964 if (!torture_open_connection(&cli2)) {
1968 if (!torture_close_connection(cli)) {
1972 if (!torture_close_connection(cli2)) {
1976 printf("finished negprot nowait test\n");
1983 This checks how the getatr calls works
1985 static BOOL run_attrtest(int dummy)
1987 struct smbcli_state *cli;
1990 const char *fname = "\\attrib123456789.tst";
1991 BOOL correct = True;
1993 printf("starting attrib test\n");
1995 if (!torture_open_connection(&cli)) {
1999 smbcli_unlink(cli->tree, fname);
2000 fnum = smbcli_open(cli->tree, fname,
2001 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2002 smbcli_close(cli->tree, fnum);
2004 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2005 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2009 printf("New file time is %s", ctime(&t));
2011 if (abs(t - time(NULL)) > 60*60*24*10) {
2012 printf("ERROR: SMBgetatr bug. time is %s",
2018 t2 = t-60*60*24; /* 1 day ago */
2020 printf("Setting file time to %s", ctime(&t2));
2022 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
2023 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
2027 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2028 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2032 printf("Retrieved file time as %s", ctime(&t));
2035 printf("ERROR: getatr/setatr bug. times are\n%s",
2037 printf("%s", ctime(&t2));
2041 smbcli_unlink(cli->tree, fname);
2043 if (!torture_close_connection(cli)) {
2047 printf("attrib test finished\n");
2054 This checks a couple of trans2 calls
2056 static BOOL run_trans2test(int dummy)
2058 struct smbcli_state *cli;
2061 time_t c_time, a_time, m_time, w_time, m_time2;
2062 const char *fname = "\\trans2.tst";
2063 const char *dname = "\\trans2";
2064 const char *fname2 = "\\trans2\\trans2.tst";
2066 BOOL correct = True;
2068 printf("starting trans2 test\n");
2070 if (!torture_open_connection(&cli)) {
2074 smbcli_unlink(cli->tree, fname);
2076 printf("Testing qfileinfo\n");
2078 fnum = smbcli_open(cli->tree, fname,
2079 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2080 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2082 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
2086 printf("Testing NAME_INFO\n");
2088 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
2089 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
2093 if (!pname || strcmp(pname, fname)) {
2094 printf("qfilename gave different name? [%s] [%s]\n",
2099 smbcli_close(cli->tree, fnum);
2100 smbcli_unlink(cli->tree, fname);
2102 fnum = smbcli_open(cli->tree, fname,
2103 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2105 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
2108 smbcli_close(cli->tree, fnum);
2110 printf("Checking for sticky create times\n");
2112 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2113 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
2116 if (c_time != m_time) {
2117 printf("create time=%s", ctime(&c_time));
2118 printf("modify time=%s", ctime(&m_time));
2119 printf("This system appears to have sticky create times\n");
2121 if (a_time % (60*60) == 0) {
2122 printf("access time=%s", ctime(&a_time));
2123 printf("This system appears to set a midnight access time\n");
2127 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2128 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2134 smbcli_unlink(cli->tree, fname);
2135 fnum = smbcli_open(cli->tree, fname,
2136 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2137 smbcli_close(cli->tree, fnum);
2138 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2139 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2142 if (w_time < 60*60*24*2) {
2143 printf("write time=%s", ctime(&w_time));
2144 printf("This system appears to set a initial 0 write time\n");
2149 smbcli_unlink(cli->tree, fname);
2152 /* check if the server updates the directory modification time
2153 when creating a new file */
2154 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
2155 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
2159 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2160 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2164 fnum = smbcli_open(cli->tree, fname2,
2165 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2166 smbcli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2167 smbcli_close(cli->tree, fnum);
2168 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2169 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2172 if (m_time2 == m_time) {
2173 printf("This system does not update directory modification times\n");
2177 smbcli_unlink(cli->tree, fname2);
2178 smbcli_rmdir(cli->tree, dname);
2180 if (!torture_close_connection(cli)) {
2184 printf("trans2 test finished\n");
2190 Test delete on close semantics.
2192 static BOOL run_deletetest(int dummy)
2194 struct smbcli_state *cli1;
2195 struct smbcli_state *cli2 = NULL;
2196 const char *fname = "\\delete.file";
2199 BOOL correct = True;
2201 printf("starting delete test\n");
2203 if (!torture_open_connection(&cli1)) {
2207 /* Test 1 - this should delete the file on close. */
2209 smbcli_setatr(cli1->tree, fname, 0, 0);
2210 smbcli_unlink(cli1->tree, fname);
2212 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2213 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2214 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2217 printf("[1] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2222 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2223 printf("[1] close failed (%s)\n", smbcli_errstr(cli1->tree));
2228 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2230 printf("[1] open of %s succeeded (should fail)\n", fname);
2235 printf("first delete on close test succeeded.\n");
2237 /* Test 2 - this should delete the file on close. */
2239 smbcli_setatr(cli1->tree, fname, 0, 0);
2240 smbcli_unlink(cli1->tree, fname);
2242 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2243 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2244 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2247 printf("[2] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2252 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2253 printf("[2] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2258 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2259 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2264 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2266 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2267 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2268 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2272 smbcli_unlink(cli1->tree, fname);
2274 printf("second delete on close test succeeded.\n");
2277 smbcli_setatr(cli1->tree, fname, 0, 0);
2278 smbcli_unlink(cli1->tree, fname);
2280 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2281 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2284 printf("[3] open - 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2289 /* This should fail with a sharing violation - open for delete is only compatible
2290 with SHARE_DELETE. */
2292 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2293 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2294 NTCREATEX_DISP_OPEN, 0, 0);
2297 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2302 /* This should succeed. */
2304 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2305 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2308 printf("[3] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2313 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2314 printf("[3] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2319 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2320 printf("[3] close 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2325 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2326 printf("[3] close 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2331 /* This should fail - file should no longer be there. */
2333 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2335 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2336 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2337 printf("[3] close failed (%s)\n", smbcli_errstr(cli1->tree));
2339 smbcli_unlink(cli1->tree, fname);
2343 printf("third delete on close test succeeded.\n");
2346 smbcli_setatr(cli1->tree, fname, 0, 0);
2347 smbcli_unlink(cli1->tree, fname);
2349 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2350 SA_RIGHT_FILE_READ_DATA |
2351 SA_RIGHT_FILE_WRITE_DATA |
2352 STD_RIGHT_DELETE_ACCESS,
2353 FILE_ATTRIBUTE_NORMAL,
2354 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2355 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2358 printf("[4] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2363 /* This should succeed. */
2364 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2365 FILE_ATTRIBUTE_NORMAL,
2366 NTCREATEX_SHARE_ACCESS_READ |
2367 NTCREATEX_SHARE_ACCESS_WRITE |
2368 NTCREATEX_SHARE_ACCESS_DELETE,
2369 NTCREATEX_DISP_OPEN, 0, 0);
2371 printf("[4] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2376 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2377 printf("[4] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2382 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2383 printf("[4] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2388 /* This should fail - no more opens once delete on close set. */
2389 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2390 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2391 NTCREATEX_DISP_OPEN, 0, 0);
2393 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2397 printf("fourth delete on close test succeeded.\n");
2399 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2400 printf("[4] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2406 smbcli_setatr(cli1->tree, fname, 0, 0);
2407 smbcli_unlink(cli1->tree, fname);
2409 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2411 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2416 /* This should fail - only allowed on NT opens with DELETE access. */
2418 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2419 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2424 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2425 printf("[5] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2430 printf("fifth delete on close test succeeded.\n");
2433 smbcli_setatr(cli1->tree, fname, 0, 0);
2434 smbcli_unlink(cli1->tree, fname);
2436 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2437 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2438 FILE_ATTRIBUTE_NORMAL,
2439 NTCREATEX_SHARE_ACCESS_READ |
2440 NTCREATEX_SHARE_ACCESS_WRITE |
2441 NTCREATEX_SHARE_ACCESS_DELETE,
2442 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2445 printf("[6] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2450 /* This should fail - only allowed on NT opens with DELETE access. */
2452 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2453 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2458 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2459 printf("[6] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2464 printf("sixth delete on close test succeeded.\n");
2467 smbcli_setatr(cli1->tree, fname, 0, 0);
2468 smbcli_unlink(cli1->tree, fname);
2470 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2471 SA_RIGHT_FILE_READ_DATA |
2472 SA_RIGHT_FILE_WRITE_DATA |
2473 STD_RIGHT_DELETE_ACCESS,
2474 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2477 printf("[7] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2482 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2483 printf("[7] setting delete_on_close on file failed !\n");
2488 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2489 printf("[7] unsetting delete_on_close on file failed !\n");
2494 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2495 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2500 /* This next open should succeed - we reset the flag. */
2502 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2504 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2509 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2510 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2515 printf("seventh delete on close test succeeded.\n");
2518 smbcli_setatr(cli1->tree, fname, 0, 0);
2519 smbcli_unlink(cli1->tree, fname);
2521 if (!torture_open_connection(&cli2)) {
2522 printf("[8] failed to open second connection.\n");
2527 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2528 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2529 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2532 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2537 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2538 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2539 NTCREATEX_DISP_OPEN, 0, 0);
2542 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2547 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2548 printf("[8] setting delete_on_close on file failed !\n");
2553 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2554 printf("[8] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2559 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
2560 printf("[8] close - 2 failed (%s)\n", smbcli_errstr(cli2->tree));
2565 /* This should fail.. */
2566 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2568 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2572 printf("eighth delete on close test succeeded.\n");
2574 /* This should fail - we need to set DELETE_ACCESS. */
2575 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2576 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2579 printf("[9] open of %s succeeded should have failed!\n", fname);
2584 printf("ninth delete on close test succeeded.\n");
2586 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2587 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2589 printf("[10] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2594 /* This should delete the file. */
2595 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2596 printf("[10] close failed (%s)\n", smbcli_errstr(cli1->tree));
2601 /* This should fail.. */
2602 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2604 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2608 printf("tenth delete on close test succeeded.\n");
2609 printf("finished delete test\n");
2612 /* FIXME: This will crash if we aborted before cli2 got
2613 * intialized, because these functions don't handle
2614 * uninitialized connections. */
2616 smbcli_close(cli1->tree, fnum1);
2617 smbcli_close(cli1->tree, fnum2);
2618 smbcli_setatr(cli1->tree, fname, 0, 0);
2619 smbcli_unlink(cli1->tree, fname);
2621 if (!torture_close_connection(cli1)) {
2624 if (!torture_close_connection(cli2)) {
2632 print out server properties
2634 static BOOL run_properties(int dummy)
2636 struct smbcli_state *cli;
2637 BOOL correct = True;
2639 printf("starting properties test\n");
2643 if (!torture_open_connection(&cli)) {
2647 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2649 if (!torture_close_connection(cli)) {
2658 /* FIRST_DESIRED_ACCESS 0xf019f */
2659 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2660 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2661 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2662 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2663 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2664 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2665 /* SECOND_DESIRED_ACCESS 0xe0080 */
2666 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2667 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2668 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2671 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2672 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2673 SA_RIGHT_FILE_READ_DATA|\
2674 WRITE_OWNER_ACCESS /* */
2678 Test ntcreate calls made by xcopy
2680 static BOOL run_xcopy(int dummy)
2682 struct smbcli_state *cli1;
2683 const char *fname = "\\test.txt";
2684 BOOL correct = True;
2687 printf("starting xcopy test\n");
2689 if (!torture_open_connection(&cli1)) {
2693 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2694 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2695 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2699 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2703 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
2704 SECOND_DESIRED_ACCESS, 0,
2705 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2708 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
2712 if (!torture_close_connection(cli1)) {
2720 Test rename on files open with share delete and no share delete.
2722 static BOOL run_rename(int dummy)
2724 struct smbcli_state *cli1;
2725 const char *fname = "\\test.txt";
2726 const char *fname1 = "\\test1.txt";
2727 BOOL correct = True;
2730 printf("starting rename test\n");
2732 if (!torture_open_connection(&cli1)) {
2736 smbcli_unlink(cli1->tree, fname);
2737 smbcli_unlink(cli1->tree, fname1);
2738 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2739 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2742 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2746 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2747 printf("First rename failed (this is correct) - %s\n", smbcli_errstr(cli1->tree));
2749 printf("First rename succeeded - this should have failed !\n");
2753 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2754 printf("close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2758 smbcli_unlink(cli1->tree, fname);
2759 smbcli_unlink(cli1->tree, fname1);
2760 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2761 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2764 printf("Second open failed - %s\n", smbcli_errstr(cli1->tree));
2768 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2769 printf("Second rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2772 printf("Second rename succeeded\n");
2775 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2776 printf("close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2780 smbcli_unlink(cli1->tree, fname);
2781 smbcli_unlink(cli1->tree, fname1);
2783 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2784 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2787 printf("Third open failed - %s\n", smbcli_errstr(cli1->tree));
2792 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2793 printf("Third rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2796 printf("Third rename succeeded\n");
2799 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2800 printf("close - 3 failed (%s)\n", smbcli_errstr(cli1->tree));
2804 smbcli_unlink(cli1->tree, fname);
2805 smbcli_unlink(cli1->tree, fname1);
2807 if (!torture_close_connection(cli1)) {
2816 see how many RPC pipes we can open at once
2818 static BOOL run_pipe_number(int dummy)
2820 struct smbcli_state *cli1;
2821 const char *pipe_name = "\\WKSSVC";
2825 printf("starting pipenumber test\n");
2826 if (!torture_open_connection(&cli1)) {
2831 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2832 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2835 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
2839 printf("%d\r", num_pipes);
2843 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2844 torture_close_connection(cli1);
2852 open N connections to the server and just hold them open
2853 used for testing performance when there are N idle users
2856 static BOOL torture_holdcon(int dummy)
2859 struct smbcli_state **cli;
2862 printf("Opening %d connections\n", torture_numops);
2864 cli = malloc(sizeof(struct smbcli_state *) * torture_numops);
2866 for (i=0;i<torture_numops;i++) {
2867 if (!torture_open_connection(&cli[i])) {
2870 printf("opened %d connections\r", i);
2874 printf("\nStarting pings\n");
2877 for (i=0;i<torture_numops;i++) {
2880 status = smbcli_chkpath(cli[i]->tree, "\\");
2881 if (!NT_STATUS_IS_OK(status)) {
2882 printf("Connection %d is dead\n", i);
2890 if (num_dead == torture_numops) {
2891 printf("All connections dead - finishing\n");
2903 Try with a wrong vuid and check error message.
2906 static BOOL run_vuidtest(int dummy)
2908 struct smbcli_state *cli;
2909 const char *fname = "\\vuid.tst";
2912 time_t c_time, a_time, m_time;
2913 BOOL correct = True;
2918 printf("starting vuid test\n");
2920 if (!torture_open_connection(&cli)) {
2924 smbcli_unlink(cli->tree, fname);
2926 fnum = smbcli_open(cli->tree, fname,
2927 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2929 orig_vuid = cli->session->vuid;
2931 cli->session->vuid += 1234;
2933 printf("Testing qfileinfo with wrong vuid\n");
2935 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
2936 &size, &c_time, &a_time,
2937 &m_time, NULL, NULL))) {
2938 printf("ERROR: qfileinfo passed with wrong vuid\n");
2942 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2943 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2944 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2945 printf("ERROR: qfileinfo should have returned DOS error "
2946 "ERRSRV:ERRbaduid\n but returned %s\n",
2947 smbcli_errstr(cli->tree));
2951 cli->session->vuid -= 1234;
2953 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
2954 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
2958 smbcli_unlink(cli->tree, fname);
2960 if (!torture_close_connection(cli)) {
2964 printf("vuid test finished\n");
2970 Test open mode returns on read-only files.
2972 static BOOL run_opentest(int dummy)
2974 static struct smbcli_state *cli1;
2975 static struct smbcli_state *cli2;
2976 const char *fname = "\\readonly.file";
2980 BOOL correct = True;
2984 printf("starting open test\n");
2986 if (!torture_open_connection(&cli1)) {
2990 smbcli_setatr(cli1->tree, fname, 0, 0);
2991 smbcli_unlink(cli1->tree, fname);
2993 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2995 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2999 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3000 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3004 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
3005 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
3006 CHECK_MAX_FAILURES(error_test1);
3010 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3012 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3013 CHECK_MAX_FAILURES(error_test1);
3017 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3018 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3020 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3021 NT_STATUS_ACCESS_DENIED)) {
3022 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3025 printf("finished open test 1\n");
3027 smbcli_close(cli1->tree, fnum1);
3029 /* Now try not readonly and ensure ERRbadshare is returned. */
3031 smbcli_setatr(cli1->tree, fname, 0, 0);
3033 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3035 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3039 /* This will fail - but the error should be ERRshare. */
3040 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3042 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3043 NT_STATUS_SHARING_VIOLATION)) {
3044 printf("correct error code ERRDOS/ERRbadshare returned\n");
3047 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3048 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3052 smbcli_unlink(cli1->tree, fname);
3054 printf("finished open test 2\n");
3056 /* Test truncate open disposition on file opened for read. */
3058 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3060 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3064 /* write 20 bytes. */
3066 memset(buf, '\0', 20);
3068 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3069 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
3073 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3074 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3078 /* Ensure size == 20. */
3079 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3080 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3081 CHECK_MAX_FAILURES(error_test3);
3086 printf("(3) file size != 20\n");
3087 CHECK_MAX_FAILURES(error_test3);
3091 /* Now test if we can truncate a file opened for readonly. */
3093 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3095 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3096 CHECK_MAX_FAILURES(error_test3);
3100 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3101 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3105 /* Ensure size == 0. */
3106 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3107 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3108 CHECK_MAX_FAILURES(error_test3);
3113 printf("(3) file size != 0\n");
3114 CHECK_MAX_FAILURES(error_test3);
3117 printf("finished open test 3\n");
3119 smbcli_unlink(cli1->tree, fname);
3122 printf("testing ctemp\n");
3123 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
3125 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
3126 CHECK_MAX_FAILURES(error_test4);
3129 printf("ctemp gave path %s\n", tmp_path);
3130 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3131 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3133 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
3134 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3137 /* Test the non-io opens... */
3139 if (!torture_open_connection(&cli2)) {
3143 smbcli_setatr(cli2->tree, fname, 0, 0);
3144 smbcli_unlink(cli2->tree, fname);
3146 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3148 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3149 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3152 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3153 CHECK_MAX_FAILURES(error_test10);
3157 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3158 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3160 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3161 CHECK_MAX_FAILURES(error_test10);
3165 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3166 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3169 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3170 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3174 printf("non-io open test #1 passed.\n");
3176 smbcli_unlink(cli1->tree, fname);
3178 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3180 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3181 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3184 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3185 CHECK_MAX_FAILURES(error_test20);
3189 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3190 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3193 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3194 CHECK_MAX_FAILURES(error_test20);
3198 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3199 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3202 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3203 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3207 printf("non-io open test #2 passed.\n");
3209 smbcli_unlink(cli1->tree, fname);
3211 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3213 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3214 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3217 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3218 CHECK_MAX_FAILURES(error_test30);
3222 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3223 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3226 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3227 CHECK_MAX_FAILURES(error_test30);
3231 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3232 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3235 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3236 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3240 printf("non-io open test #3 passed.\n");
3242 smbcli_unlink(cli1->tree, fname);
3244 printf("TEST #4 testing 2 non-io opens (both with 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_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3250 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3251 CHECK_MAX_FAILURES(error_test40);
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_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3259 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3260 CHECK_MAX_FAILURES(error_test40);
3264 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3266 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3267 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3271 printf("non-io open test #4 passed.\n");
3273 smbcli_unlink(cli1->tree, fname);
3275 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3277 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3278 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3281 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3282 CHECK_MAX_FAILURES(error_test50);
3286 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3287 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3290 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3291 CHECK_MAX_FAILURES(error_test50);
3295 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3296 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3300 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3301 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3305 printf("non-io open test #5 passed.\n");
3307 printf("TEST #6 testing 1 non-io open, one io open\n");
3309 smbcli_unlink(cli1->tree, fname);
3311 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3312 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3315 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3316 CHECK_MAX_FAILURES(error_test60);
3320 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3321 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3324 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3325 CHECK_MAX_FAILURES(error_test60);
3329 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3330 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3334 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3335 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3339 printf("non-io open test #6 passed.\n");
3341 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3343 smbcli_unlink(cli1->tree, fname);
3345 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3346 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3349 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3350 CHECK_MAX_FAILURES(error_test70);
3354 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3355 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3358 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3359 CHECK_MAX_FAILURES(error_test70);
3363 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3365 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3366 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3370 printf("non-io open test #7 passed.\n");
3374 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3376 smbcli_unlink(cli1->tree, fname);
3378 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3380 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3384 /* write 20 bytes. */
3386 memset(buf, '\0', 20);
3388 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3389 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
3393 /* Ensure size == 20. */
3394 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3395 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
3396 CHECK_MAX_FAILURES(error_test80);
3401 printf("(8) file size != 20\n");
3402 CHECK_MAX_FAILURES(error_test80);
3406 /* Get an exclusive lock on the open file. */
3407 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3408 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
3409 CHECK_MAX_FAILURES(error_test80);
3413 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3415 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3419 /* Ensure size == 0. */
3420 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3421 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
3422 CHECK_MAX_FAILURES(error_test80);
3427 printf("(8) file size != 0\n");
3428 CHECK_MAX_FAILURES(error_test80);
3432 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3433 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3437 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
3438 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3444 printf("open test #8 passed.\n");
3446 smbcli_unlink(cli1->tree, fname);
3448 if (!torture_close_connection(cli1)) {
3451 if (!torture_close_connection(cli2)) {
3459 static uint32_t open_attrs_table[] = {
3460 FILE_ATTRIBUTE_NORMAL,
3461 FILE_ATTRIBUTE_ARCHIVE,
3462 FILE_ATTRIBUTE_READONLY,
3463 FILE_ATTRIBUTE_HIDDEN,
3464 FILE_ATTRIBUTE_SYSTEM,
3466 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3467 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3468 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3469 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3470 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3471 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3473 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3474 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3475 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3476 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3479 struct trunc_open_results {
3482 uint32_t trunc_attr;
3483 uint32_t result_attr;
3486 static struct trunc_open_results attr_results[] = {
3487 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3488 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3489 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3490 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3491 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3492 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3493 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3494 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3495 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3496 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3497 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3498 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3499 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3500 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3501 { 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 },
3502 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3503 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3504 { 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 },
3505 { 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 },
3506 { 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 },
3507 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3508 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3509 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3510 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3511 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3512 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3515 static BOOL run_openattrtest(int dummy)
3517 struct smbcli_state *cli1;
3518 const char *fname = "\\openattr.file";
3520 BOOL correct = True;
3525 printf("starting open attr test\n");
3527 if (!torture_open_connection(&cli1)) {
3531 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3532 smbcli_setatr(cli1->tree, fname, 0, 0);
3533 smbcli_unlink(cli1->tree, fname);
3534 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3535 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3538 printf("open %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3542 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3543 printf("close %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3547 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3548 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
3549 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3550 open_attrs_table[j],
3551 NTCREATEX_SHARE_ACCESS_NONE,
3552 NTCREATEX_DISP_OVERWRITE, 0, 0);
3555 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3556 if (attr_results[l].num == k) {
3557 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3558 k, open_attrs_table[i],
3559 open_attrs_table[j],
3560 fname, NT_STATUS_V(smbcli_nt_error(cli1->tree)), smbcli_errstr(cli1->tree));
3562 CHECK_MAX_FAILURES(error_exit);
3565 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3566 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3567 k, open_attrs_table[i], open_attrs_table[j],
3568 smbcli_errstr(cli1->tree));
3570 CHECK_MAX_FAILURES(error_exit);
3573 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3579 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3580 printf("close %d (2) of %s failed (%s)\n", j, fname, smbcli_errstr(cli1->tree));
3584 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3585 printf("getatr(2) failed (%s)\n", smbcli_errstr(cli1->tree));
3590 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3591 k, open_attrs_table[i], open_attrs_table[j], attr );
3594 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3595 if (attr_results[l].num == k) {
3596 if (attr != attr_results[l].result_attr ||
3597 open_attrs_table[i] != attr_results[l].init_attr ||
3598 open_attrs_table[j] != attr_results[l].trunc_attr) {
3599 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3600 k, open_attrs_table[i],
3601 open_attrs_table[j],
3603 attr_results[l].result_attr);
3605 CHECK_MAX_FAILURES(error_exit);
3614 smbcli_setatr(cli1->tree, fname, 0, 0);
3615 smbcli_unlink(cli1->tree, fname);
3617 printf("open attr test %s.\n", correct ? "passed" : "failed");
3619 if (!torture_close_connection(cli1)) {
3625 static void list_fn(file_info *finfo, const char *name, void *state)
3631 test directory listing speed
3633 static BOOL run_dirtest(int dummy)
3636 struct smbcli_state *cli;
3639 BOOL correct = True;
3641 printf("starting directory test\n");
3643 if (!torture_open_connection(&cli)) {
3647 printf("Creating %d random filenames\n", torture_numops);
3650 for (i=0;i<torture_numops;i++) {
3652 asprintf(&fname, "\\%x", (int)random());
3653 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3655 fprintf(stderr,"Failed to open %s\n", fname);
3658 smbcli_close(cli->tree, fnum);
3664 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3665 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3666 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3668 printf("dirtest core %g seconds\n", end_timer() - t1);
3671 for (i=0;i<torture_numops;i++) {
3673 asprintf(&fname, "\\%x", (int)random());
3674 smbcli_unlink(cli->tree, fname);
3678 if (!torture_close_connection(cli)) {
3682 printf("finished dirtest\n");
3688 sees what IOCTLs are supported
3690 BOOL torture_ioctl_test(int dummy)
3692 struct smbcli_state *cli;
3693 uint16_t device, function;
3695 const char *fname = "\\ioctl.dat";
3697 union smb_ioctl parms;
3698 TALLOC_CTX *mem_ctx;
3700 if (!torture_open_connection(&cli)) {
3704 mem_ctx = talloc_init("ioctl_test");
3706 printf("starting ioctl test\n");
3708 smbcli_unlink(cli->tree, fname);
3710 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3712 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
3716 parms.ioctl.level = RAW_IOCTL_IOCTL;
3717 parms.ioctl.in.fnum = fnum;
3718 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3719 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3720 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
3722 for (device=0;device<0x100;device++) {
3723 printf("testing device=0x%x\n", device);
3724 for (function=0;function<0x100;function++) {
3725 parms.ioctl.in.request = (device << 16) | function;
3726 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3728 if (NT_STATUS_IS_OK(status)) {
3729 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3730 device, function, parms.ioctl.out.blob.length);
3735 if (!torture_close_connection(cli)) {
3744 tries variants of chkpath
3746 BOOL torture_chkpath_test(int dummy)
3748 struct smbcli_state *cli;
3752 if (!torture_open_connection(&cli)) {
3756 printf("starting chkpath test\n");
3758 printf("Testing valid and invalid paths\n");
3760 /* cleanup from an old run */
3761 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3762 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3763 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3765 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
3766 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
3770 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3771 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
3775 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3777 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
3780 smbcli_close(cli->tree, fnum);
3782 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
3783 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
3787 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3788 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
3792 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3793 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3794 NT_STATUS_NOT_A_DIRECTORY);
3796 printf("* chkpath on a file should fail\n");
3800 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3801 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3802 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3804 printf("* chkpath on a non existent file should fail\n");
3808 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3809 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3810 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3812 printf("* chkpath on a non existent component should fail\n");
3816 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3817 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3818 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3820 if (!torture_close_connection(cli)) {
3827 static BOOL run_dirtest1(int dummy)
3830 struct smbcli_state *cli;
3832 BOOL correct = True;
3834 printf("starting directory test\n");
3836 if (!torture_open_connection(&cli)) {
3840 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3841 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3844 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\LISTDIR"))) {
3845 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3849 printf("Creating %d files\n", torture_entries);
3851 /* Create torture_entries files and torture_entries directories. */
3852 for (i=0;i<torture_entries;i++) {
3854 asprintf(&fname, "\\LISTDIR\\f%d", i);
3855 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3856 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3858 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3862 smbcli_close(cli->tree, fnum);
3864 for (i=0;i<torture_entries;i++) {
3866 asprintf(&fname, "\\LISTDIR\\d%d", i);
3867 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
3868 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3874 /* Now ensure that doing an old list sees both files and directories. */
3875 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3876 printf("num_seen = %d\n", num_seen );
3877 /* We should see (torture_entries) each of files & directories + . and .. */
3878 if (num_seen != (2*torture_entries)+2) {
3880 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3881 (2*torture_entries)+2, num_seen);
3885 /* Ensure if we have the "must have" bits we only see the
3888 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3889 printf("num_seen = %d\n", num_seen );
3890 if (num_seen != torture_entries+2) {
3892 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3893 torture_entries+2, num_seen);
3896 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3897 printf("num_seen = %d\n", num_seen );
3898 if (num_seen != torture_entries) {
3900 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3901 torture_entries, num_seen);
3904 /* Delete everything. */
3905 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3906 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3911 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3912 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3913 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3916 if (!torture_close_connection(cli)) {
3920 printf("finished dirtest1\n");
3927 simple test harness for playing with deny modes
3929 static BOOL run_deny3test(int dummy)
3931 struct smbcli_state *cli1, *cli2;
3935 printf("starting deny3 test\n");
3937 printf("Testing simple deny modes\n");
3939 if (!torture_open_connection(&cli1)) {
3942 if (!torture_open_connection(&cli2)) {
3946 fname = "\\deny_dos1.dat";
3948 smbcli_unlink(cli1->tree, fname);
3949 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3950 fnum2 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3951 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3952 if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
3953 smbcli_unlink(cli1->tree, fname);
3954 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3957 fname = "\\deny_dos2.dat";
3959 smbcli_unlink(cli1->tree, fname);
3960 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3961 fnum2 = smbcli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3962 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3963 if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
3964 smbcli_unlink(cli1->tree, fname);
3965 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3968 torture_close_connection(cli1);
3969 torture_close_connection(cli2);
3975 parse a //server/share type UNC name
3977 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3981 if (strncmp(unc_name, "//", 2)) {
3985 *hostname = strdup(&unc_name[2]);
3986 p = strchr_m(&(*hostname)[2],'/');
3991 *sharename = strdup(p+1);
3998 static void sigcont(void)
4002 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
4005 volatile pid_t *child_status;
4006 volatile BOOL *child_status_out;
4009 double start_time_limit = 10 + (torture_nprocs * 1.5);
4010 char **unc_list = NULL;
4012 int num_unc_names = 0;
4016 signal(SIGCONT, sigcont);
4018 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
4019 if (!child_status) {
4020 printf("Failed to setup shared memory\n");
4024 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
4025 if (!child_status_out) {
4026 printf("Failed to setup result status shared memory\n");
4030 p = lp_parm_string(-1, "torture", "unclist");
4032 unc_list = file_lines_load(p, &num_unc_names);
4033 if (!unc_list || num_unc_names <= 0) {
4034 printf("Failed to load unc names list from '%s'\n", p);
4039 for (i = 0; i < torture_nprocs; i++) {
4040 child_status[i] = 0;
4041 child_status_out[i] = True;
4046 for (i=0;i<torture_nprocs;i++) {
4050 char *hostname=NULL, *sharename;
4052 pid_t mypid = getpid();
4053 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4055 asprintf(&myname, "CLIENT%d", i);
4056 lp_set_cmdline("netbios name", myname);
4061 if (!parse_unc(unc_list[i % num_unc_names],
4062 &hostname, &sharename)) {
4063 printf("Failed to parse UNC name %s\n",
4064 unc_list[i % num_unc_names]);
4071 if (torture_open_connection_share(¤t_cli,
4076 } else if (torture_open_connection(¤t_cli)) {
4080 printf("pid %d failed to start\n", (int)getpid());
4086 child_status[i] = getpid();
4090 if (child_status[i]) {
4091 printf("Child %d failed to start!\n", i);
4092 child_status_out[i] = 1;
4096 child_status_out[i] = fn(current_cli, i);
4103 for (i=0;i<torture_nprocs;i++) {
4104 if (child_status[i]) synccount++;
4106 if (synccount == torture_nprocs) break;
4108 } while (end_timer() < start_time_limit);
4110 if (synccount != torture_nprocs) {
4111 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4116 printf("Starting %d clients\n", torture_nprocs);
4118 /* start the client load */
4120 for (i=0;i<torture_nprocs;i++) {
4121 child_status[i] = 0;
4125 printf("%d clients started\n", torture_nprocs);
4127 for (i=0;i<torture_nprocs;i++) {
4129 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4130 if (ret == -1 || WEXITSTATUS(status) != 0) {
4137 for (i=0;i<torture_nprocs;i++) {
4138 if (!child_status_out[i]) {
4145 #define FLAG_MULTIPROC 1
4153 {"BASE-FDPASS", run_fdpasstest, 0},
4154 {"BASE-LOCK1", run_locktest1, 0},
4155 {"BASE-LOCK2", run_locktest2, 0},
4156 {"BASE-LOCK3", run_locktest3, 0},
4157 {"BASE-LOCK4", run_locktest4, 0},
4158 {"BASE-LOCK5", run_locktest5, 0},
4159 {"BASE-LOCK6", run_locktest6, 0},
4160 {"BASE-LOCK7", run_locktest7, 0},
4161 {"BASE-UNLINK", run_unlinktest, 0},
4162 {"BASE-ATTR", run_attrtest, 0},
4163 {"BASE-TRANS2", run_trans2test, 0},
4164 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4165 {"BASE-DIR", run_dirtest, 0},
4166 {"BASE-DIR1", run_dirtest1, 0},
4167 {"BASE-DENY1", torture_denytest1, 0},
4168 {"BASE-DENY2", torture_denytest2, 0},
4169 {"BASE-TCON", run_tcon_test, 0},
4170 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4171 {"BASE-VUID", run_vuidtest, 0},
4172 {"BASE-RW1", run_readwritetest, 0},
4173 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4174 {"BASE-OPEN", run_opentest, 0},
4175 {"BASE-DENY3", run_deny3test, 0},
4176 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4177 {"BASE-XCOPY", run_xcopy, 0},
4178 {"BASE-RENAME", run_rename, 0},
4179 {"BASE-DELETE", run_deletetest, 0},
4180 {"BASE-PROPERTIES", run_properties, 0},
4181 {"BASE-MANGLE", torture_mangle, 0},
4182 {"BASE-OPENATTR", run_openattrtest, 0},
4183 {"BASE-CHARSET", torture_charset, 0},
4184 {"BASE-CHKPATH", torture_chkpath_test, 0},
4185 {"BASE-SECLEAK", torture_sec_leak, 0},
4187 /* benchmarking tests */
4188 {"BENCH-HOLDCON", torture_holdcon, 0},
4189 {"BENCH-NBENCH", torture_nbench, 0},
4190 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4193 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4194 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4195 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4196 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4197 {"RAW-SEARCH", torture_raw_search, 0},
4198 {"RAW-CLOSE", torture_raw_close, 0},
4199 {"RAW-OPEN", torture_raw_open, 0},
4200 {"RAW-MKDIR", torture_raw_mkdir, 0},
4201 {"RAW-OPLOCK", torture_raw_oplock, 0},
4202 {"RAW-NOTIFY", torture_raw_notify, 0},
4203 {"RAW-MUX", torture_raw_mux, 0},
4204 {"RAW-IOCTL", torture_raw_ioctl, 0},
4205 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4206 {"RAW-UNLINK", torture_raw_unlink, 0},
4207 {"RAW-READ", torture_raw_read, 0},
4208 {"RAW-WRITE", torture_raw_write, 0},
4209 {"RAW-LOCK", torture_raw_lock, 0},
4210 {"RAW-CONTEXT", torture_raw_context, 0},
4211 {"RAW-RENAME", torture_raw_rename, 0},
4212 {"RAW-SEEK", torture_raw_seek, 0},
4213 {"RAW-RAP", torture_raw_rap, 0},
4215 /* protocol scanners */
4216 {"SCAN-TRANS2", torture_trans2_scan, 0},
4217 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4218 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4219 {"SCAN-SMB", torture_smb_scan, 0},
4220 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4221 {"SCAN-UTABLE", torture_utable, 0},
4222 {"SCAN-CASETABLE", torture_casetable, 0},
4223 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4224 {"SCAN-IOCTL", torture_ioctl_test, 0},
4227 {"RPC-LSA", torture_rpc_lsa, 0},
4228 {"RPC-ECHO", torture_rpc_echo, 0},
4229 {"RPC-DFS", torture_rpc_dfs, 0},
4230 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4231 {"RPC-SAMR", torture_rpc_samr, 0},
4232 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4233 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4234 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4235 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4236 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4237 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4238 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4239 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4240 {"RPC-WINREG", torture_rpc_winreg, 0},
4241 {"RPC-MGMT", torture_rpc_mgmt, 0},
4242 {"RPC-SCANNER", torture_rpc_scanner, 0},
4243 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4244 {"RPC-MULTIBIND", torture_multi_bind, 0},
4245 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4247 /* local (no server) testers */
4248 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
4249 {"LOCAL-ICONV", torture_local_iconv, 0},
4250 {"LOCAL-TALLOC", torture_local_talloc, 0},
4253 {"LDAP-BASIC", torture_ldap_basic, 0},
4259 /****************************************************************************
4260 run a specified test or "ALL"
4261 ****************************************************************************/
4262 static BOOL run_test(const char *name)
4266 BOOL matched = False;
4268 if (strequal(name,"ALL")) {
4269 for (i=0;torture_ops[i].name;i++) {
4270 if (!run_test(torture_ops[i].name)) {
4277 for (i=0;torture_ops[i].name;i++) {
4278 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4281 printf("Running %s\n", torture_ops[i].name);
4282 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4284 t = torture_create_procs(torture_ops[i].fn, &result);
4287 printf("TEST %s FAILED!\n", torture_ops[i].name);
4292 if (!torture_ops[i].fn(0)) {
4294 printf("TEST %s FAILED!\n", torture_ops[i].name);
4298 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4303 printf("Unknown torture operation '%s'\n", name);
4310 static void parse_dns(const char *dns)
4312 char *userdn, *basedn, *secret;
4315 /* retrievieng the userdn */
4316 p = strchr_m(dns, '#');
4318 lp_set_cmdline("torture:ldap_userdn", "");
4319 lp_set_cmdline("torture:ldap_basedn", "");
4320 lp_set_cmdline("torture:ldap_secret", "");
4323 userdn = strndup(dns, p - dns);
4324 lp_set_cmdline("torture:ldap_userdn", userdn);
4326 /* retrieve the basedn */
4328 p = strchr_m(d, '#');
4330 lp_set_cmdline("torture:ldap_basedn", "");
4331 lp_set_cmdline("torture:ldap_secret", "");
4334 basedn = strndup(d, p - d);
4335 lp_set_cmdline("torture:ldap_basedn", basedn);
4337 /* retrieve the secret */
4340 lp_set_cmdline("torture:ldap_secret", "");
4344 lp_set_cmdline("torture:ldap_secret", secret);
4346 printf ("%s - %s - %s\n", userdn, basedn, secret);
4350 static void usage(poptContext pc)
4355 poptPrintUsage(pc, stdout, 0);
4358 printf("tests are:");
4359 for (i=0;torture_ops[i].name;i++) {
4360 if ((i%perline)==0) {
4363 printf("%s ", torture_ops[i].name);
4367 printf("default test is ALL\n");
4372 /****************************************************************************
4374 ****************************************************************************/
4375 int main(int argc,char *argv[])
4379 BOOL correct = True;
4383 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
4384 struct poptOption long_options[] = {
4386 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
4387 {"seed", 0, POPT_ARG_STRING, NULL, 0, "seed", NULL},
4388 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
4389 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
4390 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
4391 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
4392 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
4393 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
4394 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
4395 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
4396 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
4397 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
4398 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
4400 POPT_COMMON_CONNECTION
4401 POPT_COMMON_CREDENTIALS
4406 setup_logging("smbtorture", DEBUG_STDOUT);
4408 #ifdef HAVE_SETBUFFER
4409 setbuffer(stdout, NULL, 0);
4412 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
4413 POPT_CONTEXT_KEEP_FIRST);
4415 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
4417 while((opt = poptGetNextOpt(pc)) != -1) {
4420 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
4423 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
4426 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
4429 parse_dns(poptGetOptArg(pc));
4432 lp_set_cmdline("torture:dangerous", "1");
4435 d_printf("Invalid option %s: %s\n",
4436 poptBadOption(pc, 0), poptStrerror(opt));
4442 lp_load(dyn_CONFIGFILE,True,False,False);
4444 srandom(time(NULL));
4446 argv_new = (const char **)poptGetArgs(pc);
4449 for (i=0; i<argc; i++) {
4450 if (argv_new[i] == NULL) {
4461 for(p = argv_new[1]; *p; p++) {
4466 /* see if its a RPC transport specifier */
4467 if (strncmp(argv_new[1], "ncacn_", 6) == 0) {
4468 lp_set_cmdline("torture:binding", argv_new[1]);
4470 char *binding = NULL;
4471 char *host = NULL, *share = NULL;
4473 if (!parse_unc(argv_new[1], &host, &share)) {
4477 lp_set_cmdline("torture:host", host);
4478 lp_set_cmdline("torture:share", share);
4479 asprintf(&binding, "ncacn_np:%s", host);
4480 lp_set_cmdline("torture:binding", binding);
4483 if (!lp_parm_string(-1,"torture","username")) {
4484 lp_set_cmdline("torture:username", cmdline_get_username());
4486 if (!lp_parm_string(-1,"torture","userdomain")) {
4488 * backward compatibility
4489 * maybe we should remove this to make this consistent
4490 * for all cmdline tools
4493 if (strequal(lp_netbios_name(),cmdline_get_userdomain())) {
4494 cmdline_set_userdomain(lp_workgroup());
4496 lp_set_cmdline("torture:userdomain", cmdline_get_userdomain());
4498 if (!lp_parm_string(-1,"torture","password")) {
4499 lp_set_cmdline("torture:password", cmdline_get_userpassword());
4502 if (argc_new == 0) {
4503 printf("You must specify a test to run, or 'ALL'\n");
4505 for (i=2;i<argc_new;i++) {
4506 if (!run_test(argv_new[i])) {