2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 int torture_numops=100;
25 int torture_entries=1000;
26 int torture_failures=1;
27 static int procnum; /* records process count number when forking */
28 static struct smbcli_state *current_cli;
29 static BOOL use_oplocks;
30 static BOOL use_level_II_oplocks;
31 static BOOL use_kerberos;
33 BOOL torture_showall = False;
35 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
37 static struct smbcli_state *open_nbt_connection(void)
39 struct nmb_name called, calling;
40 struct smbcli_state *cli;
41 const char *host = lp_parm_string(-1, "torture", "host");
43 make_nmb_name(&calling, lp_netbios_name(), 0x0);
44 choose_called_name(&called, host, 0x20);
46 cli = smbcli_state_init();
48 printf("Failed initialize smbcli_struct to connect with %s\n", host);
52 if (!smbcli_socket_connect(cli, host)) {
53 printf("Failed to connect with %s\n", host);
57 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
59 if (!smbcli_transport_establish(cli, &calling, &called)) {
61 * Well, that failed, try *SMBSERVER ...
62 * However, we must reconnect as well ...
64 if (!smbcli_socket_connect(cli, host)) {
65 printf("Failed to connect with %s\n", host);
69 make_nmb_name(&called, "*SMBSERVER", 0x20);
70 if (!smbcli_transport_establish(cli, &calling, &called)) {
71 printf("%s rejected the session\n",host);
72 printf("We tried with a called name of %s & %s\n",
82 BOOL torture_open_connection_share(struct smbcli_state **c,
84 const char *sharename)
89 const char *username = lp_parm_string(-1, "torture", "username");
90 const char *password = lp_parm_string(-1, "torture", "password");
93 flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS;
95 status = smbcli_full_connection(c, lp_netbios_name(),
98 username, username[0]?lp_workgroup():"",
99 password, flags, &retry);
100 if (!NT_STATUS_IS_OK(status)) {
101 printf("Failed to open connection - %s\n", nt_errstr(status));
105 (*c)->transport->options.use_oplocks = use_oplocks;
106 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
107 (*c)->transport->socket->timeout = 120000;
112 BOOL torture_open_connection(struct smbcli_state **c)
114 const char *host = lp_parm_string(-1, "torture", "host");
115 const char *share = lp_parm_string(-1, "torture", "share");
117 return torture_open_connection_share(c, host, share);
122 BOOL torture_close_connection(struct smbcli_state *c)
125 DEBUG(9,("torture_close_connection: smbcli_state@%p\n", c));
127 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
128 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
131 DEBUG(9,("torture_close_connection: call smbcli_shutdown\n"));
133 DEBUG(9,("torture_close_connection: exit\n"));
138 /* open a rpc connection to a named pipe */
139 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
140 const char *pipe_name,
141 const char *pipe_uuid,
142 uint32_t pipe_version)
145 const char *binding = lp_parm_string(-1, "torture", "binding");
148 printf("You must specify a ncacn binding string\n");
149 return NT_STATUS_INVALID_PARAMETER;
152 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
154 lp_parm_string(-1, "torture", "username"),
155 lp_parm_string(-1, "torture", "password"));
160 /* close a rpc connection to a named pipe */
161 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
163 dcerpc_pipe_close(p);
168 /* check if the server produced the expected error code */
169 static BOOL check_error(int line, struct smbcli_state *c,
170 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
172 if (smbcli_is_dos_error(c->tree)) {
176 /* Check DOS error */
178 smbcli_dos_error(c, &class, &num);
180 if (eclass != class || ecode != num) {
181 printf("unexpected error code class=%d code=%d\n",
182 (int)class, (int)num);
183 printf(" expected %d/%d %s (line=%d)\n",
184 (int)eclass, (int)ecode, nt_errstr(nterr), line);
193 status = smbcli_nt_error(c->tree);
195 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
196 printf("unexpected error code %s\n", nt_errstr(status));
197 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
206 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
208 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
209 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
215 static BOOL rw_torture(struct smbcli_state *c)
217 const char *lockfname = "\\torture.lck";
221 pid_t pid2, pid = getpid();
226 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
229 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
231 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
236 for (i=0;i<torture_numops;i++) {
237 uint_t n = (uint_t)sys_random()%10;
239 printf("%d\r", i); fflush(stdout);
241 asprintf(&fname, "\\torture.%u", n);
243 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
247 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
249 printf("open failed (%s)\n", smbcli_errstr(c->tree));
254 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
255 printf("write failed (%s)\n", smbcli_errstr(c->tree));
260 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
261 sizeof(pid)+(j*sizeof(buf)),
262 sizeof(buf)) != sizeof(buf)) {
263 printf("write failed (%s)\n", smbcli_errstr(c->tree));
270 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
271 printf("read failed (%s)\n", smbcli_errstr(c->tree));
276 printf("data corruption!\n");
280 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
281 printf("close failed (%s)\n", smbcli_errstr(c->tree));
285 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
286 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
290 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
291 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
297 smbcli_close(c->tree, fnum2);
298 smbcli_unlink(c->tree, lockfname);
305 static BOOL run_torture(struct smbcli_state *cli, int dummy)
309 ret = rw_torture(cli);
311 if (!torture_close_connection(cli)) {
318 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
325 uint_t countprev = 0;
330 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
332 SIVAL(buf, i, sys_random());
337 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
340 printf("first open read/write of %s failed (%s)\n",
341 lockfname, smbcli_errstr(c->tree));
347 for (i = 0; i < 500 && fnum == -1; i++)
349 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
354 printf("second open read-only of %s failed (%s)\n",
355 lockfname, smbcli_errstr(c->tree));
361 for (count = 0; count < sizeof(buf); count += sent)
363 if (count >= countprev) {
364 printf("%d %8d\r", i, count);
367 countprev += (sizeof(buf) / 20);
372 sent = ((uint_t)sys_random()%(20))+ 1;
373 if (sent > sizeof(buf) - count)
375 sent = sizeof(buf) - count;
378 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
379 printf("write failed (%s)\n", smbcli_errstr(c->tree));
385 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
389 printf("read failed offset:%d size:%d (%s)\n",
390 count, sizeof(buf)-count,
391 smbcli_errstr(c->tree));
397 if (memcmp(buf_rd+count, buf+count, sent) != 0)
399 printf("read/write compare failed\n");
400 printf("offset: %d req %d recvd %d\n",
401 count, sizeof(buf)-count, sent);
410 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
411 printf("close failed (%s)\n", smbcli_errstr(c->tree));
418 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
420 const char *lockfname = "\\torture2.lck";
425 uint8_t buf_rd[131072];
427 ssize_t bytes_read, bytes_written;
429 if (smbcli_deltree(c1->tree, lockfname) == -1) {
430 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
433 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
436 printf("first open read/write of %s failed (%s)\n",
437 lockfname, smbcli_errstr(c1->tree));
440 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
443 printf("second open read-only of %s failed (%s)\n",
444 lockfname, smbcli_errstr(c2->tree));
445 smbcli_close(c1->tree, fnum1);
449 printf("Checking data integrity over %d ops\n", torture_numops);
451 for (i=0;i<torture_numops;i++)
453 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
455 printf("%d\r", i); fflush(stdout);
458 generate_random_buffer(buf, buf_size);
460 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
461 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
462 printf("wrote %d, expected %d\n", bytes_written, buf_size);
467 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
468 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
469 printf("read %d, expected %d\n", bytes_read, buf_size);
474 if (memcmp(buf_rd, buf, buf_size) != 0)
476 printf("read/write compare failed\n");
482 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
483 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
486 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
487 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
491 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
492 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
499 static BOOL run_readwritetest(int dummy)
501 struct smbcli_state *cli1, *cli2;
502 BOOL test1, test2 = True;
504 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
508 printf("starting readwritetest\n");
510 test1 = rw_torture2(cli1, cli2);
511 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
514 test2 = rw_torture2(cli1, cli1);
515 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
518 if (!torture_close_connection(cli1)) {
522 if (!torture_close_connection(cli2)) {
526 return (test1 && test2);
529 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
533 test = rw_torture3(cli, "\\multitest.txt");
535 if (!torture_close_connection(cli)) {
544 This test checks for two things:
546 1) correct support for retaining locks over a close (ie. the server
547 must not use posix semantics)
548 2) support for lock timeouts
550 static BOOL run_locktest1(int dummy)
552 struct smbcli_state *cli1, *cli2;
553 const char *fname = "\\lockt1.lck";
554 int fnum1, fnum2, fnum3;
558 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
562 printf("starting locktest1\n");
564 smbcli_unlink(cli1->tree, fname);
566 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
568 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
571 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
573 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
576 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
578 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
582 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
583 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
588 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
589 printf("lock2 succeeded! This is a locking bug\n");
592 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
593 NT_STATUS_LOCK_NOT_GRANTED)) return False;
597 lock_timeout = (6 + (random() % 20));
598 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
600 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
601 printf("lock3 succeeded! This is a locking bug\n");
604 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
605 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
610 printf("error: This server appears not to support timed lock requests\n");
612 printf("server slept for %u seconds for a %u second timeout\n",
613 (uint_t)(t2-t1), lock_timeout);
615 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
616 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
620 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
621 printf("lock4 succeeded! This is a locking bug\n");
624 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
625 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
628 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
629 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
633 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
634 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
638 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
639 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
644 if (!torture_close_connection(cli1)) {
648 if (!torture_close_connection(cli2)) {
652 printf("Passed locktest1\n");
657 this checks to see if a secondary tconx can use open files from an
660 static BOOL run_tcon_test(int dummy)
662 struct smbcli_state *cli;
663 const char *fname = "\\tcontest.tmp";
665 uint16_t cnum1, cnum2, cnum3;
666 uint16_t vuid1, vuid2;
669 struct smbcli_tree *tree1;
670 const char *host = lp_parm_string(-1, "torture", "host");
671 const char *share = lp_parm_string(-1, "torture", "share");
672 const char *password = lp_parm_string(-1, "torture", "password");
674 if (!torture_open_connection(&cli)) {
678 printf("starting tcontest\n");
680 if (smbcli_deltree(cli->tree, fname) == -1) {
681 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
684 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
686 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
690 cnum1 = cli->tree->tid;
691 vuid1 = cli->session->vuid;
693 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
694 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
695 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
699 tree1 = cli->tree; /* save old tree connection */
700 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
701 printf("%s refused 2nd tree connect (%s)\n", host,
702 smbcli_errstr(cli->tree));
703 smbcli_shutdown(cli);
707 cnum2 = cli->tree->tid;
708 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
709 vuid2 = cli->session->vuid + 1;
711 /* try a write with the wrong tid */
712 cli->tree->tid = cnum2;
714 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
715 printf("* server allows write with wrong TID\n");
718 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
722 /* try a write with an invalid tid */
723 cli->tree->tid = cnum3;
725 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
726 printf("* server allows write with invalid TID\n");
729 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
732 /* try a write with an invalid vuid */
733 cli->session->vuid = vuid2;
734 cli->tree->tid = cnum1;
736 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
737 printf("* server allows write with invalid VUID\n");
740 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
743 cli->session->vuid = vuid1;
744 cli->tree->tid = cnum1;
746 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
747 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
751 cli->tree->tid = cnum2;
753 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
754 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
758 cli->tree = tree1; /* restore initial tree */
759 cli->tree->tid = cnum1;
761 if (!torture_close_connection(cli)) {
770 static BOOL tcon_devtest(struct smbcli_state *cli,
771 const char *myshare, const char *devtype,
772 NTSTATUS expected_error)
776 const char *password = lp_parm_string(-1, "torture", "password");
778 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
781 printf("Trying share %s with devtype %s\n", myshare, devtype);
783 if (NT_STATUS_IS_OK(expected_error)) {
787 printf("tconX to share %s with type %s "
788 "should have succeeded but failed\n",
795 printf("tconx to share %s with type %s "
796 "should have failed but succeeded\n",
800 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
804 printf("Returned unexpected error\n");
813 checks for correct tconX support
815 static BOOL run_tcon_devtype_test(int dummy)
817 struct smbcli_state *cli1 = NULL;
822 const char *host = lp_parm_string(-1, "torture", "host");
823 const char *share = lp_parm_string(-1, "torture", "share");
824 const char *username = lp_parm_string(-1, "torture", "username");
825 const char *password = lp_parm_string(-1, "torture", "password");
827 status = smbcli_full_connection(&cli1, lp_netbios_name(),
830 username, lp_workgroup(),
831 password, flags, &retry);
833 if (!NT_STATUS_IS_OK(status)) {
834 printf("could not open connection\n");
838 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
841 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
844 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
847 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
850 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
853 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
856 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
859 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
862 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
865 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
868 smbcli_shutdown(cli1);
871 printf("Passed tcondevtest\n");
878 This test checks that
880 1) the server supports multiple locking contexts on the one SMB
881 connection, distinguished by PID.
883 2) the server correctly fails overlapping locks made by the same PID (this
884 goes against POSIX behaviour, which is why it is tricky to implement)
886 3) the server denies unlock requests by an incorrect client PID
888 static BOOL run_locktest2(int dummy)
890 struct smbcli_state *cli;
891 const char *fname = "\\lockt2.lck";
892 int fnum1, fnum2, fnum3;
895 if (!torture_open_connection(&cli)) {
899 printf("starting locktest2\n");
901 smbcli_unlink(cli->tree, fname);
903 printf("Testing pid context\n");
905 cli->session->pid = 1;
907 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
909 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
913 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
915 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
919 cli->session->pid = 2;
921 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
923 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
927 cli->session->pid = 1;
929 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
930 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
934 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
935 printf("WRITE lock1 succeeded! This is a locking bug\n");
938 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
939 NT_STATUS_LOCK_NOT_GRANTED)) return False;
942 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
943 printf("WRITE lock2 succeeded! This is a locking bug\n");
946 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
947 NT_STATUS_LOCK_NOT_GRANTED)) return False;
950 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
951 printf("READ lock2 succeeded! This is a locking bug\n");
954 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
955 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
958 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
959 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
962 cli->session->pid = 2;
964 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
965 printf("unlock at 100 succeeded! This is a locking bug\n");
969 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
970 printf("unlock1 succeeded! This is a locking bug\n");
973 if (!check_error(__LINE__, cli,
975 NT_STATUS_RANGE_NOT_LOCKED)) return False;
978 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
979 printf("unlock2 succeeded! This is a locking bug\n");
982 if (!check_error(__LINE__, cli,
984 NT_STATUS_RANGE_NOT_LOCKED)) return False;
987 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
988 printf("lock3 succeeded! This is a locking bug\n");
991 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
994 cli->session->pid = 1;
996 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
997 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1001 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1002 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1006 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1007 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1011 if (!torture_close_connection(cli)) {
1015 printf("locktest2 finished\n");
1022 This test checks that
1024 1) the server supports the full offset range in lock requests
1026 static BOOL run_locktest3(int dummy)
1028 struct smbcli_state *cli1, *cli2;
1029 const char *fname = "\\lockt3.lck";
1030 int fnum1, fnum2, i;
1032 BOOL correct = True;
1034 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1036 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1040 printf("starting locktest3\n");
1042 printf("Testing 32 bit offset ranges\n");
1044 smbcli_unlink(cli1->tree, fname);
1046 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1048 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1051 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1053 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1057 printf("Establishing %d locks\n", torture_numops);
1059 for (offset=i=0;i<torture_numops;i++) {
1061 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1062 printf("lock1 %d failed (%s)\n",
1064 smbcli_errstr(cli1->tree));
1068 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1069 printf("lock2 %d failed (%s)\n",
1071 smbcli_errstr(cli1->tree));
1076 printf("Testing %d locks\n", torture_numops);
1078 for (offset=i=0;i<torture_numops;i++) {
1081 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1082 printf("error: lock1 %d succeeded!\n", i);
1086 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1087 printf("error: lock2 %d succeeded!\n", i);
1091 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1092 printf("error: lock3 %d succeeded!\n", i);
1096 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1097 printf("error: lock4 %d succeeded!\n", i);
1102 printf("Removing %d locks\n", torture_numops);
1104 for (offset=i=0;i<torture_numops;i++) {
1107 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1108 printf("unlock1 %d failed (%s)\n",
1110 smbcli_errstr(cli1->tree));
1114 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1115 printf("unlock2 %d failed (%s)\n",
1117 smbcli_errstr(cli1->tree));
1122 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1123 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1127 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1128 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1132 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1133 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1137 if (!torture_close_connection(cli1)) {
1141 if (!torture_close_connection(cli2)) {
1145 printf("finished locktest3\n");
1150 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1151 printf("** "); correct = False; \
1155 looks at overlapping locks
1157 static BOOL run_locktest4(int dummy)
1159 struct smbcli_state *cli1, *cli2;
1160 const char *fname = "\\lockt4.lck";
1161 int fnum1, fnum2, f;
1164 BOOL correct = True;
1166 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1170 printf("starting locktest4\n");
1172 smbcli_unlink(cli1->tree, fname);
1174 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1175 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1177 memset(buf, 0, sizeof(buf));
1179 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1180 printf("Failed to create file\n");
1185 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1186 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1187 EXPECTED(ret, False);
1188 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1190 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1191 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1192 EXPECTED(ret, True);
1193 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1195 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1196 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1197 EXPECTED(ret, False);
1198 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1200 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1201 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1202 EXPECTED(ret, True);
1203 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1205 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1206 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1207 EXPECTED(ret, False);
1208 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1210 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1211 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1212 EXPECTED(ret, True);
1213 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1215 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1216 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1217 EXPECTED(ret, True);
1218 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1220 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1221 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1222 EXPECTED(ret, False);
1223 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1225 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1226 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1227 EXPECTED(ret, False);
1228 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1230 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1231 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1232 EXPECTED(ret, True);
1233 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1235 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1236 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1237 EXPECTED(ret, False);
1238 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1240 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1241 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1242 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1243 EXPECTED(ret, False);
1244 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1247 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1248 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1249 EXPECTED(ret, False);
1250 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1252 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1253 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1254 EXPECTED(ret, False);
1255 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1258 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1259 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1260 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1261 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1262 EXPECTED(ret, True);
1263 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1266 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1267 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1268 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1269 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1270 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1271 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1272 EXPECTED(ret, True);
1273 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1275 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1276 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1277 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1278 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1279 EXPECTED(ret, True);
1280 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1282 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1283 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1284 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1285 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1286 EXPECTED(ret, True);
1287 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1289 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1290 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1291 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1292 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1293 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1294 EXPECTED(ret, True);
1295 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1297 smbcli_close(cli1->tree, fnum1);
1298 smbcli_close(cli2->tree, fnum2);
1299 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1300 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1301 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1302 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1303 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1304 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1305 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1306 smbcli_close(cli1->tree, f);
1307 smbcli_close(cli1->tree, fnum1);
1308 EXPECTED(ret, True);
1309 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1312 smbcli_close(cli1->tree, fnum1);
1313 smbcli_close(cli2->tree, fnum2);
1314 smbcli_unlink(cli1->tree, fname);
1315 torture_close_connection(cli1);
1316 torture_close_connection(cli2);
1318 printf("finished locktest4\n");
1323 looks at lock upgrade/downgrade.
1325 static BOOL run_locktest5(int dummy)
1327 struct smbcli_state *cli1, *cli2;
1328 const char *fname = "\\lockt5.lck";
1329 int fnum1, fnum2, fnum3;
1332 BOOL correct = True;
1334 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1338 printf("starting locktest5\n");
1340 smbcli_unlink(cli1->tree, fname);
1342 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1343 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1344 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1346 memset(buf, 0, sizeof(buf));
1348 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1349 printf("Failed to create file\n");
1354 /* Check for NT bug... */
1355 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1356 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1357 smbcli_close(cli1->tree, fnum1);
1358 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1359 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1360 EXPECTED(ret, True);
1361 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1362 smbcli_close(cli1->tree, fnum1);
1363 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1364 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1366 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1367 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1368 EXPECTED(ret, True);
1369 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1371 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1372 EXPECTED(ret, False);
1374 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1376 /* Unlock the process 2 lock. */
1377 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1379 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1380 EXPECTED(ret, False);
1382 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1384 /* Unlock the process 1 fnum3 lock. */
1385 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1387 /* Stack 2 more locks here. */
1388 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1389 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1391 EXPECTED(ret, True);
1392 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1394 /* Unlock the first process lock, then check this was the WRITE lock that was
1397 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1398 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1400 EXPECTED(ret, True);
1401 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1403 /* Unlock the process 2 lock. */
1404 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1406 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1408 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1409 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1410 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1412 EXPECTED(ret, True);
1413 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1415 /* Ensure the next unlock fails. */
1416 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1417 EXPECTED(ret, False);
1418 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1420 /* Ensure connection 2 can get a write lock. */
1421 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1422 EXPECTED(ret, True);
1424 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1428 smbcli_close(cli1->tree, fnum1);
1429 smbcli_close(cli2->tree, fnum2);
1430 smbcli_unlink(cli1->tree, fname);
1431 if (!torture_close_connection(cli1)) {
1434 if (!torture_close_connection(cli2)) {
1438 printf("finished locktest5\n");
1444 tries the unusual lockingX locktype bits
1446 static BOOL run_locktest6(int dummy)
1448 struct smbcli_state *cli;
1449 const char *fname[1] = { "\\lock6.txt" };
1454 if (!torture_open_connection(&cli)) {
1458 printf("starting locktest6\n");
1461 printf("Testing %s\n", fname[i]);
1463 smbcli_unlink(cli->tree, fname[i]);
1465 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1466 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1467 smbcli_close(cli->tree, fnum);
1468 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1470 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1471 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1472 smbcli_close(cli->tree, fnum);
1473 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1475 smbcli_unlink(cli->tree, fname[i]);
1478 torture_close_connection(cli);
1480 printf("finished locktest6\n");
1484 static BOOL run_locktest7(int dummy)
1486 struct smbcli_state *cli1;
1487 const char *fname = "\\lockt7.lck";
1492 BOOL correct = False;
1494 if (!torture_open_connection(&cli1)) {
1498 printf("starting locktest7\n");
1500 smbcli_unlink(cli1->tree, fname);
1502 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1504 memset(buf, 0, sizeof(buf));
1506 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1507 printf("Failed to create file\n");
1511 cli1->session->pid = 1;
1513 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1514 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1517 printf("pid1 successfully locked range 130:4 for READ\n");
1520 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1521 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1524 printf("pid1 successfully read the range 130:4\n");
1527 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1528 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1529 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1530 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1534 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1538 cli1->session->pid = 2;
1540 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1541 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1543 printf("pid2 successfully read the range 130:4\n");
1546 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1547 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1548 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1549 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1553 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1557 cli1->session->pid = 1;
1558 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1560 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1561 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1564 printf("pid1 successfully locked range 130:4 for WRITE\n");
1567 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1568 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1571 printf("pid1 successfully read the range 130:4\n");
1574 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1575 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1578 printf("pid1 successfully wrote to the range 130:4\n");
1581 cli1->session->pid = 2;
1583 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1584 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1585 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1586 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1590 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1594 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1595 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1596 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1597 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1601 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1605 printf("Testing truncate of locked file.\n");
1607 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1610 printf("Unable to truncate locked file.\n");
1614 printf("Truncated locked file.\n");
1617 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1618 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1624 printf("Unable to truncate locked file. Size was %u\n", size);
1629 cli1->session->pid = 1;
1631 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1635 smbcli_close(cli1->tree, fnum1);
1636 smbcli_close(cli1->tree, fnum2);
1637 smbcli_unlink(cli1->tree, fname);
1638 torture_close_connection(cli1);
1640 printf("finished locktest7\n");
1645 test whether fnums and tids open on one VC are available on another (a major
1648 static BOOL run_fdpasstest(int dummy)
1650 struct smbcli_state *cli1, *cli2;
1651 const char *fname = "\\fdpass.tst";
1655 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1659 printf("starting fdpasstest\n");
1661 smbcli_unlink(cli1->tree, fname);
1663 printf("Opening a file on connection 1\n");
1665 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1667 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1671 printf("writing to file on connection 1\n");
1673 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1674 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1678 oldtid = cli2->tree->tid;
1679 cli2->session->vuid = cli1->session->vuid;
1680 cli2->tree->tid = cli1->tree->tid;
1681 cli2->session->pid = cli1->session->pid;
1683 printf("reading from file on connection 2\n");
1685 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1686 printf("read succeeded! nasty security hole [%s]\n",
1691 smbcli_close(cli1->tree, fnum1);
1692 smbcli_unlink(cli1->tree, fname);
1694 cli2->tree->tid = oldtid;
1696 torture_close_connection(cli1);
1697 torture_close_connection(cli2);
1699 printf("finished fdpasstest\n");
1705 This test checks that
1707 1) the server does not allow an unlink on a file that is open
1709 static BOOL run_unlinktest(int dummy)
1711 struct smbcli_state *cli;
1712 const char *fname = "\\unlink.tst";
1714 BOOL correct = True;
1716 if (!torture_open_connection(&cli)) {
1720 printf("starting unlink test\n");
1722 smbcli_unlink(cli->tree, fname);
1724 cli->session->pid = 1;
1726 printf("Opening a file\n");
1728 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1730 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1734 printf("Unlinking a open file\n");
1736 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1737 printf("error: server allowed unlink on an open file\n");
1740 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1741 NT_STATUS_SHARING_VIOLATION);
1744 smbcli_close(cli->tree, fnum);
1745 smbcli_unlink(cli->tree, fname);
1747 if (!torture_close_connection(cli)) {
1751 printf("unlink test finished\n");
1758 test the timing of deferred open requests
1760 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1762 const char *fname = "\\defer_open_test.dat";
1765 BOOL correct = True;
1768 printf("failed to connect\n");
1772 printf("Testing deferred open requests.\n");
1778 struct timeval tv_start, tv_end;
1779 GetTimeOfDay(&tv_start);
1780 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1781 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1782 NTCREATEX_DISP_OPEN_IF, 0, 0);
1786 GetTimeOfDay(&tv_end);
1787 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1788 /* Sharing violation errors need to be 1 second apart. */
1789 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1790 if (tdif < 500000 || tdif > 1500000) {
1791 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1792 tdif / (int64_t)1000000,
1793 tdif % (int64_t)1000000);
1796 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1799 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1803 printf("pid %u open %d\n", getpid(), i);
1807 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1808 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1814 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1815 /* All until the last unlink will fail with sharing violation. */
1816 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1817 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1822 printf("deferred test finished\n");
1823 if (!torture_close_connection(cli)) {
1830 test how many open files this server supports on the one socket
1832 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1834 #define MAXFID_TEMPLATE "\\maxfid.%d.%d"
1836 int fnums[0x11000], i;
1838 BOOL correct = True;
1841 printf("failed to connect\n");
1845 printf("Testing maximum number of open files\n");
1847 for (i=0; i<0x11000; i++) {
1848 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1849 if ((fnums[i] = smbcli_open(cli->tree, fname,
1850 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1852 printf("open of %s failed (%s)\n",
1853 fname, smbcli_errstr(cli->tree));
1854 printf("maximum fnum is %d\n", i);
1863 printf("cleaning up\n");
1865 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1866 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1867 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1869 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1870 printf("unlink of %s failed (%s)\n",
1871 fname, smbcli_errstr(cli->tree));
1879 printf("maxfid test finished\n");
1880 if (!torture_close_connection(cli)) {
1884 #undef MAXFID_TEMPLATE
1887 /* send smb negprot commands, not reading the response */
1888 static BOOL run_negprot_nowait(int dummy)
1891 struct smbcli_state *cli, *cli2;
1892 BOOL correct = True;
1894 printf("starting negprot nowait test\n");
1896 cli = open_nbt_connection();
1901 printf("Filling send buffer\n");
1903 for (i=0;i<10000;i++) {
1904 struct smbcli_request *req;
1905 time_t t1 = time(NULL);
1906 req = smb_negprot_send(cli->transport, PROTOCOL_NT1);
1907 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
1908 smbcli_transport_process(cli->transport);
1910 if (req->state == SMBCLI_REQUEST_ERROR) {
1911 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
1912 torture_close_connection(cli);
1915 if (req->state == SMBCLI_REQUEST_SEND) {
1921 printf("send buffer failed to fill\n");
1922 if (!torture_close_connection(cli)) {
1928 printf("send buffer filled after %d requests\n", i);
1930 printf("Opening secondary connection\n");
1931 if (!torture_open_connection(&cli2)) {
1935 if (!torture_close_connection(cli)) {
1939 if (!torture_close_connection(cli2)) {
1943 printf("finished negprot nowait test\n");
1950 This checks how the getatr calls works
1952 static BOOL run_attrtest(int dummy)
1954 struct smbcli_state *cli;
1957 const char *fname = "\\attrib123456789.tst";
1958 BOOL correct = True;
1960 printf("starting attrib test\n");
1962 if (!torture_open_connection(&cli)) {
1966 smbcli_unlink(cli->tree, fname);
1967 fnum = smbcli_open(cli->tree, fname,
1968 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1969 smbcli_close(cli->tree, fnum);
1971 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1972 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1976 printf("New file time is %s", ctime(&t));
1978 if (abs(t - time(NULL)) > 60*60*24*10) {
1979 printf("ERROR: SMBgetatr bug. time is %s",
1985 t2 = t-60*60*24; /* 1 day ago */
1987 printf("Setting file time to %s", ctime(&t2));
1989 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
1990 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
1994 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1995 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1999 printf("Retrieved file time as %s", ctime(&t));
2002 printf("ERROR: getatr/setatr bug. times are\n%s",
2004 printf("%s", ctime(&t2));
2008 smbcli_unlink(cli->tree, fname);
2010 if (!torture_close_connection(cli)) {
2014 printf("attrib test finished\n");
2021 This checks a couple of trans2 calls
2023 static BOOL run_trans2test(int dummy)
2025 struct smbcli_state *cli;
2028 time_t c_time, a_time, m_time, w_time, m_time2;
2029 const char *fname = "\\trans2.tst";
2030 const char *dname = "\\trans2";
2031 const char *fname2 = "\\trans2\\trans2.tst";
2033 BOOL correct = True;
2035 printf("starting trans2 test\n");
2037 if (!torture_open_connection(&cli)) {
2041 smbcli_unlink(cli->tree, fname);
2043 printf("Testing qfileinfo\n");
2045 fnum = smbcli_open(cli->tree, fname,
2046 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2047 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2049 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
2053 printf("Testing NAME_INFO\n");
2055 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
2056 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
2060 if (!pname || strcmp(pname, fname)) {
2061 printf("qfilename gave different name? [%s] [%s]\n",
2066 smbcli_close(cli->tree, fnum);
2067 smbcli_unlink(cli->tree, fname);
2069 fnum = smbcli_open(cli->tree, fname,
2070 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2072 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
2075 smbcli_close(cli->tree, fnum);
2077 printf("Checking for sticky create times\n");
2079 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2080 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
2083 if (c_time != m_time) {
2084 printf("create time=%s", ctime(&c_time));
2085 printf("modify time=%s", ctime(&m_time));
2086 printf("This system appears to have sticky create times\n");
2088 if (a_time % (60*60) == 0) {
2089 printf("access time=%s", ctime(&a_time));
2090 printf("This system appears to set a midnight access time\n");
2094 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2095 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2101 smbcli_unlink(cli->tree, fname);
2102 fnum = smbcli_open(cli->tree, fname,
2103 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2104 smbcli_close(cli->tree, fnum);
2105 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2106 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2109 if (w_time < 60*60*24*2) {
2110 printf("write time=%s", ctime(&w_time));
2111 printf("This system appears to set a initial 0 write time\n");
2116 smbcli_unlink(cli->tree, fname);
2119 /* check if the server updates the directory modification time
2120 when creating a new file */
2121 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
2122 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
2126 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2127 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2131 fnum = smbcli_open(cli->tree, fname2,
2132 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2133 smbcli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2134 smbcli_close(cli->tree, fnum);
2135 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2136 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2139 if (m_time2 == m_time) {
2140 printf("This system does not update directory modification times\n");
2144 smbcli_unlink(cli->tree, fname2);
2145 smbcli_rmdir(cli->tree, dname);
2147 if (!torture_close_connection(cli)) {
2151 printf("trans2 test finished\n");
2157 Test delete on close semantics.
2159 static BOOL run_deletetest(int dummy)
2161 struct smbcli_state *cli1;
2162 struct smbcli_state *cli2 = NULL;
2163 const char *fname = "\\delete.file";
2166 BOOL correct = True;
2168 printf("starting delete test\n");
2170 if (!torture_open_connection(&cli1)) {
2174 /* Test 1 - this should delete the file on close. */
2176 smbcli_setatr(cli1->tree, fname, 0, 0);
2177 smbcli_unlink(cli1->tree, fname);
2179 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2180 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2181 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2184 printf("[1] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2189 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2190 printf("[1] close failed (%s)\n", smbcli_errstr(cli1->tree));
2195 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2197 printf("[1] open of %s succeeded (should fail)\n", fname);
2202 printf("first delete on close test succeeded.\n");
2204 /* Test 2 - this should delete the file on close. */
2206 smbcli_setatr(cli1->tree, fname, 0, 0);
2207 smbcli_unlink(cli1->tree, fname);
2209 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2210 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2211 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2214 printf("[2] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2219 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2220 printf("[2] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2225 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2226 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2231 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2233 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2234 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2235 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2239 smbcli_unlink(cli1->tree, fname);
2241 printf("second delete on close test succeeded.\n");
2244 smbcli_setatr(cli1->tree, fname, 0, 0);
2245 smbcli_unlink(cli1->tree, fname);
2247 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2248 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2251 printf("[3] open - 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2256 /* This should fail with a sharing violation - open for delete is only compatible
2257 with SHARE_DELETE. */
2259 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2260 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2261 NTCREATEX_DISP_OPEN, 0, 0);
2264 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2269 /* This should succeed. */
2271 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2272 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2275 printf("[3] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2280 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2281 printf("[3] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2286 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2287 printf("[3] close 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2292 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2293 printf("[3] close 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2298 /* This should fail - file should no longer be there. */
2300 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2302 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2303 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2304 printf("[3] close failed (%s)\n", smbcli_errstr(cli1->tree));
2306 smbcli_unlink(cli1->tree, fname);
2310 printf("third delete on close test succeeded.\n");
2313 smbcli_setatr(cli1->tree, fname, 0, 0);
2314 smbcli_unlink(cli1->tree, fname);
2316 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2317 SA_RIGHT_FILE_READ_DATA |
2318 SA_RIGHT_FILE_WRITE_DATA |
2319 STD_RIGHT_DELETE_ACCESS,
2320 FILE_ATTRIBUTE_NORMAL,
2321 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2322 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2325 printf("[4] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2330 /* This should succeed. */
2331 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2332 FILE_ATTRIBUTE_NORMAL,
2333 NTCREATEX_SHARE_ACCESS_READ |
2334 NTCREATEX_SHARE_ACCESS_WRITE |
2335 NTCREATEX_SHARE_ACCESS_DELETE,
2336 NTCREATEX_DISP_OPEN, 0, 0);
2338 printf("[4] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2343 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2344 printf("[4] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2349 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2350 printf("[4] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2355 /* This should fail - no more opens once delete on close set. */
2356 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2357 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2358 NTCREATEX_DISP_OPEN, 0, 0);
2360 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2364 printf("fourth delete on close test succeeded.\n");
2366 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2367 printf("[4] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2373 smbcli_setatr(cli1->tree, fname, 0, 0);
2374 smbcli_unlink(cli1->tree, fname);
2376 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2378 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2383 /* This should fail - only allowed on NT opens with DELETE access. */
2385 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2386 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2391 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2392 printf("[5] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2397 printf("fifth delete on close test succeeded.\n");
2400 smbcli_setatr(cli1->tree, fname, 0, 0);
2401 smbcli_unlink(cli1->tree, fname);
2403 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2404 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2405 FILE_ATTRIBUTE_NORMAL,
2406 NTCREATEX_SHARE_ACCESS_READ |
2407 NTCREATEX_SHARE_ACCESS_WRITE |
2408 NTCREATEX_SHARE_ACCESS_DELETE,
2409 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2412 printf("[6] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2417 /* This should fail - only allowed on NT opens with DELETE access. */
2419 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2420 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2425 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2426 printf("[6] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2431 printf("sixth delete on close test succeeded.\n");
2434 smbcli_setatr(cli1->tree, fname, 0, 0);
2435 smbcli_unlink(cli1->tree, fname);
2437 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2438 SA_RIGHT_FILE_READ_DATA |
2439 SA_RIGHT_FILE_WRITE_DATA |
2440 STD_RIGHT_DELETE_ACCESS,
2441 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2444 printf("[7] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2449 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2450 printf("[7] setting delete_on_close on file failed !\n");
2455 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2456 printf("[7] unsetting delete_on_close on file failed !\n");
2461 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2462 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2467 /* This next open should succeed - we reset the flag. */
2469 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2471 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2476 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2477 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2482 printf("seventh delete on close test succeeded.\n");
2485 smbcli_setatr(cli1->tree, fname, 0, 0);
2486 smbcli_unlink(cli1->tree, fname);
2488 if (!torture_open_connection(&cli2)) {
2489 printf("[8] failed to open second connection.\n");
2494 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2495 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2496 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2499 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2504 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2505 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2506 NTCREATEX_DISP_OPEN, 0, 0);
2509 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2514 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2515 printf("[8] setting delete_on_close on file failed !\n");
2520 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2521 printf("[8] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2526 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
2527 printf("[8] close - 2 failed (%s)\n", smbcli_errstr(cli2->tree));
2532 /* This should fail.. */
2533 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2535 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2539 printf("eighth delete on close test succeeded.\n");
2541 /* This should fail - we need to set DELETE_ACCESS. */
2542 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2543 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2546 printf("[9] open of %s succeeded should have failed!\n", fname);
2551 printf("ninth delete on close test succeeded.\n");
2553 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2554 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2556 printf("[10] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2561 /* This should delete the file. */
2562 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2563 printf("[10] close failed (%s)\n", smbcli_errstr(cli1->tree));
2568 /* This should fail.. */
2569 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2571 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2575 printf("tenth delete on close test succeeded.\n");
2576 printf("finished delete test\n");
2579 /* FIXME: This will crash if we aborted before cli2 got
2580 * intialized, because these functions don't handle
2581 * uninitialized connections. */
2583 smbcli_close(cli1->tree, fnum1);
2584 smbcli_close(cli1->tree, fnum2);
2585 smbcli_setatr(cli1->tree, fname, 0, 0);
2586 smbcli_unlink(cli1->tree, fname);
2588 if (!torture_close_connection(cli1)) {
2591 if (!torture_close_connection(cli2)) {
2599 print out server properties
2601 static BOOL run_properties(int dummy)
2603 struct smbcli_state *cli;
2604 BOOL correct = True;
2606 printf("starting properties test\n");
2610 if (!torture_open_connection(&cli)) {
2614 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2616 if (!torture_close_connection(cli)) {
2625 /* FIRST_DESIRED_ACCESS 0xf019f */
2626 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2627 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2628 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2629 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2630 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2631 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2632 /* SECOND_DESIRED_ACCESS 0xe0080 */
2633 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2634 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2635 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2638 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2639 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2640 SA_RIGHT_FILE_READ_DATA|\
2641 WRITE_OWNER_ACCESS /* */
2645 Test ntcreate calls made by xcopy
2647 static BOOL run_xcopy(int dummy)
2649 struct smbcli_state *cli1;
2650 const char *fname = "\\test.txt";
2651 BOOL correct = True;
2654 printf("starting xcopy test\n");
2656 if (!torture_open_connection(&cli1)) {
2660 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2661 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2662 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2666 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2670 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
2671 SECOND_DESIRED_ACCESS, 0,
2672 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2675 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
2679 if (!torture_close_connection(cli1)) {
2687 Test rename on files open with share delete and no share delete.
2689 static BOOL run_rename(int dummy)
2691 struct smbcli_state *cli1;
2692 const char *fname = "\\test.txt";
2693 const char *fname1 = "\\test1.txt";
2694 BOOL correct = True;
2697 printf("starting rename test\n");
2699 if (!torture_open_connection(&cli1)) {
2703 smbcli_unlink(cli1->tree, fname);
2704 smbcli_unlink(cli1->tree, fname1);
2705 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2706 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2709 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2713 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2714 printf("First rename failed (this is correct) - %s\n", smbcli_errstr(cli1->tree));
2716 printf("First rename succeeded - this should have failed !\n");
2720 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2721 printf("close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2725 smbcli_unlink(cli1->tree, fname);
2726 smbcli_unlink(cli1->tree, fname1);
2727 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2728 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2731 printf("Second open failed - %s\n", smbcli_errstr(cli1->tree));
2735 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2736 printf("Second rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2739 printf("Second rename succeeded\n");
2742 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2743 printf("close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2747 smbcli_unlink(cli1->tree, fname);
2748 smbcli_unlink(cli1->tree, fname1);
2750 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2751 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2754 printf("Third open failed - %s\n", smbcli_errstr(cli1->tree));
2759 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2760 printf("Third rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2763 printf("Third rename succeeded\n");
2766 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2767 printf("close - 3 failed (%s)\n", smbcli_errstr(cli1->tree));
2771 smbcli_unlink(cli1->tree, fname);
2772 smbcli_unlink(cli1->tree, fname1);
2774 if (!torture_close_connection(cli1)) {
2783 see how many RPC pipes we can open at once
2785 static BOOL run_pipe_number(int dummy)
2787 struct smbcli_state *cli1;
2788 const char *pipe_name = "\\WKSSVC";
2792 printf("starting pipenumber test\n");
2793 if (!torture_open_connection(&cli1)) {
2798 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2799 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2802 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
2806 printf("%d\r", num_pipes);
2810 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2811 torture_close_connection(cli1);
2819 open N connections to the server and just hold them open
2820 used for testing performance when there are N idle users
2823 static BOOL torture_holdcon(int dummy)
2826 struct smbcli_state **cli;
2829 printf("Opening %d connections\n", torture_numops);
2831 cli = malloc(sizeof(struct smbcli_state *) * torture_numops);
2833 for (i=0;i<torture_numops;i++) {
2834 if (!torture_open_connection(&cli[i])) {
2837 printf("opened %d connections\r", i);
2841 printf("\nStarting pings\n");
2844 for (i=0;i<torture_numops;i++) {
2847 status = smbcli_chkpath(cli[i]->tree, "\\");
2848 if (!NT_STATUS_IS_OK(status)) {
2849 printf("Connection %d is dead\n", i);
2857 if (num_dead == torture_numops) {
2858 printf("All connections dead - finishing\n");
2870 Try with a wrong vuid and check error message.
2873 static BOOL run_vuidtest(int dummy)
2875 struct smbcli_state *cli;
2876 const char *fname = "\\vuid.tst";
2879 time_t c_time, a_time, m_time;
2880 BOOL correct = True;
2885 printf("starting vuid test\n");
2887 if (!torture_open_connection(&cli)) {
2891 smbcli_unlink(cli->tree, fname);
2893 fnum = smbcli_open(cli->tree, fname,
2894 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2896 orig_vuid = cli->session->vuid;
2898 cli->session->vuid += 1234;
2900 printf("Testing qfileinfo with wrong vuid\n");
2902 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
2903 &size, &c_time, &a_time,
2904 &m_time, NULL, NULL))) {
2905 printf("ERROR: qfileinfo passed with wrong vuid\n");
2909 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2910 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2911 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2912 printf("ERROR: qfileinfo should have returned DOS error "
2913 "ERRSRV:ERRbaduid\n but returned %s\n",
2914 smbcli_errstr(cli->tree));
2918 cli->session->vuid -= 1234;
2920 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
2921 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
2925 smbcli_unlink(cli->tree, fname);
2927 if (!torture_close_connection(cli)) {
2931 printf("vuid test finished\n");
2937 Test open mode returns on read-only files.
2939 static BOOL run_opentest(int dummy)
2941 static struct smbcli_state *cli1;
2942 static struct smbcli_state *cli2;
2943 const char *fname = "\\readonly.file";
2947 BOOL correct = True;
2951 printf("starting open test\n");
2953 if (!torture_open_connection(&cli1)) {
2957 smbcli_setatr(cli1->tree, fname, 0, 0);
2958 smbcli_unlink(cli1->tree, fname);
2960 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2962 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2966 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2967 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
2971 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2972 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
2973 CHECK_MAX_FAILURES(error_test1);
2977 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2979 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2980 CHECK_MAX_FAILURES(error_test1);
2984 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2985 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2987 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2988 NT_STATUS_ACCESS_DENIED)) {
2989 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2992 printf("finished open test 1\n");
2994 smbcli_close(cli1->tree, fnum1);
2996 /* Now try not readonly and ensure ERRbadshare is returned. */
2998 smbcli_setatr(cli1->tree, fname, 0, 0);
3000 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3002 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3006 /* This will fail - but the error should be ERRshare. */
3007 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3009 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3010 NT_STATUS_SHARING_VIOLATION)) {
3011 printf("correct error code ERRDOS/ERRbadshare returned\n");
3014 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3015 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3019 smbcli_unlink(cli1->tree, fname);
3021 printf("finished open test 2\n");
3023 /* Test truncate open disposition on file opened for read. */
3025 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3027 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3031 /* write 20 bytes. */
3033 memset(buf, '\0', 20);
3035 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3036 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
3040 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3041 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3045 /* Ensure size == 20. */
3046 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3047 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3048 CHECK_MAX_FAILURES(error_test3);
3053 printf("(3) file size != 20\n");
3054 CHECK_MAX_FAILURES(error_test3);
3058 /* Now test if we can truncate a file opened for readonly. */
3060 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3062 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3063 CHECK_MAX_FAILURES(error_test3);
3067 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3068 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3072 /* Ensure size == 0. */
3073 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3074 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3075 CHECK_MAX_FAILURES(error_test3);
3080 printf("(3) file size != 0\n");
3081 CHECK_MAX_FAILURES(error_test3);
3084 printf("finished open test 3\n");
3086 smbcli_unlink(cli1->tree, fname);
3089 printf("testing ctemp\n");
3090 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
3092 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
3093 CHECK_MAX_FAILURES(error_test4);
3096 printf("ctemp gave path %s\n", tmp_path);
3097 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3098 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3100 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
3101 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3104 /* Test the non-io opens... */
3106 if (!torture_open_connection(&cli2)) {
3110 smbcli_setatr(cli2->tree, fname, 0, 0);
3111 smbcli_unlink(cli2->tree, fname);
3113 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3115 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3116 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3119 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3120 CHECK_MAX_FAILURES(error_test10);
3124 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3125 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3127 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3128 CHECK_MAX_FAILURES(error_test10);
3132 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3133 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3136 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3137 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3141 printf("non-io open test #1 passed.\n");
3143 smbcli_unlink(cli1->tree, fname);
3145 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3147 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3148 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3151 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3152 CHECK_MAX_FAILURES(error_test20);
3156 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3157 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3160 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3161 CHECK_MAX_FAILURES(error_test20);
3165 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3166 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3169 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3170 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3174 printf("non-io open test #2 passed.\n");
3176 smbcli_unlink(cli1->tree, fname);
3178 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3180 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3181 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3184 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3185 CHECK_MAX_FAILURES(error_test30);
3189 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3190 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3193 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3194 CHECK_MAX_FAILURES(error_test30);
3198 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3199 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3202 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3203 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3207 printf("non-io open test #3 passed.\n");
3209 smbcli_unlink(cli1->tree, fname);
3211 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3213 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3214 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3217 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3218 CHECK_MAX_FAILURES(error_test40);
3222 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3223 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3226 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3227 CHECK_MAX_FAILURES(error_test40);
3231 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3233 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3234 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3238 printf("non-io open test #4 passed.\n");
3240 smbcli_unlink(cli1->tree, fname);
3242 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3244 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3245 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3248 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3249 CHECK_MAX_FAILURES(error_test50);
3253 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3254 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3257 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3258 CHECK_MAX_FAILURES(error_test50);
3262 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3263 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3267 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3268 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3272 printf("non-io open test #5 passed.\n");
3274 printf("TEST #6 testing 1 non-io open, one io open\n");
3276 smbcli_unlink(cli1->tree, fname);
3278 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3279 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3282 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3283 CHECK_MAX_FAILURES(error_test60);
3287 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3288 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3291 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3292 CHECK_MAX_FAILURES(error_test60);
3296 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3297 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3301 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3302 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3306 printf("non-io open test #6 passed.\n");
3308 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3310 smbcli_unlink(cli1->tree, fname);
3312 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3313 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3316 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3317 CHECK_MAX_FAILURES(error_test70);
3321 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3322 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3325 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3326 CHECK_MAX_FAILURES(error_test70);
3330 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3332 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3333 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3337 printf("non-io open test #7 passed.\n");
3341 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3343 smbcli_unlink(cli1->tree, fname);
3345 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3347 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3351 /* write 20 bytes. */
3353 memset(buf, '\0', 20);
3355 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3356 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
3360 /* Ensure size == 20. */
3361 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3362 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
3363 CHECK_MAX_FAILURES(error_test80);
3368 printf("(8) file size != 20\n");
3369 CHECK_MAX_FAILURES(error_test80);
3373 /* Get an exclusive lock on the open file. */
3374 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3375 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
3376 CHECK_MAX_FAILURES(error_test80);
3380 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3382 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3386 /* Ensure size == 0. */
3387 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3388 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
3389 CHECK_MAX_FAILURES(error_test80);
3394 printf("(8) file size != 0\n");
3395 CHECK_MAX_FAILURES(error_test80);
3399 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3400 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3404 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
3405 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3411 printf("open test #8 passed.\n");
3413 smbcli_unlink(cli1->tree, fname);
3415 if (!torture_close_connection(cli1)) {
3418 if (!torture_close_connection(cli2)) {
3426 static uint32_t open_attrs_table[] = {
3427 FILE_ATTRIBUTE_NORMAL,
3428 FILE_ATTRIBUTE_ARCHIVE,
3429 FILE_ATTRIBUTE_READONLY,
3430 FILE_ATTRIBUTE_HIDDEN,
3431 FILE_ATTRIBUTE_SYSTEM,
3433 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3434 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3435 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3436 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3437 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3438 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3440 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3441 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3442 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3443 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3446 struct trunc_open_results {
3449 uint32_t trunc_attr;
3450 uint32_t result_attr;
3453 static struct trunc_open_results attr_results[] = {
3454 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3455 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3456 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3457 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3458 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3459 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3460 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3461 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3462 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3463 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3464 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3465 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3466 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3467 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3468 { 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 },
3469 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3470 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3471 { 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 },
3472 { 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 },
3473 { 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 },
3474 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3475 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3476 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3477 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3478 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3479 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3482 static BOOL run_openattrtest(int dummy)
3484 struct smbcli_state *cli1;
3485 const char *fname = "\\openattr.file";
3487 BOOL correct = True;
3492 printf("starting open attr test\n");
3494 if (!torture_open_connection(&cli1)) {
3498 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3499 smbcli_setatr(cli1->tree, fname, 0, 0);
3500 smbcli_unlink(cli1->tree, fname);
3501 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3502 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3505 printf("open %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3509 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3510 printf("close %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3514 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3515 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
3516 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3517 open_attrs_table[j],
3518 NTCREATEX_SHARE_ACCESS_NONE,
3519 NTCREATEX_DISP_OVERWRITE, 0, 0);
3522 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3523 if (attr_results[l].num == k) {
3524 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3525 k, open_attrs_table[i],
3526 open_attrs_table[j],
3527 fname, NT_STATUS_V(smbcli_nt_error(cli1->tree)), smbcli_errstr(cli1->tree));
3529 CHECK_MAX_FAILURES(error_exit);
3532 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3533 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3534 k, open_attrs_table[i], open_attrs_table[j],
3535 smbcli_errstr(cli1->tree));
3537 CHECK_MAX_FAILURES(error_exit);
3540 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3546 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3547 printf("close %d (2) of %s failed (%s)\n", j, fname, smbcli_errstr(cli1->tree));
3551 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3552 printf("getatr(2) failed (%s)\n", smbcli_errstr(cli1->tree));
3557 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3558 k, open_attrs_table[i], open_attrs_table[j], attr );
3561 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3562 if (attr_results[l].num == k) {
3563 if (attr != attr_results[l].result_attr ||
3564 open_attrs_table[i] != attr_results[l].init_attr ||
3565 open_attrs_table[j] != attr_results[l].trunc_attr) {
3566 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3567 k, open_attrs_table[i],
3568 open_attrs_table[j],
3570 attr_results[l].result_attr);
3572 CHECK_MAX_FAILURES(error_exit);
3581 smbcli_setatr(cli1->tree, fname, 0, 0);
3582 smbcli_unlink(cli1->tree, fname);
3584 printf("open attr test %s.\n", correct ? "passed" : "failed");
3586 if (!torture_close_connection(cli1)) {
3592 static void list_fn(file_info *finfo, const char *name, void *state)
3598 test directory listing speed
3600 static BOOL run_dirtest(int dummy)
3603 struct smbcli_state *cli;
3606 BOOL correct = True;
3608 printf("starting directory test\n");
3610 if (!torture_open_connection(&cli)) {
3614 printf("Creating %d random filenames\n", torture_numops);
3617 for (i=0;i<torture_numops;i++) {
3619 asprintf(&fname, "\\%x", (int)random());
3620 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3622 fprintf(stderr,"Failed to open %s\n", fname);
3625 smbcli_close(cli->tree, fnum);
3631 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3632 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3633 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3635 printf("dirtest core %g seconds\n", end_timer() - t1);
3638 for (i=0;i<torture_numops;i++) {
3640 asprintf(&fname, "\\%x", (int)random());
3641 smbcli_unlink(cli->tree, fname);
3645 if (!torture_close_connection(cli)) {
3649 printf("finished dirtest\n");
3655 sees what IOCTLs are supported
3657 BOOL torture_ioctl_test(int dummy)
3659 struct smbcli_state *cli;
3660 uint16_t device, function;
3662 const char *fname = "\\ioctl.dat";
3664 union smb_ioctl parms;
3665 TALLOC_CTX *mem_ctx;
3667 if (!torture_open_connection(&cli)) {
3671 mem_ctx = talloc_init("ioctl_test");
3673 printf("starting ioctl test\n");
3675 smbcli_unlink(cli->tree, fname);
3677 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3679 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
3683 parms.ioctl.level = RAW_IOCTL_IOCTL;
3684 parms.ioctl.in.fnum = fnum;
3685 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3686 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3687 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
3689 for (device=0;device<0x100;device++) {
3690 printf("testing device=0x%x\n", device);
3691 for (function=0;function<0x100;function++) {
3692 parms.ioctl.in.request = (device << 16) | function;
3693 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3695 if (NT_STATUS_IS_OK(status)) {
3696 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3697 device, function, parms.ioctl.out.blob.length);
3702 if (!torture_close_connection(cli)) {
3711 tries variants of chkpath
3713 BOOL torture_chkpath_test(int dummy)
3715 struct smbcli_state *cli;
3719 if (!torture_open_connection(&cli)) {
3723 printf("starting chkpath test\n");
3725 printf("Testing valid and invalid paths\n");
3727 /* cleanup from an old run */
3728 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3729 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3730 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3732 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
3733 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
3737 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3738 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
3742 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3744 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
3747 smbcli_close(cli->tree, fnum);
3749 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
3750 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
3754 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3755 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
3759 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3760 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3761 NT_STATUS_NOT_A_DIRECTORY);
3763 printf("* chkpath on a file should fail\n");
3767 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3768 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3769 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3771 printf("* chkpath on a non existent file should fail\n");
3775 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3776 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3777 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3779 printf("* chkpath on a non existent component should fail\n");
3783 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3784 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3785 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3787 if (!torture_close_connection(cli)) {
3794 static BOOL run_dirtest1(int dummy)
3797 struct smbcli_state *cli;
3799 BOOL correct = True;
3801 printf("starting directory test\n");
3803 if (!torture_open_connection(&cli)) {
3807 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3808 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3811 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\LISTDIR"))) {
3812 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3816 printf("Creating %d files\n", torture_entries);
3818 /* Create torture_entries files and torture_entries directories. */
3819 for (i=0;i<torture_entries;i++) {
3821 asprintf(&fname, "\\LISTDIR\\f%d", i);
3822 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3823 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3825 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3829 smbcli_close(cli->tree, fnum);
3831 for (i=0;i<torture_entries;i++) {
3833 asprintf(&fname, "\\LISTDIR\\d%d", i);
3834 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
3835 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3841 /* Now ensure that doing an old list sees both files and directories. */
3842 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3843 printf("num_seen = %d\n", num_seen );
3844 /* We should see (torture_entries) each of files & directories + . and .. */
3845 if (num_seen != (2*torture_entries)+2) {
3847 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3848 (2*torture_entries)+2, num_seen);
3852 /* Ensure if we have the "must have" bits we only see the
3855 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3856 printf("num_seen = %d\n", num_seen );
3857 if (num_seen != torture_entries+2) {
3859 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3860 torture_entries+2, num_seen);
3863 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3864 printf("num_seen = %d\n", num_seen );
3865 if (num_seen != torture_entries) {
3867 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3868 torture_entries, num_seen);
3871 /* Delete everything. */
3872 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3873 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3878 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3879 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3880 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3883 if (!torture_close_connection(cli)) {
3887 printf("finished dirtest1\n");
3894 simple test harness for playing with deny modes
3896 static BOOL run_deny3test(int dummy)
3898 struct smbcli_state *cli1, *cli2;
3902 printf("starting deny3 test\n");
3904 printf("Testing simple deny modes\n");
3906 if (!torture_open_connection(&cli1)) {
3909 if (!torture_open_connection(&cli2)) {
3913 fname = "\\deny_dos1.dat";
3915 smbcli_unlink(cli1->tree, fname);
3916 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3917 fnum2 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3918 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3919 if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
3920 smbcli_unlink(cli1->tree, fname);
3921 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3924 fname = "\\deny_dos2.dat";
3926 smbcli_unlink(cli1->tree, fname);
3927 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3928 fnum2 = smbcli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3929 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3930 if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
3931 smbcli_unlink(cli1->tree, fname);
3932 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3935 torture_close_connection(cli1);
3936 torture_close_connection(cli2);
3942 parse a //server/share type UNC name
3944 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3948 if (strncmp(unc_name, "//", 2)) {
3952 *hostname = strdup(&unc_name[2]);
3953 p = strchr_m(&(*hostname)[2],'/');
3958 *sharename = strdup(p+1);
3965 static void sigcont(void)
3969 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
3972 volatile pid_t *child_status;
3973 volatile BOOL *child_status_out;
3976 double start_time_limit = 10 + (torture_nprocs * 1.5);
3977 char **unc_list = NULL;
3979 int num_unc_names = 0;
3983 signal(SIGCONT, sigcont);
3985 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3986 if (!child_status) {
3987 printf("Failed to setup shared memory\n");
3991 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
3992 if (!child_status_out) {
3993 printf("Failed to setup result status shared memory\n");
3997 p = lp_parm_string(-1, "torture", "unclist");
3999 unc_list = file_lines_load(p, &num_unc_names);
4000 if (!unc_list || num_unc_names <= 0) {
4001 printf("Failed to load unc names list from %s\n", p);
4006 for (i = 0; i < torture_nprocs; i++) {
4007 child_status[i] = 0;
4008 child_status_out[i] = True;
4013 for (i=0;i<torture_nprocs;i++) {
4017 char *hostname=NULL, *sharename;
4019 pid_t mypid = getpid();
4020 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4022 asprintf(&myname, "CLIENT%d", i);
4023 lp_set_cmdline("netbios name", myname);
4028 if (!parse_unc(unc_list[i % num_unc_names],
4029 &hostname, &sharename)) {
4030 printf("Failed to parse UNC name %s\n",
4031 unc_list[i % num_unc_names]);
4038 if (torture_open_connection_share(¤t_cli,
4043 } else if (torture_open_connection(¤t_cli)) {
4047 printf("pid %d failed to start\n", (int)getpid());
4053 child_status[i] = getpid();
4057 if (child_status[i]) {
4058 printf("Child %d failed to start!\n", i);
4059 child_status_out[i] = 1;
4063 child_status_out[i] = fn(current_cli, i);
4070 for (i=0;i<torture_nprocs;i++) {
4071 if (child_status[i]) synccount++;
4073 if (synccount == torture_nprocs) break;
4075 } while (end_timer() < start_time_limit);
4077 if (synccount != torture_nprocs) {
4078 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4083 printf("Starting %d clients\n", torture_nprocs);
4085 /* start the client load */
4087 for (i=0;i<torture_nprocs;i++) {
4088 child_status[i] = 0;
4092 printf("%d clients started\n", torture_nprocs);
4094 for (i=0;i<torture_nprocs;i++) {
4096 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4097 if (ret == -1 || WEXITSTATUS(status) != 0) {
4104 for (i=0;i<torture_nprocs;i++) {
4105 if (!child_status_out[i]) {
4112 #define FLAG_MULTIPROC 1
4120 {"BASE-FDPASS", run_fdpasstest, 0},
4121 {"BASE-LOCK1", run_locktest1, 0},
4122 {"BASE-LOCK2", run_locktest2, 0},
4123 {"BASE-LOCK3", run_locktest3, 0},
4124 {"BASE-LOCK4", run_locktest4, 0},
4125 {"BASE-LOCK5", run_locktest5, 0},
4126 {"BASE-LOCK6", run_locktest6, 0},
4127 {"BASE-LOCK7", run_locktest7, 0},
4128 {"BASE-UNLINK", run_unlinktest, 0},
4129 {"BASE-ATTR", run_attrtest, 0},
4130 {"BASE-TRANS2", run_trans2test, 0},
4131 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4132 {"BASE-DIR", run_dirtest, 0},
4133 {"BASE-DIR1", run_dirtest1, 0},
4134 {"BASE-DENY1", torture_denytest1, 0},
4135 {"BASE-DENY2", torture_denytest2, 0},
4136 {"BASE-TCON", run_tcon_test, 0},
4137 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4138 {"BASE-VUID", run_vuidtest, 0},
4139 {"BASE-RW1", run_readwritetest, 0},
4140 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4141 {"BASE-OPEN", run_opentest, 0},
4142 {"BASE-DENY3", run_deny3test, 0},
4143 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4144 {"BASE-XCOPY", run_xcopy, 0},
4145 {"BASE-RENAME", run_rename, 0},
4146 {"BASE-DELETE", run_deletetest, 0},
4147 {"BASE-PROPERTIES", run_properties, 0},
4148 {"BASE-MANGLE", torture_mangle, 0},
4149 {"BASE-OPENATTR", run_openattrtest, 0},
4150 {"BASE-CHARSET", torture_charset, 0},
4151 {"BASE-CHKPATH", torture_chkpath_test, 0},
4153 /* benchmarking tests */
4154 {"BENCH-HOLDCON", torture_holdcon, 0},
4155 {"BENCH-NBENCH", torture_nbench, 0},
4156 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4159 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4160 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4161 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4162 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4163 {"RAW-SEARCH", torture_raw_search, 0},
4164 {"RAW-CLOSE", torture_raw_close, 0},
4165 {"RAW-OPEN", torture_raw_open, 0},
4166 {"RAW-MKDIR", torture_raw_mkdir, 0},
4167 {"RAW-OPLOCK", torture_raw_oplock, 0},
4168 {"RAW-NOTIFY", torture_raw_notify, 0},
4169 {"RAW-MUX", torture_raw_mux, 0},
4170 {"RAW-IOCTL", torture_raw_ioctl, 0},
4171 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4172 {"RAW-UNLINK", torture_raw_unlink, 0},
4173 {"RAW-READ", torture_raw_read, 0},
4174 {"RAW-WRITE", torture_raw_write, 0},
4175 {"RAW-LOCK", torture_raw_lock, 0},
4176 {"RAW-CONTEXT", torture_raw_context, 0},
4177 {"RAW-RENAME", torture_raw_rename, 0},
4178 {"RAW-SEEK", torture_raw_seek, 0},
4179 {"RAW-RAP", torture_raw_rap, 0},
4181 /* protocol scanners */
4182 {"SCAN-TRANS2", torture_trans2_scan, 0},
4183 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4184 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4185 {"SCAN-SMB", torture_smb_scan, 0},
4186 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4187 {"SCAN-UTABLE", torture_utable, 0},
4188 {"SCAN-CASETABLE", torture_casetable, 0},
4189 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4190 {"SCAN-IOCTL", torture_ioctl_test, 0},
4193 {"RPC-LSA", torture_rpc_lsa, 0},
4194 {"RPC-ECHO", torture_rpc_echo, 0},
4195 {"RPC-DFS", torture_rpc_dfs, 0},
4196 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4197 {"RPC-SAMR", torture_rpc_samr, 0},
4198 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4199 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4200 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4201 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4202 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4203 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4204 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4205 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4206 {"RPC-WINREG", torture_rpc_winreg, 0},
4207 {"RPC-MGMT", torture_rpc_mgmt, 0},
4208 {"RPC-SCANNER", torture_rpc_scanner, 0},
4209 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4210 {"RPC-MULTIBIND", torture_multi_bind, 0},
4211 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4213 /* crypto testers */
4214 {"CRYPT-NTLMSSP", torture_ntlmssp_self_check, 0},
4217 {"LDAP-BASIC", torture_ldap_basic, 0},
4223 /****************************************************************************
4224 run a specified test or "ALL"
4225 ****************************************************************************/
4226 static BOOL run_test(const char *name)
4230 BOOL matched = False;
4232 if (strequal(name,"ALL")) {
4233 for (i=0;torture_ops[i].name;i++) {
4234 if (!run_test(torture_ops[i].name)) {
4241 for (i=0;torture_ops[i].name;i++) {
4242 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4245 printf("Running %s\n", torture_ops[i].name);
4246 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4248 t = torture_create_procs(torture_ops[i].fn, &result);
4251 printf("TEST %s FAILED!\n", torture_ops[i].name);
4256 if (!torture_ops[i].fn(0)) {
4258 printf("TEST %s FAILED!\n", torture_ops[i].name);
4262 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4267 printf("Unknown torture operation '%s'\n", name);
4275 parse a username%password
4277 static void parse_user(const char *user)
4279 char *username, *password = NULL, *p;
4281 username = strdup(user);
4282 p = strchr_m(username,'%');
4285 password = strdup(p+1);
4288 lp_set_cmdline("torture:username", username);
4291 lp_set_cmdline("torture:password", password);
4294 if (!lp_parm_string(-1,"torture","password")) {
4295 password = getpass("password:");
4297 lp_set_cmdline("torture:password", password);
4301 static void parse_dns(const char *dns)
4303 char *userdn, *basedn, *secret;
4306 /* retrievieng the userdn */
4307 p = strchr_m(dns, '#');
4309 lp_set_cmdline("torture:ldap_userdn", "");
4310 lp_set_cmdline("torture:ldap_basedn", "");
4311 lp_set_cmdline("torture:ldap_secret", "");
4314 userdn = strndup(dns, p - dns);
4315 lp_set_cmdline("torture:ldap_userdn", userdn);
4317 /* retrieve the basedn */
4319 p = strchr_m(d, '#');
4321 lp_set_cmdline("torture:ldap_basedn", "");
4322 lp_set_cmdline("torture:ldap_secret", "");
4325 basedn = strndup(d, p - d);
4326 lp_set_cmdline("torture:ldap_basedn", basedn);
4328 /* retrieve the secret */
4331 lp_set_cmdline("torture:ldap_secret", "");
4335 lp_set_cmdline("torture:ldap_secret", secret);
4337 printf ("%s - %s - %s\n", userdn, basedn, secret);
4341 static void usage(void)
4345 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4347 printf("\t-d debuglevel\n");
4348 printf("\t-U user%%pass\n");
4349 printf("\t-k use kerberos\n");
4350 printf("\t-N numprocs\n");
4351 printf("\t-n my_netbios_name\n");
4352 printf("\t-W workgroup\n");
4353 printf("\t-o num_operations\n");
4354 printf("\t-e num files(entries)\n");
4355 printf("\t-O socket_options\n");
4356 printf("\t-m maximum protocol\n");
4357 printf("\t-L use oplocks\n");
4358 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4359 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4360 printf("\t-C filename specifies file with list of UNCs for connections\n");
4361 printf("\t-A showall\n");
4362 printf("\t-p port\n");
4363 printf("\t-s seed\n");
4364 printf("\t-f max failures\n");
4365 printf("\t-X enable dangerous tests\n");
4368 printf("tests are:");
4369 for (i=0;torture_ops[i].name;i++) {
4370 printf(" %s", torture_ops[i].name);
4374 printf("default test is ALL\n");
4379 /****************************************************************************
4381 ****************************************************************************/
4382 int main(int argc,char *argv[])
4386 BOOL correct = True;
4387 char *host, *share, *username;
4389 setup_logging("smbtorture", DEBUG_STDOUT);
4391 #ifdef HAVE_SETBUFFER
4392 setbuffer(stdout, NULL, 0);
4395 lp_load(dyn_CONFIGFILE,True,False,False);
4402 for(p = argv[1]; *p; p++)
4407 /* see if its a RPC transport specifier */
4408 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4409 lp_set_cmdline("torture:binding", argv[1]);
4411 char *binding = NULL;
4413 if (!parse_unc(argv[1], &host, &share)) {
4417 lp_set_cmdline("torture:host", host);
4418 lp_set_cmdline("torture:share", share);
4419 asprintf(&binding, "ncacn_np:%s", host);
4420 lp_set_cmdline("torture:binding", binding);
4423 if (getenv("LOGNAME")) {
4424 username = strdup(getenv("LOGNAME"));
4426 lp_set_cmdline("torture:username", username);
4432 srandom(time(NULL));
4434 while ((opt = getopt(argc, argv, "p:hW:D:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4437 lp_set_cmdline("smb ports", optarg);
4440 lp_set_cmdline("workgroup", optarg);
4443 lp_set_cmdline("protocol", optarg);
4446 lp_set_cmdline("netbios name", optarg);
4449 lp_set_cmdline("debug level", optarg);
4450 setup_logging(NULL, DEBUG_STDOUT);
4453 lp_set_cmdline("socket options", optarg);
4456 srandom(atoi(optarg));
4459 torture_nprocs = atoi(optarg);
4462 torture_numops = atoi(optarg);
4465 torture_entries = atoi(optarg);
4471 torture_showall = True;
4474 lp_set_cmdline("torture:loadfile", optarg);
4477 lp_set_cmdline("torture:unclist", optarg);
4480 lp_set_cmdline("torture:timelimit", optarg);
4484 use_kerberos = True;
4486 d_printf("No kerberos support compiled in\n");
4497 torture_failures = atoi(optarg);
4501 lp_set_cmdline("torture:dangerous", "1");
4505 printf("Unknown option %c (%d)\n", (char)opt, opt);
4510 if (!lp_parm_string(-1,"torture","password")) {
4511 lp_set_cmdline("torture:password", "");
4514 if (argc == optind) {
4515 printf("You must specify a test to run, or 'ALL'\n");
4517 for (i=optind;i<argc;i++) {
4518 if (!run_test(argv[i])) {