s4:torture - remove unreachable statements to quiet warnings of Solaris "cc"
[Samba/gebeck_regimport.git] / source4 / torture / basic / base.c
blob995357302ba713aa271f308c48c15f073f286c56
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 return true;
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 return true;
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)));
1366 tries variants of chkpath
1368 static bool torture_chkpath_test(struct torture_context *tctx,
1369 struct smbcli_state *cli)
1371 int fnum;
1372 bool ret;
1374 torture_comment(tctx, "Testing valid and invalid paths\n");
1376 /* cleanup from an old run */
1377 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1378 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1379 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1381 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1382 torture_comment(tctx, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1383 return false;
1386 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1387 torture_comment(tctx, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1388 return false;
1391 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1392 if (fnum == -1) {
1393 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1394 return false;
1396 smbcli_close(cli->tree, fnum);
1398 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1399 torture_comment(tctx, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1400 ret = false;
1403 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1404 torture_comment(tctx, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1405 ret = false;
1408 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1409 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1410 NT_STATUS_NOT_A_DIRECTORY);
1411 } else {
1412 torture_comment(tctx, "* chkpath on a file should fail\n");
1413 ret = false;
1416 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1417 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1418 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1419 } else {
1420 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1421 ret = false;
1424 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1425 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1426 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1427 } else {
1428 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1429 ret = false;
1432 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1433 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1434 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1436 return ret;
1440 * This is a test to excercise some weird Samba3 error paths.
1443 static bool torture_samba3_errorpaths(struct torture_context *tctx)
1445 bool nt_status_support;
1446 struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1447 bool result = false;
1448 int fnum;
1449 const char *os2_fname = ".+,;=[].";
1450 const char *dname = "samba3_errordir";
1451 union smb_open io;
1452 NTSTATUS status;
1454 nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1456 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1457 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1458 goto fail;
1461 if (!torture_open_connection(&cli_nt, tctx, 0)) {
1462 goto fail;
1465 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1466 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1467 goto fail;
1470 if (!torture_open_connection(&cli_dos, tctx, 1)) {
1471 goto fail;
1474 if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1475 nt_status_support ? "yes":"no")) {
1476 torture_comment(tctx, "Could not reset 'nt status support = yes'");
1477 goto fail;
1480 smbcli_unlink(cli_nt->tree, os2_fname);
1481 smbcli_rmdir(cli_nt->tree, dname);
1483 if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1484 torture_comment(tctx, "smbcli_mkdir(%s) failed: %s\n", dname,
1485 smbcli_errstr(cli_nt->tree));
1486 goto fail;
1489 io.generic.level = RAW_OPEN_NTCREATEX;
1490 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1491 io.ntcreatex.in.root_fid.fnum = 0;
1492 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1493 io.ntcreatex.in.alloc_size = 1024*1024;
1494 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1495 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1496 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1497 io.ntcreatex.in.create_options = 0;
1498 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1499 io.ntcreatex.in.security_flags = 0;
1500 io.ntcreatex.in.fname = dname;
1502 status = smb_raw_open(cli_nt->tree, tctx, &io);
1503 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1504 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1505 __location__, nt_errstr(status),
1506 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1507 goto fail;
1509 status = smb_raw_open(cli_dos->tree, tctx, &io);
1510 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1511 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1512 __location__, nt_errstr(status),
1513 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1514 goto fail;
1517 status = smbcli_mkdir(cli_nt->tree, dname);
1518 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1519 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1520 __location__, nt_errstr(status),
1521 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1522 goto fail;
1524 status = smbcli_mkdir(cli_dos->tree, dname);
1525 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1526 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1527 __location__, nt_errstr(status),
1528 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1529 goto fail;
1533 union smb_mkdir md;
1534 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1535 md.t2mkdir.in.path = dname;
1536 md.t2mkdir.in.num_eas = 0;
1537 md.t2mkdir.in.eas = NULL;
1539 status = smb_raw_mkdir(cli_nt->tree, &md);
1540 if (!NT_STATUS_EQUAL(status,
1541 NT_STATUS_OBJECT_NAME_COLLISION)) {
1542 torture_comment(
1543 tctx, "(%s) incorrect status %s should be "
1544 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1545 __location__, nt_errstr(status));
1546 goto fail;
1548 status = smb_raw_mkdir(cli_dos->tree, &md);
1549 if (!NT_STATUS_EQUAL(status,
1550 NT_STATUS_DOS(ERRDOS, ERRrename))) {
1551 torture_comment(tctx, "(%s) incorrect status %s "
1552 "should be ERRDOS:ERRrename\n",
1553 __location__, nt_errstr(status));
1554 goto fail;
1558 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1559 status = smb_raw_open(cli_nt->tree, tctx, &io);
1560 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1561 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1562 __location__, nt_errstr(status),
1563 nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1564 goto fail;
1567 status = smb_raw_open(cli_dos->tree, tctx, &io);
1568 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1569 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1570 __location__, nt_errstr(status),
1571 nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1572 goto fail;
1576 /* Test an invalid DOS deny mode */
1577 const char *fname = "test.txt";
1579 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1580 if (fnum != -1) {
1581 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1582 "expected failure\n", fname);
1583 smbcli_close(cli_nt->tree, fnum);
1584 goto fail;
1586 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1587 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1588 torture_comment(tctx, "Expected DOS error ERRDOS/ERRbadaccess, "
1589 "got %s\n", smbcli_errstr(cli_nt->tree));
1590 goto fail;
1593 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1594 if (fnum != -1) {
1595 torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1596 "expected failure\n", fname);
1597 smbcli_close(cli_nt->tree, fnum);
1598 goto fail;
1600 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1601 NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1602 torture_comment(tctx, "Expected DOS error ERRDOS:ERRbadaccess, "
1603 "got %s\n", smbcli_errstr(cli_nt->tree));
1604 goto fail;
1610 * Samba 3.0.23 has a bug that an existing file can be opened
1611 * as a directory using ntcreate&x. Test this.
1614 const char *fname = "\\test_dir.txt";
1616 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1617 DENY_NONE);
1618 if (fnum == -1) {
1619 d_printf("(%s) smbcli_open failed: %s\n", __location__,
1620 smbcli_errstr(cli_nt->tree));
1622 smbcli_close(cli_nt->tree, fnum);
1624 io.generic.level = RAW_OPEN_NTCREATEX;
1625 io.ntcreatex.in.root_fid.fnum = 0;
1626 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1627 io.ntcreatex.in.alloc_size = 0;
1628 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1629 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1630 NTCREATEX_SHARE_ACCESS_WRITE|
1631 NTCREATEX_SHARE_ACCESS_DELETE;
1632 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1633 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1634 io.ntcreatex.in.impersonation =
1635 NTCREATEX_IMPERSONATION_ANONYMOUS;
1636 io.ntcreatex.in.security_flags = 0;
1637 io.ntcreatex.in.fname = fname;
1638 io.ntcreatex.in.flags = 0;
1640 status = smb_raw_open(cli_nt->tree, tctx, &io);
1641 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1642 torture_comment(tctx, "ntcreate as dir gave %s, "
1643 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1644 nt_errstr(status));
1645 result = false;
1648 if (NT_STATUS_IS_OK(status)) {
1649 smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1652 status = smb_raw_open(cli_dos->tree, tctx, &io);
1653 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1654 ERRbaddirectory))) {
1655 torture_comment(tctx, "ntcreate as dir gave %s, "
1656 "expected NT_STATUS_NOT_A_DIRECTORY\n",
1657 nt_errstr(status));
1658 result = false;
1661 if (NT_STATUS_IS_OK(status)) {
1662 smbcli_close(cli_dos->tree,
1663 io.ntcreatex.out.file.fnum);
1666 smbcli_unlink(cli_nt->tree, fname);
1669 if (!torture_setting_bool(tctx, "samba3", false)) {
1670 goto done;
1673 fnum = smbcli_open(cli_dos->tree, os2_fname,
1674 O_RDWR | O_CREAT | O_TRUNC,
1675 DENY_NONE);
1676 if (fnum != -1) {
1677 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1678 os2_fname);
1679 smbcli_close(cli_dos->tree, fnum);
1680 goto fail;
1683 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1684 NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1685 torture_comment(tctx, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1686 smbcli_errstr(cli_dos->tree));
1687 goto fail;
1690 fnum = smbcli_open(cli_nt->tree, os2_fname,
1691 O_RDWR | O_CREAT | O_TRUNC,
1692 DENY_NONE);
1693 if (fnum != -1) {
1694 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1695 os2_fname);
1696 smbcli_close(cli_nt->tree, fnum);
1697 goto fail;
1700 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1701 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1702 torture_comment(tctx, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1703 "got %s\n", smbcli_errstr(cli_nt->tree));
1704 goto fail;
1707 done:
1708 result = true;
1710 fail:
1711 if (cli_dos != NULL) {
1712 torture_close_connection(cli_dos);
1714 if (cli_nt != NULL) {
1715 torture_close_connection(cli_nt);
1718 return result;
1722 This checks file/dir birthtime
1724 static void list_fn(struct clilist_file_info *finfo, const char *name,
1725 void *state){
1727 /* Just to change dir access time*/
1728 sleep(5);
1732 static bool run_birthtimetest(struct torture_context *tctx,
1733 struct smbcli_state *cli)
1735 int fnum;
1736 size_t size;
1737 time_t c_time, a_time, m_time, w_time, c_time1;
1738 const char *fname = "\\birthtime.tst";
1739 const char *dname = "\\birthtime";
1740 const char *fname2 = "\\birthtime\\birthtime.tst";
1741 bool correct = true;
1742 uint8_t buf[16];
1745 smbcli_unlink(cli->tree, fname);
1747 torture_comment(tctx, "Testing Birthtime for File\n");
1749 /* Save File birthtime/creationtime */
1750 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1751 DENY_NONE);
1752 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1753 &c_time, &a_time, &m_time, NULL, NULL))) {
1754 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n",
1755 smbcli_errstr(cli->tree));
1756 correct = false;
1758 smbcli_close(cli->tree, fnum);
1760 sleep(10);
1762 /* Change in File attribute changes file change time*/
1763 smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1765 fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1766 /* Writing updates modification time*/
1767 smbcli_smbwrite(cli->tree, fnum, &fname, 0, sizeof(fname));
1768 /*Reading updates access time */
1769 smbcli_read(cli->tree, fnum, buf, 0, 13);
1770 smbcli_close(cli->tree, fnum);
1772 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1773 &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1774 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1775 smbcli_errstr(cli->tree));
1776 correct = false;
1777 } else {
1778 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1779 (long) c_time, (long) c_time1);
1780 if (c_time1 != c_time) {
1781 torture_comment(tctx, "This system updated file \
1782 birth times! Not expected!\n");
1783 correct = false;
1786 smbcli_unlink(cli->tree, fname);
1788 torture_comment(tctx, "Testing Birthtime for Directory\n");
1790 /* check if the server does not update the directory birth time
1791 when creating a new file */
1792 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1793 torture_comment(tctx, "ERROR: mkdir failed (%s)\n",
1794 smbcli_errstr(cli->tree));
1795 correct = false;
1797 sleep(3);
1798 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1799 &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1800 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1801 smbcli_errstr(cli->tree));
1802 correct = false;
1805 /* Creating a new file changes dir modification time and change time*/
1806 smbcli_unlink(cli->tree, fname2);
1807 fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1808 DENY_NONE);
1809 smbcli_smbwrite(cli->tree, fnum, &fnum, 0, sizeof(fnum));
1810 smbcli_read(cli->tree, fnum, buf, 0, 13);
1811 smbcli_close(cli->tree, fnum);
1813 /* dir listing changes dir access time*/
1814 smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1816 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1817 &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1818 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n",
1819 smbcli_errstr(cli->tree));
1820 correct = false;
1821 } else {
1822 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1823 (long) c_time, (long) c_time1);
1824 if (c_time1 != c_time) {
1825 torture_comment(tctx, "This system updated directory \
1826 birth times! Not Expected!\n");
1827 correct = false;
1830 smbcli_unlink(cli->tree, fname2);
1831 smbcli_rmdir(cli->tree, dname);
1833 return correct;
1837 NTSTATUS torture_base_init(void)
1839 struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "BASE");
1841 torture_suite_add_2smb_test(suite, "FDPASS", run_fdpasstest);
1842 torture_suite_add_suite(suite, torture_base_locktest(suite));
1843 torture_suite_add_1smb_test(suite, "UNLINK", torture_unlinktest);
1844 torture_suite_add_1smb_test(suite, "ATTR", run_attrtest);
1845 torture_suite_add_1smb_test(suite, "TRANS2", run_trans2test);
1846 torture_suite_add_1smb_test(suite, "BIRTHTIME", run_birthtimetest);
1847 torture_suite_add_simple_test(suite, "NEGNOWAIT", run_negprot_nowait);
1848 torture_suite_add_1smb_test(suite, "DIR1", torture_dirtest1);
1849 torture_suite_add_1smb_test(suite, "DIR2", torture_dirtest2);
1850 torture_suite_add_1smb_test(suite, "DENY1", torture_denytest1);
1851 torture_suite_add_2smb_test(suite, "DENY2", torture_denytest2);
1852 torture_suite_add_2smb_test(suite, "DENY3", torture_denytest3);
1853 torture_suite_add_1smb_test(suite, "DENYDOS", torture_denydos_sharing);
1854 torture_suite_add_smb_multi_test(suite, "NTDENY1", torture_ntdenytest1);
1855 torture_suite_add_2smb_test(suite, "NTDENY2", torture_ntdenytest2);
1856 torture_suite_add_1smb_test(suite, "TCON", run_tcon_test);
1857 torture_suite_add_1smb_test(suite, "TCONDEV", run_tcon_devtype_test);
1858 torture_suite_add_1smb_test(suite, "VUID", run_vuidtest);
1859 torture_suite_add_2smb_test(suite, "RW1", run_readwritetest);
1860 torture_suite_add_2smb_test(suite, "OPEN", run_opentest);
1861 torture_suite_add_smb_multi_test(suite, "DEFER_OPEN", run_deferopen);
1862 torture_suite_add_1smb_test(suite, "XCOPY", run_xcopy);
1863 torture_suite_add_1smb_test(suite, "IOMETER", run_iometer);
1864 torture_suite_add_1smb_test(suite, "RENAME", torture_test_rename);
1865 torture_suite_add_suite(suite, torture_test_delete());
1866 torture_suite_add_1smb_test(suite, "PROPERTIES", torture_test_properties);
1867 torture_suite_add_1smb_test(suite, "MANGLE", torture_mangle);
1868 torture_suite_add_1smb_test(suite, "OPENATTR", torture_openattrtest);
1869 torture_suite_add_1smb_test(suite, "WINATTR", torture_winattrtest);
1870 torture_suite_add_suite(suite, torture_charset(suite));
1871 torture_suite_add_1smb_test(suite, "CHKPATH", torture_chkpath_test);
1872 torture_suite_add_1smb_test(suite, "SECLEAK", torture_sec_leak);
1873 torture_suite_add_simple_test(suite, "DISCONNECT", torture_disconnect);
1874 torture_suite_add_suite(suite, torture_delay_write());
1875 torture_suite_add_simple_test(suite, "SAMBA3ERROR", torture_samba3_errorpaths);
1876 torture_suite_add_1smb_test(suite, "CASETABLE", torture_casetable);
1877 torture_suite_add_1smb_test(suite, "UTABLE", torture_utable);
1878 torture_suite_add_simple_test(suite, "SMB", torture_smb_scan);
1879 torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1880 torture_suite_add_1smb_test(suite, "TRANS2-SCAN", torture_trans2_scan);
1881 torture_suite_add_1smb_test(suite, "NTTRANS", torture_nttrans_scan);
1882 torture_suite_add_1smb_test(suite, "CREATEX_ACCESS", torture_createx_access);
1883 torture_suite_add_2smb_test(suite, "CREATEX_SHAREMODES_FILE", torture_createx_sharemodes_file);
1884 torture_suite_add_2smb_test(suite, "CREATEX_SHAREMODES_DIR", torture_createx_sharemodes_dir);
1885 torture_suite_add_1smb_test(suite, "MAXIMUM_ALLOWED", torture_maximum_allowed);
1887 torture_suite_add_simple_test(suite, "BENCH-HOLDCON", torture_holdcon);
1888 torture_suite_add_1smb_test(suite, "BENCH-HOLDOPEN", torture_holdopen);
1889 torture_suite_add_simple_test(suite, "BENCH-READWRITE", run_benchrw);
1890 torture_suite_add_smb_multi_test(suite, "BENCH-TORTURE", run_torture);
1891 torture_suite_add_1smb_test(suite, "SCAN-PIPE_NUMBER", run_pipe_number);
1892 torture_suite_add_1smb_test(suite, "SCAN-IOCTL", torture_ioctl_test);
1893 torture_suite_add_smb_multi_test(suite, "SCAN-MAXFID", run_maxfidtest);
1895 suite->description = talloc_strdup(suite,
1896 "Basic SMB tests (imported from the original smbtorture)");
1898 torture_register_suite(suite);
1900 return NT_STATUS_OK;