Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB torture tester
4 : Copyright (C) Andrew Tridgell 1997-2003
5 : Copyright (C) Jelmer Vernooij 2006
6 :
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.
11 :
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.
16 :
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/>.
19 : */
20 :
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"
32 :
33 :
34 : #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
35 :
36 :
37 6 : static struct smbcli_state *open_nbt_connection(struct torture_context *tctx)
38 : {
39 0 : struct nbt_name called, calling;
40 0 : struct smbcli_state *cli;
41 6 : const char *host = torture_setting_string(tctx, "host", NULL);
42 0 : struct smbcli_options options;
43 0 : bool ok;
44 :
45 6 : make_nbt_name_client(&calling, lpcfg_netbios_name(tctx->lp_ctx));
46 :
47 6 : nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
48 :
49 6 : cli = smbcli_state_init(NULL);
50 6 : if (!cli) {
51 0 : torture_result(tctx, TORTURE_FAIL, "Failed initialize smbcli_struct to connect with %s\n", host);
52 0 : goto failed;
53 : }
54 :
55 6 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
56 :
57 6 : ok = smbcli_socket_connect(cli, host, lpcfg_smb_ports(tctx->lp_ctx),
58 : tctx->ev,
59 : lpcfg_resolve_context(tctx->lp_ctx),
60 : &options,
61 : lpcfg_socket_options(tctx->lp_ctx),
62 : &calling, &called);
63 6 : if (!ok) {
64 0 : torture_result(tctx, TORTURE_FAIL, "Failed to connect with %s\n", host);
65 0 : goto failed;
66 : }
67 :
68 6 : cli->transport = smbcli_transport_init(cli->sock, cli,
69 : true, &cli->options);
70 6 : cli->sock = NULL;
71 6 : if (!cli->transport) {
72 0 : torture_result(tctx, TORTURE_FAIL, "smbcli_transport_init failed\n");
73 0 : goto failed;
74 : }
75 :
76 6 : return cli;
77 :
78 0 : failed:
79 0 : talloc_free(cli);
80 0 : return NULL;
81 : }
82 :
83 70 : static bool tcon_devtest(struct torture_context *tctx,
84 : struct smbcli_state *cli,
85 : const char *myshare, const char *devtype,
86 : NTSTATUS expected_error)
87 : {
88 10 : bool status;
89 70 : const char *password = torture_setting_string(tctx, "password", NULL);
90 :
91 70 : status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
92 : password));
93 :
94 70 : torture_comment(tctx, "Trying share %s with devtype %s\n", myshare, devtype);
95 :
96 70 : if (NT_STATUS_IS_OK(expected_error)) {
97 28 : if (!status) {
98 0 : torture_fail(tctx, talloc_asprintf(tctx,
99 : "tconX to share %s with type %s "
100 : "should have succeeded but failed",
101 : myshare, devtype));
102 : }
103 28 : smbcli_tdis(cli);
104 : } else {
105 42 : if (status) {
106 0 : torture_fail(tctx, talloc_asprintf(tctx,
107 : "tconx to share %s with type %s "
108 : "should have failed but succeeded",
109 : myshare, devtype));
110 : } else {
111 42 : if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
112 : expected_error)) {
113 : } else {
114 0 : torture_fail(tctx, "Returned unexpected error");
115 : }
116 : }
117 : }
118 60 : return true;
119 : }
120 :
121 :
122 :
123 : /**
124 : test whether fnums and tids open on one VC are available on another (a major
125 : security hole)
126 : */
127 6 : static bool run_fdpasstest(struct torture_context *tctx,
128 : struct smbcli_state *cli1,
129 : struct smbcli_state *cli2)
130 : {
131 6 : const char *fname = "\\fdpass.tst";
132 0 : int fnum1, oldtid;
133 0 : uint8_t buf[1024];
134 :
135 6 : smbcli_unlink(cli1->tree, fname);
136 :
137 6 : torture_comment(tctx, "Opening a file on connection 1\n");
138 :
139 6 : fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
140 6 : torture_assert(tctx, fnum1 != -1,
141 : talloc_asprintf(tctx,
142 : "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
143 :
144 6 : torture_comment(tctx, "writing to file on connection 1\n");
145 :
146 6 : torture_assert(tctx,
147 : smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) == 13,
148 : talloc_asprintf(tctx,
149 : "write failed (%s)\n", smbcli_errstr(cli1->tree)));
150 :
151 6 : oldtid = cli2->tree->tid;
152 6 : cli2->session->vuid = cli1->session->vuid;
153 6 : cli2->tree->tid = cli1->tree->tid;
154 6 : cli2->session->pid = cli1->session->pid;
155 :
156 6 : torture_comment(tctx, "reading from file on connection 2\n");
157 :
158 6 : torture_assert(tctx, smbcli_read(cli2->tree, fnum1, buf, 0, 13) != 13,
159 : talloc_asprintf(tctx,
160 : "read succeeded! nasty security hole [%s]\n", buf));
161 :
162 6 : smbcli_close(cli1->tree, fnum1);
163 6 : smbcli_unlink(cli1->tree, fname);
164 :
165 6 : cli2->tree->tid = oldtid;
166 :
167 6 : return true;
168 : }
169 :
170 : /**
171 : This checks how the getatr calls works
172 : */
173 7 : static bool run_attrtest(struct torture_context *tctx,
174 : struct smbcli_state *cli)
175 : {
176 1 : int fnum;
177 1 : time_t t, t2;
178 7 : const char *fname = "\\attrib123456789.tst";
179 7 : bool correct = true;
180 :
181 7 : smbcli_unlink(cli->tree, fname);
182 7 : fnum = smbcli_open(cli->tree, fname,
183 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
184 7 : smbcli_close(cli->tree, fnum);
185 :
186 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
187 0 : torture_result(tctx, TORTURE_FAIL, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
188 0 : correct = false;
189 : }
190 :
191 7 : torture_comment(tctx, "New file time is %s", ctime(&t));
192 :
193 7 : if (labs(t - time(NULL)) > 60*60*24*10) {
194 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: SMBgetatr bug. time is %s",
195 : ctime(&t));
196 0 : t = time(NULL);
197 0 : correct = false;
198 : }
199 :
200 7 : t2 = t-60*60*24; /* 1 day ago */
201 :
202 7 : torture_comment(tctx, "Setting file time to %s", ctime(&t2));
203 :
204 7 : if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
205 0 : torture_comment(tctx, "setatr failed (%s)\n", smbcli_errstr(cli->tree));
206 0 : correct = true;
207 : }
208 :
209 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
210 0 : torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
211 0 : correct = true;
212 : }
213 :
214 7 : torture_comment(tctx, "Retrieved file time as %s", ctime(&t));
215 :
216 7 : if (t != t2) {
217 0 : torture_comment(tctx, "ERROR: getatr/setatr bug. times are\n%s",
218 : ctime(&t));
219 0 : torture_comment(tctx, "%s", ctime(&t2));
220 0 : correct = true;
221 : }
222 :
223 7 : smbcli_unlink(cli->tree, fname);
224 :
225 7 : return correct;
226 : }
227 :
228 : /**
229 : This checks a couple of trans2 calls
230 : */
231 6 : static bool run_trans2test(struct torture_context *tctx,
232 : struct smbcli_state *cli)
233 : {
234 0 : int fnum;
235 0 : size_t size;
236 0 : time_t c_time, a_time, m_time, w_time, m_time2;
237 6 : const char *fname = "\\trans2.tst";
238 6 : const char *dname = "\\trans2";
239 6 : const char *fname2 = "\\trans2\\trans2.tst";
240 0 : const char *pname;
241 6 : bool correct = true;
242 :
243 6 : smbcli_unlink(cli->tree, fname);
244 :
245 6 : torture_comment(tctx, "Testing qfileinfo\n");
246 :
247 6 : fnum = smbcli_open(cli->tree, fname,
248 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
249 6 : if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
250 : NULL, NULL))) {
251 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
252 0 : correct = false;
253 : }
254 :
255 6 : torture_comment(tctx, "Testing NAME_INFO\n");
256 :
257 6 : if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
258 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
259 0 : correct = false;
260 : }
261 :
262 6 : if (!pname || strcmp(pname, fname)) {
263 0 : torture_result(tctx, TORTURE_FAIL, "qfilename gave different name? [%s] [%s]\n",
264 : fname, pname);
265 0 : correct = false;
266 : }
267 :
268 6 : smbcli_close(cli->tree, fnum);
269 6 : smbcli_unlink(cli->tree, fname);
270 :
271 6 : fnum = smbcli_open(cli->tree, fname,
272 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
273 6 : if (fnum == -1) {
274 0 : torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
275 0 : return false;
276 : }
277 6 : smbcli_close(cli->tree, fnum);
278 :
279 6 : torture_comment(tctx, "Checking for sticky create times\n");
280 :
281 6 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
282 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
283 0 : correct = false;
284 : } else {
285 6 : time_t t = time(NULL);
286 :
287 6 : if (c_time != m_time) {
288 0 : torture_comment(tctx, "create time=%s", ctime(&c_time));
289 0 : torture_comment(tctx, "modify time=%s", ctime(&m_time));
290 0 : torture_comment(tctx, "This system appears to have sticky create times\n");
291 : }
292 6 : if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
293 0 : torture_comment(tctx, "access time=%s", ctime(&a_time));
294 0 : torture_result(tctx, TORTURE_FAIL, "This system appears to set a midnight access time\n");
295 0 : correct = false;
296 : }
297 :
298 6 : if (labs(m_time - t) > 60*60*24*7) {
299 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
300 0 : correct = false;
301 : }
302 : }
303 :
304 :
305 6 : smbcli_unlink(cli->tree, fname);
306 6 : fnum = smbcli_open(cli->tree, fname,
307 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
308 6 : smbcli_close(cli->tree, fnum);
309 6 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
310 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
311 0 : correct = false;
312 : } else {
313 6 : if (w_time < 60*60*24*2) {
314 0 : torture_comment(tctx, "write time=%s", ctime(&w_time));
315 0 : torture_result(tctx, TORTURE_FAIL, "This system appears to set a initial 0 write time\n");
316 0 : correct = false;
317 : }
318 : }
319 :
320 6 : smbcli_unlink(cli->tree, fname);
321 :
322 :
323 : /* check if the server updates the directory modification time
324 : when creating a new file */
325 6 : if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
326 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
327 0 : correct = false;
328 : }
329 6 : sleep(3);
330 6 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
331 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
332 0 : correct = false;
333 : }
334 :
335 6 : fnum = smbcli_open(cli->tree, fname2,
336 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
337 6 : smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
338 6 : smbcli_close(cli->tree, fnum);
339 6 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
340 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
341 0 : correct = false;
342 : } else {
343 6 : if (m_time2 == m_time) {
344 0 : torture_result(tctx, TORTURE_FAIL, "This system does not update directory modification times\n");
345 0 : correct = false;
346 : }
347 : }
348 6 : smbcli_unlink(cli->tree, fname2);
349 6 : smbcli_rmdir(cli->tree, dname);
350 :
351 6 : return correct;
352 : }
353 :
354 : /* send smb negprot commands, not reading the response */
355 6 : static bool run_negprot_nowait(struct torture_context *tctx)
356 : {
357 0 : int i;
358 0 : struct smbcli_state *cli, *cli2;
359 6 : bool correct = true;
360 :
361 6 : torture_comment(tctx, "starting negprot nowait test\n");
362 :
363 6 : cli = open_nbt_connection(tctx);
364 6 : if (!cli) {
365 0 : return false;
366 : }
367 :
368 6 : torture_comment(tctx, "Filling send buffer\n");
369 :
370 606 : for (i=0;i<100;i++) {
371 0 : struct tevent_req *req;
372 600 : req = smb_raw_negotiate_send(cli, tctx->ev,
373 : cli->transport,
374 : PROTOCOL_CORE,
375 : PROTOCOL_NT1);
376 600 : tevent_loop_once(tctx->ev);
377 600 : if (!tevent_req_is_in_progress(req)) {
378 0 : NTSTATUS status;
379 :
380 0 : status = smb_raw_negotiate_recv(req);
381 0 : TALLOC_FREE(req);
382 0 : if (i > 0) {
383 0 : torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n",
384 : i+1, nt_errstr(status));
385 0 : break;
386 : } else {
387 0 : torture_result(tctx, TORTURE_FAIL, "Failed to fill pipe - %s \n",
388 : nt_errstr(status));
389 0 : torture_close_connection(cli);
390 0 : return false;
391 : }
392 : }
393 : }
394 :
395 6 : torture_comment(tctx, "Opening secondary connection\n");
396 6 : if (!torture_open_connection(&cli2, tctx, 1)) {
397 0 : torture_result(tctx, TORTURE_FAIL, "Failed to open secondary connection\n");
398 0 : correct = false;
399 : }
400 :
401 6 : if (!torture_close_connection(cli2)) {
402 0 : torture_result(tctx, TORTURE_FAIL, "Failed to close secondary connection\n");
403 0 : correct = false;
404 : }
405 :
406 6 : torture_close_connection(cli);
407 :
408 6 : return correct;
409 : }
410 :
411 : /**
412 : this checks to see if a secondary tconx can use open files from an
413 : earlier tconx
414 : */
415 7 : static bool run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
416 : {
417 7 : const char *fname = "\\tcontest.tmp";
418 1 : int fnum1;
419 1 : uint16_t cnum1, cnum2, cnum3;
420 1 : uint16_t vuid1, vuid2;
421 1 : uint8_t buf[4];
422 7 : bool ret = true;
423 1 : struct smbcli_tree *tree1;
424 7 : const char *host = torture_setting_string(tctx, "host", NULL);
425 7 : const char *share = torture_setting_string(tctx, "share", NULL);
426 7 : const char *password = torture_setting_string(tctx, "password", NULL);
427 :
428 7 : if (smbcli_deltree(cli->tree, fname) == -1) {
429 0 : torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
430 : }
431 :
432 7 : fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
433 7 : if (fnum1 == -1) {
434 0 : torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
435 0 : return false;
436 : }
437 :
438 7 : cnum1 = cli->tree->tid;
439 7 : vuid1 = cli->session->vuid;
440 :
441 7 : memset(buf, 0, 4); /* init buf so valgrind won't complain */
442 7 : if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
443 0 : torture_result(tctx, TORTURE_FAIL, "initial write failed (%s)\n", smbcli_errstr(cli->tree));
444 0 : return false;
445 : }
446 :
447 7 : tree1 = cli->tree; /* save old tree connection */
448 7 : if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
449 0 : torture_result(tctx, TORTURE_FAIL, "%s refused 2nd tree connect (%s)\n", host,
450 : smbcli_errstr(cli->tree));
451 0 : return false;
452 : }
453 :
454 7 : cnum2 = cli->tree->tid;
455 7 : cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
456 7 : vuid2 = cli->session->vuid + 1;
457 :
458 : /* try a write with the wrong tid */
459 7 : cli->tree->tid = cnum2;
460 :
461 7 : if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
462 0 : torture_result(tctx, TORTURE_FAIL, "* server allows write with wrong TID\n");
463 0 : ret = false;
464 : } else {
465 7 : torture_comment(tctx, "server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
466 : }
467 :
468 :
469 : /* try a write with an invalid tid */
470 7 : cli->tree->tid = cnum3;
471 :
472 7 : if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
473 0 : torture_result(tctx, TORTURE_FAIL, "* server allows write with invalid TID\n");
474 0 : ret = false;
475 : } else {
476 7 : torture_comment(tctx, "server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
477 : }
478 :
479 : /* try a write with an invalid vuid */
480 7 : cli->session->vuid = vuid2;
481 7 : cli->tree->tid = cnum1;
482 :
483 7 : if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
484 0 : torture_result(tctx, TORTURE_FAIL, "* server allows write with invalid VUID\n");
485 0 : ret = false;
486 : } else {
487 7 : torture_comment(tctx, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
488 : }
489 :
490 7 : cli->session->vuid = vuid1;
491 7 : cli->tree->tid = cnum1;
492 :
493 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
494 0 : torture_result(tctx, TORTURE_FAIL, "close failed (%s)\n", smbcli_errstr(cli->tree));
495 0 : return false;
496 : }
497 :
498 7 : cli->tree->tid = cnum2;
499 :
500 7 : if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
501 0 : torture_result(tctx, TORTURE_FAIL, "secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
502 0 : return false;
503 : }
504 :
505 7 : cli->tree = tree1; /* restore initial tree */
506 7 : cli->tree->tid = cnum1;
507 :
508 7 : smbcli_unlink(tree1, fname);
509 :
510 7 : return ret;
511 : }
512 :
513 : /**
514 : checks for correct tconX support
515 : */
516 7 : static bool run_tcon_devtype_test(struct torture_context *tctx,
517 : struct smbcli_state *cli1)
518 : {
519 7 : const char *share = torture_setting_string(tctx, "share", NULL);
520 :
521 7 : if (!tcon_devtest(tctx, cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
522 0 : return false;
523 :
524 7 : if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
525 0 : return false;
526 :
527 7 : if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
528 0 : return false;
529 :
530 7 : if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
531 0 : return false;
532 :
533 7 : if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
534 0 : return false;
535 :
536 7 : if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
537 0 : return false;
538 :
539 7 : if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
540 0 : return false;
541 :
542 7 : if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
543 0 : return false;
544 :
545 7 : if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
546 0 : return false;
547 :
548 7 : if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
549 0 : return false;
550 :
551 7 : return true;
552 : }
553 :
554 22 : static bool rw_torture2(struct torture_context *tctx,
555 : struct smbcli_state *c1, struct smbcli_state *c2)
556 : {
557 22 : const char *lockfname = "\\torture2.lck";
558 0 : int fnum1;
559 0 : int fnum2;
560 0 : int i;
561 0 : uint8_t buf[131072];
562 0 : uint8_t buf_rd[131072];
563 22 : bool correct = true;
564 0 : ssize_t bytes_read, bytes_written;
565 :
566 22 : torture_assert(tctx, smbcli_deltree(c1->tree, lockfname) != -1,
567 : talloc_asprintf(tctx,
568 : "unlink failed (%s)", smbcli_errstr(c1->tree)));
569 :
570 22 : fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
571 : DENY_NONE);
572 22 : torture_assert(tctx, fnum1 != -1,
573 : talloc_asprintf(tctx,
574 : "first open read/write of %s failed (%s)",
575 : lockfname, smbcli_errstr(c1->tree)));
576 22 : fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
577 : DENY_NONE);
578 22 : torture_assert(tctx, fnum2 != -1,
579 : talloc_asprintf(tctx,
580 : "second open read-only of %s failed (%s)",
581 : lockfname, smbcli_errstr(c2->tree)));
582 :
583 22 : torture_comment(tctx, "Checking data integrity over %d ops\n",
584 : torture_numops);
585 :
586 242 : for (i=0;i<torture_numops;i++)
587 : {
588 220 : size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
589 220 : if (i % 10 == 0) {
590 22 : if (torture_setting_bool(tctx, "progress", true)) {
591 0 : torture_comment(tctx, "%d\r", i); fflush(stdout);
592 : }
593 : }
594 :
595 220 : generate_random_buffer(buf, buf_size);
596 :
597 220 : if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
598 0 : torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c1->tree));
599 0 : torture_result(tctx, TORTURE_FAIL, "wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
600 0 : correct = false;
601 0 : break;
602 : }
603 :
604 220 : if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
605 0 : torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c2->tree));
606 0 : torture_result(tctx, TORTURE_FAIL, "read %d, expected %d\n", (int)bytes_read, (int)buf_size);
607 0 : correct = false;
608 0 : break;
609 : }
610 :
611 220 : torture_assert_mem_equal(tctx, buf_rd, buf, buf_size,
612 : "read/write compare failed\n");
613 : }
614 :
615 22 : torture_assert_ntstatus_ok(tctx, smbcli_close(c2->tree, fnum2),
616 : talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c2->tree)));
617 22 : torture_assert_ntstatus_ok(tctx, smbcli_close(c1->tree, fnum1),
618 : talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c1->tree)));
619 :
620 22 : torture_assert_ntstatus_ok(tctx, smbcli_unlink(c1->tree, lockfname),
621 : talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(c1->tree)));
622 :
623 22 : torture_comment(tctx, "\n");
624 :
625 22 : return correct;
626 : }
627 :
628 :
629 :
630 11 : static bool run_readwritetest(struct torture_context *tctx,
631 : struct smbcli_state *cli1,
632 : struct smbcli_state *cli2)
633 : {
634 11 : torture_comment(tctx, "Running readwritetest v1\n");
635 11 : if (!rw_torture2(tctx, cli1, cli2))
636 0 : return false;
637 :
638 11 : torture_comment(tctx, "Running readwritetest v2\n");
639 :
640 11 : if (!rw_torture2(tctx, cli1, cli1))
641 0 : return false;
642 :
643 11 : return true;
644 : }
645 :
646 : /*
647 : test the timing of deferred open requests
648 : */
649 0 : static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
650 : {
651 0 : const char *fname = "\\defer_open_test.dat";
652 0 : int i = 0;
653 0 : bool correct = true;
654 0 : int nsec;
655 0 : int msec;
656 0 : double sec;
657 0 : NTSTATUS status;
658 :
659 0 : nsec = torture_setting_int(tctx, "sharedelay", 1000000);
660 0 : msec = nsec / 1000;
661 0 : sec = ((double)nsec) / ((double) 1000000);
662 :
663 0 : torture_comment(tctx, "pid %u: Testing deferred open requests.\n",
664 0 : (unsigned)getpid());
665 :
666 0 : while (i < 4) {
667 0 : int fnum = -1;
668 0 : int j = 1;
669 :
670 0 : do {
671 0 : struct timeval tv;
672 0 : tv = timeval_current();
673 :
674 0 : torture_comment(tctx,
675 : "pid %u: create[%d,%d]...\n",
676 0 : (unsigned)getpid(), i, j);
677 :
678 0 : fnum = smbcli_nt_create_full(cli->tree, fname, 0,
679 : SEC_RIGHTS_FILE_ALL,
680 : FILE_ATTRIBUTE_NORMAL,
681 : NTCREATEX_SHARE_ACCESS_NONE,
682 : NTCREATEX_DISP_OPEN_IF, 0, 0);
683 0 : status = smbcli_nt_error(cli->tree);
684 :
685 0 : torture_comment(tctx,
686 : "pid %u: create[%d,%d] gave fnum %d, status %s\n",
687 0 : (unsigned)getpid(), i, j, fnum,
688 : nt_errstr(status));
689 :
690 0 : if (fnum != -1) {
691 0 : break;
692 : }
693 :
694 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
695 0 : double e = timeval_elapsed(&tv);
696 :
697 0 : torture_comment(tctx, "pid %u: create[%d,%d] "
698 : "time elapsed: %.2f (1 sec = %.2f)\n",
699 0 : (unsigned)getpid(), i, j, e, sec);
700 0 : if (e < (0.5 * sec) || e > ((1.5 * sec) + 1.5)) {
701 0 : torture_comment(tctx, "pid %u: create[%d,%d] "
702 : "timing incorrect\n",
703 0 : (unsigned)getpid(), i, j);
704 0 : torture_result(tctx, TORTURE_FAIL, "Timing incorrect %.2f violation 1 sec == %.2f\n",
705 : e, sec);
706 0 : return false;
707 : }
708 : }
709 :
710 0 : j++;
711 :
712 0 : } while (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
713 :
714 0 : torture_comment(tctx,
715 : "pid %u: create loop %d done: fnum %d, status %s\n",
716 0 : (unsigned)getpid(), i, fnum, nt_errstr(status));
717 :
718 0 : torture_assert(tctx, fnum != -1,
719 : talloc_asprintf(tctx,
720 : "pid %u: Failed to open %s, error=%s\n",
721 : (unsigned)getpid(), fname,
722 : smbcli_errstr(cli->tree)));
723 :
724 0 : torture_comment(tctx, "pid %u: open %d\n", (unsigned)getpid(), i);
725 :
726 0 : smb_msleep(10 * msec);
727 :
728 0 : status = smbcli_close(cli->tree, fnum);
729 :
730 0 : torture_comment(tctx, "pid %u: open %d closed, status %s\n",
731 0 : (unsigned)getpid(), i, nt_errstr(status));
732 :
733 0 : torture_assert(tctx, !NT_STATUS_IS_ERR(status),
734 : talloc_asprintf(tctx,
735 : "pid %u: Failed to close %s, "
736 : "error=%s\n",
737 : (unsigned)getpid(), fname,
738 : smbcli_errstr(cli->tree)));
739 :
740 0 : smb_msleep(2 * msec);
741 :
742 0 : i++;
743 : }
744 :
745 0 : if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
746 : /* All until the last unlink will fail with sharing violation
747 : but also the last request can fail since the file could have
748 : been successfully deleted by another (test) process */
749 0 : status = smbcli_nt_error(cli->tree);
750 0 : if ((!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION))
751 0 : && (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))) {
752 0 : torture_result(tctx, TORTURE_FAIL, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
753 0 : correct = false;
754 : }
755 : }
756 :
757 0 : torture_comment(tctx, "pid %u: deferred test finished\n",
758 0 : (unsigned)getpid());
759 0 : return correct;
760 : }
761 :
762 : /**
763 : Try with a wrong vuid and check error message.
764 : */
765 :
766 6 : static bool run_vuidtest(struct torture_context *tctx,
767 : struct smbcli_state *cli)
768 : {
769 6 : const char *fname = "\\vuid.tst";
770 0 : int fnum;
771 0 : size_t size;
772 0 : time_t c_time, a_time, m_time;
773 :
774 0 : NTSTATUS result;
775 :
776 6 : smbcli_unlink(cli->tree, fname);
777 :
778 6 : fnum = smbcli_open(cli->tree, fname,
779 : O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
780 :
781 6 : cli->session->vuid += 1234;
782 :
783 6 : torture_comment(tctx, "Testing qfileinfo with wrong vuid\n");
784 :
785 6 : if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
786 : &size, &c_time, &a_time,
787 : &m_time, NULL, NULL))) {
788 0 : torture_fail(tctx, "qfileinfo passed with wrong vuid");
789 : }
790 :
791 6 : if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
792 2 : NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
793 2 : !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
794 : NT_STATUS_INVALID_HANDLE)) {
795 0 : torture_fail(tctx, talloc_asprintf(tctx,
796 : "qfileinfo should have returned DOS error "
797 : "ERRSRV:ERRbaduid\n but returned %s",
798 : smbcli_errstr(cli->tree)));
799 : }
800 :
801 6 : cli->session->vuid -= 1234;
802 :
803 6 : torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum),
804 : talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli->tree)));
805 :
806 6 : smbcli_unlink(cli->tree, fname);
807 :
808 6 : return true;
809 : }
810 :
811 : /*
812 : Test open mode returns on read-only files.
813 : */
814 7 : static bool run_opentest(struct torture_context *tctx, struct smbcli_state *cli1,
815 : struct smbcli_state *cli2)
816 : {
817 7 : const char *fname = "\\readonly.file";
818 1 : char *control_char_fname;
819 1 : int fnum1, fnum2;
820 1 : uint8_t buf[20];
821 1 : size_t fsize;
822 7 : bool correct = true;
823 1 : char *tmp_path;
824 7 : int failures = 0;
825 1 : int i;
826 :
827 7 : control_char_fname = talloc_strdup(tctx, "\\readonly.afile");
828 7 : torture_assert_not_null(tctx, control_char_fname, "asprintf failed\n");
829 :
830 224 : for (i = 1; i <= 0x1f; i++) {
831 217 : control_char_fname[10] = i;
832 217 : fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
833 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
834 :
835 217 : if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
836 217 : NT_STATUS_OBJECT_NAME_INVALID)) {
837 0 : torture_result(tctx, TORTURE_FAIL, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
838 : smbcli_errstr(cli1->tree), i);
839 0 : failures++;
840 : }
841 :
842 217 : if (fnum1 != -1) {
843 0 : smbcli_close(cli1->tree, fnum1);
844 : }
845 217 : smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
846 217 : smbcli_unlink(cli1->tree, control_char_fname);
847 : }
848 7 : TALLOC_FREE(control_char_fname);
849 :
850 7 : if (!failures)
851 7 : torture_comment(tctx, "Create file with control char names passed.\n");
852 :
853 7 : smbcli_setatr(cli1->tree, fname, 0, 0);
854 7 : smbcli_unlink(cli1->tree, fname);
855 :
856 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
857 7 : if (fnum1 == -1) {
858 0 : torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
859 0 : return false;
860 : }
861 :
862 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
863 0 : torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
864 0 : return false;
865 : }
866 :
867 7 : if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
868 0 : torture_result(tctx, TORTURE_FAIL,
869 : __location__ ": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
870 0 : CHECK_MAX_FAILURES(error_test1);
871 0 : return false;
872 : }
873 :
874 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
875 7 : if (fnum1 == -1) {
876 0 : torture_result(tctx, TORTURE_FAIL,
877 : __location__ ": open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
878 0 : CHECK_MAX_FAILURES(error_test1);
879 0 : return false;
880 : }
881 :
882 : /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
883 7 : fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
884 :
885 7 : if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
886 7 : NT_STATUS_ACCESS_DENIED)) {
887 5 : torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
888 : }
889 :
890 7 : torture_comment(tctx, "finished open test 1\n");
891 :
892 7 : error_test1:
893 7 : smbcli_close(cli1->tree, fnum1);
894 :
895 : /* Now try not readonly and ensure ERRbadshare is returned. */
896 :
897 7 : smbcli_setatr(cli1->tree, fname, 0, 0);
898 :
899 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
900 7 : if (fnum1 == -1) {
901 0 : torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
902 0 : return false;
903 : }
904 :
905 : /* This will fail - but the error should be ERRshare. */
906 7 : fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
907 :
908 7 : if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
909 7 : NT_STATUS_SHARING_VIOLATION)) {
910 7 : torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
911 : }
912 :
913 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
914 0 : torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
915 0 : return false;
916 : }
917 :
918 7 : smbcli_unlink(cli1->tree, fname);
919 :
920 7 : torture_comment(tctx, "finished open test 2\n");
921 :
922 : /* Test truncate open disposition on file opened for read. */
923 :
924 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
925 7 : if (fnum1 == -1) {
926 0 : torture_result(tctx, TORTURE_FAIL, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
927 0 : return false;
928 : }
929 :
930 : /* write 20 bytes. */
931 :
932 7 : memset(buf, '\0', 20);
933 :
934 7 : if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
935 0 : torture_result(tctx, TORTURE_FAIL, "write failed (%s)\n", smbcli_errstr(cli1->tree));
936 0 : correct = false;
937 : }
938 :
939 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
940 0 : torture_result(tctx, TORTURE_FAIL, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
941 0 : return false;
942 : }
943 :
944 : /* Ensure size == 20. */
945 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
946 0 : torture_result(tctx, TORTURE_FAIL,
947 : __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
948 0 : CHECK_MAX_FAILURES(error_test3);
949 0 : return false;
950 : }
951 :
952 7 : if (fsize != 20) {
953 0 : torture_result(tctx, TORTURE_FAIL,
954 : __location__ ": (3) file size != 20\n");
955 0 : CHECK_MAX_FAILURES(error_test3);
956 0 : return false;
957 : }
958 :
959 : /* Now test if we can truncate a file opened for readonly. */
960 :
961 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
962 7 : if (fnum1 == -1) {
963 0 : torture_result(tctx, TORTURE_FAIL,
964 : __location__ ": (3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
965 0 : CHECK_MAX_FAILURES(error_test3);
966 0 : return false;
967 : }
968 :
969 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
970 0 : torture_result(tctx, TORTURE_FAIL,
971 : __location__ ": close2 failed (%s)\n", smbcli_errstr(cli1->tree));
972 0 : return false;
973 : }
974 :
975 : /* Ensure size == 0. */
976 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
977 0 : torture_result(tctx, TORTURE_FAIL,
978 : __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
979 0 : CHECK_MAX_FAILURES(error_test3);
980 0 : return false;
981 : }
982 :
983 7 : if (fsize != 0) {
984 0 : torture_result(tctx, TORTURE_FAIL,
985 : __location__ ": (3) file size != 0\n");
986 0 : CHECK_MAX_FAILURES(error_test3);
987 0 : return false;
988 : }
989 7 : torture_comment(tctx, "finished open test 3\n");
990 7 : error_test3:
991 :
992 7 : fnum1 = fnum2 = -1;
993 7 : smbcli_unlink(cli1->tree, fname);
994 :
995 :
996 7 : torture_comment(tctx, "Testing ctemp\n");
997 7 : fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
998 7 : if (fnum1 == -1) {
999 0 : torture_result(tctx, TORTURE_FAIL,
1000 : __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1001 0 : CHECK_MAX_FAILURES(error_test4);
1002 0 : return false;
1003 : }
1004 7 : torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
1005 :
1006 7 : error_test4:
1007 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1008 0 : torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1009 : }
1010 7 : if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1011 0 : torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1012 : }
1013 :
1014 : /* Test the non-io opens... */
1015 :
1016 7 : torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
1017 7 : fnum1 = fnum2 = -1;
1018 7 : smbcli_setatr(cli2->tree, fname, 0, 0);
1019 7 : smbcli_unlink(cli2->tree, fname);
1020 :
1021 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1022 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1023 :
1024 7 : if (fnum1 == -1) {
1025 0 : torture_result(tctx, TORTURE_FAIL,
1026 : __location__ ": Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1027 0 : CHECK_MAX_FAILURES(error_test10);
1028 0 : return false;
1029 : }
1030 :
1031 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1032 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1033 7 : if (fnum2 == -1) {
1034 0 : torture_result(tctx, TORTURE_FAIL,
1035 : __location__ ": Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1036 0 : CHECK_MAX_FAILURES(error_test10);
1037 0 : return false;
1038 : }
1039 :
1040 7 : torture_comment(tctx, "non-io open test #1 passed.\n");
1041 7 : error_test10:
1042 :
1043 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1044 0 : torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1045 : }
1046 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1047 0 : torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1048 : }
1049 :
1050 7 : torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
1051 7 : fnum1 = fnum2 = -1;
1052 7 : smbcli_unlink(cli1->tree, fname);
1053 :
1054 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1055 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1056 :
1057 7 : if (fnum1 == -1) {
1058 0 : torture_result(tctx, TORTURE_FAIL,
1059 : __location__ ": Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1060 0 : CHECK_MAX_FAILURES(error_test20);
1061 0 : return false;
1062 : }
1063 :
1064 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1065 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1066 :
1067 7 : if (fnum2 == -1) {
1068 0 : torture_result(tctx, TORTURE_FAIL,
1069 : __location__ ": Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1070 0 : CHECK_MAX_FAILURES(error_test20);
1071 0 : return false;
1072 : }
1073 :
1074 7 : torture_comment(tctx, "non-io open test #2 passed.\n");
1075 7 : error_test20:
1076 :
1077 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1078 0 : torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1079 : }
1080 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1081 0 : torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1082 : }
1083 :
1084 7 : fnum1 = fnum2 = -1;
1085 7 : smbcli_unlink(cli1->tree, fname);
1086 :
1087 7 : torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
1088 :
1089 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1090 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1091 :
1092 7 : if (fnum1 == -1) {
1093 0 : torture_result(tctx, TORTURE_FAIL,
1094 : __location__ ": Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1095 0 : CHECK_MAX_FAILURES(error_test30);
1096 0 : return false;
1097 : }
1098 :
1099 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1100 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1101 :
1102 7 : if (fnum2 == -1) {
1103 0 : torture_result(tctx, TORTURE_FAIL,
1104 : __location__ ": Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1105 0 : CHECK_MAX_FAILURES(error_test30);
1106 0 : return false;
1107 : }
1108 :
1109 7 : torture_comment(tctx, "non-io open test #3 passed.\n");
1110 7 : error_test30:
1111 :
1112 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1113 0 : torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1114 : }
1115 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1116 0 : torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1117 : }
1118 :
1119 7 : torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
1120 7 : fnum1 = fnum2 = -1;
1121 7 : smbcli_unlink(cli1->tree, fname);
1122 :
1123 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1124 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1125 :
1126 7 : if (fnum1 == -1) {
1127 0 : torture_result(tctx, TORTURE_FAIL,
1128 : __location__ ": Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1129 0 : CHECK_MAX_FAILURES(error_test40);
1130 0 : return false;
1131 : }
1132 :
1133 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1134 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1135 :
1136 7 : if (fnum2 != -1) {
1137 0 : torture_result(tctx, TORTURE_FAIL,
1138 : __location__ ": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1139 0 : CHECK_MAX_FAILURES(error_test40);
1140 0 : return false;
1141 : }
1142 :
1143 7 : torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1144 :
1145 7 : torture_comment(tctx, "non-io open test #4 passed.\n");
1146 7 : error_test40:
1147 :
1148 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1149 0 : torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1150 : }
1151 7 : if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1152 0 : torture_comment(tctx, "Test 4 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1153 : }
1154 :
1155 7 : torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1156 7 : fnum1 = fnum2 = -1;
1157 7 : smbcli_unlink(cli1->tree, fname);
1158 :
1159 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1160 : NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1161 :
1162 7 : if (fnum1 == -1) {
1163 0 : torture_result(tctx, TORTURE_FAIL,
1164 : __location__ ": Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1165 0 : CHECK_MAX_FAILURES(error_test50);
1166 0 : return false;
1167 : }
1168 :
1169 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1170 : NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1171 :
1172 7 : if (fnum2 == -1) {
1173 0 : torture_result(tctx, TORTURE_FAIL,
1174 : __location__ ": Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1175 0 : CHECK_MAX_FAILURES(error_test50);
1176 0 : return false;
1177 : }
1178 :
1179 7 : torture_comment(tctx, "non-io open test #5 passed.\n");
1180 7 : error_test50:
1181 :
1182 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1183 0 : torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1184 : }
1185 :
1186 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1187 0 : torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1188 : }
1189 :
1190 7 : torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
1191 7 : fnum1 = fnum2 = -1;
1192 7 : smbcli_unlink(cli1->tree, fname);
1193 :
1194 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1195 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1196 :
1197 7 : if (fnum1 == -1) {
1198 0 : torture_result(tctx, TORTURE_FAIL,
1199 : __location__ ": Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1200 0 : CHECK_MAX_FAILURES(error_test60);
1201 0 : return false;
1202 : }
1203 :
1204 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1205 : NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1206 :
1207 7 : if (fnum2 == -1) {
1208 0 : torture_result(tctx, TORTURE_FAIL,
1209 : __location__ ": Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1210 0 : CHECK_MAX_FAILURES(error_test60);
1211 0 : return false;
1212 : }
1213 :
1214 7 : torture_comment(tctx, "non-io open test #6 passed.\n");
1215 7 : error_test60:
1216 :
1217 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1218 0 : torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1219 : }
1220 :
1221 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1222 0 : torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1223 : }
1224 :
1225 7 : torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
1226 7 : fnum1 = fnum2 = -1;
1227 7 : smbcli_unlink(cli1->tree, fname);
1228 :
1229 7 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1230 : NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1231 :
1232 7 : if (fnum1 == -1) {
1233 0 : torture_result(tctx, TORTURE_FAIL,
1234 : __location__ ": Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1235 0 : CHECK_MAX_FAILURES(error_test70);
1236 0 : return false;
1237 : }
1238 :
1239 7 : fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1240 : NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1241 :
1242 7 : if (fnum2 != -1) {
1243 0 : torture_result(tctx, TORTURE_FAIL,
1244 : __location__ ": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1245 0 : CHECK_MAX_FAILURES(error_test70);
1246 0 : return false;
1247 : }
1248 :
1249 7 : torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1250 :
1251 7 : torture_comment(tctx, "non-io open test #7 passed.\n");
1252 7 : error_test70:
1253 :
1254 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1255 0 : torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1256 : }
1257 7 : if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1258 0 : torture_comment(tctx, "Test 7 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1259 : }
1260 :
1261 7 : torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1262 7 : fnum1 = fnum2 = -1;
1263 7 : smbcli_unlink(cli1->tree, fname);
1264 :
1265 7 : fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1266 7 : if (fnum1 == -1) {
1267 0 : torture_result(tctx, TORTURE_FAIL, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1268 0 : return false;
1269 : }
1270 :
1271 : /* write 20 bytes. */
1272 :
1273 7 : memset(buf, '\0', 20);
1274 :
1275 7 : if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1276 0 : torture_result(tctx, TORTURE_FAIL, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1277 0 : correct = false;
1278 : }
1279 :
1280 : /* Ensure size == 20. */
1281 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1282 0 : torture_result(tctx, TORTURE_FAIL,
1283 : __location__ ": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1284 0 : CHECK_MAX_FAILURES(error_test80);
1285 0 : return false;
1286 : }
1287 :
1288 7 : if (fsize != 20) {
1289 0 : torture_result(tctx, TORTURE_FAIL,
1290 : __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
1291 0 : CHECK_MAX_FAILURES(error_test80);
1292 0 : return false;
1293 : }
1294 :
1295 : /* Get an exclusive lock on the open file. */
1296 7 : if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1297 0 : torture_result(tctx, TORTURE_FAIL,
1298 : __location__ ": (8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1299 0 : CHECK_MAX_FAILURES(error_test80);
1300 0 : return false;
1301 : }
1302 :
1303 7 : fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1304 7 : if (fnum1 == -1) {
1305 0 : torture_result(tctx, TORTURE_FAIL, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1306 0 : return false;
1307 : }
1308 :
1309 : /* Ensure size == 0. */
1310 7 : if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1311 0 : torture_result(tctx, TORTURE_FAIL,
1312 : __location__ ": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1313 0 : CHECK_MAX_FAILURES(error_test80);
1314 0 : return false;
1315 : }
1316 :
1317 7 : if (fsize != 0) {
1318 0 : torture_result(tctx, TORTURE_FAIL,
1319 : __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
1320 0 : CHECK_MAX_FAILURES(error_test80);
1321 0 : return false;
1322 : }
1323 :
1324 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1325 0 : torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1326 0 : return false;
1327 : }
1328 :
1329 7 : if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1330 0 : torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1331 0 : return false;
1332 : }
1333 :
1334 7 : error_test80:
1335 :
1336 7 : torture_comment(tctx, "open test #8 passed.\n");
1337 :
1338 7 : smbcli_unlink(cli1->tree, fname);
1339 :
1340 7 : return failures > 0 ? false : correct;
1341 : }
1342 :
1343 : /* FIRST_DESIRED_ACCESS 0xf019f */
1344 : #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1345 : SEC_FILE_READ_EA| /* 0xf */ \
1346 : SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1347 : SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1348 : SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1349 : SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1350 : /* SECOND_DESIRED_ACCESS 0xe0080 */
1351 : #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1352 : SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1353 : SEC_STD_WRITE_OWNER /* 0xe0000 */
1354 :
1355 : #if 0
1356 : #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1357 : READ_CONTROL|WRITE_DAC|\
1358 : SEC_FILE_READ_DATA|\
1359 : WRITE_OWNER /* */
1360 : #endif
1361 :
1362 :
1363 :
1364 : /**
1365 : Test ntcreate calls made by xcopy
1366 : */
1367 30 : static bool run_xcopy(struct torture_context *tctx,
1368 : struct smbcli_state *cli1)
1369 : {
1370 30 : const char *fname = "\\test.txt";
1371 0 : int fnum1, fnum2;
1372 :
1373 30 : fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1374 : FIRST_DESIRED_ACCESS,
1375 : FILE_ATTRIBUTE_ARCHIVE,
1376 : NTCREATEX_SHARE_ACCESS_NONE,
1377 : NTCREATEX_DISP_OVERWRITE_IF,
1378 : 0x4044, 0);
1379 :
1380 30 : torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx,
1381 : "First open failed - %s", smbcli_errstr(cli1->tree)));
1382 :
1383 30 : fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1384 : SECOND_DESIRED_ACCESS, 0,
1385 : NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1386 : 0x200000, 0);
1387 30 : torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
1388 : "second open failed - %s", smbcli_errstr(cli1->tree)));
1389 :
1390 30 : return true;
1391 : }
1392 :
1393 0 : static bool run_iometer(struct torture_context *tctx,
1394 : struct smbcli_state *cli)
1395 : {
1396 0 : const char *fname = "\\iobw.tst";
1397 0 : int fnum;
1398 0 : size_t filesize;
1399 0 : NTSTATUS status;
1400 0 : char buf[2048];
1401 0 : int ops;
1402 :
1403 0 : memset(buf, 0, sizeof(buf));
1404 :
1405 0 : status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1406 0 : torture_assert_ntstatus_ok(tctx, status,
1407 : talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1408 :
1409 0 : torture_comment(tctx, "size: %d\n", (int)filesize);
1410 :
1411 0 : filesize -= (sizeof(buf) - 1);
1412 :
1413 0 : fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1414 : 0x2019f, 0, 0x3, 3, 0x42, 0x3);
1415 0 : torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s",
1416 : smbcli_errstr(cli->tree)));
1417 :
1418 0 : ops = 0;
1419 :
1420 0 : while (true) {
1421 0 : int i, num_reads, num_writes;
1422 :
1423 0 : num_reads = random() % 10;
1424 0 : num_writes = random() % 3;
1425 :
1426 0 : for (i=0; i<num_reads; i++) {
1427 0 : ssize_t res;
1428 0 : if (ops++ > torture_numops) {
1429 0 : return true;
1430 : }
1431 0 : res = smbcli_read(cli->tree, fnum, buf,
1432 0 : random() % filesize, sizeof(buf));
1433 0 : torture_assert(tctx, res == sizeof(buf),
1434 : talloc_asprintf(tctx, "read failed: %s",
1435 : smbcli_errstr(cli->tree)));
1436 : }
1437 0 : for (i=0; i<num_writes; i++) {
1438 0 : ssize_t res;
1439 0 : if (ops++ > torture_numops) {
1440 0 : return true;
1441 : }
1442 0 : res = smbcli_write(cli->tree, fnum, 0, buf,
1443 0 : random() % filesize, sizeof(buf));
1444 0 : torture_assert(tctx, res == sizeof(buf),
1445 : talloc_asprintf(tctx, "read failed: %s",
1446 : smbcli_errstr(cli->tree)));
1447 : }
1448 : }
1449 : }
1450 :
1451 : /**
1452 : tries variants of chkpath
1453 : */
1454 7 : static bool torture_chkpath_test(struct torture_context *tctx,
1455 : struct smbcli_state *cli)
1456 : {
1457 1 : int fnum;
1458 1 : bool ret;
1459 :
1460 7 : torture_comment(tctx, "Testing valid and invalid paths\n");
1461 :
1462 : /* cleanup from an old run */
1463 7 : smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1464 7 : smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*");
1465 7 : smbcli_rmdir(cli->tree, "\\chkpath.dir");
1466 :
1467 7 : if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1468 0 : torture_result(tctx, TORTURE_FAIL, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1469 0 : return false;
1470 : }
1471 :
1472 7 : if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1473 0 : torture_result(tctx, TORTURE_FAIL, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1474 0 : return false;
1475 : }
1476 :
1477 7 : fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1478 7 : if (fnum == -1) {
1479 0 : torture_result(tctx, TORTURE_FAIL, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1480 0 : return false;
1481 : }
1482 7 : smbcli_close(cli->tree, fnum);
1483 :
1484 7 : if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1485 0 : torture_result(tctx, TORTURE_FAIL, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1486 0 : ret = false;
1487 : }
1488 :
1489 7 : if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1490 0 : torture_result(tctx, TORTURE_FAIL, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1491 0 : ret = false;
1492 : }
1493 :
1494 7 : if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1495 7 : ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1496 7 : NT_STATUS_NOT_A_DIRECTORY);
1497 : } else {
1498 0 : torture_result(tctx, TORTURE_FAIL, "* chkpath on a file should fail\n");
1499 0 : ret = false;
1500 : }
1501 :
1502 7 : if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1503 7 : ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1504 7 : NT_STATUS_OBJECT_NAME_NOT_FOUND);
1505 : } else {
1506 0 : torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent file should fail\n");
1507 0 : ret = false;
1508 : }
1509 :
1510 7 : if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1511 7 : ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1512 7 : NT_STATUS_OBJECT_PATH_NOT_FOUND);
1513 : } else {
1514 0 : torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent component should fail\n");
1515 0 : ret = false;
1516 : }
1517 :
1518 7 : smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1519 7 : smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*");
1520 7 : smbcli_rmdir(cli->tree, "\\chkpath.dir");
1521 :
1522 7 : return ret;
1523 : }
1524 :
1525 : /*
1526 : * This is a test to exercise some weird Samba3 error paths.
1527 : */
1528 :
1529 4 : static bool torture_samba3_errorpaths(struct torture_context *tctx)
1530 : {
1531 0 : bool nt_status_support;
1532 0 : bool client_ntlmv2_auth;
1533 4 : struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1534 4 : bool result = false;
1535 0 : int fnum;
1536 4 : const char *os2_fname = ".+,;=[].";
1537 4 : const char *dname = "samba3_errordir";
1538 0 : union smb_open io;
1539 0 : NTSTATUS status;
1540 :
1541 4 : nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1542 4 : client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx);
1543 :
1544 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1545 0 : torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n");
1546 0 : goto fail;
1547 : }
1548 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) {
1549 0 : torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n");
1550 0 : goto fail;
1551 : }
1552 :
1553 4 : if (!torture_open_connection(&cli_nt, tctx, 0)) {
1554 0 : goto fail;
1555 : }
1556 :
1557 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1558 0 : torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n");
1559 0 : goto fail;
1560 : }
1561 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) {
1562 0 : torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n");
1563 0 : goto fail;
1564 : }
1565 :
1566 4 : if (!torture_open_connection(&cli_dos, tctx, 1)) {
1567 0 : goto fail;
1568 : }
1569 :
1570 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1571 : nt_status_support ? "yes":"no")) {
1572 0 : torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'");
1573 0 : goto fail;
1574 : }
1575 4 : if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth",
1576 : client_ntlmv2_auth ? "yes":"no")) {
1577 0 : torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'");
1578 0 : goto fail;
1579 : }
1580 :
1581 4 : smbcli_unlink(cli_nt->tree, os2_fname);
1582 4 : smbcli_rmdir(cli_nt->tree, dname);
1583 :
1584 4 : if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1585 0 : torture_result(tctx, TORTURE_FAIL, "smbcli_mkdir(%s) failed: %s\n", dname,
1586 0 : smbcli_errstr(cli_nt->tree));
1587 0 : goto fail;
1588 : }
1589 :
1590 4 : io.generic.level = RAW_OPEN_NTCREATEX;
1591 4 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1592 4 : io.ntcreatex.in.root_fid.fnum = 0;
1593 4 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1594 4 : io.ntcreatex.in.alloc_size = 1024*1024;
1595 4 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1596 4 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1597 4 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1598 4 : io.ntcreatex.in.create_options = 0;
1599 4 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1600 4 : io.ntcreatex.in.security_flags = 0;
1601 4 : io.ntcreatex.in.fname = dname;
1602 :
1603 4 : status = smb_raw_open(cli_nt->tree, tctx, &io);
1604 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1605 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1606 : __location__, nt_errstr(status),
1607 0 : nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1608 0 : goto fail;
1609 : }
1610 4 : status = smb_raw_open(cli_dos->tree, tctx, &io);
1611 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1612 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1613 : __location__, nt_errstr(status),
1614 0 : nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1615 0 : goto fail;
1616 : }
1617 :
1618 4 : status = smbcli_mkdir(cli_nt->tree, dname);
1619 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1620 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1621 : __location__, nt_errstr(status),
1622 0 : nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1623 0 : goto fail;
1624 : }
1625 4 : status = smbcli_mkdir(cli_dos->tree, dname);
1626 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1627 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1628 : __location__, nt_errstr(status),
1629 0 : nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1630 0 : goto fail;
1631 : }
1632 :
1633 : {
1634 0 : union smb_mkdir md;
1635 4 : md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1636 4 : md.t2mkdir.in.path = dname;
1637 4 : md.t2mkdir.in.num_eas = 0;
1638 4 : md.t2mkdir.in.eas = NULL;
1639 :
1640 4 : status = smb_raw_mkdir(cli_nt->tree, &md);
1641 4 : if (!NT_STATUS_EQUAL(status,
1642 : NT_STATUS_OBJECT_NAME_COLLISION)) {
1643 0 : torture_comment(
1644 : tctx, "(%s) incorrect status %s should be "
1645 : "NT_STATUS_OBJECT_NAME_COLLISION\n",
1646 : __location__, nt_errstr(status));
1647 0 : goto fail;
1648 : }
1649 4 : status = smb_raw_mkdir(cli_dos->tree, &md);
1650 4 : if (!NT_STATUS_EQUAL(status,
1651 : NT_STATUS_DOS(ERRDOS, ERRrename))) {
1652 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s "
1653 : "should be ERRDOS:ERRrename\n",
1654 : __location__, nt_errstr(status));
1655 0 : goto fail;
1656 : }
1657 : }
1658 :
1659 4 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1660 4 : status = smb_raw_open(cli_nt->tree, tctx, &io);
1661 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1662 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1663 : __location__, nt_errstr(status),
1664 0 : nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1665 0 : goto fail;
1666 : }
1667 :
1668 4 : status = smb_raw_open(cli_dos->tree, tctx, &io);
1669 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1670 0 : torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1671 : __location__, nt_errstr(status),
1672 0 : nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1673 0 : goto fail;
1674 : }
1675 :
1676 : {
1677 : /* Test an invalid DOS deny mode */
1678 4 : const char *fname = "test.txt";
1679 :
1680 4 : fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1681 4 : if (fnum != -1) {
1682 0 : torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
1683 : "expected failure\n", fname);
1684 0 : smbcli_close(cli_nt->tree, fnum);
1685 0 : goto fail;
1686 : }
1687 4 : if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1688 : NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1689 0 : torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRbadaccess, "
1690 0 : "got %s\n", smbcli_errstr(cli_nt->tree));
1691 0 : goto fail;
1692 : }
1693 :
1694 4 : fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1695 4 : if (fnum != -1) {
1696 0 : torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
1697 : "expected failure\n", fname);
1698 0 : smbcli_close(cli_nt->tree, fnum);
1699 0 : goto fail;
1700 : }
1701 4 : if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1702 : NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1703 0 : torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS:ERRbadaccess, "
1704 0 : "got %s\n", smbcli_errstr(cli_nt->tree));
1705 0 : goto fail;
1706 : }
1707 : }
1708 :
1709 : {
1710 : /*
1711 : * Samba 3.0.23 has a bug that an existing file can be opened
1712 : * as a directory using ntcreate&x. Test this.
1713 : */
1714 :
1715 4 : const char *fname = "\\test_dir.txt";
1716 :
1717 4 : fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1718 : DENY_NONE);
1719 4 : if (fnum == -1) {
1720 0 : d_printf("(%s) smbcli_open failed: %s\n", __location__,
1721 0 : smbcli_errstr(cli_nt->tree));
1722 : }
1723 4 : smbcli_close(cli_nt->tree, fnum);
1724 :
1725 4 : io.generic.level = RAW_OPEN_NTCREATEX;
1726 4 : io.ntcreatex.in.root_fid.fnum = 0;
1727 4 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1728 4 : io.ntcreatex.in.alloc_size = 0;
1729 4 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1730 4 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1731 : NTCREATEX_SHARE_ACCESS_WRITE|
1732 : NTCREATEX_SHARE_ACCESS_DELETE;
1733 4 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1734 4 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1735 4 : io.ntcreatex.in.impersonation =
1736 : NTCREATEX_IMPERSONATION_ANONYMOUS;
1737 4 : io.ntcreatex.in.security_flags = 0;
1738 4 : io.ntcreatex.in.fname = fname;
1739 4 : io.ntcreatex.in.flags = 0;
1740 :
1741 4 : status = smb_raw_open(cli_nt->tree, tctx, &io);
1742 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1743 0 : torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
1744 : "expected NT_STATUS_NOT_A_DIRECTORY\n",
1745 : nt_errstr(status));
1746 0 : result = false;
1747 : }
1748 :
1749 4 : if (NT_STATUS_IS_OK(status)) {
1750 0 : smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1751 : }
1752 :
1753 4 : status = smb_raw_open(cli_dos->tree, tctx, &io);
1754 4 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1755 : ERRbaddirectory))) {
1756 0 : torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
1757 : "expected NT_STATUS_NOT_A_DIRECTORY\n",
1758 : nt_errstr(status));
1759 0 : result = false;
1760 : }
1761 :
1762 4 : if (NT_STATUS_IS_OK(status)) {
1763 0 : smbcli_close(cli_dos->tree,
1764 0 : io.ntcreatex.out.file.fnum);
1765 : }
1766 :
1767 4 : smbcli_unlink(cli_nt->tree, fname);
1768 : }
1769 :
1770 4 : if (!torture_setting_bool(tctx, "samba3", false)) {
1771 0 : goto done;
1772 : }
1773 :
1774 4 : fnum = smbcli_open(cli_dos->tree, os2_fname,
1775 : O_RDWR | O_CREAT | O_TRUNC,
1776 : DENY_NONE);
1777 4 : if (fnum != -1) {
1778 0 : torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
1779 : os2_fname);
1780 0 : smbcli_close(cli_dos->tree, fnum);
1781 0 : goto fail;
1782 : }
1783 :
1784 4 : if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1785 : NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1786 0 : torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1787 0 : smbcli_errstr(cli_dos->tree));
1788 0 : goto fail;
1789 : }
1790 :
1791 4 : fnum = smbcli_open(cli_nt->tree, os2_fname,
1792 : O_RDWR | O_CREAT | O_TRUNC,
1793 : DENY_NONE);
1794 4 : if (fnum != -1) {
1795 0 : torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
1796 : os2_fname);
1797 0 : smbcli_close(cli_nt->tree, fnum);
1798 0 : goto fail;
1799 : }
1800 :
1801 4 : if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1802 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1803 0 : torture_result(tctx, TORTURE_FAIL, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1804 0 : "got %s\n", smbcli_errstr(cli_nt->tree));
1805 0 : goto fail;
1806 : }
1807 :
1808 4 : done:
1809 4 : result = true;
1810 :
1811 4 : fail:
1812 4 : if (cli_dos != NULL) {
1813 4 : torture_close_connection(cli_dos);
1814 : }
1815 4 : if (cli_nt != NULL) {
1816 4 : torture_close_connection(cli_nt);
1817 : }
1818 :
1819 4 : return result;
1820 : }
1821 :
1822 : /**
1823 : This checks file/dir birthtime
1824 : */
1825 0 : static void list_fn(struct clilist_file_info *finfo, const char *name,
1826 : void *state){
1827 :
1828 : /* Just to change dir access time*/
1829 0 : sleep(5);
1830 :
1831 0 : }
1832 :
1833 0 : static bool run_birthtimetest(struct torture_context *tctx,
1834 : struct smbcli_state *cli)
1835 : {
1836 0 : int fnum;
1837 0 : size_t size;
1838 0 : time_t c_time, a_time, m_time, w_time, c_time1;
1839 0 : const char *fname = "\\birthtime.tst";
1840 0 : const char *dname = "\\birthtime";
1841 0 : const char *fname2 = "\\birthtime\\birthtime.tst";
1842 0 : bool correct = true;
1843 0 : uint8_t buf[16];
1844 :
1845 :
1846 0 : smbcli_unlink(cli->tree, fname);
1847 :
1848 0 : torture_comment(tctx, "Testing Birthtime for File\n");
1849 :
1850 : /* Save File birthtime/creationtime */
1851 0 : fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1852 : DENY_NONE);
1853 0 : if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1854 : &c_time, &a_time, &m_time, NULL, NULL))) {
1855 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qfileinfo failed (%s)\n",
1856 : smbcli_errstr(cli->tree));
1857 0 : correct = false;
1858 : }
1859 0 : smbcli_close(cli->tree, fnum);
1860 :
1861 0 : sleep(10);
1862 :
1863 : /* Change in File attribute changes file change time*/
1864 0 : smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1865 :
1866 0 : fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1867 : /* Writing updates modification time*/
1868 0 : smbcli_smbwrite(cli->tree, fnum, &fname, 0, sizeof(fname));
1869 : /*Reading updates access time */
1870 0 : smbcli_read(cli->tree, fnum, buf, 0, 13);
1871 0 : smbcli_close(cli->tree, fnum);
1872 :
1873 0 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1874 : &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1875 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1876 : smbcli_errstr(cli->tree));
1877 0 : correct = false;
1878 : } else {
1879 0 : fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1880 : (long) c_time, (long) c_time1);
1881 0 : if (c_time1 != c_time) {
1882 0 : torture_result(tctx, TORTURE_FAIL, "This system updated file \
1883 : birth times! Not expected!\n");
1884 0 : correct = false;
1885 : }
1886 : }
1887 0 : smbcli_unlink(cli->tree, fname);
1888 :
1889 0 : torture_comment(tctx, "Testing Birthtime for Directory\n");
1890 :
1891 : /* check if the server does not update the directory birth time
1892 : when creating a new file */
1893 0 : if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1894 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: mkdir failed (%s)\n",
1895 : smbcli_errstr(cli->tree));
1896 0 : correct = false;
1897 : }
1898 0 : sleep(3);
1899 0 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1900 : &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1901 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1902 : smbcli_errstr(cli->tree));
1903 0 : correct = false;
1904 : }
1905 :
1906 : /* Creating a new file changes dir modification time and change time*/
1907 0 : smbcli_unlink(cli->tree, fname2);
1908 0 : fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1909 : DENY_NONE);
1910 0 : smbcli_smbwrite(cli->tree, fnum, &fnum, 0, sizeof(fnum));
1911 0 : smbcli_read(cli->tree, fnum, buf, 0, 13);
1912 0 : smbcli_close(cli->tree, fnum);
1913 :
1914 : /* dir listing changes dir access time*/
1915 0 : smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1916 :
1917 0 : if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1918 : &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1919 0 : torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1920 : smbcli_errstr(cli->tree));
1921 0 : correct = false;
1922 : } else {
1923 0 : fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1924 : (long) c_time, (long) c_time1);
1925 0 : if (c_time1 != c_time) {
1926 0 : torture_result(tctx, TORTURE_FAIL, "This system updated directory \
1927 : birth times! Not Expected!\n");
1928 0 : correct = false;
1929 : }
1930 : }
1931 0 : smbcli_unlink(cli->tree, fname2);
1932 0 : smbcli_rmdir(cli->tree, dname);
1933 :
1934 0 : return correct;
1935 : }
1936 :
1937 : /**
1938 : SMB1 TWRP open on root of share.
1939 : */
1940 2 : static bool torture_smb1_twrp_openroot(struct torture_context *tctx,
1941 : struct smbcli_state *cli)
1942 : {
1943 2 : const char *snapshot = NULL;
1944 2 : const char *p = NULL;
1945 0 : NTSTATUS status;
1946 2 : struct tm tm = {};
1947 2 : bool ret = true;
1948 :
1949 2 : snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL);
1950 2 : if (snapshot == NULL) {
1951 0 : torture_skip(tctx, "missing 'twrp_snapshot' option\n");
1952 : }
1953 :
1954 2 : torture_comment(tctx, "Testing open of root of "
1955 : "share with timewarp (%s)\n",
1956 : snapshot);
1957 :
1958 2 : setenv("TZ", "GMT", 1);
1959 :
1960 2 : p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm);
1961 2 : torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n");
1962 2 : torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n");
1963 :
1964 2 : cli->session->flags2 |= FLAGS2_REPARSE_PATH;
1965 2 : status = smbcli_chkpath(cli->tree, snapshot);
1966 2 : cli->session->flags2 &= ~FLAGS2_REPARSE_PATH;
1967 :
1968 2 : if (NT_STATUS_IS_ERR(status)) {
1969 0 : torture_result(tctx,
1970 : TORTURE_FAIL,
1971 : "smbcli_chkpath on %s : %s\n",
1972 : snapshot,
1973 : smbcli_errstr(cli->tree));
1974 0 : return false;
1975 : }
1976 :
1977 2 : done:
1978 :
1979 2 : return ret;
1980 : }
1981 :
1982 0 : static void torture_smb1_find_gmt_mask_list_fn(struct clilist_file_info *finfo,
1983 : const char *name,
1984 : void *state)
1985 : {
1986 0 : }
1987 :
1988 : /**
1989 : * SMB1 @GMT token as search mask is valid
1990 : */
1991 0 : static bool torture_smb1_find_gmt_mask(struct torture_context *tctx,
1992 : struct smbcli_state *cli)
1993 : {
1994 0 : const char *dname = "\\torture_smb1_find_gmt_mask";
1995 0 : const char *path = "\\torture_smb1_find_gmt_mask\\@GMT-2022.11.24-16.24.00";
1996 0 : int fnum;
1997 0 : int n;
1998 0 : NTSTATUS status;
1999 0 : bool ret = true;
2000 :
2001 0 : smbcli_unlink(cli->tree, path);
2002 0 : smbcli_rmdir(cli->tree, dname);
2003 :
2004 0 : status = smbcli_mkdir(cli->tree, dname);
2005 0 : torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2006 : "smbcli_mkdir() failed\n");
2007 0 : fnum = smbcli_open(cli->tree, path, O_RDWR | O_CREAT, DENY_NONE);
2008 0 : smbcli_close(cli->tree, fnum);
2009 :
2010 : /* Note: we don't set FLAGS2_REPARSE_PATH, so this is just a path */
2011 0 : n = smbcli_list(cli->tree, path, 0, torture_smb1_find_gmt_mask_list_fn, cli);
2012 0 : torture_assert_int_equal_goto(tctx, n, 1, ret, done, "Wrong count\n");
2013 :
2014 0 : done:
2015 0 : smbcli_unlink(cli->tree, path);
2016 0 : smbcli_rmdir(cli->tree, dname);
2017 0 : return ret;
2018 : }
2019 :
2020 2354 : NTSTATUS torture_base_init(TALLOC_CTX *ctx)
2021 : {
2022 2354 : struct torture_suite *suite = torture_suite_create(ctx, "base");
2023 :
2024 2354 : torture_suite_add_2smb_test(suite, "fdpass", run_fdpasstest);
2025 2354 : torture_suite_add_suite(suite, torture_base_locktest(suite));
2026 2354 : torture_suite_add_1smb_test(suite, "unlink", torture_unlinktest);
2027 2354 : torture_suite_add_1smb_test(suite, "attr", run_attrtest);
2028 2354 : torture_suite_add_1smb_test(suite, "trans2", run_trans2test);
2029 2354 : torture_suite_add_1smb_test(suite, "birthtime", run_birthtimetest);
2030 2354 : torture_suite_add_simple_test(suite, "negnowait", run_negprot_nowait);
2031 2354 : torture_suite_add_1smb_test(suite, "dir1", torture_dirtest1);
2032 2354 : torture_suite_add_1smb_test(suite, "dir2", torture_dirtest2);
2033 2354 : torture_suite_add_1smb_test(suite, "deny1", torture_denytest1);
2034 2354 : torture_suite_add_2smb_test(suite, "deny2", torture_denytest2);
2035 2354 : torture_suite_add_2smb_test(suite, "deny3", torture_denytest3);
2036 2354 : torture_suite_add_1smb_test(suite, "denydos", torture_denydos_sharing);
2037 2354 : torture_suite_add_smb_multi_test(suite, "ntdeny1", torture_ntdenytest1);
2038 2354 : torture_suite_add_2smb_test(suite, "ntdeny2", torture_ntdenytest2);
2039 2354 : torture_suite_add_1smb_test(suite, "tcon", run_tcon_test);
2040 2354 : torture_suite_add_1smb_test(suite, "tcondev", run_tcon_devtype_test);
2041 2354 : torture_suite_add_1smb_test(suite, "vuid", run_vuidtest);
2042 2354 : torture_suite_add_2smb_test(suite, "rw1", run_readwritetest);
2043 2354 : torture_suite_add_2smb_test(suite, "open", run_opentest);
2044 2354 : torture_suite_add_smb_multi_test(suite, "defer_open", run_deferopen);
2045 2354 : torture_suite_add_1smb_test(suite, "xcopy", run_xcopy);
2046 2354 : torture_suite_add_1smb_test(suite, "iometer", run_iometer);
2047 2354 : torture_suite_add_1smb_test(suite, "rename", torture_test_rename);
2048 2354 : torture_suite_add_suite(suite, torture_test_delete(suite));
2049 2354 : torture_suite_add_1smb_test(suite, "properties", torture_test_properties);
2050 2354 : torture_suite_add_1smb_test(suite, "mangle", torture_mangle);
2051 2354 : torture_suite_add_1smb_test(suite, "openattr", torture_openattrtest);
2052 2354 : torture_suite_add_1smb_test(suite, "winattr", torture_winattrtest);
2053 2354 : torture_suite_add_suite(suite, torture_charset(suite));
2054 2354 : torture_suite_add_1smb_test(suite, "chkpath", torture_chkpath_test);
2055 2354 : torture_suite_add_1smb_test(suite, "secleak", torture_sec_leak);
2056 2354 : torture_suite_add_simple_test(suite, "disconnect", torture_disconnect);
2057 2354 : torture_suite_add_suite(suite, torture_delay_write(suite));
2058 2354 : torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths);
2059 2354 : torture_suite_add_1smb_test(suite, "casetable", torture_casetable);
2060 2354 : torture_suite_add_1smb_test(suite, "utable", torture_utable);
2061 2354 : torture_suite_add_simple_test(suite, "smb", torture_smb_scan);
2062 2354 : torture_suite_add_suite(suite, torture_trans2_aliases(suite));
2063 2354 : torture_suite_add_1smb_test(suite, "trans2-scan", torture_trans2_scan);
2064 2354 : torture_suite_add_1smb_test(suite, "nttrans", torture_nttrans_scan);
2065 2354 : torture_suite_add_1smb_test(suite, "createx_access", torture_createx_access);
2066 2354 : torture_suite_add_2smb_test(suite, "createx_sharemodes_file", torture_createx_sharemodes_file);
2067 2354 : torture_suite_add_2smb_test(suite, "createx_sharemodes_dir", torture_createx_sharemodes_dir);
2068 2354 : torture_suite_add_1smb_test(suite, "maximum_allowed", torture_maximum_allowed);
2069 :
2070 2354 : torture_suite_add_simple_test(suite, "bench-holdcon", torture_holdcon);
2071 2354 : torture_suite_add_1smb_test(suite, "bench-holdopen", torture_holdopen);
2072 2354 : torture_suite_add_simple_test(suite, "bench-readwrite", run_benchrw);
2073 2354 : torture_suite_add_smb_multi_test(suite, "bench-torture", run_torture);
2074 2354 : torture_suite_add_1smb_test(suite, "scan-pipe_number", run_pipe_number);
2075 2354 : torture_suite_add_1smb_test(suite, "scan-ioctl", torture_ioctl_test);
2076 2354 : torture_suite_add_1smb_test(suite, "scan-maxfid", torture_maxfid_test);
2077 2354 : torture_suite_add_1smb_test(suite,
2078 : "smb1-twrp-openroot",
2079 : torture_smb1_twrp_openroot);
2080 2354 : torture_suite_add_1smb_test(suite,
2081 : "smb1-find-gmt-mask",
2082 : torture_smb1_find_gmt_mask);
2083 :
2084 2354 : suite->description = talloc_strdup(suite,
2085 : "Basic SMB tests (imported from the original smbtorture)");
2086 :
2087 2354 : torture_register_suite(ctx, suite);
2088 :
2089 2354 : return NT_STATUS_OK;
2090 : }
|