source: vendor/3.5.0/source3/torture/scanner.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 12.6 KB
Line 
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
22#define VERBOSE 0
23#define OP_MIN 0
24#define OP_MAX 20
25
26#define DATA_SIZE 1024
27#define PARAM_SIZE 1024
28
29/****************************************************************************
30look for a partial hit
31****************************************************************************/
32static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
33{
34 if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
35 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
36 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
37 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
38 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
39 return;
40 }
41#if VERBOSE
42 printf("possible %s hit op=%3d level=%5d status=%s\n",
43 format, op, level, nt_errstr(status));
44#endif
45}
46
47/****************************************************************************
48check for existance of a trans2 call
49****************************************************************************/
50static NTSTATUS try_trans2(struct cli_state *cli,
51 int op,
52 char *param, char *data,
53 int param_len, int data_len,
54 unsigned int *rparam_len, unsigned int *rdata_len)
55{
56 uint16 setup = op;
57 char *rparam=NULL, *rdata=NULL;
58
59 if (!cli_send_trans(cli, SMBtrans2,
60 NULL, /* name */
61 -1, 0, /* fid, flags */
62 &setup, 1, 0, /* setup, length, max */
63 param, param_len, 2, /* param, length, max */
64 data, data_len, cli->max_xmit /* data, length, max */
65 )) {
66 return cli_nt_error(cli);
67 }
68
69 cli_receive_trans(cli, SMBtrans2,
70 &rparam, rparam_len,
71 &rdata, rdata_len);
72
73 SAFE_FREE(rdata);
74 SAFE_FREE(rparam);
75
76 return cli_nt_error(cli);
77}
78
79
80static NTSTATUS try_trans2_len(struct cli_state *cli,
81 const char *format,
82 int op, int level,
83 char *param, char *data,
84 int param_len, int *data_len,
85 unsigned int *rparam_len, unsigned int *rdata_len)
86{
87 NTSTATUS ret=NT_STATUS_OK;
88
89 ret = try_trans2(cli, op, param, data, param_len,
90 DATA_SIZE, rparam_len, rdata_len);
91#if VERBOSE
92 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
93#endif
94 if (!NT_STATUS_IS_OK(ret)) return ret;
95
96 *data_len = 0;
97 while (*data_len < DATA_SIZE) {
98 ret = try_trans2(cli, op, param, data, param_len,
99 *data_len, rparam_len, rdata_len);
100 if (NT_STATUS_IS_OK(ret)) break;
101 *data_len += 2;
102 }
103 if (NT_STATUS_IS_OK(ret)) {
104 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
105 format, level, *data_len, *rparam_len, *rdata_len);
106 } else {
107 trans2_check_hit(format, op, level, ret);
108 }
109 return ret;
110}
111
112/****************************************************************************
113check for existance of a trans2 call
114****************************************************************************/
115static bool scan_trans2(struct cli_state *cli, int op, int level,
116 int fnum, int dnum, const char *fname)
117{
118 int data_len = 0;
119 int param_len = 0;
120 unsigned int rparam_len, rdata_len;
121 char param[PARAM_SIZE], data[DATA_SIZE];
122 NTSTATUS status;
123
124 memset(data, 0, sizeof(data));
125 data_len = 4;
126
127 /* try with a info level only */
128 param_len = 2;
129 SSVAL(param, 0, level);
130 status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len,
131 &rparam_len, &rdata_len);
132 if (NT_STATUS_IS_OK(status)) return True;
133
134 /* try with a file descriptor */
135 param_len = 6;
136 SSVAL(param, 0, fnum);
137 SSVAL(param, 2, level);
138 SSVAL(param, 4, 0);
139 status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len,
140 &rparam_len, &rdata_len);
141 if (NT_STATUS_IS_OK(status)) return True;
142
143
144 /* try with a notify style */
145 param_len = 6;
146 SSVAL(param, 0, dnum);
147 SSVAL(param, 2, dnum);
148 SSVAL(param, 4, level);
149 status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len,
150 &rparam_len, &rdata_len);
151 if (NT_STATUS_IS_OK(status)) return True;
152
153 /* try with a file name */
154 param_len = 6;
155 SSVAL(param, 0, level);
156 SSVAL(param, 2, 0);
157 SSVAL(param, 4, 0);
158 param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
159
160 status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len,
161 &rparam_len, &rdata_len);
162 if (NT_STATUS_IS_OK(status)) return True;
163
164 /* try with a new file name */
165 param_len = 6;
166 SSVAL(param, 0, level);
167 SSVAL(param, 2, 0);
168 SSVAL(param, 4, 0);
169 param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
170
171 status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len,
172 &rparam_len, &rdata_len);
173 cli_unlink(cli, "\\newfile.dat", aSYSTEM | aHIDDEN);
174 cli_rmdir(cli, "\\newfile.dat");
175 if (NT_STATUS_IS_OK(status)) return True;
176
177 /* try dfs style */
178 cli_mkdir(cli, "\\testdir");
179 param_len = 2;
180 SSVAL(param, 0, level);
181 param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
182
183 status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len,
184 &rparam_len, &rdata_len);
185 cli_rmdir(cli, "\\testdir");
186 if (NT_STATUS_IS_OK(status)) return True;
187
188 return False;
189}
190
191
192bool torture_trans2_scan(int dummy)
193{
194 static struct cli_state *cli;
195 int op, level;
196 const char *fname = "\\scanner.dat";
197 uint16_t fnum, dnum;
198
199 printf("starting trans2 scan test\n");
200
201 if (!torture_open_connection(&cli, 0)) {
202 return False;
203 }
204
205 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
206 DENY_NONE, &fnum))) {
207 printf("open of %s failed\n", fname);
208 return false;
209 }
210 if (!NT_STATUS_IS_OK(cli_open(cli, "\\", O_RDONLY, DENY_NONE, &dnum))) {
211 printf("open of \\ failed\n");
212 return false;
213 }
214
215 for (op=OP_MIN; op<=OP_MAX; op++) {
216 printf("Scanning op=%d\n", op);
217 for (level = 0; level <= 50; level++) {
218 scan_trans2(cli, op, level, fnum, dnum, fname);
219 }
220
221 for (level = 0x100; level <= 0x130; level++) {
222 scan_trans2(cli, op, level, fnum, dnum, fname);
223 }
224
225 for (level = 1000; level < 1050; level++) {
226 scan_trans2(cli, op, level, fnum, dnum, fname);
227 }
228 }
229
230 torture_close_connection(cli);
231
232 printf("trans2 scan finished\n");
233 return True;
234}
235
236
237
238
239/****************************************************************************
240look for a partial hit
241****************************************************************************/
242static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
243{
244 if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
245 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
246 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
247 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
248 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
249 return;
250 }
251#if VERBOSE
252 printf("possible %s hit op=%3d level=%5d status=%s\n",
253 format, op, level, nt_errstr(status));
254#endif
255}
256
257/****************************************************************************
258check for existance of a nttrans call
259****************************************************************************/
260static NTSTATUS try_nttrans(struct cli_state *cli,
261 int op,
262 char *param, char *data,
263 int param_len, int data_len,
264 unsigned int *rparam_len, unsigned int *rdata_len)
265{
266 char *rparam=NULL, *rdata=NULL;
267
268 if (!cli_send_nt_trans(cli, op,
269 0,
270 NULL, 0, 0,
271 param, param_len, 2, /* param, length, max */
272 data, data_len, cli->max_xmit /* data, length, max */
273 )) {
274 return cli_nt_error(cli);
275 }
276
277 cli_receive_nt_trans(cli,
278 &rparam, rparam_len,
279 &rdata, rdata_len);
280
281 SAFE_FREE(rdata);
282 SAFE_FREE(rparam);
283
284 return cli_nt_error(cli);
285}
286
287
288static NTSTATUS try_nttrans_len(struct cli_state *cli,
289 const char *format,
290 int op, int level,
291 char *param, char *data,
292 int param_len, int *data_len,
293 unsigned int *rparam_len, unsigned int *rdata_len)
294{
295 NTSTATUS ret=NT_STATUS_OK;
296
297 ret = try_nttrans(cli, op, param, data, param_len,
298 DATA_SIZE, rparam_len, rdata_len);
299#if VERBOSE
300 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
301#endif
302 if (!NT_STATUS_IS_OK(ret)) return ret;
303
304 *data_len = 0;
305 while (*data_len < DATA_SIZE) {
306 ret = try_nttrans(cli, op, param, data, param_len,
307 *data_len, rparam_len, rdata_len);
308 if (NT_STATUS_IS_OK(ret)) break;
309 *data_len += 2;
310 }
311 if (NT_STATUS_IS_OK(ret)) {
312 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
313 format, level, *data_len, *rparam_len, *rdata_len);
314 } else {
315 nttrans_check_hit(format, op, level, ret);
316 }
317 return ret;
318}
319
320/****************************************************************************
321check for existance of a nttrans call
322****************************************************************************/
323static bool scan_nttrans(struct cli_state *cli, int op, int level,
324 int fnum, int dnum, const char *fname)
325{
326 int data_len = 0;
327 int param_len = 0;
328 unsigned int rparam_len, rdata_len;
329 char param[PARAM_SIZE], data[DATA_SIZE];
330 NTSTATUS status;
331
332 memset(data, 0, sizeof(data));
333 data_len = 4;
334
335 /* try with a info level only */
336 param_len = 2;
337 SSVAL(param, 0, level);
338 status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
339 &rparam_len, &rdata_len);
340 if (NT_STATUS_IS_OK(status)) return True;
341
342 /* try with a file descriptor */
343 param_len = 6;
344 SSVAL(param, 0, fnum);
345 SSVAL(param, 2, level);
346 SSVAL(param, 4, 0);
347 status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
348 &rparam_len, &rdata_len);
349 if (NT_STATUS_IS_OK(status)) return True;
350
351
352 /* try with a notify style */
353 param_len = 6;
354 SSVAL(param, 0, dnum);
355 SSVAL(param, 2, dnum);
356 SSVAL(param, 4, level);
357 status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
358 &rparam_len, &rdata_len);
359 if (NT_STATUS_IS_OK(status)) return True;
360
361 /* try with a file name */
362 param_len = 6;
363 SSVAL(param, 0, level);
364 SSVAL(param, 2, 0);
365 SSVAL(param, 4, 0);
366 param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
367
368 status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
369 &rparam_len, &rdata_len);
370 if (NT_STATUS_IS_OK(status)) return True;
371
372 /* try with a new file name */
373 param_len = 6;
374 SSVAL(param, 0, level);
375 SSVAL(param, 2, 0);
376 SSVAL(param, 4, 0);
377 param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
378
379 status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
380 &rparam_len, &rdata_len);
381 cli_unlink(cli, "\\newfile.dat", aSYSTEM | aHIDDEN);
382 cli_rmdir(cli, "\\newfile.dat");
383 if (NT_STATUS_IS_OK(status)) return True;
384
385 /* try dfs style */
386 cli_mkdir(cli, "\\testdir");
387 param_len = 2;
388 SSVAL(param, 0, level);
389 param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
390
391 status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
392 &rparam_len, &rdata_len);
393 cli_rmdir(cli, "\\testdir");
394 if (NT_STATUS_IS_OK(status)) return True;
395
396 return False;
397}
398
399
400bool torture_nttrans_scan(int dummy)
401{
402 static struct cli_state *cli;
403 int op, level;
404 const char *fname = "\\scanner.dat";
405 uint16_t fnum, dnum;
406
407 printf("starting nttrans scan test\n");
408
409 if (!torture_open_connection(&cli, 0)) {
410 return False;
411 }
412
413 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
414 DENY_NONE, &fnum);
415 cli_open(cli, "\\", O_RDONLY, DENY_NONE, &dnum);
416
417 for (op=OP_MIN; op<=OP_MAX; op++) {
418 printf("Scanning op=%d\n", op);
419 for (level = 0; level <= 50; level++) {
420 scan_nttrans(cli, op, level, fnum, dnum, fname);
421 }
422
423 for (level = 0x100; level <= 0x130; level++) {
424 scan_nttrans(cli, op, level, fnum, dnum, fname);
425 }
426
427 for (level = 1000; level < 1050; level++) {
428 scan_nttrans(cli, op, level, fnum, dnum, fname);
429 }
430 }
431
432 torture_close_connection(cli);
433
434 printf("nttrans scan finished\n");
435 return True;
436}
Note: See TracBrowser for help on using the repository browser.