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"
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 torture_context *tctx, struct smbcli_state *cli)
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_array(tctx, uint8_t, 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 torture_context *tctx,
212
struct smbcli_state *cli)
219
const int maxsize = 90000;
220
const char *fname = BASEDIR "\\test.txt";
221
const char *test_data = "TEST DATA";
222
uint_t seed = time(NULL);
224
buf = talloc_zero_array(tctx, uint8_t, maxsize);
226
if (!torture_setup_dir(cli, BASEDIR)) {
230
printf("Testing RAW_READ_LOCKREAD\n");
231
io.generic.level = RAW_READ_LOCKREAD;
233
fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
235
printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
240
printf("Trying empty file read\n");
241
io.lockread.in.file.fnum = fnum;
242
io.lockread.in.count = 1;
243
io.lockread.in.offset = 1;
244
io.lockread.in.remaining = 0;
245
io.lockread.out.data = buf;
246
status = smb_raw_read(cli->tree, &io);
248
CHECK_STATUS(status, NT_STATUS_OK);
249
CHECK_VALUE(io.lockread.out.nread, 0);
251
status = smb_raw_read(cli->tree, &io);
252
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
254
status = smb_raw_read(cli->tree, &io);
255
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
257
printf("Trying zero file read\n");
258
io.lockread.in.count = 0;
259
status = smb_raw_read(cli->tree, &io);
260
CHECK_STATUS(status, NT_STATUS_OK);
262
smbcli_unlock(cli->tree, fnum, 1, 1);
264
printf("Trying bad fnum\n");
265
io.lockread.in.file.fnum = fnum+1;
266
status = smb_raw_read(cli->tree, &io);
267
CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
268
io.lockread.in.file.fnum = fnum;
270
smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
272
printf("Trying small read\n");
273
io.lockread.in.file.fnum = fnum;
274
io.lockread.in.offset = 0;
275
io.lockread.in.remaining = 0;
276
io.lockread.in.count = strlen(test_data);
277
status = smb_raw_read(cli->tree, &io);
278
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
280
smbcli_unlock(cli->tree, fnum, 1, 0);
282
status = smb_raw_read(cli->tree, &io);
283
CHECK_STATUS(status, NT_STATUS_OK);
284
CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
285
if (memcmp(buf, test_data, strlen(test_data)) != 0) {
287
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
291
printf("Trying short read\n");
292
io.lockread.in.offset = 1;
293
io.lockread.in.count = strlen(test_data);
294
status = smb_raw_read(cli->tree, &io);
295
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
296
smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
297
status = smb_raw_read(cli->tree, &io);
298
CHECK_STATUS(status, NT_STATUS_OK);
300
CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
301
if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
303
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
307
if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
308
printf("Trying max offset\n");
309
io.lockread.in.offset = ~0;
310
io.lockread.in.count = strlen(test_data);
311
status = smb_raw_read(cli->tree, &io);
312
CHECK_STATUS(status, NT_STATUS_OK);
313
CHECK_VALUE(io.lockread.out.nread, 0);
316
setup_buffer(buf, seed, maxsize);
317
smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
318
memset(buf, 0, maxsize);
320
printf("Trying large read\n");
321
io.lockread.in.offset = 0;
322
io.lockread.in.count = ~0;
323
status = smb_raw_read(cli->tree, &io);
324
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
325
smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
326
status = smb_raw_read(cli->tree, &io);
327
CHECK_STATUS(status, NT_STATUS_OK);
328
CHECK_BUFFER(buf, seed, io.lockread.out.nread);
329
smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
332
printf("Trying locked region\n");
334
if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
335
printf("Failed to lock file at %d\n", __LINE__);
340
memset(buf, 0, maxsize);
341
io.lockread.in.offset = 0;
342
io.lockread.in.count = ~0;
343
status = smb_raw_read(cli->tree, &io);
344
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
348
smbcli_close(cli->tree, fnum);
349
smbcli_deltree(cli->tree, BASEDIR);
357
static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
364
const int maxsize = 90000;
365
const char *fname = BASEDIR "\\test.txt";
366
const char *test_data = "TEST DATA";
367
uint_t seed = time(NULL);
369
buf = talloc_zero_array(tctx, uint8_t, maxsize);
371
if (!torture_setup_dir(cli, BASEDIR)) {
375
printf("Testing RAW_READ_READX\n");
377
fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
379
printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
384
printf("Trying empty file read\n");
385
io.generic.level = RAW_READ_READX;
386
io.readx.in.file.fnum = fnum;
387
io.readx.in.mincnt = 1;
388
io.readx.in.maxcnt = 1;
389
io.readx.in.offset = 0;
390
io.readx.in.remaining = 0;
391
io.readx.in.read_for_execute = false;
392
io.readx.out.data = buf;
393
status = smb_raw_read(cli->tree, &io);
395
CHECK_STATUS(status, NT_STATUS_OK);
396
CHECK_VALUE(io.readx.out.nread, 0);
397
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
398
CHECK_VALUE(io.readx.out.compaction_mode, 0);
400
printf("Trying zero file read\n");
401
io.readx.in.mincnt = 0;
402
io.readx.in.maxcnt = 0;
403
status = smb_raw_read(cli->tree, &io);
404
CHECK_STATUS(status, NT_STATUS_OK);
405
CHECK_VALUE(io.readx.out.nread, 0);
406
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
407
CHECK_VALUE(io.readx.out.compaction_mode, 0);
409
printf("Trying bad fnum\n");
410
io.readx.in.file.fnum = fnum+1;
411
status = smb_raw_read(cli->tree, &io);
412
CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
413
io.readx.in.file.fnum = fnum;
415
smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
417
printf("Trying small read\n");
418
io.readx.in.file.fnum = fnum;
419
io.readx.in.offset = 0;
420
io.readx.in.remaining = 0;
421
io.readx.in.read_for_execute = false;
422
io.readx.in.mincnt = strlen(test_data);
423
io.readx.in.maxcnt = strlen(test_data);
424
status = smb_raw_read(cli->tree, &io);
425
CHECK_STATUS(status, NT_STATUS_OK);
426
CHECK_VALUE(io.readx.out.nread, strlen(test_data));
427
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
428
CHECK_VALUE(io.readx.out.compaction_mode, 0);
429
if (memcmp(buf, test_data, strlen(test_data)) != 0) {
431
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
435
printf("Trying short read\n");
436
io.readx.in.offset = 1;
437
io.readx.in.mincnt = strlen(test_data);
438
io.readx.in.maxcnt = strlen(test_data);
439
status = smb_raw_read(cli->tree, &io);
440
CHECK_STATUS(status, NT_STATUS_OK);
441
CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
442
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
443
CHECK_VALUE(io.readx.out.compaction_mode, 0);
444
if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
446
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
450
if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
451
printf("Trying max offset\n");
452
io.readx.in.offset = 0xffffffff;
453
io.readx.in.mincnt = strlen(test_data);
454
io.readx.in.maxcnt = strlen(test_data);
455
status = smb_raw_read(cli->tree, &io);
456
CHECK_STATUS(status, NT_STATUS_OK);
457
CHECK_VALUE(io.readx.out.nread, 0);
458
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
459
CHECK_VALUE(io.readx.out.compaction_mode, 0);
462
printf("Trying mincnt past EOF\n");
463
memset(buf, 0, maxsize);
464
io.readx.in.offset = 0;
465
io.readx.in.mincnt = 100;
466
io.readx.in.maxcnt = 110;
467
status = smb_raw_read(cli->tree, &io);
468
CHECK_STATUS(status, NT_STATUS_OK);
469
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
470
CHECK_VALUE(io.readx.out.compaction_mode, 0);
471
CHECK_VALUE(io.readx.out.nread, strlen(test_data));
472
if (memcmp(buf, test_data, strlen(test_data)) != 0) {
474
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
479
setup_buffer(buf, seed, maxsize);
480
smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
481
memset(buf, 0, maxsize);
483
printf("Trying large read\n");
484
io.readx.in.offset = 0;
485
io.readx.in.mincnt = 0xFFFF;
486
io.readx.in.maxcnt = 0xFFFF;
487
status = smb_raw_read(cli->tree, &io);
488
CHECK_STATUS(status, NT_STATUS_OK);
489
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
490
CHECK_VALUE(io.readx.out.compaction_mode, 0);
491
CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
492
CHECK_BUFFER(buf, seed, io.readx.out.nread);
494
printf("Trying extra large read\n");
495
io.readx.in.offset = 0;
496
io.readx.in.mincnt = 100;
497
io.readx.in.maxcnt = 80000;
498
status = smb_raw_read(cli->tree, &io);
499
CHECK_STATUS(status, NT_STATUS_OK);
500
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
501
CHECK_VALUE(io.readx.out.compaction_mode, 0);
502
if (torture_setting_bool(tctx, "samba3", false)) {
503
printf("SAMBA3: large read extension\n");
504
CHECK_VALUE(io.readx.out.nread, 80000);
506
CHECK_VALUE(io.readx.out.nread, 0);
508
CHECK_BUFFER(buf, seed, io.readx.out.nread);
510
printf("Trying mincnt > maxcnt\n");
511
memset(buf, 0, maxsize);
512
io.readx.in.offset = 0;
513
io.readx.in.mincnt = 30000;
514
io.readx.in.maxcnt = 20000;
515
status = smb_raw_read(cli->tree, &io);
516
CHECK_STATUS(status, NT_STATUS_OK);
517
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
518
CHECK_VALUE(io.readx.out.compaction_mode, 0);
519
CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
520
CHECK_BUFFER(buf, seed, io.readx.out.nread);
522
printf("Trying mincnt < maxcnt\n");
523
memset(buf, 0, maxsize);
524
io.readx.in.offset = 0;
525
io.readx.in.mincnt = 20000;
526
io.readx.in.maxcnt = 30000;
527
status = smb_raw_read(cli->tree, &io);
528
CHECK_STATUS(status, NT_STATUS_OK);
529
CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
530
CHECK_VALUE(io.readx.out.compaction_mode, 0);
531
CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
532
CHECK_BUFFER(buf, seed, io.readx.out.nread);
534
if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
535
printf("Trying large readx\n");
536
io.readx.in.offset = 0;
537
io.readx.in.mincnt = 0;
538
io.readx.in.maxcnt = 0x10000 - 1;
539
status = smb_raw_read(cli->tree, &io);
540
CHECK_STATUS(status, NT_STATUS_OK);
541
CHECK_VALUE(io.readx.out.nread, 0xFFFF);
543
io.readx.in.maxcnt = 0x10000;
544
status = smb_raw_read(cli->tree, &io);
545
CHECK_STATUS(status, NT_STATUS_OK);
546
if (torture_setting_bool(tctx, "samba3", false)) {
547
printf("SAMBA3: 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
printf("SAMBA3: large read extension\n");
558
CHECK_VALUE(io.readx.out.nread, 0x10001);
560
CHECK_VALUE(io.readx.out.nread, 0);
564
printf("Trying locked region\n");
566
if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
567
printf("Failed to lock file at %d\n", __LINE__);
572
memset(buf, 0, maxsize);
573
io.readx.in.offset = 0;
574
io.readx.in.mincnt = 100;
575
io.readx.in.maxcnt = 200;
576
status = smb_raw_read(cli->tree, &io);
577
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
579
if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
580
printf("skipping large file tests - CAP_LARGE_FILES not set\n");
584
printf("Trying large offset read\n");
585
io.readx.in.offset = ((uint64_t)0x2) << 32;
586
io.readx.in.mincnt = 10;
587
io.readx.in.maxcnt = 10;
588
status = smb_raw_read(cli->tree, &io);
589
CHECK_STATUS(status, NT_STATUS_OK);
590
CHECK_VALUE(io.readx.out.nread, 0);
592
if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
593
printf("Failed to lock file at %d\n", __LINE__);
598
status = smb_raw_read(cli->tree, &io);
599
CHECK_STATUS(status, NT_STATUS_OK);
600
CHECK_VALUE(io.readx.out.nread, 0);
603
smbcli_close(cli->tree, fnum);
604
smbcli_deltree(cli->tree, BASEDIR);
612
static bool test_readbraw(struct torture_context *tctx,
613
struct smbcli_state *cli)
620
const int maxsize = 90000;
621
const char *fname = BASEDIR "\\test.txt";
622
const char *test_data = "TEST DATA";
623
uint_t seed = time(NULL);
625
buf = talloc_zero_array(tctx, uint8_t, maxsize);
627
if (!torture_setup_dir(cli, BASEDIR)) {
631
printf("Testing RAW_READ_READBRAW\n");
633
fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
635
printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
640
printf("Trying empty file read\n");
641
io.generic.level = RAW_READ_READBRAW;
642
io.readbraw.in.file.fnum = fnum;
643
io.readbraw.in.mincnt = 1;
644
io.readbraw.in.maxcnt = 1;
645
io.readbraw.in.offset = 0;
646
io.readbraw.in.timeout = 0;
647
io.readbraw.out.data = buf;
648
status = smb_raw_read(cli->tree, &io);
650
CHECK_STATUS(status, NT_STATUS_OK);
651
CHECK_VALUE(io.readbraw.out.nread, 0);
653
printf("Trying zero file read\n");
654
io.readbraw.in.mincnt = 0;
655
io.readbraw.in.maxcnt = 0;
656
status = smb_raw_read(cli->tree, &io);
657
CHECK_STATUS(status, NT_STATUS_OK);
658
CHECK_VALUE(io.readbraw.out.nread, 0);
660
printf("Trying bad fnum\n");
661
io.readbraw.in.file.fnum = fnum+1;
662
status = smb_raw_read(cli->tree, &io);
663
CHECK_STATUS(status, NT_STATUS_OK);
664
CHECK_VALUE(io.readbraw.out.nread, 0);
665
io.readbraw.in.file.fnum = fnum;
667
smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
669
printf("Trying small read\n");
670
io.readbraw.in.file.fnum = fnum;
671
io.readbraw.in.offset = 0;
672
io.readbraw.in.mincnt = strlen(test_data);
673
io.readbraw.in.maxcnt = strlen(test_data);
674
status = smb_raw_read(cli->tree, &io);
675
CHECK_STATUS(status, NT_STATUS_OK);
676
CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
677
if (memcmp(buf, test_data, strlen(test_data)) != 0) {
679
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
683
printf("Trying short read\n");
684
io.readbraw.in.offset = 1;
685
io.readbraw.in.mincnt = strlen(test_data);
686
io.readbraw.in.maxcnt = strlen(test_data);
687
status = smb_raw_read(cli->tree, &io);
688
CHECK_STATUS(status, NT_STATUS_OK);
689
CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
690
if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
692
printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
696
if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
697
printf("Trying max offset\n");
698
io.readbraw.in.offset = ~0;
699
io.readbraw.in.mincnt = strlen(test_data);
700
io.readbraw.in.maxcnt = strlen(test_data);
701
status = smb_raw_read(cli->tree, &io);
702
CHECK_STATUS(status, NT_STATUS_OK);
703
CHECK_VALUE(io.readbraw.out.nread, 0);
706
setup_buffer(buf, seed, maxsize);
707
smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
708
memset(buf, 0, maxsize);
710
printf("Trying large read\n");
711
io.readbraw.in.offset = 0;
712
io.readbraw.in.mincnt = ~0;
713
io.readbraw.in.maxcnt = ~0;
714
status = smb_raw_read(cli->tree, &io);
715
CHECK_STATUS(status, NT_STATUS_OK);
716
CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
717
CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
719
printf("Trying mincnt > maxcnt\n");
720
memset(buf, 0, maxsize);
721
io.readbraw.in.offset = 0;
722
io.readbraw.in.mincnt = 30000;
723
io.readbraw.in.maxcnt = 20000;
724
status = smb_raw_read(cli->tree, &io);
725
CHECK_STATUS(status, NT_STATUS_OK);
726
CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
727
CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
729
printf("Trying mincnt < maxcnt\n");
730
memset(buf, 0, maxsize);
731
io.readbraw.in.offset = 0;
732
io.readbraw.in.mincnt = 20000;
733
io.readbraw.in.maxcnt = 30000;
734
status = smb_raw_read(cli->tree, &io);
735
CHECK_STATUS(status, NT_STATUS_OK);
736
CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
737
CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
739
printf("Trying locked region\n");
741
if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
742
printf("Failed to lock file at %d\n", __LINE__);
747
memset(buf, 0, maxsize);
748
io.readbraw.in.offset = 0;
749
io.readbraw.in.mincnt = 100;
750
io.readbraw.in.maxcnt = 200;
751
status = smb_raw_read(cli->tree, &io);
752
CHECK_STATUS(status, NT_STATUS_OK);
753
CHECK_VALUE(io.readbraw.out.nread, 0);
755
printf("Trying locked region with timeout\n");
756
memset(buf, 0, maxsize);
757
io.readbraw.in.offset = 0;
758
io.readbraw.in.mincnt = 100;
759
io.readbraw.in.maxcnt = 200;
760
io.readbraw.in.timeout = 10000;
761
status = smb_raw_read(cli->tree, &io);
762
CHECK_STATUS(status, NT_STATUS_OK);
763
CHECK_VALUE(io.readbraw.out.nread, 0);
765
if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
766
printf("Trying large offset read\n");
767
io.readbraw.in.offset = ((uint64_t)0x2) << 32;
768
io.readbraw.in.mincnt = 10;
769
io.readbraw.in.maxcnt = 10;
770
io.readbraw.in.timeout = 0;
771
status = smb_raw_read(cli->tree, &io);
772
CHECK_STATUS(status, NT_STATUS_OK);
773
CHECK_VALUE(io.readbraw.out.nread, 0);
777
smbcli_close(cli->tree, fnum);
778
smbcli_deltree(cli->tree, BASEDIR);
783
test read for execute
785
static bool test_read_for_execute(struct torture_context *tctx,
786
struct smbcli_state *cli)
795
const int maxsize = 900;
796
const char *fname = BASEDIR "\\test.txt";
797
const uint8_t data[] = "TEST DATA";
799
buf = talloc_zero_array(tctx, uint8_t, maxsize);
801
if (!torture_setup_dir(cli, BASEDIR)) {
805
printf("Testing RAW_READ_READX with read_for_execute\n");
807
op.generic.level = RAW_OPEN_NTCREATEX;
808
op.ntcreatex.in.root_fid = 0;
809
op.ntcreatex.in.flags = 0;
810
op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
811
op.ntcreatex.in.create_options = 0;
812
op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
813
op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
814
op.ntcreatex.in.alloc_size = 0;
815
op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
816
op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
817
op.ntcreatex.in.security_flags = 0;
818
op.ntcreatex.in.fname = fname;
819
status = smb_raw_open(cli->tree, tctx, &op);
820
CHECK_STATUS(status, NT_STATUS_OK);
821
fnum = op.ntcreatex.out.file.fnum;
823
wr.generic.level = RAW_WRITE_WRITEX;
824
wr.writex.in.file.fnum = fnum;
825
wr.writex.in.offset = 0;
826
wr.writex.in.wmode = 0;
827
wr.writex.in.remaining = 0;
828
wr.writex.in.count = ARRAY_SIZE(data);
829
wr.writex.in.data = data;
830
status = smb_raw_write(cli->tree, &wr);
831
CHECK_STATUS(status, NT_STATUS_OK);
832
CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
834
status = smbcli_close(cli->tree, fnum);
835
CHECK_STATUS(status, NT_STATUS_OK);
837
printf("open file with SEC_FILE_EXECUTE\n");
838
op.generic.level = RAW_OPEN_NTCREATEX;
839
op.ntcreatex.in.root_fid = 0;
840
op.ntcreatex.in.flags = 0;
841
op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
842
op.ntcreatex.in.create_options = 0;
843
op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
844
op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
845
op.ntcreatex.in.alloc_size = 0;
846
op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
847
op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
848
op.ntcreatex.in.security_flags = 0;
849
op.ntcreatex.in.fname = fname;
850
status = smb_raw_open(cli->tree, tctx, &op);
851
CHECK_STATUS(status, NT_STATUS_OK);
852
fnum = op.ntcreatex.out.file.fnum;
854
printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
855
rd.generic.level = RAW_READ_READX;
856
rd.readx.in.file.fnum = fnum;
857
rd.readx.in.mincnt = 0;
858
rd.readx.in.maxcnt = maxsize;
859
rd.readx.in.offset = 0;
860
rd.readx.in.remaining = 0;
861
rd.readx.in.read_for_execute = true;
862
rd.readx.out.data = buf;
863
status = smb_raw_read(cli->tree, &rd);
864
CHECK_STATUS(status, NT_STATUS_OK);
865
CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
866
CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
867
CHECK_VALUE(rd.readx.out.compaction_mode, 0);
869
printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
870
rd.generic.level = RAW_READ_READX;
871
rd.readx.in.file.fnum = fnum;
872
rd.readx.in.mincnt = 0;
873
rd.readx.in.maxcnt = maxsize;
874
rd.readx.in.offset = 0;
875
rd.readx.in.remaining = 0;
876
rd.readx.in.read_for_execute = false;
877
rd.readx.out.data = buf;
878
status = smb_raw_read(cli->tree, &rd);
879
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
881
status = smbcli_close(cli->tree, fnum);
882
CHECK_STATUS(status, NT_STATUS_OK);
884
printf("open file with SEC_FILE_READ_DATA\n");
885
op.generic.level = RAW_OPEN_NTCREATEX;
886
op.ntcreatex.in.root_fid = 0;
887
op.ntcreatex.in.flags = 0;
888
op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
889
op.ntcreatex.in.create_options = 0;
890
op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
891
op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
892
op.ntcreatex.in.alloc_size = 0;
893
op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
894
op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
895
op.ntcreatex.in.security_flags = 0;
896
op.ntcreatex.in.fname = fname;
897
status = smb_raw_open(cli->tree, tctx, &op);
898
CHECK_STATUS(status, NT_STATUS_OK);
899
fnum = op.ntcreatex.out.file.fnum;
901
printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
902
rd.generic.level = RAW_READ_READX;
903
rd.readx.in.file.fnum = fnum;
904
rd.readx.in.mincnt = 0;
905
rd.readx.in.maxcnt = maxsize;
906
rd.readx.in.offset = 0;
907
rd.readx.in.remaining = 0;
908
rd.readx.in.read_for_execute = true;
909
rd.readx.out.data = buf;
910
status = smb_raw_read(cli->tree, &rd);
911
CHECK_STATUS(status, NT_STATUS_OK);
912
CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
913
CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
914
CHECK_VALUE(rd.readx.out.compaction_mode, 0);
916
printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
917
rd.generic.level = RAW_READ_READX;
918
rd.readx.in.file.fnum = fnum;
919
rd.readx.in.mincnt = 0;
920
rd.readx.in.maxcnt = maxsize;
921
rd.readx.in.offset = 0;
922
rd.readx.in.remaining = 0;
923
rd.readx.in.read_for_execute = false;
924
rd.readx.out.data = buf;
925
status = smb_raw_read(cli->tree, &rd);
926
CHECK_STATUS(status, NT_STATUS_OK);
927
CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
928
CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
929
CHECK_VALUE(rd.readx.out.compaction_mode, 0);
932
smbcli_close(cli->tree, fnum);
933
smbcli_deltree(cli->tree, BASEDIR);
939
basic testing of read calls
941
struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
943
struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
945
torture_suite_add_1smb_test(suite, "read", test_read);
946
torture_suite_add_1smb_test(suite, "readx", test_readx);
947
torture_suite_add_1smb_test(suite, "lockread", test_lockread);
948
torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
949
torture_suite_add_1smb_test(suite, "read for execute",
950
test_read_for_execute);