2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "torture/torture.h"
24 #include "torture/basic/proto.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 #include "system/filesys.h"
28 #include "system/time.h"
29 #include "libcli/resolve/resolve.h"
30 #include "librpc/gen_ndr/ndr_nbt.h"
31 #include "lib/events/events.h"
32 #include "lib/cmdline/popt_common.h"
35 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
38 static struct smbcli_state
*open_nbt_connection(void)
40 struct nbt_name called
, calling
;
41 struct smbcli_state
*cli
;
42 const char *host
= lp_parm_string(-1, "torture", "host");
44 make_nbt_name_client(&calling
, lp_netbios_name());
46 nbt_choose_called_name(NULL
, &called
, host
, NBT_NAME_SERVER
);
48 cli
= smbcli_state_init(NULL
);
50 printf("Failed initialize smbcli_struct to connect with %s\n", host
);
54 if (!smbcli_socket_connect(cli
, host
)) {
55 printf("Failed to connect with %s\n", host
);
59 if (!smbcli_transport_establish(cli
, &calling
, &called
)) {
60 printf("%s rejected the session\n",host
);
71 static BOOL
tcon_devtest(struct smbcli_state
*cli
,
72 const char *myshare
, const char *devtype
,
73 NTSTATUS expected_error
)
77 const char *password
= lp_parm_string(-1, "torture", "password");
79 status
= NT_STATUS_IS_OK(smbcli_tconX(cli
, myshare
, devtype
,
82 printf("Trying share %s with devtype %s\n", myshare
, devtype
);
84 if (NT_STATUS_IS_OK(expected_error
)) {
88 printf("tconX to share %s with type %s "
89 "should have succeeded but failed\n",
96 printf("tconx to share %s with type %s "
97 "should have failed but succeeded\n",
101 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),
105 printf("Returned unexpected error\n");
116 test whether fnums and tids open on one VC are available on another (a major
119 static BOOL
run_fdpasstest(struct torture_context
*torture
)
121 struct smbcli_state
*cli1
, *cli2
;
122 const char *fname
= "\\fdpass.tst";
126 if (!torture_open_connection(&cli1
) || !torture_open_connection(&cli2
)) {
130 printf("starting fdpasstest\n");
132 smbcli_unlink(cli1
->tree
, fname
);
134 printf("Opening a file on connection 1\n");
136 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
138 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
142 printf("writing to file on connection 1\n");
144 if (smbcli_write(cli1
->tree
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
145 printf("write failed (%s)\n", smbcli_errstr(cli1
->tree
));
149 oldtid
= cli2
->tree
->tid
;
150 cli2
->session
->vuid
= cli1
->session
->vuid
;
151 cli2
->tree
->tid
= cli1
->tree
->tid
;
152 cli2
->session
->pid
= cli1
->session
->pid
;
154 printf("reading from file on connection 2\n");
156 if (smbcli_read(cli2
->tree
, fnum1
, buf
, 0, 13) == 13) {
157 printf("read succeeded! nasty security hole [%s]\n",
162 smbcli_close(cli1
->tree
, fnum1
);
163 smbcli_unlink(cli1
->tree
, fname
);
165 cli2
->tree
->tid
= oldtid
;
167 torture_close_connection(cli1
);
168 torture_close_connection(cli2
);
170 printf("finished fdpasstest\n");
175 This checks how the getatr calls works
177 static BOOL
run_attrtest(struct torture_context
*torture
)
179 struct smbcli_state
*cli
;
182 const char *fname
= "\\attrib123456789.tst";
185 printf("starting attrib test\n");
187 if (!torture_open_connection(&cli
)) {
191 smbcli_unlink(cli
->tree
, fname
);
192 fnum
= smbcli_open(cli
->tree
, fname
,
193 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
194 smbcli_close(cli
->tree
, fnum
);
196 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
197 printf("getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
201 printf("New file time is %s", ctime(&t
));
203 if (abs(t
- time(NULL
)) > 60*60*24*10) {
204 printf("ERROR: SMBgetatr bug. time is %s",
210 t2
= t
-60*60*24; /* 1 day ago */
212 printf("Setting file time to %s", ctime(&t2
));
214 if (NT_STATUS_IS_ERR(smbcli_setatr(cli
->tree
, fname
, 0, t2
))) {
215 printf("setatr failed (%s)\n", smbcli_errstr(cli
->tree
));
219 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
220 printf("getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
224 printf("Retrieved file time as %s", ctime(&t
));
227 printf("ERROR: getatr/setatr bug. times are\n%s",
229 printf("%s", ctime(&t2
));
233 smbcli_unlink(cli
->tree
, fname
);
235 if (!torture_close_connection(cli
)) {
239 printf("attrib test finished\n");
245 This checks a couple of trans2 calls
247 static BOOL
run_trans2test(struct torture_context
*torture
)
249 struct smbcli_state
*cli
;
252 time_t c_time
, a_time
, m_time
, w_time
, m_time2
;
253 const char *fname
= "\\trans2.tst";
254 const char *dname
= "\\trans2";
255 const char *fname2
= "\\trans2\\trans2.tst";
259 printf("starting trans2 test\n");
261 if (!torture_open_connection(&cli
)) {
265 smbcli_unlink(cli
->tree
, fname
);
267 printf("Testing qfileinfo\n");
269 fnum
= smbcli_open(cli
->tree
, fname
,
270 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
271 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli
->tree
, fnum
, NULL
, &size
, &c_time
, &a_time
, &m_time
,
273 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
277 printf("Testing NAME_INFO\n");
279 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli
->tree
, fnum
, &pname
))) {
280 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli
->tree
));
284 if (!pname
|| strcmp(pname
, fname
)) {
285 printf("qfilename gave different name? [%s] [%s]\n",
290 smbcli_close(cli
->tree
, fnum
);
291 smbcli_unlink(cli
->tree
, fname
);
293 fnum
= smbcli_open(cli
->tree
, fname
,
294 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
296 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
299 smbcli_close(cli
->tree
, fnum
);
301 printf("Checking for sticky create times\n");
303 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
))) {
304 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
307 if (c_time
!= m_time
) {
308 printf("create time=%s", ctime(&c_time
));
309 printf("modify time=%s", ctime(&m_time
));
310 printf("This system appears to have sticky create times\n");
312 if (a_time
% (60*60) == 0) {
313 printf("access time=%s", ctime(&a_time
));
314 printf("This system appears to set a midnight access time\n");
318 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
319 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
325 smbcli_unlink(cli
->tree
, fname
);
326 fnum
= smbcli_open(cli
->tree
, fname
,
327 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
328 smbcli_close(cli
->tree
, fnum
);
329 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
330 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
333 if (w_time
< 60*60*24*2) {
334 printf("write time=%s", ctime(&w_time
));
335 printf("This system appears to set a initial 0 write time\n");
340 smbcli_unlink(cli
->tree
, fname
);
343 /* check if the server updates the directory modification time
344 when creating a new file */
345 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, dname
))) {
346 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli
->tree
));
350 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
351 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
355 fnum
= smbcli_open(cli
->tree
, fname2
,
356 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
357 smbcli_write(cli
->tree
, fnum
, 0, &fnum
, 0, sizeof(fnum
));
358 smbcli_close(cli
->tree
, fnum
);
359 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time2
, &w_time
, &size
, NULL
, NULL
))) {
360 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
363 if (m_time2
== m_time
) {
364 printf("This system does not update directory modification times\n");
368 smbcli_unlink(cli
->tree
, fname2
);
369 smbcli_rmdir(cli
->tree
, dname
);
371 if (!torture_close_connection(cli
)) {
375 printf("trans2 test finished\n");
380 /* send smb negprot commands, not reading the response */
381 static BOOL
run_negprot_nowait(struct torture_context
*torture
)
384 struct smbcli_state
*cli
, *cli2
;
387 printf("starting negprot nowait test\n");
389 cli
= open_nbt_connection();
394 printf("Filling send buffer\n");
396 for (i
=0;i
<100;i
++) {
397 struct smbcli_request
*req
;
398 req
= smb_raw_negotiate_send(cli
->transport
, PROTOCOL_NT1
);
399 event_loop_once(cli
->transport
->socket
->event
.ctx
);
400 if (req
->state
== SMBCLI_REQUEST_ERROR
) {
402 printf("Failed to fill pipe packet[%d] - %s (ignored)\n", i
+1, nt_errstr(req
->status
));
405 printf("Failed to fill pipe - %s \n", nt_errstr(req
->status
));
406 torture_close_connection(cli
);
412 printf("Opening secondary connection\n");
413 if (!torture_open_connection(&cli2
)) {
414 printf("Failed to open secondary connection\n");
418 if (!torture_close_connection(cli2
)) {
419 printf("Failed to close secondary connection\n");
423 torture_close_connection(cli
);
425 printf("finished negprot nowait test\n");
431 this checks to see if a secondary tconx can use open files from an
434 static BOOL
run_tcon_test(struct torture_context
*torture
)
436 struct smbcli_state
*cli
;
437 const char *fname
= "\\tcontest.tmp";
439 uint16_t cnum1
, cnum2
, cnum3
;
440 uint16_t vuid1
, vuid2
;
443 struct smbcli_tree
*tree1
;
444 const char *host
= lp_parm_string(-1, "torture", "host");
445 const char *share
= lp_parm_string(-1, "torture", "share");
446 const char *password
= lp_parm_string(-1, "torture", "password");
448 if (!torture_open_connection(&cli
)) {
452 printf("starting tcontest\n");
454 if (smbcli_deltree(cli
->tree
, fname
) == -1) {
455 printf("unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
458 fnum1
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
460 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
464 cnum1
= cli
->tree
->tid
;
465 vuid1
= cli
->session
->vuid
;
467 memset(&buf
, 0, 4); /* init buf so valgrind won't complain */
468 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) != 4) {
469 printf("initial write failed (%s)\n", smbcli_errstr(cli
->tree
));
473 tree1
= cli
->tree
; /* save old tree connection */
474 if (NT_STATUS_IS_ERR(smbcli_tconX(cli
, share
, "?????", password
))) {
475 printf("%s refused 2nd tree connect (%s)\n", host
,
476 smbcli_errstr(cli
->tree
));
481 cnum2
= cli
->tree
->tid
;
482 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
483 vuid2
= cli
->session
->vuid
+ 1;
485 /* try a write with the wrong tid */
486 cli
->tree
->tid
= cnum2
;
488 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
489 printf("* server allows write with wrong TID\n");
492 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli
->tree
));
496 /* try a write with an invalid tid */
497 cli
->tree
->tid
= cnum3
;
499 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
500 printf("* server allows write with invalid TID\n");
503 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli
->tree
));
506 /* try a write with an invalid vuid */
507 cli
->session
->vuid
= vuid2
;
508 cli
->tree
->tid
= cnum1
;
510 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
511 printf("* server allows write with invalid VUID\n");
514 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli
->tree
));
517 cli
->session
->vuid
= vuid1
;
518 cli
->tree
->tid
= cnum1
;
520 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum1
))) {
521 printf("close failed (%s)\n", smbcli_errstr(cli
->tree
));
525 cli
->tree
->tid
= cnum2
;
527 if (NT_STATUS_IS_ERR(smbcli_tdis(cli
))) {
528 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli
->tree
));
532 cli
->tree
= tree1
; /* restore initial tree */
533 cli
->tree
->tid
= cnum1
;
535 smbcli_unlink(tree1
, fname
);
537 if (!torture_close_connection(cli
)) {
545 checks for correct tconX support
547 static BOOL
run_tcon_devtype_test(struct torture_context
*torture
)
549 struct smbcli_state
*cli1
= NULL
;
552 const char *host
= lp_parm_string(-1, "torture", "host");
553 const char *share
= lp_parm_string(-1, "torture", "share");
555 status
= smbcli_full_connection(NULL
,
558 cmdline_credentials
, NULL
);
560 if (!NT_STATUS_IS_OK(status
)) {
561 printf("could not open connection\n");
565 if (!tcon_devtest(cli1
, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE
))
568 if (!tcon_devtest(cli1
, "IPC$", "?????", NT_STATUS_OK
))
571 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
574 if (!tcon_devtest(cli1
, "IPC$", "IPC", NT_STATUS_OK
))
577 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
580 if (!tcon_devtest(cli1
, share
, "A:", NT_STATUS_OK
))
583 if (!tcon_devtest(cli1
, share
, "?????", NT_STATUS_OK
))
586 if (!tcon_devtest(cli1
, share
, "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
589 if (!tcon_devtest(cli1
, share
, "IPC", NT_STATUS_BAD_DEVICE_TYPE
))
592 if (!tcon_devtest(cli1
, share
, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
598 printf("Passed tcondevtest\n");
603 static BOOL
rw_torture2(struct smbcli_state
*c1
, struct smbcli_state
*c2
)
605 const char *lockfname
= "\\torture2.lck";
610 uint8_t buf_rd
[131072];
612 ssize_t bytes_read
, bytes_written
;
614 if (smbcli_deltree(c1
->tree
, lockfname
) == -1) {
615 printf("unlink failed (%s)\n", smbcli_errstr(c1
->tree
));
618 fnum1
= smbcli_open(c1
->tree
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
621 printf("first open read/write of %s failed (%s)\n",
622 lockfname
, smbcli_errstr(c1
->tree
));
625 fnum2
= smbcli_open(c2
->tree
, lockfname
, O_RDONLY
,
628 printf("second open read-only of %s failed (%s)\n",
629 lockfname
, smbcli_errstr(c2
->tree
));
630 smbcli_close(c1
->tree
, fnum1
);
634 printf("Checking data integrity over %d ops\n", torture_numops
);
636 for (i
=0;i
<torture_numops
;i
++)
638 size_t buf_size
= ((uint_t
)random()%(sizeof(buf
)-1))+ 1;
640 printf("%d\r", i
); fflush(stdout
);
643 generate_random_buffer(buf
, buf_size
);
645 if ((bytes_written
= smbcli_write(c1
->tree
, fnum1
, 0, buf
, 0, buf_size
)) != buf_size
) {
646 printf("write failed (%s)\n", smbcli_errstr(c1
->tree
));
647 printf("wrote %d, expected %d\n", (int)bytes_written
, (int)buf_size
);
652 if ((bytes_read
= smbcli_read(c2
->tree
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
653 printf("read failed (%s)\n", smbcli_errstr(c2
->tree
));
654 printf("read %d, expected %d\n", (int)bytes_read
, (int)buf_size
);
659 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
661 printf("read/write compare failed\n");
667 if (NT_STATUS_IS_ERR(smbcli_close(c2
->tree
, fnum2
))) {
668 printf("close failed (%s)\n", smbcli_errstr(c2
->tree
));
671 if (NT_STATUS_IS_ERR(smbcli_close(c1
->tree
, fnum1
))) {
672 printf("close failed (%s)\n", smbcli_errstr(c1
->tree
));
676 if (NT_STATUS_IS_ERR(smbcli_unlink(c1
->tree
, lockfname
))) {
677 printf("unlink failed (%s)\n", smbcli_errstr(c1
->tree
));
686 #define BOOLSTR(b) ((b) ? "Yes" : "No")
688 static BOOL
run_readwritetest(struct torture_context
*torture
)
690 struct smbcli_state
*cli1
, *cli2
;
691 BOOL test1
, test2
= True
;
693 if (!torture_open_connection(&cli1
) || !torture_open_connection(&cli2
)) {
697 printf("starting readwritetest\n");
699 test1
= rw_torture2(cli1
, cli2
);
700 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
703 test2
= rw_torture2(cli1
, cli1
);
704 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
707 if (!torture_close_connection(cli1
)) {
711 if (!torture_close_connection(cli2
)) {
715 return (test1
&& test2
);
723 test the timing of deferred open requests
725 static BOOL
run_deferopen(struct smbcli_state
*cli
, int dummy
)
727 const char *fname
= "\\defer_open_test.dat";
733 printf("failed to connect\n");
737 printf("Testing deferred open requests.\n");
744 tv
= timeval_current();
745 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0,
747 FILE_ATTRIBUTE_NORMAL
,
748 NTCREATEX_SHARE_ACCESS_NONE
,
749 NTCREATEX_DISP_OPEN_IF
, 0, 0);
753 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
)) {
754 double e
= timeval_elapsed(&tv
);
755 if (e
< 0.5 || e
> 1.5) {
756 fprintf(stderr
,"Timing incorrect %.2f violation\n",
760 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
));
763 fprintf(stderr
,"Failed to open %s, error=%s\n", fname
, smbcli_errstr(cli
->tree
));
767 printf("pid %u open %d\n", getpid(), i
);
771 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum
))) {
772 fprintf(stderr
,"Failed to close %s, error=%s\n", fname
, smbcli_errstr(cli
->tree
));
778 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fname
))) {
779 /* All until the last unlink will fail with sharing violation. */
780 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
)) {
781 printf("unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
786 printf("deferred test finished\n");
787 if (!torture_close_connection(cli
)) {
794 Try with a wrong vuid and check error message.
797 static BOOL
run_vuidtest(struct torture_context
*torture
)
799 struct smbcli_state
*cli
;
800 const char *fname
= "\\vuid.tst";
803 time_t c_time
, a_time
, m_time
;
809 printf("starting vuid test\n");
811 if (!torture_open_connection(&cli
)) {
815 smbcli_unlink(cli
->tree
, fname
);
817 fnum
= smbcli_open(cli
->tree
, fname
,
818 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
820 orig_vuid
= cli
->session
->vuid
;
822 cli
->session
->vuid
+= 1234;
824 printf("Testing qfileinfo with wrong vuid\n");
826 if (NT_STATUS_IS_OK(result
= smbcli_qfileinfo(cli
->tree
, fnum
, NULL
,
827 &size
, &c_time
, &a_time
,
828 &m_time
, NULL
, NULL
))) {
829 printf("ERROR: qfileinfo passed with wrong vuid\n");
833 if (!NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
834 NT_STATUS_DOS(ERRSRV
, ERRbaduid
)) &&
835 !NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
836 NT_STATUS_INVALID_HANDLE
)) {
837 printf("ERROR: qfileinfo should have returned DOS error "
838 "ERRSRV:ERRbaduid\n but returned %s\n",
839 smbcli_errstr(cli
->tree
));
843 cli
->session
->vuid
-= 1234;
845 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum
))) {
846 printf("close failed (%s)\n", smbcli_errstr(cli
->tree
));
850 smbcli_unlink(cli
->tree
, fname
);
852 if (!torture_close_connection(cli
)) {
856 printf("vuid test finished\n");
862 Test open mode returns on read-only files.
864 static BOOL
run_opentest(struct torture_context
*torture
)
866 static struct smbcli_state
*cli1
;
867 static struct smbcli_state
*cli2
;
868 const char *fname
= "\\readonly.file";
869 char *control_char_fname
;
878 printf("starting open test\n");
880 if (!torture_open_connection(&cli1
)) {
884 asprintf(&control_char_fname
, "\\readonly.afile");
885 for (i
= 1; i
<= 0x1f; i
++) {
886 control_char_fname
[10] = i
;
887 fnum1
= smbcli_nt_create_full(cli1
->tree
, control_char_fname
, 0, SEC_FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
888 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
890 if (!check_error(__location__
, cli1
, ERRDOS
, ERRinvalidname
,
891 NT_STATUS_OBJECT_NAME_INVALID
)) {
892 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
893 smbcli_errstr(cli1
->tree
), i
);
898 smbcli_close(cli1
->tree
, fnum1
);
900 smbcli_setatr(cli1
->tree
, control_char_fname
, 0, 0);
901 smbcli_unlink(cli1
->tree
, control_char_fname
);
903 free(control_char_fname
);
906 printf("Create file with control char names passed.\n");
908 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
909 smbcli_unlink(cli1
->tree
, fname
);
911 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
913 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
917 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
918 printf("close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
922 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1
->tree
, fname
, FILE_ATTRIBUTE_READONLY
, 0))) {
923 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
924 CHECK_MAX_FAILURES(error_test1
);
928 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
930 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
931 CHECK_MAX_FAILURES(error_test1
);
935 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
936 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
938 if (check_error(__location__
, cli1
, ERRDOS
, ERRnoaccess
,
939 NT_STATUS_ACCESS_DENIED
)) {
940 printf("correct error code ERRDOS/ERRnoaccess returned\n");
943 printf("finished open test 1\n");
945 smbcli_close(cli1
->tree
, fnum1
);
947 /* Now try not readonly and ensure ERRbadshare is returned. */
949 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
951 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
953 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
957 /* This will fail - but the error should be ERRshare. */
958 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
960 if (check_error(__location__
, cli1
, ERRDOS
, ERRbadshare
,
961 NT_STATUS_SHARING_VIOLATION
)) {
962 printf("correct error code ERRDOS/ERRbadshare returned\n");
965 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
966 printf("close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
970 smbcli_unlink(cli1
->tree
, fname
);
972 printf("finished open test 2\n");
974 /* Test truncate open disposition on file opened for read. */
976 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
978 printf("(3) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
982 /* write 20 bytes. */
984 memset(buf
, '\0', 20);
986 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
987 printf("write failed (%s)\n", smbcli_errstr(cli1
->tree
));
991 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
992 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
996 /* Ensure size == 20. */
997 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
998 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
999 CHECK_MAX_FAILURES(error_test3
);
1004 printf("(3) file size != 20\n");
1005 CHECK_MAX_FAILURES(error_test3
);
1009 /* Now test if we can truncate a file opened for readonly. */
1011 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
1013 printf("(3) open (2) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1014 CHECK_MAX_FAILURES(error_test3
);
1018 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1019 printf("close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1023 /* Ensure size == 0. */
1024 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1025 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
1026 CHECK_MAX_FAILURES(error_test3
);
1031 printf("(3) file size != 0\n");
1032 CHECK_MAX_FAILURES(error_test3
);
1035 printf("finished open test 3\n");
1037 smbcli_unlink(cli1
->tree
, fname
);
1040 printf("testing ctemp\n");
1041 fnum1
= smbcli_ctemp(cli1
->tree
, "\\", &tmp_path
);
1043 printf("ctemp failed (%s)\n", smbcli_errstr(cli1
->tree
));
1044 CHECK_MAX_FAILURES(error_test4
);
1047 printf("ctemp gave path %s\n", tmp_path
);
1048 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1049 printf("close of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
1051 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1
->tree
, tmp_path
))) {
1052 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
1055 /* Test the non-io opens... */
1057 if (!torture_open_connection(&cli2
)) {
1061 smbcli_setatr(cli2
->tree
, fname
, 0, 0);
1062 smbcli_unlink(cli2
->tree
, fname
);
1064 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1066 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1067 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1070 printf("test 1 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1071 CHECK_MAX_FAILURES(error_test10
);
1075 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1076 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1078 printf("test 1 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1079 CHECK_MAX_FAILURES(error_test10
);
1083 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1084 printf("test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1087 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1088 printf("test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1092 printf("non-io open test #1 passed.\n");
1094 smbcli_unlink(cli1
->tree
, fname
);
1096 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1098 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1099 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1102 printf("test 2 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1103 CHECK_MAX_FAILURES(error_test20
);
1107 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1108 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1111 printf("test 2 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1112 CHECK_MAX_FAILURES(error_test20
);
1116 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1117 printf("test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1120 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1121 printf("test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1125 printf("non-io open test #2 passed.\n");
1127 smbcli_unlink(cli1
->tree
, fname
);
1129 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1131 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1132 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1135 printf("test 3 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1136 CHECK_MAX_FAILURES(error_test30
);
1140 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1141 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1144 printf("test 3 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1145 CHECK_MAX_FAILURES(error_test30
);
1149 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1150 printf("test 3 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1153 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1154 printf("test 3 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1158 printf("non-io open test #3 passed.\n");
1160 smbcli_unlink(cli1
->tree
, fname
);
1162 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1164 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1165 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1168 printf("test 4 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1169 CHECK_MAX_FAILURES(error_test40
);
1173 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1174 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1177 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1178 CHECK_MAX_FAILURES(error_test40
);
1182 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1184 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1185 printf("test 4 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1189 printf("non-io open test #4 passed.\n");
1191 smbcli_unlink(cli1
->tree
, fname
);
1193 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1195 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1196 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1199 printf("test 5 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1200 CHECK_MAX_FAILURES(error_test50
);
1204 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1205 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1208 printf("test 5 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1209 CHECK_MAX_FAILURES(error_test50
);
1213 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1214 printf("test 5 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1218 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1219 printf("test 5 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1223 printf("non-io open test #5 passed.\n");
1225 printf("TEST #6 testing 1 non-io open, one io open\n");
1227 smbcli_unlink(cli1
->tree
, fname
);
1229 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1230 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1233 printf("test 6 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1234 CHECK_MAX_FAILURES(error_test60
);
1238 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1239 NTCREATEX_SHARE_ACCESS_READ
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1242 printf("test 6 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1243 CHECK_MAX_FAILURES(error_test60
);
1247 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1248 printf("test 6 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1252 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1253 printf("test 6 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1257 printf("non-io open test #6 passed.\n");
1259 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1261 smbcli_unlink(cli1
->tree
, fname
);
1263 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1264 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1267 printf("test 7 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1268 CHECK_MAX_FAILURES(error_test70
);
1272 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1273 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1276 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1277 CHECK_MAX_FAILURES(error_test70
);
1281 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1283 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1284 printf("test 7 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1288 printf("non-io open test #7 passed.\n");
1292 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1294 smbcli_unlink(cli1
->tree
, fname
);
1296 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1298 printf("(8) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1302 /* write 20 bytes. */
1304 memset(buf
, '\0', 20);
1306 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
1307 printf("(8) write failed (%s)\n", smbcli_errstr(cli1
->tree
));
1311 /* Ensure size == 20. */
1312 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1313 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1314 CHECK_MAX_FAILURES(error_test80
);
1319 printf("(8) file size != 20\n");
1320 CHECK_MAX_FAILURES(error_test80
);
1324 /* Get an exclusive lock on the open file. */
1325 if (NT_STATUS_IS_ERR(smbcli_lock(cli1
->tree
, fnum1
, 0, 4, 0, WRITE_LOCK
))) {
1326 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1327 CHECK_MAX_FAILURES(error_test80
);
1331 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_TRUNC
, DENY_NONE
);
1333 printf("(8) open (2) of %s with truncate failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1337 /* Ensure size == 0. */
1338 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1339 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1340 CHECK_MAX_FAILURES(error_test80
);
1345 printf("(8) file size != 0\n");
1346 CHECK_MAX_FAILURES(error_test80
);
1350 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1351 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1355 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum2
))) {
1356 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1362 printf("open test #8 passed.\n");
1364 smbcli_unlink(cli1
->tree
, fname
);
1366 if (!torture_close_connection(cli1
)) {
1369 if (!torture_close_connection(cli2
)) {
1376 /* FIRST_DESIRED_ACCESS 0xf019f */
1377 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1378 SEC_FILE_READ_EA| /* 0xf */ \
1379 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1380 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1381 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1382 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1383 /* SECOND_DESIRED_ACCESS 0xe0080 */
1384 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1385 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1386 SEC_STD_WRITE_OWNER /* 0xe0000 */
1389 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1390 READ_CONTROL|WRITE_DAC|\
1391 SEC_FILE_READ_DATA|\
1398 Test ntcreate calls made by xcopy
1400 static BOOL
run_xcopy(struct torture_context
*torture
)
1402 struct smbcli_state
*cli1
;
1403 const char *fname
= "\\test.txt";
1404 BOOL correct
= True
;
1407 printf("starting xcopy test\n");
1409 if (!torture_open_connection(&cli1
)) {
1413 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1414 FIRST_DESIRED_ACCESS
,
1415 FILE_ATTRIBUTE_ARCHIVE
,
1416 NTCREATEX_SHARE_ACCESS_NONE
,
1417 NTCREATEX_DISP_OVERWRITE_IF
,
1421 printf("First open failed - %s\n", smbcli_errstr(cli1
->tree
));
1425 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1426 SECOND_DESIRED_ACCESS
, 0,
1427 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN
,
1430 printf("second open failed - %s\n", smbcli_errstr(cli1
->tree
));
1434 if (!torture_close_connection(cli1
)) {
1441 static BOOL
run_iometer(struct torture_context
*torture
)
1443 struct smbcli_state
*cli
;
1444 const char *fname
= "\\iobw.tst";
1450 BOOL result
= False
;
1452 printf("Starting iometer test\n");
1454 memset(buf
, 0, sizeof(buf
));
1456 if (!torture_open_connection(&cli
)) {
1460 status
= smbcli_getatr(cli
->tree
, fname
, NULL
, &filesize
, NULL
);
1461 if (!NT_STATUS_IS_OK(status
)) {
1462 printf("smbcli_getatr failed: %s\n", nt_errstr(status
));
1466 printf("size: %d\n", filesize
);
1468 filesize
-= (sizeof(buf
) - 1);
1470 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0x16,
1471 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1473 printf("open failed: %s\n", smbcli_errstr(cli
->tree
));
1480 int i
, num_reads
, num_writes
;
1482 num_reads
= random() % 10;
1483 num_writes
= random() % 3;
1485 for (i
=0; i
<num_reads
; i
++) {
1487 if (ops
++ > torture_numops
) {
1491 res
= smbcli_read(cli
->tree
, fnum
, buf
,
1492 random() % filesize
, sizeof(buf
));
1493 if (res
!= sizeof(buf
)) {
1494 printf("read failed: %s\n",
1495 smbcli_errstr(cli
->tree
));
1499 for (i
=0; i
<num_writes
; i
++) {
1501 if (ops
++ > torture_numops
) {
1505 res
= smbcli_write(cli
->tree
, fnum
, 0, buf
,
1506 random() % filesize
, sizeof(buf
));
1507 if (res
!= sizeof(buf
)) {
1508 printf("read failed: %s\n",
1509 smbcli_errstr(cli
->tree
));
1518 if (!torture_close_connection(cli
)) {
1519 printf("close_connection failed: %s\n",
1520 smbcli_errstr(cli
->tree
));
1528 tries variants of chkpath
1530 static BOOL
torture_chkpath_test(struct torture_context
*torture
)
1532 struct smbcli_state
*cli
;
1536 if (!torture_open_connection(&cli
)) {
1540 printf("starting chkpath test\n");
1542 printf("Testing valid and invalid paths\n");
1544 /* cleanup from an old run */
1545 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1546 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1547 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1549 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir"))) {
1550 printf("mkdir1 failed : %s\n", smbcli_errstr(cli
->tree
));
1554 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1555 printf("mkdir2 failed : %s\n", smbcli_errstr(cli
->tree
));
1559 fnum
= smbcli_open(cli
->tree
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1561 printf("open1 failed (%s)\n", smbcli_errstr(cli
->tree
));
1564 smbcli_close(cli
->tree
, fnum
);
1566 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir"))) {
1567 printf("chkpath1 failed: %s\n", smbcli_errstr(cli
->tree
));
1571 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1572 printf("chkpath2 failed: %s\n", smbcli_errstr(cli
->tree
));
1576 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\foo.txt"))) {
1577 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1578 NT_STATUS_NOT_A_DIRECTORY
);
1580 printf("* chkpath on a file should fail\n");
1584 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\bar.txt"))) {
1585 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1586 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1588 printf("* chkpath on a non existent file should fail\n");
1592 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1593 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1594 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1596 printf("* chkpath on a non existent component should fail\n");
1600 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1601 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1602 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1604 if (!torture_close_connection(cli
)) {
1612 * This is a test to excercise some weird Samba3 error paths.
1615 static BOOL
torture_samba3_errorpaths(struct torture_context
*torture
)
1617 BOOL nt_status_support
;
1618 struct smbcli_state
*cli_nt
= NULL
, *cli_dos
= NULL
;
1619 BOOL result
= False
;
1621 const char *os2_fname
= ".+,;=[].";
1622 const char *dirname
= "samba3_errordir";
1624 TALLOC_CTX
*mem_ctx
= talloc_init(NULL
);
1627 if (mem_ctx
== NULL
) {
1628 printf("talloc_init failed\n");
1632 nt_status_support
= lp_nt_status_support();
1634 if (!lp_set_cmdline("nt status support", "yes")) {
1635 printf("Could not set 'nt status support = yes'\n");
1639 if (!torture_open_connection(&cli_nt
)) {
1643 if (!lp_set_cmdline("nt status support", "no")) {
1644 printf("Could not set 'nt status support = yes'\n");
1648 if (!torture_open_connection(&cli_dos
)) {
1652 if (!lp_set_cmdline("nt status support",
1653 nt_status_support
? "yes":"no")) {
1654 printf("Could not reset 'nt status support = yes'");
1658 smbcli_unlink(cli_nt
->tree
, os2_fname
);
1659 smbcli_rmdir(cli_nt
->tree
, dirname
);
1661 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt
->tree
, dirname
))) {
1662 printf("smbcli_mkdir(%s) failed: %s\n", dirname
,
1663 smbcli_errstr(cli_nt
->tree
));
1667 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1668 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1669 io
.ntcreatex
.in
.root_fid
= 0;
1670 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1671 io
.ntcreatex
.in
.alloc_size
= 1024*1024;
1672 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1673 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1674 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1675 io
.ntcreatex
.in
.create_options
= 0;
1676 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1677 io
.ntcreatex
.in
.security_flags
= 0;
1678 io
.ntcreatex
.in
.fname
= dirname
;
1680 status
= smb_raw_open(cli_nt
->tree
, mem_ctx
, &io
);
1681 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1682 printf("(%s) incorrect status %s should be %s\n",
1683 __location__
, nt_errstr(status
),
1684 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1687 status
= smb_raw_open(cli_dos
->tree
, mem_ctx
, &io
);
1688 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRfilexists
))) {
1689 printf("(%s) incorrect status %s should be %s\n",
1690 __location__
, nt_errstr(status
),
1691 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRfilexists
)));
1695 status
= smbcli_mkdir(cli_nt
->tree
, dirname
);
1696 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1697 printf("(%s) incorrect status %s should be %s\n",
1698 __location__
, nt_errstr(status
),
1699 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1702 status
= smbcli_mkdir(cli_dos
->tree
, dirname
);
1703 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRnoaccess
))) {
1704 printf("(%s) incorrect status %s should be %s\n",
1705 __location__
, nt_errstr(status
),
1706 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRnoaccess
)));
1710 if (!lp_parm_bool(-1, "target", "samba3", False
)) {
1714 fnum
= smbcli_open(cli_dos
->tree
, os2_fname
,
1715 O_RDWR
| O_CREAT
| O_TRUNC
,
1718 printf("Open(%s) succeeded -- expected failure\n",
1720 smbcli_close(cli_dos
->tree
, fnum
);
1724 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos
->tree
),
1725 NT_STATUS_DOS(ERRDOS
, ERRcannotopen
))) {
1726 printf("Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1727 smbcli_errstr(cli_dos
->tree
));
1731 fnum
= smbcli_open(cli_nt
->tree
, os2_fname
,
1732 O_RDWR
| O_CREAT
| O_TRUNC
,
1735 printf("Open(%s) succeeded -- expected failure\n",
1737 smbcli_close(cli_nt
->tree
, fnum
);
1741 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1742 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1743 printf("Expected DOS error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1744 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1752 if (cli_dos
!= NULL
) {
1753 torture_close_connection(cli_dos
);
1755 if (cli_nt
!= NULL
) {
1756 torture_close_connection(cli_nt
);
1763 NTSTATUS
torture_base_init(void)
1765 register_torture_op("BASE-FDPASS", run_fdpasstest
, 0);
1766 register_torture_op("BASE-LOCK1", torture_locktest1
, 0);
1767 register_torture_op("BASE-LOCK2", torture_locktest2
, 0);
1768 register_torture_op("BASE-LOCK3", torture_locktest3
, 0);
1769 register_torture_op("BASE-LOCK4", torture_locktest4
, 0);
1770 register_torture_op("BASE-LOCK5", torture_locktest5
, 0);
1771 register_torture_op("BASE-LOCK6", torture_locktest6
, 0);
1772 register_torture_op("BASE-LOCK7", torture_locktest7
, 0);
1773 register_torture_op("BASE-UNLINK", torture_unlinktest
, 0);
1774 register_torture_op("BASE-ATTR", run_attrtest
, 0);
1775 register_torture_op("BASE-TRANS2", run_trans2test
, 0);
1776 register_torture_op("BASE-NEGNOWAIT", run_negprot_nowait
, 0);
1777 register_torture_op("BASE-DIR1", torture_dirtest1
, 0);
1778 register_torture_op("BASE-DIR2", torture_dirtest2
, 0);
1779 register_torture_op("BASE-DENY1", torture_denytest1
, 0);
1780 register_torture_op("BASE-DENY2", torture_denytest2
, 0);
1781 register_torture_op("BASE-DENY3", torture_denytest3
, 0);
1782 register_torture_op("BASE-DENYDOS", torture_denydos_sharing
, 0);
1783 register_torture_op("BASE-NTDENY1", NULL
, torture_ntdenytest1
);
1784 register_torture_op("BASE-NTDENY2", torture_ntdenytest2
, 0);
1785 register_torture_op("BASE-TCON", run_tcon_test
, 0);
1786 register_torture_op("BASE-TCONDEV", run_tcon_devtype_test
, 0);
1787 register_torture_op("BASE-VUID", run_vuidtest
, 0);
1788 register_torture_op("BASE-RW1", run_readwritetest
, 0);
1789 register_torture_op("BASE-OPEN", run_opentest
, 0);
1790 register_torture_op("BASE-DEFER_OPEN", NULL
, run_deferopen
);
1791 register_torture_op("BASE-XCOPY", run_xcopy
, 0);
1792 register_torture_op("BASE-IOMETER", run_iometer
, 0);
1793 register_torture_op("BASE-RENAME", torture_test_rename
, 0);
1794 register_torture_op("BASE-DELETE", torture_test_delete
, 0);
1795 register_torture_op("BASE-PROPERTIES", torture_test_properties
, 0);
1796 register_torture_op("BASE-MANGLE", torture_mangle
, 0);
1797 register_torture_op("BASE-OPENATTR", torture_openattrtest
, 0);
1798 register_torture_op("BASE-CHARSET", torture_charset
, 0);
1799 register_torture_op("BASE-CHKPATH", torture_chkpath_test
, 0);
1800 register_torture_op("BASE-SECLEAK", torture_sec_leak
, 0);
1801 register_torture_op("BASE-DISCONNECT", torture_disconnect
, 0);
1802 register_torture_op("BASE-DELAYWRITE", torture_delay_write
, 0);
1803 register_torture_op("BASE-SAMBA3ERROR", torture_samba3_errorpaths
, 0);
1805 register_torture_op("SCAN-CASETABLE", torture_casetable
, 0);
1806 register_torture_op("SCAN-UTABLE", torture_utable
, 0);
1807 register_torture_op("SCAN-SMB", torture_smb_scan
, 0);
1808 register_torture_op("SCAN-ALIASES", torture_trans2_aliases
, 0);
1809 register_torture_op("SCAN-TRANS2", torture_trans2_scan
, 0);
1810 register_torture_op("SCAN-NTTRANS", torture_nttrans_scan
, 0);
1812 return NT_STATUS_OK
;