bb27ba71e585fafc5bba4fec8764d08cd9eb6124
[sfrench/samba-autobuild/.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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28
29 #define CHECK_STATUS(status, correct) do { \
30         if (!NT_STATUS_EQUAL(status, correct)) { \
31                 printf("(%s) Incorrect status %s - should be %s\n", \
32                        __location__, nt_errstr(status), nt_errstr(correct)); \
33                 ret = False; \
34                 goto done; \
35         }} while (0)
36
37 #define CHECK_VALUE(v, correct) do { \
38         if ((v) != (correct)) { \
39                 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
40                        __location__, #v, (long)v, (long)correct); \
41                 ret = False; \
42                 goto done; \
43         }} while (0)
44
45 #define CHECK_BUFFER(buf, seed, len) do { \
46         if (!check_buffer(buf, seed, len, __LINE__)) { \
47                 ret = False; \
48                 goto done; \
49         }} while (0)
50
51 #define BASEDIR "\\testread"
52
53
54 /*
55   setup a random buffer based on a seed
56 */
57 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
58 {
59         int i;
60         srandom(seed);
61         for (i=0;i<len;i++) buf[i] = random();
62 }
63
64 /*
65   check a random buffer based on a seed
66 */
67 static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, int line)
68 {
69         int i;
70         srandom(seed);
71         for (i=0;i<len;i++) {
72                 uint8_t v = random();
73                 if (buf[i] != v) {
74                         printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
75                                line, i, buf[i], v);
76                         return False;
77                 }
78         }
79         return True;
80 }
81
82 /*
83   test read ops
84 */
85 static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
86 {
87         union smb_read io;
88         NTSTATUS status;
89         BOOL ret = True;
90         int fnum;
91         uint8_t *buf;
92         const int maxsize = 90000;
93         const char *fname = BASEDIR "\\test.txt";
94         const char *test_data = "TEST DATA";
95         uint_t seed = time(NULL);
96
97         buf = talloc_zero_size(mem_ctx, maxsize);
98
99         if (!torture_setup_dir(cli, BASEDIR)) {
100                 return False;
101         }
102
103         printf("Testing RAW_READ_READ\n");
104         io.generic.level = RAW_READ_READ;
105         
106         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
107         if (fnum == -1) {
108                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
109                 ret = False;
110                 goto done;
111         }
112
113         printf("Trying empty file read\n");
114         io.read.in.file.fnum = fnum;
115         io.read.in.count = 1;
116         io.read.in.offset = 0;
117         io.read.in.remaining = 0;
118         io.read.out.data = buf;
119         status = smb_raw_read(cli->tree, &io);
120
121         CHECK_STATUS(status, NT_STATUS_OK);
122         CHECK_VALUE(io.read.out.nread, 0);
123
124         printf("Trying zero file read\n");
125         io.read.in.count = 0;
126         status = smb_raw_read(cli->tree, &io);
127         CHECK_STATUS(status, NT_STATUS_OK);
128         CHECK_VALUE(io.read.out.nread, 0);
129
130         printf("Trying bad fnum\n");
131         io.read.in.file.fnum = fnum+1;
132         status = smb_raw_read(cli->tree, &io);
133         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
134         io.read.in.file.fnum = fnum;
135
136         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
137
138         printf("Trying small read\n");
139         io.read.in.file.fnum = fnum;
140         io.read.in.offset = 0;
141         io.read.in.remaining = 0;
142         io.read.in.count = strlen(test_data);
143         status = smb_raw_read(cli->tree, &io);
144         CHECK_STATUS(status, NT_STATUS_OK);
145         CHECK_VALUE(io.read.out.nread, strlen(test_data));
146         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
147                 ret = False;
148                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
149                 goto done;
150         }
151
152         printf("Trying short read\n");
153         io.read.in.offset = 1;
154         io.read.in.count = strlen(test_data);
155         status = smb_raw_read(cli->tree, &io);
156         CHECK_STATUS(status, NT_STATUS_OK);
157         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
158         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
159                 ret = False;
160                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
161                 goto done;
162         }
163
164         printf("Trying max offset\n");
165         io.read.in.offset = ~0;
166         io.read.in.count = strlen(test_data);
167         status = smb_raw_read(cli->tree, &io);
168         CHECK_STATUS(status, NT_STATUS_OK);
169         CHECK_VALUE(io.read.out.nread, 0);
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 smbcli_state *cli, TALLOC_CTX *mem_ctx)
210 {
211         union smb_read io;
212         NTSTATUS status;
213         BOOL ret = True;
214         int fnum;
215         uint8_t *buf;
216         const int maxsize = 90000;
217         const char *fname = BASEDIR "\\test.txt";
218         const char *test_data = "TEST DATA";
219         uint_t seed = time(NULL);
220
221         buf = talloc_zero_size(mem_ctx, maxsize);
222
223         if (!torture_setup_dir(cli, BASEDIR)) {
224                 return False;
225         }
226
227         printf("Testing RAW_READ_LOCKREAD\n");
228         io.generic.level = RAW_READ_LOCKREAD;
229         
230         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
231         if (fnum == -1) {
232                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
233                 ret = False;
234                 goto done;
235         }
236
237         printf("Trying empty file read\n");
238         io.lockread.in.file.fnum = fnum;
239         io.lockread.in.count = 1;
240         io.lockread.in.offset = 1;
241         io.lockread.in.remaining = 0;
242         io.lockread.out.data = buf;
243         status = smb_raw_read(cli->tree, &io);
244
245         CHECK_STATUS(status, NT_STATUS_OK);
246         CHECK_VALUE(io.lockread.out.nread, 0);
247
248         status = smb_raw_read(cli->tree, &io);
249         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
250
251         status = smb_raw_read(cli->tree, &io);
252         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
253
254         printf("Trying zero file read\n");
255         io.lockread.in.count = 0;
256         status = smb_raw_read(cli->tree, &io);
257         CHECK_STATUS(status, NT_STATUS_OK);
258
259         smbcli_unlock(cli->tree, fnum, 1, 1);
260
261         printf("Trying bad fnum\n");
262         io.lockread.in.file.fnum = fnum+1;
263         status = smb_raw_read(cli->tree, &io);
264         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
265         io.lockread.in.file.fnum = fnum;
266
267         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
268
269         printf("Trying small read\n");
270         io.lockread.in.file.fnum = fnum;
271         io.lockread.in.offset = 0;
272         io.lockread.in.remaining = 0;
273         io.lockread.in.count = strlen(test_data);
274         status = smb_raw_read(cli->tree, &io);
275         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
276
277         smbcli_unlock(cli->tree, fnum, 1, 0);
278
279         status = smb_raw_read(cli->tree, &io);
280         CHECK_STATUS(status, NT_STATUS_OK);
281         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
282         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
283                 ret = False;
284                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
285                 goto done;
286         }
287
288         printf("Trying short read\n");
289         io.lockread.in.offset = 1;
290         io.lockread.in.count = strlen(test_data);
291         status = smb_raw_read(cli->tree, &io);
292         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
293         smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
294         status = smb_raw_read(cli->tree, &io);
295         CHECK_STATUS(status, NT_STATUS_OK);
296
297         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
298         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
299                 ret = False;
300                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
301                 goto done;
302         }
303
304         printf("Trying max offset\n");
305         io.lockread.in.offset = ~0;
306         io.lockread.in.count = strlen(test_data);
307         status = smb_raw_read(cli->tree, &io);
308         CHECK_STATUS(status, NT_STATUS_OK);
309         CHECK_VALUE(io.lockread.out.nread, 0);
310
311         setup_buffer(buf, seed, maxsize);
312         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
313         memset(buf, 0, maxsize);
314
315         printf("Trying large read\n");
316         io.lockread.in.offset = 0;
317         io.lockread.in.count = ~0;
318         status = smb_raw_read(cli->tree, &io);
319         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
320         smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
321         status = smb_raw_read(cli->tree, &io);
322         CHECK_STATUS(status, NT_STATUS_OK);
323         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
324         smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
325
326
327         printf("Trying locked region\n");
328         cli->session->pid++;
329         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
330                 printf("Failed to lock file at %d\n", __LINE__);
331                 ret = False;
332                 goto done;
333         }
334         cli->session->pid--;
335         memset(buf, 0, maxsize);
336         io.lockread.in.offset = 0;
337         io.lockread.in.count = ~0;
338         status = smb_raw_read(cli->tree, &io);
339         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
340         
341
342 done:
343         smbcli_close(cli->tree, fnum);
344         smbcli_deltree(cli->tree, BASEDIR);
345         return ret;
346 }
347
348
349 /*
350   test readx ops
351 */
352 static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
353 {
354         union smb_read io;
355         NTSTATUS status;
356         BOOL ret = True;
357         int fnum;
358         uint8_t *buf;
359         const int maxsize = 90000;
360         const char *fname = BASEDIR "\\test.txt";
361         const char *test_data = "TEST DATA";
362         uint_t seed = time(NULL);
363
364         buf = talloc_zero_size(mem_ctx, maxsize);
365
366         if (!torture_setup_dir(cli, BASEDIR)) {
367                 return False;
368         }
369
370         printf("Testing RAW_READ_READX\n");
371         
372         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
373         if (fnum == -1) {
374                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
375                 ret = False;
376                 goto done;
377         }
378
379         printf("Trying empty file read\n");
380         io.generic.level = RAW_READ_READX;
381         io.readx.in.file.fnum = fnum;
382         io.readx.in.mincnt = 1;
383         io.readx.in.maxcnt = 1;
384         io.readx.in.offset = 0;
385         io.readx.in.remaining = 0;
386         io.readx.in.read_for_execute = False;
387         io.readx.out.data = buf;
388         status = smb_raw_read(cli->tree, &io);
389
390         CHECK_STATUS(status, NT_STATUS_OK);
391         CHECK_VALUE(io.readx.out.nread, 0);
392         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
393         CHECK_VALUE(io.readx.out.compaction_mode, 0);
394
395         printf("Trying zero file read\n");
396         io.readx.in.mincnt = 0;
397         io.readx.in.maxcnt = 0;
398         status = smb_raw_read(cli->tree, &io);
399         CHECK_STATUS(status, NT_STATUS_OK);
400         CHECK_VALUE(io.readx.out.nread, 0);
401         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
402         CHECK_VALUE(io.readx.out.compaction_mode, 0);
403
404         printf("Trying bad fnum\n");
405         io.readx.in.file.fnum = fnum+1;
406         status = smb_raw_read(cli->tree, &io);
407         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
408         io.readx.in.file.fnum = fnum;
409
410         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
411
412         printf("Trying small read\n");
413         io.readx.in.file.fnum = fnum;
414         io.readx.in.offset = 0;
415         io.readx.in.remaining = 0;
416         io.readx.in.read_for_execute = False;
417         io.readx.in.mincnt = strlen(test_data);
418         io.readx.in.maxcnt = strlen(test_data);
419         status = smb_raw_read(cli->tree, &io);
420         CHECK_STATUS(status, NT_STATUS_OK);
421         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
422         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
423         CHECK_VALUE(io.readx.out.compaction_mode, 0);
424         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
425                 ret = False;
426                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
427                 goto done;
428         }
429
430         printf("Trying short read\n");
431         io.readx.in.offset = 1;
432         io.readx.in.mincnt = strlen(test_data);
433         io.readx.in.maxcnt = strlen(test_data);
434         status = smb_raw_read(cli->tree, &io);
435         CHECK_STATUS(status, NT_STATUS_OK);
436         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
437         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
438         CHECK_VALUE(io.readx.out.compaction_mode, 0);
439         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
440                 ret = False;
441                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
442                 goto done;
443         }
444
445         printf("Trying max offset\n");
446         io.readx.in.offset = 0xffffffff;
447         io.readx.in.mincnt = strlen(test_data);
448         io.readx.in.maxcnt = strlen(test_data);
449         status = smb_raw_read(cli->tree, &io);
450         CHECK_STATUS(status, NT_STATUS_OK);
451         CHECK_VALUE(io.readx.out.nread, 0);
452         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
453         CHECK_VALUE(io.readx.out.compaction_mode, 0);
454
455         setup_buffer(buf, seed, maxsize);
456         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
457         memset(buf, 0, maxsize);
458
459         printf("Trying large read\n");
460         io.readx.in.offset = 0;
461         io.readx.in.mincnt = 0xFFFF;
462         io.readx.in.maxcnt = 0xFFFF;
463         status = smb_raw_read(cli->tree, &io);
464         CHECK_STATUS(status, NT_STATUS_OK);
465         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
466         CHECK_VALUE(io.readx.out.compaction_mode, 0);
467         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
468         CHECK_BUFFER(buf, seed, io.readx.out.nread);
469
470         printf("Trying extra large read\n");
471         io.readx.in.offset = 0;
472         io.readx.in.mincnt = 100;
473         io.readx.in.maxcnt = 80000;
474         status = smb_raw_read(cli->tree, &io);
475         CHECK_STATUS(status, NT_STATUS_OK);
476         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
477         CHECK_VALUE(io.readx.out.compaction_mode, 0);
478         if (lp_parm_bool(-1, "torture", "samba3", False)) {
479                 printf("SAMBA3: ignore wrong nread[%d] should be [%d]\n",
480                         io.readx.out.nread, 0);
481         } else {
482                 CHECK_VALUE(io.readx.out.nread, 0);
483         }
484         CHECK_BUFFER(buf, seed, io.readx.out.nread);
485
486         printf("Trying mincnt > maxcnt\n");
487         memset(buf, 0, maxsize);
488         io.readx.in.offset = 0;
489         io.readx.in.mincnt = 30000;
490         io.readx.in.maxcnt = 20000;
491         status = smb_raw_read(cli->tree, &io);
492         CHECK_STATUS(status, NT_STATUS_OK);
493         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
494         CHECK_VALUE(io.readx.out.compaction_mode, 0);
495         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
496         CHECK_BUFFER(buf, seed, io.readx.out.nread);
497
498         printf("Trying mincnt < maxcnt\n");
499         memset(buf, 0, maxsize);
500         io.readx.in.offset = 0;
501         io.readx.in.mincnt = 20000;
502         io.readx.in.maxcnt = 30000;
503         status = smb_raw_read(cli->tree, &io);
504         CHECK_STATUS(status, NT_STATUS_OK);
505         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
506         CHECK_VALUE(io.readx.out.compaction_mode, 0);
507         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
508         CHECK_BUFFER(buf, seed, io.readx.out.nread);
509
510         printf("Trying locked region\n");
511         cli->session->pid++;
512         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
513                 printf("Failed to lock file at %d\n", __LINE__);
514                 ret = False;
515                 goto done;
516         }
517         cli->session->pid--;
518         memset(buf, 0, maxsize);
519         io.readx.in.offset = 0;
520         io.readx.in.mincnt = 100;
521         io.readx.in.maxcnt = 200;
522         status = smb_raw_read(cli->tree, &io);
523         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
524
525         printf("Trying large offset read\n");
526         io.readx.in.offset = ((uint64_t)0x2) << 32;
527         io.readx.in.mincnt = 10;
528         io.readx.in.maxcnt = 10;
529         status = smb_raw_read(cli->tree, &io);
530         CHECK_STATUS(status, NT_STATUS_OK);
531         CHECK_VALUE(io.readx.out.nread, 0);
532
533         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
534                 printf("Failed to lock file at %d\n", __LINE__);
535                 ret = False;
536                 goto done;
537         }
538
539         status = smb_raw_read(cli->tree, &io);
540         CHECK_STATUS(status, NT_STATUS_OK);
541         CHECK_VALUE(io.readx.out.nread, 0);
542
543 done:
544         smbcli_close(cli->tree, fnum);
545         smbcli_deltree(cli->tree, BASEDIR);
546         return ret;
547 }
548
549
550 /*
551   test readbraw ops
552 */
553 static BOOL test_readbraw(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
554 {
555         union smb_read io;
556         NTSTATUS status;
557         BOOL ret = True;
558         int fnum;
559         uint8_t *buf;
560         const int maxsize = 90000;
561         const char *fname = BASEDIR "\\test.txt";
562         const char *test_data = "TEST DATA";
563         uint_t seed = time(NULL);
564
565         buf = talloc_zero_size(mem_ctx, maxsize);
566
567         if (!torture_setup_dir(cli, BASEDIR)) {
568                 return False;
569         }
570
571         printf("Testing RAW_READ_READBRAW\n");
572         
573         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
574         if (fnum == -1) {
575                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
576                 ret = False;
577                 goto done;
578         }
579
580         printf("Trying empty file read\n");
581         io.generic.level = RAW_READ_READBRAW;
582         io.readbraw.in.file.fnum = fnum;
583         io.readbraw.in.mincnt = 1;
584         io.readbraw.in.maxcnt = 1;
585         io.readbraw.in.offset = 0;
586         io.readbraw.in.timeout = 0;
587         io.readbraw.out.data = buf;
588         status = smb_raw_read(cli->tree, &io);
589
590         CHECK_STATUS(status, NT_STATUS_OK);
591         CHECK_VALUE(io.readbraw.out.nread, 0);
592
593         printf("Trying zero file read\n");
594         io.readbraw.in.mincnt = 0;
595         io.readbraw.in.maxcnt = 0;
596         status = smb_raw_read(cli->tree, &io);
597         CHECK_STATUS(status, NT_STATUS_OK);
598         CHECK_VALUE(io.readbraw.out.nread, 0);
599
600         printf("Trying bad fnum\n");
601         io.readbraw.in.file.fnum = fnum+1;
602         status = smb_raw_read(cli->tree, &io);
603         CHECK_STATUS(status, NT_STATUS_OK);
604         CHECK_VALUE(io.readbraw.out.nread, 0);
605         io.readbraw.in.file.fnum = fnum;
606
607         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
608
609         printf("Trying small read\n");
610         io.readbraw.in.file.fnum = fnum;
611         io.readbraw.in.offset = 0;
612         io.readbraw.in.mincnt = strlen(test_data);
613         io.readbraw.in.maxcnt = strlen(test_data);
614         status = smb_raw_read(cli->tree, &io);
615         CHECK_STATUS(status, NT_STATUS_OK);
616         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
617         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
618                 ret = False;
619                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
620                 goto done;
621         }
622
623         printf("Trying short read\n");
624         io.readbraw.in.offset = 1;
625         io.readbraw.in.mincnt = strlen(test_data);
626         io.readbraw.in.maxcnt = strlen(test_data);
627         status = smb_raw_read(cli->tree, &io);
628         CHECK_STATUS(status, NT_STATUS_OK);
629         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
630         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
631                 ret = False;
632                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
633                 goto done;
634         }
635
636         printf("Trying max offset\n");
637         io.readbraw.in.offset = ~0;
638         io.readbraw.in.mincnt = strlen(test_data);
639         io.readbraw.in.maxcnt = strlen(test_data);
640         status = smb_raw_read(cli->tree, &io);
641         CHECK_STATUS(status, NT_STATUS_OK);
642         CHECK_VALUE(io.readbraw.out.nread, 0);
643
644         setup_buffer(buf, seed, maxsize);
645         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
646         memset(buf, 0, maxsize);
647
648         printf("Trying large read\n");
649         io.readbraw.in.offset = 0;
650         io.readbraw.in.mincnt = ~0;
651         io.readbraw.in.maxcnt = ~0;
652         status = smb_raw_read(cli->tree, &io);
653         CHECK_STATUS(status, NT_STATUS_OK);
654         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
655         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
656
657         printf("Trying mincnt > maxcnt\n");
658         memset(buf, 0, maxsize);
659         io.readbraw.in.offset = 0;
660         io.readbraw.in.mincnt = 30000;
661         io.readbraw.in.maxcnt = 20000;
662         status = smb_raw_read(cli->tree, &io);
663         CHECK_STATUS(status, NT_STATUS_OK);
664         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
665         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
666
667         printf("Trying mincnt < maxcnt\n");
668         memset(buf, 0, maxsize);
669         io.readbraw.in.offset = 0;
670         io.readbraw.in.mincnt = 20000;
671         io.readbraw.in.maxcnt = 30000;
672         status = smb_raw_read(cli->tree, &io);
673         CHECK_STATUS(status, NT_STATUS_OK);
674         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
675         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
676
677         printf("Trying locked region\n");
678         cli->session->pid++;
679         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
680                 printf("Failed to lock file at %d\n", __LINE__);
681                 ret = False;
682                 goto done;
683         }
684         cli->session->pid--;
685         memset(buf, 0, maxsize);
686         io.readbraw.in.offset = 0;
687         io.readbraw.in.mincnt = 100;
688         io.readbraw.in.maxcnt = 200;
689         status = smb_raw_read(cli->tree, &io);
690         CHECK_STATUS(status, NT_STATUS_OK);
691         CHECK_VALUE(io.readbraw.out.nread, 0);
692
693         printf("Trying locked region with timeout\n");
694         memset(buf, 0, maxsize);
695         io.readbraw.in.offset = 0;
696         io.readbraw.in.mincnt = 100;
697         io.readbraw.in.maxcnt = 200;
698         io.readbraw.in.timeout = 10000;
699         status = smb_raw_read(cli->tree, &io);
700         CHECK_STATUS(status, NT_STATUS_OK);
701         CHECK_VALUE(io.readbraw.out.nread, 0);
702
703         printf("Trying large offset read\n");
704         io.readbraw.in.offset = ((uint64_t)0x2) << 32;
705         io.readbraw.in.mincnt = 10;
706         io.readbraw.in.maxcnt = 10;
707         io.readbraw.in.timeout = 0;
708         status = smb_raw_read(cli->tree, &io);
709         CHECK_STATUS(status, NT_STATUS_OK);
710         CHECK_VALUE(io.readbraw.out.nread, 0);
711
712 done:
713         smbcli_close(cli->tree, fnum);
714         smbcli_deltree(cli->tree, BASEDIR);
715         return ret;
716 }
717
718 /*
719   test read for execute
720 */
721 static BOOL test_read_for_execute(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
722 {
723         union smb_open op;
724         union smb_write wr;
725         union smb_read rd;
726         NTSTATUS status;
727         BOOL ret = True;
728         int fnum=0;
729         uint8_t *buf;
730         const int maxsize = 900;
731         const char *fname = BASEDIR "\\test.txt";
732         const uint8_t data[] = "TEST DATA";
733
734         buf = talloc_zero_size(mem_ctx, maxsize);
735
736         if (!torture_setup_dir(cli, BASEDIR)) {
737                 return False;
738         }
739
740         printf("Testing RAW_READ_READX with read_for_execute\n");
741
742         op.generic.level = RAW_OPEN_NTCREATEX;
743         op.ntcreatex.in.root_fid = 0;
744         op.ntcreatex.in.flags = 0;
745         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
746         op.ntcreatex.in.create_options = 0;
747         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
748         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
749         op.ntcreatex.in.alloc_size = 0;
750         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
751         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
752         op.ntcreatex.in.security_flags = 0;
753         op.ntcreatex.in.fname = fname;
754         status = smb_raw_open(cli->tree, mem_ctx, &op);
755         CHECK_STATUS(status, NT_STATUS_OK);
756         fnum = op.ntcreatex.out.file.fnum;
757
758         wr.generic.level = RAW_WRITE_WRITEX;
759         wr.writex.in.file.fnum = fnum;
760         wr.writex.in.offset = 0;
761         wr.writex.in.wmode = 0;
762         wr.writex.in.remaining = 0;
763         wr.writex.in.count = ARRAY_SIZE(data);
764         wr.writex.in.data = data;
765         status = smb_raw_write(cli->tree, &wr);
766         CHECK_STATUS(status, NT_STATUS_OK);
767         CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
768
769         status = smbcli_close(cli->tree, fnum);
770         CHECK_STATUS(status, NT_STATUS_OK);
771
772         printf("open file with SEC_FILE_EXECUTE\n");
773         op.generic.level = RAW_OPEN_NTCREATEX;
774         op.ntcreatex.in.root_fid = 0;
775         op.ntcreatex.in.flags = 0;
776         op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
777         op.ntcreatex.in.create_options = 0;
778         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
779         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
780         op.ntcreatex.in.alloc_size = 0;
781         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
782         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
783         op.ntcreatex.in.security_flags = 0;
784         op.ntcreatex.in.fname = fname;
785         status = smb_raw_open(cli->tree, mem_ctx, &op);
786         CHECK_STATUS(status, NT_STATUS_OK);
787         fnum = op.ntcreatex.out.file.fnum;
788
789         printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
790         rd.generic.level = RAW_READ_READX;
791         rd.readx.in.file.fnum = fnum;
792         rd.readx.in.mincnt = 0;
793         rd.readx.in.maxcnt = maxsize;
794         rd.readx.in.offset = 0;
795         rd.readx.in.remaining = 0;
796         rd.readx.in.read_for_execute = True;
797         rd.readx.out.data = buf;
798         status = smb_raw_read(cli->tree, &rd);
799         CHECK_STATUS(status, NT_STATUS_OK);
800         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
801         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
802         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
803
804         printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
805         rd.generic.level = RAW_READ_READX;
806         rd.readx.in.file.fnum = fnum;
807         rd.readx.in.mincnt = 0;
808         rd.readx.in.maxcnt = maxsize;
809         rd.readx.in.offset = 0;
810         rd.readx.in.remaining = 0;
811         rd.readx.in.read_for_execute = False;
812         rd.readx.out.data = buf;
813         status = smb_raw_read(cli->tree, &rd);
814         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
815
816         status = smbcli_close(cli->tree, fnum);
817         CHECK_STATUS(status, NT_STATUS_OK);
818
819         printf("open file with SEC_FILE_READ_DATA\n");
820         op.generic.level = RAW_OPEN_NTCREATEX;
821         op.ntcreatex.in.root_fid = 0;
822         op.ntcreatex.in.flags = 0;
823         op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
824         op.ntcreatex.in.create_options = 0;
825         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
826         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
827         op.ntcreatex.in.alloc_size = 0;
828         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
829         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
830         op.ntcreatex.in.security_flags = 0;
831         op.ntcreatex.in.fname = fname;
832         status = smb_raw_open(cli->tree, mem_ctx, &op);
833         CHECK_STATUS(status, NT_STATUS_OK);
834         fnum = op.ntcreatex.out.file.fnum;
835
836         printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
837         rd.generic.level = RAW_READ_READX;
838         rd.readx.in.file.fnum = fnum;
839         rd.readx.in.mincnt = 0;
840         rd.readx.in.maxcnt = maxsize;
841         rd.readx.in.offset = 0;
842         rd.readx.in.remaining = 0;
843         rd.readx.in.read_for_execute = True;
844         rd.readx.out.data = buf;
845         status = smb_raw_read(cli->tree, &rd);
846         CHECK_STATUS(status, NT_STATUS_OK);
847         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
848         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
849         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
850
851         printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
852         rd.generic.level = RAW_READ_READX;
853         rd.readx.in.file.fnum = fnum;
854         rd.readx.in.mincnt = 0;
855         rd.readx.in.maxcnt = maxsize;
856         rd.readx.in.offset = 0;
857         rd.readx.in.remaining = 0;
858         rd.readx.in.read_for_execute = False;
859         rd.readx.out.data = buf;
860         status = smb_raw_read(cli->tree, &rd);
861         CHECK_STATUS(status, NT_STATUS_OK);
862         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
863         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
864         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
865
866 done:
867         smbcli_close(cli->tree, fnum);
868         smbcli_deltree(cli->tree, BASEDIR);
869         return ret;
870 }
871
872
873 /* 
874    basic testing of read calls
875 */
876 BOOL torture_raw_read(struct torture_context *torture)
877 {
878         struct smbcli_state *cli;
879         BOOL ret = True;
880         TALLOC_CTX *mem_ctx;
881
882         if (!torture_open_connection(&cli, 0)) {
883                 return False;
884         }
885
886         mem_ctx = talloc_init("torture_raw_read");
887
888         ret &= test_read(cli, mem_ctx);
889         ret &= test_readx(cli, mem_ctx);
890         ret &= test_lockread(cli, mem_ctx);
891         ret &= test_readbraw(cli, mem_ctx);
892         ret &= test_read_for_execute(cli, mem_ctx);
893
894         torture_close_connection(cli);
895         talloc_free(mem_ctx);
896         return ret;
897 }