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 int *rparam_len
, 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 int *rparam_len
, 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 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 int *rparam_len
, 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 int *rparam_len
, 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 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");