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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "torture/smbtorture.h"
23 #include "torture/basic/proto.h"
24 #include "libcli/libcli.h"
25 #include "libcli/raw/raw_proto.h"
26 #include "torture/util.h"
27 #include "system/filesys.h"
28 #include "system/time.h"
29 #include "libcli/resolve/resolve.h"
30 #include "lib/events/events.h"
31 #include "param/param.h"
34 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
37 static struct smbcli_state
*open_nbt_connection(struct torture_context
*tctx
)
39 struct nbt_name called
, calling
;
40 struct smbcli_state
*cli
;
41 const char *host
= torture_setting_string(tctx
, "host", NULL
);
42 struct smbcli_options options
;
45 make_nbt_name_client(&calling
, lpcfg_netbios_name(tctx
->lp_ctx
));
47 nbt_choose_called_name(NULL
, &called
, host
, NBT_NAME_SERVER
);
49 cli
= smbcli_state_init(NULL
);
51 torture_result(tctx
, TORTURE_FAIL
, "Failed initialize smbcli_struct to connect with %s\n", host
);
55 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
57 ok
= smbcli_socket_connect(cli
, host
, lpcfg_smb_ports(tctx
->lp_ctx
),
59 lpcfg_resolve_context(tctx
->lp_ctx
),
61 lpcfg_socket_options(tctx
->lp_ctx
),
64 torture_result(tctx
, TORTURE_FAIL
, "Failed to connect with %s\n", host
);
68 cli
->transport
= smbcli_transport_init(cli
->sock
, cli
,
71 if (!cli
->transport
) {
72 torture_result(tctx
, TORTURE_FAIL
, "smbcli_transport_init failed\n");
83 static bool tcon_devtest(struct torture_context
*tctx
,
84 struct smbcli_state
*cli
,
85 const char *myshare
, const char *devtype
,
86 NTSTATUS expected_error
)
89 const char *password
= torture_setting_string(tctx
, "password", NULL
);
91 status
= NT_STATUS_IS_OK(smbcli_tconX(cli
, myshare
, devtype
,
94 torture_comment(tctx
, "Trying share %s with devtype %s\n", myshare
, devtype
);
96 if (NT_STATUS_IS_OK(expected_error
)) {
98 torture_fail(tctx
, talloc_asprintf(tctx
,
99 "tconX to share %s with type %s "
100 "should have succeeded but failed",
106 torture_fail(tctx
, talloc_asprintf(tctx
,
107 "tconx to share %s with type %s "
108 "should have failed but succeeded",
111 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),
114 torture_fail(tctx
, "Returned unexpected error");
124 test whether fnums and tids open on one VC are available on another (a major
127 static bool run_fdpasstest(struct torture_context
*tctx
,
128 struct smbcli_state
*cli1
,
129 struct smbcli_state
*cli2
)
131 const char *fname
= "\\fdpass.tst";
135 smbcli_unlink(cli1
->tree
, fname
);
137 torture_comment(tctx
, "Opening a file on connection 1\n");
139 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
140 torture_assert(tctx
, fnum1
!= -1,
141 talloc_asprintf(tctx
,
142 "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
)));
144 torture_comment(tctx
, "writing to file on connection 1\n");
147 smbcli_write(cli1
->tree
, fnum1
, 0, "hello world\n", 0, 13) == 13,
148 talloc_asprintf(tctx
,
149 "write failed (%s)\n", smbcli_errstr(cli1
->tree
)));
151 oldtid
= cli2
->tree
->tid
;
152 cli2
->session
->vuid
= cli1
->session
->vuid
;
153 cli2
->tree
->tid
= cli1
->tree
->tid
;
154 cli2
->session
->pid
= cli1
->session
->pid
;
156 torture_comment(tctx
, "reading from file on connection 2\n");
158 torture_assert(tctx
, smbcli_read(cli2
->tree
, fnum1
, buf
, 0, 13) != 13,
159 talloc_asprintf(tctx
,
160 "read succeeded! nasty security hole [%s]\n", buf
));
162 smbcli_close(cli1
->tree
, fnum1
);
163 smbcli_unlink(cli1
->tree
, fname
);
165 cli2
->tree
->tid
= oldtid
;
171 This checks how the getatr calls works
173 static bool run_attrtest(struct torture_context
*tctx
,
174 struct smbcli_state
*cli
)
178 const char *fname
= "\\attrib123456789.tst";
181 smbcli_unlink(cli
->tree
, fname
);
182 fnum
= smbcli_open(cli
->tree
, fname
,
183 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
184 smbcli_close(cli
->tree
, fnum
);
186 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
187 torture_result(tctx
, TORTURE_FAIL
, "getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
191 torture_comment(tctx
, "New file time is %s", ctime(&t
));
193 if (abs(t
- time(NULL
)) > 60*60*24*10) {
194 torture_result(tctx
, TORTURE_FAIL
, "ERROR: SMBgetatr bug. time is %s",
200 t2
= t
-60*60*24; /* 1 day ago */
202 torture_comment(tctx
, "Setting file time to %s", ctime(&t2
));
204 if (NT_STATUS_IS_ERR(smbcli_setatr(cli
->tree
, fname
, 0, t2
))) {
205 torture_comment(tctx
, "setatr failed (%s)\n", smbcli_errstr(cli
->tree
));
209 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
210 torture_comment(tctx
, "getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
214 torture_comment(tctx
, "Retrieved file time as %s", ctime(&t
));
217 torture_comment(tctx
, "ERROR: getatr/setatr bug. times are\n%s",
219 torture_comment(tctx
, "%s", ctime(&t2
));
223 smbcli_unlink(cli
->tree
, fname
);
229 This checks a couple of trans2 calls
231 static bool run_trans2test(struct torture_context
*tctx
,
232 struct smbcli_state
*cli
)
236 time_t c_time
, a_time
, m_time
, w_time
, m_time2
;
237 const char *fname
= "\\trans2.tst";
238 const char *dname
= "\\trans2";
239 const char *fname2
= "\\trans2\\trans2.tst";
243 smbcli_unlink(cli
->tree
, fname
);
245 torture_comment(tctx
, "Testing qfileinfo\n");
247 fnum
= smbcli_open(cli
->tree
, fname
,
248 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
249 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli
->tree
, fnum
, NULL
, &size
, &c_time
, &a_time
, &m_time
,
251 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
255 torture_comment(tctx
, "Testing NAME_INFO\n");
257 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli
->tree
, fnum
, &pname
))) {
258 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli
->tree
));
262 if (!pname
|| strcmp(pname
, fname
)) {
263 torture_result(tctx
, TORTURE_FAIL
, "qfilename gave different name? [%s] [%s]\n",
268 smbcli_close(cli
->tree
, fnum
);
269 smbcli_unlink(cli
->tree
, fname
);
271 fnum
= smbcli_open(cli
->tree
, fname
,
272 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
274 torture_result(tctx
, TORTURE_FAIL
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
277 smbcli_close(cli
->tree
, fnum
);
279 torture_comment(tctx
, "Checking for sticky create times\n");
281 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
))) {
282 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
285 time_t t
= time(NULL
);
287 if (c_time
!= m_time
) {
288 torture_comment(tctx
, "create time=%s", ctime(&c_time
));
289 torture_comment(tctx
, "modify time=%s", ctime(&m_time
));
290 torture_comment(tctx
, "This system appears to have sticky create times\n");
292 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
293 torture_comment(tctx
, "access time=%s", ctime(&a_time
));
294 torture_result(tctx
, TORTURE_FAIL
, "This system appears to set a midnight access time\n");
298 if (abs(m_time
- t
) > 60*60*24*7) {
299 torture_result(tctx
, TORTURE_FAIL
, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
305 smbcli_unlink(cli
->tree
, fname
);
306 fnum
= smbcli_open(cli
->tree
, fname
,
307 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
308 smbcli_close(cli
->tree
, fnum
);
309 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
310 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
313 if (w_time
< 60*60*24*2) {
314 torture_comment(tctx
, "write time=%s", ctime(&w_time
));
315 torture_result(tctx
, TORTURE_FAIL
, "This system appears to set a initial 0 write time\n");
320 smbcli_unlink(cli
->tree
, fname
);
323 /* check if the server updates the directory modification time
324 when creating a new file */
325 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, dname
))) {
326 torture_result(tctx
, TORTURE_FAIL
, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli
->tree
));
330 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
331 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
335 fnum
= smbcli_open(cli
->tree
, fname2
,
336 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
337 smbcli_write(cli
->tree
, fnum
, 0, &fnum
, 0, sizeof(fnum
));
338 smbcli_close(cli
->tree
, fnum
);
339 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time2
, &w_time
, &size
, NULL
, NULL
))) {
340 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
343 if (m_time2
== m_time
) {
344 torture_result(tctx
, TORTURE_FAIL
, "This system does not update directory modification times\n");
348 smbcli_unlink(cli
->tree
, fname2
);
349 smbcli_rmdir(cli
->tree
, dname
);
354 /* send smb negprot commands, not reading the response */
355 static bool run_negprot_nowait(struct torture_context
*tctx
)
358 struct smbcli_state
*cli
, *cli2
;
361 torture_comment(tctx
, "starting negprot nowait test\n");
363 cli
= open_nbt_connection(tctx
);
368 torture_comment(tctx
, "Filling send buffer\n");
370 for (i
=0;i
<100;i
++) {
371 struct tevent_req
*req
;
372 req
= smb_raw_negotiate_send(cli
, tctx
->ev
,
375 tevent_loop_once(tctx
->ev
);
376 if (!tevent_req_is_in_progress(req
)) {
379 status
= smb_raw_negotiate_recv(req
);
382 torture_comment(tctx
, "Failed to fill pipe packet[%d] - %s (ignored)\n",
383 i
+1, nt_errstr(status
));
386 torture_result(tctx
, TORTURE_FAIL
, "Failed to fill pipe - %s \n",
388 torture_close_connection(cli
);
394 torture_comment(tctx
, "Opening secondary connection\n");
395 if (!torture_open_connection(&cli2
, tctx
, 1)) {
396 torture_result(tctx
, TORTURE_FAIL
, "Failed to open secondary connection\n");
400 if (!torture_close_connection(cli2
)) {
401 torture_result(tctx
, TORTURE_FAIL
, "Failed to close secondary connection\n");
405 torture_close_connection(cli
);
411 this checks to see if a secondary tconx can use open files from an
414 static bool run_tcon_test(struct torture_context
*tctx
, struct smbcli_state
*cli
)
416 const char *fname
= "\\tcontest.tmp";
418 uint16_t cnum1
, cnum2
, cnum3
;
419 uint16_t vuid1
, vuid2
;
422 struct smbcli_tree
*tree1
;
423 const char *host
= torture_setting_string(tctx
, "host", NULL
);
424 const char *share
= torture_setting_string(tctx
, "share", NULL
);
425 const char *password
= torture_setting_string(tctx
, "password", NULL
);
427 if (smbcli_deltree(cli
->tree
, fname
) == -1) {
428 torture_comment(tctx
, "unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
431 fnum1
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
433 torture_result(tctx
, TORTURE_FAIL
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
437 cnum1
= cli
->tree
->tid
;
438 vuid1
= cli
->session
->vuid
;
440 memset(buf
, 0, 4); /* init buf so valgrind won't complain */
441 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) != 4) {
442 torture_result(tctx
, TORTURE_FAIL
, "initial write failed (%s)\n", smbcli_errstr(cli
->tree
));
446 tree1
= cli
->tree
; /* save old tree connection */
447 if (NT_STATUS_IS_ERR(smbcli_tconX(cli
, share
, "?????", password
))) {
448 torture_result(tctx
, TORTURE_FAIL
, "%s refused 2nd tree connect (%s)\n", host
,
449 smbcli_errstr(cli
->tree
));
454 cnum2
= cli
->tree
->tid
;
455 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
456 vuid2
= cli
->session
->vuid
+ 1;
458 /* try a write with the wrong tid */
459 cli
->tree
->tid
= cnum2
;
461 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
462 torture_result(tctx
, TORTURE_FAIL
, "* server allows write with wrong TID\n");
465 torture_comment(tctx
, "server fails write with wrong TID : %s\n", smbcli_errstr(cli
->tree
));
469 /* try a write with an invalid tid */
470 cli
->tree
->tid
= cnum3
;
472 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
473 torture_result(tctx
, TORTURE_FAIL
, "* server allows write with invalid TID\n");
476 torture_comment(tctx
, "server fails write with invalid TID : %s\n", smbcli_errstr(cli
->tree
));
479 /* try a write with an invalid vuid */
480 cli
->session
->vuid
= vuid2
;
481 cli
->tree
->tid
= cnum1
;
483 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
484 torture_result(tctx
, TORTURE_FAIL
, "* server allows write with invalid VUID\n");
487 torture_comment(tctx
, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli
->tree
));
490 cli
->session
->vuid
= vuid1
;
491 cli
->tree
->tid
= cnum1
;
493 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum1
))) {
494 torture_result(tctx
, TORTURE_FAIL
, "close failed (%s)\n", smbcli_errstr(cli
->tree
));
498 cli
->tree
->tid
= cnum2
;
500 if (NT_STATUS_IS_ERR(smbcli_tdis(cli
))) {
501 torture_result(tctx
, TORTURE_FAIL
, "secondary tdis failed (%s)\n", smbcli_errstr(cli
->tree
));
505 cli
->tree
= tree1
; /* restore initial tree */
506 cli
->tree
->tid
= cnum1
;
508 smbcli_unlink(tree1
, fname
);
514 checks for correct tconX support
516 static bool run_tcon_devtype_test(struct torture_context
*tctx
,
517 struct smbcli_state
*cli1
)
519 const char *share
= torture_setting_string(tctx
, "share", NULL
);
521 if (!tcon_devtest(tctx
, cli1
, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE
))
524 if (!tcon_devtest(tctx
, cli1
, "IPC$", "?????", NT_STATUS_OK
))
527 if (!tcon_devtest(tctx
, cli1
, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
530 if (!tcon_devtest(tctx
, cli1
, "IPC$", "IPC", NT_STATUS_OK
))
533 if (!tcon_devtest(tctx
, cli1
, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
536 if (!tcon_devtest(tctx
, cli1
, share
, "A:", NT_STATUS_OK
))
539 if (!tcon_devtest(tctx
, cli1
, share
, "?????", NT_STATUS_OK
))
542 if (!tcon_devtest(tctx
, cli1
, share
, "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
545 if (!tcon_devtest(tctx
, cli1
, share
, "IPC", NT_STATUS_BAD_DEVICE_TYPE
))
548 if (!tcon_devtest(tctx
, cli1
, share
, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
554 static bool rw_torture2(struct torture_context
*tctx
,
555 struct smbcli_state
*c1
, struct smbcli_state
*c2
)
557 const char *lockfname
= "\\torture2.lck";
562 uint8_t buf_rd
[131072];
564 ssize_t bytes_read
, bytes_written
;
566 torture_assert(tctx
, smbcli_deltree(c1
->tree
, lockfname
) != -1,
567 talloc_asprintf(tctx
,
568 "unlink failed (%s)", smbcli_errstr(c1
->tree
)));
570 fnum1
= smbcli_open(c1
->tree
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
572 torture_assert(tctx
, fnum1
!= -1,
573 talloc_asprintf(tctx
,
574 "first open read/write of %s failed (%s)",
575 lockfname
, smbcli_errstr(c1
->tree
)));
576 fnum2
= smbcli_open(c2
->tree
, lockfname
, O_RDONLY
,
578 torture_assert(tctx
, fnum2
!= -1,
579 talloc_asprintf(tctx
,
580 "second open read-only of %s failed (%s)",
581 lockfname
, smbcli_errstr(c2
->tree
)));
583 torture_comment(tctx
, "Checking data integrity over %d ops\n",
586 for (i
=0;i
<torture_numops
;i
++)
588 size_t buf_size
= ((unsigned int)random()%(sizeof(buf
)-1))+ 1;
590 if (torture_setting_bool(tctx
, "progress", true)) {
591 torture_comment(tctx
, "%d\r", i
); fflush(stdout
);
595 generate_random_buffer(buf
, buf_size
);
597 if ((bytes_written
= smbcli_write(c1
->tree
, fnum1
, 0, buf
, 0, buf_size
)) != buf_size
) {
598 torture_comment(tctx
, "write failed (%s)\n", smbcli_errstr(c1
->tree
));
599 torture_result(tctx
, TORTURE_FAIL
, "wrote %d, expected %d\n", (int)bytes_written
, (int)buf_size
);
604 if ((bytes_read
= smbcli_read(c2
->tree
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
605 torture_comment(tctx
, "read failed (%s)\n", smbcli_errstr(c2
->tree
));
606 torture_result(tctx
, TORTURE_FAIL
, "read %d, expected %d\n", (int)bytes_read
, (int)buf_size
);
611 torture_assert_mem_equal(tctx
, buf_rd
, buf
, buf_size
,
612 "read/write compare failed\n");
615 torture_assert_ntstatus_ok(tctx
, smbcli_close(c2
->tree
, fnum2
),
616 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(c2
->tree
)));
617 torture_assert_ntstatus_ok(tctx
, smbcli_close(c1
->tree
, fnum1
),
618 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(c1
->tree
)));
620 torture_assert_ntstatus_ok(tctx
, smbcli_unlink(c1
->tree
, lockfname
),
621 talloc_asprintf(tctx
, "unlink failed (%s)", smbcli_errstr(c1
->tree
)));
623 torture_comment(tctx
, "\n");
630 static bool run_readwritetest(struct torture_context
*tctx
,
631 struct smbcli_state
*cli1
,
632 struct smbcli_state
*cli2
)
634 torture_comment(tctx
, "Running readwritetest v1\n");
635 if (!rw_torture2(tctx
, cli1
, cli2
))
638 torture_comment(tctx
, "Running readwritetest v2\n");
640 if (!rw_torture2(tctx
, cli1
, cli1
))
647 test the timing of deferred open requests
649 static bool run_deferopen(struct torture_context
*tctx
, struct smbcli_state
*cli
, int dummy
)
651 const char *fname
= "\\defer_open_test.dat";
659 nsec
= torture_setting_int(tctx
, "sharedelay", 1000000);
661 sec
= ((double)nsec
) / ((double) 1000000);
663 torture_comment(tctx
, "pid %u: Testing deferred open requests.\n",
671 tv
= timeval_current();
672 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0,
674 FILE_ATTRIBUTE_NORMAL
,
675 NTCREATEX_SHARE_ACCESS_NONE
,
676 NTCREATEX_DISP_OPEN_IF
, 0, 0);
680 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
)) {
681 double e
= timeval_elapsed(&tv
);
682 if (e
< (0.5 * sec
) || e
> ((1.5 * sec
) + 1)) {
683 torture_result(tctx
, TORTURE_FAIL
, "Timing incorrect %.2f violation 1 sec == %.2f\n",
688 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
));
690 torture_assert(tctx
, fnum
!= -1,
691 talloc_asprintf(tctx
,
692 "pid %u: Failed to open %s, error=%s\n",
693 (unsigned)getpid(), fname
,
694 smbcli_errstr(cli
->tree
)));
696 torture_comment(tctx
, "pid %u: open %d\n", (unsigned)getpid(), i
);
698 smb_msleep(10 * msec
);
700 status
= smbcli_close(cli
->tree
, fnum
);
701 torture_assert(tctx
, !NT_STATUS_IS_ERR(status
),
702 talloc_asprintf(tctx
,
703 "pid %u: Failed to close %s, "
705 (unsigned)getpid(), fname
,
706 smbcli_errstr(cli
->tree
)));
708 smb_msleep(2 * msec
);
713 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fname
))) {
714 /* All until the last unlink will fail with sharing violation
715 but also the last request can fail since the file could have
716 been successfully deleted by another (test) process */
717 status
= smbcli_nt_error(cli
->tree
);
718 if ((!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
))
719 && (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
))) {
720 torture_result(tctx
, TORTURE_FAIL
, "unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
725 torture_comment(tctx
, "pid %u: deferred test finished\n",
731 Try with a wrong vuid and check error message.
734 static bool run_vuidtest(struct torture_context
*tctx
,
735 struct smbcli_state
*cli
)
737 const char *fname
= "\\vuid.tst";
740 time_t c_time
, a_time
, m_time
;
744 smbcli_unlink(cli
->tree
, fname
);
746 fnum
= smbcli_open(cli
->tree
, fname
,
747 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
749 cli
->session
->vuid
+= 1234;
751 torture_comment(tctx
, "Testing qfileinfo with wrong vuid\n");
753 if (NT_STATUS_IS_OK(result
= smbcli_qfileinfo(cli
->tree
, fnum
, NULL
,
754 &size
, &c_time
, &a_time
,
755 &m_time
, NULL
, NULL
))) {
756 torture_fail(tctx
, "qfileinfo passed with wrong vuid");
759 if (!NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
760 NT_STATUS_DOS(ERRSRV
, ERRbaduid
)) &&
761 !NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
762 NT_STATUS_INVALID_HANDLE
)) {
763 torture_fail(tctx
, talloc_asprintf(tctx
,
764 "qfileinfo should have returned DOS error "
765 "ERRSRV:ERRbaduid\n but returned %s",
766 smbcli_errstr(cli
->tree
)));
769 cli
->session
->vuid
-= 1234;
771 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli
->tree
, fnum
),
772 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(cli
->tree
)));
774 smbcli_unlink(cli
->tree
, fname
);
780 Test open mode returns on read-only files.
782 static bool run_opentest(struct torture_context
*tctx
, struct smbcli_state
*cli1
,
783 struct smbcli_state
*cli2
)
785 const char *fname
= "\\readonly.file";
786 char *control_char_fname
;
795 asprintf(&control_char_fname
, "\\readonly.afile");
796 for (i
= 1; i
<= 0x1f; i
++) {
797 control_char_fname
[10] = i
;
798 fnum1
= smbcli_nt_create_full(cli1
->tree
, control_char_fname
, 0, SEC_FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
799 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
801 if (!check_error(__location__
, cli1
, ERRDOS
, ERRinvalidname
,
802 NT_STATUS_OBJECT_NAME_INVALID
)) {
803 torture_result(tctx
, TORTURE_FAIL
, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
804 smbcli_errstr(cli1
->tree
), i
);
809 smbcli_close(cli1
->tree
, fnum1
);
811 smbcli_setatr(cli1
->tree
, control_char_fname
, 0, 0);
812 smbcli_unlink(cli1
->tree
, control_char_fname
);
814 free(control_char_fname
);
817 torture_comment(tctx
, "Create file with control char names passed.\n");
819 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
820 smbcli_unlink(cli1
->tree
, fname
);
822 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
824 torture_result(tctx
, TORTURE_FAIL
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
828 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
829 torture_result(tctx
, TORTURE_FAIL
, "close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
833 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1
->tree
, fname
, FILE_ATTRIBUTE_READONLY
, 0))) {
834 torture_result(tctx
, TORTURE_FAIL
,
835 __location__
": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
836 CHECK_MAX_FAILURES(error_test1
);
840 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
842 torture_result(tctx
, TORTURE_FAIL
,
843 __location__
": open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
844 CHECK_MAX_FAILURES(error_test1
);
848 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
849 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
851 if (check_error(__location__
, cli1
, ERRDOS
, ERRnoaccess
,
852 NT_STATUS_ACCESS_DENIED
)) {
853 torture_comment(tctx
, "correct error code ERRDOS/ERRnoaccess returned\n");
856 torture_comment(tctx
, "finished open test 1\n");
859 smbcli_close(cli1
->tree
, fnum1
);
861 /* Now try not readonly and ensure ERRbadshare is returned. */
863 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
865 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
867 torture_result(tctx
, TORTURE_FAIL
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
871 /* This will fail - but the error should be ERRshare. */
872 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
874 if (check_error(__location__
, cli1
, ERRDOS
, ERRbadshare
,
875 NT_STATUS_SHARING_VIOLATION
)) {
876 torture_comment(tctx
, "correct error code ERRDOS/ERRbadshare returned\n");
879 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
880 torture_result(tctx
, TORTURE_FAIL
, "close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
884 smbcli_unlink(cli1
->tree
, fname
);
886 torture_comment(tctx
, "finished open test 2\n");
888 /* Test truncate open disposition on file opened for read. */
890 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
892 torture_result(tctx
, TORTURE_FAIL
, "(3) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
896 /* write 20 bytes. */
898 memset(buf
, '\0', 20);
900 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
901 torture_result(tctx
, TORTURE_FAIL
, "write failed (%s)\n", smbcli_errstr(cli1
->tree
));
905 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
906 torture_result(tctx
, TORTURE_FAIL
, "(3) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
910 /* Ensure size == 20. */
911 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
912 torture_result(tctx
, TORTURE_FAIL
,
913 __location__
": (3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
914 CHECK_MAX_FAILURES(error_test3
);
919 torture_result(tctx
, TORTURE_FAIL
,
920 __location__
": (3) file size != 20\n");
921 CHECK_MAX_FAILURES(error_test3
);
925 /* Now test if we can truncate a file opened for readonly. */
927 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
929 torture_result(tctx
, TORTURE_FAIL
,
930 __location__
": (3) open (2) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
931 CHECK_MAX_FAILURES(error_test3
);
935 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
936 torture_result(tctx
, TORTURE_FAIL
,
937 __location__
": close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
941 /* Ensure size == 0. */
942 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
943 torture_result(tctx
, TORTURE_FAIL
,
944 __location__
": (3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
945 CHECK_MAX_FAILURES(error_test3
);
950 torture_result(tctx
, TORTURE_FAIL
,
951 __location__
": (3) file size != 0\n");
952 CHECK_MAX_FAILURES(error_test3
);
955 torture_comment(tctx
, "finished open test 3\n");
959 smbcli_unlink(cli1
->tree
, fname
);
962 torture_comment(tctx
, "Testing ctemp\n");
963 fnum1
= smbcli_ctemp(cli1
->tree
, "\\", &tmp_path
);
965 torture_result(tctx
, TORTURE_FAIL
,
966 __location__
": ctemp failed (%s)\n", smbcli_errstr(cli1
->tree
));
967 CHECK_MAX_FAILURES(error_test4
);
970 torture_comment(tctx
, "ctemp gave path %s\n", tmp_path
);
973 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
974 torture_comment(tctx
, "close of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
976 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1
->tree
, tmp_path
))) {
977 torture_comment(tctx
, "unlink of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
980 /* Test the non-io opens... */
982 torture_comment(tctx
, "Test #1 testing 2 non-io opens (no delete)\n");
984 smbcli_setatr(cli2
->tree
, fname
, 0, 0);
985 smbcli_unlink(cli2
->tree
, fname
);
987 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
988 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
991 torture_result(tctx
, TORTURE_FAIL
,
992 __location__
": Test 1 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
993 CHECK_MAX_FAILURES(error_test10
);
997 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
998 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1000 torture_result(tctx
, TORTURE_FAIL
,
1001 __location__
": Test 1 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1002 CHECK_MAX_FAILURES(error_test10
);
1006 torture_comment(tctx
, "non-io open test #1 passed.\n");
1009 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1010 torture_comment(tctx
, "Test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1012 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1013 torture_comment(tctx
, "Test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1016 torture_comment(tctx
, "Test #2 testing 2 non-io opens (first with delete)\n");
1018 smbcli_unlink(cli1
->tree
, fname
);
1020 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1021 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1024 torture_result(tctx
, TORTURE_FAIL
,
1025 __location__
": Test 2 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1026 CHECK_MAX_FAILURES(error_test20
);
1030 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1031 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1034 torture_result(tctx
, TORTURE_FAIL
,
1035 __location__
": Test 2 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1036 CHECK_MAX_FAILURES(error_test20
);
1040 torture_comment(tctx
, "non-io open test #2 passed.\n");
1043 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1044 torture_comment(tctx
, "Test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1046 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1047 torture_comment(tctx
, "Test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1051 smbcli_unlink(cli1
->tree
, fname
);
1053 torture_comment(tctx
, "Test #3 testing 2 non-io opens (second with delete)\n");
1055 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1056 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1059 torture_result(tctx
, TORTURE_FAIL
,
1060 __location__
": Test 3 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1061 CHECK_MAX_FAILURES(error_test30
);
1065 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1066 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1069 torture_result(tctx
, TORTURE_FAIL
,
1070 __location__
": Test 3 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1071 CHECK_MAX_FAILURES(error_test30
);
1075 torture_comment(tctx
, "non-io open test #3 passed.\n");
1078 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1079 torture_comment(tctx
, "Test 3 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1081 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1082 torture_comment(tctx
, "Test 3 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1085 torture_comment(tctx
, "Test #4 testing 2 non-io opens (both with delete)\n");
1087 smbcli_unlink(cli1
->tree
, fname
);
1089 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1090 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1093 torture_result(tctx
, TORTURE_FAIL
,
1094 __location__
": Test 4 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1095 CHECK_MAX_FAILURES(error_test40
);
1099 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1100 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1103 torture_result(tctx
, TORTURE_FAIL
,
1104 __location__
": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1105 CHECK_MAX_FAILURES(error_test40
);
1109 torture_comment(tctx
, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1111 torture_comment(tctx
, "non-io open test #4 passed.\n");
1114 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1115 torture_comment(tctx
, "Test 4 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1117 if (fnum2
!= -1 && NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1118 torture_comment(tctx
, "Test 4 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1121 torture_comment(tctx
, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1123 smbcli_unlink(cli1
->tree
, fname
);
1125 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1126 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1129 torture_result(tctx
, TORTURE_FAIL
,
1130 __location__
": Test 5 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1131 CHECK_MAX_FAILURES(error_test50
);
1135 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1136 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1139 torture_result(tctx
, TORTURE_FAIL
,
1140 __location__
": Test 5 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1141 CHECK_MAX_FAILURES(error_test50
);
1145 torture_comment(tctx
, "non-io open test #5 passed.\n");
1148 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1149 torture_comment(tctx
, "Test 5 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1152 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1153 torture_comment(tctx
, "Test 5 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1156 torture_comment(tctx
, "Test #6 testing 1 non-io open, one io open\n");
1158 smbcli_unlink(cli1
->tree
, fname
);
1160 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1161 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1164 torture_result(tctx
, TORTURE_FAIL
,
1165 __location__
": Test 6 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1166 CHECK_MAX_FAILURES(error_test60
);
1170 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1171 NTCREATEX_SHARE_ACCESS_READ
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1174 torture_result(tctx
, TORTURE_FAIL
,
1175 __location__
": Test 6 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1176 CHECK_MAX_FAILURES(error_test60
);
1180 torture_comment(tctx
, "non-io open test #6 passed.\n");
1183 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1184 torture_comment(tctx
, "Test 6 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1187 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1188 torture_comment(tctx
, "Test 6 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1191 torture_comment(tctx
, "Test #7 testing 1 non-io open, one io open with delete\n");
1193 smbcli_unlink(cli1
->tree
, fname
);
1195 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1196 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1199 torture_result(tctx
, TORTURE_FAIL
,
1200 __location__
": Test 7 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1201 CHECK_MAX_FAILURES(error_test70
);
1205 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1206 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1209 torture_result(tctx
, TORTURE_FAIL
,
1210 __location__
": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1211 CHECK_MAX_FAILURES(error_test70
);
1215 torture_comment(tctx
, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1217 torture_comment(tctx
, "non-io open test #7 passed.\n");
1220 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1221 torture_comment(tctx
, "Test 7 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1223 if (fnum2
!= -1 && NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1224 torture_comment(tctx
, "Test 7 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1227 torture_comment(tctx
, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1229 smbcli_unlink(cli1
->tree
, fname
);
1231 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1233 torture_result(tctx
, TORTURE_FAIL
, "(8) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1237 /* write 20 bytes. */
1239 memset(buf
, '\0', 20);
1241 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
1242 torture_result(tctx
, TORTURE_FAIL
, "(8) write failed (%s)\n", smbcli_errstr(cli1
->tree
));
1246 /* Ensure size == 20. */
1247 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1248 torture_result(tctx
, TORTURE_FAIL
,
1249 __location__
": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1250 CHECK_MAX_FAILURES(error_test80
);
1255 torture_result(tctx
, TORTURE_FAIL
,
1256 __location__
": (8) file size %lu != 20\n", (unsigned long)fsize
);
1257 CHECK_MAX_FAILURES(error_test80
);
1261 /* Get an exclusive lock on the open file. */
1262 if (NT_STATUS_IS_ERR(smbcli_lock(cli1
->tree
, fnum1
, 0, 4, 0, WRITE_LOCK
))) {
1263 torture_result(tctx
, TORTURE_FAIL
,
1264 __location__
": (8) lock1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1265 CHECK_MAX_FAILURES(error_test80
);
1269 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_TRUNC
, DENY_NONE
);
1271 torture_result(tctx
, TORTURE_FAIL
, "(8) open (2) of %s with truncate failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1275 /* Ensure size == 0. */
1276 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1277 torture_result(tctx
, TORTURE_FAIL
,
1278 __location__
": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1279 CHECK_MAX_FAILURES(error_test80
);
1284 torture_result(tctx
, TORTURE_FAIL
,
1285 __location__
": (8) file size %lu != 0\n", (unsigned long)fsize
);
1286 CHECK_MAX_FAILURES(error_test80
);
1290 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1291 torture_result(tctx
, TORTURE_FAIL
, "(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1295 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum2
))) {
1296 torture_result(tctx
, TORTURE_FAIL
, "(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1302 torture_comment(tctx
, "open test #8 passed.\n");
1304 smbcli_unlink(cli1
->tree
, fname
);
1306 return failures
> 0 ? false : correct
;
1309 /* FIRST_DESIRED_ACCESS 0xf019f */
1310 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1311 SEC_FILE_READ_EA| /* 0xf */ \
1312 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1313 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1314 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1315 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1316 /* SECOND_DESIRED_ACCESS 0xe0080 */
1317 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1318 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1319 SEC_STD_WRITE_OWNER /* 0xe0000 */
1322 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1323 READ_CONTROL|WRITE_DAC|\
1324 SEC_FILE_READ_DATA|\
1331 Test ntcreate calls made by xcopy
1333 static bool run_xcopy(struct torture_context
*tctx
,
1334 struct smbcli_state
*cli1
)
1336 const char *fname
= "\\test.txt";
1339 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1340 FIRST_DESIRED_ACCESS
,
1341 FILE_ATTRIBUTE_ARCHIVE
,
1342 NTCREATEX_SHARE_ACCESS_NONE
,
1343 NTCREATEX_DISP_OVERWRITE_IF
,
1346 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
,
1347 "First open failed - %s", smbcli_errstr(cli1
->tree
)));
1349 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1350 SECOND_DESIRED_ACCESS
, 0,
1351 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN
,
1353 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
,
1354 "second open failed - %s", smbcli_errstr(cli1
->tree
)));
1359 static bool run_iometer(struct torture_context
*tctx
,
1360 struct smbcli_state
*cli
)
1362 const char *fname
= "\\iobw.tst";
1369 memset(buf
, 0, sizeof(buf
));
1371 status
= smbcli_getatr(cli
->tree
, fname
, NULL
, &filesize
, NULL
);
1372 torture_assert_ntstatus_ok(tctx
, status
,
1373 talloc_asprintf(tctx
, "smbcli_getatr failed: %s", nt_errstr(status
)));
1375 torture_comment(tctx
, "size: %d\n", (int)filesize
);
1377 filesize
-= (sizeof(buf
) - 1);
1379 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0x16,
1380 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1381 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
, "open failed: %s",
1382 smbcli_errstr(cli
->tree
)));
1387 int i
, num_reads
, num_writes
;
1389 num_reads
= random() % 10;
1390 num_writes
= random() % 3;
1392 for (i
=0; i
<num_reads
; i
++) {
1394 if (ops
++ > torture_numops
) {
1397 res
= smbcli_read(cli
->tree
, fnum
, buf
,
1398 random() % filesize
, sizeof(buf
));
1399 torture_assert(tctx
, res
== sizeof(buf
),
1400 talloc_asprintf(tctx
, "read failed: %s",
1401 smbcli_errstr(cli
->tree
)));
1403 for (i
=0; i
<num_writes
; i
++) {
1405 if (ops
++ > torture_numops
) {
1408 res
= smbcli_write(cli
->tree
, fnum
, 0, buf
,
1409 random() % filesize
, sizeof(buf
));
1410 torture_assert(tctx
, res
== sizeof(buf
),
1411 talloc_asprintf(tctx
, "read failed: %s",
1412 smbcli_errstr(cli
->tree
)));
1418 tries variants of chkpath
1420 static bool torture_chkpath_test(struct torture_context
*tctx
,
1421 struct smbcli_state
*cli
)
1426 torture_comment(tctx
, "Testing valid and invalid paths\n");
1428 /* cleanup from an old run */
1429 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1430 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1431 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1433 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir"))) {
1434 torture_result(tctx
, TORTURE_FAIL
, "mkdir1 failed : %s\n", smbcli_errstr(cli
->tree
));
1438 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1439 torture_result(tctx
, TORTURE_FAIL
, "mkdir2 failed : %s\n", smbcli_errstr(cli
->tree
));
1443 fnum
= smbcli_open(cli
->tree
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1445 torture_result(tctx
, TORTURE_FAIL
, "open1 failed (%s)\n", smbcli_errstr(cli
->tree
));
1448 smbcli_close(cli
->tree
, fnum
);
1450 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir"))) {
1451 torture_result(tctx
, TORTURE_FAIL
, "chkpath1 failed: %s\n", smbcli_errstr(cli
->tree
));
1455 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1456 torture_result(tctx
, TORTURE_FAIL
, "chkpath2 failed: %s\n", smbcli_errstr(cli
->tree
));
1460 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\foo.txt"))) {
1461 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1462 NT_STATUS_NOT_A_DIRECTORY
);
1464 torture_result(tctx
, TORTURE_FAIL
, "* chkpath on a file should fail\n");
1468 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\bar.txt"))) {
1469 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1470 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1472 torture_result(tctx
, TORTURE_FAIL
, "* chkpath on a non existent file should fail\n");
1476 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1477 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1478 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1480 torture_result(tctx
, TORTURE_FAIL
, "* chkpath on a non existent component should fail\n");
1484 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1485 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1486 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1492 * This is a test to excercise some weird Samba3 error paths.
1495 static bool torture_samba3_errorpaths(struct torture_context
*tctx
)
1497 bool nt_status_support
;
1498 struct smbcli_state
*cli_nt
= NULL
, *cli_dos
= NULL
;
1499 bool result
= false;
1501 const char *os2_fname
= ".+,;=[].";
1502 const char *dname
= "samba3_errordir";
1506 nt_status_support
= lpcfg_nt_status_support(tctx
->lp_ctx
);
1508 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support", "yes")) {
1509 torture_result(tctx
, TORTURE_FAIL
, "Could not set 'nt status support = yes'\n");
1513 if (!torture_open_connection(&cli_nt
, tctx
, 0)) {
1517 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support", "no")) {
1518 torture_result(tctx
, TORTURE_FAIL
, "Could not set 'nt status support = yes'\n");
1522 if (!torture_open_connection(&cli_dos
, tctx
, 1)) {
1526 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support",
1527 nt_status_support
? "yes":"no")) {
1528 torture_result(tctx
, TORTURE_FAIL
, "Could not reset 'nt status support = yes'");
1532 smbcli_unlink(cli_nt
->tree
, os2_fname
);
1533 smbcli_rmdir(cli_nt
->tree
, dname
);
1535 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt
->tree
, dname
))) {
1536 torture_result(tctx
, TORTURE_FAIL
, "smbcli_mkdir(%s) failed: %s\n", dname
,
1537 smbcli_errstr(cli_nt
->tree
));
1541 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1542 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1543 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1544 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1545 io
.ntcreatex
.in
.alloc_size
= 1024*1024;
1546 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1547 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1548 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1549 io
.ntcreatex
.in
.create_options
= 0;
1550 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1551 io
.ntcreatex
.in
.security_flags
= 0;
1552 io
.ntcreatex
.in
.fname
= dname
;
1554 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1555 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1556 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1557 __location__
, nt_errstr(status
),
1558 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1561 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1562 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRfilexists
))) {
1563 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1564 __location__
, nt_errstr(status
),
1565 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRfilexists
)));
1569 status
= smbcli_mkdir(cli_nt
->tree
, dname
);
1570 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1571 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1572 __location__
, nt_errstr(status
),
1573 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1576 status
= smbcli_mkdir(cli_dos
->tree
, dname
);
1577 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRnoaccess
))) {
1578 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1579 __location__
, nt_errstr(status
),
1580 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRnoaccess
)));
1586 md
.t2mkdir
.level
= RAW_MKDIR_T2MKDIR
;
1587 md
.t2mkdir
.in
.path
= dname
;
1588 md
.t2mkdir
.in
.num_eas
= 0;
1589 md
.t2mkdir
.in
.eas
= NULL
;
1591 status
= smb_raw_mkdir(cli_nt
->tree
, &md
);
1592 if (!NT_STATUS_EQUAL(status
,
1593 NT_STATUS_OBJECT_NAME_COLLISION
)) {
1595 tctx
, "(%s) incorrect status %s should be "
1596 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1597 __location__
, nt_errstr(status
));
1600 status
= smb_raw_mkdir(cli_dos
->tree
, &md
);
1601 if (!NT_STATUS_EQUAL(status
,
1602 NT_STATUS_DOS(ERRDOS
, ERRrename
))) {
1603 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s "
1604 "should be ERRDOS:ERRrename\n",
1605 __location__
, nt_errstr(status
));
1610 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1611 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1612 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1613 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1614 __location__
, nt_errstr(status
),
1615 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1619 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1620 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRfilexists
))) {
1621 torture_result(tctx
, TORTURE_FAIL
, "(%s) incorrect status %s should be %s\n",
1622 __location__
, nt_errstr(status
),
1623 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRfilexists
)));
1628 /* Test an invalid DOS deny mode */
1629 const char *fname
= "test.txt";
1631 fnum
= smbcli_open(cli_nt
->tree
, fname
, O_RDWR
| O_CREAT
, 5);
1633 torture_result(tctx
, TORTURE_FAIL
, "Open(%s) with invalid deny mode succeeded -- "
1634 "expected failure\n", fname
);
1635 smbcli_close(cli_nt
->tree
, fnum
);
1638 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1639 NT_STATUS_DOS(ERRDOS
,ERRbadaccess
))) {
1640 torture_result(tctx
, TORTURE_FAIL
, "Expected DOS error ERRDOS/ERRbadaccess, "
1641 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1645 fnum
= smbcli_open(cli_dos
->tree
, fname
, O_RDWR
| O_CREAT
, 5);
1647 torture_result(tctx
, TORTURE_FAIL
, "Open(%s) with invalid deny mode succeeded -- "
1648 "expected failure\n", fname
);
1649 smbcli_close(cli_nt
->tree
, fnum
);
1652 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1653 NT_STATUS_DOS(ERRDOS
,ERRbadaccess
))) {
1654 torture_result(tctx
, TORTURE_FAIL
, "Expected DOS error ERRDOS:ERRbadaccess, "
1655 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1662 * Samba 3.0.23 has a bug that an existing file can be opened
1663 * as a directory using ntcreate&x. Test this.
1666 const char *fname
= "\\test_dir.txt";
1668 fnum
= smbcli_open(cli_nt
->tree
, fname
, O_RDWR
|O_CREAT
,
1671 d_printf("(%s) smbcli_open failed: %s\n", __location__
,
1672 smbcli_errstr(cli_nt
->tree
));
1674 smbcli_close(cli_nt
->tree
, fnum
);
1676 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1677 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1678 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1679 io
.ntcreatex
.in
.alloc_size
= 0;
1680 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1681 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1682 NTCREATEX_SHARE_ACCESS_WRITE
|
1683 NTCREATEX_SHARE_ACCESS_DELETE
;
1684 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1685 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1686 io
.ntcreatex
.in
.impersonation
=
1687 NTCREATEX_IMPERSONATION_ANONYMOUS
;
1688 io
.ntcreatex
.in
.security_flags
= 0;
1689 io
.ntcreatex
.in
.fname
= fname
;
1690 io
.ntcreatex
.in
.flags
= 0;
1692 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1693 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_A_DIRECTORY
)) {
1694 torture_result(tctx
, TORTURE_FAIL
, "ntcreate as dir gave %s, "
1695 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1700 if (NT_STATUS_IS_OK(status
)) {
1701 smbcli_close(cli_nt
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1704 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1705 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
,
1706 ERRbaddirectory
))) {
1707 torture_result(tctx
, TORTURE_FAIL
, "ntcreate as dir gave %s, "
1708 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1713 if (NT_STATUS_IS_OK(status
)) {
1714 smbcli_close(cli_dos
->tree
,
1715 io
.ntcreatex
.out
.file
.fnum
);
1718 smbcli_unlink(cli_nt
->tree
, fname
);
1721 if (!torture_setting_bool(tctx
, "samba3", false)) {
1725 fnum
= smbcli_open(cli_dos
->tree
, os2_fname
,
1726 O_RDWR
| O_CREAT
| O_TRUNC
,
1729 torture_result(tctx
, TORTURE_FAIL
, "Open(%s) succeeded -- expected failure\n",
1731 smbcli_close(cli_dos
->tree
, fnum
);
1735 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos
->tree
),
1736 NT_STATUS_DOS(ERRDOS
, ERRcannotopen
))) {
1737 torture_result(tctx
, TORTURE_FAIL
, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1738 smbcli_errstr(cli_dos
->tree
));
1742 fnum
= smbcli_open(cli_nt
->tree
, os2_fname
,
1743 O_RDWR
| O_CREAT
| O_TRUNC
,
1746 torture_result(tctx
, TORTURE_FAIL
, "Open(%s) succeeded -- expected failure\n",
1748 smbcli_close(cli_nt
->tree
, fnum
);
1752 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1753 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1754 torture_result(tctx
, TORTURE_FAIL
, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1755 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1763 if (cli_dos
!= NULL
) {
1764 torture_close_connection(cli_dos
);
1766 if (cli_nt
!= NULL
) {
1767 torture_close_connection(cli_nt
);
1774 This checks file/dir birthtime
1776 static void list_fn(struct clilist_file_info
*finfo
, const char *name
,
1779 /* Just to change dir access time*/
1784 static bool run_birthtimetest(struct torture_context
*tctx
,
1785 struct smbcli_state
*cli
)
1789 time_t c_time
, a_time
, m_time
, w_time
, c_time1
;
1790 const char *fname
= "\\birthtime.tst";
1791 const char *dname
= "\\birthtime";
1792 const char *fname2
= "\\birthtime\\birthtime.tst";
1793 bool correct
= true;
1797 smbcli_unlink(cli
->tree
, fname
);
1799 torture_comment(tctx
, "Testing Birthtime for File\n");
1801 /* Save File birthtime/creationtime */
1802 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
1804 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli
->tree
, fnum
, NULL
, &size
,
1805 &c_time
, &a_time
, &m_time
, NULL
, NULL
))) {
1806 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qfileinfo failed (%s)\n",
1807 smbcli_errstr(cli
->tree
));
1810 smbcli_close(cli
->tree
, fnum
);
1814 /* Change in File attribute changes file change time*/
1815 smbcli_setatr(cli
->tree
, fname
, FILE_ATTRIBUTE_SYSTEM
, 0);
1817 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
| O_CREAT
, DENY_NONE
);
1818 /* Writing updates modification time*/
1819 smbcli_smbwrite(cli
->tree
, fnum
, &fname
, 0, sizeof(fname
));
1820 /*Reading updates access time */
1821 smbcli_read(cli
->tree
, fnum
, buf
, 0, 13);
1822 smbcli_close(cli
->tree
, fnum
);
1824 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, fname
, &c_time1
,
1825 &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
1826 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n",
1827 smbcli_errstr(cli
->tree
));
1830 fprintf(stdout
, "c_time = %li, c_time1 = %li\n",
1831 (long) c_time
, (long) c_time1
);
1832 if (c_time1
!= c_time
) {
1833 torture_result(tctx
, TORTURE_FAIL
, "This system updated file \
1834 birth times! Not expected!\n");
1838 smbcli_unlink(cli
->tree
, fname
);
1840 torture_comment(tctx
, "Testing Birthtime for Directory\n");
1842 /* check if the server does not update the directory birth time
1843 when creating a new file */
1844 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, dname
))) {
1845 torture_result(tctx
, TORTURE_FAIL
, "ERROR: mkdir failed (%s)\n",
1846 smbcli_errstr(cli
->tree
));
1850 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\birthtime\\",
1851 &c_time
,&a_time
,&m_time
,&w_time
, &size
, NULL
, NULL
))){
1852 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n",
1853 smbcli_errstr(cli
->tree
));
1857 /* Creating a new file changes dir modification time and change time*/
1858 smbcli_unlink(cli
->tree
, fname2
);
1859 fnum
= smbcli_open(cli
->tree
, fname2
, O_RDWR
| O_CREAT
| O_TRUNC
,
1861 smbcli_smbwrite(cli
->tree
, fnum
, &fnum
, 0, sizeof(fnum
));
1862 smbcli_read(cli
->tree
, fnum
, buf
, 0, 13);
1863 smbcli_close(cli
->tree
, fnum
);
1865 /* dir listing changes dir access time*/
1866 smbcli_list(cli
->tree
, "\\birthtime\\*", 0, list_fn
, cli
);
1868 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\birthtime\\",
1869 &c_time1
, &a_time
, &m_time
,&w_time
,&size
,NULL
,NULL
))){
1870 torture_result(tctx
, TORTURE_FAIL
, "ERROR: qpathinfo2 failed (%s)\n",
1871 smbcli_errstr(cli
->tree
));
1874 fprintf(stdout
, "c_time = %li, c_time1 = %li\n",
1875 (long) c_time
, (long) c_time1
);
1876 if (c_time1
!= c_time
) {
1877 torture_result(tctx
, TORTURE_FAIL
, "This system updated directory \
1878 birth times! Not Expected!\n");
1882 smbcli_unlink(cli
->tree
, fname2
);
1883 smbcli_rmdir(cli
->tree
, dname
);
1889 NTSTATUS
torture_base_init(void)
1891 struct torture_suite
*suite
= torture_suite_create(talloc_autofree_context(), "base");
1893 torture_suite_add_2smb_test(suite
, "fdpass", run_fdpasstest
);
1894 torture_suite_add_suite(suite
, torture_base_locktest(suite
));
1895 torture_suite_add_1smb_test(suite
, "unlink", torture_unlinktest
);
1896 torture_suite_add_1smb_test(suite
, "attr", run_attrtest
);
1897 torture_suite_add_1smb_test(suite
, "trans2", run_trans2test
);
1898 torture_suite_add_1smb_test(suite
, "birthtime", run_birthtimetest
);
1899 torture_suite_add_simple_test(suite
, "negnowait", run_negprot_nowait
);
1900 torture_suite_add_1smb_test(suite
, "dir1", torture_dirtest1
);
1901 torture_suite_add_1smb_test(suite
, "dir2", torture_dirtest2
);
1902 torture_suite_add_1smb_test(suite
, "deny1", torture_denytest1
);
1903 torture_suite_add_2smb_test(suite
, "deny2", torture_denytest2
);
1904 torture_suite_add_2smb_test(suite
, "deny3", torture_denytest3
);
1905 torture_suite_add_1smb_test(suite
, "denydos", torture_denydos_sharing
);
1906 torture_suite_add_smb_multi_test(suite
, "ntdeny1", torture_ntdenytest1
);
1907 torture_suite_add_2smb_test(suite
, "ntdeny2", torture_ntdenytest2
);
1908 torture_suite_add_1smb_test(suite
, "tcon", run_tcon_test
);
1909 torture_suite_add_1smb_test(suite
, "tcondev", run_tcon_devtype_test
);
1910 torture_suite_add_1smb_test(suite
, "vuid", run_vuidtest
);
1911 torture_suite_add_2smb_test(suite
, "rw1", run_readwritetest
);
1912 torture_suite_add_2smb_test(suite
, "open", run_opentest
);
1913 torture_suite_add_smb_multi_test(suite
, "defer_open", run_deferopen
);
1914 torture_suite_add_1smb_test(suite
, "xcopy", run_xcopy
);
1915 torture_suite_add_1smb_test(suite
, "iometer", run_iometer
);
1916 torture_suite_add_1smb_test(suite
, "rename", torture_test_rename
);
1917 torture_suite_add_suite(suite
, torture_test_delete());
1918 torture_suite_add_1smb_test(suite
, "properties", torture_test_properties
);
1919 torture_suite_add_1smb_test(suite
, "mangle", torture_mangle
);
1920 torture_suite_add_1smb_test(suite
, "openattr", torture_openattrtest
);
1921 torture_suite_add_1smb_test(suite
, "winattr", torture_winattrtest
);
1922 torture_suite_add_suite(suite
, torture_charset(suite
));
1923 torture_suite_add_1smb_test(suite
, "chkpath", torture_chkpath_test
);
1924 torture_suite_add_1smb_test(suite
, "secleak", torture_sec_leak
);
1925 torture_suite_add_simple_test(suite
, "disconnect", torture_disconnect
);
1926 torture_suite_add_suite(suite
, torture_delay_write());
1927 torture_suite_add_simple_test(suite
, "samba3error", torture_samba3_errorpaths
);
1928 torture_suite_add_1smb_test(suite
, "casetable", torture_casetable
);
1929 torture_suite_add_1smb_test(suite
, "utable", torture_utable
);
1930 torture_suite_add_simple_test(suite
, "smb", torture_smb_scan
);
1931 torture_suite_add_suite(suite
, torture_trans2_aliases(suite
));
1932 torture_suite_add_1smb_test(suite
, "trans2-scan", torture_trans2_scan
);
1933 torture_suite_add_1smb_test(suite
, "nttrans", torture_nttrans_scan
);
1934 torture_suite_add_1smb_test(suite
, "createx_access", torture_createx_access
);
1935 torture_suite_add_2smb_test(suite
, "createx_sharemodes_file", torture_createx_sharemodes_file
);
1936 torture_suite_add_2smb_test(suite
, "createx_sharemodes_dir", torture_createx_sharemodes_dir
);
1937 torture_suite_add_1smb_test(suite
, "maximum_allowed", torture_maximum_allowed
);
1939 torture_suite_add_simple_test(suite
, "bench-holdcon", torture_holdcon
);
1940 torture_suite_add_1smb_test(suite
, "bench-holdopen", torture_holdopen
);
1941 torture_suite_add_simple_test(suite
, "bench-readwrite", run_benchrw
);
1942 torture_suite_add_smb_multi_test(suite
, "bench-torture", run_torture
);
1943 torture_suite_add_1smb_test(suite
, "scan-pipe_number", run_pipe_number
);
1944 torture_suite_add_1smb_test(suite
, "scan-ioctl", torture_ioctl_test
);
1945 torture_suite_add_1smb_test(suite
, "scan-maxfid", torture_maxfid_test
);
1947 suite
->description
= talloc_strdup(suite
,
1948 "Basic SMB tests (imported from the original smbtorture)");
1950 torture_register_suite(suite
);
1952 return NT_STATUS_OK
;