~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/torture/scanner.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 2 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, write to the Free Software
18
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
*/
20
 
 
21
 
#include "includes.h"
22
 
 
23
 
#define VERBOSE 0
24
 
#define OP_MIN 0
25
 
#define OP_MAX 20
26
 
 
27
 
/****************************************************************************
28
 
look for a partial hit
29
 
****************************************************************************/
30
 
static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
31
 
{
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)) {
37
 
                return;
38
 
        }
39
 
#if VERBOSE
40
 
        printf("possible %s hit op=%3d level=%5d status=%s\n",
41
 
               format, op, level, nt_errstr(status));
42
 
#endif
43
 
}
44
 
 
45
 
/****************************************************************************
46
 
check for existance of a trans2 call
47
 
****************************************************************************/
48
 
static NTSTATUS try_trans2(struct cli_state *cli, 
49
 
                         int op,
50
 
                         char *param, char *data,
51
 
                         int param_len, int data_len,
52
 
                         unsigned int *rparam_len, unsigned int *rdata_len)
53
 
{
54
 
        uint16 setup = op;
55
 
        char *rparam=NULL, *rdata=NULL;
56
 
 
57
 
        if (!cli_send_trans(cli, SMBtrans2, 
58
 
                            NULL,                           /* name */
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 */
63
 
                           )) {
64
 
                return cli_nt_error(cli);
65
 
        }
66
 
 
67
 
        cli_receive_trans(cli, SMBtrans2,
68
 
                           &rparam, rparam_len,
69
 
                           &rdata, rdata_len);
70
 
 
71
 
        SAFE_FREE(rdata);
72
 
        SAFE_FREE(rparam);
73
 
 
74
 
        return cli_nt_error(cli);
75
 
}
76
 
 
77
 
 
78
 
static NTSTATUS try_trans2_len(struct cli_state *cli, 
79
 
                             const char *format,
80
 
                             int op, int level,
81
 
                             char *param, char *data,
82
 
                             int param_len, int *data_len,
83
 
                             unsigned int *rparam_len, unsigned int *rdata_len)
84
 
{
85
 
        NTSTATUS ret=NT_STATUS_OK;
86
 
 
87
 
        ret = try_trans2(cli, op, param, data, param_len,
88
 
                         sizeof(pstring), rparam_len, rdata_len);
89
 
#if VERBOSE 
90
 
        printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
91
 
#endif
92
 
        if (!NT_STATUS_IS_OK(ret)) return ret;
93
 
 
94
 
        *data_len = 0;
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;
99
 
                *data_len += 2;
100
 
        }
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);
104
 
        } else {
105
 
                trans2_check_hit(format, op, level, ret);
106
 
        }
107
 
        return ret;
108
 
}
109
 
 
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)
115
 
{
116
 
        int data_len = 0;
117
 
        int param_len = 0;
118
 
        unsigned int rparam_len, rdata_len;
119
 
        pstring param, data;
120
 
        NTSTATUS status;
121
 
 
122
 
        memset(data, 0, sizeof(data));
123
 
        data_len = 4;
124
 
 
125
 
        /* try with a info level only */
126
 
        param_len = 2;
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;
131
 
 
132
 
        /* try with a file descriptor */
133
 
        param_len = 6;
134
 
        SSVAL(param, 0, fnum);
135
 
        SSVAL(param, 2, level);
136
 
        SSVAL(param, 4, 0);
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;
140
 
 
141
 
 
142
 
        /* try with a notify style */
143
 
        param_len = 6;
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;
150
 
 
151
 
        /* try with a file name */
152
 
        param_len = 6;
153
 
        SSVAL(param, 0, level);
154
 
        SSVAL(param, 2, 0);
155
 
        SSVAL(param, 4, 0);
156
 
        param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
157
 
 
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;
161
 
 
162
 
        /* try with a new file name */
163
 
        param_len = 6;
164
 
        SSVAL(param, 0, level);
165
 
        SSVAL(param, 2, 0);
166
 
        SSVAL(param, 4, 0);
167
 
        param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
168
 
 
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;
174
 
 
175
 
        /* try dfs style  */
176
 
        cli_mkdir(cli, "\\testdir");
177
 
        param_len = 2;
178
 
        SSVAL(param, 0, level);
179
 
        param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
180
 
 
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;
185
 
 
186
 
        return False;
187
 
}
188
 
 
189
 
 
190
 
BOOL torture_trans2_scan(int dummy)
191
 
{
192
 
        static struct cli_state *cli;
193
 
        int op, level;
194
 
        const char *fname = "\\scanner.dat";
195
 
        int fnum, dnum;
196
 
 
197
 
        printf("starting trans2 scan test\n");
198
 
 
199
 
        if (!torture_open_connection(&cli)) {
200
 
                return False;
201
 
        }
202
 
 
203
 
        fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, 
204
 
                         DENY_NONE);
205
 
        dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
206
 
 
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);
211
 
                }
212
 
 
213
 
                for (level = 0x100; level <= 0x130; level++) {
214
 
                        scan_trans2(cli, op, level, fnum, dnum, fname);
215
 
                }
216
 
 
217
 
                for (level = 1000; level < 1050; level++) {
218
 
                        scan_trans2(cli, op, level, fnum, dnum, fname);
219
 
                }
220
 
        }
221
 
 
222
 
        torture_close_connection(cli);
223
 
 
224
 
        printf("trans2 scan finished\n");
