2 Unix SMB/Netbios implementation.
4 SMB torture tester - scanning functions
5 Copyright (C) Andrew Tridgell 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 /****************************************************************************
31 look for a partial hit
32 ****************************************************************************/
33 static void trans2_check_hit(char *format, int op, int level, NTSTATUS status)
36 case NT_STATUS_INVALID_LEVEL:
37 case NT_STATUS_NOT_IMPLEMENTED:
38 case NT_STATUS_NOT_SUPPORTED:
39 case NT_STATUS_UNSUCCESSFUL:
40 case NT_STATUS_INVALID_INFO_CLASS:
44 printf("possible %s hit op=%3d level=%5d status=%s\n",
45 format, op, level, get_nt_error_msg(status));
50 /****************************************************************************
51 check for existance of a trans2 call
52 ****************************************************************************/
53 static uint32 try_trans2(struct cli_state *cli,
55 char *param, char *data,
56 int param_len, int data_len,
57 int *rparam_len, int *rdata_len)
60 char *rparam=NULL, *rdata=NULL;
62 if (!cli_send_trans(cli, SMBtrans2,
64 -1, 0, /* fid, flags */
65 &setup, 1, 0, /* setup, length, max */
66 param, param_len, 2, /* param, length, max */
67 data, data_len, cli->max_xmit /* data, length, max */
69 return cli_nt_error(cli);
72 cli_receive_trans(cli, SMBtrans2,
76 if (rdata) free(rdata);
77 if (rparam) free(rparam);
79 return cli_nt_error(cli);
83 static uint32 try_trans2_len(struct cli_state *cli,
86 char *param, char *data,
87 int param_len, int *data_len,
88 int *rparam_len, int *rdata_len)
92 ret = try_trans2(cli, op, param, data, param_len,
93 sizeof(pstring), rparam_len, rdata_len);
95 printf("op=%d level=%d ret=%s\n", op, level, get_nt_error_msg(ret));
97 if (ret != 0) return ret;
100 while (*data_len < sizeof(pstring)) {
101 ret = try_trans2(cli, op, param, data, param_len,
102 *data_len, rparam_len, rdata_len);
106 if (ret == NT_STATUS_OK) {
107 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
108 format, level, *data_len, *rparam_len, *rdata_len);
110 trans2_check_hit(format, op, level, ret);
115 /****************************************************************************
116 check for existance of a trans2 call
117 ****************************************************************************/
118 static BOOL scan_trans2(struct cli_state *cli, int op, int level,
119 int fnum, int dnum, char *fname)
123 int rparam_len, rdata_len;
127 memset(data, 0, sizeof(data));
130 /* try with a info level only */
132 SSVAL(param, 0, level);
133 status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len,
134 &rparam_len, &rdata_len);
135 if (status == 0) return True;
137 /* try with a file descriptor */
139 SSVAL(param, 0, fnum);
140 SSVAL(param, 2, level);
142 status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len,
143 &rparam_len, &rdata_len);
144 if (status == 0) return True;
147 /* try with a notify style */
149 SSVAL(param, 0, dnum);
150 SSVAL(param, 2, dnum);
151 SSVAL(param, 4, level);
152 status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len,
153 &rparam_len, &rdata_len);
154 if (status == 0) return True;
156 /* try with a file name */
158 SSVAL(param, 0, level);
161 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
163 status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len,
164 &rparam_len, &rdata_len);
165 if (status == 0) return True;
167 /* try with a new file name */
169 SSVAL(param, 0, level);
172 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
174 status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len,
175 &rparam_len, &rdata_len);
176 cli_unlink(cli, "\\newfile.dat");
177 cli_rmdir(cli, "\\newfile.dat");
178 if (status == 0) return True;
181 cli_mkdir(cli, "\\testdir");
183 SSVAL(param, 0, level);
184 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
186 status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len,
187 &rparam_len, &rdata_len);
188 cli_rmdir(cli, "\\testdir");
189 if (status == 0) return True;
195 BOOL torture_trans2_scan(int dummy)
197 static struct cli_state cli;
199 char *fname = "\\scanner.dat";
202 printf("starting trans2 scan test\n");
204 if (!torture_open_connection(&cli)) {
208 fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC,
210 dnum = cli_open(&cli, "\\", O_RDONLY, DENY_NONE);
212 for (op=OP_MIN; op<=OP_MAX; op++) {
213 printf("Scanning op=%d\n", op);
214 for (level = 0; level <= 50; level++) {
215 scan_trans2(&cli, op, level, fnum, dnum, fname);
218 for (level = 0x100; level <= 0x130; level++) {
219 scan_trans2(&cli, op, level, fnum, dnum, fname);
222 for (level = 1000; level < 1050; level++) {
223 scan_trans2(&cli, op, level, fnum, dnum, fname);
227 torture_close_connection(&cli);
229 printf("trans2 scan finished\n");
236 /****************************************************************************
237 look for a partial hit
238 ****************************************************************************/
239 static void nttrans_check_hit(char *format, int op, int level, NTSTATUS status)
242 case NT_STATUS_INVALID_LEVEL:
243 case NT_STATUS_NOT_IMPLEMENTED:
244 case NT_STATUS_NOT_SUPPORTED:
245 case NT_STATUS_UNSUCCESSFUL:
246 case NT_STATUS_INVALID_INFO_CLASS:
250 printf("possible %s hit op=%3d level=%5d status=%s\n",
251 format, op, level, get_nt_error_msg(status));
256 /****************************************************************************
257 check for existance of a nttrans call
258 ****************************************************************************/
259 static uint32 try_nttrans(struct cli_state *cli,
261 char *param, char *data,
262 int param_len, int data_len,
263 int *rparam_len, int *rdata_len)
265 char *rparam=NULL, *rdata=NULL;
267 if (!cli_send_nt_trans(cli, op,
270 param, param_len, 2, /* param, length, max */
271 data, data_len, cli->max_xmit /* data, length, max */
273 return cli_nt_error(cli);
276 cli_receive_nt_trans(cli,
280 if (rdata) free(rdata);
281 if (rparam) free(rparam);
283 return cli_nt_error(cli);
287 static uint32 try_nttrans_len(struct cli_state *cli,
290 char *param, char *data,
291 int param_len, int *data_len,
292 int *rparam_len, int *rdata_len)
296 ret = try_nttrans(cli, op, param, data, param_len,
297 sizeof(pstring), rparam_len, rdata_len);
299 printf("op=%d level=%d ret=%s\n", op, level, get_nt_error_msg(ret));
301 if (ret != 0) return ret;
304 while (*data_len < sizeof(pstring)) {
305 ret = try_nttrans(cli, op, param, data, param_len,
306 *data_len, rparam_len, rdata_len);
310 if (ret == NT_STATUS_OK) {
311 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
312 format, level, *data_len, *rparam_len, *rdata_len);
314 nttrans_check_hit(format, op, level, ret);
319 /****************************************************************************
320 check for existance of a nttrans call
321 ****************************************************************************/
322 static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
323 int fnum, int dnum, char *fname)
327 int rparam_len, rdata_len;
331 memset(data, 0, sizeof(data));
334 /* try with a info level only */
336 SSVAL(param, 0, level);
337 status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
338 &rparam_len, &rdata_len);
339 if (status == 0) return True;
341 /* try with a file descriptor */
343 SSVAL(param, 0, fnum);
344 SSVAL(param, 2, level);
346 status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
347 &rparam_len, &rdata_len);
348 if (status == 0) return True;
351 /* try with a notify style */
353 SSVAL(param, 0, dnum);
354 SSVAL(param, 2, dnum);
355 SSVAL(param, 4, level);
356 status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
357 &rparam_len, &rdata_len);
358 if (status == 0) return True;
360 /* try with a file name */
362 SSVAL(param, 0, level);
365 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
367 status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
368 &rparam_len, &rdata_len);
369 if (status == 0) return True;
371 /* try with a new file name */
373 SSVAL(param, 0, level);
376 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
378 status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
379 &rparam_len, &rdata_len);
380 cli_unlink(cli, "\\newfile.dat");
381 cli_rmdir(cli, "\\newfile.dat");
382 if (status == 0) return True;
385 cli_mkdir(cli, "\\testdir");
387 SSVAL(param, 0, level);
388 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
390 status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
391 &rparam_len, &rdata_len);
392 cli_rmdir(cli, "\\testdir");
393 if (status == 0) return True;
399 BOOL torture_nttrans_scan(int dummy)
401 static struct cli_state cli;
403 char *fname = "\\scanner.dat";
406 printf("starting nttrans scan test\n");
408 if (!torture_open_connection(&cli)) {
412 fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC,
414 dnum = cli_open(&cli, "\\", O_RDONLY, DENY_NONE);
416 for (op=OP_MIN; op<=OP_MAX; op++) {
417 printf("Scanning op=%d\n", op);
418 for (level = 0; level <= 50; level++) {
419 scan_nttrans(&cli, op, level, fnum, dnum, fname);
422 for (level = 0x100; level <= 0x130; level++) {
423 scan_nttrans(&cli, op, level, fnum, dnum, fname);
426 for (level = 1000; level < 1050; level++) {
427 scan_nttrans(&cli, op, level, fnum, dnum, fname);
431 torture_close_connection(&cli);
433 printf("nttrans scan finished\n");