source: branches/samba-3.3.x/source/torture/scanner.c

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 12.4 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");
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 int fnum, dnum;
198
199 printf("starting trans2 scan test\n");
200
201 if (!torture_open_connection(&cli, 0)) {
202 return False;
203 }
204
205 fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
206 DENY_NONE);
207 dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
208
209 for (op=OP_MIN; op<=OP_MAX; op++) {
210 printf("Scanning op=%d\n", op);
211 for (level = 0; level <= 50; level++) {
212 scan_trans2(cli, op, level, fnum, dnum, fname);
213 }
214
215 for (level = 0x100; level <= 0x130; level++) {
216 scan_trans2(cli, op, level, fnum, dnum, fname);
217 }
218
219 for (level = 1000; level < 1050; level++) {
220 scan_trans2(cli, op, level, fnum, dnum, fname);
221 }
222 }
223
224 torture_close_connection(cli);
225
226 printf("trans2 scan finished\n");
227 return True;
228}
229
230
231
232
233/****************************************************************************
234look for a partial hit
235****************************************************************************/
236static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
237{
238 if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
239 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
240 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
241 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
242 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
243 return;
244 }
245#if VERBOSE
246 printf("possible %s hit op=%3d level=%5d status=%s\n",
247 format, op, level, nt_errstr(status));
248#endif
249}
250
251/****************************************************************************
252check for existance of a nttrans call
253****************************************************************************/
254static NTSTATUS try_nttrans(struct cli_state *cli,
255 int op,
256 char *param, char *data,
257 int param_len, int data_len,
258 unsigned int *rparam_len, unsigned int *rdata_len)
259{
260 char *rparam=NULL, *rdata=NULL;
261
262 if (!cli_send_nt_trans(cli, op,
263 0,
264 NULL, 0, 0,
265 param, param_len, 2, /* param, length, max */
266 data, data_len, cli->max_xmit /* data, length, max */
267 )) {
268 return cli_nt_error(cli);
269 }
270
271 cli_receive_nt_trans(cli,
272 &rparam, rparam_len,
273 &rdata, rdata_len);
274
275 SAFE_FREE(rdata);
276 SAFE_FREE(rparam);
277
278 return cli_nt_error(cli);
279}
280
281
282static NTSTATUS try_nttrans_len(struct cli_state *cli,
283 const char *format,
284 int op, int level,
285 char *param, char *data,
286 int param_len, int *data_len,
287 unsigned int *rparam_len, unsigned int *rdata_len)
288{
289 NTSTATUS ret=NT_STATUS_OK;
290
291 ret = try_nttrans(cli, op, param, data, param_len,
292 DATA_SIZE, rparam_len, rdata_len);
293#if VERBOSE
294 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
295#endif
296 if (!NT_STATUS_IS_OK(ret)) return ret;
297
298 *data_len = 0;
299 while (*data_len < DATA_SIZE) {
300 ret = try_nttrans(cli, op, param, data, param_len,
301 *data_len, rparam_len, rdata_len);
302 if (NT_STATUS_IS_OK(ret)) break;
303 *data_len += 2;
304 }
305 if (NT_STATUS_IS_OK(ret)) {
306 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
307 format, level, *data_len, *rparam_len, *rdata_len);
308 } else {
309 nttrans_check_hit(format, op, level, ret);
310 }
311 return ret;
312}
313
314/****************************************************************************
315check for existance of a nttrans call
316****************************************************************************/
317static bool scan_nttrans(struct cli_state *cli, int op, int level,
318 int fnum, int dnum, const char *fname)
319{
320 int data_len = 0;
321 int param_len = 0;
322 unsigned int rparam_len, rdata_len;
323 char param[PARAM_SIZE], data[DATA_SIZE];
324 NTSTATUS status;
325
326 memset(data, 0, sizeof(data));
327 data_len = 4;
328
329 /* try with a info level only */
330 param_len = 2;
331 SSVAL(param, 0, level);
332 status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
333 &rparam_len, &rdata_len);
334 if (NT_STATUS_IS_OK(status)) return True;
335
336 /* try with a file descriptor */
337 param_len = 6;
338 SSVAL(param, 0, fnum);
339 SSVAL(param, 2, level);
340 SSVAL(param, 4, 0);
341 status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
342 &rparam_len, &rdata_len);
343 if (NT_STATUS_IS_OK(status)) return True;
344
345
346 /* try with a notify style */
347 param_len = 6;
348 SSVAL(param, 0, dnum);
349 SSVAL(param, 2, dnum);
350 SSVAL(param, 4, level);
351 status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
352 &rparam_len, &rdata_len);
353 if (NT_STATUS_IS_OK(status)) return True;
354
355 /* try with a file name */
356 param_len = 6;
357 SSVAL(param, 0, level);
358 SSVAL(param, 2, 0);
359 SSVAL(param, 4, 0);
360 param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
361
362 status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
363 &rparam_len, &rdata_len);
364 if (NT_STATUS_IS_OK(status)) return True;
365
366 /* try with a new file name */
367 param_len = 6;
368 SSVAL(param, 0, level);
369 SSVAL(param, 2, 0);
370 SSVAL(param, 4, 0);
371 param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
372
373 status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
374 &rparam_len, &rdata_len);
375 cli_unlink(cli, "\\newfile.dat");
376 cli_rmdir(cli, "\\newfile.dat");
377 if (NT_STATUS_IS_OK(status)) return True;
378
379 /* try dfs style */
380 cli_mkdir(cli, "\\testdir");
381 param_len = 2;
382 SSVAL(param, 0, level);
383 param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
384
385 status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
386 &rparam_len, &rdata_len);
387 cli_rmdir(cli, "\\testdir");
388 if (NT_STATUS_IS_OK(status)) return True;
389
390 return False;
391}
392
393
394bool torture_nttrans_scan(int dummy)
395{
396 static struct cli_state *cli;
397 int op, level;
398 const char *fname = "\\scanner.dat";
399 int fnum, dnum;
400
401 printf("starting nttrans scan test\n");
402
403 if (!torture_open_connection(&cli, 0)) {
404 return False;
405 }
406
407 fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
408 DENY_NONE);
409 dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
410
411 for (op=OP_MIN; op<=OP_MAX; op++) {
412 printf("Scanning op=%d\n", op);
413 for (level = 0; level <= 50; level++) {
414 scan_nttrans(cli, op, level, fnum, dnum, fname);
415 }
416
417 for (level = 0x100; level <= 0x130; level++) {
418 scan_nttrans(cli, op, level, fnum, dnum, fname);
419 }
420
421 for (level = 1000; level < 1050; level++) {
422 scan_nttrans(cli, op, level, fnum, dnum, fname);
423 }
424 }
425
426 torture_close_connection(cli);
427
428 printf("nttrans scan finished\n");
429 return True;
430}
Note: See TracBrowser for help on using the repository browser.