2 Unix SMB/CIFS implementation.
3 SMB torture tester - scanning functions
4 Copyright (C) Andrew Tridgell 2001
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 /****************************************************************************
30 look for a partial hit
31 ****************************************************************************/
32 static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
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)) {
42 printf("possible %s hit op=%3d level=%5d status=%s\n",
43 format, op, level, nt_errstr(status));
47 /****************************************************************************
48 check for existance of a trans2 call
49 ****************************************************************************/
50 static NTSTATUS try_trans2(struct cli_state *cli,
52 char *param, char *data,
53 int param_len, int data_len,
54 int *rparam_len, int *rdata_len)
57 char *rparam=NULL, *rdata=NULL;
59 if (!cli_send_trans(cli, SMBtrans2,
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 */
66 return cli_nt_error(cli);
69 cli_receive_trans(cli, SMBtrans2,
76 return cli_nt_error(cli);
80 static NTSTATUS try_trans2_len(struct cli_state *cli,
83 char *param, char *data,
84 int param_len, int *data_len,
85 int *rparam_len, int *rdata_len)
87 NTSTATUS ret=NT_STATUS_OK;
89 ret = try_trans2(cli, op, param, data, param_len,
90 sizeof(pstring), rparam_len, rdata_len);
92 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
94 if (!NT_STATUS_IS_OK(ret)) return ret;
97 while (*data_len < sizeof(pstring)) {
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;
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);
107 trans2_check_hit(format, op, level, ret);
112 /****************************************************************************
113 check for existance of a trans2 call
114 ****************************************************************************/
115 static BOOL scan_trans2(struct cli_state *cli, int op, int level,
116 int fnum, int dnum, const char *fname)
120 int rparam_len, rdata_len;
124 memset(data, 0, sizeof(data));
127 /* try with a info level only */
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;
134 /* try with a file descriptor */
136 SSVAL(param, 0, fnum);
137 SSVAL(param, 2, level);
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;
144 /* try with a notify style */
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;
153 /* try with a file name */
155 SSVAL(param, 0, level);
158 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
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;
164 /* try with a new file name */
166 SSVAL(param, 0, level);
169 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
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;
178 cli_mkdir(cli, "\\testdir");
180 SSVAL(param, 0, level);
181 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
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;
192 BOOL torture_trans2_scan(int dummy)
194 static struct cli_state cli;
196 const char *fname = "\\scanner.dat";
199 printf("starting trans2 scan test\n");
201 if (!torture_open_connection(&cli)) {
205 fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC,
207 dnum = cli_open(&cli, "\\", O_RDONLY, DENY_NONE);
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);
215 for (level = 0x100; level <= 0x130; level++) {
216 scan_trans2(&cli, op, level, fnum, dnum, fname);
219 for (level = 1000; level < 1050; level++) {
220 scan_trans2(&cli, op, level, fnum, dnum, fname);
224 torture_close_connection(&cli);
226 printf("trans2 scan finished\n");
233 /****************************************************************************
234 look for a partial hit
235 ****************************************************************************/
236 static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
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)) {
246 printf("possible %s hit op=%3d level=%5d status=%s\n",
247 format, op, level, nt_errstr(status));
251 /****************************************************************************
252 check for existance of a nttrans call
253 ****************************************************************************/
254 static NTSTATUS try_nttrans(struct cli_state *cli,
256 char *param, char *data,
257 int param_len, int data_len,
258 int *rparam_len, int *rdata_len)
260 char *rparam=NULL, *rdata=NULL;
262 if (!cli_send_nt_trans(cli, op,
265 param, param_len, 2, /* param, length, max */
266 data, data_len, cli->max_xmit /* data, length, max */
268 return cli_nt_error(cli);
271 cli_receive_nt_trans(cli,
278 return cli_nt_error(cli);
282 static NTSTATUS try_nttrans_len(struct cli_state *cli,
285 char *param, char *data,
286 int param_len, int *data_len,
287 int *rparam_len, int *rdata_len)
289 NTSTATUS ret=NT_STATUS_OK;
291 ret = try_nttrans(cli, op, param, data, param_len,
292 sizeof(pstring), rparam_len, rdata_len);
294 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
296 if (!NT_STATUS_IS_OK(ret)) return ret;
299 while (*data_len < sizeof(pstring)) {
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;
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);
309 nttrans_check_hit(format, op, level, ret);
314 /****************************************************************************
315 check for existance of a nttrans call
316 ****************************************************************************/
317 static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
318 int fnum, int dnum, const char *fname)
322 int rparam_len, rdata_len;
326 memset(data, 0, sizeof(data));
329 /* try with a info level only */
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;
336 /* try with a file descriptor */
338 SSVAL(param, 0, fnum);
339 SSVAL(param, 2, level);
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;
346 /* try with a notify style */
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;
355 /* try with a file name */
357 SSVAL(param, 0, level);
360 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
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;
366 /* try with a new file name */
368 SSVAL(param, 0, level);
371 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
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;
380 cli_mkdir(cli, "\\testdir");
382 SSVAL(param, 0, level);
383 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
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;
394 BOOL torture_nttrans_scan(int dummy)
396 static struct cli_state cli;
398 const char *fname = "\\scanner.dat";
401 printf("starting nttrans scan test\n");
403 if (!torture_open_connection(&cli)) {
407 fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC,
409 dnum = cli_open(&cli, "\\", O_RDONLY, DENY_NONE);
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);
417 for (level = 0x100; level <= 0x130; level++) {
418 scan_nttrans(&cli, op, level, fnum, dnum, fname);
421 for (level = 1000; level < 1050; level++) {
422 scan_nttrans(&cli, op, level, fnum, dnum, fname);
426 torture_close_connection(&cli);
428 printf("nttrans scan finished\n");