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