s4-smbtorture: Make test names lowercase and dot-separated.
[Samba.git] / source4 / torture / basic / base.c
blobd7bac459c3799bd82ff34d8e2b3be29703e5b6cf
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 if (c_time != m_time) {
278 torture_comment(tctx, "create time=%s", ctime(&c_time));
279 torture_comment(tctx, "modify time=%s", ctime(&m_time));
280 torture_comment(tctx, "This system appears to have sticky create times\n");
282 if (a_time % (60*60) == 0) {
283 torture_comment(tctx, "access time=%s", ctime(&a_time));
284 torture_comment(tctx, "This system appears to set a midnight access time\n");
285 correct = false;
288 if (abs(m_time - time(NULL)) > 60*60*24*7) {
289 torture_comment(tctx, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
290 correct = false;
295 smbcli_unlink(cli->tree, fname);
296 fnum = smbcli_open(cli->tree, fname,
297 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
298 smbcli_close(cli->tree, fnum);
299 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
300 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
301 correct = false;
302 } else {
303 if (w_time < 60*60*24*2) {
304 torture_comment(tctx, "write time=%s", ctime(&w_time));
305 torture_comment(tctx, "This system appears to set a initial 0 write time\n");
306 correct = false;
310 smbcli_unlink(cli->tree, fname);
313 /* check if the server updates the directory modification time
314 when creating a new file */
315 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
316 torture_comment(tctx, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
317 correct = false;
319 sleep(3);
320 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
321 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
322 correct = false;
325 fnum = smbcli_open(cli->tree, fname2,
326 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
327 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
328 smbcli_close(cli->tree, fnum);
329 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
330 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
331 correct = false;
332 } else {
333 if (m_time2 == m_time) {
334 torture_comment(tctx, "This system does not update directory modification times\n");
335 correct = false;
338 smbcli_unlink(cli->tree, fname2);
339 smbcli_rmdir(cli->tree, dname);
341 return correct;
344 /* send smb negprot commands, not reading the response */
345 static bool run_negprot_nowait(struct torture_context *tctx)
347 int i;
348 struct smbcli_state *cli, *cli2;
349 bool correct = true;
351 torture_comment(tctx, "starting negprot nowait test\n");
353 cli = open_nbt_connection(tctx);
354 if (!cli) {
355 return false;
358 torture_comment(tctx, "Filling send buffer\n");
360 for (i=0;i<100;i++) {
361 struct smbcli_request *req;
362 req = smb_raw_negotiate_send(cli->transport, lpcfg_unicode(tctx->lp_ctx), PROTOCOL_NT1);
363 event_loop_once(cli->transport->socket->event.ctx);
364 if (req->state == SMBCLI_REQUEST_ERROR) {
365 if (i > 0) {
366 torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
367 break;
368 } else {
369 torture_comment(tctx, "Failed to fill pipe - %s \n", nt_errstr(req->status));
370 torture_close_connection(cli);
371 return false;
376 torture_comment(tctx, "Opening secondary connection\n");
377 if (!torture_open_connection(&cli2, tctx, 1)) {
378 torture_comment(tctx, "Failed to open secondary connection\n");
379 correct = false;
382 if (!torture_close_connection(cli2)) {
383 torture_comment(tctx, "Failed to close secondary connection\n");
384 correct = false;
387 torture_close_connection(cli);
389 return correct;
393 this checks to see if a secondary tconx can use open files from an
394 earlier tconx
396 static bool run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
398 const char *fname = "\\tcontest.tmp";
399 int fnum1;
400 uint16_t cnum1, cnum2, cnum3;
401 uint16_t vuid1, vuid2;
402 uint8_t buf[4];
403 bool ret = true;
404 struct smbcli_tree *tree1;
405 const char *host = torture_setting_string(tctx, "host", NULL);
406 const char *share = torture_setting_string(tctx, "share", NULL);
407 const char *password = torture_setting_string(tctx, "password", NULL);
409 if (smbcli_deltree(cli->tree, fname) == -1) {
410 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
413 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
414 if (fnum1 == -1) {
415 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
416 return false;
419 cnum1 = cli->tree->tid;
420 vuid1 = cli->session->vuid;
422 memset(buf, 0, 4); /* init buf so valgrind won't complain */
423 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
424 torture_comment(tctx, "initial write failed (%s)\n", smbcli_errstr(cli->tree));
425 return false;
428 tree1 = cli->tree; /* save old tree connection */
429 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
430 torture_comment(tctx, "%s refused 2nd tree connect (%s)\n", host,
431 smbcli_errstr(cli->tree));
432 talloc_free(cli);
433 return false;
436 cnum2 = cli->tree->tid;
437 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
438 vuid2 = cli->session->vuid + 1;
440 /* try a write with the wrong tid */
441 cli->tree->tid = cnum2;
443 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
444 torture_comment(tctx, "* server allows write with wrong TID\n");
445 ret = false;
446 } else {
447 torture_comment(tctx, "server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
451 /* try a write with an invalid tid */
452 cli->tree->tid = cnum3;
454 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
455 torture_comment(tctx, "* server allows write with invalid TID\n");
456 ret = false;
457 } else {
458 torture_comment(tctx, "server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
461 /* try a write with an invalid vuid */
462 cli->session->vuid = vuid2;
463 cli->tree->tid = cnum1;
465 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
466 torture_comment(tctx, "* server allows write with invalid VUID\n");
467 ret = false;
468 } else {
469 torture_comment(tctx, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
472 cli->session->vuid = vuid1;
473 cli->tree->tid = cnum1;
475 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
476 torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(cli->tree));
477 return false;
480 cli->tree->tid = cnum2;
482 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
483 torture_comment(tctx, "secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
484 return false;
487 cli->tree = tree1; /* restore initial tree */
488 cli->tree->tid = cnum1;
490 smbcli_unlink(tree1, fname);
492 return ret;
496 checks for correct tconX support
498 static bool run_tcon_devtype_test(struct torture_context *tctx,
499 struct smbcli_state *cli1)
501 const char *share = torture_setting_string(tctx, "share", NULL);
503 if (!tcon_devtest(tctx, cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
504 return false;
506 if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
507 return false;
509 if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
510 return false;
512 if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
513 return false;
515 if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
516 return false;
518 if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
519 return false;
521 if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
522 return false;
524 if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
525 return false;
527 if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
528 return false;
530 if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
531 return false;
533 return true;
536 static bool rw_torture2(struct torture_context *tctx,
537 struct smbcli_state *c1, struct smbcli_state *c2)
539 const char *lockfname = "\\torture2.lck";
540 int fnum1;
541 int fnum2;
542 int i;
543 uint8_t buf[131072];
544 uint8_t buf_rd[131072];
545 bool correct = true;
546 ssize_t bytes_read, bytes_written;
548 torture_assert(tctx, smbcli_deltree(c1->tree, lockfname) != -1,
549 talloc_asprintf(tctx,
550 "unlink failed (%s)", smbcli_errstr(c1->tree)));
552 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
553 DENY_NONE);
554 torture_assert(tctx, fnum1 != -1,
555 talloc_asprintf(tctx,
556 "first open read/write of %s failed (%s)",
557 lockfname, smbcli_errstr(c1->tree)));
558 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
559 DENY_NONE);
560 torture_assert(tctx, fnum2 != -1,
561 talloc_asprintf(tctx,
562 "second open read-only of %s failed (%s)",
563 lockfname, smbcli_errstr(c2->tree)));
565 torture_comment(tctx, "Checking data integrity over %d ops\n",
566 torture_numops);
568 for (i=0;i<torture_numops;i++)
570 size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
571 if (i % 10 == 0) {
572 if (torture_setting_bool(tctx, "progress", true)) {
573 torture_comment(tctx, "%d\r", i); fflush(stdout);
577 generate_random_buffer(buf, buf_size);
579 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
580 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c1->tree));
581 torture_comment(tctx, "wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
582 correct = false;
583 break;
586 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
587 torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c2->tree));
588 torture_comment(tctx, "read %d, expected %d\n", (int)bytes_read, (int)buf_size);
589 correct = false;
590 break;
593 torture_assert_mem_equal(tctx, buf_rd, buf, buf_size,
594 "read/write compare failed\n");
597 torture_assert_ntstatus_ok(tctx, smbcli_close(c2->tree, fnum2),
598 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c2->tree)));
599 torture_assert_ntstatus_ok(tctx, smbcli_close(c1->tree, fnum1),
600 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c1->tree)));
602 torture_assert_ntstatus_ok(tctx, smbcli_unlink(c1->tree, lockfname),
603 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(c1->tree)));
605 torture_comment(tctx, "\n");
607 return correct;
612 static bool run_readwritetest(struct torture_context *tctx,
613 struct smbcli_state *cli1,
614 struct smbcli_state *cli2)
616 torture_comment(tctx, "Running readwritetest v1\n");
617 if (!rw_torture2(tctx, cli1, cli2))
618 return false;
620 torture_comment(tctx, "Running readwritetest v2\n");
622 if (!rw_torture2(tctx, cli1, cli1))
623 return false;
625 return true;
629 test the timing of deferred open requests
631 static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
633 const char *fname = "\\defer_open_test.dat";
634 int retries=4;
635 int i = 0;
636 bool correct = true;
637 int nsec;
638 int msec;
639 double sec;
641 nsec = torture_setting_int(tctx, "sharedelay", 1000000);
642 msec = nsec / 1000;
643 sec = ((double)nsec) / ((double) 1000000);
645 if (retries <= 0) {
646 torture_comment(tctx, "failed to connect\n");
647 return false;
650 torture_comment(tctx, "Testing deferred open requests.\n");
652 while (i < 4) {
653 int fnum = -1;
655 do {
656 struct timeval tv;
657 tv = timeval_current();
658 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
659 SEC_RIGHTS_FILE_ALL,
660 FILE_ATTRIBUTE_NORMAL,
661 NTCREATEX_SHARE_ACCESS_NONE,
662 NTCREATEX_DISP_OPEN_IF, 0, 0);
663 if (fnum != -1) {
664 break;
666 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
667 double e = timeval_elapsed(&tv);
668 if (e < (0.5 * sec) || e > ((1.5 * sec) + 1)) {
669 torture_comment(tctx,"Timing incorrect %.2f violation 1 sec == %.2f\n",
670 e, sec);
671 return false;
674 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
676 if (fnum == -1) {
677 torture_comment(tctx,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
678 return false;
681 torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i);
683 smb_msleep(10 * msec);
684 i++;
685 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
686 torture_comment(tctx,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
687 return false;
689 smb_msleep(2 * msec);
692 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
693 /* All until the last unlink will fail with sharing violation
694 but also the last request can fail since the file could have
695 been successfully deleted by another (test) process */
696 NTSTATUS status = smbcli_nt_error(cli->tree);
697 if ((!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION))
698 && (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))) {
699 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
700 correct = false;
704 torture_comment(tctx, "deferred test finished\n");
705 return correct;
709 Try with a wrong vuid and check error message.
712 static bool run_vuidtest(struct torture_context *tctx,
713 struct smbcli_state *cli)
715 const char *fname = "\\vuid.tst";
716 int fnum;
717 size_t size;
718 time_t c_time, a_time, m_time;
720 uint16_t orig_vuid;
721 NTSTATUS result;
723 smbcli_unlink(cli->tree, fname);
725 fnum = smbcli_open(cli->tree, fname,
726 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
728 orig_vuid = cli->session->vuid;
730 cli->session->vuid += 1234;
732 torture_comment(tctx, "Testing qfileinfo with wrong vuid\n");
734 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
735 &size, &c_time, &a_time,
736 &m_time, NULL, NULL))) {
737 torture_fail(tctx, "qfileinfo passed with wrong vuid");
740 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
741 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
742 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
743 NT_STATUS_INVALID_HANDLE)) {
744 torture_fail(tctx, talloc_asprintf(tctx,
745 "qfileinfo should have returned DOS error "
746 "ERRSRV:ERRbaduid\n but returned %s",
747 smbcli_errstr(cli->tree)));
750 cli->session->vuid -= 1234;
752 torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum),
753 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli->tree)));
755 smbcli_unlink(cli->tree, fname);
757 return true;
761 Test open mode returns on read-only files.
763 static bool run_opentest(struct torture_context *tctx, struct smbcli_state *cli1,
764 struct smbcli_state *cli2)
766 const char *fname = "\\readonly.file";
767 char *control_char_fname;
768 int fnum1, fnum2;
769 uint8_t buf[20];
770 size_t fsize;
771 bool correct = true;
772 char *tmp_path;
773 int failures = 0;
774 int i;
776 asprintf(&control_char_fname, "\\readonly.afile");
777 for (i = 1; i <= 0x1f; i++) {
778 control_char_fname[10] = i;
779 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
780 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
782 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
783 NT_STATUS_OBJECT_NAME_INVALID)) {
784 torture_comment(tctx, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
785 smbcli_errstr(cli1->tree), i);
786 failures++;
789 if (fnum1 != -1) {
790 smbcli_close(cli1->tree, fnum1);
792 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
793 smbcli_unlink(cli1->tree, control_char_fname);
795 free(control_char_fname);
797 if (!failures)
798 torture_comment(tctx, "Create file with control char names passed.\n");
800 smbcli_setatr(cli1->tree, fname, 0, 0);
801 smbcli_unlink(cli1->tree, fname);
803 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
804 if (fnum1 == -1) {
805 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
806 return false;
809 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
810 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
811 return false;
814 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
815 torture_result(tctx, TORTURE_FAIL,
816 __location__ ": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
817 CHECK_MAX_FAILURES(error_test1);
818 return false;
821 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
822 if (fnum1 == -1) {
823 torture_result(tctx, TORTURE_FAIL,
824 __location__ ": open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
825 CHECK_MAX_FAILURES(error_test1);
826 return false;
829 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
830 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
832 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
833 NT_STATUS_ACCESS_DENIED)) {
834 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
837 torture_comment(tctx, "finished open test 1\n");
839 error_test1:
840 smbcli_close(cli1->tree, fnum1);
842 /* Now try not readonly and ensure ERRbadshare is returned. */
844 smbcli_setatr(cli1->tree, fname, 0, 0);
846 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
847 if (fnum1 == -1) {
848 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
849 return false;
852 /* This will fail - but the error should be ERRshare. */
853 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
855 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
856 NT_STATUS_SHARING_VIOLATION)) {
857 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
860 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
861 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
862 return false;
865 smbcli_unlink(cli1->tree, fname);
867 torture_comment(tctx, "finished open test 2\n");
869 /* Test truncate open disposition on file opened for read. */
871 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
872 if (fnum1 == -1) {
873 torture_comment(tctx, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
874 return false;
877 /* write 20 bytes. */
879 memset(buf, '\0', 20);
881 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
882 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(cli1->tree));
883 correct = false;
886 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
887 torture_comment(tctx, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
888 return false;
891 /* Ensure size == 20. */
892 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
893 torture_result(tctx, TORTURE_FAIL,
894 __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
895 CHECK_MAX_FAILURES(error_test3);
896 return false;
899 if (fsize != 20) {
900 torture_result(tctx, TORTURE_FAIL,
901 __location__ ": (3) file size != 20\n");
902 CHECK_MAX_FAILURES(error_test3);
903 return false;
906 /* Now test if we can truncate a file opened for readonly. */
908 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
909 if (fnum1 == -1) {
910 torture_result(tctx, TORTURE_FAIL,
911 __location__ ": (3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
912 CHECK_MAX_FAILURES(error_test3);
913 return false;
916 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
917 torture_result(tctx, TORTURE_FAIL,
918 __location__ ": close2 failed (%s)\n", smbcli_errstr(cli1->tree));
919 return false;
922 /* Ensure size == 0. */
923 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
924 torture_result(tctx, TORTURE_FAIL,
925 __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
926 CHECK_MAX_FAILURES(error_test3);
927 return false;
930 if (fsize != 0) {
931 torture_result(tctx, TORTURE_FAIL,
932 __location__ ": (3) file size != 0\n");
933 CHECK_MAX_FAILURES(error_test3);
934 return false;
936 torture_comment(tctx, "finished open test 3\n");
937 error_test3:
939 fnum1 = fnum2 = -1;
940 smbcli_unlink(cli1->tree, fname);
943 torture_comment(tctx, "Testing ctemp\n");
944 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
945 if (fnum1 == -1) {
946 torture_result(tctx, TORTURE_FAIL,
947 __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
948 CHECK_MAX_FAILURES(error_test4);
949 return false;
951 torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
953 error_test4:
954 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
955 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
957 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
958 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
961 /* Test the non-io opens... */
963 torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
964 fnum1 = fnum2 = -1;
965 smbcli_setatr(cli2->tree, fname, 0, 0);
966 smbcli_unlink(cli2->tree, fname);
968 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
969 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
971 if (fnum1 == -1) {
972 torture_result(tctx, TORTURE_FAIL,
973 __location__ ": Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
974 CHECK_MAX_FAILURES(error_test10);
975 return false;
978 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
979 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
980 if (fnum2 == -1) {
981 torture_result(tctx, TORTURE_FAIL,
982 __location__ ": Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
983 CHECK_MAX_FAILURES(error_test10);
984 return false;
987 torture_comment(tctx, "non-io open test #1 passed.\n");
988 error_test10:
990 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
991 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
993 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
994 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
997 torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
998 fnum1 = fnum2 = -1;
999 smbcli_unlink(cli1->tree, fname);
1001 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1002 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1004 if (fnum1 == -1) {
1005 torture_result(tctx, TORTURE_FAIL,
1006 __location__ ": Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1007 CHECK_MAX_FAILURES(error_test20);
1008 return false;
1011 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1012 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1014 if (fnum2 == -1) {
1015 torture_result(tctx, TORTURE_FAIL,
1016 __location__ ": Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1017 CHECK_MAX_FAILURES(error_test20);
1018 return false;
1021 torture_comment(tctx, "non-io open test #2 passed.\n");
1022 error_test20:
1024 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1025 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1027 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1028 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1031 fnum1 = fnum2 = -1;
1032 smbcli_unlink(cli1->tree, fname);
1034 torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
1036 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1037 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1039 if (fnum1 == -1) {
1040 torture_result(tctx, TORTURE_FAIL,
1041 __location__ ": Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1042 CHECK_MAX_FAILURES(error_test30);
1043 return false;
1046 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1047 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1049 if (fnum2 == -1) {
1050 torture_result(tctx, TORTURE_FAIL,
1051 __location__ ": Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1052 CHECK_MAX_FAILURES(error_test30);
1053 return false;
1056 torture_comment(tctx, "non-io open test #3 passed.\n");
1057 error_test30:
1059 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1060 torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1062 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1063 torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1066 torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
1067 fnum1 = fnum2 = -1;
1068 smbcli_unlink(cli1->tree, fname);
1070 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1071 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1073 if (fnum1 == -1) {
1074 torture_result(tctx, TORTURE_FAIL,
1075 __location__ ": Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1076 CHECK_MAX_FAILURES(error_test40);
1077 return false;
1080 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1081 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1083 if (fnum2 != -1) {
1084 torture_result(tctx, TORTURE_FAIL,
1085 __location__ ": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1086 CHECK_MAX_FAILURES(error_test40);
1087 return false;
1090 torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1092 torture_comment(tctx, "non-io open test #4 passed.\n");
1093 error_test40:
1095 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1096 torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1098 if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1099 torture_comment(tctx, "Test 4 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1102 torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1103 fnum1 = fnum2 = -1;
1104 smbcli_unlink(cli1->tree, fname);
1106 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1107 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1109 if (fnum1 == -1) {
1110 torture_result(tctx, TORTURE_FAIL,
1111 __location__ ": Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1112 CHECK_MAX_FAILURES(error_test50);
1113 return false;
1116 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1117 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1119 if (fnum2 == -1) {
1120 torture_result(tctx, TORTURE_FAIL,
1121 __location__ ": Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1122 CHECK_MAX_FAILURES(error_test50);
1123 return false;
1126 torture_comment(tctx, "non-io open test #5 passed.\n");
1127 error_test50:
1129 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1130 torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1133 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1134 torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1137 torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
1138 fnum1 = fnum2 = -1;
1139 smbcli_unlink(cli1->tree, fname);
1141 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1142 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1144 if (fnum1 == -1) {
1145 torture_result(tctx, TORTURE_FAIL,
1146 __location__ ": Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1147 CHECK_MAX_FAILURES(error_test60);
1148 return false;
1151 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1152 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1154 if (fnum2 == -1) {
1155 torture_result(tctx, TORTURE_FAIL,
1156 __location__ ": Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1157 CHECK_MAX_FAILURES(error_test60);
1158 return false;
1161 torture_comment(tctx, "non-io open test #6 passed.\n");
1162 error_test60:
1164 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1165 torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1168 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1169 torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1172 torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
1173 fnum1 = fnum2 = -1;
1174 smbcli_unlink(cli1->tree, fname);
1176 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1177 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1179 if (fnum1 == -1) {
1180 torture_result(tctx, TORTURE_FAIL,
1181 __location__ ": Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1182 CHECK_MAX_FAILURES(error_test70);
1183 return false;
1186 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1187 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1189 if (fnum2 != -1) {
1190 torture_result(tctx, TORTURE_FAIL,
1191 __location__ ": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1192 CHECK_MAX_FAILURES(error_test70);
1193 return false;
1196 torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1198 torture_comment(tctx, "non-io open test #7 passed.\n");
1199 error_test70:
1201 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1202 torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1204 if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1205 torture_comment(tctx, "Test 7 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1208 torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1209 fnum1 = fnum2 = -1;
1210 smbcli_unlink(cli1->tree, fname);
1212 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1213 if (fnum1 == -1) {
1214 torture_comment(tctx, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1215 return false;
1218 /* write 20 bytes. */
1220 memset(buf, '\0', 20);
1222 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1223 torture_comment(tctx, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1224 correct = false;
1227 /* Ensure size == 20. */
1228 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1229 torture_result(tctx, TORTURE_FAIL,
1230 __location__ ": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1231 CHECK_MAX_FAILURES(error_test80);
1232 return false;
1235 if (fsize != 20) {
1236 torture_result(tctx, TORTURE_FAIL,
1237 __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
1238 CHECK_MAX_FAILURES(error_test80);
1239 return false;
1242 /* Get an exclusive lock on the open file. */
1243 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1244 torture_result(tctx, TORTURE_FAIL,
1245 __location__ ": (8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1246 CHECK_MAX_FAILURES(error_test80);
1247 return false;
1250 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1251 if (fnum1 == -1) {
1252 torture_comment(tctx, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1253 return false;
1256 /* Ensure size == 0. */
1257 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1258 torture_result(tctx, TORTURE_FAIL,
1259 __location__ ": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1260 CHECK_MAX_FAILURES(error_test80);
1261 return false;
1264 if (fsize != 0) {
1265 torture_result(tctx, TORTURE_FAIL,
1266 __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
1267 CHECK_MAX_FAILURES(error_test80);
1268 return false;
1271 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1272 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1273 return false;
1276 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1277 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1278 return false;
1281 error_test80:
1283 torture_comment(tctx, "open test #8 passed.\n");
1285 smbcli_unlink(cli1->tree, fname);
1287 return failures > 0 ? false : correct;
1290 /* FIRST_DESIRED_ACCESS 0xf019f */
1291 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1292 SEC_FILE_READ_EA| /* 0xf */ \
1293 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1294 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1295 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1296 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1297 /* SECOND_DESIRED_ACCESS 0xe0080 */
1298 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1299 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1300 SEC_STD_WRITE_OWNER /* 0xe0000 */
1302 #if 0
1303 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1304 READ_CONTROL|WRITE_DAC|\
1305 SEC_FILE_READ_DATA|\
1306 WRITE_OWNER /* */
1307 #endif
1312 Test ntcreate calls made by xcopy
1314 static bool run_xcopy(struct torture_context *tctx,
1315 struct smbcli_state *cli1)
1317 const char *fname = "\\test.txt";
1318 int fnum1, fnum2;
1320 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1321 FIRST_DESIRED_ACCESS,
1322 FILE_ATTRIBUTE_ARCHIVE,
1323 NTCREATEX_SHARE_ACCESS_NONE,
1324 NTCREATEX_DISP_OVERWRITE_IF,
1325 0x4044, 0);
1327 torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx,
1328 "First open failed - %s", smbcli_errstr(cli1->tree)));
1330 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1331 SECOND_DESIRED_ACCESS, 0,
1332 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1333 0x200000, 0);
1334 torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
1335 "second open failed - %s", smbcli_errstr(cli1->tree)));
1337 return true;
1340 static bool run_iometer(struct torture_context *tctx,
1341 struct smbcli_state *cli)
1343 const char *fname = "\\iobw.tst";
1344 int fnum;
1345 size_t filesize;
1346 NTSTATUS status;
1347 char buf[2048];
1348 int ops;
1350 memset(buf, 0, sizeof(buf));
1352 status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1353 torture_assert_ntstatus_ok(tctx, status,
1354 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1356 torture_comment(tctx, "size: %d\n", (int)filesize);
1358 filesize -= (sizeof(buf) - 1);
1360 fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1361 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1362 torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s",
1363 smbcli_errstr(cli->tree)));
1365 ops = 0;
1367 while (true) {
1368 int i, num_reads, num_writes;
1370 num_reads = random() % 10;
1371 num_writes = random() % 3;
1373 for (i=0; i<num_reads; i++) {
1374 ssize_t res;
1375 if (ops++ > torture_numops) {
1376 return true;
1378 res = smbcli_read(cli->tree, fnum, buf,
1379 random() % filesize, sizeof(buf));
1380 torture_assert(tctx, res == sizeof(buf),
1381 talloc_asprintf(tctx, "read failed: %s",
1382 smbcli_errstr(cli->tree)));
1384 for (i=0; i<num_writes; i++) {
1385 ssize_t res;
1386 if (ops++ > torture_numops) {
1387 return true;
1389 res = smbcli_write(cli->tree, fnum, 0, buf,
1390 random() % filesize, sizeof(buf));
1391 torture_assert(tctx, res == sizeof(buf),
1392 talloc_asprintf(tctx, "read failed: %s",
1393 smbcli_errstr(cli->tree)));
1399 tries variants of chkpath
1401 static bool torture_chkpath_test(struct torture_context *tctx,
1402 struct smbcli_state *cli)
1404 int fnum;
1405 bool ret;
1407 torture_comment(tctx, "Testing valid and invalid paths\n");
1409 /* cleanup from an old run */
1410 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1411 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1412 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1414 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1415 torture_comment(tctx, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1416 return false;
1419 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1420 torture_comment(tctx, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1421 return false;
1424 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1425 if (fnum == -1) {
1426 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1427 return false;
1429 smbcli_close(cli->tree, fnum);
1431 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1432 torture_comment(tctx, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1433 ret = false;
1436 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1437 torture_comment(tctx, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1438 ret = false;
1441 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1442 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1443 NT_STATUS_NOT_A_DIRECTORY);
1444 } else {
1445 torture_comment(tctx, "* chkpath on a file should fail\n");
1446 ret = false;
1449 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1450 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1451 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1452 } else {
1453 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1454 ret = false;
1457 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1458 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1459 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1460 } else {
1461 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1462 ret = false;
1465 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1466 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1467 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1469 return ret;
1473 * This is a test to excercise some weird Samba3 error paths.
1476 static bool torture_samba3_errorpaths(struct torture_context *tctx)
1478 bool nt_status_support;
1479 struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1480 bool result = false;
1481 int fnum;
1482 const char *os2_fname = ".+,;=[].";
1483 const char *dname = "samba3_errordir";
1484 union smb_open io;
1485 NTSTATUS status;
1487 nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1489 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1490 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1491 goto fail;
1494 if (!torture_open_connection(&cli_nt, tctx, 0)) {
1495 goto fail;
1498 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1499 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1500 goto fail;
1503 if (!torture_open_connection(&cli_dos, tctx, 1)) {
1504 goto fail;
1507 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1508 nt_status_support ? "yes":"no")) {
1509 torture_comment(tctx, "Could not reset 'nt status support = yes'");
1510 goto fail;
1513 smbcli_unlink(cli_nt->tree, os2_fname);
1514 smbcli_rmdir(cli_nt->tree, dname);
1516 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1517 torture_comment(tctx, "smbcli_mkdir(%s) failed: %s\n", dname,
1518 smbcli_errstr(cli_nt->tree));
1519 goto fail;
1522 io.generic.level = RAW_OPEN_NTCREATEX;
1523 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1524 io.ntcreatex.in.root_fid.fnum = 0;
1525 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1526 io.ntcreatex.in.alloc_size = 1024*1024;
1527 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1528 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1529 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1530 io.ntcreatex.in.create_options = 0;
1531 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1532 io.ntcreatex.in.security_flags = 0;
1533 io.ntcreatex.in.fname = dname;
1535 status = smb_raw_open(cli_nt->tree, tctx, &io);
1536 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1537 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1538 __location__, nt_errstr(status),
1539 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1540 goto fail;
1542 status = smb_raw_open(cli_dos->tree, tctx, &io);
1543 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1544 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1545 __location__, nt_errstr(status),
1546 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1547 goto fail;
1550 status = smbcli_mkdir(cli_nt->tree, dname);
1551 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1552 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1553 __location__, nt_errstr(status),
1554 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1555 goto fail;
1557 status = smbcli_mkdir(cli_dos->tree, dname);
1558 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1559 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1560 __location__, nt_errstr(status),
1561 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1562 goto fail;
1566 union smb_mkdir md;
1567 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1568 md.t2mkdir.in.path = dname;
1569 md.t2mkdir.in.num_eas = 0;
1570 md.t2mkdir.in.eas = NULL;
1572 status = smb_raw_mkdir(cli_nt->tree, &md);
1573 if (!NT_STATUS_EQUAL(status,
1574 NT_STATUS_OBJECT_NAME_COLLISION)) {
1575 torture_comment(
1576 tctx, "(%s) incorrect status %s should be "
1577 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1578 __location__, nt_errstr(status));
1579 goto fail;
1581 status = smb_raw_mkdir(cli_dos->tree, &md);
1582 if (!NT_STATUS_EQUAL(status,
1583 NT_STATUS_DOS(ERRDOS, ERRrename))) {
1584 torture_comment(tctx, "(%s) incorrect status %s "
1585 "should be ERRDOS:ERRrename\n",
1586 __location__, nt_errstr(status));
1587 goto fail;
1591 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1592 status = smb_raw_open(cli_nt->tree, tctx, &io);
1593 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1594 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1595 __location__, nt_errstr(status),
1596 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1597 goto fail;
1600 status = smb_raw_open(cli_dos->tree, tctx, &io);
1601 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1602 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1603 __location__, nt_errstr(status),
1604 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1605 goto fail;
1609 /* Test an invalid DOS deny mode */
1610 const char *fname = "test.txt";
1612 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1613 if (fnum != -1) {
1614 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1615 "expected failure\n", fname);
1616 smbcli_close(cli_nt->tree, fnum);
1617 goto fail;
1619 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1620 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1621 torture_comment(tctx, "Expected DOS error ERRDOS/ERRbadaccess, "
1622 "got %s\n", smbcli_errstr(cli_nt->tree));
1623 goto fail;
1626 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1627 if (fnum != -1) {
1628 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1629 "expected failure\n", fname);
1630 smbcli_close(cli_nt->tree, fnum);
1631 goto fail;
1633 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1634 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1635 torture_comment(tctx, "Expected DOS error ERRDOS:ERRbadaccess, "
1636 "got %s\n", smbcli_errstr(cli_nt->tree));
1637 goto fail;
1643 * Samba 3.0.23 has a bug that an existing file can be opened
1644 * as a directory using ntcreate&x. Test this.
1647 const char *fname = "\\test_dir.txt";
1649 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1650 DENY_NONE);
1651 if (fnum == -1) {
1652 d_printf("(%s) smbcli_open failed: %s\n", __location__,
1653 smbcli_errstr(cli_nt->tree));
1655 smbcli_close(cli_nt->tree, fnum);
1657 io.generic.level = RAW_OPEN_NTCREATEX;
1658 io.ntcreatex.in.root_fid.fnum = 0;
1659 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1660 io.ntcreatex.in.alloc_size = 0;
1661 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1662 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1663 NTCREATEX_SHARE_ACCESS_WRITE|
1664 NTCREATEX_SHARE_ACCESS_DELETE;
1665 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1666 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1667 io.ntcreatex.in.impersonation =
1668 NTCREATEX_IMPERSONATION_ANONYMOUS;
1669 io.ntcreatex.in.security_flags = 0;
1670 io.ntcreatex.in.fname = fname;
1671 io.ntcreatex.in.flags = 0;
1673 status = smb_raw_open(cli_nt->tree, tctx, &io);
1674 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1675 torture_comment(tctx, "ntcreate as dir gave %s, "
1676 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1677 nt_errstr(status));
1678 result = false;
1681 if (NT_STATUS_IS_OK(status)) {
1682 smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1685 status = smb_raw_open(cli_dos->tree, tctx, &io);
1686 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1687 ERRbaddirectory))) {
1688 torture_comment(tctx, "ntcreate as dir gave %s, "
1689 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1690 nt_errstr(status));
1691 result = false;
1694 if (NT_STATUS_IS_OK(status)) {
1695 smbcli_close(cli_dos->tree,
1696 io.ntcreatex.out.file.fnum);
1699 smbcli_unlink(cli_nt->tree, fname);
1702 if (!torture_setting_bool(tctx, "samba3", false)) {
1703 goto done;
1706 fnum = smbcli_open(cli_dos->tree, os2_fname,
1707 O_RDWR | O_CREAT | O_TRUNC,
1708 DENY_NONE);
1709 if (fnum != -1) {
1710 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1711 os2_fname);
1712 smbcli_close(cli_dos->tree, fnum);
1713 goto fail;
1716 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1717 NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1718 torture_comment(tctx, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1719 smbcli_errstr(cli_dos->tree));
1720 goto fail;
1723 fnum = smbcli_open(cli_nt->tree, os2_fname,
1724 O_RDWR | O_CREAT | O_TRUNC,
1725 DENY_NONE);
1726 if (fnum != -1) {
1727 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1728 os2_fname);
1729 smbcli_close(cli_nt->tree, fnum);
1730 goto fail;
1733 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1734 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1735 torture_comment(tctx, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1736 "got %s\n", smbcli_errstr(cli_nt->tree));
1737 goto fail;
1740 done:
1741 result = true;
1743 fail:
1744 if (cli_dos != NULL) {
1745 torture_close_connection(cli_dos);
1747 if (cli_nt != NULL) {
1748 torture_close_connection(cli_nt);
1751 return result;
1755 This checks file/dir birthtime
1757 static void list_fn(struct clilist_file_info *finfo, const char *name,
1758 void *state){
1760 /* Just to change dir access time*/
1761 sleep(5);
1765 static bool run_birthtimetest(struct torture_context *tctx,
1766 struct smbcli_state *cli)
1768 int fnum;
1769 size_t size;
1770 time_t c_time, a_time, m_time, w_time, c_time1;
1771 const char *fname = "\\birthtime.tst";
1772 const char *dname = "\\birthtime";
1773 const char *fname2 = "\\birthtime\\birthtime.tst";
1774 bool correct = true;
1775 uint8_t buf[16];
1778 smbcli_unlink(cli->tree, fname);
1780 torture_comment(tctx, "Testing Birthtime for File\n");
1782 /* Save File birthtime/creationtime */
1783 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1784 DENY_NONE);
1785 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1786 &c_time, &a_time, &m_time, NULL, NULL))) {
1787 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n",
1788 smbcli_errstr(cli->tree));
1789 correct = false;
1791 smbcli_close(cli->tree, fnum);
1793 sleep(10);
1795 /* Change in File attribute changes file change time*/
1796 smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1798 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1799 /* Writing updates modification time*/
1800 smbcli_smbwrite(cli->tree, fnum, &fname, 0, sizeof(fname));
1801 /*Reading updates access time */
1802 smbcli_read(cli->tree, fnum, buf, 0, 13);
1803 smbcli_close(cli->tree, fnum);
1805 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1806 &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1807 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1808 smbcli_errstr(cli->tree));
1809 correct = false;
1810 } else {
1811 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1812 (long) c_time, (long) c_time1);
1813 if (c_time1 != c_time) {
1814 torture_comment(tctx, "This system updated file \
1815 birth times! Not expected!\n");
1816 correct = false;
1819 smbcli_unlink(cli->tree, fname);
1821 torture_comment(tctx, "Testing Birthtime for Directory\n");
1823 /* check if the server does not update the directory birth time
1824 when creating a new file */
1825 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1826 torture_comment(tctx, "ERROR: mkdir failed (%s)\n",
1827 smbcli_errstr(cli->tree));
1828 correct = false;
1830 sleep(3);
1831 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1832 &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1833 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1834 smbcli_errstr(cli->tree));
1835 correct = false;
1838 /* Creating a new file changes dir modification time and change time*/
1839 smbcli_unlink(cli->tree, fname2);
1840 fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1841 DENY_NONE);
1842 smbcli_smbwrite(cli->tree, fnum, &fnum, 0, sizeof(fnum));
1843 smbcli_read(cli->tree, fnum, buf, 0, 13);
1844 smbcli_close(cli->tree, fnum);
1846 /* dir listing changes dir access time*/
1847 smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1849 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1850 &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1851 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1852 smbcli_errstr(cli->tree));
1853 correct = false;
1854 } else {
1855 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1856 (long) c_time, (long) c_time1);
1857 if (c_time1 != c_time) {
1858 torture_comment(tctx, "This system updated directory \
1859 birth times! Not Expected!\n");
1860 correct = false;
1863 smbcli_unlink(cli->tree, fname2);
1864 smbcli_rmdir(cli->tree, dname);
1866 return correct;
1870 NTSTATUS torture_base_init(void)
1872 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "base");
1874 torture_suite_add_2smb_test(suite, "fdpass", run_fdpasstest);
1875 torture_suite_add_suite(suite, torture_base_locktest(suite));
1876 torture_suite_add_1smb_test(suite, "unlink", torture_unlinktest);
1877 torture_suite_add_1smb_test(suite, "attr", run_attrtest);
1878 torture_suite_add_1smb_test(suite, "trans2", run_trans2test);
1879 torture_suite_add_1smb_test(suite, "birthtime", run_birthtimetest);
1880 torture_suite_add_simple_test(suite, "negnowait", run_negprot_nowait);
1881 torture_suite_add_1smb_test(suite, "dir1", torture_dirtest1);
1882 torture_suite_add_1smb_test(suite, "dir2", torture_dirtest2);
1883 torture_suite_add_1smb_test(suite, "deny1", torture_denytest1);
1884 torture_suite_add_2smb_test(suite, "deny2", torture_denytest2);
1885 torture_suite_add_2smb_test(suite, "deny3", torture_denytest3);
1886 torture_suite_add_1smb_test(suite, "denydos", torture_denydos_sharing);
1887 torture_suite_add_smb_multi_test(suite, "ntdeny1", torture_ntdenytest1);
1888 torture_suite_add_2smb_test(suite, "ntdeny2", torture_ntdenytest2);
1889 torture_suite_add_1smb_test(suite, "tcon", run_tcon_test);
1890 torture_suite_add_1smb_test(suite, "tcondev", run_tcon_devtype_test);
1891 torture_suite_add_1smb_test(suite, "vuid", run_vuidtest);
1892 torture_suite_add_2smb_test(suite, "rw1", run_readwritetest);
1893 torture_suite_add_2smb_test(suite, "open", run_opentest);
1894 torture_suite_add_smb_multi_test(suite, "defer_open", run_deferopen);
1895 torture_suite_add_1smb_test(suite, "xcopy", run_xcopy);
1896 torture_suite_add_1smb_test(suite, "iometer", run_iometer);
1897 torture_suite_add_1smb_test(suite, "rename", torture_test_rename);
1898 torture_suite_add_suite(suite, torture_test_delete());
1899 torture_suite_add_1smb_test(suite, "properties", torture_test_properties);
1900 torture_suite_add_1smb_test(suite, "mangle", torture_mangle);
1901 torture_suite_add_1smb_test(suite, "openattr", torture_openattrtest);
1902 torture_suite_add_1smb_test(suite, "winattr", torture_winattrtest);
1903 torture_suite_add_suite(suite, torture_charset(suite));
1904 torture_suite_add_1smb_test(suite, "chkpath", torture_chkpath_test);
1905 torture_suite_add_1smb_test(suite, "secleak", torture_sec_leak);
1906 torture_suite_add_simple_test(suite, "disconnect", torture_disconnect);
1907 torture_suite_add_suite(suite, torture_delay_write());
1908 torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths);
1909 torture_suite_add_1smb_test(suite, "casetable", torture_casetable);
1910 torture_suite_add_1smb_test(suite, "utable", torture_utable);
1911 torture_suite_add_simple_test(suite, "smb", torture_smb_scan);
1912 torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1913 torture_suite_add_1smb_test(suite, "trans2-scan", torture_trans2_scan);
1914 torture_suite_add_1smb_test(suite, "nttrans", torture_nttrans_scan);
1915 torture_suite_add_1smb_test(suite, "createx_access", torture_createx_access);
1916 torture_suite_add_2smb_test(suite, "createx_sharemodes_file", torture_createx_sharemodes_file);
1917 torture_suite_add_2smb_test(suite, "createx_sharemodes_dir", torture_createx_sharemodes_dir);
1918 torture_suite_add_1smb_test(suite, "maximum_allowed", torture_maximum_allowed);
1920 torture_suite_add_simple_test(suite, "bench-holdcon", torture_holdcon);
1921 torture_suite_add_1smb_test(suite, "bench-holdopen", torture_holdopen);
1922 torture_suite_add_simple_test(suite, "bench-readwrite", run_benchrw);
1923 torture_suite_add_smb_multi_test(suite, "bench-torture", run_torture);
1924 torture_suite_add_1smb_test(suite, "scan-pipe_number", run_pipe_number);
1925 torture_suite_add_1smb_test(suite, "scan-ioctl", torture_ioctl_test);
1926 torture_suite_add_smb_multi_test(suite, "scan-maxfid", run_maxfidtest);
1928 suite->description = talloc_strdup(suite,
1929 "Basic SMB tests (imported from the original smbtorture)");
1931 torture_register_suite(suite);
1933 return NT_STATUS_OK;