~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/raw/read.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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