s3-utils: net - Fix one error/usage message
[Samba/vl.git] / source4 / torture / basic / base.c
blob10dc892333df6d419eece41333363ef1d545841e
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
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/>.
21 #include "includes.h"
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);
49 if (!cli) {
50 torture_comment(tctx, "Failed initialize smbcli_struct to connect with %s\n", host);
51 goto failed;
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);
60 goto failed;
63 if (!smbcli_transport_establish(cli, &calling, &called)) {
64 torture_comment(tctx, "%s rejected the session\n",host);
65 goto failed;
68 return cli;
70 failed:
71 talloc_free(cli);
72 return NULL;
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)
80 bool status;
81 const char *password = torture_setting_string(tctx, "password", NULL);
83 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
84 password));
86 torture_comment(tctx, "Trying share %s with devtype %s\n", myshare, devtype);
88 if (NT_STATUS_IS_OK(expected_error)) {
89 if (!status) {
90 torture_fail(tctx, talloc_asprintf(tctx,
91 "tconX to share %s with type %s "
92 "should have succeeded but failed",
93 myshare, devtype));
95 smbcli_tdis(cli);
96 } else {
97 if (status) {
98 torture_fail(tctx, talloc_asprintf(tctx,
99 "tconx to share %s with type %s "
100 "should have failed but succeeded",
101 myshare, devtype));
102 } else {
103 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
104 expected_error)) {
105 } else {
106 torture_fail(tctx, "Returned unexpected error");
110 return true;
116 test whether fnums and tids open on one VC are available on another (a major
117 security hole)
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";
124 int fnum1, oldtid;
125 uint8_t buf[1024];
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");
138 torture_assert(tctx,
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;
159 return true;
163 This checks how the getatr calls works
165 static bool run_attrtest(struct torture_context *tctx,
166 struct smbcli_state *cli)
168 int fnum;
169 time_t t, t2;
170 const char *fname = "\\attrib123456789.tst";
171 bool correct = true;
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));
180 correct = false;
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",
187 ctime(&t));
188 t = time(NULL);
189 correct = false;
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));
198 correct = true;
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));
203 correct = true;
206 torture_comment(tctx, "Retrieved file time as %s", ctime(&t));
208 if (t != t2) {
209 torture_comment(tctx, "ERROR: getatr/setatr bug. times are\n%s",
210 ctime(&t));
211 torture_comment(tctx, "%s", ctime(&t2));
212 correct = true;
215 smbcli_unlink(cli->tree, fname);
217 return correct;
221 This checks a couple of trans2 calls
223 static bool run_trans2test(struct torture_context *tctx,
224 struct smbcli_state *cli)
226 int fnum;
227 size_t size;
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";
232 const char *pname;
233 bool correct = true;
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,
242 NULL, NULL))) {
243 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
244 correct = false;
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));
251 correct = false;
254 if (!pname || strcmp(pname, fname)) {
255 torture_comment(tctx, "qfilename gave different name? [%s] [%s]\n",
256 fname, pname);
257 correct = false;
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);
265 if (fnum == -1) {
266 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
267 return false;
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));
275 correct = false;
276 } else {
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");
287 correct = false;
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));
292 correct = false;
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));
303 correct = false;
304 } else {
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");
308 correct = false;
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));
319 correct = false;
321 sleep(3);
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));
324 correct = false;
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));
333 correct = false;
334 } else {
335 if (m_time2 == m_time) {
336 torture_comment(tctx, "This system does not update directory modification times\n");
337 correct = false;
340 smbcli_unlink(cli->tree, fname2);
341 smbcli_rmdir(cli->tree, dname);
343 return correct;
346 /* send smb negprot commands, not reading the response */
347 static bool run_negprot_nowait(struct torture_context *tctx)
349 int i;
350 struct smbcli_state *cli, *cli2;
351 bool correct = true;
353 torture_comment(tctx, "starting negprot nowait test\n");
355 cli = open_nbt_connection(tctx);
356 if (!cli) {
357 return false;
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) {
367 if (i > 0) {
368 torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
369 break;
370 } else {
371 torture_comment(tctx, "Failed to fill pipe - %s \n", nt_errstr(req->status));
372 torture_close_connection(cli);
373 return false;
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");
381 correct = false;
384 if (!torture_close_connection(cli2)) {
385 torture_comment(tctx, "Failed to close secondary connection\n");
386 correct = false;
389 torture_close_connection(cli);
391 return correct;
395 this checks to see if a secondary tconx can use open files from an
396 earlier tconx
398 static bool run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
400 const char *fname = "\\tcontest.tmp";
401 int fnum1;
402 uint16_t cnum1, cnum2, cnum3;
403 uint16_t vuid1, vuid2;
404 uint8_t buf[4];
405 bool ret = true;
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);
416 if (fnum1 == -1) {
417 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
418 return false;
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));
427 return false;
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));
434 talloc_free(cli);
435 return false;
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");
447 ret = false;
448 } else {
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");
458 ret = false;
459 } else {
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");
469 ret = false;
470 } else {
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));
479 return false;
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));
486 return false;
489 cli->tree = tree1; /* restore initial tree */
490 cli->tree->tid = cnum1;
492 smbcli_unlink(tree1, fname);
494 return ret;
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))
506 return false;
508 if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
509 return false;
511 if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
512 return false;
514 if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
515 return false;
517 if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
518 return false;
520 if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
521 return false;
523 if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
524 return false;
526 if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
527 return false;
529 if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
530 return false;
532 if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
533 return false;
535 return true;
538 static bool rw_torture2(struct torture_context *tctx,
539 struct smbcli_state *c1, struct smbcli_state *c2)
541 const char *lockfname = "\\torture2.lck";
542 int fnum1;
543 int fnum2;
544 int i;
545 uint8_t buf[131072];
546 uint8_t buf_rd[131072];
547 bool correct = true;
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,
555 DENY_NONE);
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,
561 DENY_NONE);
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",
568 torture_numops);
570 for (i=0;i<torture_numops;i++)
572 size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
573 if (i % 10 == 0) {
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);
584 correct = false;
585 break;
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);
591 correct = false;
592 break;
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");
609 return correct;
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))
620 return false;
622 torture_comment(tctx, "Running readwritetest v2\n");
624 if (!rw_torture2(tctx, cli1, cli1))
625 return false;
627 return true;
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";
636 int retries=4;
637 int i = 0;
638 bool correct = true;
639 int nsec;
640 int msec;
641 double sec;
643 nsec = torture_setting_int(tctx, "sharedelay", 1000000);
644 msec = nsec / 1000;
645 sec = ((double)nsec) / ((double) 1000000);
647 if (retries <= 0) {
648 torture_comment(tctx, "failed to connect\n");
649 return false;
652 torture_comment(tctx, "Testing deferred open requests.\n");
654 while (i < 4) {
655 int fnum = -1;
657 do {
658 struct timeval tv;
659 tv = timeval_current();
660 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
661 SEC_RIGHTS_FILE_ALL,
662 FILE_ATTRIBUTE_NORMAL,
663 NTCREATEX_SHARE_ACCESS_NONE,
664 NTCREATEX_DISP_OPEN_IF, 0, 0);
665 if (fnum != -1) {
666 break;
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",
672 e, sec);
673 return false;
676 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
678 if (fnum == -1) {
679 torture_comment(tctx,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
680 return false;
683 torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i);
685 smb_msleep(10 * msec);
686 i++;
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));
689 return false;
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));
702 correct = false;
706 torture_comment(tctx, "deferred test finished\n");
707 return correct;
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";
718 int fnum;
719 size_t size;
720 time_t c_time, a_time, m_time;
722 uint16_t orig_vuid;
723 NTSTATUS result;
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);
759 return true;
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;
770 int fnum1, fnum2;
771 uint8_t buf[20];
772 size_t fsize;
773 bool correct = true;
774 char *tmp_path;
775 int failures = 0;
776 int i;
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);
788 failures++;
791 if (fnum1 != -1) {
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);
799 if (!failures)
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);
806 if (fnum1 == -1) {
807 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
808 return false;
811 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
812 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
813 return false;
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);
820 return false;
823 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
824 if (fnum1 == -1) {
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);
828 return false;
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");
841 error_test1:
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);
849 if (fnum1 == -1) {
850 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
851 return false;
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));
864 return false;
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);
874 if (fnum1 == -1) {
875 torture_comment(tctx, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
876 return false;
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));
885 correct = false;
888 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
889 torture_comment(tctx, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
890 return false;
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);
898 return false;
901 if (fsize != 20) {
902 torture_result(tctx, TORTURE_FAIL,
903 __location__ ": (3) file size != 20\n");
904 CHECK_MAX_FAILURES(error_test3);
905 return false;
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);
911 if (fnum1 == -1) {
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);
915 return false;
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));
921 return false;
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);
929 return false;
932 if (fsize != 0) {
933 torture_result(tctx, TORTURE_FAIL,
934 __location__ ": (3) file size != 0\n");
935 CHECK_MAX_FAILURES(error_test3);
936 return false;
938 torture_comment(tctx, "finished open test 3\n");
939 error_test3:
941 fnum1 = fnum2 = -1;
942 smbcli_unlink(cli1->tree, fname);
945 torture_comment(tctx, "Testing ctemp\n");
946 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
947 if (fnum1 == -1) {
948 torture_result(tctx, TORTURE_FAIL,
949 __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
950 CHECK_MAX_FAILURES(error_test4);
951 return false;
953 torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
955 error_test4:
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");
966 fnum1 = fnum2 = -1;
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);
973 if (fnum1 == -1) {
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);
977 return false;
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);
982 if (fnum2 == -1) {
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);
986 return false;
989 torture_comment(tctx, "non-io open test #1 passed.\n");
990 error_test10:
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");
1000 fnum1 = fnum2 = -1;
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);
1006 if (fnum1 == -1) {
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);
1010 return false;
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);
1016 if (fnum2 == -1) {
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);
1020 return false;
1023 torture_comment(tctx, "non-io open test #2 passed.\n");
1024 error_test20:
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));
1033 fnum1 = fnum2 = -1;
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);
1041 if (fnum1 == -1) {
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);
1045 return false;
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);
1051 if (fnum2 == -1) {
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);
1055 return false;
1058 torture_comment(tctx, "non-io open test #3 passed.\n");
1059 error_test30:
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");
1069 fnum1 = fnum2 = -1;
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);
1075 if (fnum1 == -1) {
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);
1079 return false;
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);
1085 if (fnum2 != -1) {
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);
1089 return false;
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");
1095 error_test40:
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");
1105 fnum1 = fnum2 = -1;
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);
1111 if (fnum1 == -1) {
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);
1115 return false;
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);
1121 if (fnum2 == -1) {
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);
1125 return false;
1128 torture_comment(tctx, "non-io open test #5 passed.\n");
1129 error_test50:
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");
1140 fnum1 = fnum2 = -1;
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);
1146 if (fnum1 == -1) {
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);
1150 return false;
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);
1156 if (fnum2 == -1) {
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);
1160 return false;
1163 torture_comment(tctx, "non-io open test #6 passed.\n");
1164 error_test60:
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");
1175 fnum1 = fnum2 = -1;
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);
1181 if (fnum1 == -1) {
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);
1185 return false;
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);
1191 if (fnum2 != -1) {
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);
1195 return false;
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");
1201 error_test70:
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");
1211 fnum1 = fnum2 = -1;
1212 smbcli_unlink(cli1->tree, fname);
1214 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1215 if (fnum1 == -1) {
1216 torture_comment(tctx, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1217 return false;
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));
1226 correct = false;
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);
1234 return false;
1237 if (fsize != 20) {
1238 torture_result(tctx, TORTURE_FAIL,
1239 __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
1240 CHECK_MAX_FAILURES(error_test80);
1241 return false;
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);
1249 return false;
1252 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1253 if (fnum1 == -1) {
1254 torture_comment(tctx, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1255 return false;
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);
1263 return false;
1266 if (fsize != 0) {
1267 torture_result(tctx, TORTURE_FAIL,
1268 __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
1269 CHECK_MAX_FAILURES(error_test80);
1270 return false;
1273 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1274 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1275 return false;
1278 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1279 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1280 return false;
1283 error_test80:
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 */
1304 #if 0
1305 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1306 READ_CONTROL|WRITE_DAC|\
1307 SEC_FILE_READ_DATA|\
1308 WRITE_OWNER /* */
1309 #endif
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";
1320 int fnum1, fnum2;
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,
1327 0x4044, 0);
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,
1335 0x200000, 0);
1336 torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
1337 "second open failed - %s", smbcli_errstr(cli1->tree)));
1339 return true;
1342 static bool run_iometer(struct torture_context *tctx,
1343 struct smbcli_state *cli)
1345 const char *fname = "\\iobw.tst";
1346 int fnum;
1347 size_t filesize;
1348 NTSTATUS status;
1349 char buf[2048];
1350 int ops;
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)));
1367 ops = 0;
1369 while (true) {
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++) {
1376 ssize_t res;
1377 if (ops++ > torture_numops) {
1378 return true;
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++) {
1387 ssize_t res;
1388 if (ops++ > torture_numops) {
1389 return true;
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)
1406 int fnum;
1407 bool ret;
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));
1418 return false;
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));
1423 return false;
1426 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1427 if (fnum == -1) {
1428 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1429 return false;
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));
1435 ret = false;
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));
1440 ret = false;
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);
1446 } else {
1447 torture_comment(tctx, "* chkpath on a file should fail\n");
1448 ret = false;
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);
1454 } else {
1455 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1456 ret = false;
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);
1462 } else {
1463 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1464 ret = false;
1467 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1468 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1469 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1471 return ret;
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;
1483 int fnum;
1484 const char *os2_fname = ".+,;=[].";
1485 const char *dname = "samba3_errordir";
1486 union smb_open io;
1487 NTSTATUS status;
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");
1493 goto fail;
1496 if (!torture_open_connection(&cli_nt, tctx, 0)) {
1497 goto fail;
1500 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1501 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1502 goto fail;
1505 if (!torture_open_connection(&cli_dos, tctx, 1)) {
1506 goto fail;
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'");
1512 goto fail;
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));
1521 goto fail;
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));
1542 goto fail;
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)));
1549 goto fail;
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));
1557 goto fail;
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)));
1564 goto fail;
1568 union smb_mkdir md;
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)) {
1577 torture_comment(
1578 tctx, "(%s) incorrect status %s should be "
1579 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1580 __location__, nt_errstr(status));
1581 goto fail;
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));
1589 goto fail;
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));
1599 goto fail;
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)));
1607 goto fail;
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);
1615 if (fnum != -1) {
1616 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1617 "expected failure\n", fname);
1618 smbcli_close(cli_nt->tree, fnum);
1619 goto fail;
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));
1625 goto fail;
1628 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1629 if (fnum != -1) {
1630 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1631 "expected failure\n", fname);
1632 smbcli_close(cli_nt->tree, fnum);
1633 goto fail;
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));
1639 goto fail;
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,
1652 DENY_NONE);
1653 if (fnum == -1) {
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",
1679 nt_errstr(status));
1680 result = false;
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",
1692 nt_errstr(status));
1693 result = false;
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)) {
1705 goto done;
1708 fnum = smbcli_open(cli_dos->tree, os2_fname,
1709 O_RDWR | O_CREAT | O_TRUNC,
1710 DENY_NONE);
1711 if (fnum != -1) {
1712 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1713 os2_fname);
1714 smbcli_close(cli_dos->tree, fnum);
1715 goto fail;
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));
1722 goto fail;
1725 fnum = smbcli_open(cli_nt->tree, os2_fname,
1726 O_RDWR | O_CREAT | O_TRUNC,
1727 DENY_NONE);
1728 if (fnum != -1) {
1729 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1730 os2_fname);
1731 smbcli_close(cli_nt->tree, fnum);
1732 goto fail;
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));
1739 goto fail;
1742 done:
1743 result = true;
1745 fail:
1746 if (cli_dos != NULL) {
1747 torture_close_connection(cli_dos);
1749 if (cli_nt != NULL) {
1750 torture_close_connection(cli_nt);
1753 return result;
1757 This checks file/dir birthtime
1759 static void list_fn(struct clilist_file_info *finfo, const char *name,
1760 void *state){
1762 /* Just to change dir access time*/
1763 sleep(5);
1767 static bool run_birthtimetest(struct torture_context *tctx,
1768 struct smbcli_state *cli)
1770 int fnum;
1771 size_t size;
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;
1777 uint8_t buf[16];
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,
1786 DENY_NONE);
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));
1791 correct = false;
1793 smbcli_close(cli->tree, fnum);
1795 sleep(10);
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));
1811 correct = false;
1812 } else {
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");
1818 correct = false;
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));
1830 correct = false;
1832 sleep(3);
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));
1837 correct = false;
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,
1843 DENY_NONE);
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));
1855 correct = false;
1856 } else {
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");
1862 correct = false;
1865 smbcli_unlink(cli->tree, fname2);
1866 smbcli_rmdir(cli->tree, dname);
1868 return correct;
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;