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 "libcli/raw/libcliraw.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "libcli/libcli.h"
25 #include "torture/util.h"
27 #define CHECK_STATUS(status, correct) do { \
28 if (!NT_STATUS_EQUAL(status, correct)) { \
29 printf("(%s) Incorrect status %s - should be %s\n", \
30 __location__, nt_errstr(status), nt_errstr(correct)); \
35 #define CHECK_VALUE(v, correct) do { \
36 if ((v) != (correct)) { \
37 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
38 __location__, #v, (long)v, (long)correct); \
43 #define CHECK_BUFFER(buf, seed, len) do { \
44 if (!check_buffer(buf, seed, len, __LINE__)) { \
49 #define BASEDIR "\\testread"
53 setup a random buffer based on a seed
55 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
59 for (i=0;i<len;i++) buf[i] = random();
63 check a random buffer based on a seed
65 static bool check_buffer(uint8_t *buf, uint_t seed, int len, int line)
72 printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n",
83 static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
90 const int maxsize = 90000;
91 const char *fname = BASEDIR "\\test.txt";
92 const char *test_data = "TEST DATA";
93 uint_t seed = time(NULL);
95 buf = talloc_zero_array(tctx, uint8_t, maxsize);
97 if (!torture_setup_dir(cli, BASEDIR)) {
101 printf("Testing RAW_READ_READ\n");
102 io.generic.level = RAW_READ_READ;
104 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
106 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
111 printf("Trying empty file read\n");
112 io.read.in.file.fnum = fnum;
113 io.read.in.count = 1;
114 io.read.in.offset = 0;
115 io.read.in.remaining = 0;
116 io.read.out.data = buf;
117 status = smb_raw_read(cli->tree, &io);
119 CHECK_STATUS(status, NT_STATUS_OK);
120 CHECK_VALUE(io.read.out.nread, 0);
122 printf("Trying zero file read\n");
123 io.read.in.count = 0;
124 status = smb_raw_read(cli->tree, &io);
125 CHECK_STATUS(status, NT_STATUS_OK);
126 CHECK_VALUE(io.read.out.nread, 0);
128 printf("Trying bad fnum\n");
129 io.read.in.file.fnum = fnum+1;
130 status = smb_raw_read(cli->tree, &io);
131 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
132 io.read.in.file.fnum = fnum;
134 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
136 printf("Trying small read\n");
137 io.read.in.file.fnum = fnum;
138 io.read.in.offset = 0;
139 io.read.in.remaining = 0;
140 io.read.in.count = strlen(test_data);
141 status = smb_raw_read(cli->tree, &io);
142 CHECK_STATUS(status, NT_STATUS_OK);
143 CHECK_VALUE(io.read.out.nread, strlen(test_data));
144 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
146 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
150 printf("Trying short read\n");
151 io.read.in.offset = 1;
152 io.read.in.count = strlen(test_data);
153 status = smb_raw_read(cli->tree, &io);
154 CHECK_STATUS(status, NT_STATUS_OK);
155 CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
156 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
158 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
162 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
163 printf("Trying max offset\n");
164 io.read.in.offset = ~0;
165 io.read.in.count = strlen(test_data);
166 status = smb_raw_read(cli->tree, &io);
167 CHECK_STATUS(status, NT_STATUS_OK);
168 CHECK_VALUE(io.read.out.nread, 0);
171 setup_buffer(buf, seed, maxsize);
172 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
173 memset(buf, 0, maxsize);
175 printf("Trying large read\n");
176 io.read.in.offset = 0;
177 io.read.in.count = ~0;
178 status = smb_raw_read(cli->tree, &io);
179 CHECK_STATUS(status, NT_STATUS_OK);
180 CHECK_BUFFER(buf, seed, io.read.out.nread);
183 printf("Trying locked region\n");
185 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
186 printf("Failed to lock file at %d\n", __LINE__);
191 memset(buf, 0, maxsize);
192 io.read.in.offset = 0;
193 io.read.in.count = ~0;
194 status = smb_raw_read(cli->tree, &io);
195 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
199 smbcli_close(cli->tree, fnum);
200 smb_raw_exit(cli->session);
201 smbcli_deltree(cli->tree, BASEDIR);
209 static bool test_lockread(struct torture_context *tctx,
210 struct smbcli_state *cli)
217 const int maxsize = 90000;
218 const char *fname = BASEDIR "\\test.txt";
219 const char *test_data = "TEST DATA";
220 uint_t seed = time(NULL);
222 buf = talloc_zero_array(tctx, uint8_t, maxsize);
224 if (!torture_setup_dir(cli, BASEDIR)) {
228 printf("Testing RAW_READ_LOCKREAD\n");
229 io.generic.level = RAW_READ_LOCKREAD;
231 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
233 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
238 printf("Trying empty file read\n");
239 io.lockread.in.file.fnum = fnum;
240 io.lockread.in.count = 1;
241 io.lockread.in.offset = 1;
242 io.lockread.in.remaining = 0;
243 io.lockread.out.data = buf;
244 status = smb_raw_read(cli->tree, &io);
246 CHECK_STATUS(status, NT_STATUS_OK);
247 CHECK_VALUE(io.lockread.out.nread, 0);
249 status = smb_raw_read(cli->tree, &io);
250 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
252 status = smb_raw_read(cli->tree, &io);
253 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
255 printf("Trying zero file read\n");
256 io.lockread.in.count = 0;
257 status = smb_raw_read(cli->tree, &io);
258 CHECK_STATUS(status, NT_STATUS_OK);
260 smbcli_unlock(cli->tree, fnum, 1, 1);
262 printf("Trying bad fnum\n");
263 io.lockread.in.file.fnum = fnum+1;
264 status = smb_raw_read(cli->tree, &io);
265 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
266 io.lockread.in.file.fnum = fnum;
268 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
270 printf("Trying small read\n");
271 io.lockread.in.file.fnum = fnum;
272 io.lockread.in.offset = 0;
273 io.lockread.in.remaining = 0;
274 io.lockread.in.count = strlen(test_data);
275 status = smb_raw_read(cli->tree, &io);
276 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
278 smbcli_unlock(cli->tree, fnum, 1, 0);
280 status = smb_raw_read(cli->tree, &io);
281 CHECK_STATUS(status, NT_STATUS_OK);
282 CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
283 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
285 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
289 printf("Trying short read\n");
290 io.lockread.in.offset = 1;
291 io.lockread.in.count = strlen(test_data);
292 status = smb_raw_read(cli->tree, &io);
293 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
294 smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
295 status = smb_raw_read(cli->tree, &io);
296 CHECK_STATUS(status, NT_STATUS_OK);
298 CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
299 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
301 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
305 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
306 printf("Trying max offset\n");
307 io.lockread.in.offset = ~0;
308 io.lockread.in.count = strlen(test_data);
309 status = smb_raw_read(cli->tree, &io);
310 CHECK_STATUS(status, NT_STATUS_OK);
311 CHECK_VALUE(io.lockread.out.nread, 0);
314 setup_buffer(buf, seed, maxsize);
315 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
316 memset(buf, 0, maxsize);
318 printf("Trying large read\n");
319 io.lockread.in.offset = 0;
320 io.lockread.in.count = ~0;
321 status = smb_raw_read(cli->tree, &io);
322 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
323 smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
324 status = smb_raw_read(cli->tree, &io);
325 CHECK_STATUS(status, NT_STATUS_OK);
326 CHECK_BUFFER(buf, seed, io.lockread.out.nread);
327 smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
330 printf("Trying locked region\n");
332 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
333 printf("Failed to lock file at %d\n", __LINE__);
338 memset(buf, 0, maxsize);
339 io.lockread.in.offset = 0;
340 io.lockread.in.count = ~0;
341 status = smb_raw_read(cli->tree, &io);
342 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
346 smbcli_close(cli->tree, fnum);
347 smbcli_deltree(cli->tree, BASEDIR);
355 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
362 const int maxsize = 90000;
363 const char *fname = BASEDIR "\\test.txt";
364 const char *test_data = "TEST DATA";
365 uint_t seed = time(NULL);
367 buf = talloc_zero_array(tctx, uint8_t, maxsize);
369 if (!torture_setup_dir(cli, BASEDIR)) {
373 printf("Testing RAW_READ_READX\n");
375 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
377 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
382 printf("Trying empty file read\n");
383 io.generic.level = RAW_READ_READX;
384 io.readx.in.file.fnum = fnum;
385 io.readx.in.mincnt = 1;
386 io.readx.in.maxcnt = 1;
387 io.readx.in.offset = 0;
388 io.readx.in.remaining = 0;
389 io.readx.in.read_for_execute = false;
390 io.readx.out.data = buf;
391 status = smb_raw_read(cli->tree, &io);
393 CHECK_STATUS(status, NT_STATUS_OK);
394 CHECK_VALUE(io.readx.out.nread, 0);
395 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
396 CHECK_VALUE(io.readx.out.compaction_mode, 0);
398 printf("Trying zero file read\n");
399 io.readx.in.mincnt = 0;
400 io.readx.in.maxcnt = 0;
401 status = smb_raw_read(cli->tree, &io);
402 CHECK_STATUS(status, NT_STATUS_OK);
403 CHECK_VALUE(io.readx.out.nread, 0);
404 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
405 CHECK_VALUE(io.readx.out.compaction_mode, 0);
407 printf("Trying bad fnum\n");
408 io.readx.in.file.fnum = fnum+1;
409 status = smb_raw_read(cli->tree, &io);
410 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
411 io.readx.in.file.fnum = fnum;
413 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
415 printf("Trying small read\n");
416 io.readx.in.file.fnum = fnum;
417 io.readx.in.offset = 0;
418 io.readx.in.remaining = 0;
419 io.readx.in.read_for_execute = false;
420 io.readx.in.mincnt = strlen(test_data);
421 io.readx.in.maxcnt = strlen(test_data);
422 status = smb_raw_read(cli->tree, &io);
423 CHECK_STATUS(status, NT_STATUS_OK);
424 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
425 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
426 CHECK_VALUE(io.readx.out.compaction_mode, 0);
427 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
429 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
433 printf("Trying short read\n");
434 io.readx.in.offset = 1;
435 io.readx.in.mincnt = strlen(test_data);
436 io.readx.in.maxcnt = strlen(test_data);
437 status = smb_raw_read(cli->tree, &io);
438 CHECK_STATUS(status, NT_STATUS_OK);
439 CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
440 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
441 CHECK_VALUE(io.readx.out.compaction_mode, 0);
442 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
444 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
448 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
449 printf("Trying max offset\n");
450 io.readx.in.offset = 0xffffffff;
451 io.readx.in.mincnt = strlen(test_data);
452 io.readx.in.maxcnt = strlen(test_data);
453 status = smb_raw_read(cli->tree, &io);
454 CHECK_STATUS(status, NT_STATUS_OK);
455 CHECK_VALUE(io.readx.out.nread, 0);
456 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
457 CHECK_VALUE(io.readx.out.compaction_mode, 0);
460 printf("Trying mincnt past EOF\n");
461 memset(buf, 0, maxsize);
462 io.readx.in.offset = 0;
463 io.readx.in.mincnt = 100;
464 io.readx.in.maxcnt = 110;
465 status = smb_raw_read(cli->tree, &io);
466 CHECK_STATUS(status, NT_STATUS_OK);
467 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
468 CHECK_VALUE(io.readx.out.compaction_mode, 0);
469 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
470 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
472 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
477 setup_buffer(buf, seed, maxsize);
478 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
479 memset(buf, 0, maxsize);
481 printf("Trying large read\n");
482 io.readx.in.offset = 0;
483 io.readx.in.mincnt = 0xFFFF;
484 io.readx.in.maxcnt = 0xFFFF;
485 status = smb_raw_read(cli->tree, &io);
486 CHECK_STATUS(status, NT_STATUS_OK);
487 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
488 CHECK_VALUE(io.readx.out.compaction_mode, 0);
489 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
490 CHECK_BUFFER(buf, seed, io.readx.out.nread);
492 printf("Trying extra large read\n");
493 io.readx.in.offset = 0;
494 io.readx.in.mincnt = 100;
495 io.readx.in.maxcnt = 80000;
496 status = smb_raw_read(cli->tree, &io);
497 CHECK_STATUS(status, NT_STATUS_OK);
498 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
499 CHECK_VALUE(io.readx.out.compaction_mode, 0);
500 if (torture_setting_bool(tctx, "samba3", false) ||
501 torture_setting_bool(tctx, "samba4", false)) {
502 printf("SAMBA: large read extension\n");
503 CHECK_VALUE(io.readx.out.nread, 80000);
505 CHECK_VALUE(io.readx.out.nread, 0);
507 CHECK_BUFFER(buf, seed, io.readx.out.nread);
509 printf("Trying mincnt > maxcnt\n");
510 memset(buf, 0, maxsize);
511 io.readx.in.offset = 0;
512 io.readx.in.mincnt = 30000;
513 io.readx.in.maxcnt = 20000;
514 status = smb_raw_read(cli->tree, &io);
515 CHECK_STATUS(status, NT_STATUS_OK);
516 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
517 CHECK_VALUE(io.readx.out.compaction_mode, 0);
518 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
519 CHECK_BUFFER(buf, seed, io.readx.out.nread);
521 printf("Trying mincnt < maxcnt\n");
522 memset(buf, 0, maxsize);
523 io.readx.in.offset = 0;
524 io.readx.in.mincnt = 20000;
525 io.readx.in.maxcnt = 30000;
526 status = smb_raw_read(cli->tree, &io);
527 CHECK_STATUS(status, NT_STATUS_OK);
528 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
529 CHECK_VALUE(io.readx.out.compaction_mode, 0);
530 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
531 CHECK_BUFFER(buf, seed, io.readx.out.nread);
533 if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
534 printf("Trying large readx\n");
535 io.readx.in.offset = 0;
536 io.readx.in.mincnt = 0;
537 io.readx.in.maxcnt = 0x10000 - 1;
538 status = smb_raw_read(cli->tree, &io);
539 CHECK_STATUS(status, NT_STATUS_OK);
540 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
542 io.readx.in.maxcnt = 0x10000;
543 status = smb_raw_read(cli->tree, &io);
544 CHECK_STATUS(status, NT_STATUS_OK);
545 if (torture_setting_bool(tctx, "samba3", false) ||
546 torture_setting_bool(tctx, "samba4", false)) {
547 printf("SAMBA: large read extension\n");
548 CHECK_VALUE(io.readx.out.nread, 0x10000);
550 CHECK_VALUE(io.readx.out.nread, 0);
553 io.readx.in.maxcnt = 0x10001;
554 status = smb_raw_read(cli->tree, &io);
555 CHECK_STATUS(status, NT_STATUS_OK);
556 if (torture_setting_bool(tctx, "samba3", false) ||
557 torture_setting_bool(tctx, "samba4", false)) {
558 printf("SAMBA: large read extension\n");
559 CHECK_VALUE(io.readx.out.nread, 0x10001);
561 CHECK_VALUE(io.readx.out.nread, 0);
564 printf("Server does not support the CAP_LARGE_READX extension\n");
567 printf("Trying locked region\n");
569 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
570 printf("Failed to lock file at %d\n", __LINE__);
575 memset(buf, 0, maxsize);
576 io.readx.in.offset = 0;
577 io.readx.in.mincnt = 100;
578 io.readx.in.maxcnt = 200;
579 status = smb_raw_read(cli->tree, &io);
580 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
582 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
583 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
587 printf("Trying large offset read\n");
588 io.readx.in.offset = ((uint64_t)0x2) << 32;
589 io.readx.in.mincnt = 10;
590 io.readx.in.maxcnt = 10;
591 status = smb_raw_read(cli->tree, &io);
592 CHECK_STATUS(status, NT_STATUS_OK);
593 CHECK_VALUE(io.readx.out.nread, 0);
595 if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
596 printf("Failed to lock file at %d\n", __LINE__);
601 status = smb_raw_read(cli->tree, &io);
602 CHECK_STATUS(status, NT_STATUS_OK);
603 CHECK_VALUE(io.readx.out.nread, 0);
606 smbcli_close(cli->tree, fnum);
607 smbcli_deltree(cli->tree, BASEDIR);
615 static bool test_readbraw(struct torture_context *tctx,
616 struct smbcli_state *cli)
623 const int maxsize = 90000;
624 const char *fname = BASEDIR "\\test.txt";
625 const char *test_data = "TEST DATA";
626 uint_t seed = time(NULL);
628 if (!cli->transport->negotiate.readbraw_supported) {
629 printf("Server does not support readbraw - skipping\n");
633 buf = talloc_zero_array(tctx, uint8_t, maxsize);
635 if (!torture_setup_dir(cli, BASEDIR)) {
639 printf("Testing RAW_READ_READBRAW\n");
641 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
643 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
648 printf("Trying empty file read\n");
649 io.generic.level = RAW_READ_READBRAW;
650 io.readbraw.in.file.fnum = fnum;
651 io.readbraw.in.mincnt = 1;
652 io.readbraw.in.maxcnt = 1;
653 io.readbraw.in.offset = 0;
654 io.readbraw.in.timeout = 0;
655 io.readbraw.out.data = buf;
656 status = smb_raw_read(cli->tree, &io);
658 CHECK_STATUS(status, NT_STATUS_OK);
659 CHECK_VALUE(io.readbraw.out.nread, 0);
661 printf("Trying zero file read\n");
662 io.readbraw.in.mincnt = 0;
663 io.readbraw.in.maxcnt = 0;
664 status = smb_raw_read(cli->tree, &io);
665 CHECK_STATUS(status, NT_STATUS_OK);
666 CHECK_VALUE(io.readbraw.out.nread, 0);
668 printf("Trying bad fnum\n");
669 io.readbraw.in.file.fnum = fnum+1;
670 status = smb_raw_read(cli->tree, &io);
671 CHECK_STATUS(status, NT_STATUS_OK);
672 CHECK_VALUE(io.readbraw.out.nread, 0);
673 io.readbraw.in.file.fnum = fnum;
675 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
677 printf("Trying small read\n");
678 io.readbraw.in.file.fnum = fnum;
679 io.readbraw.in.offset = 0;
680 io.readbraw.in.mincnt = strlen(test_data);
681 io.readbraw.in.maxcnt = strlen(test_data);
682 status = smb_raw_read(cli->tree, &io);
683 CHECK_STATUS(status, NT_STATUS_OK);
684 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
685 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
687 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
691 printf("Trying short read\n");
692 io.readbraw.in.offset = 1;
693 io.readbraw.in.mincnt = strlen(test_data);
694 io.readbraw.in.maxcnt = strlen(test_data);
695 status = smb_raw_read(cli->tree, &io);
696 CHECK_STATUS(status, NT_STATUS_OK);
697 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
698 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
700 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
704 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
705 printf("Trying max offset\n");
706 io.readbraw.in.offset = ~0;
707 io.readbraw.in.mincnt = strlen(test_data);
708 io.readbraw.in.maxcnt = strlen(test_data);
709 status = smb_raw_read(cli->tree, &io);
710 CHECK_STATUS(status, NT_STATUS_OK);
711 CHECK_VALUE(io.readbraw.out.nread, 0);
714 setup_buffer(buf, seed, maxsize);
715 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
716 memset(buf, 0, maxsize);
718 printf("Trying large read\n");
719 io.readbraw.in.offset = 0;
720 io.readbraw.in.mincnt = ~0;
721 io.readbraw.in.maxcnt = ~0;
722 status = smb_raw_read(cli->tree, &io);
723 CHECK_STATUS(status, NT_STATUS_OK);
724 CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
725 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
727 printf("Trying mincnt > maxcnt\n");
728 memset(buf, 0, maxsize);
729 io.readbraw.in.offset = 0;
730 io.readbraw.in.mincnt = 30000;
731 io.readbraw.in.maxcnt = 20000;
732 status = smb_raw_read(cli->tree, &io);
733 CHECK_STATUS(status, NT_STATUS_OK);
734 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
735 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
737 printf("Trying mincnt < maxcnt\n");
738 memset(buf, 0, maxsize);
739 io.readbraw.in.offset = 0;
740 io.readbraw.in.mincnt = 20000;
741 io.readbraw.in.maxcnt = 30000;
742 status = smb_raw_read(cli->tree, &io);
743 CHECK_STATUS(status, NT_STATUS_OK);
744 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
745 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
747 printf("Trying locked region\n");
749 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
750 printf("Failed to lock file at %d\n", __LINE__);
755 memset(buf, 0, maxsize);
756 io.readbraw.in.offset = 0;
757 io.readbraw.in.mincnt = 100;
758 io.readbraw.in.maxcnt = 200;
759 status = smb_raw_read(cli->tree, &io);
760 CHECK_STATUS(status, NT_STATUS_OK);
761 CHECK_VALUE(io.readbraw.out.nread, 0);
763 printf("Trying locked region with timeout\n");
764 memset(buf, 0, maxsize);
765 io.readbraw.in.offset = 0;
766 io.readbraw.in.mincnt = 100;
767 io.readbraw.in.maxcnt = 200;
768 io.readbraw.in.timeout = 10000;
769 status = smb_raw_read(cli->tree, &io);
770 CHECK_STATUS(status, NT_STATUS_OK);
771 CHECK_VALUE(io.readbraw.out.nread, 0);
773 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
774 printf("Trying large offset read\n");
775 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
776 io.readbraw.in.mincnt = 10;
777 io.readbraw.in.maxcnt = 10;
778 io.readbraw.in.timeout = 0;
779 status = smb_raw_read(cli->tree, &io);
780 CHECK_STATUS(status, NT_STATUS_OK);
781 CHECK_VALUE(io.readbraw.out.nread, 0);
785 smbcli_close(cli->tree, fnum);
786 smbcli_deltree(cli->tree, BASEDIR);
791 test read for execute
793 static bool test_read_for_execute(struct torture_context *tctx,
794 struct smbcli_state *cli)
803 const int maxsize = 900;
804 const char *fname = BASEDIR "\\test.txt";
805 const uint8_t data[] = "TEST DATA";
807 buf = talloc_zero_array(tctx, uint8_t, maxsize);
809 if (!torture_setup_dir(cli, BASEDIR)) {
813 printf("Testing RAW_READ_READX with read_for_execute\n");
815 op.generic.level = RAW_OPEN_NTCREATEX;
816 op.ntcreatex.in.root_fid.fnum = 0;
817 op.ntcreatex.in.flags = 0;
818 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
819 op.ntcreatex.in.create_options = 0;
820 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
821 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
822 op.ntcreatex.in.alloc_size = 0;
823 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
824 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
825 op.ntcreatex.in.security_flags = 0;
826 op.ntcreatex.in.fname = fname;
827 status = smb_raw_open(cli->tree, tctx, &op);
828 CHECK_STATUS(status, NT_STATUS_OK);
829 fnum = op.ntcreatex.out.file.fnum;
831 wr.generic.level = RAW_WRITE_WRITEX;
832 wr.writex.in.file.fnum = fnum;
833 wr.writex.in.offset = 0;
834 wr.writex.in.wmode = 0;
835 wr.writex.in.remaining = 0;
836 wr.writex.in.count = ARRAY_SIZE(data);
837 wr.writex.in.data = data;
838 status = smb_raw_write(cli->tree, &wr);
839 CHECK_STATUS(status, NT_STATUS_OK);
840 CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
842 status = smbcli_close(cli->tree, fnum);
843 CHECK_STATUS(status, NT_STATUS_OK);
845 printf("open file with SEC_FILE_EXECUTE\n");
846 op.generic.level = RAW_OPEN_NTCREATEX;
847 op.ntcreatex.in.root_fid.fnum = 0;
848 op.ntcreatex.in.flags = 0;
849 op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
850 op.ntcreatex.in.create_options = 0;
851 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
852 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
853 op.ntcreatex.in.alloc_size = 0;
854 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
855 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
856 op.ntcreatex.in.security_flags = 0;
857 op.ntcreatex.in.fname = fname;
858 status = smb_raw_open(cli->tree, tctx, &op);
859 CHECK_STATUS(status, NT_STATUS_OK);
860 fnum = op.ntcreatex.out.file.fnum;
862 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
863 rd.generic.level = RAW_READ_READX;
864 rd.readx.in.file.fnum = fnum;
865 rd.readx.in.mincnt = 0;
866 rd.readx.in.maxcnt = maxsize;
867 rd.readx.in.offset = 0;
868 rd.readx.in.remaining = 0;
869 rd.readx.in.read_for_execute = true;
870 rd.readx.out.data = buf;
871 status = smb_raw_read(cli->tree, &rd);
872 CHECK_STATUS(status, NT_STATUS_OK);
873 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
874 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
875 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
877 printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
878 rd.generic.level = RAW_READ_READX;
879 rd.readx.in.file.fnum = fnum;
880 rd.readx.in.mincnt = 0;
881 rd.readx.in.maxcnt = maxsize;
882 rd.readx.in.offset = 0;
883 rd.readx.in.remaining = 0;
884 rd.readx.in.read_for_execute = false;
885 rd.readx.out.data = buf;
886 status = smb_raw_read(cli->tree, &rd);
887 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
889 status = smbcli_close(cli->tree, fnum);
890 CHECK_STATUS(status, NT_STATUS_OK);
892 printf("open file with SEC_FILE_READ_DATA\n");
893 op.generic.level = RAW_OPEN_NTCREATEX;
894 op.ntcreatex.in.root_fid.fnum = 0;
895 op.ntcreatex.in.flags = 0;
896 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
897 op.ntcreatex.in.create_options = 0;
898 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
899 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
900 op.ntcreatex.in.alloc_size = 0;
901 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
902 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
903 op.ntcreatex.in.security_flags = 0;
904 op.ntcreatex.in.fname = fname;
905 status = smb_raw_open(cli->tree, tctx, &op);
906 CHECK_STATUS(status, NT_STATUS_OK);
907 fnum = op.ntcreatex.out.file.fnum;
909 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
910 rd.generic.level = RAW_READ_READX;
911 rd.readx.in.file.fnum = fnum;
912 rd.readx.in.mincnt = 0;
913 rd.readx.in.maxcnt = maxsize;
914 rd.readx.in.offset = 0;
915 rd.readx.in.remaining = 0;
916 rd.readx.in.read_for_execute = true;
917 rd.readx.out.data = buf;
918 status = smb_raw_read(cli->tree, &rd);
919 CHECK_STATUS(status, NT_STATUS_OK);
920 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
921 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
922 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
924 printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
925 rd.generic.level = RAW_READ_READX;
926 rd.readx.in.file.fnum = fnum;
927 rd.readx.in.mincnt = 0;
928 rd.readx.in.maxcnt = maxsize;
929 rd.readx.in.offset = 0;
930 rd.readx.in.remaining = 0;
931 rd.readx.in.read_for_execute = false;
932 rd.readx.out.data = buf;
933 status = smb_raw_read(cli->tree, &rd);
934 CHECK_STATUS(status, NT_STATUS_OK);
935 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
936 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
937 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
940 smbcli_close(cli->tree, fnum);
941 smbcli_deltree(cli->tree, BASEDIR);
947 basic testing of read calls
949 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
951 struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
953 torture_suite_add_1smb_test(suite, "read", test_read);
954 torture_suite_add_1smb_test(suite, "readx", test_readx);
955 torture_suite_add_1smb_test(suite, "lockread", test_lockread);
956 torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
957 torture_suite_add_1smb_test(suite, "read for execute",
958 test_read_for_execute);