225
 
        return True;
226
 
}
227
 
 
228
 
 
229
 
 
230
 
 
231
 
/****************************************************************************
232
 
look for a partial hit
233
 
****************************************************************************/
234
 
static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
235
 
{
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)) {
241
 
                return;
242
 
        }
243
 
#if VERBOSE
244
 
                printf("possible %s hit op=%3d level=%5d status=%s\n",
245
 
                       format, op, level, nt_errstr(status));
246
 
#endif
247
 
}
248
 
 
249
 
/****************************************************************************
250
 
check for existance of a nttrans call
251
 
****************************************************************************/
252
 
static NTSTATUS try_nttrans(struct cli_state *cli, 
253
 
                         int op,
254
 
                         char *param, char *data,
255
 
                         int param_len, int data_len,
256
 
                         unsigned int *rparam_len, unsigned int *rdata_len)
257
 
{
258
 
        char *rparam=NULL, *rdata=NULL;
259
 
 
260
 
        if (!cli_send_nt_trans(cli, op, 
261
 
                               0,   
262
 
                               NULL, 0, 0,
263
 
                               param, param_len, 2,            /* param, length, max */
264
 
                               data, data_len, cli->max_xmit   /* data, length, max */
265
 
                           )) {
266
 
                return cli_nt_error(cli);
267
 
        }
268
 
 
269
 
        cli_receive_nt_trans(cli,
270
 
                             &rparam, rparam_len,
271
 
                             &rdata, rdata_len);
272
 
 
273
 
        SAFE_FREE(rdata);
274
 
        SAFE_FREE(rparam);
275
 
 
276
 
        return cli_nt_error(cli);
277
 
}
278
 
 
279
 
 
280
 
static NTSTATUS try_nttrans_len(struct cli_state *cli, 
281
 
                             const char *format,
282
 
                             int op, int level,
283
 
                             char *param, char *data,
284
 
                             int param_len, int *data_len,
285
 
                             unsigned int *rparam_len, unsigned int *rdata_len)
286
 
{
287
 
        NTSTATUS ret=NT_STATUS_OK;
288
 
 
289
 
        ret = try_nttrans(cli, op, param, data, param_len,
290
 
                         sizeof(pstring), rparam_len, rdata_len);
291
 
#if VERBOSE 
292
 
        printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
293
 
#endif
294
 
        if (!NT_STATUS_IS_OK(ret)) return ret;
295
 
 
296
 
        *data_len = 0;
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;
301
 
                *data_len += 2;
302
 
        }
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);
306
 
        } else {
307
 
                nttrans_check_hit(format, op, level, ret);
308
 
        }
309
 
        return ret;
310
 
}
311
 
 
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)
317
 
{
318
 
        int data_len = 0;
319
 
        int param_len = 0;
320
 
        unsigned int rparam_len, rdata_len;
321
 
        pstring param, data;
322
 
        NTSTATUS status;
323
 
 
324
 
        memset(data, 0, sizeof(data));
325
 
        data_len = 4;
326
 
 
327
 
        /* try with a info level only */
328
 
        param_len = 2;
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;
333
 
 
334
 
        /* try with a file descriptor */
335
 
        param_len = 6;
336
 
        SSVAL(param, 0, fnum);
337
 
        SSVAL(param, 2, level);
338
 
        SSVAL(param, 4, 0);
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;
342
 
 
343
 
 
344
 
        /* try with a notify style */
345
 
        param_len = 6;
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;
352
 
 
353
 
        /* try with a file name */
354
 
        param_len = 6;
355
 
        SSVAL(param, 0, level);
356
 
        SSVAL(param, 2, 0);
357
 
        SSVAL(param, 4, 0);
358
 
        param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
359
 
 
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;
363
 
 
364
 
        /* try with a new file name */
365
 
        param_len = 6;
366
 
        SSVAL(param, 0, level);
367
 
        SSVAL(param, 2, 0);
368
 
        SSVAL(param, 4, 0);
369
 
        param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
370
 
 
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;
376
 
 
377
 
        /* try dfs style  */
378
 
        cli_mkdir(cli, "\\testdir");
379
 
        param_len = 2;
380
 
        SSVAL(param, 0, level);
381
 
        param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
382
 
 
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;
387
 
 
388
 
        return False;
389
 
}
390
 
 
391
 
 
392
 
BOOL torture_nttrans_scan(int dummy)
393
 
{
394
 
        static struct cli_state *cli;
395
 
        int op, level;
396
 
        const char *fname = "\\scanner.dat";
397
 
        int fnum, dnum;
398
 
 
399
 
        printf("starting nttrans scan test\n");
400
 
 
401
 
        if (!torture_open_connection(&cli)) {
402
 
                return False;
403
 
        }
404
 
 
405
 
        fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, 
406
 
                         DENY_NONE);
407
 
        dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
408
 
 
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);
413
 
                }
414
 
 
415
 
                for (level = 0x100; level <= 0x130; level++) {
416
 
                        scan_nttrans(cli, op, level, fnum, dnum, fname);
417
 
                }
418
 
 
419
 
                for (level = 1000; level < 1050; level++) {
420
 
                        scan_nttrans(cli, op, level, fnum, dnum, fname);
421
 
                }
422
 
        }
423
 
 
424
 
        torture_close_connection(cli);
425
 
 
426
 
        printf("nttrans scan finished\n");
427
 
        return True;
428
 
}