2 Unix SMB/CIFS implementation.
3 test suite for various read operations
4 Copyright (C) Andrew Tridgell 2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/torture.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/raw/raw_proto.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28 #include "param/param.h"
30 #define CHECK_STATUS(status, correct) do { \
31 if (!NT_STATUS_EQUAL(status, correct)) { \
32 printf("(%s) Incorrect status %s - should be %s\n", \
33 __location__, nt_errstr(status), nt_errstr(correct)); \
38 #define CHECK_VALUE(v, correct) do { \
39 if ((v) != (correct)) { \
40 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
41 __location__, #v, (long)v, (long)correct); \
46 #define CHECK_BUFFER(buf, seed, len) do { \
47 if (!check_buffer(buf, seed, len, __LINE__)) { \
52 #define BASEDIR "\\testread"
56 setup a random buffer based on a seed
58 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
62 for (i=0;i<len;i++) buf[i] = random();
66 check a random buffer based on a seed
68 static bool check_buffer(uint8_t *buf, uint_t seed, int len, int line)
75 printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n",
86 static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
93 const int maxsize = 90000;
94 const char *fname = BASEDIR "\\test.txt";
95 const char *test_data = "TEST DATA";
96 uint_t seed = time(NULL);
98 buf = talloc_zero_array(tctx, uint8_t, maxsize);
100 if (!torture_setup_dir(cli, BASEDIR)) {
104 printf("Testing RAW_READ_READ\n");
105 io.generic.level = RAW_READ_READ;
107 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
109 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
114 printf("Trying empty file read\n");
115 io.read.in.file.fnum = fnum;
116 io.read.in.count = 1;
117 io.read.in.offset = 0;
118 io.read.in.remaining = 0;
119 io.read.out.data = buf;
120 status = smb_raw_read(cli->tree, &io);
122 CHECK_STATUS(status, NT_STATUS_OK);
123 CHECK_VALUE(io.read.out.nread, 0);
125 printf("Trying zero file read\n");
126 io.read.in.count = 0;
127 status = smb_raw_read(cli->tree, &io);
128 CHECK_STATUS(status, NT_STATUS_OK);
129 CHECK_VALUE(io.read.out.nread, 0);
131 printf("Trying bad fnum\n");
132 io.read.in.file.fnum = fnum+1;
133 status = smb_raw_read(cli->tree, &io);
134 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
135 io.read.in.file.fnum = fnum;
137 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
139 printf("Trying small read\n");
140 io.read.in.file.fnum = fnum;
141 io.read.in.offset = 0;
142 io.read.in.remaining = 0;
143 io.read.in.count = strlen(test_data);
144 status = smb_raw_read(cli->tree, &io);
145 CHECK_STATUS(status, NT_STATUS_OK);
146 CHECK_VALUE(io.read.out.nread, strlen(test_data));
147 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
149 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
153 printf("Trying short read\n");
154 io.read.in.offset = 1;
155 io.read.in.count = strlen(test_data);
156 status = smb_raw_read(cli->tree, &io);
157 CHECK_STATUS(status, NT_STATUS_OK);
158 CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
159 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
161 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
165 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
166 printf("Trying max offset\n");
167 io.read.in.offset = ~0;
168 io.read.in.count = strlen(test_data);
169 status = smb_raw_read(cli->tree, &io);
170 CHECK_STATUS(status, NT_STATUS_OK);
171 CHECK_VALUE(io.read.out.nread, 0);
174 setup_buffer(buf, seed, maxsize);
175 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
176 memset(buf, 0, maxsize);
178 printf("Trying large read\n");
179 io.read.in.offset = 0;
180 io.read.in.count = ~0;
181 status = smb_raw_read(cli->tree, &io);
182 CHECK_STATUS(status, NT_STATUS_OK);
183 CHECK_BUFFER(buf, seed, io.read.out.nread);
186 printf("Trying locked region\n");
188 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
189 printf("Failed to lock file at %d\n", __LINE__);
194 memset(buf, 0, maxsize);
195 io.read.in.offset = 0;
196 io.read.in.count = ~0;
197 status = smb_raw_read(cli->tree, &io);
198 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
202 smbcli_close(cli->tree, fnum);
203 smb_raw_exit(cli->session);
204 smbcli_deltree(cli->tree, BASEDIR);
212 static bool test_lockread(struct torture_context *tctx,
213 struct smbcli_state *cli)
220 const int maxsize = 90000;
221 const char *fname = BASEDIR "\\test.txt";
222 const char *test_data = "TEST DATA";
223 uint_t seed = time(NULL);
225 buf = talloc_zero_array(tctx, uint8_t, maxsize);
227 if (!torture_setup_dir(cli, BASEDIR)) {
231 printf("Testing RAW_READ_LOCKREAD\n");
232 io.generic.level = RAW_READ_LOCKREAD;
234 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
236 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
241 printf("Trying empty file read\n");
242 io.lockread.in.file.fnum = fnum;
243 io.lockread.in.count = 1;
244 io.lockread.in.offset = 1;
245 io.lockread.in.remaining = 0;
246 io.lockread.out.data = buf;
247 status = smb_raw_read(cli->tree, &io);
249 CHECK_STATUS(status, NT_STATUS_OK);
250 CHECK_VALUE(io.lockread.out.nread, 0);
252 status = smb_raw_read(cli->tree, &io);
253 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
255 status = smb_raw_read(cli->tree, &io);
256 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
258 printf("Trying zero file read\n");
259 io.lockread.in.count = 0;
260 status = smb_raw_read(cli->tree, &io);
261 CHECK_STATUS(status, NT_STATUS_OK);
263 smbcli_unlock(cli->tree, fnum, 1, 1);
265 printf("Trying bad fnum\n");
266 io.lockread.in.file.fnum = fnum+1;
267 status = smb_raw_read(cli->tree, &io);
268 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
269 io.lockread.in.file.fnum = fnum;
271 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
273 printf("Trying small read\n");
274 io.lockread.in.file.fnum = fnum;
275 io.lockread.in.offset = 0;
276 io.lockread.in.remaining = 0;
277 io.lockread.in.count = strlen(test_data);
278 status = smb_raw_read(cli->tree, &io);
279 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
281 smbcli_unlock(cli->tree, fnum, 1, 0);
283 status = smb_raw_read(cli->tree, &io);
284 CHECK_STATUS(status, NT_STATUS_OK);
285 CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
286 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
288 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
292 printf("Trying short read\n");
293 io.lockread.in.offset = 1;
294 io.lockread.in.count = strlen(test_data);
295 status = smb_raw_read(cli->tree, &io);
296 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
297 smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
298 status = smb_raw_read(cli->tree, &io);
299 CHECK_STATUS(status, NT_STATUS_OK);
301 CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
302 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
304 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
308 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
309 printf("Trying max offset\n");
310 io.lockread.in.offset = ~0;
311 io.lockread.in.count = strlen(test_data);
312 status = smb_raw_read(cli->tree, &io);
313 CHECK_STATUS(status, NT_STATUS_OK);
314 CHECK_VALUE(io.lockread.out.nread, 0);
317 setup_buffer(buf, seed, maxsize);
318 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
319 memset(buf, 0, maxsize);
321 printf("Trying large read\n");
322 io.lockread.in.offset = 0;
323 io.lockread.in.count = ~0;
324 status = smb_raw_read(cli->tree, &io);
325 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
326 smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
327 status = smb_raw_read(cli->tree, &io);
328 CHECK_STATUS(status, NT_STATUS_OK);
329 CHECK_BUFFER(buf, seed, io.lockread.out.nread);
330 smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
333 printf("Trying locked region\n");
335 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
336 printf("Failed to lock file at %d\n", __LINE__);
341 memset(buf, 0, maxsize);
342 io.lockread.in.offset = 0;
343 io.lockread.in.count = ~0;
344 status = smb_raw_read(cli->tree, &io);
345 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
349 smbcli_close(cli->tree, fnum);
350 smbcli_deltree(cli->tree, BASEDIR);
358 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
365 const int maxsize = 90000;
366 const char *fname = BASEDIR "\\test.txt";
367 const char *test_data = "TEST DATA";
368 uint_t seed = time(NULL);
370 buf = talloc_zero_array(tctx, uint8_t, maxsize);
372 if (!torture_setup_dir(cli, BASEDIR)) {
376 printf("Testing RAW_READ_READX\n");
378 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
380 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
385 printf("Trying empty file read\n");
386 io.generic.level = RAW_READ_READX;
387 io.readx.in.file.fnum = fnum;
388 io.readx.in.mincnt = 1;
389 io.readx.in.maxcnt = 1;
390 io.readx.in.offset = 0;
391 io.readx.in.remaining = 0;
392 io.readx.in.read_for_execute = false;
393 io.readx.out.data = buf;
394 status = smb_raw_read(cli->tree, &io);
396 CHECK_STATUS(status, NT_STATUS_OK);
397 CHECK_VALUE(io.readx.out.nread, 0);
398 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
399 CHECK_VALUE(io.readx.out.compaction_mode, 0);
401 printf("Trying zero file read\n");
402 io.readx.in.mincnt = 0;
403 io.readx.in.maxcnt = 0;
404 status = smb_raw_read(cli->tree, &io);
405 CHECK_STATUS(status, NT_STATUS_OK);
406 CHECK_VALUE(io.readx.out.nread, 0);
407 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
408 CHECK_VALUE(io.readx.out.compaction_mode, 0);
410 printf("Trying bad fnum\n");
411 io.readx.in.file.fnum = fnum+1;
412 status = smb_raw_read(cli->tree, &io);
413 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
414 io.readx.in.file.fnum = fnum;
416 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
418 printf("Trying small read\n");
419 io.readx.in.file.fnum = fnum;
420 io.readx.in.offset = 0;
421 io.readx.in.remaining = 0;
422 io.readx.in.read_for_execute = false;
423 io.readx.in.mincnt = strlen(test_data);
424 io.readx.in.maxcnt = strlen(test_data);
425 status = smb_raw_read(cli->tree, &io);
426 CHECK_STATUS(status, NT_STATUS_OK);
427 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
428 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
429 CHECK_VALUE(io.readx.out.compaction_mode, 0);
430 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
432 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
436 printf("Trying short read\n");
437 io.readx.in.offset = 1;
438 io.readx.in.mincnt = strlen(test_data);
439 io.readx.in.maxcnt = strlen(test_data);
440 status = smb_raw_read(cli->tree, &io);
441 CHECK_STATUS(status, NT_STATUS_OK);
442 CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
443 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
444 CHECK_VALUE(io.readx.out.compaction_mode, 0);
445 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
447 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
451 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
452 printf("Trying max offset\n");
453 io.readx.in.offset = 0xffffffff;
454 io.readx.in.mincnt = strlen(test_data);
455 io.readx.in.maxcnt = strlen(test_data);
456 status = smb_raw_read(cli->tree, &io);
457 CHECK_STATUS(status, NT_STATUS_OK);
458 CHECK_VALUE(io.readx.out.nread, 0);
459 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
460 CHECK_VALUE(io.readx.out.compaction_mode, 0);
463 setup_buffer(buf, seed, maxsize);
464 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
465 memset(buf, 0, maxsize);
467 printf("Trying large read\n");
468 io.readx.in.offset = 0;
469 io.readx.in.mincnt = 0xFFFF;
470 io.readx.in.maxcnt = 0xFFFF;
471 status = smb_raw_read(cli->tree, &io);
472 CHECK_STATUS(status, NT_STATUS_OK);
473 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
474 CHECK_VALUE(io.readx.out.compaction_mode, 0);
475 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
476 CHECK_BUFFER(buf, seed, io.readx.out.nread);
478 printf("Trying extra large read\n");
479 io.readx.in.offset = 0;
480 io.readx.in.mincnt = 100;
481 io.readx.in.maxcnt = 80000;
482 status = smb_raw_read(cli->tree, &io);
483 CHECK_STATUS(status, NT_STATUS_OK);
484 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
485 CHECK_VALUE(io.readx.out.compaction_mode, 0);
486 if (torture_setting_bool(tctx, "samba3", false)) {
487 printf("SAMBA3: large read extension\n");
488 CHECK_VALUE(io.readx.out.nread, 80000);
490 CHECK_VALUE(io.readx.out.nread, 0);
492 CHECK_BUFFER(buf, seed, io.readx.out.nread);
494 printf("Trying mincnt > maxcnt\n");
495 memset(buf, 0, maxsize);
496 io.readx.in.offset = 0;
497 io.readx.in.mincnt = 30000;
498 io.readx.in.maxcnt = 20000;
499 status = smb_raw_read(cli->tree, &io);
500 CHECK_STATUS(status, NT_STATUS_OK);
501 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
502 CHECK_VALUE(io.readx.out.compaction_mode, 0);
503 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
504 CHECK_BUFFER(buf, seed, io.readx.out.nread);
506 printf("Trying mincnt < maxcnt\n");
507 memset(buf, 0, maxsize);
508 io.readx.in.offset = 0;
509 io.readx.in.mincnt = 20000;
510 io.readx.in.maxcnt = 30000;
511 status = smb_raw_read(cli->tree, &io);
512 CHECK_STATUS(status, NT_STATUS_OK);
513 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
514 CHECK_VALUE(io.readx.out.compaction_mode, 0);
515 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
516 CHECK_BUFFER(buf, seed, io.readx.out.nread);
518 if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
519 printf("Trying large readx\n");
520 io.readx.in.offset = 0;
521 io.readx.in.mincnt = 0;
522 io.readx.in.maxcnt = 0x10000 - 1;
523 status = smb_raw_read(cli->tree, &io);
524 CHECK_STATUS(status, NT_STATUS_OK);
525 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
527 io.readx.in.maxcnt = 0x10000;
528 status = smb_raw_read(cli->tree, &io);
529 CHECK_STATUS(status, NT_STATUS_OK);
530 if (torture_setting_bool(tctx, "samba3", false)) {
531 printf("SAMBA3: large read extension\n");
532 CHECK_VALUE(io.readx.out.nread, 0x10000);
534 CHECK_VALUE(io.readx.out.nread, 0);
537 io.readx.in.maxcnt = 0x10001;
538 status = smb_raw_read(cli->tree, &io);
539 CHECK_STATUS(status, NT_STATUS_OK);
540 if (torture_setting_bool(tctx, "samba3", false)) {
541 printf("SAMBA3: large read extension\n");
542 CHECK_VALUE(io.readx.out.nread, 0x10001);
544 CHECK_VALUE(io.readx.out.nread, 0);
548 printf("Trying locked region\n");
550 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
551 printf("Failed to lock file at %d\n", __LINE__);
556 memset(buf, 0, maxsize);
557 io.readx.in.offset = 0;
558 io.readx.in.mincnt = 100;
559 io.readx.in.maxcnt = 200;
560 status = smb_raw_read(cli->tree, &io);
561 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
563 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
564 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
568 printf("Trying large offset read\n");
569 io.readx.in.offset = ((uint64_t)0x2) << 32;
570 io.readx.in.mincnt = 10;
571 io.readx.in.maxcnt = 10;
572 status = smb_raw_read(cli->tree, &io);
573 CHECK_STATUS(status, NT_STATUS_OK);
574 CHECK_VALUE(io.readx.out.nread, 0);
576 if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
577 printf("Failed to lock file at %d\n", __LINE__);
582 status = smb_raw_read(cli->tree, &io);
583 CHECK_STATUS(status, NT_STATUS_OK);
584 CHECK_VALUE(io.readx.out.nread, 0);
587 smbcli_close(cli->tree, fnum);
588 smbcli_deltree(cli->tree, BASEDIR);
596 static bool test_readbraw(struct torture_context *tctx,
597 struct smbcli_state *cli)
604 const int maxsize = 90000;
605 const char *fname = BASEDIR "\\test.txt";
606 const char *test_data = "TEST DATA";
607 uint_t seed = time(NULL);
609 buf = talloc_zero_array(tctx, uint8_t, maxsize);
611 if (!torture_setup_dir(cli, BASEDIR)) {
615 printf("Testing RAW_READ_READBRAW\n");
617 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
619 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
624 printf("Trying empty file read\n");
625 io.generic.level = RAW_READ_READBRAW;
626 io.readbraw.in.file.fnum = fnum;
627 io.readbraw.in.mincnt = 1;
628 io.readbraw.in.maxcnt = 1;
629 io.readbraw.in.offset = 0;
630 io.readbraw.in.timeout = 0;
631 io.readbraw.out.data = buf;
632 status = smb_raw_read(cli->tree, &io);
634 CHECK_STATUS(status, NT_STATUS_OK);
635 CHECK_VALUE(io.readbraw.out.nread, 0);
637 printf("Trying zero file read\n");
638 io.readbraw.in.mincnt = 0;
639 io.readbraw.in.maxcnt = 0;
640 status = smb_raw_read(cli->tree, &io);
641 CHECK_STATUS(status, NT_STATUS_OK);
642 CHECK_VALUE(io.readbraw.out.nread, 0);
644 printf("Trying bad fnum\n");
645 io.readbraw.in.file.fnum = fnum+1;
646 status = smb_raw_read(cli->tree, &io);
647 CHECK_STATUS(status, NT_STATUS_OK);
648 CHECK_VALUE(io.readbraw.out.nread, 0);
649 io.readbraw.in.file.fnum = fnum;
651 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
653 printf("Trying small read\n");
654 io.readbraw.in.file.fnum = fnum;
655 io.readbraw.in.offset = 0;
656 io.readbraw.in.mincnt = strlen(test_data);
657 io.readbraw.in.maxcnt = strlen(test_data);
658 status = smb_raw_read(cli->tree, &io);
659 CHECK_STATUS(status, NT_STATUS_OK);
660 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
661 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
663 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
667 printf("Trying short read\n");
668 io.readbraw.in.offset = 1;
669 io.readbraw.in.mincnt = strlen(test_data);
670 io.readbraw.in.maxcnt = strlen(test_data);
671 status = smb_raw_read(cli->tree, &io);
672 CHECK_STATUS(status, NT_STATUS_OK);
673 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
674 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
676 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
680 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
681 printf("Trying max offset\n");
682 io.readbraw.in.offset = ~0;
683 io.readbraw.in.mincnt = strlen(test_data);
684 io.readbraw.in.maxcnt = strlen(test_data);
685 status = smb_raw_read(cli->tree, &io);
686 CHECK_STATUS(status, NT_STATUS_OK);
687 CHECK_VALUE(io.readbraw.out.nread, 0);
690 setup_buffer(buf, seed, maxsize);
691 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
692 memset(buf, 0, maxsize);
694 printf("Trying large read\n");
695 io.readbraw.in.offset = 0;
696 io.readbraw.in.mincnt = ~0;
697 io.readbraw.in.maxcnt = ~0;
698 status = smb_raw_read(cli->tree, &io);
699 CHECK_STATUS(status, NT_STATUS_OK);
700 CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
701 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
703 printf("Trying mincnt > maxcnt\n");
704 memset(buf, 0, maxsize);
705 io.readbraw.in.offset = 0;
706 io.readbraw.in.mincnt = 30000;
707 io.readbraw.in.maxcnt = 20000;
708 status = smb_raw_read(cli->tree, &io);
709 CHECK_STATUS(status, NT_STATUS_OK);
710 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
711 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
713 printf("Trying mincnt < maxcnt\n");
714 memset(buf, 0, maxsize);
715 io.readbraw.in.offset = 0;
716 io.readbraw.in.mincnt = 20000;
717 io.readbraw.in.maxcnt = 30000;
718 status = smb_raw_read(cli->tree, &io);
719 CHECK_STATUS(status, NT_STATUS_OK);
720 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
721 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
723 printf("Trying locked region\n");
725 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
726 printf("Failed to lock file at %d\n", __LINE__);
731 memset(buf, 0, maxsize);
732 io.readbraw.in.offset = 0;
733 io.readbraw.in.mincnt = 100;
734 io.readbraw.in.maxcnt = 200;
735 status = smb_raw_read(cli->tree, &io);
736 CHECK_STATUS(status, NT_STATUS_OK);
737 CHECK_VALUE(io.readbraw.out.nread, 0);
739 printf("Trying locked region with timeout\n");
740 memset(buf, 0, maxsize);
741 io.readbraw.in.offset = 0;
742 io.readbraw.in.mincnt = 100;
743 io.readbraw.in.maxcnt = 200;
744 io.readbraw.in.timeout = 10000;
745 status = smb_raw_read(cli->tree, &io);
746 CHECK_STATUS(status, NT_STATUS_OK);
747 CHECK_VALUE(io.readbraw.out.nread, 0);
749 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
750 printf("Trying large offset read\n");
751 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
752 io.readbraw.in.mincnt = 10;
753 io.readbraw.in.maxcnt = 10;
754 io.readbraw.in.timeout = 0;
755 status = smb_raw_read(cli->tree, &io);
756 CHECK_STATUS(status, NT_STATUS_OK);
757 CHECK_VALUE(io.readbraw.out.nread, 0);
761 smbcli_close(cli->tree, fnum);
762 smbcli_deltree(cli->tree, BASEDIR);
767 test read for execute
769 static bool test_read_for_execute(struct torture_context *tctx,
770 struct smbcli_state *cli)
779 const int maxsize = 900;
780 const char *fname = BASEDIR "\\test.txt";
781 const uint8_t data[] = "TEST DATA";
783 buf = talloc_zero_array(tctx, uint8_t, maxsize);
785 if (!torture_setup_dir(cli, BASEDIR)) {
789 printf("Testing RAW_READ_READX with read_for_execute\n");
791 op.generic.level = RAW_OPEN_NTCREATEX;
792 op.ntcreatex.in.root_fid = 0;
793 op.ntcreatex.in.flags = 0;
794 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
795 op.ntcreatex.in.create_options = 0;
796 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
797 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
798 op.ntcreatex.in.alloc_size = 0;
799 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
800 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
801 op.ntcreatex.in.security_flags = 0;
802 op.ntcreatex.in.fname = fname;
803 status = smb_raw_open(cli->tree, tctx, &op);
804 CHECK_STATUS(status, NT_STATUS_OK);
805 fnum = op.ntcreatex.out.file.fnum;
807 wr.generic.level = RAW_WRITE_WRITEX;
808 wr.writex.in.file.fnum = fnum;
809 wr.writex.in.offset = 0;
810 wr.writex.in.wmode = 0;
811 wr.writex.in.remaining = 0;
812 wr.writex.in.count = ARRAY_SIZE(data);
813 wr.writex.in.data = data;
814 status = smb_raw_write(cli->tree, &wr);
815 CHECK_STATUS(status, NT_STATUS_OK);
816 CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
818 status = smbcli_close(cli->tree, fnum);
819 CHECK_STATUS(status, NT_STATUS_OK);
821 printf("open file with SEC_FILE_EXECUTE\n");
822 op.generic.level = RAW_OPEN_NTCREATEX;
823 op.ntcreatex.in.root_fid = 0;
824 op.ntcreatex.in.flags = 0;
825 op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
826 op.ntcreatex.in.create_options = 0;
827 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
828 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
829 op.ntcreatex.in.alloc_size = 0;
830 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
831 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
832 op.ntcreatex.in.security_flags = 0;
833 op.ntcreatex.in.fname = fname;
834 status = smb_raw_open(cli->tree, tctx, &op);
835 CHECK_STATUS(status, NT_STATUS_OK);
836 fnum = op.ntcreatex.out.file.fnum;
838 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
839 rd.generic.level = RAW_READ_READX;
840 rd.readx.in.file.fnum = fnum;
841 rd.readx.in.mincnt = 0;
842 rd.readx.in.maxcnt = maxsize;
843 rd.readx.in.offset = 0;
844 rd.readx.in.remaining = 0;
845 rd.readx.in.read_for_execute = true;
846 rd.readx.out.data = buf;
847 status = smb_raw_read(cli->tree, &rd);
848 CHECK_STATUS(status, NT_STATUS_OK);
849 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
850 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
851 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
853 printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
854 rd.generic.level = RAW_READ_READX;
855 rd.readx.in.file.fnum = fnum;
856 rd.readx.in.mincnt = 0;
857 rd.readx.in.maxcnt = maxsize;
858 rd.readx.in.offset = 0;
859 rd.readx.in.remaining = 0;
860 rd.readx.in.read_for_execute = false;
861 rd.readx.out.data = buf;
862 status = smb_raw_read(cli->tree, &rd);
863 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
865 status = smbcli_close(cli->tree, fnum);
866 CHECK_STATUS(status, NT_STATUS_OK);
868 printf("open file with SEC_FILE_READ_DATA\n");
869 op.generic.level = RAW_OPEN_NTCREATEX;
870 op.ntcreatex.in.root_fid = 0;
871 op.ntcreatex.in.flags = 0;
872 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
873 op.ntcreatex.in.create_options = 0;
874 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
875 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
876 op.ntcreatex.in.alloc_size = 0;
877 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
878 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
879 op.ntcreatex.in.security_flags = 0;
880 op.ntcreatex.in.fname = fname;
881 status = smb_raw_open(cli->tree, tctx, &op);
882 CHECK_STATUS(status, NT_STATUS_OK);
883 fnum = op.ntcreatex.out.file.fnum;
885 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
886 rd.generic.level = RAW_READ_READX;
887 rd.readx.in.file.fnum = fnum;
888 rd.readx.in.mincnt = 0;
889 rd.readx.in.maxcnt = maxsize;
890 rd.readx.in.offset = 0;
891 rd.readx.in.remaining = 0;
892 rd.readx.in.read_for_execute = true;
893 rd.readx.out.data = buf;
894 status = smb_raw_read(cli->tree, &rd);
895 CHECK_STATUS(status, NT_STATUS_OK);
896 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
897 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
898 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
900 printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
901 rd.generic.level = RAW_READ_READX;
902 rd.readx.in.file.fnum = fnum;
903 rd.readx.in.mincnt = 0;
904 rd.readx.in.maxcnt = maxsize;
905 rd.readx.in.offset = 0;
906 rd.readx.in.remaining = 0;
907 rd.readx.in.read_for_execute = false;
908 rd.readx.out.data = buf;
909 status = smb_raw_read(cli->tree, &rd);
910 CHECK_STATUS(status, NT_STATUS_OK);
911 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
912 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
913 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
916 smbcli_close(cli->tree, fnum);
917 smbcli_deltree(cli->tree, BASEDIR);
923 basic testing of read calls
925 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
927 struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
929 torture_suite_add_1smb_test(suite, "read", test_read);
930 torture_suite_add_1smb_test(suite, "readx", test_readx);
931 torture_suite_add_1smb_test(suite, "lockread", test_lockread);
932 torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
933 torture_suite_add_1smb_test(suite, "read for execute",
934 test_read_for_execute);