source: trunk/server/source4/torture/raw/read.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 30.1 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 test suite for various read operations
4 Copyright (C) Andrew Tridgell 2003
5
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.
10
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.
15
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/>.
18*/
19
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
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)); \
31 ret = false; \
32 goto done; \
33 }} while (0)
34
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); \
39 ret = false; \
40 goto done; \
41 }} while (0)
42
43#define CHECK_BUFFER(buf, seed, len) do { \
44 if (!check_buffer(buf, seed, len, __LINE__)) { \
45 ret = false; \
46 goto done; \
47 }} while (0)
48
49#define BASEDIR "\\testread"
50
51
52/*
53 setup a random buffer based on a seed
54*/
55static void setup_buffer(uint8_t *buf, unsigned int seed, int len)
56{
57 int i;
58 srandom(seed);
59 for (i=0;i<len;i++) buf[i] = random();
60}
61
62/*
63 check a random buffer based on a seed
64*/
65static bool check_buffer(uint8_t *buf, unsigned int seed, int len, int line)
66{
67 int i;
68 srandom(seed);
69 for (i=0;i<len;i++) {
70 uint8_t v = random();
71 if (buf[i] != v) {
72 printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n",
73 line, i, buf[i], v);
74 return false;
75 }
76 }
77 return true;
78}
79
80/*
81 test read ops
82*/
83static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
84{
85 union smb_read io;
86 NTSTATUS status;
87 bool ret = true;
88 int fnum;
89 uint8_t *buf;
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);
94
95 buf = talloc_zero_array(tctx, uint8_t, maxsize);
96
97 if (!torture_setting_bool(tctx, "read_support", true)) {
98 printf("server refuses to support READ\n");
99 return true;
100 }
101
102 if (!torture_setup_dir(cli, BASEDIR)) {
103 return false;
104 }
105
106 printf("Testing RAW_READ_READ\n");
107 io.generic.level = RAW_READ_READ;
108
109 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
110 if (fnum == -1) {
111 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
112 ret = false;
113 goto done;
114 }
115
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);
123
124 CHECK_STATUS(status, NT_STATUS_OK);
125 CHECK_VALUE(io.read.out.nread, 0);
126
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);
132
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;
138
139 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
140
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) {
150 ret = false;
151 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
152 goto done;
153 }
154
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) {
162 ret = false;
163 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
164 goto done;
165 }
166
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);
174 }
175
176 setup_buffer(buf, seed, maxsize);
177 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
178 memset(buf, 0, maxsize);
179
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);
186
187
188 printf("Trying locked region\n");
189 cli->session->pid++;
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__);
192 ret = false;
193 goto done;
194 }
195 cli->session->pid--;
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);
201
202
203done:
204 smbcli_close(cli->tree, fnum);
205 smb_raw_exit(cli->session);
206 smbcli_deltree(cli->tree, BASEDIR);
207 return ret;
208}
209
210
211/*
212 test lockread ops
213*/
214static bool test_lockread(struct torture_context *tctx,
215 struct smbcli_state *cli)
216{
217 union smb_read io;
218 NTSTATUS status;
219 bool ret = true;
220 int fnum;
221 uint8_t *buf;
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);
226
227 if (!cli->transport->negotiate.lockread_supported) {
228 printf("Server does not support lockread - skipping\n");
229 return true;
230 }
231
232 buf = talloc_zero_array(tctx, uint8_t, maxsize);
233
234 if (!torture_setup_dir(cli, BASEDIR)) {
235 return false;
236 }
237
238 printf("Testing RAW_READ_LOCKREAD\n");
239 io.generic.level = RAW_READ_LOCKREAD;
240
241 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
242 if (fnum == -1) {
243 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
244 ret = false;
245 goto done;
246 }
247
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);
255
256 CHECK_STATUS(status, NT_STATUS_OK);
257 CHECK_VALUE(io.lockread.out.nread, 0);
258
259 status = smb_raw_read(cli->tree, &io);
260 CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
261
262 status = smb_raw_read(cli->tree, &io);
263 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
264
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);
269
270 smbcli_unlock(cli->tree, fnum, 1, 1);
271
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;
277
278 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
279
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);
287
288 smbcli_unlock(cli->tree, fnum, 1, 0);
289
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) {
294 ret = false;
295 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
296 goto done;
297 }
298
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);
307
308 CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
309 if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
310 ret = false;
311 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
312 goto done;
313 }
314
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);
322 }
323
324 setup_buffer(buf, seed, maxsize);
325 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
326 memset(buf, 0, maxsize);
327
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);
338
339
340 printf("Trying locked region\n");
341 cli->session->pid++;
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__);
344 ret = false;
345 goto done;
346 }
347 cli->session->pid--;
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);
353
354
355done:
356 smbcli_close(cli->tree, fnum);
357 smbcli_deltree(cli->tree, BASEDIR);
358 return ret;
359}
360
361
362/*
363 test readx ops
364*/
365static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
366{
367 union smb_read io;
368 NTSTATUS status;
369 bool ret = true;
370 int fnum;
371 uint8_t *buf;
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);
376
377 buf = talloc_zero_array(tctx, uint8_t, maxsize);
378
379 if (!torture_setup_dir(cli, BASEDIR)) {
380 return false;
381 }
382
383 printf("Testing RAW_READ_READX\n");
384
385 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
386 if (fnum == -1) {
387 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
388 ret = false;
389 goto done;
390 }
391
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);
402
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);
407
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);
416
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;
422
423 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
424
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) {
438 ret = false;
439 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
440 goto done;
441 }
442
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) {
453 ret = false;
454 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
455 goto done;
456 }
457
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);
468 }
469
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) {
481 ret = false;
482 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
483 goto done;
484 }
485
486
487 setup_buffer(buf, seed, maxsize);
488 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
489 memset(buf, 0, maxsize);
490
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);
501
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);
512
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);
523
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);
536 } else {
537 CHECK_VALUE(io.readx.out.nread, 0);
538 }
539 CHECK_BUFFER(buf, seed, io.readx.out.nread);
540
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);
552
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);
564
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);
573
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);
581 } else {
582 CHECK_VALUE(io.readx.out.nread, 0);
583 }
584
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);
592 } else {
593 CHECK_VALUE(io.readx.out.nread, 0);
594 }
595 } else {
596 printf("Server does not support the CAP_LARGE_READX extension\n");
597 }
598
599 printf("Trying locked region\n");
600 cli->session->pid++;
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__);
603 ret = false;
604 goto done;
605 }
606 cli->session->pid--;
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);
613
614 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
615 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
616 goto done;
617 }
618
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);
626
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__);
629 ret = false;
630 goto done;
631 }
632
633 status = smb_raw_read(cli->tree, &io);
634 CHECK_STATUS(status, NT_STATUS_OK);
635 CHECK_VALUE(io.readx.out.nread, 0);
636
637done:
638 smbcli_close(cli->tree, fnum);
639 smbcli_deltree(cli->tree, BASEDIR);
640 return ret;
641}
642
643
644/*
645 test readbraw ops
646*/
647static bool test_readbraw(struct torture_context *tctx,
648 struct smbcli_state *cli)
649{
650 union smb_read io;
651 NTSTATUS status;
652 bool ret = true;
653 int fnum;
654 uint8_t *buf;
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);
659
660 if (!cli->transport->negotiate.readbraw_supported) {
661 printf("Server does not support readbraw - skipping\n");
662 return true;
663 }
664
665 buf = talloc_zero_array(tctx, uint8_t, maxsize);
666
667 if (!torture_setup_dir(cli, BASEDIR)) {
668 return false;
669 }
670
671 printf("Testing RAW_READ_READBRAW\n");
672
673 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
674 if (fnum == -1) {
675 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
676 ret = false;
677 goto done;
678 }
679
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);
689
690 CHECK_STATUS(status, NT_STATUS_OK);
691 CHECK_VALUE(io.readbraw.out.nread, 0);
692
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);
699
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;
706
707 smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
708
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) {
718 ret = false;
719 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
720 goto done;
721 }
722
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) {
731 ret = false;
732 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
733 goto done;
734 }
735
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);
744 }
745
746 setup_buffer(buf, seed, maxsize);
747 smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
748 memset(buf, 0, maxsize);
749
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);
758
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);
768
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);
778
779 printf("Trying locked region\n");
780 cli->session->pid++;
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__);
783 ret = false;
784 goto done;
785 }
786 cli->session->pid--;
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);
794
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);
804
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);
814 }
815
816done:
817 smbcli_close(cli->tree, fnum);
818 smbcli_deltree(cli->tree, BASEDIR);
819 return ret;
820}
821
822/*
823 test read for execute
824*/
825static bool test_read_for_execute(struct torture_context *tctx,
826 struct smbcli_state *cli)
827{
828 union smb_open op;
829 union smb_write wr;
830 union smb_read rd;
831 NTSTATUS status;
832 bool ret = true;
833 int fnum=0;
834 uint8_t *buf;
835 const int maxsize = 900;
836 const char *fname = BASEDIR "\\test.txt";
837 const uint8_t data[] = "TEST DATA";
838
839 buf = talloc_zero_array(tctx, uint8_t, maxsize);
840
841 if (!torture_setup_dir(cli, BASEDIR)) {
842 return false;
843 }
844
845 printf("Testing RAW_READ_READX with read_for_execute\n");
846
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;
862
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));
873
874 status = smbcli_close(cli->tree, fnum);
875 CHECK_STATUS(status, NT_STATUS_OK);
876
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;
893
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);
908
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);
920
921 status = smbcli_close(cli->tree, fnum);
922 CHECK_STATUS(status, NT_STATUS_OK);
923
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;
940
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);
955
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);
970
971done:
972 smbcli_close(cli->tree, fnum);
973 smbcli_deltree(cli->tree, BASEDIR);
974 return ret;
975}
976
977
978/*
979 basic testing of read calls
980*/
981struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
982{
983 struct torture_suite *suite = torture_suite_create(mem_ctx, "read");
984
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);
991
992 return suite;
993}
Note: See TracBrowser for help on using the repository browser.