s3-waf: remove version from libpdb.so for now.
[Samba/vl.git] / source4 / torture / raw / read.c
blob9bb626f3cd3a86c715134ca419d5848353a76af0
1 /*
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/>.
20 #include "includes.h"
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"
26 #include "torture/raw/proto.h"
28 #define CHECK_STATUS(status, correct) do { \
29 if (!NT_STATUS_EQUAL(status, correct)) { \
30 printf("(%s) Incorrect status %s - should be %s\n", \
31 __location__, nt_errstr(status), nt_errstr(correct)); \
32 ret = false; \
33 goto done; \
34 }} while (0)
36 #define CHECK_VALUE(v, correct) do { \
37 if ((v) != (correct)) { \
38 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
39 __location__, #v, (long)v, (long)correct); \
40 ret = false; \
41 goto done; \
42 }} while (0)
44 #define CHECK_BUFFER(buf, seed, len) do { \
45 if (!check_buffer(buf, seed, len, __LINE__)) { \
46 ret = false; \
47 goto done; \
48 }} while (0)
50 #define BASEDIR "\\testread"
54 setup a random buffer based on a seed
56 static void setup_buffer(uint8_t *buf, unsigned int seed, int len)
58 int i;
59 srandom(seed);
60 for (i=0;i<len;i++) buf[i] = random();
64 check a random buffer based on a seed
66 static bool check_buffer(uint8_t *buf, unsigned int seed, int len, int line)
68 int i;
69 srandom(seed);
70 for (i=0;i<len;i++) {
71 uint8_t v = random();
72 if (buf[i] != v) {
73 printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n",
74 line, i, buf[i], v);
75 return false;
78 return true;
82 test read ops
84 static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
86 union smb_read io;
87 NTSTATUS status;
88 bool ret = true;
89 int fnum;
90 uint8_t *buf;
91 const int maxsize = 90000;
92 const char *fname = BASEDIR "\\test.txt";
93 const char *test_data = "TEST DATA";
94 unsigned int seed = time(NULL);
96 buf = talloc_zero_array(tctx, uint8_t, maxsize);
98 if (!torture_setting_bool(tctx, "read_support", true)) {
99 printf("server refuses to support READ\n");
100 return true;
103 if (!torture_setup_dir(cli, BASEDIR)) {
104 return false;
107 printf("Testing RAW_READ_READ\n");
108 io.generic.level = RAW_READ_READ;
110 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
111 if (fnum == -1) {
112 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
113 ret = false;
114 goto done;
117 printf("Trying empty file read\n");
118 io.read.in.file.fnum = fnum;
119 io.read.in.count = 1;
120 io.read.in.offset = 0;
121 io.read.in.remaining = 0;
122 io.read.out.data = buf;
123 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 zero file read\n");
129 io.read.in.count = 0;
130 status = smb_raw_read(cli->tree, &io);
131 CHECK_STATUS(status, NT_STATUS_OK);
132 CHECK_VALUE(io.read.out.nread, 0);
134 printf("Trying bad fnum\n");
135 io.read.in.file.fnum = fnum+1;
136 status = smb_raw_read(cli->tree, &io);
137 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
138 io.read.in.file.fnum = fnum;
140 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
142 printf("Trying small read\n");
143 io.read.in.file.fnum = fnum;
144 io.read.in.offset = 0;
145 io.read.in.remaining = 0;
146 io.read.in.count = strlen(test_data);
147 status = smb_raw_read(cli->tree, &io);
148 CHECK_STATUS(status, NT_STATUS_OK);
149 CHECK_VALUE(io.read.out.nread, strlen(test_data));
150 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
151 ret = false;
152 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
153 goto done;
156 printf("Trying short read\n");
157 io.read.in.offset = 1;
158 io.read.in.count = strlen(test_data);
159 status = smb_raw_read(cli->tree, &io);
160 CHECK_STATUS(status, NT_STATUS_OK);
161 CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
162 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
163 ret = false;
164 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
165 goto done;
168 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
169 printf("Trying max offset\n");
170 io.read.in.offset = ~0;
171 io.read.in.count = strlen(test_data);
172 status = smb_raw_read(cli->tree, &io);
173 CHECK_STATUS(status, NT_STATUS_OK);
174 CHECK_VALUE(io.read.out.nread, 0);
177 setup_buffer(buf, seed, maxsize);
178 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
179 memset(buf, 0, maxsize);
181 printf("Trying large read\n");
182 io.read.in.offset = 0;
183 io.read.in.count = ~0;
184 status = smb_raw_read(cli->tree, &io);
185 CHECK_STATUS(status, NT_STATUS_OK);
186 CHECK_BUFFER(buf, seed, io.read.out.nread);
189 printf("Trying locked region\n");
190 cli->session->pid++;
191 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
192 printf("Failed to lock file at %d\n", __LINE__);
193 ret = false;
194 goto done;
196 cli->session->pid--;
197 memset(buf, 0, maxsize);
198 io.read.in.offset = 0;
199 io.read.in.count = ~0;
200 status = smb_raw_read(cli->tree, &io);
201 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
204 done:
205 smbcli_close(cli->tree, fnum);
206 smb_raw_exit(cli->session);
207 smbcli_deltree(cli->tree, BASEDIR);
208 return ret;
213 test lockread ops
215 static bool test_lockread(struct torture_context *tctx,
216 struct smbcli_state *cli)
218 union smb_read io;
219 NTSTATUS status;
220 bool ret = true;
221 int fnum;
222 uint8_t *buf;
223 const int maxsize = 90000;
224 const char *fname = BASEDIR "\\test.txt";
225 const char *test_data = "TEST DATA";
226 unsigned int seed = time(NULL);
228 if (!cli->transport->negotiate.lockread_supported) {
229 printf("Server does not support lockread - skipping\n");
230 return true;
233 buf = talloc_zero_array(tctx, uint8_t, maxsize);
235 if (!torture_setup_dir(cli, BASEDIR)) {
236 return false;
239 printf("Testing RAW_READ_LOCKREAD\n");
240 io.generic.level = RAW_READ_LOCKREAD;
242 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
243 if (fnum == -1) {
244 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
245 ret = false;
246 goto done;
249 printf("Trying empty file read\n");
250 io.lockread.in.file.fnum = fnum;
251 io.lockread.in.count = 1;
252 io.lockread.in.offset = 1;
253 io.lockread.in.remaining = 0;
254 io.lockread.out.data = buf;
255 status = smb_raw_read(cli->tree, &io);
257 CHECK_STATUS(status, NT_STATUS_OK);
258 CHECK_VALUE(io.lockread.out.nread, 0);
260 status = smb_raw_read(cli->tree, &io);
261 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
263 status = smb_raw_read(cli->tree, &io);
264 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
266 printf("Trying zero file read\n");
267 io.lockread.in.count = 0;
268 status = smb_raw_read(cli->tree, &io);
269 CHECK_STATUS(status, NT_STATUS_OK);
271 smbcli_unlock(cli->tree, fnum, 1, 1);
273 printf("Trying bad fnum\n");
274 io.lockread.in.file.fnum = fnum+1;
275 status = smb_raw_read(cli->tree, &io);
276 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
277 io.lockread.in.file.fnum = fnum;
279 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
281 printf("Trying small read\n");
282 io.lockread.in.file.fnum = fnum;
283 io.lockread.in.offset = 0;
284 io.lockread.in.remaining = 0;
285 io.lockread.in.count = strlen(test_data);
286 status = smb_raw_read(cli->tree, &io);
287 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
289 smbcli_unlock(cli->tree, fnum, 1, 0);
291 status = smb_raw_read(cli->tree, &io);
292 CHECK_STATUS(status, NT_STATUS_OK);
293 CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
294 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
295 ret = false;
296 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
297 goto done;
300 printf("Trying short read\n");
301 io.lockread.in.offset = 1;
302 io.lockread.in.count = strlen(test_data);
303 status = smb_raw_read(cli->tree, &io);
304 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
305 smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
306 status = smb_raw_read(cli->tree, &io);
307 CHECK_STATUS(status, NT_STATUS_OK);
309 CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
310 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
311 ret = false;
312 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
313 goto done;
316 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
317 printf("Trying max offset\n");
318 io.lockread.in.offset = ~0;
319 io.lockread.in.count = strlen(test_data);
320 status = smb_raw_read(cli->tree, &io);
321 CHECK_STATUS(status, NT_STATUS_OK);
322 CHECK_VALUE(io.lockread.out.nread, 0);
325 setup_buffer(buf, seed, maxsize);
326 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
327 memset(buf, 0, maxsize);
329 printf("Trying large read\n");
330 io.lockread.in.offset = 0;
331 io.lockread.in.count = ~0;
332 status = smb_raw_read(cli->tree, &io);
333 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
334 smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
335 status = smb_raw_read(cli->tree, &io);
336 CHECK_STATUS(status, NT_STATUS_OK);
337 CHECK_BUFFER(buf, seed, io.lockread.out.nread);
338 smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
341 printf("Trying locked region\n");
342 cli->session->pid++;
343 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
344 printf("Failed to lock file at %d\n", __LINE__);
345 ret = false;
346 goto done;
348 cli->session->pid--;
349 memset(buf, 0, maxsize);
350 io.lockread.in.offset = 0;
351 io.lockread.in.count = ~0;
352 status = smb_raw_read(cli->tree, &io);
353 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
356 done:
357 smbcli_close(cli->tree, fnum);
358 smbcli_deltree(cli->tree, BASEDIR);
359 return ret;
364 test readx ops
366 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
368 union smb_read io;
369 NTSTATUS status;
370 bool ret = true;
371 int fnum;
372 uint8_t *buf;
373 const int maxsize = 90000;
374 const char *fname = BASEDIR "\\test.txt";
375 const char *test_data = "TEST DATA";
376 unsigned int seed = time(NULL);
378 buf = talloc_zero_array(tctx, uint8_t, maxsize);
380 if (!torture_setup_dir(cli, BASEDIR)) {
381 return false;
384 printf("Testing RAW_READ_READX\n");
386 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
387 if (fnum == -1) {
388 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
389 ret = false;
390 goto done;
393 printf("Trying empty file read\n");
394 io.generic.level = RAW_READ_READX;
395 io.readx.in.file.fnum = fnum;
396 io.readx.in.mincnt = 1;
397 io.readx.in.maxcnt = 1;
398 io.readx.in.offset = 0;
399 io.readx.in.remaining = 0;
400 io.readx.in.read_for_execute = false;
401 io.readx.out.data = buf;
402 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 zero file read\n");
410 io.readx.in.mincnt = 0;
411 io.readx.in.maxcnt = 0;
412 status = smb_raw_read(cli->tree, &io);
413 CHECK_STATUS(status, NT_STATUS_OK);
414 CHECK_VALUE(io.readx.out.nread, 0);
415 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
416 CHECK_VALUE(io.readx.out.compaction_mode, 0);
418 printf("Trying bad fnum\n");
419 io.readx.in.file.fnum = fnum+1;
420 status = smb_raw_read(cli->tree, &io);
421 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
422 io.readx.in.file.fnum = fnum;
424 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
426 printf("Trying small read\n");
427 io.readx.in.file.fnum = fnum;
428 io.readx.in.offset = 0;
429 io.readx.in.remaining = 0;
430 io.readx.in.read_for_execute = false;
431 io.readx.in.mincnt = strlen(test_data);
432 io.readx.in.maxcnt = strlen(test_data);
433 status = smb_raw_read(cli->tree, &io);
434 CHECK_STATUS(status, NT_STATUS_OK);
435 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
436 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
437 CHECK_VALUE(io.readx.out.compaction_mode, 0);
438 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
439 ret = false;
440 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
441 goto done;
444 printf("Trying short read\n");
445 io.readx.in.offset = 1;
446 io.readx.in.mincnt = strlen(test_data);
447 io.readx.in.maxcnt = strlen(test_data);
448 status = smb_raw_read(cli->tree, &io);
449 CHECK_STATUS(status, NT_STATUS_OK);
450 CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
451 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
452 CHECK_VALUE(io.readx.out.compaction_mode, 0);
453 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
454 ret = false;
455 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
456 goto done;
459 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
460 printf("Trying max offset\n");
461 io.readx.in.offset = 0xffffffff;
462 io.readx.in.mincnt = strlen(test_data);
463 io.readx.in.maxcnt = strlen(test_data);
464 status = smb_raw_read(cli->tree, &io);
465 CHECK_STATUS(status, NT_STATUS_OK);
466 CHECK_VALUE(io.readx.out.nread, 0);
467 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
468 CHECK_VALUE(io.readx.out.compaction_mode, 0);
471 printf("Trying mincnt past EOF\n");
472 memset(buf, 0, maxsize);
473 io.readx.in.offset = 0;
474 io.readx.in.mincnt = 100;
475 io.readx.in.maxcnt = 110;
476 status = smb_raw_read(cli->tree, &io);
477 CHECK_STATUS(status, NT_STATUS_OK);
478 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
479 CHECK_VALUE(io.readx.out.compaction_mode, 0);
480 CHECK_VALUE(io.readx.out.nread, strlen(test_data));
481 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
482 ret = false;
483 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
484 goto done;
488 setup_buffer(buf, seed, maxsize);
489 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
490 memset(buf, 0, maxsize);
492 printf("Trying page sized read\n");
493 io.readx.in.offset = 0;
494 io.readx.in.mincnt = 0x1000;
495 io.readx.in.maxcnt = 0x1000;
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 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
501 CHECK_BUFFER(buf, seed, io.readx.out.nread);
503 printf("Trying page + 1 sized read (check alignment)\n");
504 io.readx.in.offset = 0;
505 io.readx.in.mincnt = 0x1001;
506 io.readx.in.maxcnt = 0x1001;
507 status = smb_raw_read(cli->tree, &io);
508 CHECK_STATUS(status, NT_STATUS_OK);
509 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
510 CHECK_VALUE(io.readx.out.compaction_mode, 0);
511 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
512 CHECK_BUFFER(buf, seed, io.readx.out.nread);
514 printf("Trying large read (UINT16_MAX)\n");
515 io.readx.in.offset = 0;
516 io.readx.in.mincnt = 0xFFFF;
517 io.readx.in.maxcnt = 0xFFFF;
518 status = smb_raw_read(cli->tree, &io);
519 CHECK_STATUS(status, NT_STATUS_OK);
520 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
521 CHECK_VALUE(io.readx.out.compaction_mode, 0);
522 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
523 CHECK_BUFFER(buf, seed, io.readx.out.nread);
525 printf("Trying extra large read\n");
526 io.readx.in.offset = 0;
527 io.readx.in.mincnt = 100;
528 io.readx.in.maxcnt = 80000;
529 status = smb_raw_read(cli->tree, &io);
530 CHECK_STATUS(status, NT_STATUS_OK);
531 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
532 CHECK_VALUE(io.readx.out.compaction_mode, 0);
533 if (torture_setting_bool(tctx, "samba3", false) ||
534 torture_setting_bool(tctx, "samba4", false)) {
535 printf("SAMBA: large read extension\n");
536 CHECK_VALUE(io.readx.out.nread, 80000);
537 } else {
538 CHECK_VALUE(io.readx.out.nread, 0);
540 CHECK_BUFFER(buf, seed, io.readx.out.nread);
542 printf("Trying mincnt > maxcnt\n");
543 memset(buf, 0, maxsize);
544 io.readx.in.offset = 0;
545 io.readx.in.mincnt = 30000;
546 io.readx.in.maxcnt = 20000;
547 status = smb_raw_read(cli->tree, &io);
548 CHECK_STATUS(status, NT_STATUS_OK);
549 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
550 CHECK_VALUE(io.readx.out.compaction_mode, 0);
551 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
552 CHECK_BUFFER(buf, seed, io.readx.out.nread);
554 printf("Trying mincnt < maxcnt\n");
555 memset(buf, 0, maxsize);
556 io.readx.in.offset = 0;
557 io.readx.in.mincnt = 20000;
558 io.readx.in.maxcnt = 30000;
559 status = smb_raw_read(cli->tree, &io);
560 CHECK_STATUS(status, NT_STATUS_OK);
561 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
562 CHECK_VALUE(io.readx.out.compaction_mode, 0);
563 CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
564 CHECK_BUFFER(buf, seed, io.readx.out.nread);
566 if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
567 printf("Trying large readx\n");
568 io.readx.in.offset = 0;
569 io.readx.in.mincnt = 0;
570 io.readx.in.maxcnt = 0x10000 - 1;
571 status = smb_raw_read(cli->tree, &io);
572 CHECK_STATUS(status, NT_STATUS_OK);
573 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
575 io.readx.in.maxcnt = 0x10000;
576 status = smb_raw_read(cli->tree, &io);
577 CHECK_STATUS(status, NT_STATUS_OK);
578 if (torture_setting_bool(tctx, "samba3", false) ||
579 torture_setting_bool(tctx, "samba4", false)) {
580 printf("SAMBA: large read extension\n");
581 CHECK_VALUE(io.readx.out.nread, 0x10000);
582 } else {
583 CHECK_VALUE(io.readx.out.nread, 0);
586 io.readx.in.maxcnt = 0x10001;
587 status = smb_raw_read(cli->tree, &io);
588 CHECK_STATUS(status, NT_STATUS_OK);
589 if (torture_setting_bool(tctx, "samba3", false) ||
590 torture_setting_bool(tctx, "samba4", false)) {
591 printf("SAMBA: large read extension\n");
592 CHECK_VALUE(io.readx.out.nread, 0x10001);
593 } else {
594 CHECK_VALUE(io.readx.out.nread, 0);
596 } else {
597 printf("Server does not support the CAP_LARGE_READX extension\n");
600 printf("Trying locked region\n");
601 cli->session->pid++;
602 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
603 printf("Failed to lock file at %d\n", __LINE__);
604 ret = false;
605 goto done;
607 cli->session->pid--;
608 memset(buf, 0, maxsize);
609 io.readx.in.offset = 0;
610 io.readx.in.mincnt = 100;
611 io.readx.in.maxcnt = 200;
612 status = smb_raw_read(cli->tree, &io);
613 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
615 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
616 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
617 goto done;
620 printf("Trying large offset read\n");
621 io.readx.in.offset = ((uint64_t)0x2) << 32;
622 io.readx.in.mincnt = 10;
623 io.readx.in.maxcnt = 10;
624 status = smb_raw_read(cli->tree, &io);
625 CHECK_STATUS(status, NT_STATUS_OK);
626 CHECK_VALUE(io.readx.out.nread, 0);
628 if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
629 printf("Failed to lock file at %d\n", __LINE__);
630 ret = false;
631 goto done;
634 status = smb_raw_read(cli->tree, &io);
635 CHECK_STATUS(status, NT_STATUS_OK);
636 CHECK_VALUE(io.readx.out.nread, 0);
638 done:
639 smbcli_close(cli->tree, fnum);
640 smbcli_deltree(cli->tree, BASEDIR);
641 return ret;
646 test readbraw ops
648 static bool test_readbraw(struct torture_context *tctx,
649 struct smbcli_state *cli)
651 union smb_read io;
652 NTSTATUS status;
653 bool ret = true;
654 int fnum;
655 uint8_t *buf;
656 const int maxsize = 90000;
657 const char *fname = BASEDIR "\\test.txt";
658 const char *test_data = "TEST DATA";
659 unsigned int seed = time(NULL);
661 if (!cli->transport->negotiate.readbraw_supported) {
662 printf("Server does not support readbraw - skipping\n");
663 return true;
666 buf = talloc_zero_array(tctx, uint8_t, maxsize);
668 if (!torture_setup_dir(cli, BASEDIR)) {
669 return false;
672 printf("Testing RAW_READ_READBRAW\n");
674 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
675 if (fnum == -1) {
676 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
677 ret = false;
678 goto done;
681 printf("Trying empty file read\n");
682 io.generic.level = RAW_READ_READBRAW;
683 io.readbraw.in.file.fnum = fnum;
684 io.readbraw.in.mincnt = 1;
685 io.readbraw.in.maxcnt = 1;
686 io.readbraw.in.offset = 0;
687 io.readbraw.in.timeout = 0;
688 io.readbraw.out.data = buf;
689 status = smb_raw_read(cli->tree, &io);
691 CHECK_STATUS(status, NT_STATUS_OK);
692 CHECK_VALUE(io.readbraw.out.nread, 0);
694 printf("Trying zero file read\n");
695 io.readbraw.in.mincnt = 0;
696 io.readbraw.in.maxcnt = 0;
697 status = smb_raw_read(cli->tree, &io);
698 CHECK_STATUS(status, NT_STATUS_OK);
699 CHECK_VALUE(io.readbraw.out.nread, 0);
701 printf("Trying bad fnum\n");
702 io.readbraw.in.file.fnum = fnum+1;
703 status = smb_raw_read(cli->tree, &io);
704 CHECK_STATUS(status, NT_STATUS_OK);
705 CHECK_VALUE(io.readbraw.out.nread, 0);
706 io.readbraw.in.file.fnum = fnum;
708 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
710 printf("Trying small read\n");
711 io.readbraw.in.file.fnum = fnum;
712 io.readbraw.in.offset = 0;
713 io.readbraw.in.mincnt = strlen(test_data);
714 io.readbraw.in.maxcnt = strlen(test_data);
715 status = smb_raw_read(cli->tree, &io);
716 CHECK_STATUS(status, NT_STATUS_OK);
717 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
718 if (memcmp(buf, test_data, strlen(test_data)) != 0) {
719 ret = false;
720 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
721 goto done;
724 printf("Trying short read\n");
725 io.readbraw.in.offset = 1;
726 io.readbraw.in.mincnt = strlen(test_data);
727 io.readbraw.in.maxcnt = strlen(test_data);
728 status = smb_raw_read(cli->tree, &io);
729 CHECK_STATUS(status, NT_STATUS_OK);
730 CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
731 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
732 ret = false;
733 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
734 goto done;
737 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
738 printf("Trying max offset\n");
739 io.readbraw.in.offset = ~0;
740 io.readbraw.in.mincnt = strlen(test_data);
741 io.readbraw.in.maxcnt = strlen(test_data);
742 status = smb_raw_read(cli->tree, &io);
743 CHECK_STATUS(status, NT_STATUS_OK);
744 CHECK_VALUE(io.readbraw.out.nread, 0);
747 setup_buffer(buf, seed, maxsize);
748 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
749 memset(buf, 0, maxsize);
751 printf("Trying large read\n");
752 io.readbraw.in.offset = 0;
753 io.readbraw.in.mincnt = ~0;
754 io.readbraw.in.maxcnt = ~0;
755 status = smb_raw_read(cli->tree, &io);
756 CHECK_STATUS(status, NT_STATUS_OK);
757 CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
758 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
760 printf("Trying mincnt > maxcnt\n");
761 memset(buf, 0, maxsize);
762 io.readbraw.in.offset = 0;
763 io.readbraw.in.mincnt = 30000;
764 io.readbraw.in.maxcnt = 20000;
765 status = smb_raw_read(cli->tree, &io);
766 CHECK_STATUS(status, NT_STATUS_OK);
767 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
768 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
770 printf("Trying mincnt < maxcnt\n");
771 memset(buf, 0, maxsize);
772 io.readbraw.in.offset = 0;
773 io.readbraw.in.mincnt = 20000;
774 io.readbraw.in.maxcnt = 30000;
775 status = smb_raw_read(cli->tree, &io);
776 CHECK_STATUS(status, NT_STATUS_OK);
777 CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
778 CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
780 printf("Trying locked region\n");
781 cli->session->pid++;
782 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
783 printf("Failed to lock file at %d\n", __LINE__);
784 ret = false;
785 goto done;
787 cli->session->pid--;
788 memset(buf, 0, maxsize);
789 io.readbraw.in.offset = 0;
790 io.readbraw.in.mincnt = 100;
791 io.readbraw.in.maxcnt = 200;
792 status = smb_raw_read(cli->tree, &io);
793 CHECK_STATUS(status, NT_STATUS_OK);
794 CHECK_VALUE(io.readbraw.out.nread, 0);
796 printf("Trying locked region with timeout\n");
797 memset(buf, 0, maxsize);
798 io.readbraw.in.offset = 0;
799 io.readbraw.in.mincnt = 100;
800 io.readbraw.in.maxcnt = 200;
801 io.readbraw.in.timeout = 10000;
802 status = smb_raw_read(cli->tree, &io);
803 CHECK_STATUS(status, NT_STATUS_OK);
804 CHECK_VALUE(io.readbraw.out.nread, 0);
806 if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
807 printf("Trying large offset read\n");
808 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
809 io.readbraw.in.mincnt = 10;
810 io.readbraw.in.maxcnt = 10;
811 io.readbraw.in.timeout = 0;
812 status = smb_raw_read(cli->tree, &io);
813 CHECK_STATUS(status, NT_STATUS_OK);
814 CHECK_VALUE(io.readbraw.out.nread, 0);
817 done:
818 smbcli_close(cli->tree, fnum);
819 smbcli_deltree(cli->tree, BASEDIR);
820 return ret;
824 test read for execute
826 static bool test_read_for_execute(struct torture_context *tctx,
827 struct smbcli_state *cli)
829 union smb_open op;
830 union smb_write wr;
831 union smb_read rd;
832 NTSTATUS status;
833 bool ret = true;
834 int fnum=0;
835 uint8_t *buf;
836 const int maxsize = 900;
837 const char *fname = BASEDIR "\\test.txt";
838 const uint8_t data[] = "TEST DATA";
840 buf = talloc_zero_array(tctx, uint8_t, maxsize);
842 if (!torture_setup_dir(cli, BASEDIR)) {
843 return false;
846 printf("Testing RAW_READ_READX with read_for_execute\n");
848 op.generic.level = RAW_OPEN_NTCREATEX;
849 op.ntcreatex.in.root_fid.fnum = 0;
850 op.ntcreatex.in.flags = 0;
851 op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
852 op.ntcreatex.in.create_options = 0;
853 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
854 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
855 op.ntcreatex.in.alloc_size = 0;
856 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
857 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
858 op.ntcreatex.in.security_flags = 0;
859 op.ntcreatex.in.fname = fname;
860 status = smb_raw_open(cli->tree, tctx, &op);
861 CHECK_STATUS(status, NT_STATUS_OK);
862 fnum = op.ntcreatex.out.file.fnum;
864 wr.generic.level = RAW_WRITE_WRITEX;
865 wr.writex.in.file.fnum = fnum;
866 wr.writex.in.offset = 0;
867 wr.writex.in.wmode = 0;
868 wr.writex.in.remaining = 0;
869 wr.writex.in.count = ARRAY_SIZE(data);
870 wr.writex.in.data = data;
871 status = smb_raw_write(cli->tree, &wr);
872 CHECK_STATUS(status, NT_STATUS_OK);
873 CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
875 status = smbcli_close(cli->tree, fnum);
876 CHECK_STATUS(status, NT_STATUS_OK);
878 printf("open file with SEC_FILE_EXECUTE\n");
879 op.generic.level = RAW_OPEN_NTCREATEX;
880 op.ntcreatex.in.root_fid.fnum = 0;
881 op.ntcreatex.in.flags = 0;
882 op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
883 op.ntcreatex.in.create_options = 0;
884 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
885 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
886 op.ntcreatex.in.alloc_size = 0;
887 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
888 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
889 op.ntcreatex.in.security_flags = 0;
890 op.ntcreatex.in.fname = fname;
891 status = smb_raw_open(cli->tree, tctx, &op);
892 CHECK_STATUS(status, NT_STATUS_OK);
893 fnum = op.ntcreatex.out.file.fnum;
895 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
896 rd.generic.level = RAW_READ_READX;
897 rd.readx.in.file.fnum = fnum;
898 rd.readx.in.mincnt = 0;
899 rd.readx.in.maxcnt = maxsize;
900 rd.readx.in.offset = 0;
901 rd.readx.in.remaining = 0;
902 rd.readx.in.read_for_execute = true;
903 rd.readx.out.data = buf;
904 status = smb_raw_read(cli->tree, &rd);
905 CHECK_STATUS(status, NT_STATUS_OK);
906 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
907 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
908 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
910 printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
911 rd.generic.level = RAW_READ_READX;
912 rd.readx.in.file.fnum = fnum;
913 rd.readx.in.mincnt = 0;
914 rd.readx.in.maxcnt = maxsize;
915 rd.readx.in.offset = 0;
916 rd.readx.in.remaining = 0;
917 rd.readx.in.read_for_execute = false;
918 rd.readx.out.data = buf;
919 status = smb_raw_read(cli->tree, &rd);
920 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
922 status = smbcli_close(cli->tree, fnum);
923 CHECK_STATUS(status, NT_STATUS_OK);
925 printf("open file with SEC_FILE_READ_DATA\n");
926 op.generic.level = RAW_OPEN_NTCREATEX;
927 op.ntcreatex.in.root_fid.fnum = 0;
928 op.ntcreatex.in.flags = 0;
929 op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
930 op.ntcreatex.in.create_options = 0;
931 op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
932 op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
933 op.ntcreatex.in.alloc_size = 0;
934 op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
935 op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
936 op.ntcreatex.in.security_flags = 0;
937 op.ntcreatex.in.fname = fname;
938 status = smb_raw_open(cli->tree, tctx, &op);
939 CHECK_STATUS(status, NT_STATUS_OK);
940 fnum = op.ntcreatex.out.file.fnum;
942 printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
943 rd.generic.level = RAW_READ_READX;
944 rd.readx.in.file.fnum = fnum;
945 rd.readx.in.mincnt = 0;
946 rd.readx.in.maxcnt = maxsize;
947 rd.readx.in.offset = 0;
948 rd.readx.in.remaining = 0;
949 rd.readx.in.read_for_execute = true;
950 rd.readx.out.data = buf;
951 status = smb_raw_read(cli->tree, &rd);
952 CHECK_STATUS(status, NT_STATUS_OK);
953 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
954 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
955 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
957 printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
958 rd.generic.level = RAW_READ_READX;
959 rd.readx.in.file.fnum = fnum;
960 rd.readx.in.mincnt = 0;
961 rd.readx.in.maxcnt = maxsize;
962 rd.readx.in.offset = 0;
963 rd.readx.in.remaining = 0;
964 rd.readx.in.read_for_execute = false;
965 rd.readx.out.data = buf;
966 status = smb_raw_read(cli->tree, &rd);
967 CHECK_STATUS(status, NT_STATUS_OK);
968 CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
969 CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
970 CHECK_VALUE(rd.readx.out.compaction_mode, 0);
972 done:
973 smbcli_close(cli->tree, fnum);
974 smbcli_deltree(cli->tree, BASEDIR);
975 return ret;
980 basic testing of read calls
982 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
984 struct torture_suite *suite = torture_suite_create(mem_ctx, "read");
986 torture_suite_add_1smb_test(suite, "read", test_read);
987 torture_suite_add_1smb_test(suite, "readx", test_readx);
988 torture_suite_add_1smb_test(suite, "lockread", test_lockread);
989 torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
990 torture_suite_add_1smb_test(suite, "read for execute",
991 test_read_for_execute);
993 return suite;