s3:smbd: move struct privilege_paths to smbd.h
[Samba/gebeck_regimport.git] / source4 / torture / basic / base.c
blob56461005e80997561ca4394c82430f60332b99f3
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;
43 bool ok;
45 make_nbt_name_client(&calling, lpcfg_netbios_name(tctx->lp_ctx));
47 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
49 cli = smbcli_state_init(NULL);
50 if (!cli) {
51 torture_comment(tctx, "Failed initialize smbcli_struct to connect with %s\n", host);
52 goto failed;
55 lpcfg_smbcli_options(tctx->lp_ctx, &options);
57 ok = smbcli_socket_connect(cli, host, lpcfg_smb_ports(tctx->lp_ctx),
58 tctx->ev,
59 lpcfg_resolve_context(tctx->lp_ctx),
60 &options,
61 lpcfg_socket_options(tctx->lp_ctx),
62 &calling, &called);
63 if (!ok) {
64 torture_comment(tctx, "Failed to connect with %s\n", host);
65 goto failed;
68 cli->transport = smbcli_transport_init(cli->sock, cli,
69 true, &cli->options);
70 cli->sock = NULL;
71 if (!cli->transport) {
72 torture_comment(tctx, "smbcli_transport_init failed\n");
73 goto failed;
76 return cli;
78 failed:
79 talloc_free(cli);
80 return NULL;
83 static bool tcon_devtest(struct torture_context *tctx,
84 struct smbcli_state *cli,
85 const char *myshare, const char *devtype,
86 NTSTATUS expected_error)
88 bool status;
89 const char *password = torture_setting_string(tctx, "password", NULL);
91 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
92 password));
94 torture_comment(tctx, "Trying share %s with devtype %s\n", myshare, devtype);
96 if (NT_STATUS_IS_OK(expected_error)) {
97 if (!status) {
98 torture_fail(tctx, talloc_asprintf(tctx,
99 "tconX to share %s with type %s "
100 "should have succeeded but failed",
101 myshare, devtype));
103 smbcli_tdis(cli);
104 } else {
105 if (status) {
106 torture_fail(tctx, talloc_asprintf(tctx,
107 "tconx to share %s with type %s "
108 "should have failed but succeeded",
109 myshare, devtype));
110 } else {
111 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
112 expected_error)) {
113 } else {
114 torture_fail(tctx, "Returned unexpected error");
118 return true;
124 test whether fnums and tids open on one VC are available on another (a major
125 security hole)
127 static bool run_fdpasstest(struct torture_context *tctx,
128 struct smbcli_state *cli1,
129 struct smbcli_state *cli2)
131 const char *fname = "\\fdpass.tst";
132 int fnum1, oldtid;
133 uint8_t buf[1024];
135 smbcli_unlink(cli1->tree, fname);
137 torture_comment(tctx, "Opening a file on connection 1\n");
139 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
140 torture_assert(tctx, fnum1 != -1,
141 talloc_asprintf(tctx,
142 "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
144 torture_comment(tctx, "writing to file on connection 1\n");
146 torture_assert(tctx,
147 smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) == 13,
148 talloc_asprintf(tctx,
149 "write failed (%s)\n", smbcli_errstr(cli1->tree)));
151 oldtid = cli2->tree->tid;
152 cli2->session->vuid = cli1->session->vuid;
153 cli2->tree->tid = cli1->tree->tid;
154 cli2->session->pid = cli1->session->pid;
156 torture_comment(tctx, "reading from file on connection 2\n");
158 torture_assert(tctx, smbcli_read(cli2->tree, fnum1, buf, 0, 13) != 13,
159 talloc_asprintf(tctx,
160 "read succeeded! nasty security hole [%s]\n", buf));
162 smbcli_close(cli1->tree, fnum1);
163 smbcli_unlink(cli1->tree, fname);
165 cli2->tree->tid = oldtid;
167 return true;
171 This checks how the getatr calls works
173 static bool run_attrtest(struct torture_context *tctx,
174 struct smbcli_state *cli)
176 int fnum;
177 time_t t, t2;
178 const char *fname = "\\attrib123456789.tst";
179 bool correct = true;
181 smbcli_unlink(cli->tree, fname);
182 fnum = smbcli_open(cli->tree, fname,
183 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
184 smbcli_close(cli->tree, fnum);
186 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
187 torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
188 correct = false;
191 torture_comment(tctx, "New file time is %s", ctime(&t));
193 if (abs(t - time(NULL)) > 60*60*24*10) {
194 torture_comment(tctx, "ERROR: SMBgetatr bug. time is %s",
195 ctime(&t));
196 t = time(NULL);
197 correct = false;
200 t2 = t-60*60*24; /* 1 day ago */
202 torture_comment(tctx, "Setting file time to %s", ctime(&t2));
204 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
205 torture_comment(tctx, "setatr failed (%s)\n", smbcli_errstr(cli->tree));
206 correct = true;
209 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
210 torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
211 correct = true;
214 torture_comment(tctx, "Retrieved file time as %s", ctime(&t));
216 if (t != t2) {
217 torture_comment(tctx, "ERROR: getatr/setatr bug. times are\n%s",
218 ctime(&t));
219 torture_comment(tctx, "%s", ctime(&t2));
220 correct = true;
223 smbcli_unlink(cli->tree, fname);
225 return correct;
229 This checks a couple of trans2 calls
231 static bool run_trans2test(struct torture_context *tctx,
232 struct smbcli_state *cli)
234 int fnum;
235 size_t size;
236 time_t c_time, a_time, m_time, w_time, m_time2;
237 const char *fname = "\\trans2.tst";
238 const char *dname = "\\trans2";
239 const char *fname2 = "\\trans2\\trans2.tst";
240 const char *pname;
241 bool correct = true;
243 smbcli_unlink(cli->tree, fname);
245 torture_comment(tctx, "Testing qfileinfo\n");
247 fnum = smbcli_open(cli->tree, fname,
248 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
249 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
250 NULL, NULL))) {
251 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
252 correct = false;
255 torture_comment(tctx, "Testing NAME_INFO\n");
257 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
258 torture_comment(tctx, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
259 correct = false;
262 if (!pname || strcmp(pname, fname)) {
263 torture_comment(tctx, "qfilename gave different name? [%s] [%s]\n",
264 fname, pname);
265 correct = false;
268 smbcli_close(cli->tree, fnum);
269 smbcli_unlink(cli->tree, fname);
271 fnum = smbcli_open(cli->tree, fname,
272 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
273 if (fnum == -1) {
274 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
275 return false;
277 smbcli_close(cli->tree, fnum);
279 torture_comment(tctx, "Checking for sticky create times\n");
281 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
282 torture_comment(tctx, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
283 correct = false;
284 } else {
285 time_t t = time(NULL);
287 if (c_time != m_time) {
288 torture_comment(tctx, "create time=%s", ctime(&c_time));
289 torture_comment(tctx, "modify time=%s", ctime(&m_time));
290 torture_comment(tctx, "This system appears to have sticky create times\n");
292 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
293 torture_comment(tctx, "access time=%s", ctime(&a_time));
294 torture_comment(tctx, "This system appears to set a midnight access time\n");
295 correct = false;
298 if (abs(m_time - t) > 60*60*24*7) {
299 torture_comment(tctx, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
300 correct = false;
305 smbcli_unlink(cli->tree, fname);
306 fnum = smbcli_open(cli->tree, fname,
307 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
308 smbcli_close(cli->tree, fnum);
309 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
310 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
311 correct = false;
312 } else {
313 if (w_time < 60*60*24*2) {
314 torture_comment(tctx, "write time=%s", ctime(&w_time));
315 torture_comment(tctx, "This system appears to set a initial 0 write time\n");
316 correct = false;
320 smbcli_unlink(cli->tree, fname);
323 /* check if the server updates the directory modification time
324 when creating a new file */
325 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
326 torture_comment(tctx, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
327 correct = false;
329 sleep(3);
330 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
331 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
332 correct = false;
335 fnum = smbcli_open(cli->tree, fname2,
336 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
337 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
338 smbcli_close(cli->tree, fnum);
339 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
340 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
341 correct = false;
342 } else {
343 if (m_time2 == m_time) {
344 torture_comment(tctx, "This system does not update directory modification times\n");
345 correct = false;
348 smbcli_unlink(cli->tree, fname2);
349 smbcli_rmdir(cli->tree, dname);
351 return correct;
354 /* send smb negprot commands, not reading the response */
355 static bool run_negprot_nowait(struct torture_context *tctx)
357 int i;
358 struct smbcli_state *cli, *cli2;
359 bool correct = true;
361 torture_comment(tctx, "starting negprot nowait test\n");
363 cli = open_nbt_connection(tctx);
364 if (!cli) {
365 return false;
368 torture_comment(tctx, "Filling send buffer\n");
370 for (i=0;i<100;i++) {
371 struct tevent_req *req;
372 req = smb_raw_negotiate_send(cli, tctx->ev,
373 cli->transport,
374 PROTOCOL_NT1);
375 tevent_loop_once(tctx->ev);
376 if (!tevent_req_is_in_progress(req)) {
377 NTSTATUS status;
379 status = smb_raw_negotiate_recv(req);
380 TALLOC_FREE(req);
381 if (i > 0) {
382 torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n",
383 i+1, nt_errstr(status));
384 break;
385 } else {
386 torture_comment(tctx, "Failed to fill pipe - %s \n",
387 nt_errstr(status));
388 torture_close_connection(cli);
389 return false;
394 torture_comment(tctx, "Opening secondary connection\n");
395 if (!torture_open_connection(&cli2, tctx, 1)) {
396 torture_comment(tctx, "Failed to open secondary connection\n");
397 correct = false;
400 if (!torture_close_connection(cli2)) {
401 torture_comment(tctx, "Failed to close secondary connection\n");
402 correct = false;
405 torture_close_connection(cli);
407 return correct;
411 this checks to see if a secondary tconx can use open files from an
412 earlier tconx
414 static bool run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
416 const char *fname = "\\tcontest.tmp";
417 int fnum1;
418 uint16_t cnum1, cnum2, cnum3;
419 uint16_t vuid1, vuid2;
420 uint8_t buf[4];
421 bool ret = true;
422 struct smbcli_tree *tree1;
423 const char *host = torture_setting_string(tctx, "host", NULL);
424 const char *share = torture_setting_string(tctx, "share", NULL);
425 const char *password = torture_setting_string(tctx, "password", NULL);
427 if (smbcli_deltree(cli->tree, fname) == -1) {
428 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
431 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
432 if (fnum1 == -1) {
433 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
434 return false;
437 cnum1 = cli->tree->tid;
438 vuid1 = cli->session->vuid;
440 memset(buf, 0, 4); /* init buf so valgrind won't complain */
441 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
442 torture_comment(tctx, "initial write failed (%s)\n", smbcli_errstr(cli->tree));
443 return false;
446 tree1 = cli->tree; /* save old tree connection */
447 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
448 torture_comment(tctx, "%s refused 2nd tree connect (%s)\n", host,
449 smbcli_errstr(cli->tree));
450 talloc_free(cli);
451 return false;
454 cnum2 = cli->tree->tid;
455 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
456 vuid2 = cli->session->vuid + 1;
458 /* try a write with the wrong tid */
459 cli->tree->tid = cnum2;
461 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
462 torture_comment(tctx, "* server allows write with wrong TID\n");
463 ret = false;
464 } else {
465 torture_comment(tctx, "server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
469 /* try a write with an invalid tid */
470 cli->tree->tid = cnum3;
472 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
473 torture_comment(tctx, "* server allows write with invalid TID\n");
474 ret = false;
475 } else {
476 torture_comment(tctx, "server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
479 /* try a write with an invalid vuid */
480 cli->session->vuid = vuid2;
481 cli->tree->tid = cnum1;
483 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
484 torture_comment(tctx, "* server allows write with invalid VUID\n");
485 ret = false;
486 } else {
487 torture_comment(tctx, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
490 cli->session->vuid = vuid1;
491 cli->tree->tid = cnum1;
493 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
494 torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(cli->tree));
495 return false;
498 cli->tree->tid = cnum2;
500 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
501 torture_comment(tctx, "secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
502 return false;
505 cli->tree = tree1; /* restore initial tree */
506 cli->tree->tid = cnum1;
508 smbcli_unlink(tree1, fname);
510 return ret;
514 checks for correct tconX support
516 static bool run_tcon_devtype_test(struct torture_context *tctx,
517 struct smbcli_state *cli1)
519 const char *share = torture_setting_string(tctx, "share", NULL);
521 if (!tcon_devtest(tctx, cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
522 return false;
524 if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
525 return false;
527 if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
528 return false;
530 if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
531 return false;
533 if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
534 return false;
536 if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
537 return false;
539 if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
540 return false;
542 if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
543 return false;
545 if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
546 return false;
548 if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
549 return false;
551 return true;
554 static bool rw_torture2(struct torture_context *tctx,
555 struct smbcli_state *c1, struct smbcli_state *c2)
557 const char *lockfname = "\\torture2.lck";
558 int fnum1;
559 int fnum2;
560 int i;
561 uint8_t buf[131072];
562 uint8_t buf_rd[131072];
563 bool correct = true;
564 ssize_t bytes_read, bytes_written;
566 torture_assert(tctx, smbcli_deltree(c1->tree, lockfname) != -1,
567 talloc_asprintf(tctx,
568 "unlink failed (%s)", smbcli_errstr(c1->tree)));
570 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
571 DENY_NONE);
572 torture_assert(tctx, fnum1 != -1,
573 talloc_asprintf(tctx,
574 "first open read/write of %s failed (%s)",
575 lockfname, smbcli_errstr(c1->tree)));
576 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
577 DENY_NONE);
578 torture_assert(tctx, fnum2 != -1,
579 talloc_asprintf(tctx,
580 "second open read-only of %s failed (%s)",
581 lockfname, smbcli_errstr(c2->tree)));
583 torture_comment(tctx, "Checking data integrity over %d ops\n",
584 torture_numops);
586 for (i=0;i<torture_numops;i++)
588 size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
589 if (i % 10 == 0) {
590 if (torture_setting_bool(tctx, "progress", true)) {
591 torture_comment(tctx, "%d\r", i); fflush(stdout);
595 generate_random_buffer(buf, buf_size);
597 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
598 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c1->tree));
599 torture_comment(tctx, "wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
600 correct = false;
601 break;
604 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
605 torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c2->tree));
606 torture_comment(tctx, "read %d, expected %d\n", (int)bytes_read, (int)buf_size);
607 correct = false;
608 break;
611 torture_assert_mem_equal(tctx, buf_rd, buf, buf_size,
612 "read/write compare failed\n");
615 torture_assert_ntstatus_ok(tctx, smbcli_close(c2->tree, fnum2),
616 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c2->tree)));
617 torture_assert_ntstatus_ok(tctx, smbcli_close(c1->tree, fnum1),
618 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c1->tree)));
620 torture_assert_ntstatus_ok(tctx, smbcli_unlink(c1->tree, lockfname),
621 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(c1->tree)));
623 torture_comment(tctx, "\n");
625 return correct;
630 static bool run_readwritetest(struct torture_context *tctx,
631 struct smbcli_state *cli1,
632 struct smbcli_state *cli2)
634 torture_comment(tctx, "Running readwritetest v1\n");
635 if (!rw_torture2(tctx, cli1, cli2))
636 return false;
638 torture_comment(tctx, "Running readwritetest v2\n");
640 if (!rw_torture2(tctx, cli1, cli1))
641 return false;
643 return true;
647 test the timing of deferred open requests
649 static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
651 const char *fname = "\\defer_open_test.dat";
652 int retries=4;
653 int i = 0;
654 bool correct = true;
655 int nsec;
656 int msec;
657 double sec;
659 nsec = torture_setting_int(tctx, "sharedelay", 1000000);
660 msec = nsec / 1000;
661 sec = ((double)nsec) / ((double) 1000000);
663 if (retries <= 0) {
664 torture_comment(tctx, "failed to connect\n");
665 return false;
668 torture_comment(tctx, "Testing deferred open requests.\n");
670 while (i < 4) {
671 int fnum = -1;
673 do {
674 struct timeval tv;
675 tv = timeval_current();
676 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
677 SEC_RIGHTS_FILE_ALL,
678 FILE_ATTRIBUTE_NORMAL,
679 NTCREATEX_SHARE_ACCESS_NONE,
680 NTCREATEX_DISP_OPEN_IF, 0, 0);
681 if (fnum != -1) {
682 break;
684 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
685 double e = timeval_elapsed(&tv);
686 if (e < (0.5 * sec) || e > ((1.5 * sec) + 1)) {
687 torture_comment(tctx,"Timing incorrect %.2f violation 1 sec == %.2f\n",
688 e, sec);
689 return false;
692 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
694 if (fnum == -1) {
695 torture_comment(tctx,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
696 return false;
699 torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i);
701 smb_msleep(10 * msec);
702 i++;
703 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
704 torture_comment(tctx,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
705 return false;
707 smb_msleep(2 * msec);
710 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
711 /* All until the last unlink will fail with sharing violation
712 but also the last request can fail since the file could have
713 been successfully deleted by another (test) process */
714 NTSTATUS status = smbcli_nt_error(cli->tree);
715 if ((!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION))
716 && (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))) {
717 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
718 correct = false;
722 torture_comment(tctx, "deferred test finished\n");
723 return correct;
727 Try with a wrong vuid and check error message.
730 static bool run_vuidtest(struct torture_context *tctx,
731 struct smbcli_state *cli)
733 const char *fname = "\\vuid.tst";
734 int fnum;
735 size_t size;
736 time_t c_time, a_time, m_time;
738 NTSTATUS result;
740 smbcli_unlink(cli->tree, fname);
742 fnum = smbcli_open(cli->tree, fname,
743 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
745 cli->session->vuid += 1234;
747 torture_comment(tctx, "Testing qfileinfo with wrong vuid\n");
749 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
750 &size, &c_time, &a_time,
751 &m_time, NULL, NULL))) {
752 torture_fail(tctx, "qfileinfo passed with wrong vuid");
755 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
756 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
757 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
758 NT_STATUS_INVALID_HANDLE)) {
759 torture_fail(tctx, talloc_asprintf(tctx,
760 "qfileinfo should have returned DOS error "
761 "ERRSRV:ERRbaduid\n but returned %s",
762 smbcli_errstr(cli->tree)));
765 cli->session->vuid -= 1234;
767 torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum),
768 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli->tree)));
770 smbcli_unlink(cli->tree, fname);
772 return true;
776 Test open mode returns on read-only files.
778 static bool run_opentest(struct torture_context *tctx, struct smbcli_state *cli1,
779 struct smbcli_state *cli2)
781 const char *fname = "\\readonly.file";
782 char *control_char_fname;
783 int fnum1, fnum2;
784 uint8_t buf[20];
785 size_t fsize;
786 bool correct = true;
787 char *tmp_path;
788 int failures = 0;
789 int i;
791 asprintf(&control_char_fname, "\\readonly.afile");
792 for (i = 1; i <= 0x1f; i++) {
793 control_char_fname[10] = i;
794 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
795 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
797 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
798 NT_STATUS_OBJECT_NAME_INVALID)) {
799 torture_comment(tctx, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
800 smbcli_errstr(cli1->tree), i);
801 failures++;
804 if (fnum1 != -1) {
805 smbcli_close(cli1->tree, fnum1);
807 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
808 smbcli_unlink(cli1->tree, control_char_fname);
810 free(control_char_fname);
812 if (!failures)
813 torture_comment(tctx, "Create file with control char names passed.\n");
815 smbcli_setatr(cli1->tree, fname, 0, 0);
816 smbcli_unlink(cli1->tree, fname);
818 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
819 if (fnum1 == -1) {
820 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
821 return false;
824 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
825 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
826 return false;
829 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
830 torture_result(tctx, TORTURE_FAIL,
831 __location__ ": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
832 CHECK_MAX_FAILURES(error_test1);
833 return false;
836 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
837 if (fnum1 == -1) {
838 torture_result(tctx, TORTURE_FAIL,
839 __location__ ": open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
840 CHECK_MAX_FAILURES(error_test1);
841 return false;
844 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
845 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
847 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
848 NT_STATUS_ACCESS_DENIED)) {
849 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
852 torture_comment(tctx, "finished open test 1\n");
854 error_test1:
855 smbcli_close(cli1->tree, fnum1);
857 /* Now try not readonly and ensure ERRbadshare is returned. */
859 smbcli_setatr(cli1->tree, fname, 0, 0);
861 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
862 if (fnum1 == -1) {
863 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
864 return false;
867 /* This will fail - but the error should be ERRshare. */
868 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
870 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
871 NT_STATUS_SHARING_VIOLATION)) {
872 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
875 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
876 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
877 return false;
880 smbcli_unlink(cli1->tree, fname);
882 torture_comment(tctx, "finished open test 2\n");
884 /* Test truncate open disposition on file opened for read. */
886 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
887 if (fnum1 == -1) {
888 torture_comment(tctx, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
889 return false;
892 /* write 20 bytes. */
894 memset(buf, '\0', 20);
896 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
897 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(cli1->tree));
898 correct = false;
901 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
902 torture_comment(tctx, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
903 return false;
906 /* Ensure size == 20. */
907 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
908 torture_result(tctx, TORTURE_FAIL,
909 __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
910 CHECK_MAX_FAILURES(error_test3);
911 return false;
914 if (fsize != 20) {
915 torture_result(tctx, TORTURE_FAIL,
916 __location__ ": (3) file size != 20\n");
917 CHECK_MAX_FAILURES(error_test3);
918 return false;
921 /* Now test if we can truncate a file opened for readonly. */
923 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
924 if (fnum1 == -1) {
925 torture_result(tctx, TORTURE_FAIL,
926 __location__ ": (3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
927 CHECK_MAX_FAILURES(error_test3);
928 return false;
931 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
932 torture_result(tctx, TORTURE_FAIL,
933 __location__ ": close2 failed (%s)\n", smbcli_errstr(cli1->tree));
934 return false;
937 /* Ensure size == 0. */
938 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
939 torture_result(tctx, TORTURE_FAIL,
940 __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
941 CHECK_MAX_FAILURES(error_test3);
942 return false;
945 if (fsize != 0) {
946 torture_result(tctx, TORTURE_FAIL,
947 __location__ ": (3) file size != 0\n");
948 CHECK_MAX_FAILURES(error_test3);
949 return false;
951 torture_comment(tctx, "finished open test 3\n");
952 error_test3:
954 fnum1 = fnum2 = -1;
955 smbcli_unlink(cli1->tree, fname);
958 torture_comment(tctx, "Testing ctemp\n");
959 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
960 if (fnum1 == -1) {
961 torture_result(tctx, TORTURE_FAIL,
962 __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
963 CHECK_MAX_FAILURES(error_test4);
964 return false;
966 torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
968 error_test4:
969 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
970 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
972 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
973 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
976 /* Test the non-io opens... */
978 torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
979 fnum1 = fnum2 = -1;
980 smbcli_setatr(cli2->tree, fname, 0, 0);
981 smbcli_unlink(cli2->tree, fname);
983 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
984 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
986 if (fnum1 == -1) {
987 torture_result(tctx, TORTURE_FAIL,
988 __location__ ": Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
989 CHECK_MAX_FAILURES(error_test10);
990 return false;
993 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
994 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
995 if (fnum2 == -1) {
996 torture_result(tctx, TORTURE_FAIL,
997 __location__ ": Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
998 CHECK_MAX_FAILURES(error_test10);
999 return false;
1002 torture_comment(tctx, "non-io open test #1 passed.\n");
1003 error_test10:
1005 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1006 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1008 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1009 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1012 torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
1013 fnum1 = fnum2 = -1;
1014 smbcli_unlink(cli1->tree, fname);
1016 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1017 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1019 if (fnum1 == -1) {
1020 torture_result(tctx, TORTURE_FAIL,
1021 __location__ ": Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1022 CHECK_MAX_FAILURES(error_test20);
1023 return false;
1026 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1027 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1029 if (fnum2 == -1) {
1030 torture_result(tctx, TORTURE_FAIL,
1031 __location__ ": Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1032 CHECK_MAX_FAILURES(error_test20);
1033 return false;
1036 torture_comment(tctx, "non-io open test #2 passed.\n");
1037 error_test20:
1039 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1040 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1042 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1043 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1046 fnum1 = fnum2 = -1;
1047 smbcli_unlink(cli1->tree, fname);
1049 torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
1051 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1052 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1054 if (fnum1 == -1) {
1055 torture_result(tctx, TORTURE_FAIL,
1056 __location__ ": Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1057 CHECK_MAX_FAILURES(error_test30);
1058 return false;
1061 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1062 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1064 if (fnum2 == -1) {
1065 torture_result(tctx, TORTURE_FAIL,
1066 __location__ ": Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1067 CHECK_MAX_FAILURES(error_test30);
1068 return false;
1071 torture_comment(tctx, "non-io open test #3 passed.\n");
1072 error_test30:
1074 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1075 torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1077 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1078 torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1081 torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
1082 fnum1 = fnum2 = -1;
1083 smbcli_unlink(cli1->tree, fname);
1085 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1086 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1088 if (fnum1 == -1) {
1089 torture_result(tctx, TORTURE_FAIL,
1090 __location__ ": Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1091 CHECK_MAX_FAILURES(error_test40);
1092 return false;
1095 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1096 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1098 if (fnum2 != -1) {
1099 torture_result(tctx, TORTURE_FAIL,
1100 __location__ ": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1101 CHECK_MAX_FAILURES(error_test40);
1102 return false;
1105 torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1107 torture_comment(tctx, "non-io open test #4 passed.\n");
1108 error_test40:
1110 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1111 torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1113 if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1114 torture_comment(tctx, "Test 4 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1117 torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1118 fnum1 = fnum2 = -1;
1119 smbcli_unlink(cli1->tree, fname);
1121 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1122 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1124 if (fnum1 == -1) {
1125 torture_result(tctx, TORTURE_FAIL,
1126 __location__ ": Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1127 CHECK_MAX_FAILURES(error_test50);
1128 return false;
1131 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1132 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1134 if (fnum2 == -1) {
1135 torture_result(tctx, TORTURE_FAIL,
1136 __location__ ": Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1137 CHECK_MAX_FAILURES(error_test50);
1138 return false;
1141 torture_comment(tctx, "non-io open test #5 passed.\n");
1142 error_test50:
1144 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1145 torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1148 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1149 torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1152 torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
1153 fnum1 = fnum2 = -1;
1154 smbcli_unlink(cli1->tree, fname);
1156 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1157 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1159 if (fnum1 == -1) {
1160 torture_result(tctx, TORTURE_FAIL,
1161 __location__ ": Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1162 CHECK_MAX_FAILURES(error_test60);
1163 return false;
1166 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1167 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1169 if (fnum2 == -1) {
1170 torture_result(tctx, TORTURE_FAIL,
1171 __location__ ": Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1172 CHECK_MAX_FAILURES(error_test60);
1173 return false;
1176 torture_comment(tctx, "non-io open test #6 passed.\n");
1177 error_test60:
1179 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1180 torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1183 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1184 torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1187 torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
1188 fnum1 = fnum2 = -1;
1189 smbcli_unlink(cli1->tree, fname);
1191 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1192 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1194 if (fnum1 == -1) {
1195 torture_result(tctx, TORTURE_FAIL,
1196 __location__ ": Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1197 CHECK_MAX_FAILURES(error_test70);
1198 return false;
1201 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1202 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1204 if (fnum2 != -1) {
1205 torture_result(tctx, TORTURE_FAIL,
1206 __location__ ": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1207 CHECK_MAX_FAILURES(error_test70);
1208 return false;
1211 torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1213 torture_comment(tctx, "non-io open test #7 passed.\n");
1214 error_test70:
1216 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1217 torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1219 if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1220 torture_comment(tctx, "Test 7 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1223 torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1224 fnum1 = fnum2 = -1;
1225 smbcli_unlink(cli1->tree, fname);
1227 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1228 if (fnum1 == -1) {
1229 torture_comment(tctx, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1230 return false;
1233 /* write 20 bytes. */
1235 memset(buf, '\0', 20);
1237 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1238 torture_comment(tctx, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1239 correct = false;
1242 /* Ensure size == 20. */
1243 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1244 torture_result(tctx, TORTURE_FAIL,
1245 __location__ ": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1246 CHECK_MAX_FAILURES(error_test80);
1247 return false;
1250 if (fsize != 20) {
1251 torture_result(tctx, TORTURE_FAIL,
1252 __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
1253 CHECK_MAX_FAILURES(error_test80);
1254 return false;
1257 /* Get an exclusive lock on the open file. */
1258 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1259 torture_result(tctx, TORTURE_FAIL,
1260 __location__ ": (8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1261 CHECK_MAX_FAILURES(error_test80);
1262 return false;
1265 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1266 if (fnum1 == -1) {
1267 torture_comment(tctx, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1268 return false;
1271 /* Ensure size == 0. */
1272 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1273 torture_result(tctx, TORTURE_FAIL,
1274 __location__ ": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1275 CHECK_MAX_FAILURES(error_test80);
1276 return false;
1279 if (fsize != 0) {
1280 torture_result(tctx, TORTURE_FAIL,
1281 __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
1282 CHECK_MAX_FAILURES(error_test80);
1283 return false;
1286 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1287 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1288 return false;
1291 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1292 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1293 return false;
1296 error_test80:
1298 torture_comment(tctx, "open test #8 passed.\n");
1300 smbcli_unlink(cli1->tree, fname);
1302 return failures > 0 ? false : correct;
1305 /* FIRST_DESIRED_ACCESS 0xf019f */
1306 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1307 SEC_FILE_READ_EA| /* 0xf */ \
1308 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1309 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1310 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1311 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1312 /* SECOND_DESIRED_ACCESS 0xe0080 */
1313 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1314 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1315 SEC_STD_WRITE_OWNER /* 0xe0000 */
1317 #if 0
1318 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1319 READ_CONTROL|WRITE_DAC|\
1320 SEC_FILE_READ_DATA|\
1321 WRITE_OWNER /* */
1322 #endif
1327 Test ntcreate calls made by xcopy
1329 static bool run_xcopy(struct torture_context *tctx,
1330 struct smbcli_state *cli1)
1332 const char *fname = "\\test.txt";
1333 int fnum1, fnum2;
1335 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1336 FIRST_DESIRED_ACCESS,
1337 FILE_ATTRIBUTE_ARCHIVE,
1338 NTCREATEX_SHARE_ACCESS_NONE,
1339 NTCREATEX_DISP_OVERWRITE_IF,
1340 0x4044, 0);
1342 torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx,
1343 "First open failed - %s", smbcli_errstr(cli1->tree)));
1345 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1346 SECOND_DESIRED_ACCESS, 0,
1347 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1348 0x200000, 0);
1349 torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
1350 "second open failed - %s", smbcli_errstr(cli1->tree)));
1352 return true;
1355 static bool run_iometer(struct torture_context *tctx,
1356 struct smbcli_state *cli)
1358 const char *fname = "\\iobw.tst";
1359 int fnum;
1360 size_t filesize;
1361 NTSTATUS status;
1362 char buf[2048];
1363 int ops;
1365 memset(buf, 0, sizeof(buf));
1367 status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1368 torture_assert_ntstatus_ok(tctx, status,
1369 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1371 torture_comment(tctx, "size: %d\n", (int)filesize);
1373 filesize -= (sizeof(buf) - 1);
1375 fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1376 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1377 torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s",
1378 smbcli_errstr(cli->tree)));
1380 ops = 0;
1382 while (true) {
1383 int i, num_reads, num_writes;
1385 num_reads = random() % 10;
1386 num_writes = random() % 3;
1388 for (i=0; i<num_reads; i++) {
1389 ssize_t res;
1390 if (ops++ > torture_numops) {
1391 return true;
1393 res = smbcli_read(cli->tree, fnum, buf,
1394 random() % filesize, sizeof(buf));
1395 torture_assert(tctx, res == sizeof(buf),
1396 talloc_asprintf(tctx, "read failed: %s",
1397 smbcli_errstr(cli->tree)));
1399 for (i=0; i<num_writes; i++) {
1400 ssize_t res;
1401 if (ops++ > torture_numops) {
1402 return true;
1404 res = smbcli_write(cli->tree, fnum, 0, buf,
1405 random() % filesize, sizeof(buf));
1406 torture_assert(tctx, res == sizeof(buf),
1407 talloc_asprintf(tctx, "read failed: %s",
1408 smbcli_errstr(cli->tree)));
1414 tries variants of chkpath
1416 static bool torture_chkpath_test(struct torture_context *tctx,
1417 struct smbcli_state *cli)
1419 int fnum;
1420 bool ret;
1422 torture_comment(tctx, "Testing valid and invalid paths\n");
1424 /* cleanup from an old run */
1425 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1426 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1427 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1429 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1430 torture_comment(tctx, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1431 return false;
1434 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1435 torture_comment(tctx, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1436 return false;
1439 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1440 if (fnum == -1) {
1441 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1442 return false;
1444 smbcli_close(cli->tree, fnum);
1446 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1447 torture_comment(tctx, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1448 ret = false;
1451 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1452 torture_comment(tctx, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1453 ret = false;
1456 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1457 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1458 NT_STATUS_NOT_A_DIRECTORY);
1459 } else {
1460 torture_comment(tctx, "* chkpath on a file should fail\n");
1461 ret = false;
1464 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1465 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1466 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1467 } else {
1468 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1469 ret = false;
1472 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1473 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1474 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1475 } else {
1476 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1477 ret = false;
1480 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1481 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1482 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1484 return ret;
1488 * This is a test to excercise some weird Samba3 error paths.
1491 static bool torture_samba3_errorpaths(struct torture_context *tctx)
1493 bool nt_status_support;
1494 struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1495 bool result = false;
1496 int fnum;
1497 const char *os2_fname = ".+,;=[].";
1498 const char *dname = "samba3_errordir";
1499 union smb_open io;
1500 NTSTATUS status;
1502 nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1504 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1505 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1506 goto fail;
1509 if (!torture_open_connection(&cli_nt, tctx, 0)) {
1510 goto fail;
1513 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1514 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1515 goto fail;
1518 if (!torture_open_connection(&cli_dos, tctx, 1)) {
1519 goto fail;
1522 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1523 nt_status_support ? "yes":"no")) {
1524 torture_comment(tctx, "Could not reset 'nt status support = yes'");
1525 goto fail;
1528 smbcli_unlink(cli_nt->tree, os2_fname);
1529 smbcli_rmdir(cli_nt->tree, dname);
1531 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1532 torture_comment(tctx, "smbcli_mkdir(%s) failed: %s\n", dname,
1533 smbcli_errstr(cli_nt->tree));
1534 goto fail;
1537 io.generic.level = RAW_OPEN_NTCREATEX;
1538 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1539 io.ntcreatex.in.root_fid.fnum = 0;
1540 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1541 io.ntcreatex.in.alloc_size = 1024*1024;
1542 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1543 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1544 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1545 io.ntcreatex.in.create_options = 0;
1546 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1547 io.ntcreatex.in.security_flags = 0;
1548 io.ntcreatex.in.fname = dname;
1550 status = smb_raw_open(cli_nt->tree, tctx, &io);
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 = smb_raw_open(cli_dos->tree, tctx, &io);
1558 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1559 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1560 __location__, nt_errstr(status),
1561 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1562 goto fail;
1565 status = smbcli_mkdir(cli_nt->tree, dname);
1566 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1567 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1568 __location__, nt_errstr(status),
1569 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1570 goto fail;
1572 status = smbcli_mkdir(cli_dos->tree, dname);
1573 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1574 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1575 __location__, nt_errstr(status),
1576 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1577 goto fail;
1581 union smb_mkdir md;
1582 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1583 md.t2mkdir.in.path = dname;
1584 md.t2mkdir.in.num_eas = 0;
1585 md.t2mkdir.in.eas = NULL;
1587 status = smb_raw_mkdir(cli_nt->tree, &md);
1588 if (!NT_STATUS_EQUAL(status,
1589 NT_STATUS_OBJECT_NAME_COLLISION)) {
1590 torture_comment(
1591 tctx, "(%s) incorrect status %s should be "
1592 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1593 __location__, nt_errstr(status));
1594 goto fail;
1596 status = smb_raw_mkdir(cli_dos->tree, &md);
1597 if (!NT_STATUS_EQUAL(status,
1598 NT_STATUS_DOS(ERRDOS, ERRrename))) {
1599 torture_comment(tctx, "(%s) incorrect status %s "
1600 "should be ERRDOS:ERRrename\n",
1601 __location__, nt_errstr(status));
1602 goto fail;
1606 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1607 status = smb_raw_open(cli_nt->tree, tctx, &io);
1608 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1609 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1610 __location__, nt_errstr(status),
1611 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1612 goto fail;
1615 status = smb_raw_open(cli_dos->tree, tctx, &io);
1616 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1617 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1618 __location__, nt_errstr(status),
1619 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1620 goto fail;
1624 /* Test an invalid DOS deny mode */
1625 const char *fname = "test.txt";
1627 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1628 if (fnum != -1) {
1629 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1630 "expected failure\n", fname);
1631 smbcli_close(cli_nt->tree, fnum);
1632 goto fail;
1634 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1635 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1636 torture_comment(tctx, "Expected DOS error ERRDOS/ERRbadaccess, "
1637 "got %s\n", smbcli_errstr(cli_nt->tree));
1638 goto fail;
1641 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1642 if (fnum != -1) {
1643 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1644 "expected failure\n", fname);
1645 smbcli_close(cli_nt->tree, fnum);
1646 goto fail;
1648 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1649 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1650 torture_comment(tctx, "Expected DOS error ERRDOS:ERRbadaccess, "
1651 "got %s\n", smbcli_errstr(cli_nt->tree));
1652 goto fail;
1658 * Samba 3.0.23 has a bug that an existing file can be opened
1659 * as a directory using ntcreate&x. Test this.
1662 const char *fname = "\\test_dir.txt";
1664 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1665 DENY_NONE);
1666 if (fnum == -1) {
1667 d_printf("(%s) smbcli_open failed: %s\n", __location__,
1668 smbcli_errstr(cli_nt->tree));
1670 smbcli_close(cli_nt->tree, fnum);
1672 io.generic.level = RAW_OPEN_NTCREATEX;
1673 io.ntcreatex.in.root_fid.fnum = 0;
1674 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1675 io.ntcreatex.in.alloc_size = 0;
1676 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1677 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1678 NTCREATEX_SHARE_ACCESS_WRITE|
1679 NTCREATEX_SHARE_ACCESS_DELETE;
1680 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1681 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1682 io.ntcreatex.in.impersonation =
1683 NTCREATEX_IMPERSONATION_ANONYMOUS;
1684 io.ntcreatex.in.security_flags = 0;
1685 io.ntcreatex.in.fname = fname;
1686 io.ntcreatex.in.flags = 0;
1688 status = smb_raw_open(cli_nt->tree, tctx, &io);
1689 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
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_nt->tree, io.ntcreatex.out.file.fnum);
1700 status = smb_raw_open(cli_dos->tree, tctx, &io);
1701 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1702 ERRbaddirectory))) {
1703 torture_comment(tctx, "ntcreate as dir gave %s, "
1704 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1705 nt_errstr(status));
1706 result = false;
1709 if (NT_STATUS_IS_OK(status)) {
1710 smbcli_close(cli_dos->tree,
1711 io.ntcreatex.out.file.fnum);
1714 smbcli_unlink(cli_nt->tree, fname);
1717 if (!torture_setting_bool(tctx, "samba3", false)) {
1718 goto done;
1721 fnum = smbcli_open(cli_dos->tree, os2_fname,
1722 O_RDWR | O_CREAT | O_TRUNC,
1723 DENY_NONE);
1724 if (fnum != -1) {
1725 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1726 os2_fname);
1727 smbcli_close(cli_dos->tree, fnum);
1728 goto fail;
1731 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1732 NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1733 torture_comment(tctx, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1734 smbcli_errstr(cli_dos->tree));
1735 goto fail;
1738 fnum = smbcli_open(cli_nt->tree, os2_fname,
1739 O_RDWR | O_CREAT | O_TRUNC,
1740 DENY_NONE);
1741 if (fnum != -1) {
1742 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1743 os2_fname);
1744 smbcli_close(cli_nt->tree, fnum);
1745 goto fail;
1748 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1749 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1750 torture_comment(tctx, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1751 "got %s\n", smbcli_errstr(cli_nt->tree));
1752 goto fail;
1755 done:
1756 result = true;
1758 fail:
1759 if (cli_dos != NULL) {
1760 torture_close_connection(cli_dos);
1762 if (cli_nt != NULL) {
1763 torture_close_connection(cli_nt);
1766 return result;
1770 This checks file/dir birthtime
1772 static void list_fn(struct clilist_file_info *finfo, const char *name,
1773 void *state){
1775 /* Just to change dir access time*/
1776 sleep(5);
1780 static bool run_birthtimetest(struct torture_context *tctx,
1781 struct smbcli_state *cli)
1783 int fnum;
1784 size_t size;
1785 time_t c_time, a_time, m_time, w_time, c_time1;
1786 const char *fname = "\\birthtime.tst";
1787 const char *dname = "\\birthtime";
1788 const char *fname2 = "\\birthtime\\birthtime.tst";
1789 bool correct = true;
1790 uint8_t buf[16];
1793 smbcli_unlink(cli->tree, fname);
1795 torture_comment(tctx, "Testing Birthtime for File\n");
1797 /* Save File birthtime/creationtime */
1798 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1799 DENY_NONE);
1800 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1801 &c_time, &a_time, &m_time, NULL, NULL))) {
1802 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n",
1803 smbcli_errstr(cli->tree));
1804 correct = false;
1806 smbcli_close(cli->tree, fnum);
1808 sleep(10);
1810 /* Change in File attribute changes file change time*/
1811 smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1813 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1814 /* Writing updates modification time*/
1815 smbcli_smbwrite(cli->tree, fnum, &fname, 0, sizeof(fname));
1816 /*Reading updates access time */
1817 smbcli_read(cli->tree, fnum, buf, 0, 13);
1818 smbcli_close(cli->tree, fnum);
1820 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1821 &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1822 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1823 smbcli_errstr(cli->tree));
1824 correct = false;
1825 } else {
1826 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1827 (long) c_time, (long) c_time1);
1828 if (c_time1 != c_time) {
1829 torture_comment(tctx, "This system updated file \
1830 birth times! Not expected!\n");
1831 correct = false;
1834 smbcli_unlink(cli->tree, fname);
1836 torture_comment(tctx, "Testing Birthtime for Directory\n");
1838 /* check if the server does not update the directory birth time
1839 when creating a new file */
1840 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1841 torture_comment(tctx, "ERROR: mkdir failed (%s)\n",
1842 smbcli_errstr(cli->tree));
1843 correct = false;
1845 sleep(3);
1846 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1847 &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1848 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1849 smbcli_errstr(cli->tree));
1850 correct = false;
1853 /* Creating a new file changes dir modification time and change time*/
1854 smbcli_unlink(cli->tree, fname2);
1855 fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1856 DENY_NONE);
1857 smbcli_smbwrite(cli->tree, fnum, &fnum, 0, sizeof(fnum));
1858 smbcli_read(cli->tree, fnum, buf, 0, 13);
1859 smbcli_close(cli->tree, fnum);
1861 /* dir listing changes dir access time*/
1862 smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1864 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1865 &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1866 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1867 smbcli_errstr(cli->tree));
1868 correct = false;
1869 } else {
1870 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1871 (long) c_time, (long) c_time1);
1872 if (c_time1 != c_time) {
1873 torture_comment(tctx, "This system updated directory \
1874 birth times! Not Expected!\n");
1875 correct = false;
1878 smbcli_unlink(cli->tree, fname2);
1879 smbcli_rmdir(cli->tree, dname);
1881 return correct;
1885 NTSTATUS torture_base_init(void)
1887 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "base");
1889 torture_suite_add_2smb_test(suite, "fdpass", run_fdpasstest);
1890 torture_suite_add_suite(suite, torture_base_locktest(suite));
1891 torture_suite_add_1smb_test(suite, "unlink", torture_unlinktest);
1892 torture_suite_add_1smb_test(suite, "attr", run_attrtest);
1893 torture_suite_add_1smb_test(suite, "trans2", run_trans2test);
1894 torture_suite_add_1smb_test(suite, "birthtime", run_birthtimetest);
1895 torture_suite_add_simple_test(suite, "negnowait", run_negprot_nowait);
1896 torture_suite_add_1smb_test(suite, "dir1", torture_dirtest1);
1897 torture_suite_add_1smb_test(suite, "dir2", torture_dirtest2);
1898 torture_suite_add_1smb_test(suite, "deny1", torture_denytest1);
1899 torture_suite_add_2smb_test(suite, "deny2", torture_denytest2);
1900 torture_suite_add_2smb_test(suite, "deny3", torture_denytest3);
1901 torture_suite_add_1smb_test(suite, "denydos", torture_denydos_sharing);
1902 torture_suite_add_smb_multi_test(suite, "ntdeny1", torture_ntdenytest1);
1903 torture_suite_add_2smb_test(suite, "ntdeny2", torture_ntdenytest2);
1904 torture_suite_add_1smb_test(suite, "tcon", run_tcon_test);
1905 torture_suite_add_1smb_test(suite, "tcondev", run_tcon_devtype_test);
1906 torture_suite_add_1smb_test(suite, "vuid", run_vuidtest);
1907 torture_suite_add_2smb_test(suite, "rw1", run_readwritetest);
1908 torture_suite_add_2smb_test(suite, "open", run_opentest);
1909 torture_suite_add_smb_multi_test(suite, "defer_open", run_deferopen);
1910 torture_suite_add_1smb_test(suite, "xcopy", run_xcopy);
1911 torture_suite_add_1smb_test(suite, "iometer", run_iometer);
1912 torture_suite_add_1smb_test(suite, "rename", torture_test_rename);
1913 torture_suite_add_suite(suite, torture_test_delete());
1914 torture_suite_add_1smb_test(suite, "properties", torture_test_properties);
1915 torture_suite_add_1smb_test(suite, "mangle", torture_mangle);
1916 torture_suite_add_1smb_test(suite, "openattr", torture_openattrtest);
1917 torture_suite_add_1smb_test(suite, "winattr", torture_winattrtest);
1918 torture_suite_add_suite(suite, torture_charset(suite));
1919 torture_suite_add_1smb_test(suite, "chkpath", torture_chkpath_test);
1920 torture_suite_add_1smb_test(suite, "secleak", torture_sec_leak);
1921 torture_suite_add_simple_test(suite, "disconnect", torture_disconnect);
1922 torture_suite_add_suite(suite, torture_delay_write());
1923 torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths);
1924 torture_suite_add_1smb_test(suite, "casetable", torture_casetable);
1925 torture_suite_add_1smb_test(suite, "utable", torture_utable);
1926 torture_suite_add_simple_test(suite, "smb", torture_smb_scan);
1927 torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1928 torture_suite_add_1smb_test(suite, "trans2-scan", torture_trans2_scan);
1929 torture_suite_add_1smb_test(suite, "nttrans", torture_nttrans_scan);
1930 torture_suite_add_1smb_test(suite, "createx_access", torture_createx_access);
1931 torture_suite_add_2smb_test(suite, "createx_sharemodes_file", torture_createx_sharemodes_file);
1932 torture_suite_add_2smb_test(suite, "createx_sharemodes_dir", torture_createx_sharemodes_dir);
1933 torture_suite_add_1smb_test(suite, "maximum_allowed", torture_maximum_allowed);
1935 torture_suite_add_simple_test(suite, "bench-holdcon", torture_holdcon);
1936 torture_suite_add_1smb_test(suite, "bench-holdopen", torture_holdopen);
1937 torture_suite_add_simple_test(suite, "bench-readwrite", run_benchrw);
1938 torture_suite_add_smb_multi_test(suite, "bench-torture", run_torture);
1939 torture_suite_add_1smb_test(suite, "scan-pipe_number", run_pipe_number);
1940 torture_suite_add_1smb_test(suite, "scan-ioctl", torture_ioctl_test);
1941 torture_suite_add_smb_multi_test(suite, "scan-maxfid", run_maxfidtest);
1943 suite->description = talloc_strdup(suite,
1944 "Basic SMB tests (imported from the original smbtorture)");
1946 torture_register_suite(suite);
1948 return NT_STATUS_OK;