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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
29 #define CHECK_STATUS(status, correct) do { \
30 if (!NT_STATUS_EQUAL(status, correct)) { \
31 printf("(%s) Incorrect status %s - should be %s\n", \
32 __location__, nt_errstr(status), nt_errstr(correct)); \
37 #define CHECK_VALUE(v, correct) do { \
38 if ((v) != (correct)) { \
39 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
40 __location__, #v, (long)v, (long)correct); \
45 #define CHECK_BUFFER(buf, seed, len) do { \
46 if (!check_buffer(buf, seed, len, __LINE__)) { \
51 #define BASEDIR "\\testread"
55 setup a random buffer based on a seed
57 static void setup_buffer(uint8_t *buf
, uint_t seed
, int len
)
61 for (i
=0;i
<len
;i
++) buf
[i
] = random();
65 check a random buffer based on a seed
67 static BOOL
check_buffer(uint8_t *buf
, uint_t seed
, int len
, int line
)
74 printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n",
85 static BOOL
test_read(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
92 const int maxsize
= 90000;
93 const char *fname
= BASEDIR
"\\test.txt";
94 const char *test_data
= "TEST DATA";
95 uint_t seed
= time(NULL
);
97 buf
= talloc_zero_size(mem_ctx
, maxsize
);
99 if (!torture_setup_dir(cli
, BASEDIR
)) {
103 printf("Testing RAW_READ_READ\n");
104 io
.generic
.level
= RAW_READ_READ
;
106 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
108 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
113 printf("Trying empty file read\n");
114 io
.read
.in
.file
.fnum
= fnum
;
115 io
.read
.in
.count
= 1;
116 io
.read
.in
.offset
= 0;
117 io
.read
.in
.remaining
= 0;
118 io
.read
.out
.data
= buf
;
119 status
= smb_raw_read(cli
->tree
, &io
);
121 CHECK_STATUS(status
, NT_STATUS_OK
);
122 CHECK_VALUE(io
.read
.out
.nread
, 0);
124 printf("Trying zero file read\n");
125 io
.read
.in
.count
= 0;
126 status
= smb_raw_read(cli
->tree
, &io
);
127 CHECK_STATUS(status
, NT_STATUS_OK
);
128 CHECK_VALUE(io
.read
.out
.nread
, 0);
130 printf("Trying bad fnum\n");
131 io
.read
.in
.file
.fnum
= fnum
+1;
132 status
= smb_raw_read(cli
->tree
, &io
);
133 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
134 io
.read
.in
.file
.fnum
= fnum
;
136 smbcli_write(cli
->tree
, fnum
, 0, test_data
, 0, strlen(test_data
));
138 printf("Trying small read\n");
139 io
.read
.in
.file
.fnum
= fnum
;
140 io
.read
.in
.offset
= 0;
141 io
.read
.in
.remaining
= 0;
142 io
.read
.in
.count
= strlen(test_data
);
143 status
= smb_raw_read(cli
->tree
, &io
);
144 CHECK_STATUS(status
, NT_STATUS_OK
);
145 CHECK_VALUE(io
.read
.out
.nread
, strlen(test_data
));
146 if (memcmp(buf
, test_data
, strlen(test_data
)) != 0) {
148 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
, buf
);
152 printf("Trying short read\n");
153 io
.read
.in
.offset
= 1;
154 io
.read
.in
.count
= strlen(test_data
);
155 status
= smb_raw_read(cli
->tree
, &io
);
156 CHECK_STATUS(status
, NT_STATUS_OK
);
157 CHECK_VALUE(io
.read
.out
.nread
, strlen(test_data
)-1);
158 if (memcmp(buf
, test_data
+1, strlen(test_data
)-1) != 0) {
160 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
+1, buf
);
164 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
) {
165 printf("Trying max offset\n");
166 io
.read
.in
.offset
= ~0;
167 io
.read
.in
.count
= strlen(test_data
);
168 status
= smb_raw_read(cli
->tree
, &io
);
169 CHECK_STATUS(status
, NT_STATUS_OK
);
170 CHECK_VALUE(io
.read
.out
.nread
, 0);
173 setup_buffer(buf
, seed
, maxsize
);
174 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, maxsize
);
175 memset(buf
, 0, maxsize
);
177 printf("Trying large read\n");
178 io
.read
.in
.offset
= 0;
179 io
.read
.in
.count
= ~0;
180 status
= smb_raw_read(cli
->tree
, &io
);
181 CHECK_STATUS(status
, NT_STATUS_OK
);
182 CHECK_BUFFER(buf
, seed
, io
.read
.out
.nread
);
185 printf("Trying locked region\n");
187 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 103, 1, 0, WRITE_LOCK
))) {
188 printf("Failed to lock file at %d\n", __LINE__
);
193 memset(buf
, 0, maxsize
);
194 io
.read
.in
.offset
= 0;
195 io
.read
.in
.count
= ~0;
196 status
= smb_raw_read(cli
->tree
, &io
);
197 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
201 smbcli_close(cli
->tree
, fnum
);
202 smb_raw_exit(cli
->session
);
203 smbcli_deltree(cli
->tree
, BASEDIR
);
211 static BOOL
test_lockread(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
218 const int maxsize
= 90000;
219 const char *fname
= BASEDIR
"\\test.txt";
220 const char *test_data
= "TEST DATA";
221 uint_t seed
= time(NULL
);
223 buf
= talloc_zero_size(mem_ctx
, maxsize
);
225 if (!torture_setup_dir(cli
, BASEDIR
)) {
229 printf("Testing RAW_READ_LOCKREAD\n");
230 io
.generic
.level
= RAW_READ_LOCKREAD
;
232 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
234 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
239 printf("Trying empty file read\n");
240 io
.lockread
.in
.file
.fnum
= fnum
;
241 io
.lockread
.in
.count
= 1;
242 io
.lockread
.in
.offset
= 1;
243 io
.lockread
.in
.remaining
= 0;
244 io
.lockread
.out
.data
= buf
;
245 status
= smb_raw_read(cli
->tree
, &io
);
247 CHECK_STATUS(status
, NT_STATUS_OK
);
248 CHECK_VALUE(io
.lockread
.out
.nread
, 0);
250 status
= smb_raw_read(cli
->tree
, &io
);
251 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
253 status
= smb_raw_read(cli
->tree
, &io
);
254 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
256 printf("Trying zero file read\n");
257 io
.lockread
.in
.count
= 0;
258 status
= smb_raw_read(cli
->tree
, &io
);
259 CHECK_STATUS(status
, NT_STATUS_OK
);
261 smbcli_unlock(cli
->tree
, fnum
, 1, 1);
263 printf("Trying bad fnum\n");
264 io
.lockread
.in
.file
.fnum
= fnum
+1;
265 status
= smb_raw_read(cli
->tree
, &io
);
266 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
267 io
.lockread
.in
.file
.fnum
= fnum
;
269 smbcli_write(cli
->tree
, fnum
, 0, test_data
, 0, strlen(test_data
));
271 printf("Trying small read\n");
272 io
.lockread
.in
.file
.fnum
= fnum
;
273 io
.lockread
.in
.offset
= 0;
274 io
.lockread
.in
.remaining
= 0;
275 io
.lockread
.in
.count
= strlen(test_data
);
276 status
= smb_raw_read(cli
->tree
, &io
);
277 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
279 smbcli_unlock(cli
->tree
, fnum
, 1, 0);
281 status
= smb_raw_read(cli
->tree
, &io
);
282 CHECK_STATUS(status
, NT_STATUS_OK
);
283 CHECK_VALUE(io
.lockread
.out
.nread
, strlen(test_data
));
284 if (memcmp(buf
, test_data
, strlen(test_data
)) != 0) {
286 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
, buf
);
290 printf("Trying short read\n");
291 io
.lockread
.in
.offset
= 1;
292 io
.lockread
.in
.count
= strlen(test_data
);
293 status
= smb_raw_read(cli
->tree
, &io
);
294 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
295 smbcli_unlock(cli
->tree
, fnum
, 0, strlen(test_data
));
296 status
= smb_raw_read(cli
->tree
, &io
);
297 CHECK_STATUS(status
, NT_STATUS_OK
);
299 CHECK_VALUE(io
.lockread
.out
.nread
, strlen(test_data
)-1);
300 if (memcmp(buf
, test_data
+1, strlen(test_data
)-1) != 0) {
302 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
+1, buf
);
306 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
) {
307 printf("Trying max offset\n");
308 io
.lockread
.in
.offset
= ~0;
309 io
.lockread
.in
.count
= strlen(test_data
);
310 status
= smb_raw_read(cli
->tree
, &io
);
311 CHECK_STATUS(status
, NT_STATUS_OK
);
312 CHECK_VALUE(io
.lockread
.out
.nread
, 0);
315 setup_buffer(buf
, seed
, maxsize
);
316 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, maxsize
);
317 memset(buf
, 0, maxsize
);
319 printf("Trying large read\n");
320 io
.lockread
.in
.offset
= 0;
321 io
.lockread
.in
.count
= ~0;
322 status
= smb_raw_read(cli
->tree
, &io
);
323 CHECK_STATUS(status
, NT_STATUS_LOCK_NOT_GRANTED
);
324 smbcli_unlock(cli
->tree
, fnum
, 1, strlen(test_data
));
325 status
= smb_raw_read(cli
->tree
, &io
);
326 CHECK_STATUS(status
, NT_STATUS_OK
);
327 CHECK_BUFFER(buf
, seed
, io
.lockread
.out
.nread
);
328 smbcli_unlock(cli
->tree
, fnum
, 0, 0xFFFF);
331 printf("Trying locked region\n");
333 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 103, 1, 0, WRITE_LOCK
))) {
334 printf("Failed to lock file at %d\n", __LINE__
);
339 memset(buf
, 0, maxsize
);
340 io
.lockread
.in
.offset
= 0;
341 io
.lockread
.in
.count
= ~0;
342 status
= smb_raw_read(cli
->tree
, &io
);
343 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
347 smbcli_close(cli
->tree
, fnum
);
348 smbcli_deltree(cli
->tree
, BASEDIR
);
356 static BOOL
test_readx(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
363 const int maxsize
= 90000;
364 const char *fname
= BASEDIR
"\\test.txt";
365 const char *test_data
= "TEST DATA";
366 uint_t seed
= time(NULL
);
368 buf
= talloc_zero_size(mem_ctx
, maxsize
);
370 if (!torture_setup_dir(cli
, BASEDIR
)) {
374 printf("Testing RAW_READ_READX\n");
376 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
378 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
383 printf("Trying empty file read\n");
384 io
.generic
.level
= RAW_READ_READX
;
385 io
.readx
.in
.file
.fnum
= fnum
;
386 io
.readx
.in
.mincnt
= 1;
387 io
.readx
.in
.maxcnt
= 1;
388 io
.readx
.in
.offset
= 0;
389 io
.readx
.in
.remaining
= 0;
390 io
.readx
.in
.read_for_execute
= False
;
391 io
.readx
.out
.data
= buf
;
392 status
= smb_raw_read(cli
->tree
, &io
);
394 CHECK_STATUS(status
, NT_STATUS_OK
);
395 CHECK_VALUE(io
.readx
.out
.nread
, 0);
396 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
397 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
399 printf("Trying zero file read\n");
400 io
.readx
.in
.mincnt
= 0;
401 io
.readx
.in
.maxcnt
= 0;
402 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 bad fnum\n");
409 io
.readx
.in
.file
.fnum
= fnum
+1;
410 status
= smb_raw_read(cli
->tree
, &io
);
411 CHECK_STATUS(status
, NT_STATUS_INVALID_HANDLE
);
412 io
.readx
.in
.file
.fnum
= fnum
;
414 smbcli_write(cli
->tree
, fnum
, 0, test_data
, 0, strlen(test_data
));
416 printf("Trying small read\n");
417 io
.readx
.in
.file
.fnum
= fnum
;
418 io
.readx
.in
.offset
= 0;
419 io
.readx
.in
.remaining
= 0;
420 io
.readx
.in
.read_for_execute
= False
;
421 io
.readx
.in
.mincnt
= strlen(test_data
);
422 io
.readx
.in
.maxcnt
= strlen(test_data
);
423 status
= smb_raw_read(cli
->tree
, &io
);
424 CHECK_STATUS(status
, NT_STATUS_OK
);
425 CHECK_VALUE(io
.readx
.out
.nread
, strlen(test_data
));
426 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
427 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
428 if (memcmp(buf
, test_data
, strlen(test_data
)) != 0) {
430 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
, buf
);
434 printf("Trying short read\n");
435 io
.readx
.in
.offset
= 1;
436 io
.readx
.in
.mincnt
= strlen(test_data
);
437 io
.readx
.in
.maxcnt
= strlen(test_data
);
438 status
= smb_raw_read(cli
->tree
, &io
);
439 CHECK_STATUS(status
, NT_STATUS_OK
);
440 CHECK_VALUE(io
.readx
.out
.nread
, strlen(test_data
)-1);
441 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
442 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
443 if (memcmp(buf
, test_data
+1, strlen(test_data
)-1) != 0) {
445 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
+1, buf
);
449 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
) {
450 printf("Trying max offset\n");
451 io
.readx
.in
.offset
= 0xffffffff;
452 io
.readx
.in
.mincnt
= strlen(test_data
);
453 io
.readx
.in
.maxcnt
= strlen(test_data
);
454 status
= smb_raw_read(cli
->tree
, &io
);
455 CHECK_STATUS(status
, NT_STATUS_OK
);
456 CHECK_VALUE(io
.readx
.out
.nread
, 0);
457 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
458 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
461 setup_buffer(buf
, seed
, maxsize
);
462 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, maxsize
);
463 memset(buf
, 0, maxsize
);
465 printf("Trying large read\n");
466 io
.readx
.in
.offset
= 0;
467 io
.readx
.in
.mincnt
= 0xFFFF;
468 io
.readx
.in
.maxcnt
= 0xFFFF;
469 status
= smb_raw_read(cli
->tree
, &io
);
470 CHECK_STATUS(status
, NT_STATUS_OK
);
471 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
472 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
473 CHECK_VALUE(io
.readx
.out
.nread
, io
.readx
.in
.maxcnt
);
474 CHECK_BUFFER(buf
, seed
, io
.readx
.out
.nread
);
476 printf("Trying extra large read\n");
477 io
.readx
.in
.offset
= 0;
478 io
.readx
.in
.mincnt
= 100;
479 io
.readx
.in
.maxcnt
= 80000;
480 status
= smb_raw_read(cli
->tree
, &io
);
481 CHECK_STATUS(status
, NT_STATUS_OK
);
482 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
483 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
484 if (lp_parm_bool(-1, "torture", "samba3", False
)) {
485 printf("SAMBA3: large read extension\n");
486 CHECK_VALUE(io
.readx
.out
.nread
, 80000);
488 CHECK_VALUE(io
.readx
.out
.nread
, 0);
490 CHECK_BUFFER(buf
, seed
, io
.readx
.out
.nread
);
492 printf("Trying mincnt > maxcnt\n");
493 memset(buf
, 0, maxsize
);
494 io
.readx
.in
.offset
= 0;
495 io
.readx
.in
.mincnt
= 30000;
496 io
.readx
.in
.maxcnt
= 20000;
497 status
= smb_raw_read(cli
->tree
, &io
);
498 CHECK_STATUS(status
, NT_STATUS_OK
);
499 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
500 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
501 CHECK_VALUE(io
.readx
.out
.nread
, io
.readx
.in
.maxcnt
);
502 CHECK_BUFFER(buf
, seed
, io
.readx
.out
.nread
);
504 printf("Trying mincnt < maxcnt\n");
505 memset(buf
, 0, maxsize
);
506 io
.readx
.in
.offset
= 0;
507 io
.readx
.in
.mincnt
= 20000;
508 io
.readx
.in
.maxcnt
= 30000;
509 status
= smb_raw_read(cli
->tree
, &io
);
510 CHECK_STATUS(status
, NT_STATUS_OK
);
511 CHECK_VALUE(io
.readx
.out
.remaining
, 0xFFFF);
512 CHECK_VALUE(io
.readx
.out
.compaction_mode
, 0);
513 CHECK_VALUE(io
.readx
.out
.nread
, io
.readx
.in
.maxcnt
);
514 CHECK_BUFFER(buf
, seed
, io
.readx
.out
.nread
);
516 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_READX
) {
517 printf("Trying large readx\n");
518 io
.readx
.in
.offset
= 0;
519 io
.readx
.in
.mincnt
= 0;
520 io
.readx
.in
.maxcnt
= 0x10000 - 1;
521 status
= smb_raw_read(cli
->tree
, &io
);
522 CHECK_STATUS(status
, NT_STATUS_OK
);
523 CHECK_VALUE(io
.readx
.out
.nread
, 0xFFFF);
525 io
.readx
.in
.maxcnt
= 0x10000;
526 status
= smb_raw_read(cli
->tree
, &io
);
527 CHECK_STATUS(status
, NT_STATUS_OK
);
528 if (lp_parm_bool(-1, "torture", "samba3", False
)) {
529 printf("SAMBA3: large read extension\n");
530 CHECK_VALUE(io
.readx
.out
.nread
, 0x10000);
532 CHECK_VALUE(io
.readx
.out
.nread
, 0);
535 io
.readx
.in
.maxcnt
= 0x10001;
536 status
= smb_raw_read(cli
->tree
, &io
);
537 CHECK_STATUS(status
, NT_STATUS_OK
);
538 if (lp_parm_bool(-1, "torture", "samba3", False
)) {
539 printf("SAMBA3: large read extension\n");
540 CHECK_VALUE(io
.readx
.out
.nread
, 0x10001);
542 CHECK_VALUE(io
.readx
.out
.nread
, 0);
546 printf("Trying locked region\n");
548 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 103, 1, 0, WRITE_LOCK
))) {
549 printf("Failed to lock file at %d\n", __LINE__
);
554 memset(buf
, 0, maxsize
);
555 io
.readx
.in
.offset
= 0;
556 io
.readx
.in
.mincnt
= 100;
557 io
.readx
.in
.maxcnt
= 200;
558 status
= smb_raw_read(cli
->tree
, &io
);
559 CHECK_STATUS(status
, NT_STATUS_FILE_LOCK_CONFLICT
);
561 if (!(cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
)) {
562 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
566 printf("Trying large offset read\n");
567 io
.readx
.in
.offset
= ((uint64_t)0x2) << 32;
568 io
.readx
.in
.mincnt
= 10;
569 io
.readx
.in
.maxcnt
= 10;
570 status
= smb_raw_read(cli
->tree
, &io
);
571 CHECK_STATUS(status
, NT_STATUS_OK
);
572 CHECK_VALUE(io
.readx
.out
.nread
, 0);
574 if (NT_STATUS_IS_ERR(smbcli_lock64(cli
->tree
, fnum
, io
.readx
.in
.offset
, 1, 0, WRITE_LOCK
))) {
575 printf("Failed to lock file at %d\n", __LINE__
);
580 status
= smb_raw_read(cli
->tree
, &io
);
581 CHECK_STATUS(status
, NT_STATUS_OK
);
582 CHECK_VALUE(io
.readx
.out
.nread
, 0);
585 smbcli_close(cli
->tree
, fnum
);
586 smbcli_deltree(cli
->tree
, BASEDIR
);
594 static BOOL
test_readbraw(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
601 const int maxsize
= 90000;
602 const char *fname
= BASEDIR
"\\test.txt";
603 const char *test_data
= "TEST DATA";
604 uint_t seed
= time(NULL
);
606 buf
= talloc_zero_size(mem_ctx
, maxsize
);
608 if (!torture_setup_dir(cli
, BASEDIR
)) {
612 printf("Testing RAW_READ_READBRAW\n");
614 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
616 printf("Failed to create %s - %s\n", fname
, smbcli_errstr(cli
->tree
));
621 printf("Trying empty file read\n");
622 io
.generic
.level
= RAW_READ_READBRAW
;
623 io
.readbraw
.in
.file
.fnum
= fnum
;
624 io
.readbraw
.in
.mincnt
= 1;
625 io
.readbraw
.in
.maxcnt
= 1;
626 io
.readbraw
.in
.offset
= 0;
627 io
.readbraw
.in
.timeout
= 0;
628 io
.readbraw
.out
.data
= buf
;
629 status
= smb_raw_read(cli
->tree
, &io
);
631 CHECK_STATUS(status
, NT_STATUS_OK
);
632 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
634 printf("Trying zero file read\n");
635 io
.readbraw
.in
.mincnt
= 0;
636 io
.readbraw
.in
.maxcnt
= 0;
637 status
= smb_raw_read(cli
->tree
, &io
);
638 CHECK_STATUS(status
, NT_STATUS_OK
);
639 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
641 printf("Trying bad fnum\n");
642 io
.readbraw
.in
.file
.fnum
= fnum
+1;
643 status
= smb_raw_read(cli
->tree
, &io
);
644 CHECK_STATUS(status
, NT_STATUS_OK
);
645 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
646 io
.readbraw
.in
.file
.fnum
= fnum
;
648 smbcli_write(cli
->tree
, fnum
, 0, test_data
, 0, strlen(test_data
));
650 printf("Trying small read\n");
651 io
.readbraw
.in
.file
.fnum
= fnum
;
652 io
.readbraw
.in
.offset
= 0;
653 io
.readbraw
.in
.mincnt
= strlen(test_data
);
654 io
.readbraw
.in
.maxcnt
= strlen(test_data
);
655 status
= smb_raw_read(cli
->tree
, &io
);
656 CHECK_STATUS(status
, NT_STATUS_OK
);
657 CHECK_VALUE(io
.readbraw
.out
.nread
, strlen(test_data
));
658 if (memcmp(buf
, test_data
, strlen(test_data
)) != 0) {
660 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
, buf
);
664 printf("Trying short read\n");
665 io
.readbraw
.in
.offset
= 1;
666 io
.readbraw
.in
.mincnt
= strlen(test_data
);
667 io
.readbraw
.in
.maxcnt
= strlen(test_data
);
668 status
= smb_raw_read(cli
->tree
, &io
);
669 CHECK_STATUS(status
, NT_STATUS_OK
);
670 CHECK_VALUE(io
.readbraw
.out
.nread
, strlen(test_data
)-1);
671 if (memcmp(buf
, test_data
+1, strlen(test_data
)-1) != 0) {
673 printf("incorrect data at %d!? (%s:%s)\n", __LINE__
, test_data
+1, buf
);
677 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
) {
678 printf("Trying max offset\n");
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
, 0);
687 setup_buffer(buf
, seed
, maxsize
);
688 smbcli_write(cli
->tree
, fnum
, 0, buf
, 0, maxsize
);
689 memset(buf
, 0, maxsize
);
691 printf("Trying large read\n");
692 io
.readbraw
.in
.offset
= 0;
693 io
.readbraw
.in
.mincnt
= ~0;
694 io
.readbraw
.in
.maxcnt
= ~0;
695 status
= smb_raw_read(cli
->tree
, &io
);
696 CHECK_STATUS(status
, NT_STATUS_OK
);
697 CHECK_VALUE(io
.readbraw
.out
.nread
, 0xFFFF);
698 CHECK_BUFFER(buf
, seed
, io
.readbraw
.out
.nread
);
700 printf("Trying mincnt > maxcnt\n");
701 memset(buf
, 0, maxsize
);
702 io
.readbraw
.in
.offset
= 0;
703 io
.readbraw
.in
.mincnt
= 30000;
704 io
.readbraw
.in
.maxcnt
= 20000;
705 status
= smb_raw_read(cli
->tree
, &io
);
706 CHECK_STATUS(status
, NT_STATUS_OK
);
707 CHECK_VALUE(io
.readbraw
.out
.nread
, io
.readbraw
.in
.maxcnt
);
708 CHECK_BUFFER(buf
, seed
, io
.readbraw
.out
.nread
);
710 printf("Trying mincnt < maxcnt\n");
711 memset(buf
, 0, maxsize
);
712 io
.readbraw
.in
.offset
= 0;
713 io
.readbraw
.in
.mincnt
= 20000;
714 io
.readbraw
.in
.maxcnt
= 30000;
715 status
= smb_raw_read(cli
->tree
, &io
);
716 CHECK_STATUS(status
, NT_STATUS_OK
);
717 CHECK_VALUE(io
.readbraw
.out
.nread
, io
.readbraw
.in
.maxcnt
);
718 CHECK_BUFFER(buf
, seed
, io
.readbraw
.out
.nread
);
720 printf("Trying locked region\n");
722 if (NT_STATUS_IS_ERR(smbcli_lock(cli
->tree
, fnum
, 103, 1, 0, WRITE_LOCK
))) {
723 printf("Failed to lock file at %d\n", __LINE__
);
728 memset(buf
, 0, maxsize
);
729 io
.readbraw
.in
.offset
= 0;
730 io
.readbraw
.in
.mincnt
= 100;
731 io
.readbraw
.in
.maxcnt
= 200;
732 status
= smb_raw_read(cli
->tree
, &io
);
733 CHECK_STATUS(status
, NT_STATUS_OK
);
734 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
736 printf("Trying locked region with timeout\n");
737 memset(buf
, 0, maxsize
);
738 io
.readbraw
.in
.offset
= 0;
739 io
.readbraw
.in
.mincnt
= 100;
740 io
.readbraw
.in
.maxcnt
= 200;
741 io
.readbraw
.in
.timeout
= 10000;
742 status
= smb_raw_read(cli
->tree
, &io
);
743 CHECK_STATUS(status
, NT_STATUS_OK
);
744 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
746 if (cli
->transport
->negotiate
.capabilities
& CAP_LARGE_FILES
) {
747 printf("Trying large offset read\n");
748 io
.readbraw
.in
.offset
= ((uint64_t)0x2) << 32;
749 io
.readbraw
.in
.mincnt
= 10;
750 io
.readbraw
.in
.maxcnt
= 10;
751 io
.readbraw
.in
.timeout
= 0;
752 status
= smb_raw_read(cli
->tree
, &io
);
753 CHECK_STATUS(status
, NT_STATUS_OK
);
754 CHECK_VALUE(io
.readbraw
.out
.nread
, 0);
758 smbcli_close(cli
->tree
, fnum
);
759 smbcli_deltree(cli
->tree
, BASEDIR
);
764 test read for execute
766 static BOOL
test_read_for_execute(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
)
775 const int maxsize
= 900;
776 const char *fname
= BASEDIR
"\\test.txt";
777 const uint8_t data
[] = "TEST DATA";
779 buf
= talloc_zero_size(mem_ctx
, maxsize
);
781 if (!torture_setup_dir(cli
, BASEDIR
)) {
785 printf("Testing RAW_READ_READX with read_for_execute\n");
787 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
788 op
.ntcreatex
.in
.root_fid
= 0;
789 op
.ntcreatex
.in
.flags
= 0;
790 op
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
791 op
.ntcreatex
.in
.create_options
= 0;
792 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
793 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
794 op
.ntcreatex
.in
.alloc_size
= 0;
795 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
796 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
797 op
.ntcreatex
.in
.security_flags
= 0;
798 op
.ntcreatex
.in
.fname
= fname
;
799 status
= smb_raw_open(cli
->tree
, mem_ctx
, &op
);
800 CHECK_STATUS(status
, NT_STATUS_OK
);
801 fnum
= op
.ntcreatex
.out
.file
.fnum
;
803 wr
.generic
.level
= RAW_WRITE_WRITEX
;
804 wr
.writex
.in
.file
.fnum
= fnum
;
805 wr
.writex
.in
.offset
= 0;
806 wr
.writex
.in
.wmode
= 0;
807 wr
.writex
.in
.remaining
= 0;
808 wr
.writex
.in
.count
= ARRAY_SIZE(data
);
809 wr
.writex
.in
.data
= data
;
810 status
= smb_raw_write(cli
->tree
, &wr
);
811 CHECK_STATUS(status
, NT_STATUS_OK
);
812 CHECK_VALUE(wr
.writex
.out
.nwritten
, ARRAY_SIZE(data
));
814 status
= smbcli_close(cli
->tree
, fnum
);
815 CHECK_STATUS(status
, NT_STATUS_OK
);
817 printf("open file with SEC_FILE_EXECUTE\n");
818 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
819 op
.ntcreatex
.in
.root_fid
= 0;
820 op
.ntcreatex
.in
.flags
= 0;
821 op
.ntcreatex
.in
.access_mask
= SEC_FILE_EXECUTE
;
822 op
.ntcreatex
.in
.create_options
= 0;
823 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
824 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
825 op
.ntcreatex
.in
.alloc_size
= 0;
826 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
827 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
828 op
.ntcreatex
.in
.security_flags
= 0;
829 op
.ntcreatex
.in
.fname
= fname
;
830 status
= smb_raw_open(cli
->tree
, mem_ctx
, &op
);
831 CHECK_STATUS(status
, NT_STATUS_OK
);
832 fnum
= op
.ntcreatex
.out
.file
.fnum
;
834 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
835 rd
.generic
.level
= RAW_READ_READX
;
836 rd
.readx
.in
.file
.fnum
= fnum
;
837 rd
.readx
.in
.mincnt
= 0;
838 rd
.readx
.in
.maxcnt
= maxsize
;
839 rd
.readx
.in
.offset
= 0;
840 rd
.readx
.in
.remaining
= 0;
841 rd
.readx
.in
.read_for_execute
= True
;
842 rd
.readx
.out
.data
= buf
;
843 status
= smb_raw_read(cli
->tree
, &rd
);
844 CHECK_STATUS(status
, NT_STATUS_OK
);
845 CHECK_VALUE(rd
.readx
.out
.nread
, ARRAY_SIZE(data
));
846 CHECK_VALUE(rd
.readx
.out
.remaining
, 0xFFFF);
847 CHECK_VALUE(rd
.readx
.out
.compaction_mode
, 0);
849 printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
850 rd
.generic
.level
= RAW_READ_READX
;
851 rd
.readx
.in
.file
.fnum
= fnum
;
852 rd
.readx
.in
.mincnt
= 0;
853 rd
.readx
.in
.maxcnt
= maxsize
;
854 rd
.readx
.in
.offset
= 0;
855 rd
.readx
.in
.remaining
= 0;
856 rd
.readx
.in
.read_for_execute
= False
;
857 rd
.readx
.out
.data
= buf
;
858 status
= smb_raw_read(cli
->tree
, &rd
);
859 CHECK_STATUS(status
, NT_STATUS_ACCESS_DENIED
);
861 status
= smbcli_close(cli
->tree
, fnum
);
862 CHECK_STATUS(status
, NT_STATUS_OK
);
864 printf("open file with SEC_FILE_READ_DATA\n");
865 op
.generic
.level
= RAW_OPEN_NTCREATEX
;
866 op
.ntcreatex
.in
.root_fid
= 0;
867 op
.ntcreatex
.in
.flags
= 0;
868 op
.ntcreatex
.in
.access_mask
= SEC_FILE_READ_DATA
;
869 op
.ntcreatex
.in
.create_options
= 0;
870 op
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
871 op
.ntcreatex
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
| NTCREATEX_SHARE_ACCESS_WRITE
;
872 op
.ntcreatex
.in
.alloc_size
= 0;
873 op
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
874 op
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
875 op
.ntcreatex
.in
.security_flags
= 0;
876 op
.ntcreatex
.in
.fname
= fname
;
877 status
= smb_raw_open(cli
->tree
, mem_ctx
, &op
);
878 CHECK_STATUS(status
, NT_STATUS_OK
);
879 fnum
= op
.ntcreatex
.out
.file
.fnum
;
881 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
882 rd
.generic
.level
= RAW_READ_READX
;
883 rd
.readx
.in
.file
.fnum
= fnum
;
884 rd
.readx
.in
.mincnt
= 0;
885 rd
.readx
.in
.maxcnt
= maxsize
;
886 rd
.readx
.in
.offset
= 0;
887 rd
.readx
.in
.remaining
= 0;
888 rd
.readx
.in
.read_for_execute
= True
;
889 rd
.readx
.out
.data
= buf
;
890 status
= smb_raw_read(cli
->tree
, &rd
);
891 CHECK_STATUS(status
, NT_STATUS_OK
);
892 CHECK_VALUE(rd
.readx
.out
.nread
, ARRAY_SIZE(data
));
893 CHECK_VALUE(rd
.readx
.out
.remaining
, 0xFFFF);
894 CHECK_VALUE(rd
.readx
.out
.compaction_mode
, 0);
896 printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
897 rd
.generic
.level
= RAW_READ_READX
;
898 rd
.readx
.in
.file
.fnum
= fnum
;
899 rd
.readx
.in
.mincnt
= 0;
900 rd
.readx
.in
.maxcnt
= maxsize
;
901 rd
.readx
.in
.offset
= 0;
902 rd
.readx
.in
.remaining
= 0;
903 rd
.readx
.in
.read_for_execute
= False
;
904 rd
.readx
.out
.data
= buf
;
905 status
= smb_raw_read(cli
->tree
, &rd
);
906 CHECK_STATUS(status
, NT_STATUS_OK
);
907 CHECK_VALUE(rd
.readx
.out
.nread
, ARRAY_SIZE(data
));
908 CHECK_VALUE(rd
.readx
.out
.remaining
, 0xFFFF);
909 CHECK_VALUE(rd
.readx
.out
.compaction_mode
, 0);
912 smbcli_close(cli
->tree
, fnum
);
913 smbcli_deltree(cli
->tree
, BASEDIR
);
919 basic testing of read calls
921 BOOL
torture_raw_read(struct torture_context
*torture
)
923 struct smbcli_state
*cli
;
927 if (!torture_open_connection(&cli
, 0)) {
931 mem_ctx
= talloc_init("torture_raw_read");
933 ret
&= test_read(cli
, mem_ctx
);
934 ret
&= test_readx(cli
, mem_ctx
);
935 ret
&= test_lockread(cli
, mem_ctx
);
936 ret
&= test_readbraw(cli
, mem_ctx
);
937 ret
&= test_read_for_execute(cli
, mem_ctx
);
939 torture_close_connection(cli
);
940 talloc_free(mem_ctx
);