s4-torture: ran minimal_includes.pl over source4/torture
[samba.git] / source4 / torture / raw / read.c
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 */
55 static void setup_buffer(uint8_t *buf, uint_t 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 */
65 static bool check_buffer(uint8_t *buf, uint_t 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 */
83 static 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         uint_t seed = time(NULL);
94
95         buf = talloc_zero_array(tctx, uint8_t, maxsize);
96
97         if (!torture_setup_dir(cli, BASEDIR)) {
98                 return false;
99         }
100
101         printf("Testing RAW_READ_READ\n");
102         io.generic.level = RAW_READ_READ;
103         
104         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
105         if (fnum == -1) {
106                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
107                 ret = false;
108                 goto done;
109         }
110
111         printf("Trying empty file read\n");
112         io.read.in.file.fnum = fnum;
113         io.read.in.count = 1;
114         io.read.in.offset = 0;
115         io.read.in.remaining = 0;
116         io.read.out.data = buf;
117         status = smb_raw_read(cli->tree, &io);
118
119         CHECK_STATUS(status, NT_STATUS_OK);
120         CHECK_VALUE(io.read.out.nread, 0);
121
122         printf("Trying zero file read\n");
123         io.read.in.count = 0;
124         status = smb_raw_read(cli->tree, &io);
125         CHECK_STATUS(status, NT_STATUS_OK);
126         CHECK_VALUE(io.read.out.nread, 0);
127
128         printf("Trying bad fnum\n");
129         io.read.in.file.fnum = fnum+1;
130         status = smb_raw_read(cli->tree, &io);
131         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
132         io.read.in.file.fnum = fnum;
133
134         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
135
136         printf("Trying small read\n");
137         io.read.in.file.fnum = fnum;
138         io.read.in.offset = 0;
139         io.read.in.remaining = 0;
140         io.read.in.count = strlen(test_data);
141         status = smb_raw_read(cli->tree, &io);
142         CHECK_STATUS(status, NT_STATUS_OK);
143         CHECK_VALUE(io.read.out.nread, strlen(test_data));
144         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
145                 ret = false;
146                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
147                 goto done;
148         }
149
150         printf("Trying short read\n");
151         io.read.in.offset = 1;
152         io.read.in.count = strlen(test_data);
153         status = smb_raw_read(cli->tree, &io);
154         CHECK_STATUS(status, NT_STATUS_OK);
155         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
156         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
157                 ret = false;
158                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
159                 goto done;
160         }
161
162         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
163                 printf("Trying max offset\n");
164                 io.read.in.offset = ~0;
165                 io.read.in.count = strlen(test_data);
166                 status = smb_raw_read(cli->tree, &io);
167                 CHECK_STATUS(status, NT_STATUS_OK);
168                 CHECK_VALUE(io.read.out.nread, 0);
169         }
170
171         setup_buffer(buf, seed, maxsize);
172         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
173         memset(buf, 0, maxsize);
174
175         printf("Trying large read\n");
176         io.read.in.offset = 0;
177         io.read.in.count = ~0;
178         status = smb_raw_read(cli->tree, &io);
179         CHECK_STATUS(status, NT_STATUS_OK);
180         CHECK_BUFFER(buf, seed, io.read.out.nread);
181
182
183         printf("Trying locked region\n");
184         cli->session->pid++;
185         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
186                 printf("Failed to lock file at %d\n", __LINE__);
187                 ret = false;
188                 goto done;
189         }
190         cli->session->pid--;
191         memset(buf, 0, maxsize);
192         io.read.in.offset = 0;
193         io.read.in.count = ~0;
194         status = smb_raw_read(cli->tree, &io);
195         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
196         
197
198 done:
199         smbcli_close(cli->tree, fnum);
200         smb_raw_exit(cli->session);
201         smbcli_deltree(cli->tree, BASEDIR);
202         return ret;
203 }
204
205
206 /*
207   test lockread ops
208 */
209 static bool test_lockread(struct torture_context *tctx, 
210                                                   struct smbcli_state *cli)
211 {
212         union smb_read io;
213         NTSTATUS status;
214         bool ret = true;
215         int fnum;
216         uint8_t *buf;
217         const int maxsize = 90000;
218         const char *fname = BASEDIR "\\test.txt";
219         const char *test_data = "TEST DATA";
220         uint_t seed = time(NULL);
221
222         buf = talloc_zero_array(tctx, uint8_t, maxsize);
223
224         if (!torture_setup_dir(cli, BASEDIR)) {
225                 return false;
226         }
227
228         printf("Testing RAW_READ_LOCKREAD\n");
229         io.generic.level = RAW_READ_LOCKREAD;
230         
231         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
232         if (fnum == -1) {
233                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
234                 ret = false;
235                 goto done;
236         }
237
238         printf("Trying empty file read\n");
239         io.lockread.in.file.fnum = fnum;
240         io.lockread.in.count = 1;
241         io.lockread.in.offset = 1;
242         io.lockread.in.remaining = 0;
243         io.lockread.out.data = buf;
244         status = smb_raw_read(cli->tree, &io);
245
246         CHECK_STATUS(status, NT_STATUS_OK);
247         CHECK_VALUE(io.lockread.out.nread, 0);
248
249         status = smb_raw_read(cli->tree, &io);
250         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
251
252         status = smb_raw_read(cli->tree, &io);
253         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
254
255         printf("Trying zero file read\n");
256         io.lockread.in.count = 0;
257         status = smb_raw_read(cli->tree, &io);
258         CHECK_STATUS(status, NT_STATUS_OK);
259
260         smbcli_unlock(cli->tree, fnum, 1, 1);
261
262         printf("Trying bad fnum\n");
263         io.lockread.in.file.fnum = fnum+1;
264         status = smb_raw_read(cli->tree, &io);
265         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
266         io.lockread.in.file.fnum = fnum;
267
268         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
269
270         printf("Trying small read\n");
271         io.lockread.in.file.fnum = fnum;
272         io.lockread.in.offset = 0;
273         io.lockread.in.remaining = 0;
274         io.lockread.in.count = strlen(test_data);
275         status = smb_raw_read(cli->tree, &io);
276         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
277
278         smbcli_unlock(cli->tree, fnum, 1, 0);
279
280         status = smb_raw_read(cli->tree, &io);
281         CHECK_STATUS(status, NT_STATUS_OK);
282         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
283         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
284                 ret = false;
285                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
286                 goto done;
287         }
288
289         printf("Trying short read\n");
290         io.lockread.in.offset = 1;
291         io.lockread.in.count = strlen(test_data);
292         status = smb_raw_read(cli->tree, &io);
293         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
294         smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
295         status = smb_raw_read(cli->tree, &io);
296         CHECK_STATUS(status, NT_STATUS_OK);
297
298         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
299         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
300                 ret = false;
301                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
302                 goto done;
303         }
304
305         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
306                 printf("Trying max offset\n");
307                 io.lockread.in.offset = ~0;
308                 io.lockread.in.count = strlen(test_data);
309                 status = smb_raw_read(cli->tree, &io);
310                 CHECK_STATUS(status, NT_STATUS_OK);
311                 CHECK_VALUE(io.lockread.out.nread, 0);
312         }
313
314         setup_buffer(buf, seed, maxsize);
315         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
316         memset(buf, 0, maxsize);
317
318         printf("Trying large read\n");
319         io.lockread.in.offset = 0;
320         io.lockread.in.count = ~0;
321         status = smb_raw_read(cli->tree, &io);
322         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
323         smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
324         status = smb_raw_read(cli->tree, &io);
325         CHECK_STATUS(status, NT_STATUS_OK);
326         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
327         smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
328
329
330         printf("Trying locked region\n");
331         cli->session->pid++;
332         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
333                 printf("Failed to lock file at %d\n", __LINE__);
334                 ret = false;
335                 goto done;
336         }
337         cli->session->pid--;
338         memset(buf, 0, maxsize);
339         io.lockread.in.offset = 0;
340         io.lockread.in.count = ~0;
341         status = smb_raw_read(cli->tree, &io);
342         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
343         
344
345 done:
346         smbcli_close(cli->tree, fnum);
347         smbcli_deltree(cli->tree, BASEDIR);
348         return ret;
349 }
350
351
352 /*
353   test readx ops
354 */
355 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
356 {
357         union smb_read io;
358         NTSTATUS status;
359         bool ret = true;
360         int fnum;
361         uint8_t *buf;
362         const int maxsize = 90000;
363         const char *fname = BASEDIR "\\test.txt";
364         const char *test_data = "TEST DATA";
365         uint_t seed = time(NULL);
366
367         buf = talloc_zero_array(tctx, uint8_t, maxsize);
368
369         if (!torture_setup_dir(cli, BASEDIR)) {
370                 return false;
371         }
372
373         printf("Testing RAW_READ_READX\n");
374         
375         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
376         if (fnum == -1) {
377                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
378                 ret = false;
379                 goto done;
380         }
381
382         printf("Trying empty file read\n");
383         io.generic.level = RAW_READ_READX;
384         io.readx.in.file.fnum = fnum;
385         io.readx.in.mincnt = 1;
386         io.readx.in.maxcnt = 1;
387         io.readx.in.offset = 0;
388         io.readx.in.remaining = 0;
389         io.readx.in.read_for_execute = false;
390         io.readx.out.data = buf;
391         status = smb_raw_read(cli->tree, &io);
392
393         CHECK_STATUS(status, NT_STATUS_OK);
394         CHECK_VALUE(io.readx.out.nread, 0);
395         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
396         CHECK_VALUE(io.readx.out.compaction_mode, 0);
397
398         printf("Trying zero file read\n");
399         io.readx.in.mincnt = 0;
400         io.readx.in.maxcnt = 0;
401         status = smb_raw_read(cli->tree, &io);
402         CHECK_STATUS(status, NT_STATUS_OK);
403         CHECK_VALUE(io.readx.out.nread, 0);
404         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
405         CHECK_VALUE(io.readx.out.compaction_mode, 0);
406
407         printf("Trying bad fnum\n");
408         io.readx.in.file.fnum = fnum+1;
409         status = smb_raw_read(cli->tree, &io);
410         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
411         io.readx.in.file.fnum = fnum;
412
413         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
414
415         printf("Trying small read\n");
416         io.readx.in.file.fnum = fnum;
417         io.readx.in.offset = 0;
418         io.readx.in.remaining = 0;
419         io.readx.in.read_for_execute = false;
420         io.readx.in.mincnt = strlen(test_data);
421         io.readx.in.maxcnt = strlen(test_data);
422         status = smb_raw_read(cli->tree, &io);
423         CHECK_STATUS(status, NT_STATUS_OK);
424         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
425         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
426         CHECK_VALUE(io.readx.out.compaction_mode, 0);
427         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
428                 ret = false;
429                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
430                 goto done;
431         }
432
433         printf("Trying short read\n");
434         io.readx.in.offset = 1;
435         io.readx.in.mincnt = strlen(test_data);
436         io.readx.in.maxcnt = strlen(test_data);
437         status = smb_raw_read(cli->tree, &io);
438         CHECK_STATUS(status, NT_STATUS_OK);
439         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
440         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
441         CHECK_VALUE(io.readx.out.compaction_mode, 0);
442         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
443                 ret = false;
444                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
445                 goto done;
446         }
447
448         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
449                 printf("Trying max offset\n");
450                 io.readx.in.offset = 0xffffffff;
451                 io.readx.in.mincnt = strlen(test_data);
452                 io.readx.in.maxcnt = strlen(test_data);
453                 status = smb_raw_read(cli->tree, &io);
454                 CHECK_STATUS(status, NT_STATUS_OK);
455                 CHECK_VALUE(io.readx.out.nread, 0);
456                 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
457                 CHECK_VALUE(io.readx.out.compaction_mode, 0);
458         }
459
460         printf("Trying mincnt past EOF\n");
461         memset(buf, 0, maxsize);
462         io.readx.in.offset = 0;
463         io.readx.in.mincnt = 100;
464         io.readx.in.maxcnt = 110;
465         status = smb_raw_read(cli->tree, &io);
466         CHECK_STATUS(status, NT_STATUS_OK);
467         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
468         CHECK_VALUE(io.readx.out.compaction_mode, 0);
469         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
470         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
471                 ret = false;
472                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
473                 goto done;
474         }
475
476
477         setup_buffer(buf, seed, maxsize);
478         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
479         memset(buf, 0, maxsize);
480
481         printf("Trying large read\n");
482         io.readx.in.offset = 0;
483         io.readx.in.mincnt = 0xFFFF;
484         io.readx.in.maxcnt = 0xFFFF;
485         status = smb_raw_read(cli->tree, &io);
486         CHECK_STATUS(status, NT_STATUS_OK);
487         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
488         CHECK_VALUE(io.readx.out.compaction_mode, 0);
489         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
490         CHECK_BUFFER(buf, seed, io.readx.out.nread);
491
492         printf("Trying extra large read\n");
493         io.readx.in.offset = 0;
494         io.readx.in.mincnt = 100;
495         io.readx.in.maxcnt = 80000;
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         if (torture_setting_bool(tctx, "samba3", false) ||
501             torture_setting_bool(tctx, "samba4", false)) {
502                 printf("SAMBA: large read extension\n");
503                 CHECK_VALUE(io.readx.out.nread, 80000);
504         } else {
505                 CHECK_VALUE(io.readx.out.nread, 0);
506         }
507         CHECK_BUFFER(buf, seed, io.readx.out.nread);
508
509         printf("Trying mincnt > maxcnt\n");
510         memset(buf, 0, maxsize);
511         io.readx.in.offset = 0;
512         io.readx.in.mincnt = 30000;
513         io.readx.in.maxcnt = 20000;
514         status = smb_raw_read(cli->tree, &io);
515         CHECK_STATUS(status, NT_STATUS_OK);
516         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
517         CHECK_VALUE(io.readx.out.compaction_mode, 0);
518         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
519         CHECK_BUFFER(buf, seed, io.readx.out.nread);
520
521         printf("Trying mincnt < maxcnt\n");
522         memset(buf, 0, maxsize);
523         io.readx.in.offset = 0;
524         io.readx.in.mincnt = 20000;
525         io.readx.in.maxcnt = 30000;
526         status = smb_raw_read(cli->tree, &io);
527         CHECK_STATUS(status, NT_STATUS_OK);
528         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
529         CHECK_VALUE(io.readx.out.compaction_mode, 0);
530         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
531         CHECK_BUFFER(buf, seed, io.readx.out.nread);
532
533         if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
534                 printf("Trying large readx\n");
535                 io.readx.in.offset = 0;
536                 io.readx.in.mincnt = 0;
537                 io.readx.in.maxcnt = 0x10000 - 1;
538                 status = smb_raw_read(cli->tree, &io);
539                 CHECK_STATUS(status, NT_STATUS_OK);
540                 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
541
542                 io.readx.in.maxcnt = 0x10000;
543                 status = smb_raw_read(cli->tree, &io);
544                 CHECK_STATUS(status, NT_STATUS_OK);
545                 if (torture_setting_bool(tctx, "samba3", false) || 
546                     torture_setting_bool(tctx, "samba4", false)) {
547                         printf("SAMBA: large read extension\n");
548                         CHECK_VALUE(io.readx.out.nread, 0x10000);
549                 } else {
550                         CHECK_VALUE(io.readx.out.nread, 0);
551                 }
552
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                     torture_setting_bool(tctx, "samba4", false)) {
558                         printf("SAMBA: large read extension\n");
559                         CHECK_VALUE(io.readx.out.nread, 0x10001);
560                 } else {
561                         CHECK_VALUE(io.readx.out.nread, 0);
562                 }
563         } else {
564                 printf("Server does not support the CAP_LARGE_READX extension\n");
565         }
566
567         printf("Trying locked region\n");
568         cli->session->pid++;
569         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
570                 printf("Failed to lock file at %d\n", __LINE__);
571                 ret = false;
572                 goto done;
573         }
574         cli->session->pid--;
575         memset(buf, 0, maxsize);
576         io.readx.in.offset = 0;
577         io.readx.in.mincnt = 100;
578         io.readx.in.maxcnt = 200;
579         status = smb_raw_read(cli->tree, &io);
580         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
581
582         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
583                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
584                 goto done;
585         }
586
587         printf("Trying large offset read\n");
588         io.readx.in.offset = ((uint64_t)0x2) << 32;
589         io.readx.in.mincnt = 10;
590         io.readx.in.maxcnt = 10;
591         status = smb_raw_read(cli->tree, &io);
592         CHECK_STATUS(status, NT_STATUS_OK);
593         CHECK_VALUE(io.readx.out.nread, 0);
594
595         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
596                 printf("Failed to lock file at %d\n", __LINE__);
597                 ret = false;
598                 goto done;
599         }
600
601         status = smb_raw_read(cli->tree, &io);
602         CHECK_STATUS(status, NT_STATUS_OK);
603         CHECK_VALUE(io.readx.out.nread, 0);
604
605 done:
606         smbcli_close(cli->tree, fnum);
607         smbcli_deltree(cli->tree, BASEDIR);
608         return ret;
609 }
610
611
612 /*
613   test readbraw ops
614 */
615 static bool test_readbraw(struct torture_context *tctx, 
616                                                   struct smbcli_state *cli)
617 {
618         union smb_read io;
619         NTSTATUS status;
620         bool ret = true;
621         int fnum;
622         uint8_t *buf;
623         const int maxsize = 90000;
624         const char *fname = BASEDIR "\\test.txt";
625         const char *test_data = "TEST DATA";
626         uint_t seed = time(NULL);
627
628         if (!cli->transport->negotiate.readbraw_supported) {
629                 printf("Server does not support readbraw - skipping\n");
630                 return true;
631         }
632
633         buf = talloc_zero_array(tctx, uint8_t, maxsize);
634
635         if (!torture_setup_dir(cli, BASEDIR)) {
636                 return false;
637         }
638
639         printf("Testing RAW_READ_READBRAW\n");
640         
641         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
642         if (fnum == -1) {
643                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
644                 ret = false;
645                 goto done;
646         }
647
648         printf("Trying empty file read\n");
649         io.generic.level = RAW_READ_READBRAW;
650         io.readbraw.in.file.fnum = fnum;
651         io.readbraw.in.mincnt = 1;
652         io.readbraw.in.maxcnt = 1;
653         io.readbraw.in.offset = 0;
654         io.readbraw.in.timeout = 0;
655         io.readbraw.out.data = buf;
656         status = smb_raw_read(cli->tree, &io);
657
658         CHECK_STATUS(status, NT_STATUS_OK);
659         CHECK_VALUE(io.readbraw.out.nread, 0);
660
661         printf("Trying zero file read\n");
662         io.readbraw.in.mincnt = 0;
663         io.readbraw.in.maxcnt = 0;
664         status = smb_raw_read(cli->tree, &io);
665         CHECK_STATUS(status, NT_STATUS_OK);
666         CHECK_VALUE(io.readbraw.out.nread, 0);
667
668         printf("Trying bad fnum\n");
669         io.readbraw.in.file.fnum = fnum+1;
670         status = smb_raw_read(cli->tree, &io);
671         CHECK_STATUS(status, NT_STATUS_OK);
672         CHECK_VALUE(io.readbraw.out.nread, 0);
673         io.readbraw.in.file.fnum = fnum;
674
675         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
676
677         printf("Trying small read\n");
678         io.readbraw.in.file.fnum = fnum;
679         io.readbraw.in.offset = 0;
680         io.readbraw.in.mincnt = strlen(test_data);
681         io.readbraw.in.maxcnt = strlen(test_data);
682         status = smb_raw_read(cli->tree, &io);
683         CHECK_STATUS(status, NT_STATUS_OK);
684         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
685         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
686                 ret = false;
687                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
688                 goto done;
689         }
690
691         printf("Trying short read\n");
692         io.readbraw.in.offset = 1;
693         io.readbraw.in.mincnt = strlen(test_data);
694         io.readbraw.in.maxcnt = strlen(test_data);
695         status = smb_raw_read(cli->tree, &io);
696         CHECK_STATUS(status, NT_STATUS_OK);
697         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
698         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
699                 ret = false;
700                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
701                 goto done;
702         }
703
704         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
705                 printf("Trying max offset\n");
706                 io.readbraw.in.offset = ~0;
707                 io.readbraw.in.mincnt = strlen(test_data);
708                 io.readbraw.in.maxcnt = strlen(test_data);
709                 status = smb_raw_read(cli->tree, &io);
710                 CHECK_STATUS(status, NT_STATUS_OK);
711                 CHECK_VALUE(io.readbraw.out.nread, 0);
712         }
713
714         setup_buffer(buf, seed, maxsize);
715         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
716         memset(buf, 0, maxsize);
717
718         printf("Trying large read\n");
719         io.readbraw.in.offset = 0;
720         io.readbraw.in.mincnt = ~0;
721         io.readbraw.in.maxcnt = ~0;
722         status = smb_raw_read(cli->tree, &io);
723         CHECK_STATUS(status, NT_STATUS_OK);
724         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
725         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
726
727         printf("Trying mincnt > maxcnt\n");
728         memset(buf, 0, maxsize);
729         io.readbraw.in.offset = 0;
730         io.readbraw.in.mincnt = 30000;
731         io.readbraw.in.maxcnt = 20000;
732         status = smb_raw_read(cli->tree, &io);
733         CHECK_STATUS(status, NT_STATUS_OK);
734         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
735         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
736
737         printf("Trying mincnt < maxcnt\n");
738         memset(buf, 0, maxsize);
739         io.readbraw.in.offset = 0;
740         io.readbraw.in.mincnt = 20000;
741         io.readbraw.in.maxcnt = 30000;
742         status = smb_raw_read(cli->tree, &io);
743         CHECK_STATUS(status, NT_STATUS_OK);
744         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
745         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
746
747         printf("Trying locked region\n");
748         cli->session->pid++;
749         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
750                 printf("Failed to lock file at %d\n", __LINE__);
751                 ret = false;
752                 goto done;
753         }
754         cli->session->pid--;
755         memset(buf, 0, maxsize);
756         io.readbraw.in.offset = 0;
757         io.readbraw.in.mincnt = 100;
758         io.readbraw.in.maxcnt = 200;
759         status = smb_raw_read(cli->tree, &io);
760         CHECK_STATUS(status, NT_STATUS_OK);
761         CHECK_VALUE(io.readbraw.out.nread, 0);
762
763         printf("Trying locked region with timeout\n");
764         memset(buf, 0, maxsize);
765         io.readbraw.in.offset = 0;
766         io.readbraw.in.mincnt = 100;
767         io.readbraw.in.maxcnt = 200;
768         io.readbraw.in.timeout = 10000;
769         status = smb_raw_read(cli->tree, &io);
770         CHECK_STATUS(status, NT_STATUS_OK);
771         CHECK_VALUE(io.readbraw.out.nread, 0);
772
773         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
774                 printf("Trying large offset read\n");
775                 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
776                 io.readbraw.in.mincnt = 10;
777                 io.readbraw.in.maxcnt = 10;
778                 io.readbraw.in.timeout = 0;
779                 status = smb_raw_read(cli->tree, &io);
780                 CHECK_STATUS(status, NT_STATUS_OK);
781                 CHECK_VALUE(io.readbraw.out.nread, 0);
782         }
783
784 done:
785         smbcli_close(cli->tree, fnum);
786         smbcli_deltree(cli->tree, BASEDIR);
787         return ret;
788 }
789
790 /*
791   test read for execute
792 */
793 static bool test_read_for_execute(struct torture_context *tctx, 
794                                                                   struct smbcli_state *cli)
795 {
796         union smb_open op;
797         union smb_write wr;
798         union smb_read rd;
799         NTSTATUS status;
800         bool ret = true;
801         int fnum=0;
802         uint8_t *buf;
803         const int maxsize = 900;
804         const char *fname = BASEDIR "\\test.txt";
805         const uint8_t data[] = "TEST DATA";
806
807         buf = talloc_zero_array(tctx, uint8_t, maxsize);
808
809         if (!torture_setup_dir(cli, BASEDIR)) {
810                 return false;
811         }
812
813         printf("Testing RAW_READ_READX with read_for_execute\n");
814
815         op.generic.level = RAW_OPEN_NTCREATEX;
816         op.ntcreatex.in.root_fid.fnum = 0;
817         op.ntcreatex.in.flags = 0;
818         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
819         op.ntcreatex.in.create_options = 0;
820         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
821         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
822         op.ntcreatex.in.alloc_size = 0;
823         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
824         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
825         op.ntcreatex.in.security_flags = 0;
826         op.ntcreatex.in.fname = fname;
827         status = smb_raw_open(cli->tree, tctx, &op);
828         CHECK_STATUS(status, NT_STATUS_OK);
829         fnum = op.ntcreatex.out.file.fnum;
830
831         wr.generic.level = RAW_WRITE_WRITEX;
832         wr.writex.in.file.fnum = fnum;
833         wr.writex.in.offset = 0;
834         wr.writex.in.wmode = 0;
835         wr.writex.in.remaining = 0;
836         wr.writex.in.count = ARRAY_SIZE(data);
837         wr.writex.in.data = data;
838         status = smb_raw_write(cli->tree, &wr);
839         CHECK_STATUS(status, NT_STATUS_OK);
840         CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
841
842         status = smbcli_close(cli->tree, fnum);
843         CHECK_STATUS(status, NT_STATUS_OK);
844
845         printf("open file with SEC_FILE_EXECUTE\n");
846         op.generic.level = RAW_OPEN_NTCREATEX;
847         op.ntcreatex.in.root_fid.fnum = 0;
848         op.ntcreatex.in.flags = 0;
849         op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
850         op.ntcreatex.in.create_options = 0;
851         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
852         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
853         op.ntcreatex.in.alloc_size = 0;
854         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
855         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
856         op.ntcreatex.in.security_flags = 0;
857         op.ntcreatex.in.fname = fname;
858         status = smb_raw_open(cli->tree, tctx, &op);
859         CHECK_STATUS(status, NT_STATUS_OK);
860         fnum = op.ntcreatex.out.file.fnum;
861
862         printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
863         rd.generic.level = RAW_READ_READX;
864         rd.readx.in.file.fnum = fnum;
865         rd.readx.in.mincnt = 0;
866         rd.readx.in.maxcnt = maxsize;
867         rd.readx.in.offset = 0;
868         rd.readx.in.remaining = 0;
869         rd.readx.in.read_for_execute = true;
870         rd.readx.out.data = buf;
871         status = smb_raw_read(cli->tree, &rd);
872         CHECK_STATUS(status, NT_STATUS_OK);
873         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
874         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
875         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
876
877         printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
878         rd.generic.level = RAW_READ_READX;
879         rd.readx.in.file.fnum = fnum;
880         rd.readx.in.mincnt = 0;
881         rd.readx.in.maxcnt = maxsize;
882         rd.readx.in.offset = 0;
883         rd.readx.in.remaining = 0;
884         rd.readx.in.read_for_execute = false;
885         rd.readx.out.data = buf;
886         status = smb_raw_read(cli->tree, &rd);
887         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
888
889         status = smbcli_close(cli->tree, fnum);
890         CHECK_STATUS(status, NT_STATUS_OK);
891
892         printf("open file with SEC_FILE_READ_DATA\n");
893         op.generic.level = RAW_OPEN_NTCREATEX;
894         op.ntcreatex.in.root_fid.fnum = 0;
895         op.ntcreatex.in.flags = 0;
896         op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
897         op.ntcreatex.in.create_options = 0;
898         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
899         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
900         op.ntcreatex.in.alloc_size = 0;
901         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
902         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
903         op.ntcreatex.in.security_flags = 0;
904         op.ntcreatex.in.fname = fname;
905         status = smb_raw_open(cli->tree, tctx, &op);
906         CHECK_STATUS(status, NT_STATUS_OK);
907         fnum = op.ntcreatex.out.file.fnum;
908
909         printf("read with FLAGS2_READ_PERMIT_EXECUTE\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 = true;
917         rd.readx.out.data = buf;
918         status = smb_raw_read(cli->tree, &rd);
919         CHECK_STATUS(status, NT_STATUS_OK);
920         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
921         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
922         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
923
924         printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
925         rd.generic.level = RAW_READ_READX;
926         rd.readx.in.file.fnum = fnum;
927         rd.readx.in.mincnt = 0;
928         rd.readx.in.maxcnt = maxsize;
929         rd.readx.in.offset = 0;
930         rd.readx.in.remaining = 0;
931         rd.readx.in.read_for_execute = false;
932         rd.readx.out.data = buf;
933         status = smb_raw_read(cli->tree, &rd);
934         CHECK_STATUS(status, NT_STATUS_OK);
935         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
936         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
937         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
938
939 done:
940         smbcli_close(cli->tree, fnum);
941         smbcli_deltree(cli->tree, BASEDIR);
942         return ret;
943 }
944
945
946 /* 
947    basic testing of read calls
948 */
949 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
950 {
951         struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
952
953         torture_suite_add_1smb_test(suite, "read", test_read);
954         torture_suite_add_1smb_test(suite, "readx", test_readx);
955         torture_suite_add_1smb_test(suite, "lockread", test_lockread);
956         torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
957         torture_suite_add_1smb_test(suite, "read for execute", 
958                                                                 test_read_for_execute);
959
960         return suite;
961 }