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.
22 #include "dynconfig.h"
24 #include "lib/cmdline/popt_common.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "system/time.h"
27 #include "system/wait.h"
28 #include "system/filesys.h"
30 #include "librpc/gen_ndr/ndr_security.h"
33 int torture_numops=100;
34 int torture_entries=1000;
35 int torture_failures=1;
37 static int procnum; /* records process count number when forking */
38 static struct smbcli_state *current_cli;
39 static BOOL use_oplocks;
40 static BOOL use_level_II_oplocks;
42 BOOL torture_showall = False;
44 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
46 static struct smbcli_state *open_nbt_connection(void)
48 struct nbt_name called, calling;
49 struct smbcli_state *cli;
50 const char *host = lp_parm_string(-1, "torture", "host");
52 make_nbt_name_client(&calling, lp_netbios_name());
54 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
56 cli = smbcli_state_init(NULL);
58 printf("Failed initialize smbcli_struct to connect with %s\n", host);
62 if (!smbcli_socket_connect(cli, host)) {
63 printf("Failed to connect with %s\n", host);
67 if (!smbcli_transport_establish(cli, &calling, &called)) {
68 printf("%s rejected the session\n",host);
79 BOOL torture_open_connection_share(struct smbcli_state **c,
81 const char *sharename)
85 status = smbcli_full_connection(NULL,
88 cmdline_credentials, NULL);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("Failed to open connection - %s\n", nt_errstr(status));
94 (*c)->transport->options.use_oplocks = use_oplocks;
95 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
100 BOOL torture_open_connection(struct smbcli_state **c)
102 const char *host = lp_parm_string(-1, "torture", "host");
103 const char *share = lp_parm_string(-1, "torture", "share");
105 return torture_open_connection_share(c, host, share);
110 BOOL torture_close_connection(struct smbcli_state *c)
114 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
115 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
122 /* open a rpc connection to the chosen binding string */
123 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
124 struct dcerpc_pipe **p,
125 const char *pipe_name,
126 const char *pipe_uuid,
127 uint32_t pipe_version)
130 const char *binding = lp_parm_string(-1, "torture", "binding");
133 printf("You must specify a ncacn binding string\n");
134 return NT_STATUS_INVALID_PARAMETER;
137 status = dcerpc_pipe_connect(parent_ctx,
138 p, binding, pipe_uuid, pipe_version,
139 cmdline_credentials, NULL);
144 /* open a rpc connection to a specific transport */
145 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
146 struct dcerpc_pipe **p,
147 const char *pipe_name,
148 const char *pipe_uuid,
149 uint32_t pipe_version,
150 enum dcerpc_transport_t transport)
153 const char *binding = lp_parm_string(-1, "torture", "binding");
154 struct dcerpc_binding *b;
155 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
158 printf("You must specify a ncacn binding string\n");
159 talloc_free(mem_ctx);
160 return NT_STATUS_INVALID_PARAMETER;
163 status = dcerpc_parse_binding(mem_ctx, binding, &b);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
166 talloc_free(mem_ctx);
170 b->transport = transport;
172 status = dcerpc_pipe_connect_b(mem_ctx, p, b, pipe_uuid, pipe_version,
173 cmdline_credentials, NULL);
175 if (NT_STATUS_IS_OK(status)) {
176 *p = talloc_reference(parent_ctx, *p);
180 talloc_free(mem_ctx);
184 /* check if the server produced the expected error code */
185 BOOL check_error(const char *location, struct smbcli_state *c,
186 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
188 if (smbcli_is_dos_error(c->tree)) {
192 /* Check DOS error */
194 smbcli_dos_error(c, &class, &num);
196 if (eclass != class || ecode != num) {
197 printf("unexpected error code class=%d code=%d\n",
198 (int)class, (int)num);
199 printf(" expected %d/%d %s (at %s)\n",
200 (int)eclass, (int)ecode, nt_errstr(nterr), location);
209 status = smbcli_nt_error(c->tree);
211 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
212 printf("unexpected error code %s\n", nt_errstr(status));
213 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
222 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
224 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
225 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
231 static BOOL rw_torture(struct smbcli_state *c)
233 const char *lockfname = "\\torture.lck";
237 pid_t pid2, pid = getpid();
242 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
245 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
247 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
252 for (i=0;i<torture_numops;i++) {
253 uint_t n = (uint_t)random()%10;
255 printf("%d\r", i); fflush(stdout);
257 asprintf(&fname, "\\torture.%u", n);
259 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
263 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
265 printf("open failed (%s)\n", smbcli_errstr(c->tree));
270 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
271 printf("write failed (%s)\n", smbcli_errstr(c->tree));
276 if (smbcli_write(c->tree, fnum, 0, buf,
277 sizeof(pid)+(j*sizeof(buf)),
278 sizeof(buf)) != sizeof(buf)) {
279 printf("write failed (%s)\n", smbcli_errstr(c->tree));
286 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
287 printf("read failed (%s)\n", smbcli_errstr(c->tree));
292 printf("data corruption!\n");
296 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
297 printf("close failed (%s)\n", smbcli_errstr(c->tree));
301 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
302 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
306 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
307 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
313 smbcli_close(c->tree, fnum2);
314 smbcli_unlink(c->tree, lockfname);
321 static BOOL run_torture(struct smbcli_state *cli, int dummy)
325 ret = rw_torture(cli);
327 if (!torture_close_connection(cli)) {
335 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
337 const char *lockfname = "\\torture2.lck";
342 uint8_t buf_rd[131072];
344 ssize_t bytes_read, bytes_written;
346 if (smbcli_deltree(c1->tree, lockfname) == -1) {
347 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
350 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
353 printf("first open read/write of %s failed (%s)\n",
354 lockfname, smbcli_errstr(c1->tree));
357 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
360 printf("second open read-only of %s failed (%s)\n",
361 lockfname, smbcli_errstr(c2->tree));
362 smbcli_close(c1->tree, fnum1);
366 printf("Checking data integrity over %d ops\n", torture_numops);
368 for (i=0;i<torture_numops;i++)
370 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
372 printf("%d\r", i); fflush(stdout);
375 generate_random_buffer(buf, buf_size);
377 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
378 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
379 printf("wrote %d, expected %d\n", bytes_written, buf_size);
384 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
385 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
386 printf("read %d, expected %d\n", bytes_read, buf_size);
391 if (memcmp(buf_rd, buf, buf_size) != 0)
393 printf("read/write compare failed\n");
399 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
400 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
403 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
404 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
408 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
409 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
416 #define BOOLSTR(b) ((b) ? "Yes" : "No")
418 static BOOL run_readwritetest(void)
420 struct smbcli_state *cli1, *cli2;
421 BOOL test1, test2 = True;
423 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
427 printf("starting readwritetest\n");
429 test1 = rw_torture2(cli1, cli2);
430 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
433 test2 = rw_torture2(cli1, cli1);
434 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
437 if (!torture_close_connection(cli1)) {
441 if (!torture_close_connection(cli2)) {
445 return (test1 && test2);
449 this checks to see if a secondary tconx can use open files from an
452 static BOOL run_tcon_test(void)
454 struct smbcli_state *cli;
455 const char *fname = "\\tcontest.tmp";
457 uint16_t cnum1, cnum2, cnum3;
458 uint16_t vuid1, vuid2;
461 struct smbcli_tree *tree1;
462 const char *host = lp_parm_string(-1, "torture", "host");
463 const char *share = lp_parm_string(-1, "torture", "share");
464 const char *password = lp_parm_string(-1, "torture", "password");
466 if (!torture_open_connection(&cli)) {
470 printf("starting tcontest\n");
472 if (smbcli_deltree(cli->tree, fname) == -1) {
473 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
476 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
478 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
482 cnum1 = cli->tree->tid;
483 vuid1 = cli->session->vuid;
485 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
486 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
487 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
491 tree1 = cli->tree; /* save old tree connection */
492 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
493 printf("%s refused 2nd tree connect (%s)\n", host,
494 smbcli_errstr(cli->tree));
499 cnum2 = cli->tree->tid;
500 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
501 vuid2 = cli->session->vuid + 1;
503 /* try a write with the wrong tid */
504 cli->tree->tid = cnum2;
506 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
507 printf("* server allows write with wrong TID\n");
510 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
514 /* try a write with an invalid tid */
515 cli->tree->tid = cnum3;
517 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
518 printf("* server allows write with invalid TID\n");
521 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
524 /* try a write with an invalid vuid */
525 cli->session->vuid = vuid2;
526 cli->tree->tid = cnum1;
528 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
529 printf("* server allows write with invalid VUID\n");
532 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
535 cli->session->vuid = vuid1;
536 cli->tree->tid = cnum1;
538 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
539 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
543 cli->tree->tid = cnum2;
545 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
546 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
550 cli->tree = tree1; /* restore initial tree */
551 cli->tree->tid = cnum1;
553 if (!torture_close_connection(cli)) {
562 static BOOL tcon_devtest(struct smbcli_state *cli,
563 const char *myshare, const char *devtype,
564 NTSTATUS expected_error)
568 const char *password = lp_parm_string(-1, "torture", "password");
570 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
573 printf("Trying share %s with devtype %s\n", myshare, devtype);
575 if (NT_STATUS_IS_OK(expected_error)) {
579 printf("tconX to share %s with type %s "
580 "should have succeeded but failed\n",
587 printf("tconx to share %s with type %s "
588 "should have failed but succeeded\n",
592 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
596 printf("Returned unexpected error\n");
605 checks for correct tconX support
607 static BOOL run_tcon_devtype_test(void)
609 struct smbcli_state *cli1 = NULL;
612 const char *host = lp_parm_string(-1, "torture", "host");
613 const char *share = lp_parm_string(-1, "torture", "share");
615 status = smbcli_full_connection(NULL,
618 cmdline_credentials, NULL);
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("could not open connection\n");
625 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
628 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
631 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
634 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
637 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
640 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
643 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
646 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
649 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
652 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
658 printf("Passed tcondevtest\n");
665 test whether fnums and tids open on one VC are available on another (a major
668 static BOOL run_fdpasstest(void)
670 struct smbcli_state *cli1, *cli2;
671 const char *fname = "\\fdpass.tst";
675 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
679 printf("starting fdpasstest\n");
681 smbcli_unlink(cli1->tree, fname);
683 printf("Opening a file on connection 1\n");
685 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
687 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
691 printf("writing to file on connection 1\n");
693 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
694 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
698 oldtid = cli2->tree->tid;
699 cli2->session->vuid = cli1->session->vuid;
700 cli2->tree->tid = cli1->tree->tid;
701 cli2->session->pid = cli1->session->pid;
703 printf("reading from file on connection 2\n");
705 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
706 printf("read succeeded! nasty security hole [%s]\n",
711 smbcli_close(cli1->tree, fnum1);
712 smbcli_unlink(cli1->tree, fname);
714 cli2->tree->tid = oldtid;
716 torture_close_connection(cli1);
717 torture_close_connection(cli2);
719 printf("finished fdpasstest\n");
725 test the timing of deferred open requests
727 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
729 const char *fname = "\\defer_open_test.dat";
735 printf("failed to connect\n");
739 printf("Testing deferred open requests.\n");
746 tv = timeval_current();
747 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
749 FILE_ATTRIBUTE_NORMAL,
750 NTCREATEX_SHARE_ACCESS_NONE,
751 NTCREATEX_DISP_OPEN_IF, 0, 0);
755 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
756 double e = timeval_elapsed(&tv);
757 if (e < 0.5 || e > 1.5) {
758 fprintf(stderr,"Timing incorrect %.2f violation\n",
762 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
765 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
769 printf("pid %u open %d\n", getpid(), i);
773 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
774 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
780 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
781 /* All until the last unlink will fail with sharing violation. */
782 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
783 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
788 printf("deferred test finished\n");
789 if (!torture_close_connection(cli)) {
796 test how many open files this server supports on the one socket
798 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
800 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
802 int fnums[0x11000], i;
803 int retries=4, maxfid;
807 printf("failed to connect\n");
811 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
812 printf("Failed to deltree \\maxfid - %s\n",
813 smbcli_errstr(cli->tree));
816 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
817 printf("Failed to mkdir \\maxfid, error=%s\n",
818 smbcli_errstr(cli->tree));
822 printf("Testing maximum number of open files\n");
824 for (i=0; i<0x11000; i++) {
826 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
827 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
828 printf("Failed to mkdir %s, error=%s\n",
829 fname, smbcli_errstr(cli->tree));
834 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
835 if ((fnums[i] = smbcli_open(cli->tree, fname,
836 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
838 printf("open of %s failed (%s)\n",
839 fname, smbcli_errstr(cli->tree));
840 printf("maximum fnum is %d\n", i);
851 printf("cleaning up\n");
852 for (i=0;i<maxfid/2;i++) {
853 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
854 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
855 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
857 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
858 printf("unlink of %s failed (%s)\n",
859 fname, smbcli_errstr(cli->tree));
864 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
865 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
866 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
868 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
869 printf("unlink of %s failed (%s)\n",
870 fname, smbcli_errstr(cli->tree));
875 printf("%6d %6d\r", i, maxfid-i);
879 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
880 printf("Failed to deltree \\maxfid - %s\n",
881 smbcli_errstr(cli->tree));
885 printf("maxfid test finished\n");
886 if (!torture_close_connection(cli)) {
890 #undef MAXFID_TEMPLATE
893 /* send smb negprot commands, not reading the response */
894 static BOOL run_negprot_nowait(void)
897 struct smbcli_state *cli, *cli2;
900 printf("starting negprot nowait test\n");
902 cli = open_nbt_connection();
907 printf("Filling send buffer\n");
909 for (i=0;i<10000;i++) {
910 struct smbcli_request *req;
911 time_t t1 = time(NULL);
912 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
913 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
914 smbcli_transport_process(cli->transport);
916 if (req->state == SMBCLI_REQUEST_ERROR) {
917 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
918 torture_close_connection(cli);
921 if (req->state == SMBCLI_REQUEST_SEND) {
927 printf("send buffer failed to fill\n");
928 if (!torture_close_connection(cli)) {
934 printf("send buffer filled after %d requests\n", i);
936 printf("Opening secondary connection\n");
937 if (!torture_open_connection(&cli2)) {
941 if (!torture_close_connection(cli)) {
945 if (!torture_close_connection(cli2)) {
949 printf("finished negprot nowait test\n");
956 This checks how the getatr calls works
958 static BOOL run_attrtest(void)
960 struct smbcli_state *cli;
963 const char *fname = "\\attrib123456789.tst";
966 printf("starting attrib test\n");
968 if (!torture_open_connection(&cli)) {
972 smbcli_unlink(cli->tree, fname);
973 fnum = smbcli_open(cli->tree, fname,
974 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
975 smbcli_close(cli->tree, fnum);
977 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
978 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
982 printf("New file time is %s", ctime(&t));
984 if (abs(t - time(NULL)) > 60*60*24*10) {
985 printf("ERROR: SMBgetatr bug. time is %s",
991 t2 = t-60*60*24; /* 1 day ago */
993 printf("Setting file time to %s", ctime(&t2));
995 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
996 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
1000 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1001 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1005 printf("Retrieved file time as %s", ctime(&t));
1008 printf("ERROR: getatr/setatr bug. times are\n%s",
1010 printf("%s", ctime(&t2));
1014 smbcli_unlink(cli->tree, fname);
1016 if (!torture_close_connection(cli)) {
1020 printf("attrib test finished\n");
1027 This checks a couple of trans2 calls
1029 static BOOL run_trans2test(void)
1031 struct smbcli_state *cli;
1034 time_t c_time, a_time, m_time, w_time, m_time2;
1035 const char *fname = "\\trans2.tst";
1036 const char *dname = "\\trans2";
1037 const char *fname2 = "\\trans2\\trans2.tst";
1039 BOOL correct = True;
1041 printf("starting trans2 test\n");
1043 if (!torture_open_connection(&cli)) {
1047 smbcli_unlink(cli->tree, fname);
1049 printf("Testing qfileinfo\n");
1051 fnum = smbcli_open(cli->tree, fname,
1052 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1053 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1055 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1059 printf("Testing NAME_INFO\n");
1061 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1062 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1066 if (!pname || strcmp(pname, fname)) {
1067 printf("qfilename gave different name? [%s] [%s]\n",
1072 smbcli_close(cli->tree, fnum);
1073 smbcli_unlink(cli->tree, fname);
1075 fnum = smbcli_open(cli->tree, fname,
1076 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1078 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1081 smbcli_close(cli->tree, fnum);
1083 printf("Checking for sticky create times\n");
1085 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1086 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1089 if (c_time != m_time) {
1090 printf("create time=%s", ctime(&c_time));
1091 printf("modify time=%s", ctime(&m_time));
1092 printf("This system appears to have sticky create times\n");
1094 if (a_time % (60*60) == 0) {
1095 printf("access time=%s", ctime(&a_time));
1096 printf("This system appears to set a midnight access time\n");
1100 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1101 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1107 smbcli_unlink(cli->tree, fname);
1108 fnum = smbcli_open(cli->tree, fname,
1109 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1110 smbcli_close(cli->tree, fnum);
1111 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1112 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1115 if (w_time < 60*60*24*2) {
1116 printf("write time=%s", ctime(&w_time));
1117 printf("This system appears to set a initial 0 write time\n");
1122 smbcli_unlink(cli->tree, fname);
1125 /* check if the server updates the directory modification time
1126 when creating a new file */
1127 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1128 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1132 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1133 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1137 fnum = smbcli_open(cli->tree, fname2,
1138 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1139 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1140 smbcli_close(cli->tree, fnum);
1141 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1142 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1145 if (m_time2 == m_time) {
1146 printf("This system does not update directory modification times\n");
1150 smbcli_unlink(cli->tree, fname2);
1151 smbcli_rmdir(cli->tree, dname);
1153 if (!torture_close_connection(cli)) {
1157 printf("trans2 test finished\n");
1164 /* FIRST_DESIRED_ACCESS 0xf019f */
1165 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1166 SEC_FILE_READ_EA| /* 0xf */ \
1167 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1168 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1169 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1170 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1171 /* SECOND_DESIRED_ACCESS 0xe0080 */
1172 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1173 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1174 SEC_STD_WRITE_OWNER /* 0xe0000 */
1177 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1178 READ_CONTROL|WRITE_DAC|\
1179 SEC_FILE_READ_DATA|\
1184 Test ntcreate calls made by xcopy
1186 static BOOL run_xcopy(void)
1188 struct smbcli_state *cli1;
1189 const char *fname = "\\test.txt";
1190 BOOL correct = True;
1193 printf("starting xcopy test\n");
1195 if (!torture_open_connection(&cli1)) {
1199 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1200 FIRST_DESIRED_ACCESS,
1201 FILE_ATTRIBUTE_ARCHIVE,
1202 NTCREATEX_SHARE_ACCESS_NONE,
1203 NTCREATEX_DISP_OVERWRITE_IF,
1207 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1211 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1212 SECOND_DESIRED_ACCESS, 0,
1213 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1216 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1220 if (!torture_close_connection(cli1)) {
1229 see how many RPC pipes we can open at once
1231 static BOOL run_pipe_number(void)
1233 struct smbcli_state *cli1;
1234 const char *pipe_name = "\\WKSSVC";
1238 printf("starting pipenumber test\n");
1239 if (!torture_open_connection(&cli1)) {
1244 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1245 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1248 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1252 printf("%d\r", num_pipes);
1256 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1257 torture_close_connection(cli1);
1265 open N connections to the server and just hold them open
1266 used for testing performance when there are N idle users
1269 static BOOL torture_holdcon(void)
1272 struct smbcli_state **cli;
1275 printf("Opening %d connections\n", torture_numops);
1277 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1279 for (i=0;i<torture_numops;i++) {
1280 if (!torture_open_connection(&cli[i])) {
1283 printf("opened %d connections\r", i);
1287 printf("\nStarting pings\n");
1290 for (i=0;i<torture_numops;i++) {
1293 status = smbcli_chkpath(cli[i]->tree, "\\");
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("Connection %d is dead\n", i);
1303 if (num_dead == torture_numops) {
1304 printf("All connections dead - finishing\n");
1316 Try with a wrong vuid and check error message.
1319 static BOOL run_vuidtest(void)
1321 struct smbcli_state *cli;
1322 const char *fname = "\\vuid.tst";
1325 time_t c_time, a_time, m_time;
1326 BOOL correct = True;
1331 printf("starting vuid test\n");
1333 if (!torture_open_connection(&cli)) {
1337 smbcli_unlink(cli->tree, fname);
1339 fnum = smbcli_open(cli->tree, fname,
1340 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1342 orig_vuid = cli->session->vuid;
1344 cli->session->vuid += 1234;
1346 printf("Testing qfileinfo with wrong vuid\n");
1348 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1349 &size, &c_time, &a_time,
1350 &m_time, NULL, NULL))) {
1351 printf("ERROR: qfileinfo passed with wrong vuid\n");
1355 if ( (cli->transport->error.etype != ETYPE_DOS) ||
1356 (cli->transport->error.e.dos.eclass != ERRSRV) ||
1357 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
1358 printf("ERROR: qfileinfo should have returned DOS error "
1359 "ERRSRV:ERRbaduid\n but returned %s\n",
1360 smbcli_errstr(cli->tree));
1364 cli->session->vuid -= 1234;
1366 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1367 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1371 smbcli_unlink(cli->tree, fname);
1373 if (!torture_close_connection(cli)) {
1377 printf("vuid test finished\n");
1383 Test open mode returns on read-only files.
1385 static BOOL run_opentest(void)
1387 static struct smbcli_state *cli1;
1388 static struct smbcli_state *cli2;
1389 const char *fname = "\\readonly.file";
1390 char *control_char_fname;
1394 BOOL correct = True;
1399 printf("starting open test\n");
1401 if (!torture_open_connection(&cli1)) {
1405 asprintf(&control_char_fname, "\\readonly.afile");
1406 for (i = 1; i <= 0x1f; i++) {
1407 control_char_fname[10] = i;
1408 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1409 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1411 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1412 NT_STATUS_OBJECT_NAME_INVALID)) {
1413 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1414 smbcli_errstr(cli1->tree), i);
1419 smbcli_close(cli1->tree, fnum1);
1421 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1422 smbcli_unlink(cli1->tree, control_char_fname);
1424 free(control_char_fname);
1427 printf("Create file with control char names passed.\n");
1429 smbcli_setatr(cli1->tree, fname, 0, 0);
1430 smbcli_unlink(cli1->tree, fname);
1432 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1434 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1438 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1439 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1443 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1444 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1445 CHECK_MAX_FAILURES(error_test1);
1449 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1451 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1452 CHECK_MAX_FAILURES(error_test1);
1456 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1457 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1459 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1460 NT_STATUS_ACCESS_DENIED)) {
1461 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1464 printf("finished open test 1\n");
1466 smbcli_close(cli1->tree, fnum1);
1468 /* Now try not readonly and ensure ERRbadshare is returned. */
1470 smbcli_setatr(cli1->tree, fname, 0, 0);
1472 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1474 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1478 /* This will fail - but the error should be ERRshare. */
1479 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1481 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1482 NT_STATUS_SHARING_VIOLATION)) {
1483 printf("correct error code ERRDOS/ERRbadshare returned\n");
1486 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1487 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1491 smbcli_unlink(cli1->tree, fname);
1493 printf("finished open test 2\n");
1495 /* Test truncate open disposition on file opened for read. */
1497 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1499 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1503 /* write 20 bytes. */
1505 memset(buf, '\0', 20);
1507 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1508 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1512 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1513 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1517 /* Ensure size == 20. */
1518 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1519 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1520 CHECK_MAX_FAILURES(error_test3);
1525 printf("(3) file size != 20\n");
1526 CHECK_MAX_FAILURES(error_test3);
1530 /* Now test if we can truncate a file opened for readonly. */
1532 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1534 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1535 CHECK_MAX_FAILURES(error_test3);
1539 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1540 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1544 /* Ensure size == 0. */
1545 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1546 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1547 CHECK_MAX_FAILURES(error_test3);
1552 printf("(3) file size != 0\n");
1553 CHECK_MAX_FAILURES(error_test3);
1556 printf("finished open test 3\n");
1558 smbcli_unlink(cli1->tree, fname);
1561 printf("testing ctemp\n");
1562 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1564 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1565 CHECK_MAX_FAILURES(error_test4);
1568 printf("ctemp gave path %s\n", tmp_path);
1569 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1570 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1572 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1573 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1576 /* Test the non-io opens... */
1578 if (!torture_open_connection(&cli2)) {
1582 smbcli_setatr(cli2->tree, fname, 0, 0);
1583 smbcli_unlink(cli2->tree, fname);
1585 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1587 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1588 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1591 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1592 CHECK_MAX_FAILURES(error_test10);
1596 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1597 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1599 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1600 CHECK_MAX_FAILURES(error_test10);
1604 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1605 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1608 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1609 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1613 printf("non-io open test #1 passed.\n");
1615 smbcli_unlink(cli1->tree, fname);
1617 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1619 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1620 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1623 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1624 CHECK_MAX_FAILURES(error_test20);
1628 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1629 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1632 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1633 CHECK_MAX_FAILURES(error_test20);
1637 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1638 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1641 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1642 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1646 printf("non-io open test #2 passed.\n");
1648 smbcli_unlink(cli1->tree, fname);
1650 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1652 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1653 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1656 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1657 CHECK_MAX_FAILURES(error_test30);
1661 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1662 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1665 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1666 CHECK_MAX_FAILURES(error_test30);
1670 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1671 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1674 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1675 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1679 printf("non-io open test #3 passed.\n");
1681 smbcli_unlink(cli1->tree, fname);
1683 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1685 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1686 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1689 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1690 CHECK_MAX_FAILURES(error_test40);
1694 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1695 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1698 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1699 CHECK_MAX_FAILURES(error_test40);
1703 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1705 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1706 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1710 printf("non-io open test #4 passed.\n");
1712 smbcli_unlink(cli1->tree, fname);
1714 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1716 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1717 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1720 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1721 CHECK_MAX_FAILURES(error_test50);
1725 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1726 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1729 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1730 CHECK_MAX_FAILURES(error_test50);
1734 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1735 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1739 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1740 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1744 printf("non-io open test #5 passed.\n");
1746 printf("TEST #6 testing 1 non-io open, one io open\n");
1748 smbcli_unlink(cli1->tree, fname);
1750 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1751 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1754 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1755 CHECK_MAX_FAILURES(error_test60);
1759 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1760 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1763 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1764 CHECK_MAX_FAILURES(error_test60);
1768 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1769 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1773 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1774 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1778 printf("non-io open test #6 passed.\n");
1780 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1782 smbcli_unlink(cli1->tree, fname);
1784 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1785 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1788 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1789 CHECK_MAX_FAILURES(error_test70);
1793 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1794 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1797 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1798 CHECK_MAX_FAILURES(error_test70);
1802 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1804 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1805 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1809 printf("non-io open test #7 passed.\n");
1813 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1815 smbcli_unlink(cli1->tree, fname);
1817 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1819 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1823 /* write 20 bytes. */
1825 memset(buf, '\0', 20);
1827 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1828 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1832 /* Ensure size == 20. */
1833 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1834 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1835 CHECK_MAX_FAILURES(error_test80);
1840 printf("(8) file size != 20\n");
1841 CHECK_MAX_FAILURES(error_test80);
1845 /* Get an exclusive lock on the open file. */
1846 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1847 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1848 CHECK_MAX_FAILURES(error_test80);
1852 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1854 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1858 /* Ensure size == 0. */
1859 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1860 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1861 CHECK_MAX_FAILURES(error_test80);
1866 printf("(8) file size != 0\n");
1867 CHECK_MAX_FAILURES(error_test80);
1871 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1872 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1876 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1877 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1883 printf("open test #8 passed.\n");
1885 smbcli_unlink(cli1->tree, fname);
1887 if (!torture_close_connection(cli1)) {
1890 if (!torture_close_connection(cli2)) {
1899 sees what IOCTLs are supported
1901 BOOL torture_ioctl_test(void)
1903 struct smbcli_state *cli;
1904 uint16_t device, function;
1906 const char *fname = "\\ioctl.dat";
1908 union smb_ioctl parms;
1909 TALLOC_CTX *mem_ctx;
1911 if (!torture_open_connection(&cli)) {
1915 mem_ctx = talloc_init("ioctl_test");
1917 printf("starting ioctl test\n");
1919 smbcli_unlink(cli->tree, fname);
1921 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1923 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1927 parms.ioctl.level = RAW_IOCTL_IOCTL;
1928 parms.ioctl.in.fnum = fnum;
1929 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1930 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1931 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1933 for (device=0;device<0x100;device++) {
1934 printf("testing device=0x%x\n", device);
1935 for (function=0;function<0x100;function++) {
1936 parms.ioctl.in.request = (device << 16) | function;
1937 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1939 if (NT_STATUS_IS_OK(status)) {
1940 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1941 device, function, parms.ioctl.out.blob.length);
1946 if (!torture_close_connection(cli)) {
1955 tries variants of chkpath
1957 BOOL torture_chkpath_test(void)
1959 struct smbcli_state *cli;
1963 if (!torture_open_connection(&cli)) {
1967 printf("starting chkpath test\n");
1969 printf("Testing valid and invalid paths\n");
1971 /* cleanup from an old run */
1972 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1973 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1974 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1976 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1977 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1981 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1982 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1986 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1988 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1991 smbcli_close(cli->tree, fnum);
1993 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1994 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1998 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1999 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
2003 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
2004 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2005 NT_STATUS_NOT_A_DIRECTORY);
2007 printf("* chkpath on a file should fail\n");
2011 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2012 ret = check_error(__location__, cli, ERRDOS, ERRbadfile,
2013 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2015 printf("* chkpath on a non existent file should fail\n");
2019 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2020 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2021 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2023 printf("* chkpath on a non existent component should fail\n");
2027 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2028 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2029 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2031 if (!torture_close_connection(cli)) {
2039 static void sigcont(int sig)
2043 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2046 volatile pid_t *child_status;
2047 volatile BOOL *child_status_out;
2050 double start_time_limit = 10 + (torture_nprocs * 1.5);
2051 char **unc_list = NULL;
2053 int num_unc_names = 0;
2060 signal(SIGCONT, sigcont);
2062 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2063 if (!child_status) {
2064 printf("Failed to setup shared memory\n");
2068 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2069 if (!child_status_out) {
2070 printf("Failed to setup result status shared memory\n");
2074 p = lp_parm_string(-1, "torture", "unclist");
2076 unc_list = file_lines_load(p, &num_unc_names);
2077 if (!unc_list || num_unc_names <= 0) {
2078 printf("Failed to load unc names list from '%s'\n", p);
2083 for (i = 0; i < torture_nprocs; i++) {
2084 child_status[i] = 0;
2085 child_status_out[i] = True;
2088 tv = timeval_current();
2090 for (i=0;i<torture_nprocs;i++) {
2094 const char *hostname=NULL, *sharename;
2096 pid_t mypid = getpid();
2097 srandom(((int)mypid) ^ ((int)time(NULL)));
2099 asprintf(&myname, "CLIENT%d", i);
2100 lp_set_cmdline("netbios name", myname);
2105 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2106 NULL, &hostname, &sharename)) {
2107 printf("Failed to parse UNC name %s\n",
2108 unc_list[i % num_unc_names]);
2115 if (torture_open_connection_share(¤t_cli,
2120 } else if (torture_open_connection(¤t_cli)) {
2124 printf("pid %d failed to start\n", (int)getpid());
2130 child_status[i] = getpid();
2134 if (child_status[i]) {
2135 printf("Child %d failed to start!\n", i);
2136 child_status_out[i] = 1;
2140 child_status_out[i] = fn(current_cli, i);
2147 for (i=0;i<torture_nprocs;i++) {
2148 if (child_status[i]) synccount++;
2150 if (synccount == torture_nprocs) break;
2152 } while (timeval_elapsed(&tv) < start_time_limit);
2154 if (synccount != torture_nprocs) {
2155 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2157 return timeval_elapsed(&tv);
2160 printf("Starting %d clients\n", torture_nprocs);
2162 /* start the client load */
2163 tv = timeval_current();
2164 for (i=0;i<torture_nprocs;i++) {
2165 child_status[i] = 0;
2168 printf("%d clients started\n", torture_nprocs);
2172 for (i=0;i<torture_nprocs;i++) {
2174 while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2175 if (ret == -1 || WEXITSTATUS(status) != 0) {
2182 for (i=0;i<torture_nprocs;i++) {
2183 if (!child_status_out[i]) {
2187 return timeval_elapsed(&tv);
2190 #define FLAG_MULTIPROC 1
2195 BOOL (*multi_fn)(struct smbcli_state *, int );
2198 {"BASE-FDPASS", run_fdpasstest, 0},
2199 {"BASE-LOCK1", torture_locktest1, 0},
2200 {"BASE-LOCK2", torture_locktest2, 0},
2201 {"BASE-LOCK3", torture_locktest3, 0},
2202 {"BASE-LOCK4", torture_locktest4, 0},
2203 {"BASE-LOCK5", torture_locktest5, 0},
2204 {"BASE-LOCK6", torture_locktest6, 0},
2205 {"BASE-LOCK7", torture_locktest7, 0},
2206 {"BASE-UNLINK", torture_unlinktest, 0},
2207 {"BASE-ATTR", run_attrtest, 0},
2208 {"BASE-TRANS2", run_trans2test, 0},
2209 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2210 {"BASE-DIR1", torture_dirtest1, 0},
2211 {"BASE-DIR2", torture_dirtest2, 0},
2212 {"BASE-DENY1", torture_denytest1, 0},
2213 {"BASE-DENY2", torture_denytest2, 0},
2214 {"BASE-DENY3", torture_denytest3, 0},
2215 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2216 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2217 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2218 {"BASE-TCON", run_tcon_test, 0},
2219 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2220 {"BASE-VUID", run_vuidtest, 0},
2221 {"BASE-RW1", run_readwritetest, 0},
2222 {"BASE-OPEN", run_opentest, 0},
2223 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2224 {"BASE-XCOPY", run_xcopy, 0},
2225 {"BASE-RENAME", torture_test_rename, 0},
2226 {"BASE-DELETE", torture_test_delete, 0},
2227 {"BASE-PROPERTIES", torture_test_properties, 0},
2228 {"BASE-MANGLE", torture_mangle, 0},
2229 {"BASE-OPENATTR", torture_openattrtest, 0},
2230 {"BASE-CHARSET", torture_charset, 0},
2231 {"BASE-CHKPATH", torture_chkpath_test, 0},
2232 {"BASE-SECLEAK", torture_sec_leak, 0},
2233 {"BASE-DISCONNECT", torture_disconnect, 0},
2234 {"BASE-DELAYWRITE", torture_delay_write, 0},
2236 /* benchmarking tests */
2237 {"BENCH-HOLDCON", torture_holdcon, 0},
2238 {"BENCH-NBENCH", torture_nbench, 0},
2239 {"BENCH-TORTURE", NULL, run_torture},
2240 {"BENCH-NBT", torture_bench_nbt, 0},
2241 {"BENCH-WINS", torture_bench_wins, 0},
2242 {"BENCH-RPC", torture_bench_rpc, 0},
2243 {"BENCH-CLDAP", torture_bench_cldap, 0},
2246 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2247 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2248 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2249 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2250 {"RAW-SEARCH", torture_raw_search, 0},
2251 {"RAW-CLOSE", torture_raw_close, 0},
2252 {"RAW-OPEN", torture_raw_open, 0},
2253 {"RAW-MKDIR", torture_raw_mkdir, 0},
2254 {"RAW-OPLOCK", torture_raw_oplock, 0},
2255 {"RAW-NOTIFY", torture_raw_notify, 0},
2256 {"RAW-MUX", torture_raw_mux, 0},
2257 {"RAW-IOCTL", torture_raw_ioctl, 0},
2258 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2259 {"RAW-UNLINK", torture_raw_unlink, 0},
2260 {"RAW-READ", torture_raw_read, 0},
2261 {"RAW-WRITE", torture_raw_write, 0},
2262 {"RAW-LOCK", torture_raw_lock, 0},
2263 {"RAW-CONTEXT", torture_raw_context, 0},
2264 {"RAW-RENAME", torture_raw_rename, 0},
2265 {"RAW-SEEK", torture_raw_seek, 0},
2266 {"RAW-EAS", torture_raw_eas, 0},
2267 {"RAW-EAMAX", torture_max_eas, 0},
2268 {"RAW-STREAMS", torture_raw_streams, 0},
2269 {"RAW-ACLS", torture_raw_acls, 0},
2270 {"RAW-RAP", torture_raw_rap, 0},
2271 {"RAW-COMPOSITE", torture_raw_composite, 0},
2273 /* protocol scanners */
2274 {"SCAN-TRANS2", torture_trans2_scan, 0},
2275 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2276 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2277 {"SCAN-SMB", torture_smb_scan, 0},
2278 {"SCAN-MAXFID", NULL, run_maxfidtest},
2279 {"SCAN-UTABLE", torture_utable, 0},
2280 {"SCAN-CASETABLE", torture_casetable, 0},
2281 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2282 {"SCAN-IOCTL", torture_ioctl_test, 0},
2283 {"SCAN-RAP", torture_rap_scan, 0},
2286 {"RPC-LSA", torture_rpc_lsa, 0},
2287 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2288 {"RPC-ECHO", torture_rpc_echo, 0},
2289 {"RPC-DFS", torture_rpc_dfs, 0},
2290 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2291 {"RPC-SAMR", torture_rpc_samr, 0},
2292 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2293 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2294 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2295 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2296 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2297 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2298 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2299 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2300 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2301 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2302 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2303 {"RPC-WINREG", torture_rpc_winreg, 0},
2304 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2305 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2306 {"RPC-REMACT", torture_rpc_remact, 0},
2307 {"RPC-MGMT", torture_rpc_mgmt, 0},
2308 {"RPC-SCANNER", torture_rpc_scanner, 0},
2309 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2310 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2311 {"RPC-MULTIBIND", torture_multi_bind, 0},
2312 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2313 {"RPC-LOGIN", torture_rpc_login, 0},
2314 {"RPC-ROT", torture_rpc_rot, 0},
2315 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2316 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2318 /* local (no server) testers */
2319 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2320 {"LOCAL-ICONV", torture_local_iconv, 0},
2321 {"LOCAL-TALLOC", torture_local_talloc, 0},
2322 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2323 {"LOCAL-IRPC", torture_local_irpc, 0},
2324 {"LOCAL-BINDING", torture_local_binding_string, 0},
2325 {"LOCAL-IDTREE", torture_local_idtree, 0},
2326 {"LOCAL-SOCKET", torture_local_socket, 0},
2328 /* COM (Component Object Model) testers */
2329 {"COM-SIMPLE", torture_com_simple, 0 },
2332 {"LDAP-BASIC", torture_ldap_basic, 0},
2333 {"LDAP-CLDAP", torture_cldap, 0},
2336 {"NBT-REGISTER", torture_nbt_register, 0},
2337 {"NBT-WINS", torture_nbt_wins, 0},
2338 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2339 {"NBT-DGRAM", torture_nbt_dgram, 0},
2342 {"NET-USERINFO", torture_userinfo, 0},
2343 {"NET-USERADD", torture_useradd, 0},
2344 {"NET-USERDEL", torture_userdel, 0},
2345 {"NET-DOMOPEN", torture_domainopen, 0},
2346 {"NET-API-LOOKUP", torture_lookup, 0},
2347 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2348 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2349 {"NET-API-CREATEUSER", torture_createuser, 0},
2350 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2356 /****************************************************************************
2357 run a specified test or "ALL"
2358 ****************************************************************************/
2359 static BOOL run_test(const char *name)
2363 BOOL matched = False;
2365 if (strequal(name,"ALL")) {
2366 for (i=0;torture_ops[i].name;i++) {
2367 if (!run_test(torture_ops[i].name)) {
2374 for (i=0;torture_ops[i].name;i++) {
2375 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2379 printf("Running %s\n", torture_ops[i].name);
2380 if (torture_ops[i].multi_fn) {
2381 BOOL result = False;
2382 t = torture_create_procs(torture_ops[i].multi_fn,
2386 printf("TEST %s FAILED!\n", torture_ops[i].name);
2390 struct timeval tv = timeval_current();
2391 if (!torture_ops[i].fn()) {
2393 printf("TEST %s FAILED!\n", torture_ops[i].name);
2395 t = timeval_elapsed(&tv);
2397 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2402 printf("Unknown torture operation '%s'\n", name);
2409 static void parse_dns(const char *dns)
2411 char *userdn, *basedn, *secret;
2414 /* retrievieng the userdn */
2415 p = strchr_m(dns, '#');
2417 lp_set_cmdline("torture:ldap_userdn", "");
2418 lp_set_cmdline("torture:ldap_basedn", "");
2419 lp_set_cmdline("torture:ldap_secret", "");
2422 userdn = strndup(dns, p - dns);
2423 lp_set_cmdline("torture:ldap_userdn", userdn);
2425 /* retrieve the basedn */
2427 p = strchr_m(d, '#');
2429 lp_set_cmdline("torture:ldap_basedn", "");
2430 lp_set_cmdline("torture:ldap_secret", "");
2433 basedn = strndup(d, p - d);
2434 lp_set_cmdline("torture:ldap_basedn", basedn);
2436 /* retrieve the secret */
2439 lp_set_cmdline("torture:ldap_secret", "");
2443 lp_set_cmdline("torture:ldap_secret", secret);
2445 printf ("%s - %s - %s\n", userdn, basedn, secret);
2449 static void usage(poptContext pc)
2454 poptPrintUsage(pc, stdout, 0);
2457 printf("The binding format is:\n\n");
2459 printf(" TRANSPORT:host[flags]\n\n");
2461 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2463 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2464 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2465 printf(" string.\n\n");
2467 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2468 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2469 printf(" will be auto-determined.\n\n");
2471 printf(" other recognised flags are:\n\n");
2473 printf(" sign : enable ntlmssp signing\n");
2474 printf(" seal : enable ntlmssp sealing\n");
2475 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2476 printf(" validate: enable the NDR validator\n");
2477 printf(" print: enable debugging of the packets\n");
2478 printf(" bigendian: use bigendian RPC\n");
2479 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2481 printf(" For example, these all connect to the samr pipe:\n\n");
2483 printf(" ncacn_np:myserver\n");
2484 printf(" ncacn_np:myserver[samr]\n");
2485 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2486 printf(" ncacn_np:myserver[/pipe/samr]\n");
2487 printf(" ncacn_np:myserver[samr,sign,print]\n");
2488 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2489 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2490 printf(" ncacn_np:\n");
2491 printf(" ncacn_np:[/pipe/samr]\n\n");
2493 printf(" ncacn_ip_tcp:myserver\n");
2494 printf(" ncacn_ip_tcp:myserver[1024]\n");
2495 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2497 printf("The unc format is:\n\n");
2499 printf(" //server/share\n\n");
2501 printf("tests are:");
2502 for (i=0;torture_ops[i].name;i++) {
2503 if ((i%perline)==0) {
2506 printf("%s ", torture_ops[i].name);
2510 printf("default test is ALL\n");
2515 static BOOL is_binding_string(const char *binding_string)
2517 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2518 struct dcerpc_binding *binding_struct;
2521 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2523 talloc_free(mem_ctx);
2524 return NT_STATUS_IS_OK(status);
2527 static void max_runtime_handler(int sig)
2529 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2533 /****************************************************************************
2535 ****************************************************************************/
2536 int main(int argc,char *argv[])
2540 BOOL correct = True;
2545 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2546 struct poptOption long_options[] = {
2548 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2549 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2550 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2551 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2552 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2553 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2554 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2555 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2556 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2557 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2558 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2559 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2560 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2561 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2562 "set maximum time for smbtorture to live", "seconds"},
2564 POPT_COMMON_CONNECTION
2565 POPT_COMMON_CREDENTIALS
2570 #ifdef HAVE_SETBUFFER
2571 setbuffer(stdout, NULL, 0);
2574 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2575 POPT_CONTEXT_KEEP_FIRST);
2577 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2579 while((opt = poptGetNextOpt(pc)) != -1) {
2582 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2585 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2588 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2591 parse_dns(poptGetOptArg(pc));
2594 lp_set_cmdline("torture:dangerous", "Yes");
2597 d_printf("Invalid option %s: %s\n",
2598 poptBadOption(pc, 0), poptStrerror(opt));
2605 /* this will only work if nobody else uses alarm(),
2606 which means it won't work for some tests, but we
2607 can't use the event context method we use for smbd
2608 as so many tests create their own event
2609 context. This will at least catch most cases. */
2610 signal(SIGALRM, max_runtime_handler);
2614 smbtorture_init_subsystems;
2617 if (torture_seed == 0) {
2618 torture_seed = time(NULL);
2620 printf("Using seed %d\n", torture_seed);
2621 srandom(torture_seed);
2623 argv_new = discard_const_p(char *, poptGetArgs(pc));
2626 for (i=0; i<argc; i++) {
2627 if (argv_new[i] == NULL) {
2638 for(p = argv_new[1]; *p; p++) {
2643 /* see if its a RPC transport specifier */
2644 if (is_binding_string(argv_new[1])) {
2645 lp_set_cmdline("torture:binding", argv_new[1]);
2647 char *binding = NULL;
2648 const char *host = NULL, *share = NULL;
2650 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2651 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2655 lp_set_cmdline("torture:host", host);
2656 lp_set_cmdline("torture:share", share);
2657 asprintf(&binding, "ncacn_np:%s", host);
2658 lp_set_cmdline("torture:binding", binding);
2661 if (argc_new == 0) {
2662 printf("You must specify a test to run, or 'ALL'\n");
2664 for (i=2;i<argc_new;i++) {
2665 if (!run_test(argv_new[i])) {