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(NULL);
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(NULL,
100 username, username[0]?userdomain:"",
101 password, flags, &retry);
102 if (!NT_STATUS_IS_OK(status)) {
103 printf("Failed to open connection - %s\n", nt_errstr(status));
107 (*c)->transport->options.use_oplocks = use_oplocks;
108 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
109 (*c)->transport->socket->timeout = 120000;
114 BOOL torture_open_connection(struct smbcli_state **c)
116 const char *host = lp_parm_string(-1, "torture", "host");
117 const char *share = lp_parm_string(-1, "torture", "share");
119 return torture_open_connection_share(c, host, share);
124 BOOL torture_close_connection(struct smbcli_state *c)
128 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
129 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
137 /* open a rpc connection to the chosen binding string */
138 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
139 const char *pipe_name,
140 const char *pipe_uuid,
141 uint32_t pipe_version)
144 const char *binding = lp_parm_string(-1, "torture", "binding");
147 printf("You must specify a ncacn binding string\n");
148 return NT_STATUS_INVALID_PARAMETER;
151 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
152 lp_parm_string(-1, "torture", "userdomain"),
153 lp_parm_string(-1, "torture", "username"),
154 lp_parm_string(-1, "torture", "password"));
159 /* open a rpc connection to a specific transport */
160 NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
161 const char *pipe_name,
162 const char *pipe_uuid,
163 uint32_t pipe_version,
164 enum dcerpc_transport_t transport)
167 const char *binding = lp_parm_string(-1, "torture", "binding");
168 struct dcerpc_binding b;
169 TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb");
172 printf("You must specify a ncacn binding string\n");
173 return NT_STATUS_INVALID_PARAMETER;
176 status = dcerpc_parse_binding(mem_ctx, binding, &b);
177 if (!NT_STATUS_IS_OK(status)) {
178 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
179 talloc_destroy(mem_ctx);
183 b.transport = transport;
185 status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version,
186 lp_parm_string(-1, "torture", "userdomain"),
187 lp_parm_string(-1, "torture", "username"),
188 lp_parm_string(-1, "torture", "password"));
193 /* close a rpc connection to a named pipe */
194 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
196 dcerpc_pipe_close(p);
201 /* check if the server produced the expected error code */
202 static BOOL check_error(int line, struct smbcli_state *c,
203 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
205 if (smbcli_is_dos_error(c->tree)) {
209 /* Check DOS error */
211 smbcli_dos_error(c, &class, &num);
213 if (eclass != class || ecode != num) {
214 printf("unexpected error code class=%d code=%d\n",
215 (int)class, (int)num);
216 printf(" expected %d/%d %s (line=%d)\n",
217 (int)eclass, (int)ecode, nt_errstr(nterr), line);
226 status = smbcli_nt_error(c->tree);
228 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
229 printf("unexpected error code %s\n", nt_errstr(status));
230 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
239 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
241 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
242 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
248 static BOOL rw_torture(struct smbcli_state *c)
250 const char *lockfname = "\\torture.lck";
254 pid_t pid2, pid = getpid();
259 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
262 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
264 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
269 for (i=0;i<torture_numops;i++) {
270 uint_t n = (uint_t)sys_random()%10;
272 printf("%d\r", i); fflush(stdout);
274 asprintf(&fname, "\\torture.%u", n);
276 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
280 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
282 printf("open failed (%s)\n", smbcli_errstr(c->tree));
287 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
288 printf("write failed (%s)\n", smbcli_errstr(c->tree));
293 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
294 sizeof(pid)+(j*sizeof(buf)),
295 sizeof(buf)) != sizeof(buf)) {
296 printf("write failed (%s)\n", smbcli_errstr(c->tree));
303 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
304 printf("read failed (%s)\n", smbcli_errstr(c->tree));
309 printf("data corruption!\n");
313 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
314 printf("close failed (%s)\n", smbcli_errstr(c->tree));
318 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
319 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
323 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
324 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
330 smbcli_close(c->tree, fnum2);
331 smbcli_unlink(c->tree, lockfname);
338 static BOOL run_torture(struct smbcli_state *cli, int dummy)
342 ret = rw_torture(cli);
344 if (!torture_close_connection(cli)) {
351 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
358 uint_t countprev = 0;
363 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
365 SIVAL(buf, i, sys_random());
370 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
373 printf("first open read/write of %s failed (%s)\n",
374 lockfname, smbcli_errstr(c->tree));
380 for (i = 0; i < 500 && fnum == -1; i++)
382 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
387 printf("second open read-only of %s failed (%s)\n",
388 lockfname, smbcli_errstr(c->tree));
394 for (count = 0; count < sizeof(buf); count += sent)
396 if (count >= countprev) {
397 printf("%d %8d\r", i, count);
400 countprev += (sizeof(buf) / 20);
405 sent = ((uint_t)sys_random()%(20))+ 1;
406 if (sent > sizeof(buf) - count)
408 sent = sizeof(buf) - count;
411 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
412 printf("write failed (%s)\n", smbcli_errstr(c->tree));
418 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
422 printf("read failed offset:%d size:%d (%s)\n",
423 count, sizeof(buf)-count,
424 smbcli_errstr(c->tree));
430 if (memcmp(buf_rd+count, buf+count, sent) != 0)
432 printf("read/write compare failed\n");
433 printf("offset: %d req %d recvd %d\n",
434 count, sizeof(buf)-count, sent);
443 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
444 printf("close failed (%s)\n", smbcli_errstr(c->tree));
451 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
453 const char *lockfname = "\\torture2.lck";
458 uint8_t buf_rd[131072];
460 ssize_t bytes_read, bytes_written;
462 if (smbcli_deltree(c1->tree, lockfname) == -1) {
463 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
466 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
469 printf("first open read/write of %s failed (%s)\n",
470 lockfname, smbcli_errstr(c1->tree));
473 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
476 printf("second open read-only of %s failed (%s)\n",
477 lockfname, smbcli_errstr(c2->tree));
478 smbcli_close(c1->tree, fnum1);
482 printf("Checking data integrity over %d ops\n", torture_numops);
484 for (i=0;i<torture_numops;i++)
486 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
488 printf("%d\r", i); fflush(stdout);
491 generate_random_buffer(buf, buf_size);
493 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
494 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
495 printf("wrote %d, expected %d\n", bytes_written, buf_size);
500 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
501 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
502 printf("read %d, expected %d\n", bytes_read, buf_size);
507 if (memcmp(buf_rd, buf, buf_size) != 0)
509 printf("read/write compare failed\n");
515 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
516 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
519 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
520 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
524 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
525 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
532 static BOOL run_readwritetest(int dummy)
534 struct smbcli_state *cli1, *cli2;
535 BOOL test1, test2 = True;
537 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
541 printf("starting readwritetest\n");
543 test1 = rw_torture2(cli1, cli2);
544 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
547 test2 = rw_torture2(cli1, cli1);
548 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
551 if (!torture_close_connection(cli1)) {
555 if (!torture_close_connection(cli2)) {
559 return (test1 && test2);
562 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
566 test = rw_torture3(cli, "\\multitest.txt");
568 if (!torture_close_connection(cli)) {
577 This test checks for two things:
579 1) correct support for retaining locks over a close (ie. the server
580 must not use posix semantics)
581 2) support for lock timeouts
583 static BOOL run_locktest1(int dummy)
585 struct smbcli_state *cli1, *cli2;
586 const char *fname = "\\lockt1.lck";
587 int fnum1, fnum2, fnum3;
591 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
595 printf("starting locktest1\n");
597 smbcli_unlink(cli1->tree, fname);
599 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
601 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
604 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
606 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
609 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
611 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
615 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
616 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
621 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
622 printf("lock2 succeeded! This is a locking bug\n");
625 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
626 NT_STATUS_LOCK_NOT_GRANTED)) return False;
630 lock_timeout = (6 + (random() % 20));
631 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
633 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
634 printf("lock3 succeeded! This is a locking bug\n");
637 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
638 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
643 printf("error: This server appears not to support timed lock requests\n");
645 printf("server slept for %u seconds for a %u second timeout\n",
646 (uint_t)(t2-t1), lock_timeout);
648 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
649 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
653 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
654 printf("lock4 succeeded! This is a locking bug\n");
657 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
658 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
661 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
662 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
666 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
667 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
671 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
672 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
677 if (!torture_close_connection(cli1)) {
681 if (!torture_close_connection(cli2)) {
685 printf("Passed locktest1\n");
690 this checks to see if a secondary tconx can use open files from an
693 static BOOL run_tcon_test(int dummy)
695 struct smbcli_state *cli;
696 const char *fname = "\\tcontest.tmp";
698 uint16_t cnum1, cnum2, cnum3;
699 uint16_t vuid1, vuid2;
702 struct smbcli_tree *tree1;
703 const char *host = lp_parm_string(-1, "torture", "host");
704 const char *share = lp_parm_string(-1, "torture", "share");
705 const char *password = lp_parm_string(-1, "torture", "password");
707 if (!torture_open_connection(&cli)) {
711 printf("starting tcontest\n");
713 if (smbcli_deltree(cli->tree, fname) == -1) {
714 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
717 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
719 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
723 cnum1 = cli->tree->tid;
724 vuid1 = cli->session->vuid;
726 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
727 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
728 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
732 tree1 = cli->tree; /* save old tree connection */
733 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
734 printf("%s refused 2nd tree connect (%s)\n", host,
735 smbcli_errstr(cli->tree));
736 smbcli_shutdown(cli);
740 cnum2 = cli->tree->tid;
741 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
742 vuid2 = cli->session->vuid + 1;
744 /* try a write with the wrong tid */
745 cli->tree->tid = cnum2;
747 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
748 printf("* server allows write with wrong TID\n");
751 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
755 /* try a write with an invalid tid */
756 cli->tree->tid = cnum3;
758 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
759 printf("* server allows write with invalid TID\n");
762 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
765 /* try a write with an invalid vuid */
766 cli->session->vuid = vuid2;
767 cli->tree->tid = cnum1;
769 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
770 printf("* server allows write with invalid VUID\n");
773 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
776 cli->session->vuid = vuid1;
777 cli->tree->tid = cnum1;
779 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
780 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
784 cli->tree->tid = cnum2;
786 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
787 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
791 cli->tree = tree1; /* restore initial tree */
792 cli->tree->tid = cnum1;
794 if (!torture_close_connection(cli)) {
803 static BOOL tcon_devtest(struct smbcli_state *cli,
804 const char *myshare, const char *devtype,
805 NTSTATUS expected_error)
809 const char *password = lp_parm_string(-1, "torture", "password");
811 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
814 printf("Trying share %s with devtype %s\n", myshare, devtype);
816 if (NT_STATUS_IS_OK(expected_error)) {
820 printf("tconX to share %s with type %s "
821 "should have succeeded but failed\n",
828 printf("tconx to share %s with type %s "
829 "should have failed but succeeded\n",
833 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
837 printf("Returned unexpected error\n");
846 checks for correct tconX support
848 static BOOL run_tcon_devtype_test(int dummy)
850 struct smbcli_state *cli1 = NULL;
855 const char *host = lp_parm_string(-1, "torture", "host");
856 const char *share = lp_parm_string(-1, "torture", "share");
857 const char *username = lp_parm_string(-1, "torture", "username");
858 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
859 const char *password = lp_parm_string(-1, "torture", "password");
861 status = smbcli_full_connection(NULL,
862 &cli1, lp_netbios_name(),
865 username, userdomain,
866 password, flags, &retry);
868 if (!NT_STATUS_IS_OK(status)) {
869 printf("could not open connection\n");
873 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
876 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
879 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
882 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
885 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
888 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
891 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
894 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
897 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
900 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
903 smbcli_shutdown(cli1);
906 printf("Passed tcondevtest\n");
913 This test checks that
915 1) the server supports multiple locking contexts on the one SMB
916 connection, distinguished by PID.
918 2) the server correctly fails overlapping locks made by the same PID (this
919 goes against POSIX behaviour, which is why it is tricky to implement)
921 3) the server denies unlock requests by an incorrect client PID
923 static BOOL run_locktest2(int dummy)
925 struct smbcli_state *cli;
926 const char *fname = "\\lockt2.lck";
927 int fnum1, fnum2, fnum3;
930 if (!torture_open_connection(&cli)) {
934 printf("starting locktest2\n");
936 smbcli_unlink(cli->tree, fname);
938 printf("Testing pid context\n");
940 cli->session->pid = 1;
942 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
944 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
948 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
950 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
954 cli->session->pid = 2;
956 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
958 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
962 cli->session->pid = 1;
964 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
965 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
969 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
970 printf("WRITE lock1 succeeded! This is a locking bug\n");
973 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
974 NT_STATUS_LOCK_NOT_GRANTED)) return False;
977 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
978 printf("WRITE lock2 succeeded! This is a locking bug\n");
981 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
982 NT_STATUS_LOCK_NOT_GRANTED)) return False;
985 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
986 printf("READ lock2 succeeded! This is a locking bug\n");
989 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
990 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
993 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
994 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
997 cli->session->pid = 2;
999 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
1000 printf("unlock at 100 succeeded! This is a locking bug\n");
1004 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
1005 printf("unlock1 succeeded! This is a locking bug\n");
1008 if (!check_error(__LINE__, cli,
1010 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1013 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
1014 printf("unlock2 succeeded! This is a locking bug\n");
1017 if (!check_error(__LINE__, cli,
1019 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1022 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
1023 printf("lock3 succeeded! This is a locking bug\n");
1026 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1029 cli->session->pid = 1;
1031 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
1032 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1036 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1037 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1041 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1042 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1046 if (!torture_close_connection(cli)) {
1050 printf("locktest2 finished\n");
1057 This test checks that
1059 1) the server supports the full offset range in lock requests
1061 static BOOL run_locktest3(int dummy)
1063 struct smbcli_state *cli1, *cli2;
1064 const char *fname = "\\lockt3.lck";
1065 int fnum1, fnum2, i;
1067 BOOL correct = True;
1069 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1071 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1075 printf("starting locktest3\n");
1077 printf("Testing 32 bit offset ranges\n");
1079 smbcli_unlink(cli1->tree, fname);
1081 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1083 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1086 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1088 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1092 printf("Establishing %d locks\n", torture_numops);
1094 for (offset=i=0;i<torture_numops;i++) {
1096 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1097 printf("lock1 %d failed (%s)\n",
1099 smbcli_errstr(cli1->tree));
1103 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1104 printf("lock2 %d failed (%s)\n",
1106 smbcli_errstr(cli1->tree));
1111 printf("Testing %d locks\n", torture_numops);
1113 for (offset=i=0;i<torture_numops;i++) {
1116 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1117 printf("error: lock1 %d succeeded!\n", i);
1121 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1122 printf("error: lock2 %d succeeded!\n", i);
1126 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1127 printf("error: lock3 %d succeeded!\n", i);
1131 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1132 printf("error: lock4 %d succeeded!\n", i);
1137 printf("Removing %d locks\n", torture_numops);
1139 for (offset=i=0;i<torture_numops;i++) {
1142 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1143 printf("unlock1 %d failed (%s)\n",
1145 smbcli_errstr(cli1->tree));
1149 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1150 printf("unlock2 %d failed (%s)\n",
1152 smbcli_errstr(cli1->tree));
1157 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1158 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1162 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1163 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1167 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1168 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1172 if (!torture_close_connection(cli1)) {
1176 if (!torture_close_connection(cli2)) {
1180 printf("finished locktest3\n");
1185 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1186 printf("** "); correct = False; \
1190 looks at overlapping locks
1192 static BOOL run_locktest4(int dummy)
1194 struct smbcli_state *cli1, *cli2;
1195 const char *fname = "\\lockt4.lck";
1196 int fnum1, fnum2, f;
1199 BOOL correct = True;
1201 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1205 printf("starting locktest4\n");
1207 smbcli_unlink(cli1->tree, fname);
1209 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1210 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1212 memset(buf, 0, sizeof(buf));
1214 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1215 printf("Failed to create file\n");
1220 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1221 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1222 EXPECTED(ret, False);
1223 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1225 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1226 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1227 EXPECTED(ret, True);
1228 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1230 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1231 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1232 EXPECTED(ret, False);
1233 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1235 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1236 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1237 EXPECTED(ret, True);
1238 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1240 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1241 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1242 EXPECTED(ret, False);
1243 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1245 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1246 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1247 EXPECTED(ret, True);
1248 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1250 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1251 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1252 EXPECTED(ret, True);
1253 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1255 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1256 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1257 EXPECTED(ret, False);
1258 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1260 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1261 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1262 EXPECTED(ret, False);
1263 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1265 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1266 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1267 EXPECTED(ret, True);
1268 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1270 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1271 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1272 EXPECTED(ret, False);
1273 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1275 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1276 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1277 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1278 EXPECTED(ret, False);
1279 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1282 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1283 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1284 EXPECTED(ret, False);
1285 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1287 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1288 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1289 EXPECTED(ret, False);
1290 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1293 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1294 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1295 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1296 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1297 EXPECTED(ret, True);
1298 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1301 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1302 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1303 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1304 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1305 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1306 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1307 EXPECTED(ret, True);
1308 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1310 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1311 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1312 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1313 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1314 EXPECTED(ret, True);
1315 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1317 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1318 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1319 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1320 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1321 EXPECTED(ret, True);
1322 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1324 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1325 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1326 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1327 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1328 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1329 EXPECTED(ret, True);
1330 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1332 smbcli_close(cli1->tree, fnum1);
1333 smbcli_close(cli2->tree, fnum2);
1334 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1335 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1336 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1337 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1338 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1339 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1340 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1341 smbcli_close(cli1->tree, f);
1342 smbcli_close(cli1->tree, fnum1);
1343 EXPECTED(ret, True);
1344 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1347 smbcli_close(cli1->tree, fnum1);
1348 smbcli_close(cli2->tree, fnum2);
1349 smbcli_unlink(cli1->tree, fname);
1350 torture_close_connection(cli1);
1351 torture_close_connection(cli2);
1353 printf("finished locktest4\n");
1358 looks at lock upgrade/downgrade.
1360 static BOOL run_locktest5(int dummy)
1362 struct smbcli_state *cli1, *cli2;
1363 const char *fname = "\\lockt5.lck";
1364 int fnum1, fnum2, fnum3;
1367 BOOL correct = True;
1369 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1373 printf("starting locktest5\n");
1375 smbcli_unlink(cli1->tree, fname);
1377 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1378 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1379 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1381 memset(buf, 0, sizeof(buf));
1383 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1384 printf("Failed to create file\n");
1389 /* Check for NT bug... */
1390 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1391 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1392 smbcli_close(cli1->tree, fnum1);
1393 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1394 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1395 EXPECTED(ret, True);
1396 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1397 smbcli_close(cli1->tree, fnum1);
1398 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1399 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1401 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1402 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1403 EXPECTED(ret, True);
1404 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1406 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1407 EXPECTED(ret, False);
1409 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1411 /* Unlock the process 2 lock. */
1412 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1414 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1415 EXPECTED(ret, False);
1417 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1419 /* Unlock the process 1 fnum3 lock. */
1420 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1422 /* Stack 2 more locks here. */
1423 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1424 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1426 EXPECTED(ret, True);
1427 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1429 /* Unlock the first process lock, then check this was the WRITE lock that was
1432 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1433 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1435 EXPECTED(ret, True);
1436 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1438 /* Unlock the process 2 lock. */
1439 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1441 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1443 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1444 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1445 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1447 EXPECTED(ret, True);
1448 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1450 /* Ensure the next unlock fails. */
1451 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1452 EXPECTED(ret, False);
1453 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1455 /* Ensure connection 2 can get a write lock. */
1456 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1457 EXPECTED(ret, True);
1459 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1463 smbcli_close(cli1->tree, fnum1);
1464 smbcli_close(cli2->tree, fnum2);
1465 smbcli_unlink(cli1->tree, fname);
1466 if (!torture_close_connection(cli1)) {
1469 if (!torture_close_connection(cli2)) {
1473 printf("finished locktest5\n");
1479 tries the unusual lockingX locktype bits
1481 static BOOL run_locktest6(int dummy)
1483 struct smbcli_state *cli;
1484 const char *fname[1] = { "\\lock6.txt" };
1489 if (!torture_open_connection(&cli)) {
1493 printf("starting locktest6\n");
1496 printf("Testing %s\n", fname[i]);
1498 smbcli_unlink(cli->tree, fname[i]);
1500 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1501 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1502 smbcli_close(cli->tree, fnum);
1503 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1505 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1506 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1507 smbcli_close(cli->tree, fnum);
1508 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1510 smbcli_unlink(cli->tree, fname[i]);
1513 torture_close_connection(cli);
1515 printf("finished locktest6\n");
1519 static BOOL run_locktest7(int dummy)
1521 struct smbcli_state *cli1;
1522 const char *fname = "\\lockt7.lck";
1527 BOOL correct = False;
1529 if (!torture_open_connection(&cli1)) {
1533 printf("starting locktest7\n");
1535 smbcli_unlink(cli1->tree, fname);
1537 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1539 memset(buf, 0, sizeof(buf));
1541 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1542 printf("Failed to create file\n");
1546 cli1->session->pid = 1;
1548 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1549 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1552 printf("pid1 successfully locked range 130:4 for READ\n");
1555 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1556 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1559 printf("pid1 successfully read the range 130:4\n");
1562 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1563 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1564 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1565 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1569 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1573 cli1->session->pid = 2;
1575 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1576 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1578 printf("pid2 successfully read the range 130:4\n");
1581 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1582 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1583 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1584 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1588 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1592 cli1->session->pid = 1;
1593 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1595 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1596 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1599 printf("pid1 successfully locked range 130:4 for WRITE\n");
1602 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1603 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1606 printf("pid1 successfully read the range 130:4\n");
1609 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1610 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1613 printf("pid1 successfully wrote to the range 130:4\n");
1616 cli1->session->pid = 2;
1618 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1619 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1620 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1621 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1625 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1629 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1630 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1631 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1632 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1636 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1640 printf("Testing truncate of locked file.\n");
1642 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1645 printf("Unable to truncate locked file.\n");
1649 printf("Truncated locked file.\n");
1652 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1653 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1659 printf("Unable to truncate locked file. Size was %u\n", size);
1664 cli1->session->pid = 1;
1666 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1670 smbcli_close(cli1->tree, fnum1);
1671 smbcli_close(cli1->tree, fnum2);
1672 smbcli_unlink(cli1->tree, fname);
1673 torture_close_connection(cli1);
1675 printf("finished locktest7\n");
1680 test whether fnums and tids open on one VC are available on another (a major
1683 static BOOL run_fdpasstest(int dummy)
1685 struct smbcli_state *cli1, *cli2;
1686 const char *fname = "\\fdpass.tst";
1690 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1694 printf("starting fdpasstest\n");
1696 smbcli_unlink(cli1->tree, fname);
1698 printf("Opening a file on connection 1\n");
1700 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1702 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1706 printf("writing to file on connection 1\n");
1708 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1709 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1713 oldtid = cli2->tree->tid;
1714 cli2->session->vuid = cli1->session->vuid;
1715 cli2->tree->tid = cli1->tree->tid;
1716 cli2->session->pid = cli1->session->pid;
1718 printf("reading from file on connection 2\n");
1720 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1721 printf("read succeeded! nasty security hole [%s]\n",
1726 smbcli_close(cli1->tree, fnum1);
1727 smbcli_unlink(cli1->tree, fname);
1729 cli2->tree->tid = oldtid;
1731 torture_close_connection(cli1);
1732 torture_close_connection(cli2);
1734 printf("finished fdpasstest\n");
1740 This test checks that
1742 1) the server does not allow an unlink on a file that is open
1744 static BOOL run_unlinktest(int dummy)
1746 struct smbcli_state *cli;
1747 const char *fname = "\\unlink.tst";
1749 BOOL correct = True;
1751 if (!torture_open_connection(&cli)) {
1755 printf("starting unlink test\n");
1757 smbcli_unlink(cli->tree, fname);
1759 cli->session->pid = 1;
1761 printf("Opening a file\n");
1763 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1765 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1769 printf("Unlinking a open file\n");
1771 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1772 printf("error: server allowed unlink on an open file\n");
1775 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1776 NT_STATUS_SHARING_VIOLATION);
1779 smbcli_close(cli->tree, fnum);
1780 smbcli_unlink(cli->tree, fname);
1782 if (!torture_close_connection(cli)) {
1786 printf("unlink test finished\n");
1793 test the timing of deferred open requests
1795 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1797 const char *fname = "\\defer_open_test.dat";
1800 BOOL correct = True;
1803 printf("failed to connect\n");
1807 printf("Testing deferred open requests.\n");
1813 struct timeval tv_start, tv_end;
1814 GetTimeOfDay(&tv_start);
1815 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1816 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1817 NTCREATEX_DISP_OPEN_IF, 0, 0);
1821 GetTimeOfDay(&tv_end);
1822 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1823 /* Sharing violation errors need to be 1 second apart. */
1824 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1825 if (tdif < 500000 || tdif > 1500000) {
1826 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1827 tdif / (int64_t)1000000,
1828 tdif % (int64_t)1000000);
1831 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1834 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1838 printf("pid %u open %d\n", getpid(), i);
1842 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1843 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1849 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1850 /* All until the last unlink will fail with sharing violation. */
1851 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1852 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1857 printf("deferred test finished\n");
1858 if (!torture_close_connection(cli)) {
1865 test how many open files this server supports on the one socket
1867 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1869 #define MAXFID_TEMPLATE "\\maxfid.%d.%d"
1871 int fnums[0x11000], i;
1873 BOOL correct = True;
1876 printf("failed to connect\n");
1880 printf("Testing maximum number of open files\n");
1882 for (i=0; i<0x11000; i++) {
1883 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1884 if ((fnums[i] = smbcli_open(cli->tree, fname,
1885 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1887 printf("open of %s failed (%s)\n",
1888 fname, smbcli_errstr(cli->tree));
1889 printf("maximum fnum is %d\n", i);
1898 printf("cleaning up\n");
1900 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1901 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1902 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1904 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1905 printf("unlink of %s failed (%s)\n",
1906 fname, smbcli_errstr(cli->tree));
1914 printf("maxfid test finished\n");
1915 if (!torture_close_connection(cli)) {
1919 #undef MAXFID_TEMPLATE
1922 /* send smb negprot commands, not reading the response */
1923 static BOOL run_negprot_nowait(int dummy)
1926 struct smbcli_state *cli, *cli2;
1927 BOOL correct = True;
1929 printf("starting negprot nowait test\n");
1931 cli = open_nbt_connection();
1936 printf("Filling send buffer\n");
1938 for (i=0;i<10000;i++) {
1939 struct smbcli_request *req;
1940 time_t t1 = time(NULL);
1941 req = smb_negprot_send(cli->transport, PROTOCOL_NT1);
1942 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
1943 smbcli_transport_process(cli->transport);
1945 if (req->state == SMBCLI_REQUEST_ERROR) {
1946 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
1947 torture_close_connection(cli);
1950 if (req->state == SMBCLI_REQUEST_SEND) {
1956 printf("send buffer failed to fill\n");
1957 if (!torture_close_connection(cli)) {
1963 printf("send buffer filled after %d requests\n", i);
1965 printf("Opening secondary connection\n");
1966 if (!torture_open_connection(&cli2)) {
1970 if (!torture_close_connection(cli)) {
1974 if (!torture_close_connection(cli2)) {
1978 printf("finished negprot nowait test\n");
1985 This checks how the getatr calls works
1987 static BOOL run_attrtest(int dummy)
1989 struct smbcli_state *cli;
1992 const char *fname = "\\attrib123456789.tst";
1993 BOOL correct = True;
1995 printf("starting attrib test\n");
1997 if (!torture_open_connection(&cli)) {
2001 smbcli_unlink(cli->tree, fname);
2002 fnum = smbcli_open(cli->tree, fname,
2003 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2004 smbcli_close(cli->tree, fnum);
2006 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2007 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2011 printf("New file time is %s", ctime(&t));
2013 if (abs(t - time(NULL)) > 60*60*24*10) {
2014 printf("ERROR: SMBgetatr bug. time is %s",
2020 t2 = t-60*60*24; /* 1 day ago */
2022 printf("Setting file time to %s", ctime(&t2));
2024 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
2025 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
2029 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2030 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2034 printf("Retrieved file time as %s", ctime(&t));
2037 printf("ERROR: getatr/setatr bug. times are\n%s",
2039 printf("%s", ctime(&t2));
2043 smbcli_unlink(cli->tree, fname);
2045 if (!torture_close_connection(cli)) {
2049 printf("attrib test finished\n");
2056 This checks a couple of trans2 calls
2058 static BOOL run_trans2test(int dummy)
2060 struct smbcli_state *cli;
2063 time_t c_time, a_time, m_time, w_time, m_time2;
2064 const char *fname = "\\trans2.tst";
2065 const char *dname = "\\trans2";
2066 const char *fname2 = "\\trans2\\trans2.tst";
2068 BOOL correct = True;
2070 printf("starting trans2 test\n");
2072 if (!torture_open_connection(&cli)) {
2076 smbcli_unlink(cli->tree, fname);
2078 printf("Testing qfileinfo\n");
2080 fnum = smbcli_open(cli->tree, fname,
2081 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2082 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2084 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
2088 printf("Testing NAME_INFO\n");
2090 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
2091 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
2095 if (!pname || strcmp(pname, fname)) {
2096 printf("qfilename gave different name? [%s] [%s]\n",
2101 smbcli_close(cli->tree, fnum);
2102 smbcli_unlink(cli->tree, fname);
2104 fnum = smbcli_open(cli->tree, fname,
2105 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2107 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
2110 smbcli_close(cli->tree, fnum);
2112 printf("Checking for sticky create times\n");
2114 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2115 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
2118 if (c_time != m_time) {
2119 printf("create time=%s", ctime(&c_time));
2120 printf("modify time=%s", ctime(&m_time));
2121 printf("This system appears to have sticky create times\n");
2123 if (a_time % (60*60) == 0) {
2124 printf("access time=%s", ctime(&a_time));
2125 printf("This system appears to set a midnight access time\n");
2129 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2130 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2136 smbcli_unlink(cli->tree, fname);
2137 fnum = smbcli_open(cli->tree, fname,
2138 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2139 smbcli_close(cli->tree, fnum);
2140 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2141 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2144 if (w_time < 60*60*24*2) {
2145 printf("write time=%s", ctime(&w_time));
2146 printf("This system appears to set a initial 0 write time\n");
2151 smbcli_unlink(cli->tree, fname);
2154 /* check if the server updates the directory modification time
2155 when creating a new file */
2156 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
2157 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
2161 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2162 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2166 fnum = smbcli_open(cli->tree, fname2,
2167 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2168 smbcli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2169 smbcli_close(cli->tree, fnum);
2170 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2171 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2174 if (m_time2 == m_time) {
2175 printf("This system does not update directory modification times\n");
2179 smbcli_unlink(cli->tree, fname2);
2180 smbcli_rmdir(cli->tree, dname);
2182 if (!torture_close_connection(cli)) {
2186 printf("trans2 test finished\n");
2192 Test delete on close semantics.
2194 static BOOL run_deletetest(int dummy)
2196 struct smbcli_state *cli1;
2197 struct smbcli_state *cli2 = NULL;
2198 const char *fname = "\\delete.file";
2201 BOOL correct = True;
2203 printf("starting delete test\n");
2205 if (!torture_open_connection(&cli1)) {
2209 /* Test 1 - this should delete the file on close. */
2211 smbcli_setatr(cli1->tree, fname, 0, 0);
2212 smbcli_unlink(cli1->tree, fname);
2214 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2215 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2216 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2219 printf("[1] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2224 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2225 printf("[1] close failed (%s)\n", smbcli_errstr(cli1->tree));
2230 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2232 printf("[1] open of %s succeeded (should fail)\n", fname);
2237 printf("first delete on close test succeeded.\n");
2239 /* Test 2 - this should delete the file on close. */
2241 smbcli_setatr(cli1->tree, fname, 0, 0);
2242 smbcli_unlink(cli1->tree, fname);
2244 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2245 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2246 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2249 printf("[2] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2254 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2255 printf("[2] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2260 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2261 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2266 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2268 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2269 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2270 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2274 smbcli_unlink(cli1->tree, fname);
2276 printf("second delete on close test succeeded.\n");
2279 smbcli_setatr(cli1->tree, fname, 0, 0);
2280 smbcli_unlink(cli1->tree, fname);
2282 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2283 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2286 printf("[3] open - 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2291 /* This should fail with a sharing violation - open for delete is only compatible
2292 with SHARE_DELETE. */
2294 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2295 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2296 NTCREATEX_DISP_OPEN, 0, 0);
2299 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2304 /* This should succeed. */
2306 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2307 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2310 printf("[3] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2315 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2316 printf("[3] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2321 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2322 printf("[3] close 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2327 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2328 printf("[3] close 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2333 /* This should fail - file should no longer be there. */
2335 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2337 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2338 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2339 printf("[3] close failed (%s)\n", smbcli_errstr(cli1->tree));
2341 smbcli_unlink(cli1->tree, fname);
2345 printf("third delete on close test succeeded.\n");
2348 smbcli_setatr(cli1->tree, fname, 0, 0);
2349 smbcli_unlink(cli1->tree, fname);
2351 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2352 SA_RIGHT_FILE_READ_DATA |
2353 SA_RIGHT_FILE_WRITE_DATA |
2354 STD_RIGHT_DELETE_ACCESS,
2355 FILE_ATTRIBUTE_NORMAL,
2356 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2357 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2360 printf("[4] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2365 /* This should succeed. */
2366 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2367 FILE_ATTRIBUTE_NORMAL,
2368 NTCREATEX_SHARE_ACCESS_READ |
2369 NTCREATEX_SHARE_ACCESS_WRITE |
2370 NTCREATEX_SHARE_ACCESS_DELETE,
2371 NTCREATEX_DISP_OPEN, 0, 0);
2373 printf("[4] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2378 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2379 printf("[4] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2384 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2385 printf("[4] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2390 /* This should fail - no more opens once delete on close set. */
2391 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2392 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2393 NTCREATEX_DISP_OPEN, 0, 0);
2395 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2399 printf("fourth delete on close test succeeded.\n");
2401 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2402 printf("[4] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2408 smbcli_setatr(cli1->tree, fname, 0, 0);
2409 smbcli_unlink(cli1->tree, fname);
2411 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2413 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2418 /* This should fail - only allowed on NT opens with DELETE access. */
2420 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2421 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2426 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2427 printf("[5] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2432 printf("fifth delete on close test succeeded.\n");
2435 smbcli_setatr(cli1->tree, fname, 0, 0);
2436 smbcli_unlink(cli1->tree, fname);
2438 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2439 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2440 FILE_ATTRIBUTE_NORMAL,
2441 NTCREATEX_SHARE_ACCESS_READ |
2442 NTCREATEX_SHARE_ACCESS_WRITE |
2443 NTCREATEX_SHARE_ACCESS_DELETE,
2444 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2447 printf("[6] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2452 /* This should fail - only allowed on NT opens with DELETE access. */
2454 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2455 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2460 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2461 printf("[6] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2466 printf("sixth delete on close test succeeded.\n");
2469 smbcli_setatr(cli1->tree, fname, 0, 0);
2470 smbcli_unlink(cli1->tree, fname);
2472 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2473 SA_RIGHT_FILE_READ_DATA |
2474 SA_RIGHT_FILE_WRITE_DATA |
2475 STD_RIGHT_DELETE_ACCESS,
2476 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2479 printf("[7] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2484 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2485 printf("[7] setting delete_on_close on file failed !\n");
2490 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2491 printf("[7] unsetting delete_on_close on file failed !\n");
2496 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2497 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2502 /* This next open should succeed - we reset the flag. */
2504 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2506 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2511 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2512 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2517 printf("seventh delete on close test succeeded.\n");
2520 smbcli_setatr(cli1->tree, fname, 0, 0);
2521 smbcli_unlink(cli1->tree, fname);
2523 if (!torture_open_connection(&cli2)) {
2524 printf("[8] failed to open second connection.\n");
2529 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2530 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2531 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2534 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2539 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2540 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2541 NTCREATEX_DISP_OPEN, 0, 0);
2544 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2549 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2550 printf("[8] setting delete_on_close on file failed !\n");
2555 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2556 printf("[8] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2561 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
2562 printf("[8] close - 2 failed (%s)\n", smbcli_errstr(cli2->tree));
2567 /* This should fail.. */
2568 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2570 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2574 printf("eighth delete on close test succeeded.\n");
2576 /* This should fail - we need to set DELETE_ACCESS. */
2577 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2578 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2581 printf("[9] open of %s succeeded should have failed!\n", fname);
2586 printf("ninth delete on close test succeeded.\n");
2588 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2589 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2591 printf("[10] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2596 /* This should delete the file. */
2597 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2598 printf("[10] close failed (%s)\n", smbcli_errstr(cli1->tree));
2603 /* This should fail.. */
2604 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2606 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2610 printf("tenth delete on close test succeeded.\n");
2611 printf("finished delete test\n");
2614 /* FIXME: This will crash if we aborted before cli2 got
2615 * intialized, because these functions don't handle
2616 * uninitialized connections. */
2618 smbcli_close(cli1->tree, fnum1);
2619 smbcli_close(cli1->tree, fnum2);
2620 smbcli_setatr(cli1->tree, fname, 0, 0);
2621 smbcli_unlink(cli1->tree, fname);
2623 if (!torture_close_connection(cli1)) {
2626 if (!torture_close_connection(cli2)) {
2634 print out server properties
2636 static BOOL run_properties(int dummy)
2638 struct smbcli_state *cli;
2639 BOOL correct = True;
2641 printf("starting properties test\n");
2645 if (!torture_open_connection(&cli)) {
2649 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2651 if (!torture_close_connection(cli)) {
2660 /* FIRST_DESIRED_ACCESS 0xf019f */
2661 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2662 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2663 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2664 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2665 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2666 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2667 /* SECOND_DESIRED_ACCESS 0xe0080 */
2668 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2669 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2670 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2673 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2674 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2675 SA_RIGHT_FILE_READ_DATA|\
2676 WRITE_OWNER_ACCESS /* */
2680 Test ntcreate calls made by xcopy
2682 static BOOL run_xcopy(int dummy)
2684 struct smbcli_state *cli1;
2685 const char *fname = "\\test.txt";
2686 BOOL correct = True;
2689 printf("starting xcopy test\n");
2691 if (!torture_open_connection(&cli1)) {
2695 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2696 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2697 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2701 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2705 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
2706 SECOND_DESIRED_ACCESS, 0,
2707 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2710 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
2714 if (!torture_close_connection(cli1)) {
2722 Test rename on files open with share delete and no share delete.
2724 static BOOL run_rename(int dummy)
2726 struct smbcli_state *cli1;
2727 const char *fname = "\\test.txt";
2728 const char *fname1 = "\\test1.txt";
2729 BOOL correct = True;
2732 printf("starting rename test\n");
2734 if (!torture_open_connection(&cli1)) {
2738 smbcli_unlink(cli1->tree, fname);
2739 smbcli_unlink(cli1->tree, fname1);
2740 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2741 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2744 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2748 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2749 printf("First rename failed (this is correct) - %s\n", smbcli_errstr(cli1->tree));
2751 printf("First rename succeeded - this should have failed !\n");
2755 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2756 printf("close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2760 smbcli_unlink(cli1->tree, fname);
2761 smbcli_unlink(cli1->tree, fname1);
2762 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2763 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2766 printf("Second open failed - %s\n", smbcli_errstr(cli1->tree));
2770 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2771 printf("Second rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2774 printf("Second rename succeeded\n");
2777 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2778 printf("close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2782 smbcli_unlink(cli1->tree, fname);
2783 smbcli_unlink(cli1->tree, fname1);
2785 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2786 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2789 printf("Third open failed - %s\n", smbcli_errstr(cli1->tree));
2794 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2795 printf("Third rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2798 printf("Third rename succeeded\n");
2801 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2802 printf("close - 3 failed (%s)\n", smbcli_errstr(cli1->tree));
2806 smbcli_unlink(cli1->tree, fname);
2807 smbcli_unlink(cli1->tree, fname1);
2809 if (!torture_close_connection(cli1)) {
2818 see how many RPC pipes we can open at once
2820 static BOOL run_pipe_number(int dummy)
2822 struct smbcli_state *cli1;
2823 const char *pipe_name = "\\WKSSVC";
2827 printf("starting pipenumber test\n");
2828 if (!torture_open_connection(&cli1)) {
2833 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2834 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2837 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
2841 printf("%d\r", num_pipes);
2845 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2846 torture_close_connection(cli1);
2854 open N connections to the server and just hold them open
2855 used for testing performance when there are N idle users
2858 static BOOL torture_holdcon(int dummy)
2861 struct smbcli_state **cli;
2864 printf("Opening %d connections\n", torture_numops);
2866 cli = malloc(sizeof(struct smbcli_state *) * torture_numops);
2868 for (i=0;i<torture_numops;i++) {
2869 if (!torture_open_connection(&cli[i])) {
2872 printf("opened %d connections\r", i);
2876 printf("\nStarting pings\n");
2879 for (i=0;i<torture_numops;i++) {
2882 status = smbcli_chkpath(cli[i]->tree, "\\");
2883 if (!NT_STATUS_IS_OK(status)) {
2884 printf("Connection %d is dead\n", i);
2892 if (num_dead == torture_numops) {
2893 printf("All connections dead - finishing\n");
2905 Try with a wrong vuid and check error message.
2908 static BOOL run_vuidtest(int dummy)
2910 struct smbcli_state *cli;
2911 const char *fname = "\\vuid.tst";
2914 time_t c_time, a_time, m_time;
2915 BOOL correct = True;
2920 printf("starting vuid test\n");
2922 if (!torture_open_connection(&cli)) {
2926 smbcli_unlink(cli->tree, fname);
2928 fnum = smbcli_open(cli->tree, fname,
2929 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2931 orig_vuid = cli->session->vuid;
2933 cli->session->vuid += 1234;
2935 printf("Testing qfileinfo with wrong vuid\n");
2937 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
2938 &size, &c_time, &a_time,
2939 &m_time, NULL, NULL))) {
2940 printf("ERROR: qfileinfo passed with wrong vuid\n");
2944 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2945 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2946 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2947 printf("ERROR: qfileinfo should have returned DOS error "
2948 "ERRSRV:ERRbaduid\n but returned %s\n",
2949 smbcli_errstr(cli->tree));
2953 cli->session->vuid -= 1234;
2955 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
2956 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
2960 smbcli_unlink(cli->tree, fname);
2962 if (!torture_close_connection(cli)) {
2966 printf("vuid test finished\n");
2972 Test open mode returns on read-only files.
2974 static BOOL run_opentest(int dummy)
2976 static struct smbcli_state *cli1;
2977 static struct smbcli_state *cli2;
2978 const char *fname = "\\readonly.file";
2982 BOOL correct = True;
2986 printf("starting open test\n");
2988 if (!torture_open_connection(&cli1)) {
2992 smbcli_setatr(cli1->tree, fname, 0, 0);
2993 smbcli_unlink(cli1->tree, fname);
2995 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2997 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3001 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3002 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3006 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
3007 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
3008 CHECK_MAX_FAILURES(error_test1);
3012 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3014 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3015 CHECK_MAX_FAILURES(error_test1);
3019 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3020 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3022 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3023 NT_STATUS_ACCESS_DENIED)) {
3024 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3027 printf("finished open test 1\n");
3029 smbcli_close(cli1->tree, fnum1);
3031 /* Now try not readonly and ensure ERRbadshare is returned. */
3033 smbcli_setatr(cli1->tree, fname, 0, 0);
3035 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3037 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3041 /* This will fail - but the error should be ERRshare. */
3042 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3044 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3045 NT_STATUS_SHARING_VIOLATION)) {
3046 printf("correct error code ERRDOS/ERRbadshare returned\n");
3049 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3050 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3054 smbcli_unlink(cli1->tree, fname);
3056 printf("finished open test 2\n");
3058 /* Test truncate open disposition on file opened for read. */
3060 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3062 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3066 /* write 20 bytes. */
3068 memset(buf, '\0', 20);
3070 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3071 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
3075 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3076 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3080 /* Ensure size == 20. */
3081 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3082 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3083 CHECK_MAX_FAILURES(error_test3);
3088 printf("(3) file size != 20\n");
3089 CHECK_MAX_FAILURES(error_test3);
3093 /* Now test if we can truncate a file opened for readonly. */
3095 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3097 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3098 CHECK_MAX_FAILURES(error_test3);
3102 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3103 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3107 /* Ensure size == 0. */
3108 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3109 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3110 CHECK_MAX_FAILURES(error_test3);
3115 printf("(3) file size != 0\n");
3116 CHECK_MAX_FAILURES(error_test3);
3119 printf("finished open test 3\n");
3121 smbcli_unlink(cli1->tree, fname);
3124 printf("testing ctemp\n");
3125 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
3127 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
3128 CHECK_MAX_FAILURES(error_test4);
3131 printf("ctemp gave path %s\n", tmp_path);
3132 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3133 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3135 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
3136 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3139 /* Test the non-io opens... */
3141 if (!torture_open_connection(&cli2)) {
3145 smbcli_setatr(cli2->tree, fname, 0, 0);
3146 smbcli_unlink(cli2->tree, fname);
3148 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3150 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3151 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3154 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3155 CHECK_MAX_FAILURES(error_test10);
3159 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3160 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3162 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3163 CHECK_MAX_FAILURES(error_test10);
3167 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3168 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3171 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3172 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3176 printf("non-io open test #1 passed.\n");
3178 smbcli_unlink(cli1->tree, fname);
3180 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3182 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3183 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3186 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3187 CHECK_MAX_FAILURES(error_test20);
3191 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3192 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3195 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3196 CHECK_MAX_FAILURES(error_test20);
3200 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3201 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3204 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3205 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3209 printf("non-io open test #2 passed.\n");
3211 smbcli_unlink(cli1->tree, fname);
3213 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3215 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3216 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3219 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3220 CHECK_MAX_FAILURES(error_test30);
3224 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3225 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3228 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3229 CHECK_MAX_FAILURES(error_test30);
3233 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3234 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3237 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3238 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3242 printf("non-io open test #3 passed.\n");
3244 smbcli_unlink(cli1->tree, fname);
3246 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3248 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3249 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3252 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3253 CHECK_MAX_FAILURES(error_test40);
3257 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3258 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3261 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3262 CHECK_MAX_FAILURES(error_test40);
3266 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3268 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3269 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3273 printf("non-io open test #4 passed.\n");
3275 smbcli_unlink(cli1->tree, fname);
3277 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3279 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3280 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3283 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3284 CHECK_MAX_FAILURES(error_test50);
3288 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3289 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3292 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3293 CHECK_MAX_FAILURES(error_test50);
3297 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3298 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3302 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3303 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3307 printf("non-io open test #5 passed.\n");
3309 printf("TEST #6 testing 1 non-io open, one io open\n");
3311 smbcli_unlink(cli1->tree, fname);
3313 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3314 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3317 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3318 CHECK_MAX_FAILURES(error_test60);
3322 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3323 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3326 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3327 CHECK_MAX_FAILURES(error_test60);
3331 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3332 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3336 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3337 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3341 printf("non-io open test #6 passed.\n");
3343 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3345 smbcli_unlink(cli1->tree, fname);
3347 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3348 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3351 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3352 CHECK_MAX_FAILURES(error_test70);
3356 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3357 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3360 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3361 CHECK_MAX_FAILURES(error_test70);
3365 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3367 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3368 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3372 printf("non-io open test #7 passed.\n");
3376 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3378 smbcli_unlink(cli1->tree, fname);
3380 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3382 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3386 /* write 20 bytes. */
3388 memset(buf, '\0', 20);
3390 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3391 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
3395 /* Ensure size == 20. */
3396 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3397 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
3398 CHECK_MAX_FAILURES(error_test80);
3403 printf("(8) file size != 20\n");
3404 CHECK_MAX_FAILURES(error_test80);
3408 /* Get an exclusive lock on the open file. */
3409 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3410 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
3411 CHECK_MAX_FAILURES(error_test80);
3415 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3417 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3421 /* Ensure size == 0. */
3422 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3423 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
3424 CHECK_MAX_FAILURES(error_test80);
3429 printf("(8) file size != 0\n");
3430 CHECK_MAX_FAILURES(error_test80);
3434 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3435 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3439 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
3440 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3446 printf("open test #8 passed.\n");
3448 smbcli_unlink(cli1->tree, fname);
3450 if (!torture_close_connection(cli1)) {
3453 if (!torture_close_connection(cli2)) {
3461 static uint32_t open_attrs_table[] = {
3462 FILE_ATTRIBUTE_NORMAL,
3463 FILE_ATTRIBUTE_ARCHIVE,
3464 FILE_ATTRIBUTE_READONLY,
3465 FILE_ATTRIBUTE_HIDDEN,
3466 FILE_ATTRIBUTE_SYSTEM,
3468 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3469 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3470 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3471 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3472 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3473 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3475 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3476 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3477 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3478 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3481 struct trunc_open_results {
3484 uint32_t trunc_attr;
3485 uint32_t result_attr;
3488 static struct trunc_open_results attr_results[] = {
3489 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3490 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3491 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3492 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3493 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3494 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3495 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3496 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3497 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3498 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3499 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3500 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3501 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3502 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3503 { 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 },
3504 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3505 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3506 { 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 },
3507 { 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 },
3508 { 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 },
3509 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3510 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3511 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3512 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3513 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3514 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3517 static BOOL run_openattrtest(int dummy)
3519 struct smbcli_state *cli1;
3520 const char *fname = "\\openattr.file";
3522 BOOL correct = True;
3527 printf("starting open attr test\n");
3529 if (!torture_open_connection(&cli1)) {
3533 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3534 smbcli_setatr(cli1->tree, fname, 0, 0);
3535 smbcli_unlink(cli1->tree, fname);
3536 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3537 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3540 printf("open %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3544 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3545 printf("close %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3549 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3550 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
3551 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3552 open_attrs_table[j],
3553 NTCREATEX_SHARE_ACCESS_NONE,
3554 NTCREATEX_DISP_OVERWRITE, 0, 0);
3557 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3558 if (attr_results[l].num == k) {
3559 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3560 k, open_attrs_table[i],
3561 open_attrs_table[j],
3562 fname, NT_STATUS_V(smbcli_nt_error(cli1->tree)), smbcli_errstr(cli1->tree));
3564 CHECK_MAX_FAILURES(error_exit);
3567 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3568 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3569 k, open_attrs_table[i], open_attrs_table[j],
3570 smbcli_errstr(cli1->tree));
3572 CHECK_MAX_FAILURES(error_exit);
3575 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3581 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3582 printf("close %d (2) of %s failed (%s)\n", j, fname, smbcli_errstr(cli1->tree));
3586 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3587 printf("getatr(2) failed (%s)\n", smbcli_errstr(cli1->tree));
3592 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3593 k, open_attrs_table[i], open_attrs_table[j], attr );
3596 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3597 if (attr_results[l].num == k) {
3598 if (attr != attr_results[l].result_attr ||
3599 open_attrs_table[i] != attr_results[l].init_attr ||
3600 open_attrs_table[j] != attr_results[l].trunc_attr) {
3601 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3602 k, open_attrs_table[i],
3603 open_attrs_table[j],
3605 attr_results[l].result_attr);
3607 CHECK_MAX_FAILURES(error_exit);
3616 smbcli_setatr(cli1->tree, fname, 0, 0);
3617 smbcli_unlink(cli1->tree, fname);
3619 printf("open attr test %s.\n", correct ? "passed" : "failed");
3621 if (!torture_close_connection(cli1)) {
3627 static void list_fn(file_info *finfo, const char *name, void *state)
3633 test directory listing speed
3635 static BOOL run_dirtest(int dummy)
3638 struct smbcli_state *cli;
3641 BOOL correct = True;
3643 printf("starting directory test\n");
3645 if (!torture_open_connection(&cli)) {
3649 printf("Creating %d random filenames\n", torture_numops);
3652 for (i=0;i<torture_numops;i++) {
3654 asprintf(&fname, "\\%x", (int)random());
3655 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3657 fprintf(stderr,"Failed to open %s\n", fname);
3660 smbcli_close(cli->tree, fnum);
3666 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3667 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3668 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3670 printf("dirtest core %g seconds\n", end_timer() - t1);
3673 for (i=0;i<torture_numops;i++) {
3675 asprintf(&fname, "\\%x", (int)random());
3676 smbcli_unlink(cli->tree, fname);
3680 if (!torture_close_connection(cli)) {
3684 printf("finished dirtest\n");
3690 sees what IOCTLs are supported
3692 BOOL torture_ioctl_test(int dummy)
3694 struct smbcli_state *cli;
3695 uint16_t device, function;
3697 const char *fname = "\\ioctl.dat";
3699 union smb_ioctl parms;
3700 TALLOC_CTX *mem_ctx;
3702 if (!torture_open_connection(&cli)) {
3706 mem_ctx = talloc_init("ioctl_test");
3708 printf("starting ioctl test\n");
3710 smbcli_unlink(cli->tree, fname);
3712 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3714 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
3718 parms.ioctl.level = RAW_IOCTL_IOCTL;
3719 parms.ioctl.in.fnum = fnum;
3720 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3721 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3722 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
3724 for (device=0;device<0x100;device++) {
3725 printf("testing device=0x%x\n", device);
3726 for (function=0;function<0x100;function++) {
3727 parms.ioctl.in.request = (device << 16) | function;
3728 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3730 if (NT_STATUS_IS_OK(status)) {
3731 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3732 device, function, parms.ioctl.out.blob.length);
3737 if (!torture_close_connection(cli)) {
3746 tries variants of chkpath
3748 BOOL torture_chkpath_test(int dummy)
3750 struct smbcli_state *cli;
3754 if (!torture_open_connection(&cli)) {
3758 printf("starting chkpath test\n");
3760 printf("Testing valid and invalid paths\n");
3762 /* cleanup from an old run */
3763 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3764 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3765 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3767 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
3768 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
3772 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3773 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
3777 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3779 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
3782 smbcli_close(cli->tree, fnum);
3784 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
3785 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
3789 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3790 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
3794 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3795 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3796 NT_STATUS_NOT_A_DIRECTORY);
3798 printf("* chkpath on a file should fail\n");
3802 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3803 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3804 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3806 printf("* chkpath on a non existent file should fail\n");
3810 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3811 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3812 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3814 printf("* chkpath on a non existent component should fail\n");
3818 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3819 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3820 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3822 if (!torture_close_connection(cli)) {
3829 static BOOL run_dirtest1(int dummy)
3832 struct smbcli_state *cli;
3834 BOOL correct = True;
3836 printf("starting directory test\n");
3838 if (!torture_open_connection(&cli)) {
3842 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3843 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3846 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\LISTDIR"))) {
3847 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3851 printf("Creating %d files\n", torture_entries);
3853 /* Create torture_entries files and torture_entries directories. */
3854 for (i=0;i<torture_entries;i++) {
3856 asprintf(&fname, "\\LISTDIR\\f%d", i);
3857 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3858 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3860 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3864 smbcli_close(cli->tree, fnum);
3866 for (i=0;i<torture_entries;i++) {
3868 asprintf(&fname, "\\LISTDIR\\d%d", i);
3869 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
3870 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3876 /* Now ensure that doing an old list sees both files and directories. */
3877 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3878 printf("num_seen = %d\n", num_seen );
3879 /* We should see (torture_entries) each of files & directories + . and .. */
3880 if (num_seen != (2*torture_entries)+2) {
3882 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3883 (2*torture_entries)+2, num_seen);
3887 /* Ensure if we have the "must have" bits we only see the
3890 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3891 printf("num_seen = %d\n", num_seen );
3892 if (num_seen != torture_entries+2) {
3894 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3895 torture_entries+2, num_seen);
3898 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3899 printf("num_seen = %d\n", num_seen );
3900 if (num_seen != torture_entries) {
3902 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3903 torture_entries, num_seen);
3906 /* Delete everything. */
3907 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3908 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3913 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3914 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3915 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3918 if (!torture_close_connection(cli)) {
3922 printf("finished dirtest1\n");
3929 simple test harness for playing with deny modes
3931 static BOOL run_deny3test(int dummy)
3933 struct smbcli_state *cli1, *cli2;
3937 printf("starting deny3 test\n");
3939 printf("Testing simple deny modes\n");
3941 if (!torture_open_connection(&cli1)) {
3944 if (!torture_open_connection(&cli2)) {
3948 fname = "\\deny_dos1.dat";
3950 smbcli_unlink(cli1->tree, fname);
3951 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3952 fnum2 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3953 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3954 if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
3955 smbcli_unlink(cli1->tree, fname);
3956 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3959 fname = "\\deny_dos2.dat";
3961 smbcli_unlink(cli1->tree, fname);
3962 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3963 fnum2 = smbcli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3964 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3965 if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
3966 smbcli_unlink(cli1->tree, fname);
3967 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3970 torture_close_connection(cli1);
3971 torture_close_connection(cli2);
3977 parse a //server/share type UNC name
3979 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3983 if (strncmp(unc_name, "//", 2)) {
3987 *hostname = strdup(&unc_name[2]);
3988 p = strchr_m(&(*hostname)[2],'/');
3993 *sharename = strdup(p+1);
4000 static void sigcont(void)
4004 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
4007 volatile pid_t *child_status;
4008 volatile BOOL *child_status_out;
4011 double start_time_limit = 10 + (torture_nprocs * 1.5);
4012 char **unc_list = NULL;
4014 int num_unc_names = 0;
4018 signal(SIGCONT, sigcont);
4020 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
4021 if (!child_status) {
4022 printf("Failed to setup shared memory\n");
4026 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
4027 if (!child_status_out) {
4028 printf("Failed to setup result status shared memory\n");
4032 p = lp_parm_string(-1, "torture", "unclist");
4034 unc_list = file_lines_load(p, &num_unc_names);
4035 if (!unc_list || num_unc_names <= 0) {
4036 printf("Failed to load unc names list from '%s'\n", p);
4041 for (i = 0; i < torture_nprocs; i++) {
4042 child_status[i] = 0;
4043 child_status_out[i] = True;
4048 for (i=0;i<torture_nprocs;i++) {
4052 char *hostname=NULL, *sharename;
4054 pid_t mypid = getpid();
4055 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4057 asprintf(&myname, "CLIENT%d", i);
4058 lp_set_cmdline("netbios name", myname);
4063 if (!parse_unc(unc_list[i % num_unc_names],
4064 &hostname, &sharename)) {
4065 printf("Failed to parse UNC name %s\n",
4066 unc_list[i % num_unc_names]);
4073 if (torture_open_connection_share(¤t_cli,
4078 } else if (torture_open_connection(¤t_cli)) {
4082 printf("pid %d failed to start\n", (int)getpid());
4088 child_status[i] = getpid();
4092 if (child_status[i]) {
4093 printf("Child %d failed to start!\n", i);
4094 child_status_out[i] = 1;
4098 child_status_out[i] = fn(current_cli, i);
4105 for (i=0;i<torture_nprocs;i++) {
4106 if (child_status[i]) synccount++;
4108 if (synccount == torture_nprocs) break;
4110 } while (end_timer() < start_time_limit);
4112 if (synccount != torture_nprocs) {
4113 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4118 printf("Starting %d clients\n", torture_nprocs);
4120 /* start the client load */
4122 for (i=0;i<torture_nprocs;i++) {
4123 child_status[i] = 0;
4127 printf("%d clients started\n", torture_nprocs);
4129 for (i=0;i<torture_nprocs;i++) {
4131 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4132 if (ret == -1 || WEXITSTATUS(status) != 0) {
4139 for (i=0;i<torture_nprocs;i++) {
4140 if (!child_status_out[i]) {
4147 #define FLAG_MULTIPROC 1
4155 {"BASE-FDPASS", run_fdpasstest, 0},
4156 {"BASE-LOCK1", run_locktest1, 0},
4157 {"BASE-LOCK2", run_locktest2, 0},
4158 {"BASE-LOCK3", run_locktest3, 0},
4159 {"BASE-LOCK4", run_locktest4, 0},
4160 {"BASE-LOCK5", run_locktest5, 0},
4161 {"BASE-LOCK6", run_locktest6, 0},
4162 {"BASE-LOCK7", run_locktest7, 0},
4163 {"BASE-UNLINK", run_unlinktest, 0},
4164 {"BASE-ATTR", run_attrtest, 0},
4165 {"BASE-TRANS2", run_trans2test, 0},
4166 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4167 {"BASE-DIR", run_dirtest, 0},
4168 {"BASE-DIR1", run_dirtest1, 0},
4169 {"BASE-DENY1", torture_denytest1, 0},
4170 {"BASE-DENY2", torture_denytest2, 0},
4171 {"BASE-TCON", run_tcon_test, 0},
4172 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4173 {"BASE-VUID", run_vuidtest, 0},
4174 {"BASE-RW1", run_readwritetest, 0},
4175 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4176 {"BASE-OPEN", run_opentest, 0},
4177 {"BASE-DENY3", run_deny3test, 0},
4178 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4179 {"BASE-XCOPY", run_xcopy, 0},
4180 {"BASE-RENAME", run_rename, 0},
4181 {"BASE-DELETE", run_deletetest, 0},
4182 {"BASE-PROPERTIES", run_properties, 0},
4183 {"BASE-MANGLE", torture_mangle, 0},
4184 {"BASE-OPENATTR", run_openattrtest, 0},
4185 {"BASE-CHARSET", torture_charset, 0},
4186 {"BASE-CHKPATH", torture_chkpath_test, 0},
4187 {"BASE-SECLEAK", torture_sec_leak, 0},
4189 /* benchmarking tests */
4190 {"BENCH-HOLDCON", torture_holdcon, 0},
4191 {"BENCH-NBENCH", torture_nbench, 0},
4192 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4195 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4196 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4197 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4198 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4199 {"RAW-SEARCH", torture_raw_search, 0},
4200 {"RAW-CLOSE", torture_raw_close, 0},
4201 {"RAW-OPEN", torture_raw_open, 0},
4202 {"RAW-MKDIR", torture_raw_mkdir, 0},
4203 {"RAW-OPLOCK", torture_raw_oplock, 0},
4204 {"RAW-NOTIFY", torture_raw_notify, 0},
4205 {"RAW-MUX", torture_raw_mux, 0},
4206 {"RAW-IOCTL", torture_raw_ioctl, 0},
4207 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4208 {"RAW-UNLINK", torture_raw_unlink, 0},
4209 {"RAW-READ", torture_raw_read, 0},
4210 {"RAW-WRITE", torture_raw_write, 0},
4211 {"RAW-LOCK", torture_raw_lock, 0},
4212 {"RAW-CONTEXT", torture_raw_context, 0},
4213 {"RAW-RENAME", torture_raw_rename, 0},
4214 {"RAW-SEEK", torture_raw_seek, 0},
4215 {"RAW-RAP", torture_raw_rap, 0},
4217 /* protocol scanners */
4218 {"SCAN-TRANS2", torture_trans2_scan, 0},
4219 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4220 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4221 {"SCAN-SMB", torture_smb_scan, 0},
4222 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4223 {"SCAN-UTABLE", torture_utable, 0},
4224 {"SCAN-CASETABLE", torture_casetable, 0},
4225 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4226 {"SCAN-IOCTL", torture_ioctl_test, 0},
4229 {"RPC-LSA", torture_rpc_lsa, 0},
4230 {"RPC-ECHO", torture_rpc_echo, 0},
4231 {"RPC-DFS", torture_rpc_dfs, 0},
4232 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4233 {"RPC-SAMR", torture_rpc_samr, 0},
4234 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4235 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4236 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4237 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4238 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4239 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4240 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4241 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4242 {"RPC-WINREG", torture_rpc_winreg, 0},
4243 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
4244 {"RPC-MGMT", torture_rpc_mgmt, 0},
4245 {"RPC-SCANNER", torture_rpc_scanner, 0},
4246 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4247 {"RPC-MULTIBIND", torture_multi_bind, 0},
4248 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4250 /* local (no server) testers */
4251 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
4252 {"LOCAL-ICONV", torture_local_iconv, 0},
4253 {"LOCAL-TALLOC", torture_local_talloc, 0},
4256 {"LDAP-BASIC", torture_ldap_basic, 0},
4262 /****************************************************************************
4263 run a specified test or "ALL"
4264 ****************************************************************************/
4265 static BOOL run_test(const char *name)
4269 BOOL matched = False;
4271 if (strequal(name,"ALL")) {
4272 for (i=0;torture_ops[i].name;i++) {
4273 if (!run_test(torture_ops[i].name)) {
4280 for (i=0;torture_ops[i].name;i++) {
4281 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4285 printf("Running %s\n", torture_ops[i].name);
4286 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4288 t = torture_create_procs(torture_ops[i].fn, &result);
4291 printf("TEST %s FAILED!\n", torture_ops[i].name);
4296 if (!torture_ops[i].fn(0)) {
4298 printf("TEST %s FAILED!\n", torture_ops[i].name);
4302 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4307 printf("Unknown torture operation '%s'\n", name);
4314 static void parse_dns(const char *dns)
4316 char *userdn, *basedn, *secret;
4319 /* retrievieng the userdn */
4320 p = strchr_m(dns, '#');
4322 lp_set_cmdline("torture:ldap_userdn", "");
4323 lp_set_cmdline("torture:ldap_basedn", "");
4324 lp_set_cmdline("torture:ldap_secret", "");
4327 userdn = strndup(dns, p - dns);
4328 lp_set_cmdline("torture:ldap_userdn", userdn);
4330 /* retrieve the basedn */
4332 p = strchr_m(d, '#');
4334 lp_set_cmdline("torture:ldap_basedn", "");
4335 lp_set_cmdline("torture:ldap_secret", "");
4338 basedn = strndup(d, p - d);
4339 lp_set_cmdline("torture:ldap_basedn", basedn);
4341 /* retrieve the secret */
4344 lp_set_cmdline("torture:ldap_secret", "");
4348 lp_set_cmdline("torture:ldap_secret", secret);
4350 printf ("%s - %s - %s\n", userdn, basedn, secret);
4354 static void usage(poptContext pc)
4359 poptPrintUsage(pc, stdout, 0);
4362 printf("tests are:");
4363 for (i=0;torture_ops[i].name;i++) {
4364 if ((i%perline)==0) {
4367 printf("%s ", torture_ops[i].name);
4371 printf("default test is ALL\n");
4376 /****************************************************************************
4378 ****************************************************************************/
4379 int main(int argc,char *argv[])
4383 BOOL correct = True;
4387 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
4388 struct poptOption long_options[] = {
4390 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
4391 {"seed", 0, POPT_ARG_STRING, NULL, 0, "seed", NULL},
4392 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
4393 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
4394 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
4395 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
4396 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
4397 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
4398 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
4399 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
4400 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
4401 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
4402 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
4404 POPT_COMMON_CONNECTION
4405 POPT_COMMON_CREDENTIALS
4410 setup_logging("smbtorture", DEBUG_STDOUT);
4412 #ifdef HAVE_SETBUFFER
4413 setbuffer(stdout, NULL, 0);
4416 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
4417 POPT_CONTEXT_KEEP_FIRST);
4419 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
4421 while((opt = poptGetNextOpt(pc)) != -1) {
4424 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
4427 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
4430 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
4433 parse_dns(poptGetOptArg(pc));
4436 lp_set_cmdline("torture:dangerous", "1");
4439 d_printf("Invalid option %s: %s\n",
4440 poptBadOption(pc, 0), poptStrerror(opt));
4446 lp_load(dyn_CONFIGFILE,True,False,False);
4448 srandom(time(NULL));
4450 argv_new = (const char **)poptGetArgs(pc);
4453 for (i=0; i<argc; i++) {
4454 if (argv_new[i] == NULL) {
4465 for(p = argv_new[1]; *p; p++) {
4470 /* see if its a RPC transport specifier */
4471 if (strncmp(argv_new[1], "ncacn_", 6) == 0) {
4472 lp_set_cmdline("torture:binding", argv_new[1]);
4474 char *binding = NULL;
4475 char *host = NULL, *share = NULL;
4477 if (!parse_unc(argv_new[1], &host, &share)) {
4481 lp_set_cmdline("torture:host", host);
4482 lp_set_cmdline("torture:share", share);
4483 asprintf(&binding, "ncacn_np:%s", host);
4484 lp_set_cmdline("torture:binding", binding);
4487 if (!lp_parm_string(-1,"torture","username")) {
4488 lp_set_cmdline("torture:username", cmdline_get_username());
4490 if (!lp_parm_string(-1,"torture","userdomain")) {
4492 * backward compatibility
4493 * maybe we should remove this to make this consistent
4494 * for all cmdline tools
4497 if (strequal(lp_netbios_name(),cmdline_get_userdomain())) {
4498 cmdline_set_userdomain(lp_workgroup());
4500 lp_set_cmdline("torture:userdomain", cmdline_get_userdomain());
4502 if (!lp_parm_string(-1,"torture","password")) {
4503 lp_set_cmdline("torture:password", cmdline_get_userpassword());
4506 if (argc_new == 0) {
4507 printf("You must specify a test to run, or 'ALL'\n");
4509 for (i=2;i<argc_new;i++) {
4510 if (!run_test(argv_new[i])) {