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
;
44 make_nbt_name_client(&calling
, lpcfg_netbios_name(tctx
->lp_ctx
));
46 nbt_choose_called_name(NULL
, &called
, host
, NBT_NAME_SERVER
);
48 cli
= smbcli_state_init(NULL
);
50 torture_comment(tctx
, "Failed initialize smbcli_struct to connect with %s\n", host
);
54 lpcfg_smbcli_options(tctx
->lp_ctx
, &options
);
56 if (!smbcli_socket_connect(cli
, host
, lpcfg_smb_ports(tctx
->lp_ctx
), tctx
->ev
,
57 lpcfg_resolve_context(tctx
->lp_ctx
), &options
,
58 lpcfg_socket_options(tctx
->lp_ctx
))) {
59 torture_comment(tctx
, "Failed to connect with %s\n", host
);
63 if (!smbcli_transport_establish(cli
, &calling
, &called
)) {
64 torture_comment(tctx
, "%s rejected the session\n",host
);
75 static bool tcon_devtest(struct torture_context
*tctx
,
76 struct smbcli_state
*cli
,
77 const char *myshare
, const char *devtype
,
78 NTSTATUS expected_error
)
81 const char *password
= torture_setting_string(tctx
, "password", NULL
);
83 status
= NT_STATUS_IS_OK(smbcli_tconX(cli
, myshare
, devtype
,
86 torture_comment(tctx
, "Trying share %s with devtype %s\n", myshare
, devtype
);
88 if (NT_STATUS_IS_OK(expected_error
)) {
90 torture_fail(tctx
, talloc_asprintf(tctx
,
91 "tconX to share %s with type %s "
92 "should have succeeded but failed",
98 torture_fail(tctx
, talloc_asprintf(tctx
,
99 "tconx to share %s with type %s "
100 "should have failed but succeeded",
103 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),
106 torture_fail(tctx
, "Returned unexpected error");
116 test whether fnums and tids open on one VC are available on another (a major
119 static bool run_fdpasstest(struct torture_context
*tctx
,
120 struct smbcli_state
*cli1
,
121 struct smbcli_state
*cli2
)
123 const char *fname
= "\\fdpass.tst";
127 smbcli_unlink(cli1
->tree
, fname
);
129 torture_comment(tctx
, "Opening a file on connection 1\n");
131 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
132 torture_assert(tctx
, fnum1
!= -1,
133 talloc_asprintf(tctx
,
134 "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
)));
136 torture_comment(tctx
, "writing to file on connection 1\n");
139 smbcli_write(cli1
->tree
, fnum1
, 0, "hello world\n", 0, 13) == 13,
140 talloc_asprintf(tctx
,
141 "write failed (%s)\n", smbcli_errstr(cli1
->tree
)));
143 oldtid
= cli2
->tree
->tid
;
144 cli2
->session
->vuid
= cli1
->session
->vuid
;
145 cli2
->tree
->tid
= cli1
->tree
->tid
;
146 cli2
->session
->pid
= cli1
->session
->pid
;
148 torture_comment(tctx
, "reading from file on connection 2\n");
150 torture_assert(tctx
, smbcli_read(cli2
->tree
, fnum1
, buf
, 0, 13) != 13,
151 talloc_asprintf(tctx
,
152 "read succeeded! nasty security hole [%s]\n", buf
));
154 smbcli_close(cli1
->tree
, fnum1
);
155 smbcli_unlink(cli1
->tree
, fname
);
157 cli2
->tree
->tid
= oldtid
;
163 This checks how the getatr calls works
165 static bool run_attrtest(struct torture_context
*tctx
,
166 struct smbcli_state
*cli
)
170 const char *fname
= "\\attrib123456789.tst";
173 smbcli_unlink(cli
->tree
, fname
);
174 fnum
= smbcli_open(cli
->tree
, fname
,
175 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
176 smbcli_close(cli
->tree
, fnum
);
178 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
179 torture_comment(tctx
, "getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
183 torture_comment(tctx
, "New file time is %s", ctime(&t
));
185 if (abs(t
- time(NULL
)) > 60*60*24*10) {
186 torture_comment(tctx
, "ERROR: SMBgetatr bug. time is %s",
192 t2
= t
-60*60*24; /* 1 day ago */
194 torture_comment(tctx
, "Setting file time to %s", ctime(&t2
));
196 if (NT_STATUS_IS_ERR(smbcli_setatr(cli
->tree
, fname
, 0, t2
))) {
197 torture_comment(tctx
, "setatr failed (%s)\n", smbcli_errstr(cli
->tree
));
201 if (NT_STATUS_IS_ERR(smbcli_getatr(cli
->tree
, fname
, NULL
, NULL
, &t
))) {
202 torture_comment(tctx
, "getatr failed (%s)\n", smbcli_errstr(cli
->tree
));
206 torture_comment(tctx
, "Retrieved file time as %s", ctime(&t
));
209 torture_comment(tctx
, "ERROR: getatr/setatr bug. times are\n%s",
211 torture_comment(tctx
, "%s", ctime(&t2
));
215 smbcli_unlink(cli
->tree
, fname
);
221 This checks a couple of trans2 calls
223 static bool run_trans2test(struct torture_context
*tctx
,
224 struct smbcli_state
*cli
)
228 time_t c_time
, a_time
, m_time
, w_time
, m_time2
;
229 const char *fname
= "\\trans2.tst";
230 const char *dname
= "\\trans2";
231 const char *fname2
= "\\trans2\\trans2.tst";
235 smbcli_unlink(cli
->tree
, fname
);
237 torture_comment(tctx
, "Testing qfileinfo\n");
239 fnum
= smbcli_open(cli
->tree
, fname
,
240 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
241 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli
->tree
, fnum
, NULL
, &size
, &c_time
, &a_time
, &m_time
,
243 torture_comment(tctx
, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
247 torture_comment(tctx
, "Testing NAME_INFO\n");
249 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli
->tree
, fnum
, &pname
))) {
250 torture_comment(tctx
, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli
->tree
));
254 if (!pname
|| strcmp(pname
, fname
)) {
255 torture_comment(tctx
, "qfilename gave different name? [%s] [%s]\n",
260 smbcli_close(cli
->tree
, fnum
);
261 smbcli_unlink(cli
->tree
, fname
);
263 fnum
= smbcli_open(cli
->tree
, fname
,
264 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
266 torture_comment(tctx
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
269 smbcli_close(cli
->tree
, fnum
);
271 torture_comment(tctx
, "Checking for sticky create times\n");
273 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
))) {
274 torture_comment(tctx
, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli
->tree
));
277 time_t t
= time(NULL
);
279 if (c_time
!= m_time
) {
280 torture_comment(tctx
, "create time=%s", ctime(&c_time
));
281 torture_comment(tctx
, "modify time=%s", ctime(&m_time
));
282 torture_comment(tctx
, "This system appears to have sticky create times\n");
284 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
285 torture_comment(tctx
, "access time=%s", ctime(&a_time
));
286 torture_comment(tctx
, "This system appears to set a midnight access time\n");
290 if (abs(m_time
- t
) > 60*60*24*7) {
291 torture_comment(tctx
, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
297 smbcli_unlink(cli
->tree
, fname
);
298 fnum
= smbcli_open(cli
->tree
, fname
,
299 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
300 smbcli_close(cli
->tree
, fnum
);
301 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, fname
, &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
302 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
305 if (w_time
< 60*60*24*2) {
306 torture_comment(tctx
, "write time=%s", ctime(&w_time
));
307 torture_comment(tctx
, "This system appears to set a initial 0 write time\n");
312 smbcli_unlink(cli
->tree
, fname
);
315 /* check if the server updates the directory modification time
316 when creating a new file */
317 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, dname
))) {
318 torture_comment(tctx
, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli
->tree
));
322 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
323 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
327 fnum
= smbcli_open(cli
->tree
, fname2
,
328 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
329 smbcli_write(cli
->tree
, fnum
, 0, &fnum
, 0, sizeof(fnum
));
330 smbcli_close(cli
->tree
, fnum
);
331 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\trans2\\", &c_time
, &a_time
, &m_time2
, &w_time
, &size
, NULL
, NULL
))) {
332 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli
->tree
));
335 if (m_time2
== m_time
) {
336 torture_comment(tctx
, "This system does not update directory modification times\n");
340 smbcli_unlink(cli
->tree
, fname2
);
341 smbcli_rmdir(cli
->tree
, dname
);
346 /* send smb negprot commands, not reading the response */
347 static bool run_negprot_nowait(struct torture_context
*tctx
)
350 struct smbcli_state
*cli
, *cli2
;
353 torture_comment(tctx
, "starting negprot nowait test\n");
355 cli
= open_nbt_connection(tctx
);
360 torture_comment(tctx
, "Filling send buffer\n");
362 for (i
=0;i
<100;i
++) {
363 struct smbcli_request
*req
;
364 req
= smb_raw_negotiate_send(cli
->transport
, lpcfg_unicode(tctx
->lp_ctx
), PROTOCOL_NT1
);
365 tevent_loop_once(cli
->transport
->socket
->event
.ctx
);
366 if (req
->state
== SMBCLI_REQUEST_ERROR
) {
368 torture_comment(tctx
, "Failed to fill pipe packet[%d] - %s (ignored)\n", i
+1, nt_errstr(req
->status
));
371 torture_comment(tctx
, "Failed to fill pipe - %s \n", nt_errstr(req
->status
));
372 torture_close_connection(cli
);
378 torture_comment(tctx
, "Opening secondary connection\n");
379 if (!torture_open_connection(&cli2
, tctx
, 1)) {
380 torture_comment(tctx
, "Failed to open secondary connection\n");
384 if (!torture_close_connection(cli2
)) {
385 torture_comment(tctx
, "Failed to close secondary connection\n");
389 torture_close_connection(cli
);
395 this checks to see if a secondary tconx can use open files from an
398 static bool run_tcon_test(struct torture_context
*tctx
, struct smbcli_state
*cli
)
400 const char *fname
= "\\tcontest.tmp";
402 uint16_t cnum1
, cnum2
, cnum3
;
403 uint16_t vuid1
, vuid2
;
406 struct smbcli_tree
*tree1
;
407 const char *host
= torture_setting_string(tctx
, "host", NULL
);
408 const char *share
= torture_setting_string(tctx
, "share", NULL
);
409 const char *password
= torture_setting_string(tctx
, "password", NULL
);
411 if (smbcli_deltree(cli
->tree
, fname
) == -1) {
412 torture_comment(tctx
, "unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
415 fnum1
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
417 torture_comment(tctx
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
421 cnum1
= cli
->tree
->tid
;
422 vuid1
= cli
->session
->vuid
;
424 memset(buf
, 0, 4); /* init buf so valgrind won't complain */
425 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) != 4) {
426 torture_comment(tctx
, "initial write failed (%s)\n", smbcli_errstr(cli
->tree
));
430 tree1
= cli
->tree
; /* save old tree connection */
431 if (NT_STATUS_IS_ERR(smbcli_tconX(cli
, share
, "?????", password
))) {
432 torture_comment(tctx
, "%s refused 2nd tree connect (%s)\n", host
,
433 smbcli_errstr(cli
->tree
));
438 cnum2
= cli
->tree
->tid
;
439 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
440 vuid2
= cli
->session
->vuid
+ 1;
442 /* try a write with the wrong tid */
443 cli
->tree
->tid
= cnum2
;
445 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
446 torture_comment(tctx
, "* server allows write with wrong TID\n");
449 torture_comment(tctx
, "server fails write with wrong TID : %s\n", smbcli_errstr(cli
->tree
));
453 /* try a write with an invalid tid */
454 cli
->tree
->tid
= cnum3
;
456 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
457 torture_comment(tctx
, "* server allows write with invalid TID\n");
460 torture_comment(tctx
, "server fails write with invalid TID : %s\n", smbcli_errstr(cli
->tree
));
463 /* try a write with an invalid vuid */
464 cli
->session
->vuid
= vuid2
;
465 cli
->tree
->tid
= cnum1
;
467 if (smbcli_write(cli
->tree
, fnum1
, 0, buf
, 130, 4) == 4) {
468 torture_comment(tctx
, "* server allows write with invalid VUID\n");
471 torture_comment(tctx
, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli
->tree
));
474 cli
->session
->vuid
= vuid1
;
475 cli
->tree
->tid
= cnum1
;
477 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum1
))) {
478 torture_comment(tctx
, "close failed (%s)\n", smbcli_errstr(cli
->tree
));
482 cli
->tree
->tid
= cnum2
;
484 if (NT_STATUS_IS_ERR(smbcli_tdis(cli
))) {
485 torture_comment(tctx
, "secondary tdis failed (%s)\n", smbcli_errstr(cli
->tree
));
489 cli
->tree
= tree1
; /* restore initial tree */
490 cli
->tree
->tid
= cnum1
;
492 smbcli_unlink(tree1
, fname
);
498 checks for correct tconX support
500 static bool run_tcon_devtype_test(struct torture_context
*tctx
,
501 struct smbcli_state
*cli1
)
503 const char *share
= torture_setting_string(tctx
, "share", NULL
);
505 if (!tcon_devtest(tctx
, cli1
, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE
))
508 if (!tcon_devtest(tctx
, cli1
, "IPC$", "?????", NT_STATUS_OK
))
511 if (!tcon_devtest(tctx
, cli1
, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
514 if (!tcon_devtest(tctx
, cli1
, "IPC$", "IPC", NT_STATUS_OK
))
517 if (!tcon_devtest(tctx
, cli1
, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
520 if (!tcon_devtest(tctx
, cli1
, share
, "A:", NT_STATUS_OK
))
523 if (!tcon_devtest(tctx
, cli1
, share
, "?????", NT_STATUS_OK
))
526 if (!tcon_devtest(tctx
, cli1
, share
, "LPT:", NT_STATUS_BAD_DEVICE_TYPE
))
529 if (!tcon_devtest(tctx
, cli1
, share
, "IPC", NT_STATUS_BAD_DEVICE_TYPE
))
532 if (!tcon_devtest(tctx
, cli1
, share
, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE
))
538 static bool rw_torture2(struct torture_context
*tctx
,
539 struct smbcli_state
*c1
, struct smbcli_state
*c2
)
541 const char *lockfname
= "\\torture2.lck";
546 uint8_t buf_rd
[131072];
548 ssize_t bytes_read
, bytes_written
;
550 torture_assert(tctx
, smbcli_deltree(c1
->tree
, lockfname
) != -1,
551 talloc_asprintf(tctx
,
552 "unlink failed (%s)", smbcli_errstr(c1
->tree
)));
554 fnum1
= smbcli_open(c1
->tree
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
556 torture_assert(tctx
, fnum1
!= -1,
557 talloc_asprintf(tctx
,
558 "first open read/write of %s failed (%s)",
559 lockfname
, smbcli_errstr(c1
->tree
)));
560 fnum2
= smbcli_open(c2
->tree
, lockfname
, O_RDONLY
,
562 torture_assert(tctx
, fnum2
!= -1,
563 talloc_asprintf(tctx
,
564 "second open read-only of %s failed (%s)",
565 lockfname
, smbcli_errstr(c2
->tree
)));
567 torture_comment(tctx
, "Checking data integrity over %d ops\n",
570 for (i
=0;i
<torture_numops
;i
++)
572 size_t buf_size
= ((unsigned int)random()%(sizeof(buf
)-1))+ 1;
574 if (torture_setting_bool(tctx
, "progress", true)) {
575 torture_comment(tctx
, "%d\r", i
); fflush(stdout
);
579 generate_random_buffer(buf
, buf_size
);
581 if ((bytes_written
= smbcli_write(c1
->tree
, fnum1
, 0, buf
, 0, buf_size
)) != buf_size
) {
582 torture_comment(tctx
, "write failed (%s)\n", smbcli_errstr(c1
->tree
));
583 torture_comment(tctx
, "wrote %d, expected %d\n", (int)bytes_written
, (int)buf_size
);
588 if ((bytes_read
= smbcli_read(c2
->tree
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
589 torture_comment(tctx
, "read failed (%s)\n", smbcli_errstr(c2
->tree
));
590 torture_comment(tctx
, "read %d, expected %d\n", (int)bytes_read
, (int)buf_size
);
595 torture_assert_mem_equal(tctx
, buf_rd
, buf
, buf_size
,
596 "read/write compare failed\n");
599 torture_assert_ntstatus_ok(tctx
, smbcli_close(c2
->tree
, fnum2
),
600 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(c2
->tree
)));
601 torture_assert_ntstatus_ok(tctx
, smbcli_close(c1
->tree
, fnum1
),
602 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(c1
->tree
)));
604 torture_assert_ntstatus_ok(tctx
, smbcli_unlink(c1
->tree
, lockfname
),
605 talloc_asprintf(tctx
, "unlink failed (%s)", smbcli_errstr(c1
->tree
)));
607 torture_comment(tctx
, "\n");
614 static bool run_readwritetest(struct torture_context
*tctx
,
615 struct smbcli_state
*cli1
,
616 struct smbcli_state
*cli2
)
618 torture_comment(tctx
, "Running readwritetest v1\n");
619 if (!rw_torture2(tctx
, cli1
, cli2
))
622 torture_comment(tctx
, "Running readwritetest v2\n");
624 if (!rw_torture2(tctx
, cli1
, cli1
))
631 test the timing of deferred open requests
633 static bool run_deferopen(struct torture_context
*tctx
, struct smbcli_state
*cli
, int dummy
)
635 const char *fname
= "\\defer_open_test.dat";
643 nsec
= torture_setting_int(tctx
, "sharedelay", 1000000);
645 sec
= ((double)nsec
) / ((double) 1000000);
648 torture_comment(tctx
, "failed to connect\n");
652 torture_comment(tctx
, "Testing deferred open requests.\n");
659 tv
= timeval_current();
660 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0,
662 FILE_ATTRIBUTE_NORMAL
,
663 NTCREATEX_SHARE_ACCESS_NONE
,
664 NTCREATEX_DISP_OPEN_IF
, 0, 0);
668 if (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
)) {
669 double e
= timeval_elapsed(&tv
);
670 if (e
< (0.5 * sec
) || e
> ((1.5 * sec
) + 1)) {
671 torture_comment(tctx
,"Timing incorrect %.2f violation 1 sec == %.2f\n",
676 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli
->tree
),NT_STATUS_SHARING_VIOLATION
));
679 torture_comment(tctx
,"Failed to open %s, error=%s\n", fname
, smbcli_errstr(cli
->tree
));
683 torture_comment(tctx
, "pid %u open %d\n", (unsigned)getpid(), i
);
685 smb_msleep(10 * msec
);
687 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnum
))) {
688 torture_comment(tctx
,"Failed to close %s, error=%s\n", fname
, smbcli_errstr(cli
->tree
));
691 smb_msleep(2 * msec
);
694 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fname
))) {
695 /* All until the last unlink will fail with sharing violation
696 but also the last request can fail since the file could have
697 been successfully deleted by another (test) process */
698 NTSTATUS status
= smbcli_nt_error(cli
->tree
);
699 if ((!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
))
700 && (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
))) {
701 torture_comment(tctx
, "unlink of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
706 torture_comment(tctx
, "deferred test finished\n");
711 Try with a wrong vuid and check error message.
714 static bool run_vuidtest(struct torture_context
*tctx
,
715 struct smbcli_state
*cli
)
717 const char *fname
= "\\vuid.tst";
720 time_t c_time
, a_time
, m_time
;
725 smbcli_unlink(cli
->tree
, fname
);
727 fnum
= smbcli_open(cli
->tree
, fname
,
728 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
730 orig_vuid
= cli
->session
->vuid
;
732 cli
->session
->vuid
+= 1234;
734 torture_comment(tctx
, "Testing qfileinfo with wrong vuid\n");
736 if (NT_STATUS_IS_OK(result
= smbcli_qfileinfo(cli
->tree
, fnum
, NULL
,
737 &size
, &c_time
, &a_time
,
738 &m_time
, NULL
, NULL
))) {
739 torture_fail(tctx
, "qfileinfo passed with wrong vuid");
742 if (!NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
743 NT_STATUS_DOS(ERRSRV
, ERRbaduid
)) &&
744 !NT_STATUS_EQUAL(cli
->transport
->error
.e
.nt_status
,
745 NT_STATUS_INVALID_HANDLE
)) {
746 torture_fail(tctx
, talloc_asprintf(tctx
,
747 "qfileinfo should have returned DOS error "
748 "ERRSRV:ERRbaduid\n but returned %s",
749 smbcli_errstr(cli
->tree
)));
752 cli
->session
->vuid
-= 1234;
754 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli
->tree
, fnum
),
755 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(cli
->tree
)));
757 smbcli_unlink(cli
->tree
, fname
);
763 Test open mode returns on read-only files.
765 static bool run_opentest(struct torture_context
*tctx
, struct smbcli_state
*cli1
,
766 struct smbcli_state
*cli2
)
768 const char *fname
= "\\readonly.file";
769 char *control_char_fname
;
778 asprintf(&control_char_fname
, "\\readonly.afile");
779 for (i
= 1; i
<= 0x1f; i
++) {
780 control_char_fname
[10] = i
;
781 fnum1
= smbcli_nt_create_full(cli1
->tree
, control_char_fname
, 0, SEC_FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
782 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
784 if (!check_error(__location__
, cli1
, ERRDOS
, ERRinvalidname
,
785 NT_STATUS_OBJECT_NAME_INVALID
)) {
786 torture_comment(tctx
, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
787 smbcli_errstr(cli1
->tree
), i
);
792 smbcli_close(cli1
->tree
, fnum1
);
794 smbcli_setatr(cli1
->tree
, control_char_fname
, 0, 0);
795 smbcli_unlink(cli1
->tree
, control_char_fname
);
797 free(control_char_fname
);
800 torture_comment(tctx
, "Create file with control char names passed.\n");
802 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
803 smbcli_unlink(cli1
->tree
, fname
);
805 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
807 torture_comment(tctx
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
811 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
812 torture_comment(tctx
, "close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
816 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1
->tree
, fname
, FILE_ATTRIBUTE_READONLY
, 0))) {
817 torture_result(tctx
, TORTURE_FAIL
,
818 __location__
": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
819 CHECK_MAX_FAILURES(error_test1
);
823 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
825 torture_result(tctx
, TORTURE_FAIL
,
826 __location__
": open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
827 CHECK_MAX_FAILURES(error_test1
);
831 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
832 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
834 if (check_error(__location__
, cli1
, ERRDOS
, ERRnoaccess
,
835 NT_STATUS_ACCESS_DENIED
)) {
836 torture_comment(tctx
, "correct error code ERRDOS/ERRnoaccess returned\n");
839 torture_comment(tctx
, "finished open test 1\n");
842 smbcli_close(cli1
->tree
, fnum1
);
844 /* Now try not readonly and ensure ERRbadshare is returned. */
846 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
848 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_WRITE
);
850 torture_comment(tctx
, "open of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
854 /* This will fail - but the error should be ERRshare. */
855 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_ALL
);
857 if (check_error(__location__
, cli1
, ERRDOS
, ERRbadshare
,
858 NT_STATUS_SHARING_VIOLATION
)) {
859 torture_comment(tctx
, "correct error code ERRDOS/ERRbadshare returned\n");
862 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
863 torture_comment(tctx
, "close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
867 smbcli_unlink(cli1
->tree
, fname
);
869 torture_comment(tctx
, "finished open test 2\n");
871 /* Test truncate open disposition on file opened for read. */
873 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
875 torture_comment(tctx
, "(3) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
879 /* write 20 bytes. */
881 memset(buf
, '\0', 20);
883 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
884 torture_comment(tctx
, "write failed (%s)\n", smbcli_errstr(cli1
->tree
));
888 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
889 torture_comment(tctx
, "(3) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
893 /* Ensure size == 20. */
894 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
895 torture_result(tctx
, TORTURE_FAIL
,
896 __location__
": (3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
897 CHECK_MAX_FAILURES(error_test3
);
902 torture_result(tctx
, TORTURE_FAIL
,
903 __location__
": (3) file size != 20\n");
904 CHECK_MAX_FAILURES(error_test3
);
908 /* Now test if we can truncate a file opened for readonly. */
910 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
912 torture_result(tctx
, TORTURE_FAIL
,
913 __location__
": (3) open (2) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
914 CHECK_MAX_FAILURES(error_test3
);
918 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
919 torture_result(tctx
, TORTURE_FAIL
,
920 __location__
": close2 failed (%s)\n", smbcli_errstr(cli1
->tree
));
924 /* Ensure size == 0. */
925 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
926 torture_result(tctx
, TORTURE_FAIL
,
927 __location__
": (3) getatr failed (%s)\n", smbcli_errstr(cli1
->tree
));
928 CHECK_MAX_FAILURES(error_test3
);
933 torture_result(tctx
, TORTURE_FAIL
,
934 __location__
": (3) file size != 0\n");
935 CHECK_MAX_FAILURES(error_test3
);
938 torture_comment(tctx
, "finished open test 3\n");
942 smbcli_unlink(cli1
->tree
, fname
);
945 torture_comment(tctx
, "Testing ctemp\n");
946 fnum1
= smbcli_ctemp(cli1
->tree
, "\\", &tmp_path
);
948 torture_result(tctx
, TORTURE_FAIL
,
949 __location__
": ctemp failed (%s)\n", smbcli_errstr(cli1
->tree
));
950 CHECK_MAX_FAILURES(error_test4
);
953 torture_comment(tctx
, "ctemp gave path %s\n", tmp_path
);
956 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
957 torture_comment(tctx
, "close of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
959 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1
->tree
, tmp_path
))) {
960 torture_comment(tctx
, "unlink of temp failed (%s)\n", smbcli_errstr(cli1
->tree
));
963 /* Test the non-io opens... */
965 torture_comment(tctx
, "Test #1 testing 2 non-io opens (no delete)\n");
967 smbcli_setatr(cli2
->tree
, fname
, 0, 0);
968 smbcli_unlink(cli2
->tree
, fname
);
970 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
971 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
974 torture_result(tctx
, TORTURE_FAIL
,
975 __location__
": Test 1 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
976 CHECK_MAX_FAILURES(error_test10
);
980 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
981 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
983 torture_result(tctx
, TORTURE_FAIL
,
984 __location__
": Test 1 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
985 CHECK_MAX_FAILURES(error_test10
);
989 torture_comment(tctx
, "non-io open test #1 passed.\n");
992 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
993 torture_comment(tctx
, "Test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
995 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
996 torture_comment(tctx
, "Test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
999 torture_comment(tctx
, "Test #2 testing 2 non-io opens (first with delete)\n");
1001 smbcli_unlink(cli1
->tree
, fname
);
1003 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1004 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1007 torture_result(tctx
, TORTURE_FAIL
,
1008 __location__
": Test 2 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1009 CHECK_MAX_FAILURES(error_test20
);
1013 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1014 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1017 torture_result(tctx
, TORTURE_FAIL
,
1018 __location__
": Test 2 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1019 CHECK_MAX_FAILURES(error_test20
);
1023 torture_comment(tctx
, "non-io open test #2 passed.\n");
1026 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1027 torture_comment(tctx
, "Test 1 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1029 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1030 torture_comment(tctx
, "Test 1 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1034 smbcli_unlink(cli1
->tree
, fname
);
1036 torture_comment(tctx
, "Test #3 testing 2 non-io opens (second with delete)\n");
1038 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1039 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1042 torture_result(tctx
, TORTURE_FAIL
,
1043 __location__
": Test 3 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1044 CHECK_MAX_FAILURES(error_test30
);
1048 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1049 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1052 torture_result(tctx
, TORTURE_FAIL
,
1053 __location__
": Test 3 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1054 CHECK_MAX_FAILURES(error_test30
);
1058 torture_comment(tctx
, "non-io open test #3 passed.\n");
1061 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1062 torture_comment(tctx
, "Test 3 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1064 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1065 torture_comment(tctx
, "Test 3 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1068 torture_comment(tctx
, "Test #4 testing 2 non-io opens (both with delete)\n");
1070 smbcli_unlink(cli1
->tree
, fname
);
1072 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1073 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1076 torture_result(tctx
, TORTURE_FAIL
,
1077 __location__
": Test 4 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1078 CHECK_MAX_FAILURES(error_test40
);
1082 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1083 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1086 torture_result(tctx
, TORTURE_FAIL
,
1087 __location__
": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1088 CHECK_MAX_FAILURES(error_test40
);
1092 torture_comment(tctx
, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1094 torture_comment(tctx
, "non-io open test #4 passed.\n");
1097 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1098 torture_comment(tctx
, "Test 4 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1100 if (fnum2
!= -1 && NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1101 torture_comment(tctx
, "Test 4 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1104 torture_comment(tctx
, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1106 smbcli_unlink(cli1
->tree
, fname
);
1108 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1109 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1112 torture_result(tctx
, TORTURE_FAIL
,
1113 __location__
": Test 5 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1114 CHECK_MAX_FAILURES(error_test50
);
1118 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1119 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1122 torture_result(tctx
, TORTURE_FAIL
,
1123 __location__
": Test 5 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1124 CHECK_MAX_FAILURES(error_test50
);
1128 torture_comment(tctx
, "non-io open test #5 passed.\n");
1131 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1132 torture_comment(tctx
, "Test 5 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1135 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1136 torture_comment(tctx
, "Test 5 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1139 torture_comment(tctx
, "Test #6 testing 1 non-io open, one io open\n");
1141 smbcli_unlink(cli1
->tree
, fname
);
1143 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1144 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1147 torture_result(tctx
, TORTURE_FAIL
,
1148 __location__
": Test 6 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1149 CHECK_MAX_FAILURES(error_test60
);
1153 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1154 NTCREATEX_SHARE_ACCESS_READ
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1157 torture_result(tctx
, TORTURE_FAIL
,
1158 __location__
": Test 6 open 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1159 CHECK_MAX_FAILURES(error_test60
);
1163 torture_comment(tctx
, "non-io open test #6 passed.\n");
1166 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1167 torture_comment(tctx
, "Test 6 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1170 if (NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1171 torture_comment(tctx
, "Test 6 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1174 torture_comment(tctx
, "Test #7 testing 1 non-io open, one io open with delete\n");
1176 smbcli_unlink(cli1
->tree
, fname
);
1178 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
1179 NTCREATEX_SHARE_ACCESS_NONE
, NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
1182 torture_result(tctx
, TORTURE_FAIL
,
1183 __location__
": Test 7 open 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1184 CHECK_MAX_FAILURES(error_test70
);
1188 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0, SEC_STD_DELETE
|SEC_FILE_READ_ATTRIBUTE
, FILE_ATTRIBUTE_NORMAL
,
1189 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
1192 torture_result(tctx
, TORTURE_FAIL
,
1193 __location__
": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1194 CHECK_MAX_FAILURES(error_test70
);
1198 torture_comment(tctx
, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, smbcli_errstr(cli2
->tree
), "sharing violation");
1200 torture_comment(tctx
, "non-io open test #7 passed.\n");
1203 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1204 torture_comment(tctx
, "Test 7 close 1 of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1206 if (fnum2
!= -1 && NT_STATUS_IS_ERR(smbcli_close(cli2
->tree
, fnum2
))) {
1207 torture_comment(tctx
, "Test 7 close 2 of %s failed (%s)\n", fname
, smbcli_errstr(cli2
->tree
));
1210 torture_comment(tctx
, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1212 smbcli_unlink(cli1
->tree
, fname
);
1214 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1216 torture_comment(tctx
, "(8) open (1) of %s failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1220 /* write 20 bytes. */
1222 memset(buf
, '\0', 20);
1224 if (smbcli_write(cli1
->tree
, fnum1
, 0, buf
, 0, 20) != 20) {
1225 torture_comment(tctx
, "(8) write failed (%s)\n", smbcli_errstr(cli1
->tree
));
1229 /* Ensure size == 20. */
1230 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1231 torture_result(tctx
, TORTURE_FAIL
,
1232 __location__
": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1233 CHECK_MAX_FAILURES(error_test80
);
1238 torture_result(tctx
, TORTURE_FAIL
,
1239 __location__
": (8) file size %lu != 20\n", (unsigned long)fsize
);
1240 CHECK_MAX_FAILURES(error_test80
);
1244 /* Get an exclusive lock on the open file. */
1245 if (NT_STATUS_IS_ERR(smbcli_lock(cli1
->tree
, fnum1
, 0, 4, 0, WRITE_LOCK
))) {
1246 torture_result(tctx
, TORTURE_FAIL
,
1247 __location__
": (8) lock1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1248 CHECK_MAX_FAILURES(error_test80
);
1252 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
|O_TRUNC
, DENY_NONE
);
1254 torture_comment(tctx
, "(8) open (2) of %s with truncate failed (%s)\n", fname
, smbcli_errstr(cli1
->tree
));
1258 /* Ensure size == 0. */
1259 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1
->tree
, fname
, NULL
, &fsize
, NULL
))) {
1260 torture_result(tctx
, TORTURE_FAIL
,
1261 __location__
": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1
->tree
));
1262 CHECK_MAX_FAILURES(error_test80
);
1267 torture_result(tctx
, TORTURE_FAIL
,
1268 __location__
": (8) file size %lu != 0\n", (unsigned long)fsize
);
1269 CHECK_MAX_FAILURES(error_test80
);
1273 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum1
))) {
1274 torture_comment(tctx
, "(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1278 if (NT_STATUS_IS_ERR(smbcli_close(cli1
->tree
, fnum2
))) {
1279 torture_comment(tctx
, "(8) close1 failed (%s)\n", smbcli_errstr(cli1
->tree
));
1285 torture_comment(tctx
, "open test #8 passed.\n");
1287 smbcli_unlink(cli1
->tree
, fname
);
1289 return failures
> 0 ? false : correct
;
1292 /* FIRST_DESIRED_ACCESS 0xf019f */
1293 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1294 SEC_FILE_READ_EA| /* 0xf */ \
1295 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1296 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1297 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1298 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1299 /* SECOND_DESIRED_ACCESS 0xe0080 */
1300 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1301 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1302 SEC_STD_WRITE_OWNER /* 0xe0000 */
1305 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1306 READ_CONTROL|WRITE_DAC|\
1307 SEC_FILE_READ_DATA|\
1314 Test ntcreate calls made by xcopy
1316 static bool run_xcopy(struct torture_context
*tctx
,
1317 struct smbcli_state
*cli1
)
1319 const char *fname
= "\\test.txt";
1322 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1323 FIRST_DESIRED_ACCESS
,
1324 FILE_ATTRIBUTE_ARCHIVE
,
1325 NTCREATEX_SHARE_ACCESS_NONE
,
1326 NTCREATEX_DISP_OVERWRITE_IF
,
1329 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
,
1330 "First open failed - %s", smbcli_errstr(cli1
->tree
)));
1332 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1333 SECOND_DESIRED_ACCESS
, 0,
1334 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OPEN
,
1336 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
,
1337 "second open failed - %s", smbcli_errstr(cli1
->tree
)));
1342 static bool run_iometer(struct torture_context
*tctx
,
1343 struct smbcli_state
*cli
)
1345 const char *fname
= "\\iobw.tst";
1352 memset(buf
, 0, sizeof(buf
));
1354 status
= smbcli_getatr(cli
->tree
, fname
, NULL
, &filesize
, NULL
);
1355 torture_assert_ntstatus_ok(tctx
, status
,
1356 talloc_asprintf(tctx
, "smbcli_getatr failed: %s", nt_errstr(status
)));
1358 torture_comment(tctx
, "size: %d\n", (int)filesize
);
1360 filesize
-= (sizeof(buf
) - 1);
1362 fnum
= smbcli_nt_create_full(cli
->tree
, fname
, 0x16,
1363 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1364 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
, "open failed: %s",
1365 smbcli_errstr(cli
->tree
)));
1370 int i
, num_reads
, num_writes
;
1372 num_reads
= random() % 10;
1373 num_writes
= random() % 3;
1375 for (i
=0; i
<num_reads
; i
++) {
1377 if (ops
++ > torture_numops
) {
1380 res
= smbcli_read(cli
->tree
, fnum
, buf
,
1381 random() % filesize
, sizeof(buf
));
1382 torture_assert(tctx
, res
== sizeof(buf
),
1383 talloc_asprintf(tctx
, "read failed: %s",
1384 smbcli_errstr(cli
->tree
)));
1386 for (i
=0; i
<num_writes
; i
++) {
1388 if (ops
++ > torture_numops
) {
1391 res
= smbcli_write(cli
->tree
, fnum
, 0, buf
,
1392 random() % filesize
, sizeof(buf
));
1393 torture_assert(tctx
, res
== sizeof(buf
),
1394 talloc_asprintf(tctx
, "read failed: %s",
1395 smbcli_errstr(cli
->tree
)));
1401 tries variants of chkpath
1403 static bool torture_chkpath_test(struct torture_context
*tctx
,
1404 struct smbcli_state
*cli
)
1409 torture_comment(tctx
, "Testing valid and invalid paths\n");
1411 /* cleanup from an old run */
1412 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1413 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1414 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1416 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir"))) {
1417 torture_comment(tctx
, "mkdir1 failed : %s\n", smbcli_errstr(cli
->tree
));
1421 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1422 torture_comment(tctx
, "mkdir2 failed : %s\n", smbcli_errstr(cli
->tree
));
1426 fnum
= smbcli_open(cli
->tree
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1428 torture_comment(tctx
, "open1 failed (%s)\n", smbcli_errstr(cli
->tree
));
1431 smbcli_close(cli
->tree
, fnum
);
1433 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir"))) {
1434 torture_comment(tctx
, "chkpath1 failed: %s\n", smbcli_errstr(cli
->tree
));
1438 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dir2"))) {
1439 torture_comment(tctx
, "chkpath2 failed: %s\n", smbcli_errstr(cli
->tree
));
1443 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\foo.txt"))) {
1444 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1445 NT_STATUS_NOT_A_DIRECTORY
);
1447 torture_comment(tctx
, "* chkpath on a file should fail\n");
1451 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\bar.txt"))) {
1452 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1453 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1455 torture_comment(tctx
, "* chkpath on a non existent file should fail\n");
1459 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli
->tree
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1460 ret
= check_error(__location__
, cli
, ERRDOS
, ERRbadpath
,
1461 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1463 torture_comment(tctx
, "* chkpath on a non existent component should fail\n");
1467 smbcli_rmdir(cli
->tree
, "\\chkpath.dir\\dir2");
1468 smbcli_unlink(cli
->tree
, "\\chkpath.dir\\*");
1469 smbcli_rmdir(cli
->tree
, "\\chkpath.dir");
1475 * This is a test to excercise some weird Samba3 error paths.
1478 static bool torture_samba3_errorpaths(struct torture_context
*tctx
)
1480 bool nt_status_support
;
1481 struct smbcli_state
*cli_nt
= NULL
, *cli_dos
= NULL
;
1482 bool result
= false;
1484 const char *os2_fname
= ".+,;=[].";
1485 const char *dname
= "samba3_errordir";
1489 nt_status_support
= lpcfg_nt_status_support(tctx
->lp_ctx
);
1491 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support", "yes")) {
1492 torture_comment(tctx
, "Could not set 'nt status support = yes'\n");
1496 if (!torture_open_connection(&cli_nt
, tctx
, 0)) {
1500 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support", "no")) {
1501 torture_comment(tctx
, "Could not set 'nt status support = yes'\n");
1505 if (!torture_open_connection(&cli_dos
, tctx
, 1)) {
1509 if (!lpcfg_set_cmdline(tctx
->lp_ctx
, "nt status support",
1510 nt_status_support
? "yes":"no")) {
1511 torture_comment(tctx
, "Could not reset 'nt status support = yes'");
1515 smbcli_unlink(cli_nt
->tree
, os2_fname
);
1516 smbcli_rmdir(cli_nt
->tree
, dname
);
1518 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt
->tree
, dname
))) {
1519 torture_comment(tctx
, "smbcli_mkdir(%s) failed: %s\n", dname
,
1520 smbcli_errstr(cli_nt
->tree
));
1524 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1525 io
.ntcreatex
.in
.flags
= NTCREATEX_FLAGS_EXTENDED
;
1526 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1527 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1528 io
.ntcreatex
.in
.alloc_size
= 1024*1024;
1529 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1530 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_NONE
;
1531 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
1532 io
.ntcreatex
.in
.create_options
= 0;
1533 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
1534 io
.ntcreatex
.in
.security_flags
= 0;
1535 io
.ntcreatex
.in
.fname
= dname
;
1537 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1538 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1539 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1540 __location__
, nt_errstr(status
),
1541 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1544 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1545 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRfilexists
))) {
1546 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1547 __location__
, nt_errstr(status
),
1548 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRfilexists
)));
1552 status
= smbcli_mkdir(cli_nt
->tree
, dname
);
1553 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1554 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1555 __location__
, nt_errstr(status
),
1556 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1559 status
= smbcli_mkdir(cli_dos
->tree
, dname
);
1560 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRnoaccess
))) {
1561 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1562 __location__
, nt_errstr(status
),
1563 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRnoaccess
)));
1569 md
.t2mkdir
.level
= RAW_MKDIR_T2MKDIR
;
1570 md
.t2mkdir
.in
.path
= dname
;
1571 md
.t2mkdir
.in
.num_eas
= 0;
1572 md
.t2mkdir
.in
.eas
= NULL
;
1574 status
= smb_raw_mkdir(cli_nt
->tree
, &md
);
1575 if (!NT_STATUS_EQUAL(status
,
1576 NT_STATUS_OBJECT_NAME_COLLISION
)) {
1578 tctx
, "(%s) incorrect status %s should be "
1579 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1580 __location__
, nt_errstr(status
));
1583 status
= smb_raw_mkdir(cli_dos
->tree
, &md
);
1584 if (!NT_STATUS_EQUAL(status
,
1585 NT_STATUS_DOS(ERRDOS
, ERRrename
))) {
1586 torture_comment(tctx
, "(%s) incorrect status %s "
1587 "should be ERRDOS:ERRrename\n",
1588 __location__
, nt_errstr(status
));
1593 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1594 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1595 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
1596 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1597 __location__
, nt_errstr(status
),
1598 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION
));
1602 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1603 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
, ERRfilexists
))) {
1604 torture_comment(tctx
, "(%s) incorrect status %s should be %s\n",
1605 __location__
, nt_errstr(status
),
1606 nt_errstr(NT_STATUS_DOS(ERRDOS
, ERRfilexists
)));
1611 /* Test an invalid DOS deny mode */
1612 const char *fname
= "test.txt";
1614 fnum
= smbcli_open(cli_nt
->tree
, fname
, O_RDWR
| O_CREAT
, 5);
1616 torture_comment(tctx
, "Open(%s) with invalid deny mode succeeded -- "
1617 "expected failure\n", fname
);
1618 smbcli_close(cli_nt
->tree
, fnum
);
1621 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1622 NT_STATUS_DOS(ERRDOS
,ERRbadaccess
))) {
1623 torture_comment(tctx
, "Expected DOS error ERRDOS/ERRbadaccess, "
1624 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1628 fnum
= smbcli_open(cli_dos
->tree
, fname
, O_RDWR
| O_CREAT
, 5);
1630 torture_comment(tctx
, "Open(%s) with invalid deny mode succeeded -- "
1631 "expected failure\n", fname
);
1632 smbcli_close(cli_nt
->tree
, fnum
);
1635 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1636 NT_STATUS_DOS(ERRDOS
,ERRbadaccess
))) {
1637 torture_comment(tctx
, "Expected DOS error ERRDOS:ERRbadaccess, "
1638 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1645 * Samba 3.0.23 has a bug that an existing file can be opened
1646 * as a directory using ntcreate&x. Test this.
1649 const char *fname
= "\\test_dir.txt";
1651 fnum
= smbcli_open(cli_nt
->tree
, fname
, O_RDWR
|O_CREAT
,
1654 d_printf("(%s) smbcli_open failed: %s\n", __location__
,
1655 smbcli_errstr(cli_nt
->tree
));
1657 smbcli_close(cli_nt
->tree
, fnum
);
1659 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
1660 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
1661 io
.ntcreatex
.in
.access_mask
= SEC_RIGHTS_FILE_ALL
;
1662 io
.ntcreatex
.in
.alloc_size
= 0;
1663 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_DIRECTORY
;
1664 io
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
1665 NTCREATEX_SHARE_ACCESS_WRITE
|
1666 NTCREATEX_SHARE_ACCESS_DELETE
;
1667 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
1668 io
.ntcreatex
.in
.create_options
= NTCREATEX_OPTIONS_DIRECTORY
;
1669 io
.ntcreatex
.in
.impersonation
=
1670 NTCREATEX_IMPERSONATION_ANONYMOUS
;
1671 io
.ntcreatex
.in
.security_flags
= 0;
1672 io
.ntcreatex
.in
.fname
= fname
;
1673 io
.ntcreatex
.in
.flags
= 0;
1675 status
= smb_raw_open(cli_nt
->tree
, tctx
, &io
);
1676 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_A_DIRECTORY
)) {
1677 torture_comment(tctx
, "ntcreate as dir gave %s, "
1678 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1683 if (NT_STATUS_IS_OK(status
)) {
1684 smbcli_close(cli_nt
->tree
, io
.ntcreatex
.out
.file
.fnum
);
1687 status
= smb_raw_open(cli_dos
->tree
, tctx
, &io
);
1688 if (!NT_STATUS_EQUAL(status
, NT_STATUS_DOS(ERRDOS
,
1689 ERRbaddirectory
))) {
1690 torture_comment(tctx
, "ntcreate as dir gave %s, "
1691 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1696 if (NT_STATUS_IS_OK(status
)) {
1697 smbcli_close(cli_dos
->tree
,
1698 io
.ntcreatex
.out
.file
.fnum
);
1701 smbcli_unlink(cli_nt
->tree
, fname
);
1704 if (!torture_setting_bool(tctx
, "samba3", false)) {
1708 fnum
= smbcli_open(cli_dos
->tree
, os2_fname
,
1709 O_RDWR
| O_CREAT
| O_TRUNC
,
1712 torture_comment(tctx
, "Open(%s) succeeded -- expected failure\n",
1714 smbcli_close(cli_dos
->tree
, fnum
);
1718 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos
->tree
),
1719 NT_STATUS_DOS(ERRDOS
, ERRcannotopen
))) {
1720 torture_comment(tctx
, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1721 smbcli_errstr(cli_dos
->tree
));
1725 fnum
= smbcli_open(cli_nt
->tree
, os2_fname
,
1726 O_RDWR
| O_CREAT
| O_TRUNC
,
1729 torture_comment(tctx
, "Open(%s) succeeded -- expected failure\n",
1731 smbcli_close(cli_nt
->tree
, fnum
);
1735 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt
->tree
),
1736 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1737 torture_comment(tctx
, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1738 "got %s\n", smbcli_errstr(cli_nt
->tree
));
1746 if (cli_dos
!= NULL
) {
1747 torture_close_connection(cli_dos
);
1749 if (cli_nt
!= NULL
) {
1750 torture_close_connection(cli_nt
);
1757 This checks file/dir birthtime
1759 static void list_fn(struct clilist_file_info
*finfo
, const char *name
,
1762 /* Just to change dir access time*/
1767 static bool run_birthtimetest(struct torture_context
*tctx
,
1768 struct smbcli_state
*cli
)
1772 time_t c_time
, a_time
, m_time
, w_time
, c_time1
;
1773 const char *fname
= "\\birthtime.tst";
1774 const char *dname
= "\\birthtime";
1775 const char *fname2
= "\\birthtime\\birthtime.tst";
1776 bool correct
= true;
1780 smbcli_unlink(cli
->tree
, fname
);
1782 torture_comment(tctx
, "Testing Birthtime for File\n");
1784 /* Save File birthtime/creationtime */
1785 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
1787 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli
->tree
, fnum
, NULL
, &size
,
1788 &c_time
, &a_time
, &m_time
, NULL
, NULL
))) {
1789 torture_comment(tctx
, "ERROR: qfileinfo failed (%s)\n",
1790 smbcli_errstr(cli
->tree
));
1793 smbcli_close(cli
->tree
, fnum
);
1797 /* Change in File attribute changes file change time*/
1798 smbcli_setatr(cli
->tree
, fname
, FILE_ATTRIBUTE_SYSTEM
, 0);
1800 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
| O_CREAT
, DENY_NONE
);
1801 /* Writing updates modification time*/
1802 smbcli_smbwrite(cli
->tree
, fnum
, &fname
, 0, sizeof(fname
));
1803 /*Reading updates access time */
1804 smbcli_read(cli
->tree
, fnum
, buf
, 0, 13);
1805 smbcli_close(cli
->tree
, fnum
);
1807 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, fname
, &c_time1
,
1808 &a_time
, &m_time
, &w_time
, &size
, NULL
, NULL
))) {
1809 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n",
1810 smbcli_errstr(cli
->tree
));
1813 fprintf(stdout
, "c_time = %li, c_time1 = %li\n",
1814 (long) c_time
, (long) c_time1
);
1815 if (c_time1
!= c_time
) {
1816 torture_comment(tctx
, "This system updated file \
1817 birth times! Not expected!\n");
1821 smbcli_unlink(cli
->tree
, fname
);
1823 torture_comment(tctx
, "Testing Birthtime for Directory\n");
1825 /* check if the server does not update the directory birth time
1826 when creating a new file */
1827 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, dname
))) {
1828 torture_comment(tctx
, "ERROR: mkdir failed (%s)\n",
1829 smbcli_errstr(cli
->tree
));
1833 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\birthtime\\",
1834 &c_time
,&a_time
,&m_time
,&w_time
, &size
, NULL
, NULL
))){
1835 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n",
1836 smbcli_errstr(cli
->tree
));
1840 /* Creating a new file changes dir modification time and change time*/
1841 smbcli_unlink(cli
->tree
, fname2
);
1842 fnum
= smbcli_open(cli
->tree
, fname2
, O_RDWR
| O_CREAT
| O_TRUNC
,
1844 smbcli_smbwrite(cli
->tree
, fnum
, &fnum
, 0, sizeof(fnum
));
1845 smbcli_read(cli
->tree
, fnum
, buf
, 0, 13);
1846 smbcli_close(cli
->tree
, fnum
);
1848 /* dir listing changes dir access time*/
1849 smbcli_list(cli
->tree
, "\\birthtime\\*", 0, list_fn
, cli
);
1851 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli
->tree
, "\\birthtime\\",
1852 &c_time1
, &a_time
, &m_time
,&w_time
,&size
,NULL
,NULL
))){
1853 torture_comment(tctx
, "ERROR: qpathinfo2 failed (%s)\n",
1854 smbcli_errstr(cli
->tree
));
1857 fprintf(stdout
, "c_time = %li, c_time1 = %li\n",
1858 (long) c_time
, (long) c_time1
);
1859 if (c_time1
!= c_time
) {
1860 torture_comment(tctx
, "This system updated directory \
1861 birth times! Not Expected!\n");
1865 smbcli_unlink(cli
->tree
, fname2
);
1866 smbcli_rmdir(cli
->tree
, dname
);
1872 NTSTATUS
torture_base_init(void)
1874 struct torture_suite
*suite
= torture_suite_create(talloc_autofree_context(), "base");
1876 torture_suite_add_2smb_test(suite
, "fdpass", run_fdpasstest
);
1877 torture_suite_add_suite(suite
, torture_base_locktest(suite
));
1878 torture_suite_add_1smb_test(suite
, "unlink", torture_unlinktest
);
1879 torture_suite_add_1smb_test(suite
, "attr", run_attrtest
);
1880 torture_suite_add_1smb_test(suite
, "trans2", run_trans2test
);
1881 torture_suite_add_1smb_test(suite
, "birthtime", run_birthtimetest
);
1882 torture_suite_add_simple_test(suite
, "negnowait", run_negprot_nowait
);
1883 torture_suite_add_1smb_test(suite
, "dir1", torture_dirtest1
);
1884 torture_suite_add_1smb_test(suite
, "dir2", torture_dirtest2
);
1885 torture_suite_add_1smb_test(suite
, "deny1", torture_denytest1
);
1886 torture_suite_add_2smb_test(suite
, "deny2", torture_denytest2
);
1887 torture_suite_add_2smb_test(suite
, "deny3", torture_denytest3
);
1888 torture_suite_add_1smb_test(suite
, "denydos", torture_denydos_sharing
);
1889 torture_suite_add_smb_multi_test(suite
, "ntdeny1", torture_ntdenytest1
);
1890 torture_suite_add_2smb_test(suite
, "ntdeny2", torture_ntdenytest2
);
1891 torture_suite_add_1smb_test(suite
, "tcon", run_tcon_test
);
1892 torture_suite_add_1smb_test(suite
, "tcondev", run_tcon_devtype_test
);
1893 torture_suite_add_1smb_test(suite
, "vuid", run_vuidtest
);
1894 torture_suite_add_2smb_test(suite
, "rw1", run_readwritetest
);
1895 torture_suite_add_2smb_test(suite
, "open", run_opentest
);
1896 torture_suite_add_smb_multi_test(suite
, "defer_open", run_deferopen
);
1897 torture_suite_add_1smb_test(suite
, "xcopy", run_xcopy
);
1898 torture_suite_add_1smb_test(suite
, "iometer", run_iometer
);
1899 torture_suite_add_1smb_test(suite
, "rename", torture_test_rename
);
1900 torture_suite_add_suite(suite
, torture_test_delete());
1901 torture_suite_add_1smb_test(suite
, "properties", torture_test_properties
);
1902 torture_suite_add_1smb_test(suite
, "mangle", torture_mangle
);
1903 torture_suite_add_1smb_test(suite
, "openattr", torture_openattrtest
);
1904 torture_suite_add_1smb_test(suite
, "winattr", torture_winattrtest
);
1905 torture_suite_add_suite(suite
, torture_charset(suite
));
1906 torture_suite_add_1smb_test(suite
, "chkpath", torture_chkpath_test
);
1907 torture_suite_add_1smb_test(suite
, "secleak", torture_sec_leak
);
1908 torture_suite_add_simple_test(suite
, "disconnect", torture_disconnect
);
1909 torture_suite_add_suite(suite
, torture_delay_write());
1910 torture_suite_add_simple_test(suite
, "samba3error", torture_samba3_errorpaths
);
1911 torture_suite_add_1smb_test(suite
, "casetable", torture_casetable
);
1912 torture_suite_add_1smb_test(suite
, "utable", torture_utable
);
1913 torture_suite_add_simple_test(suite
, "smb", torture_smb_scan
);
1914 torture_suite_add_suite(suite
, torture_trans2_aliases(suite
));
1915 torture_suite_add_1smb_test(suite
, "trans2-scan", torture_trans2_scan
);
1916 torture_suite_add_1smb_test(suite
, "nttrans", torture_nttrans_scan
);
1917 torture_suite_add_1smb_test(suite
, "createx_access", torture_createx_access
);
1918 torture_suite_add_2smb_test(suite
, "createx_sharemodes_file", torture_createx_sharemodes_file
);
1919 torture_suite_add_2smb_test(suite
, "createx_sharemodes_dir", torture_createx_sharemodes_dir
);
1920 torture_suite_add_1smb_test(suite
, "maximum_allowed", torture_maximum_allowed
);
1922 torture_suite_add_simple_test(suite
, "bench-holdcon", torture_holdcon
);
1923 torture_suite_add_1smb_test(suite
, "bench-holdopen", torture_holdopen
);
1924 torture_suite_add_simple_test(suite
, "bench-readwrite", run_benchrw
);
1925 torture_suite_add_smb_multi_test(suite
, "bench-torture", run_torture
);
1926 torture_suite_add_1smb_test(suite
, "scan-pipe_number", run_pipe_number
);
1927 torture_suite_add_1smb_test(suite
, "scan-ioctl", torture_ioctl_test
);
1928 torture_suite_add_smb_multi_test(suite
, "scan-maxfid", run_maxfidtest
);
1930 suite
->description
= talloc_strdup(suite
,
1931 "Basic SMB tests (imported from the original smbtorture)");
1933 torture_register_suite(suite
);
1935 return NT_STATUS_OK
;