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