1 | /*
|
---|
2 | Unix SMB/CIFS implementation.
|
---|
3 | SMB torture tester - scanning functions
|
---|
4 | Copyright (C) Andrew Tridgell 2001
|
---|
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/libcli.h"
|
---|
22 | #include "torture/util.h"
|
---|
23 | #include "libcli/raw/raw_proto.h"
|
---|
24 | #include "system/filesys.h"
|
---|
25 | #include "param/param.h"
|
---|
26 |
|
---|
27 | #define VERBOSE 0
|
---|
28 | #define OP_MIN 0
|
---|
29 | #define OP_MAX 100
|
---|
30 | #define PARAM_SIZE 1024
|
---|
31 |
|
---|
32 | /****************************************************************************
|
---|
33 | look for a partial hit
|
---|
34 | ****************************************************************************/
|
---|
35 | static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
|
---|
36 | {
|
---|
37 | if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL) ||
|
---|
38 | NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) ||
|
---|
39 | NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) ||
|
---|
40 | NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL) ||
|
---|
41 | NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
|
---|
42 | return;
|
---|
43 | }
|
---|
44 | #if VERBOSE
|
---|
45 | printf("possible %s hit op=%3d level=%5d status=%s\n",
|
---|
46 | format, op, level, nt_errstr(status));
|
---|
47 | #endif
|
---|
48 | }
|
---|
49 |
|
---|
50 | /****************************************************************************
|
---|
51 | check for existance of a trans2 call
|
---|
52 | ****************************************************************************/
|
---|
53 | static NTSTATUS try_trans2(struct smbcli_state *cli,
|
---|
54 | int op,
|
---|
55 | uint8_t *param, uint8_t *data,
|
---|
56 | int param_len, int data_len,
|
---|
57 | int *rparam_len, int *rdata_len)
|
---|
58 | {
|
---|
59 | NTSTATUS status;
|
---|
60 | struct smb_trans2 t2;
|
---|
61 | uint16_t setup = op;
|
---|
62 | TALLOC_CTX *mem_ctx;
|
---|
63 |
|
---|
64 | mem_ctx = talloc_init("try_trans2");
|
---|
65 |
|
---|
66 | t2.in.max_param = UINT16_MAX;
|
---|
67 | t2.in.max_data = UINT16_MAX;
|
---|
68 | t2.in.max_setup = 10;
|
---|
69 | t2.in.flags = 0;
|
---|
70 | t2.in.timeout = 0;
|
---|
71 | t2.in.setup_count = 1;
|
---|
72 | t2.in.setup = &setup;
|
---|
73 | t2.in.params.data = param;
|
---|
74 | t2.in.params.length = param_len;
|
---|
75 | t2.in.data.data = data;
|
---|
76 | t2.in.data.length = data_len;
|
---|
77 |
|
---|
78 | status = smb_raw_trans2(cli->tree, mem_ctx, &t2);
|
---|
79 |
|
---|
80 | *rparam_len = t2.out.params.length;
|
---|
81 | *rdata_len = t2.out.data.length;
|
---|
82 |
|
---|
83 | talloc_free(mem_ctx);
|
---|
84 |
|
---|
85 | return status;
|
---|
86 | }
|
---|
87 |
|
---|
88 |
|
---|
89 | static NTSTATUS try_trans2_len(struct smbcli_state *cli,
|
---|
90 | const char *format,
|
---|
91 | int op, int level,
|
---|
92 | uint8_t *param, uint8_t *data,
|
---|
93 | int param_len, int *data_len,
|
---|
94 | int *rparam_len, int *rdata_len)
|
---|
95 | {
|
---|
96 | NTSTATUS ret=NT_STATUS_OK;
|
---|
97 |
|
---|
98 | ret = try_trans2(cli, op, param, data, param_len,
|
---|
99 | PARAM_SIZE, rparam_len, rdata_len);
|
---|
100 | #if VERBOSE
|
---|
101 | printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
|
---|
102 | #endif
|
---|
103 | if (!NT_STATUS_IS_OK(ret)) return ret;
|
---|
104 |
|
---|
105 | *data_len = 0;
|
---|
106 | while (*data_len < PARAM_SIZE) {
|
---|
107 | ret = try_trans2(cli, op, param, data, param_len,
|
---|
108 | *data_len, rparam_len, rdata_len);
|
---|
109 | if (NT_STATUS_IS_OK(ret)) break;
|
---|
110 | *data_len += 2;
|
---|
111 | }
|
---|
112 | if (NT_STATUS_IS_OK(ret)) {
|
---|
113 | printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
|
---|
114 | format, level, *data_len, *rparam_len, *rdata_len);
|
---|
115 | } else {
|
---|
116 | trans2_check_hit(format, op, level, ret);
|
---|
117 | }
|
---|
118 | return ret;
|
---|
119 | }
|
---|
120 |
|
---|
121 |
|
---|
122 | /****************************************************************************
|
---|
123 | check whether a trans2 opnum exists at all
|
---|
124 | ****************************************************************************/
|
---|
125 | static bool trans2_op_exists(struct smbcli_state *cli, int op)
|
---|
126 | {
|
---|
127 | int data_len = PARAM_SIZE;
|
---|
128 | int param_len = PARAM_SIZE;
|
---|
129 | int rparam_len, rdata_len;
|
---|
130 | uint8_t *param, *data;
|
---|
131 | NTSTATUS status1, status2;
|
---|
132 | TALLOC_CTX *mem_ctx;
|
---|
133 |
|
---|
134 | mem_ctx = talloc_init("trans2_op_exists");
|
---|
135 |
|
---|
136 | /* try with a info level only */
|
---|
137 |
|
---|
138 | param = talloc_array(mem_ctx, uint8_t, param_len);
|
---|
139 | data = talloc_array(mem_ctx, uint8_t, data_len);
|
---|
140 |
|
---|
141 | memset(param, 0xFF, param_len);
|
---|
142 | memset(data, 0xFF, data_len);
|
---|
143 |
|
---|
144 | status1 = try_trans2(cli, 0xFFFF, param, data, param_len, data_len,
|
---|
145 | &rparam_len, &rdata_len);
|
---|
146 |
|
---|
147 | status2 = try_trans2(cli, op, param, data, param_len, data_len,
|
---|
148 | &rparam_len, &rdata_len);
|
---|
149 |
|
---|
150 | if (NT_STATUS_EQUAL(status1, status2)) {
|
---|
151 | talloc_free(mem_ctx);
|
---|
152 | return false;
|
---|
153 | }
|
---|
154 |
|
---|
155 | printf("Found op %d (status=%s)\n", op, nt_errstr(status2));
|
---|
156 |
|
---|
157 | talloc_free(mem_ctx);
|
---|
158 | return true;
|
---|
159 | }
|
---|
160 |
|
---|
161 | /****************************************************************************
|
---|
162 | check for existance of a trans2 call
|
---|
163 | ****************************************************************************/
|
---|
164 | static bool scan_trans2(
|
---|
165 | struct smbcli_state *cli, int op, int level,
|
---|
166 | int fnum, int dnum, int qfnum, const char *fname)
|
---|
167 | {
|
---|
168 | int data_len = 0;
|
---|
169 | int param_len = 0;
|
---|
170 | int rparam_len, rdata_len;
|
---|
171 | uint8_t *param, *data;
|
---|
172 | NTSTATUS status;
|
---|
173 | TALLOC_CTX *mem_ctx;
|
---|
174 |
|
---|
175 | mem_ctx = talloc_init("scan_trans2");
|
---|
176 |
|
---|
177 | data = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
|
---|
178 | param = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
|
---|
179 |
|
---|
180 | memset(data, 0, PARAM_SIZE);
|
---|
181 | data_len = 4;
|
---|
182 |
|
---|
183 | /* try with a info level only */
|
---|
184 | param_len = 2;
|
---|
185 | SSVAL(param, 0, level);
|
---|
186 | status = try_trans2_len(cli, "void", op, level, param, data, param_len,
|
---|
187 | &data_len, &rparam_len, &rdata_len);
|
---|
188 | if (NT_STATUS_IS_OK(status)) {
|
---|
189 | talloc_free(mem_ctx);
|
---|
190 | return true;
|
---|
191 | }
|
---|
192 |
|
---|
193 | /* try with a file descriptor */
|
---|
194 | param_len = 6;
|
---|
195 | SSVAL(param, 0, fnum);
|
---|
196 | SSVAL(param, 2, level);
|
---|
197 | SSVAL(param, 4, 0);
|
---|
198 | status = try_trans2_len(cli, "fnum", op, level, param, data, param_len,
|
---|
199 | &data_len, &rparam_len, &rdata_len);
|
---|
200 | if (NT_STATUS_IS_OK(status)) {
|
---|
201 | talloc_free(mem_ctx);
|
---|
202 | return true;
|
---|
203 | }
|
---|
204 |
|
---|
205 | /* try with a quota file descriptor */
|
---|
206 | param_len = 6;
|
---|
207 | SSVAL(param, 0, qfnum);
|
---|
208 | SSVAL(param, 2, level);
|
---|
209 | SSVAL(param, 4, 0);
|
---|
210 | status = try_trans2_len(cli, "qfnum", op, level, param, data, param_len,
|
---|
211 | &data_len, &rparam_len, &rdata_len);
|
---|
212 | if (NT_STATUS_IS_OK(status)) {
|
---|
213 | talloc_free(mem_ctx);
|
---|
214 | return true;
|
---|
215 | }
|
---|
216 |
|
---|
217 | /* try with a notify style */
|
---|
218 | param_len = 6;
|
---|
219 | SSVAL(param, 0, dnum);
|
---|
220 | SSVAL(param, 2, dnum);
|
---|
221 | SSVAL(param, 4, level);
|
---|
222 | status = try_trans2_len(cli, "notify", op, level, param, data,
|
---|
223 | param_len, &data_len, &rparam_len, &rdata_len);
|
---|
224 | if (NT_STATUS_IS_OK(status)) {
|
---|
225 | talloc_free(mem_ctx);
|
---|
226 | return true;
|
---|
227 | }
|
---|
228 |
|
---|
229 | /* try with a file name */
|
---|
230 | param_len = 6;
|
---|
231 | SSVAL(param, 0, level);
|
---|
232 | SSVAL(param, 2, 0);
|
---|
233 | SSVAL(param, 4, 0);
|
---|
234 | param_len += push_string(
|
---|
235 | ¶m[6], fname, PARAM_SIZE-7,
|
---|
236 | STR_TERMINATE|STR_UNICODE);
|
---|
237 |
|
---|
238 | status = try_trans2_len(cli, "fname", op, level, param, data, param_len,
|
---|
239 | &data_len, &rparam_len, &rdata_len);
|
---|
240 | if (NT_STATUS_IS_OK(status)) {
|
---|
241 | talloc_free(mem_ctx);
|
---|
242 | return true;
|
---|
243 | }
|
---|
244 |
|
---|
245 | /* try with a new file name */
|
---|
246 | param_len = 6;
|
---|
247 | SSVAL(param, 0, level);
|
---|
248 | SSVAL(param, 2, 0);
|
---|
249 | SSVAL(param, 4, 0);
|
---|
250 | param_len += push_string(
|
---|
251 | ¶m[6], "\\newfile.dat", PARAM_SIZE-7,
|
---|
252 | STR_TERMINATE|STR_UNICODE);
|
---|
253 |
|
---|
254 | status = try_trans2_len(cli, "newfile", op, level, param, data,
|
---|
255 | param_len, &data_len, &rparam_len, &rdata_len);
|
---|
256 | smbcli_unlink(cli->tree, "\\newfile.dat");
|
---|
257 | smbcli_rmdir(cli->tree, "\\newfile.dat");
|
---|
258 | if (NT_STATUS_IS_OK(status)) {
|
---|
259 | talloc_free(mem_ctx);
|
---|
260 | return true;
|
---|
261 | }
|
---|
262 |
|
---|
263 | /* try dfs style */
|
---|
264 | smbcli_mkdir(cli->tree, "\\testdir");
|
---|
265 | param_len = 2;
|
---|
266 | SSVAL(param, 0, level);
|
---|
267 | param_len += push_string(
|
---|
268 | ¶m[2], "\\testdir", PARAM_SIZE-3,
|
---|
269 | STR_TERMINATE|STR_UNICODE);
|
---|
270 |
|
---|
271 | status = try_trans2_len(cli, "dfs", op, level, param, data, param_len,
|
---|
272 | &data_len, &rparam_len, &rdata_len);
|
---|
273 | smbcli_rmdir(cli->tree, "\\testdir");
|
---|
274 | if (NT_STATUS_IS_OK(status)) {
|
---|
275 | talloc_free(mem_ctx);
|
---|
276 | return true;
|
---|
277 | }
|
---|
278 |
|
---|
279 | talloc_free(mem_ctx);
|
---|
280 | return false;
|
---|
281 | }
|
---|
282 |
|
---|
283 | bool torture_trans2_scan(struct torture_context *torture,
|
---|
284 | struct smbcli_state *cli)
|
---|
285 | {
|
---|
286 | int op, level;
|
---|
287 | const char *fname = "\\scanner.dat";
|
---|
288 | int fnum, dnum, qfnum;
|
---|
289 |
|
---|
290 | fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
|
---|
291 | if (fnum == -1) {
|
---|
292 | printf("file open failed - %s\n", smbcli_errstr(cli->tree));
|
---|
293 | }
|
---|
294 | dnum = smbcli_nt_create_full(cli->tree, "\\",
|
---|
295 | 0,
|
---|
296 | SEC_RIGHTS_FILE_READ,
|
---|
297 | FILE_ATTRIBUTE_NORMAL,
|
---|
298 | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE,
|
---|
299 | NTCREATEX_DISP_OPEN,
|
---|
300 | NTCREATEX_OPTIONS_DIRECTORY, 0);
|
---|
301 | if (dnum == -1) {
|
---|
302 | printf("directory open failed - %s\n", smbcli_errstr(cli->tree));
|
---|
303 | }
|
---|
304 | qfnum = smbcli_nt_create_full(cli->tree, "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION",
|
---|
305 | NTCREATEX_FLAGS_EXTENDED,
|
---|
306 | SEC_FLAG_MAXIMUM_ALLOWED,
|
---|
307 | 0,
|
---|
308 | NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
|
---|
309 | NTCREATEX_DISP_OPEN,
|
---|
310 | 0, 0);
|
---|
311 | if (qfnum == -1) {
|
---|
312 | printf("quota open failed - %s\n", smbcli_errstr(cli->tree));
|
---|
313 | }
|
---|
314 |
|
---|
315 | for (op=OP_MIN; op<=OP_MAX; op++) {
|
---|
316 |
|
---|
317 | if (!trans2_op_exists(cli, op)) {
|
---|
318 | continue;
|
---|
319 | }
|
---|
320 |
|
---|
321 | for (level = 0; level <= 50; level++) {
|
---|
322 | scan_trans2(cli, op, level, fnum, dnum, qfnum, fname);
|
---|
323 | }
|
---|
324 |
|
---|
325 | for (level = 0x100; level <= 0x130; level++) {
|
---|
326 | scan_trans2(cli, op, level, fnum, dnum, qfnum, fname);
|
---|
327 | }
|
---|
328 |
|
---|
329 | for (level = 1000; level < 1050; level++) {
|
---|
330 | scan_trans2(cli, op, level, fnum, dnum, qfnum, fname);
|
---|
331 | }
|
---|
332 | }
|
---|
333 |
|
---|
334 | return true;
|
---|
335 | }
|
---|
336 |
|
---|
337 |
|
---|
338 |
|
---|
339 |
|
---|
340 | /****************************************************************************
|
---|
341 | look for a partial hit
|
---|
342 | ****************************************************************************/
|
---|
343 | static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
|
---|
344 | {
|
---|
345 | if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL) ||
|
---|
346 | NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) ||
|
---|
347 | NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) ||
|
---|
348 | NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL) ||
|
---|
349 | NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
|
---|
350 | return;
|
---|
351 | }
|
---|
352 | #if VERBOSE
|
---|
353 | printf("possible %s hit op=%3d level=%5d status=%s\n",
|
---|
354 | format, op, level, nt_errstr(status));
|
---|
355 | #endif
|
---|
356 | }
|
---|
357 |
|
---|
358 | /****************************************************************************
|
---|
359 | check for existence of a nttrans call
|
---|
360 | ****************************************************************************/
|
---|
361 | static NTSTATUS try_nttrans(struct smbcli_state *cli,
|
---|
362 | int op,
|
---|
363 | uint8_t *param, uint8_t *data,
|
---|
364 | int param_len, int data_len,
|
---|
365 | int *rparam_len, int *rdata_len)
|
---|
366 | {
|
---|
367 | struct smb_nttrans parms;
|
---|
368 | DATA_BLOB ntparam_blob, ntdata_blob;
|
---|
369 | TALLOC_CTX *mem_ctx;
|
---|
370 | NTSTATUS status;
|
---|
371 |
|
---|
372 | mem_ctx = talloc_init("try_nttrans");
|
---|
373 |
|
---|
374 | ntparam_blob.length = param_len;
|
---|
375 | ntparam_blob.data = param;
|
---|
376 | ntdata_blob.length = data_len;
|
---|
377 | ntdata_blob.data = data;
|
---|
378 |
|
---|
379 | parms.in.max_param = UINT32_MAX;
|
---|
380 | parms.in.max_data = UINT32_MAX;
|
---|
381 | parms.in.max_setup = 0;
|
---|
382 | parms.in.setup_count = 0;
|
---|
383 | parms.in.function = op;
|
---|
384 | parms.in.params = ntparam_blob;
|
---|
385 | parms.in.data = ntdata_blob;
|
---|
386 |
|
---|
387 | status = smb_raw_nttrans(cli->tree, mem_ctx, &parms);
|
---|
388 |
|
---|
389 | if (NT_STATUS_IS_ERR(status)) {
|
---|
390 | DEBUG(1,("Failed to send NT_TRANS\n"));
|
---|
391 | talloc_free(mem_ctx);
|
---|
392 | return status;
|
---|
393 | }
|
---|
394 | *rparam_len = parms.out.params.length;
|
---|
395 | *rdata_len = parms.out.data.length;
|
---|
396 |
|
---|
397 | talloc_free(mem_ctx);
|
---|
398 |
|
---|
399 | return status;
|
---|
400 | }
|
---|
401 |
|
---|
402 |
|
---|
403 | static NTSTATUS try_nttrans_len(struct smbcli_state *cli,
|
---|
404 | const char *format,
|
---|
405 | int op, int level,
|
---|
406 | uint8_t *param, uint8_t *data,
|
---|
407 | int param_len, int *data_len,
|
---|
408 | int *rparam_len, int *rdata_len)
|
---|
409 | {
|
---|
410 | NTSTATUS ret=NT_STATUS_OK;
|
---|
411 |
|
---|
412 | ret = try_nttrans(cli, op, param, data, param_len,
|
---|
413 | PARAM_SIZE, rparam_len, rdata_len);
|
---|
414 | #if VERBOSE
|
---|
415 | printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
|
---|
416 | #endif
|
---|
417 | if (!NT_STATUS_IS_OK(ret)) return ret;
|
---|
418 |
|
---|
419 | *data_len = 0;
|
---|
420 | while (*data_len < PARAM_SIZE) {
|
---|
421 | ret = try_nttrans(cli, op, param, data, param_len,
|
---|
422 | *data_len, rparam_len, rdata_len);
|
---|
423 | if (NT_STATUS_IS_OK(ret)) break;
|
---|
424 | *data_len += 2;
|
---|
425 | }
|
---|
426 | if (NT_STATUS_IS_OK(ret)) {
|
---|
427 | printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
|
---|
428 | format, level, *data_len, *rparam_len, *rdata_len);
|
---|
429 | } else {
|
---|
430 | nttrans_check_hit(format, op, level, ret);
|
---|
431 | }
|
---|
432 | return ret;
|
---|
433 | }
|
---|
434 |
|
---|
435 | /****************************************************************************
|
---|
436 | check for existance of a nttrans call
|
---|
437 | ****************************************************************************/
|
---|
438 | static bool scan_nttrans(struct smbcli_state *cli, int op, int level,
|
---|
439 | int fnum, int dnum, const char *fname)
|
---|
440 | {
|
---|
441 | int data_len = 0;
|
---|
442 | int param_len = 0;
|
---|
443 | int rparam_len, rdata_len;
|
---|
444 | uint8_t *param, *data;
|
---|
445 | NTSTATUS status;
|
---|
446 | TALLOC_CTX *mem_ctx;
|
---|
447 |
|
---|
448 | mem_ctx = talloc_init("scan_nttrans");
|
---|
449 |
|
---|
450 | param = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
|
---|
451 | data = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
|
---|
452 | memset(data, 0, PARAM_SIZE);
|
---|
453 | data_len = 4;
|
---|
454 |
|
---|
455 | /* try with a info level only */
|
---|
456 | param_len = 2;
|
---|
457 | SSVAL(param, 0, level);
|
---|
458 | status = try_nttrans_len(cli, "void", op, level, param, data, param_len,
|
---|
459 | &data_len, &rparam_len, &rdata_len);
|
---|
460 | if (NT_STATUS_IS_OK(status)) {
|
---|
461 | talloc_free(mem_ctx);
|
---|
462 | return true;
|
---|
463 | }
|
---|
464 |
|
---|
465 | /* try with a file descriptor */
|
---|
466 | param_len = 6;
|
---|
467 | SSVAL(param, 0, fnum);
|
---|
468 | SSVAL(param, 2, level);
|
---|
469 | SSVAL(param, 4, 0);
|
---|
470 | status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len,
|
---|
471 | &data_len, &rparam_len, &rdata_len);
|
---|
472 | if (NT_STATUS_IS_OK(status)) {
|
---|
473 | talloc_free(mem_ctx);
|
---|
474 | return true;
|
---|
475 | }
|
---|
476 |
|
---|
477 | /* try with a notify style */
|
---|
478 | param_len = 6;
|
---|
479 | SSVAL(param, 0, dnum);
|
---|
480 | SSVAL(param, 2, dnum);
|
---|
481 | SSVAL(param, 4, level);
|
---|
482 | status = try_nttrans_len(cli, "notify", op, level, param, data,
|
---|
483 | param_len, &data_len, &rparam_len, &rdata_len);
|
---|
484 | if (NT_STATUS_IS_OK(status)) {
|
---|
485 | talloc_free(mem_ctx);
|
---|
486 | return true;
|
---|
487 | }
|
---|
488 |
|
---|
489 | /* try with a file name */
|
---|
490 | param_len = 6;
|
---|
491 | SSVAL(param, 0, level);
|
---|
492 | SSVAL(param, 2, 0);
|
---|
493 | SSVAL(param, 4, 0);
|
---|
494 | param_len += push_string(
|
---|
495 | ¶m[6], fname, PARAM_SIZE,
|
---|
496 | STR_TERMINATE | STR_UNICODE);
|
---|
497 |
|
---|
498 | status = try_nttrans_len(cli, "fname", op, level, param, data,
|
---|
499 | param_len, &data_len, &rparam_len, &rdata_len);
|
---|
500 | if (NT_STATUS_IS_OK(status)) {
|
---|
501 | talloc_free(mem_ctx);
|
---|
502 | return true;
|
---|
503 | }
|
---|
504 |
|
---|
505 | /* try with a new file name */
|
---|
506 | param_len = 6;
|
---|
507 | SSVAL(param, 0, level);
|
---|
508 | SSVAL(param, 2, 0);
|
---|
509 | SSVAL(param, 4, 0);
|
---|
510 | param_len += push_string(
|
---|
511 | ¶m[6], "\\newfile.dat", PARAM_SIZE,
|
---|
512 | STR_TERMINATE | STR_UNICODE);
|
---|
513 |
|
---|
514 | status = try_nttrans_len(cli, "newfile", op, level, param, data,
|
---|
515 | param_len, &data_len, &rparam_len, &rdata_len);
|
---|
516 | smbcli_unlink(cli->tree, "\\newfile.dat");
|
---|
517 | smbcli_rmdir(cli->tree, "\\newfile.dat");
|
---|
518 | if (NT_STATUS_IS_OK(status)) {
|
---|
519 | talloc_free(mem_ctx);
|
---|
520 | return true;
|
---|
521 | }
|
---|
522 |
|
---|
523 | /* try dfs style */
|
---|
524 | smbcli_mkdir(cli->tree, "\\testdir");
|
---|
525 | param_len = 2;
|
---|
526 | SSVAL(param, 0, level);
|
---|
527 | param_len += push_string(¶m[2], "\\testdir", PARAM_SIZE,
|
---|
528 | STR_TERMINATE | STR_UNICODE);
|
---|
529 |
|
---|
530 | status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len,
|
---|
531 | &data_len, &rparam_len, &rdata_len);
|
---|
532 | smbcli_rmdir(cli->tree, "\\testdir");
|
---|
533 | if (NT_STATUS_IS_OK(status)) {
|
---|
534 | talloc_free(mem_ctx);
|
---|
535 | return true;
|
---|
536 | }
|
---|
537 |
|
---|
538 | talloc_free(mem_ctx);
|
---|
539 | return false;
|
---|
540 | }
|
---|
541 |
|
---|
542 |
|
---|
543 | bool torture_nttrans_scan(struct torture_context *torture,
|
---|
544 | struct smbcli_state *cli)
|
---|
545 | {
|
---|
546 | int op, level;
|
---|
547 | const char *fname = "\\scanner.dat";
|
---|
548 | int fnum, dnum;
|
---|
549 |
|
---|
550 | fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
|
---|
551 | DENY_NONE);
|
---|
552 | dnum = smbcli_open(cli->tree, "\\", O_RDONLY, DENY_NONE);
|
---|
553 |
|
---|
554 | for (op=OP_MIN; op<=OP_MAX; op++) {
|
---|
555 | printf("Scanning op=%d\n", op);
|
---|
556 | for (level = 0; level <= 50; level++) {
|
---|
557 | scan_nttrans(cli, op, level, fnum, dnum, fname);
|
---|
558 | }
|
---|
559 |
|
---|
560 | for (level = 0x100; level <= 0x130; level++) {
|
---|
561 | scan_nttrans(cli, op, level, fnum, dnum, fname);
|
---|
562 | }
|
---|
563 |
|
---|
564 | for (level = 1000; level < 1050; level++) {
|
---|
565 | scan_nttrans(cli, op, level, fnum, dnum, fname);
|
---|
566 | }
|
---|
567 | }
|
---|
568 |
|
---|
569 | printf("nttrans scan finished\n");
|
---|
570 | return true;
|
---|
571 | }
|
---|
572 |
|
---|
573 |
|
---|
574 | /* scan for valid base SMB requests */
|
---|
575 | bool torture_smb_scan(struct torture_context *torture)
|
---|
576 | {
|
---|
577 | static struct smbcli_state *cli;
|
---|
578 | int op;
|
---|
579 | struct smbcli_request *req;
|
---|
580 | NTSTATUS status;
|
---|
581 |
|
---|
582 | for (op=0x0;op<=0xFF;op++) {
|
---|
583 | if (op == SMBreadbraw) continue;
|
---|
584 |
|
---|
585 | if (!torture_open_connection(&cli, torture, 0)) {
|
---|
586 | return false;
|
---|
587 | }
|
---|
588 |
|
---|
589 | req = smbcli_request_setup(cli->tree, op, 0, 0);
|
---|
590 |
|
---|
591 | if (!smbcli_request_send(req)) {
|
---|
592 | smbcli_request_destroy(req);
|
---|
593 | break;
|
---|
594 | }
|
---|
595 |
|
---|
596 | usleep(10000);
|
---|
597 | smbcli_transport_process(cli->transport);
|
---|
598 | if (req->state > SMBCLI_REQUEST_RECV) {
|
---|
599 | status = smbcli_request_simple_recv(req);
|
---|
600 | printf("op=0x%x status=%s\n", op, nt_errstr(status));
|
---|
601 | torture_close_connection(cli);
|
---|
602 | continue;
|
---|
603 | }
|
---|
604 |
|
---|
605 | sleep(1);
|
---|
606 | smbcli_transport_process(cli->transport);
|
---|
607 | if (req->state > SMBCLI_REQUEST_RECV) {
|
---|
608 | status = smbcli_request_simple_recv(req);
|
---|
609 | printf("op=0x%x status=%s\n", op, nt_errstr(status));
|
---|
610 | } else {
|
---|
611 | printf("op=0x%x no reply\n", op);
|
---|
612 | smbcli_request_destroy(req);
|
---|
613 | continue; /* don't attempt close! */
|
---|
614 | }
|
---|
615 |
|
---|
616 | torture_close_connection(cli);
|
---|
617 | }
|
---|
618 |
|
---|
619 |
|
---|
620 | printf("smb scan finished\n");
|
---|
621 | return true;
|
---|
622 | }
|
---|