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, unsigned int 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, unsigned int 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 unsigned int seed = time(NULL);
95 buf = talloc_zero_array(tctx, uint8_t, maxsize);
97 if (!torture_setting_bool(tctx, "read_support", true)) {
98 printf("server refuses to support READ\n");
102 if (!torture_setup_dir(cli, BASEDIR)) {
106 printf("Testing RAW_READ_READ\n");
107 io.generic.level = RAW_READ_READ;
109 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
111 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
116 printf("Trying empty file read\n");
117 io.read.in.file.fnum = fnum;
118 io.read.in.count = 1;
119 io.read.in.offset = 0;
120 io.read.in.remaining = 0;
121 io.read.out.data = buf;
122 status = smb_raw_read(cli->tree, &io);
124 CHECK_STATUS(status, NT_STATUS_OK);
125 CHECK_VALUE(io.read.out.nread, 0);
127 printf("Trying zero file read\n");
128 io.read.in.count = 0;
129 status = smb_raw_read(cli->tree, &io);
130 CHECK_STATUS(status, NT_STATUS_OK);
131 CHECK_VALUE(io.read.out.nread, 0);
133 printf("Trying bad fnum\n");
134 io.read.in.file.fnum = fnum+1;
135 status = smb_raw_read(cli->tree, &io);
136 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
137 io.read.in.file.fnum = fnum;
139 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
141 printf("Trying small read\n");
142 io.read.in.file.fnum = fnum;
143 io.read.in.offset = 0;
144 io.read.in.remaining = 0;
145 io.read.in.count = strlen(test_data);
146 status = smb_raw_read(cli->tree, &io);
147 CHECK_STATUS(status, NT_STATUS_OK);
148 CHECK_VALUE(io.read.out.nread, strlen(test_data));
149 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
151 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
155 printf("Trying short read\n");
156 io.read.in.offset = 1;
157 io.read.in.count = strlen(test_data);
158 status = smb_raw_read(cli->tree, &io);
159 CHECK_STATUS(status, NT_STATUS_OK);
160 CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
161 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
163 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
167 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
168 printf("Trying max offset\n");
169 io.read.in.offset = ~0;
170 io.read.in.count = strlen(test_data);
171 status = smb_raw_read(cli->tree, &io);
172 CHECK_STATUS(status, NT_STATUS_OK);
173 CHECK_VALUE(io.read.out.nread, 0);
176 setup_buffer(buf, seed, maxsize);
177 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
178 memset(buf, 0, maxsize);
180 printf("Trying large read\n");
181 io.read.in.offset = 0;
182 io.read.in.count = ~0;
183 status = smb_raw_read(cli->tree, &io);
184 CHECK_STATUS(status, NT_STATUS_OK);
185 CHECK_BUFFER(buf, seed, io.read.out.nread);
188 printf("Trying locked region\n");
190 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
191 printf("Failed to lock file at %d\n", __LINE__);
196 memset(buf, 0, maxsize);
197 io.read.in.offset = 0;
198 io.read.in.count = ~0;
199 status = smb_raw_read(cli->tree, &io);
200 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
204 smbcli_close(cli->tree, fnum);
205 smb_raw_exit(cli->session);
206 smbcli_deltree(cli->tree, BASEDIR);
214 static bool test_lockread(struct torture_context *tctx,
215 struct smbcli_state *cli)
222 const int maxsize = 90000;
223 const char *fname = BASEDIR "\\test.txt";
224 const char *test_data = "TEST DATA";
225 unsigned int seed = time(NULL);
227 if (!cli->transport->negotiate.lockread_supported) {
228 printf("Server does not support lockread - skipping\n");
232 buf = talloc_zero_array(tctx, uint8_t, maxsize);
234 if (!torture_setup_dir(cli, BASEDIR)) {
238 printf("Testing RAW_READ_LOCKREAD\n");
239 io.generic.level = RAW_READ_LOCKREAD;
241 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
243 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
248 printf("Trying empty file read\n");
249 io.lockread.in.file.fnum = fnum;
250 io.lockread.in.count = 1;
251 io.lockread.in.offset = 1;
252 io.lockread.in.remaining = 0;
253 io.lockread.out.data = buf;
254 status = smb_raw_read(cli->tree, &io);
256 CHECK_STATUS(status, NT_STATUS_OK);
257 CHECK_VALUE(io.lockread.out.nread, 0);
259 status = smb_raw_read(cli->tree, &io);
260 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
262 status = smb_raw_read(cli->tree, &io);
263 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
265 printf("Trying zero file read\n");
266 io.lockread.in.count = 0;
267 status = smb_raw_read(cli->tree, &io);
268 CHECK_STATUS(status, NT_STATUS_OK);
270 smbcli_unlock(cli->tree, fnum, 1, 1);
272 printf("Trying bad fnum\n");
273 io.lockread.in.file.fnum = fnum+1;
274 status = smb_raw_read(cli->tree, &io);
275 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
276 io.lockread.in.file.fnum = fnum;
278 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
280 printf("Trying small read\n");
281 io.lockread.in.file.fnum = fnum;
282 io.lockread.in.offset = 0;
283 io.lockread.in.remaining = 0;
284 io.lockread.in.count = strlen(test_data);
285 status = smb_raw_read(cli->tree, &io);
286 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
288 smbcli_unlock(cli->tree, fnum, 1, 0);
290 status = smb_raw_read(cli->tree, &io);
291 CHECK_STATUS(status, NT_STATUS_OK);
292 CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
293 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
295 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
299 printf("Trying short read\n");
300 io.lockread.in.offset = 1;
301 io.lockread.in.count = strlen(test_data);
302 status = smb_raw_read(cli->tree, &io);
303 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
304 smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
305 status = smb_raw_read(cli->tree, &io);
306 CHECK_STATUS(status, NT_STATUS_OK);
308 CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
309 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
311 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
315 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
316 printf("Trying max offset\n");
317 io.lockread.in.offset = ~0;
318 io.lockread.in.count = strlen(test_data);
319 status = smb_raw_read(cli->tree, &io);
320 CHECK_STATUS(status, NT_STATUS_OK);
321 CHECK_VALUE(io.lockread.out.nread, 0);
324 setup_buffer(buf, seed, maxsize);
325 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
326 memset(buf, 0, maxsize);
328 printf("Trying large read\n");
329 io.lockread.in.offset = 0;
330 io.lockread.in.count = ~0;
331 status = smb_raw_read(cli->tree, &io);
332 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
333 smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
334 status = smb_raw_read(cli->tree, &io);
335 CHECK_STATUS(status, NT_STATUS_OK);
336 CHECK_BUFFER(buf, seed, io.lockread.out.nread);
337 smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
340 printf("Trying locked region\n");
342 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
343 printf("Failed to lock file at %d\n", __LINE__);
348 memset(buf, 0, maxsize);
349 io.lockread.in.offset = 0;
350 io.lockread.in.count = ~0;
351 status = smb_raw_read(cli->tree, &io);
352 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
356 smbcli_close(cli->tree, fnum);
357 smbcli_deltree(cli->tree, BASEDIR);
365 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
372 const int maxsize = 90000;
373 const char *fname = BASEDIR "\\test.txt";
374 const char *test_data = "TEST DATA";
375 unsigned int seed = time(NULL);
377 buf = talloc_zero_array(tctx, uint8_t, maxsize);
379 if (!torture_setup_dir(cli, BASEDIR)) {
383 printf("Testing RAW_READ_READX\n");
385 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
387 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
392 printf("Trying empty file read\n");
393 io.generic.level = RAW_READ_READX;
394 io.readx.in.file.fnum = fnum;
395 io.readx.in.mincnt = 1;
396 io.readx.in.maxcnt = 1;
397 io.readx.in.offset = 0;
398 io.readx.in.remaining = 0;
399 io.readx.in.read_for_execute = false;
400 io.readx.out.data = buf;
401 status = smb_raw_read(cli->tree, &io);
403 CHECK_STATUS(status, NT_STATUS_OK);
404 CHECK_VALUE(io.readx.out.nread, 0);
405 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
406 CHECK_VALUE(io.readx.out.compaction_mode, 0);
408 printf("Trying zero file read\n");
409 io.readx.in.mincnt = 0;
410 io.readx.in.maxcnt = 0;
411 status = smb_raw_read(cli->tree, &io);
412 CHECK_STATUS(status, NT_STATUS_OK);
413 CHECK_VALUE(io.readx.out.nread, 0);
414 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
415 CHECK_VALUE(io.readx.out.compaction_mode, 0);
417 printf("Trying bad fnum\n");
418 io.readx.in.file.fnum = fnum+1;
419 status = smb_raw_read(cli->tree, &io);
420 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
421 io.readx.in.file.fnum = fnum;
423 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
425 printf("Trying small read\n");
426 io.readx.in.file.fnum = fnum;
427 io.readx.in.offset = 0;
428 io.readx.in.remaining = 0;
429 io.readx.in.read_for_execute = false;
430 io.readx.in.mincnt = strlen(test_data);
431 io.readx.in.maxcnt = strlen(test_data);
432 status = smb_raw_read(cli->tree, &io);
433 CHECK_STATUS(status, NT_STATUS_OK);
434 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
435 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
436 CHECK_VALUE(io.readx.out.compaction_mode, 0);
437 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
439 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
443 printf("Trying short read\n");
444 io.readx.in.offset = 1;
445 io.readx.in.mincnt = strlen(test_data);
446 io.readx.in.maxcnt = strlen(test_data);
447 status = smb_raw_read(cli->tree, &io);
448 CHECK_STATUS(status, NT_STATUS_OK);
449 CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
450 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
451 CHECK_VALUE(io.readx.out.compaction_mode, 0);
452 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
454 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
458 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
459 printf("Trying max offset\n");
460 io.readx.in.offset = 0xffffffff;
461 io.readx.in.mincnt = strlen(test_data);
462 io.readx.in.maxcnt = strlen(test_data);
463 status = smb_raw_read(cli->tree, &io);
464 CHECK_STATUS(status, NT_STATUS_OK);
465 CHECK_VALUE(io.readx.out.nread, 0);
466 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
467 CHECK_VALUE(io.readx.out.compaction_mode, 0);
470 printf("Trying mincnt past EOF\n");
471 memset(buf, 0, maxsize);
472 io.readx.in.offset = 0;
473 io.readx.in.mincnt = 100;
474 io.readx.in.maxcnt = 110;
475 status = smb_raw_read(cli->tree, &io);
476 CHECK_STATUS(status, NT_STATUS_OK);
477 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
478 CHECK_VALUE(io.readx.out.compaction_mode, 0);
479 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
480 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
482 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
487 setup_buffer(buf, seed, maxsize);
488 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
489 memset(buf, 0, maxsize);
491 printf("Trying page sized read\n");
492 io.readx.in.offset = 0;
493 io.readx.in.mincnt = 0x1000;
494 io.readx.in.maxcnt = 0x1000;
495 status = smb_raw_read(cli->tree, &io);
496 CHECK_STATUS(status, NT_STATUS_OK);
497 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
498 CHECK_VALUE(io.readx.out.compaction_mode, 0);
499 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
500 CHECK_BUFFER(buf, seed, io.readx.out.nread);
502 printf("Trying page + 1 sized read (check alignment)\n");
503 io.readx.in.offset = 0;
504 io.readx.in.mincnt = 0x1001;
505 io.readx.in.maxcnt = 0x1001;
506 status = smb_raw_read(cli->tree, &io);
507 CHECK_STATUS(status, NT_STATUS_OK);
508 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
509 CHECK_VALUE(io.readx.out.compaction_mode, 0);
510 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
511 CHECK_BUFFER(buf, seed, io.readx.out.nread);
513 printf("Trying large read (UINT16_MAX)\n");
514 io.readx.in.offset = 0;
515 io.readx.in.mincnt = 0xFFFF;
516 io.readx.in.maxcnt = 0xFFFF;
517 status = smb_raw_read(cli->tree, &io);
518 CHECK_STATUS(status, NT_STATUS_OK);
519 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
520 CHECK_VALUE(io.readx.out.compaction_mode, 0);
521 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
522 CHECK_BUFFER(buf, seed, io.readx.out.nread);
524 printf("Trying extra large read\n");
525 io.readx.in.offset = 0;
526 io.readx.in.mincnt = 100;
527 io.readx.in.maxcnt = 80000;
528 status = smb_raw_read(cli->tree, &io);
529 CHECK_STATUS(status, NT_STATUS_OK);
530 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
531 CHECK_VALUE(io.readx.out.compaction_mode, 0);
532 if (torture_setting_bool(tctx, "samba3", false) ||
533 torture_setting_bool(tctx, "samba4", false)) {
534 printf("SAMBA: large read extension\n");
535 CHECK_VALUE(io.readx.out.nread, 80000);
537 CHECK_VALUE(io.readx.out.nread, 0);
539 CHECK_BUFFER(buf, seed, io.readx.out.nread);
541 printf("Trying mincnt > maxcnt\n");
542 memset(buf, 0, maxsize);
543 io.readx.in.offset = 0;
544 io.readx.in.mincnt = 30000;
545 io.readx.in.maxcnt = 20000;
546 status = smb_raw_read(cli->tree, &io);
547 CHECK_STATUS(status, NT_STATUS_OK);
548 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
549 CHECK_VALUE(io.readx.out.compaction_mode, 0);
550 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
551 CHECK_BUFFER(buf, seed, io.readx.out.nread);
553 printf("Trying mincnt < maxcnt\n");
554 memset(buf, 0, maxsize);
555 io.readx.in.offset = 0;
556 io.readx.in.mincnt = 20000;
557 io.readx.in.maxcnt = 30000;
558 status = smb_raw_read(cli->tree, &io);
559 CHECK_STATUS(status, NT_STATUS_OK);
560 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
561 CHECK_VALUE(io.readx.out.compaction_mode, 0);
562 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
563 CHECK_BUFFER(buf, seed, io.readx.out.nread);
565 if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
566 printf("Trying large readx\n");
567 io.readx.in.offset = 0;
568 io.readx.in.mincnt = 0;
569 io.readx.in.maxcnt = 0x10000 - 1;
570 status = smb_raw_read(cli->tree, &io);
571 CHECK_STATUS(status, NT_STATUS_OK);
572 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
574 io.readx.in.maxcnt = 0x10000;
575 status = smb_raw_read(cli->tree, &io);
576 CHECK_STATUS(status, NT_STATUS_OK);
577 if (torture_setting_bool(tctx, "samba3", false) ||
578 torture_setting_bool(tctx, "samba4", false)) {
579 printf("SAMBA: large read extension\n");
580 CHECK_VALUE(io.readx.out.nread, 0x10000);
582 CHECK_VALUE(io.readx.out.nread, 0);
585 io.readx.in.maxcnt = 0x10001;
586 status = smb_raw_read(cli->tree, &io);
587 CHECK_STATUS(status, NT_STATUS_OK);
588 if (torture_setting_bool(tctx, "samba3", false) ||
589 torture_setting_bool(tctx, "samba4", false)) {
590 printf("SAMBA: large read extension\n");
591 CHECK_VALUE(io.readx.out.nread, 0x10001);
593 CHECK_VALUE(io.readx.out.nread, 0);
596 printf("Server does not support the CAP_LARGE_READX extension\n");
599 printf("Trying locked region\n");
601 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
602 printf("Failed to lock file at %d\n", __LINE__);
607 memset(buf, 0, maxsize);
608 io.readx.in.offset = 0;
609 io.readx.in.mincnt = 100;
610 io.readx.in.maxcnt = 200;
611 status = smb_raw_read(cli->tree, &io);
612 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
614 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
615 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
619 printf("Trying large offset read\n");
620 io.readx.in.offset = ((uint64_t)0x2) << 32;
621 io.readx.in.mincnt = 10;
622 io.readx.in.maxcnt = 10;
623 status = smb_raw_read(cli->tree, &io);
624 CHECK_STATUS(status, NT_STATUS_OK);
625 CHECK_VALUE(io.readx.out.nread, 0);
627 if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
628 printf("Failed to lock file at %d\n", __LINE__);
633 status = smb_raw_read(cli->tree, &io);
634 CHECK_STATUS(status, NT_STATUS_OK);
635 CHECK_VALUE(io.readx.out.nread, 0);
638 smbcli_close(cli->tree, fnum);
639 smbcli_deltree(cli->tree, BASEDIR);
647 static bool test_readbraw(struct torture_context *tctx,
648 struct smbcli_state *cli)
655 const int maxsize = 90000;
656 const char *fname = BASEDIR "\\test.txt";
657 const char *test_data = "TEST DATA";
658 unsigned int seed = time(NULL);
660 if (!cli->transport->negotiate.readbraw_supported) {
661 printf("Server does not support readbraw - skipping\n");
665 buf = talloc_zero_array(tctx, uint8_t, maxsize);
667 if (!torture_setup_dir(cli, BASEDIR)) {
671 printf("Testing RAW_READ_READBRAW\n");
673 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
675 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
680 printf("Trying empty file read\n");
681 io.generic.level = RAW_READ_READBRAW;
682 io.readbraw.in.file.fnum = fnum;
683 io.readbraw.in.mincnt = 1;
684 io.readbraw.in.maxcnt = 1;
685 io.readbraw.in.offset = 0;
686 io.readbraw.in.timeout = 0;
687 io.readbraw.out.data = buf;
688 status = smb_raw_read(cli->tree, &io);
690 CHECK_STATUS(status, NT_STATUS_OK);
691 CHECK_VALUE(io.readbraw.out.nread, 0);
693 printf("Trying zero file read\n");
694 io.readbraw.in.mincnt = 0;
695 io.readbraw.in.maxcnt = 0;
696 status = smb_raw_read(cli->tree, &io);
697 CHECK_STATUS(status, NT_STATUS_OK);
698 CHECK_VALUE(io.readbraw.out.nread, 0);
700 printf("Trying bad fnum\n");
701 io.readbraw.in.file.fnum = fnum+1;
702 status = smb_raw_read(cli->tree, &io);
703 CHECK_STATUS(status, NT_STATUS_OK);
704 CHECK_VALUE(io.readbraw.out.nread, 0);
705 io.readbraw.in.file.fnum = fnum;
707 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
709 printf("Trying small read\n");
710 io.readbraw.in.file.fnum = fnum;
711 io.readbraw.in.offset = 0;
712 io.readbraw.in.mincnt = strlen(test_data);
713 io.readbraw.in.maxcnt = strlen(test_data);
714 status = smb_raw_read(cli->tree, &io);
715 CHECK_STATUS(status, NT_STATUS_OK);
716 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
717 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
719 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
723 printf("Trying short read\n");
724 io.readbraw.in.offset = 1;
725 io.readbraw.in.mincnt = strlen(test_data);
726 io.readbraw.in.maxcnt = strlen(test_data);
727 status = smb_raw_read(cli->tree, &io);
728 CHECK_STATUS(status, NT_STATUS_OK);
729 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
730 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
732 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
736 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
737 printf("Trying max offset\n");
738 io.readbraw.in.offset = ~0;
739 io.readbraw.in.mincnt = strlen(test_data);
740 io.readbraw.in.maxcnt = strlen(test_data);
741 status = smb_raw_read(cli->tree, &io);
742 CHECK_STATUS(status, NT_STATUS_OK);
743 CHECK_VALUE(io.readbraw.out.nread, 0);
746 setup_buffer(buf, seed, maxsize);
747 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
748 memset(buf, 0, maxsize);
750 printf("Trying large read\n");
751 io.readbraw.in.offset = 0;
752 io.readbraw.in.mincnt = ~0;
753 io.readbraw.in.maxcnt = ~0;
754 status = smb_raw_read(cli->tree, &io);
755 CHECK_STATUS(status, NT_STATUS_OK);
756 CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
757 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
759 printf("Trying mincnt > maxcnt\n");
760 memset(buf, 0, maxsize);
761 io.readbraw.in.offset = 0;
762 io.readbraw.in.mincnt = 30000;
763 io.readbraw.in.maxcnt = 20000;
764 status = smb_raw_read(cli->tree, &io);
765 CHECK_STATUS(status, NT_STATUS_OK);
766 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
767 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
769 printf("Trying mincnt < maxcnt\n");
770 memset(buf, 0, maxsize);
771 io.readbraw.in.offset = 0;
772 io.readbraw.in.mincnt = 20000;
773 io.readbraw.in.maxcnt = 30000;
774 status = smb_raw_read(cli->tree, &io);
775 CHECK_STATUS(status, NT_STATUS_OK);
776 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
777 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
779 printf("Trying locked region\n");
781 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
782 printf("Failed to lock file at %d\n", __LINE__);
787 memset(buf, 0, maxsize);
788 io.readbraw.in.offset = 0;
789 io.readbraw.in.mincnt = 100;
790 io.readbraw.in.maxcnt = 200;
791 status = smb_raw_read(cli->tree, &io);
792 CHECK_STATUS(status, NT_STATUS_OK);
793 CHECK_VALUE(io.readbraw.out.nread, 0);
795 printf("Trying locked region with timeout\n");
796 memset(buf, 0, maxsize);
797 io.readbraw.in.offset = 0;
798 io.readbraw.in.mincnt = 100;
799 io.readbraw.in.maxcnt = 200;
800 io.readbraw.in.timeout = 10000;
801 status = smb_raw_read(cli->tree, &io);
802 CHECK_STATUS(status, NT_STATUS_OK);
803 CHECK_VALUE(io.readbraw.out.nread, 0);
805 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
806 printf("Trying large offset read\n");
807 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
808 io.readbraw.in.mincnt = 10;
809 io.readbraw.in.maxcnt = 10;
810 io.readbraw.in.timeout = 0;
811 status = smb_raw_read(cli->tree, &io);
812 CHECK_STATUS(status, NT_STATUS_OK);
813 CHECK_VALUE(io.readbraw.out.nread, 0);
817 smbcli_close(cli->tree, fnum);
818 smbcli_deltree(cli->tree, BASEDIR);
823 test read for execute
825 static bool test_read_for_execute(struct torture_context *tctx,
826 struct smbcli_state *cli)
835 const int maxsize = 900;
836 const char *fname = BASEDIR "\\test.txt";
837 const uint8_t data[] = "TEST DATA";
839 buf = talloc_zero_array(tctx, uint8_t, maxsize);
841 if (!torture_setup_dir(cli, BASEDIR)) {
845 printf("Testing RAW_READ_READX with read_for_execute\n");
847 op.generic.level = RAW_OPEN_NTCREATEX;
848 op.ntcreatex.in.root_fid.fnum = 0;
849 op.ntcreatex.in.flags = 0;
850 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
851 op.ntcreatex.in.create_options = 0;
852 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
853 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
854 op.ntcreatex.in.alloc_size = 0;
855 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
856 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
857 op.ntcreatex.in.security_flags = 0;
858 op.ntcreatex.in.fname = fname;
859 status = smb_raw_open(cli->tree, tctx, &op);
860 CHECK_STATUS(status, NT_STATUS_OK);
861 fnum = op.ntcreatex.out.file.fnum;
863 wr.generic.level = RAW_WRITE_WRITEX;
864 wr.writex.in.file.fnum = fnum;
865 wr.writex.in.offset = 0;
866 wr.writex.in.wmode = 0;
867 wr.writex.in.remaining = 0;
868 wr.writex.in.count = ARRAY_SIZE(data);
869 wr.writex.in.data = data;
870 status = smb_raw_write(cli->tree, &wr);
871 CHECK_STATUS(status, NT_STATUS_OK);
872 CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
874 status = smbcli_close(cli->tree, fnum);
875 CHECK_STATUS(status, NT_STATUS_OK);
877 printf("open file with SEC_FILE_EXECUTE\n");
878 op.generic.level = RAW_OPEN_NTCREATEX;
879 op.ntcreatex.in.root_fid.fnum = 0;
880 op.ntcreatex.in.flags = 0;
881 op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
882 op.ntcreatex.in.create_options = 0;
883 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
884 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
885 op.ntcreatex.in.alloc_size = 0;
886 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
887 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
888 op.ntcreatex.in.security_flags = 0;
889 op.ntcreatex.in.fname = fname;
890 status = smb_raw_open(cli->tree, tctx, &op);
891 CHECK_STATUS(status, NT_STATUS_OK);
892 fnum = op.ntcreatex.out.file.fnum;
894 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
895 rd.generic.level = RAW_READ_READX;
896 rd.readx.in.file.fnum = fnum;
897 rd.readx.in.mincnt = 0;
898 rd.readx.in.maxcnt = maxsize;
899 rd.readx.in.offset = 0;
900 rd.readx.in.remaining = 0;
901 rd.readx.in.read_for_execute = true;
902 rd.readx.out.data = buf;
903 status = smb_raw_read(cli->tree, &rd);
904 CHECK_STATUS(status, NT_STATUS_OK);
905 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
906 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
907 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
909 printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\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 = false;
917 rd.readx.out.data = buf;
918 status = smb_raw_read(cli->tree, &rd);
919 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
921 status = smbcli_close(cli->tree, fnum);
922 CHECK_STATUS(status, NT_STATUS_OK);
924 printf("open file with SEC_FILE_READ_DATA\n");
925 op.generic.level = RAW_OPEN_NTCREATEX;
926 op.ntcreatex.in.root_fid.fnum = 0;
927 op.ntcreatex.in.flags = 0;
928 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
929 op.ntcreatex.in.create_options = 0;
930 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
931 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
932 op.ntcreatex.in.alloc_size = 0;
933 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
934 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
935 op.ntcreatex.in.security_flags = 0;
936 op.ntcreatex.in.fname = fname;
937 status = smb_raw_open(cli->tree, tctx, &op);
938 CHECK_STATUS(status, NT_STATUS_OK);
939 fnum = op.ntcreatex.out.file.fnum;
941 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
942 rd.generic.level = RAW_READ_READX;
943 rd.readx.in.file.fnum = fnum;
944 rd.readx.in.mincnt = 0;
945 rd.readx.in.maxcnt = maxsize;
946 rd.readx.in.offset = 0;
947 rd.readx.in.remaining = 0;
948 rd.readx.in.read_for_execute = true;
949 rd.readx.out.data = buf;
950 status = smb_raw_read(cli->tree, &rd);
951 CHECK_STATUS(status, NT_STATUS_OK);
952 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
953 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
954 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
956 printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
957 rd.generic.level = RAW_READ_READX;
958 rd.readx.in.file.fnum = fnum;
959 rd.readx.in.mincnt = 0;
960 rd.readx.in.maxcnt = maxsize;
961 rd.readx.in.offset = 0;
962 rd.readx.in.remaining = 0;
963 rd.readx.in.read_for_execute = false;
964 rd.readx.out.data = buf;
965 status = smb_raw_read(cli->tree, &rd);
966 CHECK_STATUS(status, NT_STATUS_OK);
967 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
968 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
969 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
972 smbcli_close(cli->tree, fnum);
973 smbcli_deltree(cli->tree, BASEDIR);
979 basic testing of read calls
981 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
983 struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
985 torture_suite_add_1smb_test(suite, "read", test_read);
986 torture_suite_add_1smb_test(suite, "readx", test_readx);
987 torture_suite_add_1smb_test(suite, "lockread", test_lockread);
988 torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
989 torture_suite_add_1smb_test(suite, "read for execute",
990 test_read_for_execute);