s4:torture - prefer the termination "return"s at the end of two unittests
[Samba/gebeck_regimport.git] / source4 / torture / basic / base.c
blob0e168ed95b52f44cb01270c1f9fa7a95fe2c21be
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_comment(tctx, "smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
816 CHECK_MAX_FAILURES(error_test1);
817 return false;
820 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
821 if (fnum1 == -1) {
822 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
823 CHECK_MAX_FAILURES(error_test1);
824 return false;
827 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
828 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
830 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
831 NT_STATUS_ACCESS_DENIED)) {
832 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
835 torture_comment(tctx, "finished open test 1\n");
836 error_test1:
837 smbcli_close(cli1->tree, fnum1);
839 /* Now try not readonly and ensure ERRbadshare is returned. */
841 smbcli_setatr(cli1->tree, fname, 0, 0);
843 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
844 if (fnum1 == -1) {
845 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
846 return false;
849 /* This will fail - but the error should be ERRshare. */
850 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
852 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
853 NT_STATUS_SHARING_VIOLATION)) {
854 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
857 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
858 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
859 return false;
862 smbcli_unlink(cli1->tree, fname);
864 torture_comment(tctx, "finished open test 2\n");
866 /* Test truncate open disposition on file opened for read. */
868 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
869 if (fnum1 == -1) {
870 torture_comment(tctx, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
871 return false;
874 /* write 20 bytes. */
876 memset(buf, '\0', 20);
878 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
879 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(cli1->tree));
880 correct = false;
883 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
884 torture_comment(tctx, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
885 return false;
888 /* Ensure size == 20. */
889 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
890 torture_comment(tctx, "(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
891 CHECK_MAX_FAILURES(error_test3);
892 return false;
895 if (fsize != 20) {
896 torture_comment(tctx, "(3) file size != 20\n");
897 CHECK_MAX_FAILURES(error_test3);
898 return false;
901 /* Now test if we can truncate a file opened for readonly. */
903 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
904 if (fnum1 == -1) {
905 torture_comment(tctx, "(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
906 CHECK_MAX_FAILURES(error_test3);
907 return false;
910 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
911 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
912 return false;
915 /* Ensure size == 0. */
916 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
917 torture_comment(tctx, "(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
918 CHECK_MAX_FAILURES(error_test3);
919 return false;
922 if (fsize != 0) {
923 torture_comment(tctx, "(3) file size != 0\n");
924 CHECK_MAX_FAILURES(error_test3);
925 return false;
927 torture_comment(tctx, "finished open test 3\n");
928 error_test3:
929 smbcli_unlink(cli1->tree, fname);
932 torture_comment(tctx, "Testing ctemp\n");
933 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
934 if (fnum1 == -1) {
935 torture_comment(tctx, "ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
936 CHECK_MAX_FAILURES(error_test4);
937 return false;
939 torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
940 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
941 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
943 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
944 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
946 error_test4:
947 /* Test the non-io opens... */
949 smbcli_setatr(cli2->tree, fname, 0, 0);
950 smbcli_unlink(cli2->tree, fname);
952 torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
954 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
955 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
957 if (fnum1 == -1) {
958 torture_comment(tctx, "Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
959 CHECK_MAX_FAILURES(error_test10);
960 return false;
963 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
964 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
965 if (fnum2 == -1) {
966 torture_comment(tctx, "Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
967 CHECK_MAX_FAILURES(error_test10);
968 return false;
971 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
972 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
973 return false;
975 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
976 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
977 return false;
980 torture_comment(tctx, "non-io open test #1 passed.\n");
981 error_test10:
982 smbcli_unlink(cli1->tree, fname);
984 torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
986 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
987 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
989 if (fnum1 == -1) {
990 torture_comment(tctx, "Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
991 CHECK_MAX_FAILURES(error_test20);
992 return false;
995 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
996 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
998 if (fnum2 == -1) {
999 torture_comment(tctx, "Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1000 CHECK_MAX_FAILURES(error_test20);
1001 return false;
1004 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1005 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1006 return false;
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(cli1->tree));
1010 return false;
1013 torture_comment(tctx, "non-io open test #2 passed.\n");
1014 error_test20:
1015 smbcli_unlink(cli1->tree, fname);
1017 torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
1019 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1020 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1022 if (fnum1 == -1) {
1023 torture_comment(tctx, "Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1024 CHECK_MAX_FAILURES(error_test30);
1025 return false;
1028 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1029 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1031 if (fnum2 == -1) {
1032 torture_comment(tctx, "Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1033 CHECK_MAX_FAILURES(error_test30);
1034 return false;
1037 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1038 torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1039 return false;
1041 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1042 torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1043 return false;
1046 torture_comment(tctx, "non-io open test #3 passed.\n");
1047 error_test30:
1048 smbcli_unlink(cli1->tree, fname);
1050 torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
1052 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1053 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1055 if (fnum1 == -1) {
1056 torture_comment(tctx, "Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1057 CHECK_MAX_FAILURES(error_test40);
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_comment(tctx, "Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1066 CHECK_MAX_FAILURES(error_test40);
1067 return false;
1070 torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1072 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1073 torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1074 return false;
1077 torture_comment(tctx, "non-io open test #4 passed.\n");
1078 error_test40:
1079 smbcli_unlink(cli1->tree, fname);
1081 torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1083 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1084 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1086 if (fnum1 == -1) {
1087 torture_comment(tctx, "Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1088 CHECK_MAX_FAILURES(error_test50);
1089 return false;
1092 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1093 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1095 if (fnum2 == -1) {
1096 torture_comment(tctx, "Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1097 CHECK_MAX_FAILURES(error_test50);
1098 return false;
1101 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1102 torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1103 return false;
1106 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1107 torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1108 return false;
1111 torture_comment(tctx, "non-io open test #5 passed.\n");
1112 error_test50:
1113 torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
1115 smbcli_unlink(cli1->tree, fname);
1117 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1118 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1120 if (fnum1 == -1) {
1121 torture_comment(tctx, "Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1122 CHECK_MAX_FAILURES(error_test60);
1123 return false;
1126 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1127 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1129 if (fnum2 == -1) {
1130 torture_comment(tctx, "Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1131 CHECK_MAX_FAILURES(error_test60);
1132 return false;
1135 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1136 torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1137 return false;
1140 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1141 torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1142 return false;
1145 torture_comment(tctx, "non-io open test #6 passed.\n");
1146 error_test60:
1147 torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
1149 smbcli_unlink(cli1->tree, fname);
1151 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1152 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1154 if (fnum1 == -1) {
1155 torture_comment(tctx, "Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1156 CHECK_MAX_FAILURES(error_test70);
1157 return false;
1160 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1161 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1163 if (fnum2 != -1) {
1164 torture_comment(tctx, "Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1165 CHECK_MAX_FAILURES(error_test70);
1166 return false;
1169 torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1171 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1172 torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1173 return false;
1176 torture_comment(tctx, "non-io open test #7 passed.\n");
1178 error_test70:
1180 torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1182 smbcli_unlink(cli1->tree, fname);
1184 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1185 if (fnum1 == -1) {
1186 torture_comment(tctx, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1187 return false;
1190 /* write 20 bytes. */
1192 memset(buf, '\0', 20);
1194 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1195 torture_comment(tctx, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1196 correct = false;
1199 /* Ensure size == 20. */
1200 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1201 torture_comment(tctx, "(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1202 CHECK_MAX_FAILURES(error_test80);
1203 return false;
1206 if (fsize != 20) {
1207 torture_comment(tctx, "(8) file size != 20\n");
1208 CHECK_MAX_FAILURES(error_test80);
1209 return false;
1212 /* Get an exclusive lock on the open file. */
1213 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1214 torture_comment(tctx, "(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1215 CHECK_MAX_FAILURES(error_test80);
1216 return false;
1219 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1220 if (fnum1 == -1) {
1221 torture_comment(tctx, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1222 return false;
1225 /* Ensure size == 0. */
1226 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1227 torture_comment(tctx, "(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1228 CHECK_MAX_FAILURES(error_test80);
1229 return false;
1232 if (fsize != 0) {
1233 torture_comment(tctx, "(8) file size != 0\n");
1234 CHECK_MAX_FAILURES(error_test80);
1235 return false;
1238 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1239 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1240 return false;
1243 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1244 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1245 return false;
1248 error_test80:
1250 torture_comment(tctx, "open test #8 passed.\n");
1252 smbcli_unlink(cli1->tree, fname);
1254 return correct;
1257 /* FIRST_DESIRED_ACCESS 0xf019f */
1258 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1259 SEC_FILE_READ_EA| /* 0xf */ \
1260 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1261 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1262 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1263 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1264 /* SECOND_DESIRED_ACCESS 0xe0080 */
1265 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1266 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1267 SEC_STD_WRITE_OWNER /* 0xe0000 */
1269 #if 0
1270 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1271 READ_CONTROL|WRITE_DAC|\
1272 SEC_FILE_READ_DATA|\
1273 WRITE_OWNER /* */
1274 #endif
1279 Test ntcreate calls made by xcopy
1281 static bool run_xcopy(struct torture_context *tctx,
1282 struct smbcli_state *cli1)
1284 const char *fname = "\\test.txt";
1285 int fnum1, fnum2;
1287 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1288 FIRST_DESIRED_ACCESS,
1289 FILE_ATTRIBUTE_ARCHIVE,
1290 NTCREATEX_SHARE_ACCESS_NONE,
1291 NTCREATEX_DISP_OVERWRITE_IF,
1292 0x4044, 0);
1294 torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx,
1295 "First open failed - %s", smbcli_errstr(cli1->tree)));
1297 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1298 SECOND_DESIRED_ACCESS, 0,
1299 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1300 0x200000, 0);
1301 torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
1302 "second open failed - %s", smbcli_errstr(cli1->tree)));
1304 return true;
1307 static bool run_iometer(struct torture_context *tctx,
1308 struct smbcli_state *cli)
1310 const char *fname = "\\iobw.tst";
1311 int fnum;
1312 size_t filesize;
1313 NTSTATUS status;
1314 char buf[2048];
1315 int ops;
1317 memset(buf, 0, sizeof(buf));
1319 status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1320 torture_assert_ntstatus_ok(tctx, status,
1321 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1323 torture_comment(tctx, "size: %d\n", (int)filesize);
1325 filesize -= (sizeof(buf) - 1);
1327 fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1328 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1329 torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s",
1330 smbcli_errstr(cli->tree)));
1332 ops = 0;
1334 while (true) {
1335 int i, num_reads, num_writes;
1337 num_reads = random() % 10;
1338 num_writes = random() % 3;
1340 for (i=0; i<num_reads; i++) {
1341 ssize_t res;
1342 if (ops++ > torture_numops) {
1343 break;
1345 res = smbcli_read(cli->tree, fnum, buf,
1346 random() % filesize, sizeof(buf));
1347 torture_assert(tctx, res == sizeof(buf),
1348 talloc_asprintf(tctx, "read failed: %s",
1349 smbcli_errstr(cli->tree)));
1351 for (i=0; i<num_writes; i++) {
1352 ssize_t res;
1353 if (ops++ > torture_numops) {
1354 break;
1356 res = smbcli_write(cli->tree, fnum, 0, buf,
1357 random() % filesize, sizeof(buf));
1358 torture_assert(tctx, res == sizeof(buf),
1359 talloc_asprintf(tctx, "read failed: %s",
1360 smbcli_errstr(cli->tree)));
1364 return true;
1368 tries variants of chkpath
1370 static bool torture_chkpath_test(struct torture_context *tctx,
1371 struct smbcli_state *cli)
1373 int fnum;
1374 bool ret;
1376 torture_comment(tctx, "Testing valid and invalid paths\n");
1378 /* cleanup from an old run */
1379 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1380 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1381 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1383 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1384 torture_comment(tctx, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1385 return false;
1388 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1389 torture_comment(tctx, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1390 return false;
1393 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1394 if (fnum == -1) {
1395 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1396 return false;
1398 smbcli_close(cli->tree, fnum);
1400 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1401 torture_comment(tctx, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1402 ret = false;
1405 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1406 torture_comment(tctx, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1407 ret = false;
1410 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1411 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1412 NT_STATUS_NOT_A_DIRECTORY);
1413 } else {
1414 torture_comment(tctx, "* chkpath on a file should fail\n");
1415 ret = false;
1418 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1419 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1420 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1421 } else {
1422 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1423 ret = false;
1426 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1427 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1428 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1429 } else {
1430 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1431 ret = false;
1434 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1435 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1436 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1438 return ret;
1442 * This is a test to excercise some weird Samba3 error paths.
1445 static bool torture_samba3_errorpaths(struct torture_context *tctx)
1447 bool nt_status_support;
1448 struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1449 bool result = false;
1450 int fnum;
1451 const char *os2_fname = ".+,;=[].";
1452 const char *dname = "samba3_errordir";
1453 union smb_open io;
1454 NTSTATUS status;
1456 nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1458 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1459 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1460 goto fail;
1463 if (!torture_open_connection(&cli_nt, tctx, 0)) {
1464 goto fail;
1467 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1468 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1469 goto fail;
1472 if (!torture_open_connection(&cli_dos, tctx, 1)) {
1473 goto fail;
1476 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1477 nt_status_support ? "yes":"no")) {
1478 torture_comment(tctx, "Could not reset 'nt status support = yes'");
1479 goto fail;
1482 smbcli_unlink(cli_nt->tree, os2_fname);
1483 smbcli_rmdir(cli_nt->tree, dname);
1485 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1486 torture_comment(tctx, "smbcli_mkdir(%s) failed: %s\n", dname,
1487 smbcli_errstr(cli_nt->tree));
1488 goto fail;
1491 io.generic.level = RAW_OPEN_NTCREATEX;
1492 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1493 io.ntcreatex.in.root_fid.fnum = 0;
1494 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1495 io.ntcreatex.in.alloc_size = 1024*1024;
1496 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1497 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1498 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1499 io.ntcreatex.in.create_options = 0;
1500 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1501 io.ntcreatex.in.security_flags = 0;
1502 io.ntcreatex.in.fname = dname;
1504 status = smb_raw_open(cli_nt->tree, tctx, &io);
1505 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1506 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1507 __location__, nt_errstr(status),
1508 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1509 goto fail;
1511 status = smb_raw_open(cli_dos->tree, tctx, &io);
1512 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1513 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1514 __location__, nt_errstr(status),
1515 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1516 goto fail;
1519 status = smbcli_mkdir(cli_nt->tree, dname);
1520 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1521 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1522 __location__, nt_errstr(status),
1523 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1524 goto fail;
1526 status = smbcli_mkdir(cli_dos->tree, dname);
1527 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1528 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1529 __location__, nt_errstr(status),
1530 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1531 goto fail;
1535 union smb_mkdir md;
1536 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1537 md.t2mkdir.in.path = dname;
1538 md.t2mkdir.in.num_eas = 0;
1539 md.t2mkdir.in.eas = NULL;
1541 status = smb_raw_mkdir(cli_nt->tree, &md);
1542 if (!NT_STATUS_EQUAL(status,
1543 NT_STATUS_OBJECT_NAME_COLLISION)) {
1544 torture_comment(
1545 tctx, "(%s) incorrect status %s should be "
1546 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1547 __location__, nt_errstr(status));
1548 goto fail;
1550 status = smb_raw_mkdir(cli_dos->tree, &md);
1551 if (!NT_STATUS_EQUAL(status,
1552 NT_STATUS_DOS(ERRDOS, ERRrename))) {
1553 torture_comment(tctx, "(%s) incorrect status %s "
1554 "should be ERRDOS:ERRrename\n",
1555 __location__, nt_errstr(status));
1556 goto fail;
1560 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1561 status = smb_raw_open(cli_nt->tree, tctx, &io);
1562 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1563 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1564 __location__, nt_errstr(status),
1565 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1566 goto fail;
1569 status = smb_raw_open(cli_dos->tree, tctx, &io);
1570 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1571 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1572 __location__, nt_errstr(status),
1573 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1574 goto fail;
1578 /* Test an invalid DOS deny mode */
1579 const char *fname = "test.txt";
1581 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1582 if (fnum != -1) {
1583 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1584 "expected failure\n", fname);
1585 smbcli_close(cli_nt->tree, fnum);
1586 goto fail;
1588 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1589 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1590 torture_comment(tctx, "Expected DOS error ERRDOS/ERRbadaccess, "
1591 "got %s\n", smbcli_errstr(cli_nt->tree));
1592 goto fail;
1595 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1596 if (fnum != -1) {
1597 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1598 "expected failure\n", fname);
1599 smbcli_close(cli_nt->tree, fnum);
1600 goto fail;
1602 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1603 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1604 torture_comment(tctx, "Expected DOS error ERRDOS:ERRbadaccess, "
1605 "got %s\n", smbcli_errstr(cli_nt->tree));
1606 goto fail;
1612 * Samba 3.0.23 has a bug that an existing file can be opened
1613 * as a directory using ntcreate&x. Test this.
1616 const char *fname = "\\test_dir.txt";
1618 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1619 DENY_NONE);
1620 if (fnum == -1) {
1621 d_printf("(%s) smbcli_open failed: %s\n", __location__,
1622 smbcli_errstr(cli_nt->tree));
1624 smbcli_close(cli_nt->tree, fnum);
1626 io.generic.level = RAW_OPEN_NTCREATEX;
1627 io.ntcreatex.in.root_fid.fnum = 0;
1628 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1629 io.ntcreatex.in.alloc_size = 0;
1630 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1631 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1632 NTCREATEX_SHARE_ACCESS_WRITE|
1633 NTCREATEX_SHARE_ACCESS_DELETE;
1634 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1635 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1636 io.ntcreatex.in.impersonation =
1637 NTCREATEX_IMPERSONATION_ANONYMOUS;
1638 io.ntcreatex.in.security_flags = 0;
1639 io.ntcreatex.in.fname = fname;
1640 io.ntcreatex.in.flags = 0;
1642 status = smb_raw_open(cli_nt->tree, tctx, &io);
1643 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1644 torture_comment(tctx, "ntcreate as dir gave %s, "
1645 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1646 nt_errstr(status));
1647 result = false;
1650 if (NT_STATUS_IS_OK(status)) {
1651 smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1654 status = smb_raw_open(cli_dos->tree, tctx, &io);
1655 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1656 ERRbaddirectory))) {
1657 torture_comment(tctx, "ntcreate as dir gave %s, "
1658 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1659 nt_errstr(status));
1660 result = false;
1663 if (NT_STATUS_IS_OK(status)) {
1664 smbcli_close(cli_dos->tree,
1665 io.ntcreatex.out.file.fnum);
1668 smbcli_unlink(cli_nt->tree, fname);
1671 if (!torture_setting_bool(tctx, "samba3", false)) {
1672 goto done;
1675 fnum = smbcli_open(cli_dos->tree, os2_fname,
1676 O_RDWR | O_CREAT | O_TRUNC,
1677 DENY_NONE);
1678 if (fnum != -1) {
1679 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1680 os2_fname);
1681 smbcli_close(cli_dos->tree, fnum);
1682 goto fail;
1685 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1686 NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1687 torture_comment(tctx, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1688 smbcli_errstr(cli_dos->tree));
1689 goto fail;
1692 fnum = smbcli_open(cli_nt->tree, os2_fname,
1693 O_RDWR | O_CREAT | O_TRUNC,
1694 DENY_NONE);
1695 if (fnum != -1) {
1696 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1697 os2_fname);
1698 smbcli_close(cli_nt->tree, fnum);
1699 goto fail;
1702 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1703 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1704 torture_comment(tctx, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1705 "got %s\n", smbcli_errstr(cli_nt->tree));
1706 goto fail;
1709 done:
1710 result = true;
1712 fail:
1713 if (cli_dos != NULL) {
1714 torture_close_connection(cli_dos);
1716 if (cli_nt != NULL) {
1717 torture_close_connection(cli_nt);
1720 return result;
1724 This checks file/dir birthtime
1726 static void list_fn(struct clilist_file_info *finfo, const char *name,
1727 void *state){
1729 /* Just to change dir access time*/
1730 sleep(5);
1734 static bool run_birthtimetest(struct torture_context *tctx,
1735 struct smbcli_state *cli)
1737 int fnum;
1738 size_t size;
1739 time_t c_time, a_time, m_time, w_time, c_time1;
1740 const char *fname = "\\birthtime.tst";
1741 const char *dname = "\\birthtime";
1742 const char *fname2 = "\\birthtime\\birthtime.tst";
1743 bool correct = true;
1744 uint8_t buf[16];
1747 smbcli_unlink(cli->tree, fname);
1749 torture_comment(tctx, "Testing Birthtime for File\n");
1751 /* Save File birthtime/creationtime */
1752 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1753 DENY_NONE);
1754 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1755 &c_time, &a_time, &m_time, NULL, NULL))) {
1756 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n",
1757 smbcli_errstr(cli->tree));
1758 correct = false;
1760 smbcli_close(cli->tree, fnum);
1762 sleep(10);
1764 /* Change in File attribute changes file change time*/
1765 smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1767 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1768 /* Writing updates modification time*/
1769 smbcli_smbwrite(cli->tree, fnum, &fname, 0, sizeof(fname));
1770 /*Reading updates access time */
1771 smbcli_read(cli->tree, fnum, buf, 0, 13);
1772 smbcli_close(cli->tree, fnum);
1774 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1775 &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1776 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1777 smbcli_errstr(cli->tree));
1778 correct = false;
1779 } else {
1780 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1781 (long) c_time, (long) c_time1);
1782 if (c_time1 != c_time) {
1783 torture_comment(tctx, "This system updated file \
1784 birth times! Not expected!\n");
1785 correct = false;
1788 smbcli_unlink(cli->tree, fname);
1790 torture_comment(tctx, "Testing Birthtime for Directory\n");
1792 /* check if the server does not update the directory birth time
1793 when creating a new file */
1794 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1795 torture_comment(tctx, "ERROR: mkdir failed (%s)\n",
1796 smbcli_errstr(cli->tree));
1797 correct = false;
1799 sleep(3);
1800 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1801 &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1802 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1803 smbcli_errstr(cli->tree));
1804 correct = false;
1807 /* Creating a new file changes dir modification time and change time*/
1808 smbcli_unlink(cli->tree, fname2);
1809 fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1810 DENY_NONE);
1811 smbcli_smbwrite(cli->tree, fnum, &fnum, 0, sizeof(fnum));
1812 smbcli_read(cli->tree, fnum, buf, 0, 13);
1813 smbcli_close(cli->tree, fnum);
1815 /* dir listing changes dir access time*/
1816 smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1818 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1819 &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1820 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1821 smbcli_errstr(cli->tree));
1822 correct = false;
1823 } else {
1824 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1825 (long) c_time, (long) c_time1);
1826 if (c_time1 != c_time) {
1827 torture_comment(tctx, "This system updated directory \
1828 birth times! Not Expected!\n");
1829 correct = false;
1832 smbcli_unlink(cli->tree, fname2);
1833 smbcli_rmdir(cli->tree, dname);
1835 return correct;
1839 NTSTATUS torture_base_init(void)
1841 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "BASE");
1843 torture_suite_add_2smb_test(suite, "FDPASS", run_fdpasstest);
1844 torture_suite_add_suite(suite, torture_base_locktest(suite));
1845 torture_suite_add_1smb_test(suite, "UNLINK", torture_unlinktest);
1846 torture_suite_add_1smb_test(suite, "ATTR", run_attrtest);
1847 torture_suite_add_1smb_test(suite, "TRANS2", run_trans2test);
1848 torture_suite_add_1smb_test(suite, "BIRTHTIME", run_birthtimetest);
1849 torture_suite_add_simple_test(suite, "NEGNOWAIT", run_negprot_nowait);
1850 torture_suite_add_1smb_test(suite, "DIR1", torture_dirtest1);
1851 torture_suite_add_1smb_test(suite, "DIR2", torture_dirtest2);
1852 torture_suite_add_1smb_test(suite, "DENY1", torture_denytest1);
1853 torture_suite_add_2smb_test(suite, "DENY2", torture_denytest2);
1854 torture_suite_add_2smb_test(suite, "DENY3", torture_denytest3);
1855 torture_suite_add_1smb_test(suite, "DENYDOS", torture_denydos_sharing);
1856 torture_suite_add_smb_multi_test(suite, "NTDENY1", torture_ntdenytest1);
1857 torture_suite_add_2smb_test(suite, "NTDENY2", torture_ntdenytest2);
1858 torture_suite_add_1smb_test(suite, "TCON", run_tcon_test);
1859 torture_suite_add_1smb_test(suite, "TCONDEV", run_tcon_devtype_test);
1860 torture_suite_add_1smb_test(suite, "VUID", run_vuidtest);
1861 torture_suite_add_2smb_test(suite, "RW1", run_readwritetest);
1862 torture_suite_add_2smb_test(suite, "OPEN", run_opentest);
1863 torture_suite_add_smb_multi_test(suite, "DEFER_OPEN", run_deferopen);
1864 torture_suite_add_1smb_test(suite, "XCOPY", run_xcopy);
1865 torture_suite_add_1smb_test(suite, "IOMETER", run_iometer);
1866 torture_suite_add_1smb_test(suite, "RENAME", torture_test_rename);
1867 torture_suite_add_suite(suite, torture_test_delete());
1868 torture_suite_add_1smb_test(suite, "PROPERTIES", torture_test_properties);
1869 torture_suite_add_1smb_test(suite, "MANGLE", torture_mangle);
1870 torture_suite_add_1smb_test(suite, "OPENATTR", torture_openattrtest);
1871 torture_suite_add_1smb_test(suite, "WINATTR", torture_winattrtest);
1872 torture_suite_add_suite(suite, torture_charset(suite));
1873 torture_suite_add_1smb_test(suite, "CHKPATH", torture_chkpath_test);
1874 torture_suite_add_1smb_test(suite, "SECLEAK", torture_sec_leak);
1875 torture_suite_add_simple_test(suite, "DISCONNECT", torture_disconnect);
1876 torture_suite_add_suite(suite, torture_delay_write());
1877 torture_suite_add_simple_test(suite, "SAMBA3ERROR", torture_samba3_errorpaths);
1878 torture_suite_add_1smb_test(suite, "CASETABLE", torture_casetable);
1879 torture_suite_add_1smb_test(suite, "UTABLE", torture_utable);
1880 torture_suite_add_simple_test(suite, "SMB", torture_smb_scan);
1881 torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1882 torture_suite_add_1smb_test(suite, "TRANS2-SCAN", torture_trans2_scan);
1883 torture_suite_add_1smb_test(suite, "NTTRANS", torture_nttrans_scan);
1884 torture_suite_add_1smb_test(suite, "CREATEX_ACCESS", torture_createx_access);
1885 torture_suite_add_2smb_test(suite, "CREATEX_SHAREMODES_FILE", torture_createx_sharemodes_file);
1886 torture_suite_add_2smb_test(suite, "CREATEX_SHAREMODES_DIR", torture_createx_sharemodes_dir);
1887 torture_suite_add_1smb_test(suite, "MAXIMUM_ALLOWED", torture_maximum_allowed);
1889 torture_suite_add_simple_test(suite, "BENCH-HOLDCON", torture_holdcon);
1890 torture_suite_add_1smb_test(suite, "BENCH-HOLDOPEN", torture_holdopen);
1891 torture_suite_add_simple_test(suite, "BENCH-READWRITE", run_benchrw);
1892 torture_suite_add_smb_multi_test(suite, "BENCH-TORTURE", run_torture);
1893 torture_suite_add_1smb_test(suite, "SCAN-PIPE_NUMBER", run_pipe_number);
1894 torture_suite_add_1smb_test(suite, "SCAN-IOCTL", torture_ioctl_test);
1895 torture_suite_add_smb_multi_test(suite, "SCAN-MAXFID", run_maxfidtest);
1897 suite->description = talloc_strdup(suite,
1898 "Basic SMB tests (imported from the original smbtorture)");
1900 torture_register_suite(suite);
1902 return NT_STATUS_OK;