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.
27
/****************************************************************************
28
look for a partial hit
29
****************************************************************************/
30
static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
32
if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
33
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
34
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
35
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
36
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
40
printf("possible %s hit op=%3d level=%5d status=%s\n",
41
format, op, level, nt_errstr(status));
45
/****************************************************************************
46
check for existance of a trans2 call
47
****************************************************************************/
48
static NTSTATUS try_trans2(struct cli_state *cli,
50
char *param, char *data,
51
int param_len, int data_len,
52
unsigned int *rparam_len, unsigned int *rdata_len)
55
char *rparam=NULL, *rdata=NULL;
57
if (!cli_send_trans(cli, SMBtrans2,
59
-1, 0, /* fid, flags */
60
&setup, 1, 0, /* setup, length, max */
61
param, param_len, 2, /* param, length, max */
62
data, data_len, cli->max_xmit /* data, length, max */
64
return cli_nt_error(cli);
67
cli_receive_trans(cli, SMBtrans2,
74
return cli_nt_error(cli);
78
static NTSTATUS try_trans2_len(struct cli_state *cli,
81
char *param, char *data,
82
int param_len, int *data_len,
83
unsigned int *rparam_len, unsigned int *rdata_len)
85
NTSTATUS ret=NT_STATUS_OK;
87
ret = try_trans2(cli, op, param, data, param_len,
88
sizeof(pstring), rparam_len, rdata_len);
90
printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
92
if (!NT_STATUS_IS_OK(ret)) return ret;
95
while (*data_len < sizeof(pstring)) {
96
ret = try_trans2(cli, op, param, data, param_len,
97
*data_len, rparam_len, rdata_len);
98
if (NT_STATUS_IS_OK(ret)) break;
101
if (NT_STATUS_IS_OK(ret)) {
102
printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
103
format, level, *data_len, *rparam_len, *rdata_len);
105
trans2_check_hit(format, op, level, ret);
110
/****************************************************************************
111
check for existance of a trans2 call
112
****************************************************************************/
113
static BOOL scan_trans2(struct cli_state *cli, int op, int level,
114
int fnum, int dnum, const char *fname)
118
unsigned int rparam_len, rdata_len;
122
memset(data, 0, sizeof(data));
125
/* try with a info level only */
127
SSVAL(param, 0, level);
128
status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len,
129
&rparam_len, &rdata_len);
130
if (NT_STATUS_IS_OK(status)) return True;
132
/* try with a file descriptor */
134
SSVAL(param, 0, fnum);
135
SSVAL(param, 2, level);
137
status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len,
138
&rparam_len, &rdata_len);
139
if (NT_STATUS_IS_OK(status)) return True;
142
/* try with a notify style */
144
SSVAL(param, 0, dnum);
145
SSVAL(param, 2, dnum);
146
SSVAL(param, 4, level);
147
status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len,
148
&rparam_len, &rdata_len);
149
if (NT_STATUS_IS_OK(status)) return True;
151
/* try with a file name */
153
SSVAL(param, 0, level);
156
param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
158
status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len,
159
&rparam_len, &rdata_len);
160
if (NT_STATUS_IS_OK(status)) return True;
162
/* try with a new file name */
164
SSVAL(param, 0, level);
167
param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
169
status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len,
170
&rparam_len, &rdata_len);
171
cli_unlink(cli, "\\newfile.dat");
172
cli_rmdir(cli, "\\newfile.dat");
173
if (NT_STATUS_IS_OK(status)) return True;
176
cli_mkdir(cli, "\\testdir");
178
SSVAL(param, 0, level);
179
param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
181
status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len,
182
&rparam_len, &rdata_len);
183
cli_rmdir(cli, "\\testdir");
184
if (NT_STATUS_IS_OK(status)) return True;
190
BOOL torture_trans2_scan(int dummy)
192
static struct cli_state *cli;
194
const char *fname = "\\scanner.dat";
197
printf("starting trans2 scan test\n");
199
if (!torture_open_connection(&cli)) {
203
fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
205
dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
207
for (op=OP_MIN; op<=OP_MAX; op++) {
208
printf("Scanning op=%d\n", op);
209
for (level = 0; level <= 50; level++) {
210
scan_trans2(cli, op, level, fnum, dnum, fname);
213
for (level = 0x100; level <= 0x130; level++) {
214
scan_trans2(cli, op, level, fnum, dnum, fname);
217
for (level = 1000; level < 1050; level++) {
218
scan_trans2(cli, op, level, fnum, dnum, fname);
222
torture_close_connection(cli);
224
printf("trans2 scan finished\n");
231
/****************************************************************************
232
look for a partial hit
233
****************************************************************************/
234
static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
236
if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
237
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
238
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
239
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
240
NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
244
printf("possible %s hit op=%3d level=%5d status=%s\n",
245
format, op, level, nt_errstr(status));
249
/****************************************************************************
250
check for existance of a nttrans call
251
****************************************************************************/
252
static NTSTATUS try_nttrans(struct cli_state *cli,
254
char *param, char *data,
255
int param_len, int data_len,
256
unsigned int *rparam_len, unsigned int *rdata_len)
258
char *rparam=NULL, *rdata=NULL;
260
if (!cli_send_nt_trans(cli, op,
263
param, param_len, 2, /* param, length, max */
264
data, data_len, cli->max_xmit /* data, length, max */
266
return cli_nt_error(cli);
269
cli_receive_nt_trans(cli,
276
return cli_nt_error(cli);
280
static NTSTATUS try_nttrans_len(struct cli_state *cli,
283
char *param, char *data,
284
int param_len, int *data_len,
285
unsigned int *rparam_len, unsigned int *rdata_len)
287
NTSTATUS ret=NT_STATUS_OK;
289
ret = try_nttrans(cli, op, param, data, param_len,
290
sizeof(pstring), rparam_len, rdata_len);
292
printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
294
if (!NT_STATUS_IS_OK(ret)) return ret;
297
while (*data_len < sizeof(pstring)) {
298
ret = try_nttrans(cli, op, param, data, param_len,
299
*data_len, rparam_len, rdata_len);
300
if (NT_STATUS_IS_OK(ret)) break;
303
if (NT_STATUS_IS_OK(ret)) {
304
printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
305
format, level, *data_len, *rparam_len, *rdata_len);
307
nttrans_check_hit(format, op, level, ret);
312
/****************************************************************************
313
check for existance of a nttrans call
314
****************************************************************************/
315
static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
316
int fnum, int dnum, const char *fname)
320
unsigned int rparam_len, rdata_len;
324
memset(data, 0, sizeof(data));
327
/* try with a info level only */
329
SSVAL(param, 0, level);
330
status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
331
&rparam_len, &rdata_len);
332
if (NT_STATUS_IS_OK(status)) return True;
334
/* try with a file descriptor */
336
SSVAL(param, 0, fnum);
337
SSVAL(param, 2, level);
339
status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
340
&rparam_len, &rdata_len);
341
if (NT_STATUS_IS_OK(status)) return True;
344
/* try with a notify style */
346
SSVAL(param, 0, dnum);
347
SSVAL(param, 2, dnum);
348
SSVAL(param, 4, level);
349
status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
350
&rparam_len, &rdata_len);
351
if (NT_STATUS_IS_OK(status)) return True;
353
/* try with a file name */
355
SSVAL(param, 0, level);
358
param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
360
status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
361
&rparam_len, &rdata_len);
362
if (NT_STATUS_IS_OK(status)) return True;
364
/* try with a new file name */
366
SSVAL(param, 0, level);
369
param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
371
status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
372
&rparam_len, &rdata_len);
373
cli_unlink(cli, "\\newfile.dat");
374
cli_rmdir(cli, "\\newfile.dat");
375
if (NT_STATUS_IS_OK(status)) return True;
378
cli_mkdir(cli, "\\testdir");
380
SSVAL(param, 0, level);
381
param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
383
status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
384
&rparam_len, &rdata_len);
385
cli_rmdir(cli, "\\testdir");
386
if (NT_STATUS_IS_OK(status)) return True;
392
BOOL torture_nttrans_scan(int dummy)
394
static struct cli_state *cli;
396
const char *fname = "\\scanner.dat";
399
printf("starting nttrans scan test\n");
401
if (!torture_open_connection(&cli)) {
405
fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
407
dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
409
for (op=OP_MIN; op<=OP_MAX; op++) {
410
printf("Scanning op=%d\n", op);
411
for (level = 0; level <= 50; level++) {
412
scan_nttrans(cli, op, level, fnum, dnum, fname);
415
for (level = 0x100; level <= 0x130; level++) {
416
scan_nttrans(cli, op, level, fnum, dnum, fname);
419
for (level = 1000; level < 1050; level++) {
420
scan_nttrans(cli, op, level, fnum, dnum, fname);
424
torture_close_connection(cli);
426
printf("nttrans scan finished\n");