2 Unix SMB/CIFS implementation.
3 SMB trans2 alias scanner
4 Copyright (C) Andrew Tridgell 2003
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 3 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, see <http://www.gnu.org/licenses/>.
21 #include "../lib/util/dlinklist.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/raw/raw_proto.h"
24 #include "torture/torture.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
28 int create_complex_file(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
, const char *fname
);
31 struct trans2_blobs
*next
, *prev
;
33 DATA_BLOB params
, data
;
36 /* look for aliases for a query */
37 static bool gen_aliases(struct torture_context
*tctx
,
38 struct smbcli_state
*cli
, struct smb_trans2
*t2
,
42 struct trans2_blobs
*alias_blobs
= NULL
;
43 struct trans2_blobs
*t2b
, *t2b2
;
44 int count
=0, alias_count
=0;
46 for (level
=0;level
<2000;level
++) {
49 SSVAL(t2
->in
.params
.data
, level_offset
, level
);
51 status
= smb_raw_trans2(cli
->tree
, tctx
, t2
);
52 if (!NT_STATUS_IS_OK(status
)) continue;
54 t2b
= talloc(tctx
, struct trans2_blobs
);
56 t2b
->params
= t2
->out
.params
;
57 t2b
->data
= t2
->out
.data
;
58 DLIST_ADD(alias_blobs
, t2b
);
60 "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n",
62 (int)t2b
->data
.length
, (int)t2b
->data
.length
);
66 torture_comment(tctx
, "Found %d levels with success status\n", count
);
68 for (t2b
=alias_blobs
; t2b
; t2b
=t2b
->next
) {
69 for (t2b2
=alias_blobs
; t2b2
; t2b2
=t2b2
->next
) {
70 if (t2b
->level
>= t2b2
->level
) continue;
71 if (data_blob_cmp(&t2b
->params
, &t2b2
->params
) == 0 &&
72 data_blob_cmp(&t2b
->data
, &t2b2
->data
) == 0) {
74 "\tLevel %u (0x%x) and level %u (0x%x) are possible aliases\n",
75 t2b
->level
, t2b
->level
, t2b2
->level
, t2b2
->level
);
81 torture_comment(tctx
, "Found %d aliased levels\n", alias_count
);
86 /* look for qfsinfo aliases */
87 static bool qfsinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
90 uint16_t setup
= TRANSACT2_QFSINFO
;
93 t2
.in
.max_data
= UINT16_MAX
;
97 t2
.in
.setup_count
= 1;
99 t2
.in
.params
= data_blob_talloc_zero(tctx
, 2);
100 t2
.in
.data
= data_blob(NULL
, 0);
103 return gen_aliases(tctx
, cli
, &t2
, 0);
106 /* look for qfileinfo aliases */
107 static bool qfileinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
109 struct smb_trans2 t2
;
110 uint16_t setup
= TRANSACT2_QFILEINFO
;
111 const char *fname
= "\\qfileinfo_aliases.txt";
115 t2
.in
.max_data
= UINT16_MAX
;
119 t2
.in
.setup_count
= 1;
120 t2
.in
.setup
= &setup
;
121 t2
.in
.params
= data_blob_talloc_zero(tctx
, 4);
122 t2
.in
.data
= data_blob(NULL
, 0);
125 smbcli_unlink(cli
->tree
, fname
);
126 fnum
= create_complex_file(cli
, cli
, fname
);
127 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
128 "open of %s failed (%s)", fname
,
129 smbcli_errstr(cli
->tree
)));
131 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
133 SSVAL(t2
.in
.params
.data
, 0, fnum
);
135 if (!gen_aliases(tctx
, cli
, &t2
, 2))
138 smbcli_close(cli
->tree
, fnum
);
139 smbcli_unlink(cli
->tree
, fname
);
145 /* look for qpathinfo aliases */
146 static bool qpathinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
148 struct smb_trans2 t2
;
149 uint16_t setup
= TRANSACT2_QPATHINFO
;
150 const char *fname
= "\\qpathinfo_aliases.txt";
154 t2
.in
.max_data
= UINT16_MAX
;
158 t2
.in
.setup_count
= 1;
159 t2
.in
.setup
= &setup
;
160 t2
.in
.params
= data_blob_talloc_zero(tctx
, 6);
161 t2
.in
.data
= data_blob(NULL
, 0);
164 smbcli_unlink(cli
->tree
, fname
);
165 fnum
= create_complex_file(cli
, cli
, fname
);
166 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
167 "open of %s failed (%s)", fname
,
168 smbcli_errstr(cli
->tree
)));
170 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
171 smbcli_close(cli
->tree
, fnum
);
173 SIVAL(t2
.in
.params
.data
, 2, 0);
175 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
176 fname
, STR_TERMINATE
);
178 if (!gen_aliases(tctx
, cli
, &t2
, 0))
181 smbcli_unlink(cli
->tree
, fname
);
187 /* look for trans2 findfirst aliases */
188 static bool findfirst_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
190 struct smb_trans2 t2
;
191 uint16_t setup
= TRANSACT2_FINDFIRST
;
192 const char *fname
= "\\findfirst_aliases.txt";
195 t2
.in
.max_param
= 16;
196 t2
.in
.max_data
= UINT16_MAX
;
200 t2
.in
.setup_count
= 1;
201 t2
.in
.setup
= &setup
;
202 t2
.in
.params
= data_blob_talloc_zero(tctx
, 12);
203 t2
.in
.data
= data_blob(NULL
, 0);
206 smbcli_unlink(cli
->tree
, fname
);
207 fnum
= create_complex_file(cli
, cli
, fname
);
208 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
209 "open of %s failed (%s)", fname
,
210 smbcli_errstr(cli
->tree
)));
212 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
213 smbcli_close(cli
->tree
, fnum
);
215 SSVAL(t2
.in
.params
.data
, 0, 0);
216 SSVAL(t2
.in
.params
.data
, 2, 1);
217 SSVAL(t2
.in
.params
.data
, 4, FLAG_TRANS2_FIND_CLOSE
);
218 SSVAL(t2
.in
.params
.data
, 6, 0);
219 SIVAL(t2
.in
.params
.data
, 8, 0);
221 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
222 fname
, STR_TERMINATE
);
224 if (!gen_aliases(tctx
, cli
, &t2
, 6))
227 smbcli_unlink(cli
->tree
, fname
);
234 /* look for aliases for a set function */
235 static bool gen_set_aliases(struct torture_context
*tctx
,
236 struct smbcli_state
*cli
,
237 struct smb_trans2
*t2
, int level_offset
)
240 struct trans2_blobs
*alias_blobs
= NULL
;
241 struct trans2_blobs
*t2b
;
244 for (level
=1;level
<1100;level
++) {
245 NTSTATUS status
, status1
;
246 SSVAL(t2
->in
.params
.data
, level_offset
, level
);
248 status1
= NT_STATUS_OK
;
250 for (dsize
=2; dsize
<1024; dsize
+= 2) {
251 data_blob_free(&t2
->in
.data
);
252 t2
->in
.data
= data_blob(NULL
, dsize
);
253 data_blob_clear(&t2
->in
.data
);
254 status
= smb_raw_trans2(cli
->tree
, tctx
, t2
);
255 /* some error codes mean that this whole level doesn't exist */
256 if (NT_STATUS_EQUAL(NT_STATUS_INVALID_LEVEL
, status
) ||
257 NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
) ||
258 NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED
, status
)) {
261 if (NT_STATUS_IS_OK(status
)) break;
263 /* invalid parameter means that the level exists at this
264 size, but the contents are wrong (not surprising with
266 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) break;
268 /* this is the usual code for 'wrong size' */
269 if (NT_STATUS_EQUAL(status
, NT_STATUS_INFO_LENGTH_MISMATCH
)) {
273 if (!NT_STATUS_EQUAL(status
, status1
)) {
274 torture_comment(tctx
, "level=%d size=%d %s\n", level
, dsize
, nt_errstr(status
));
279 if (!NT_STATUS_IS_OK(status
) &&
280 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) continue;
282 t2b
= talloc(tctx
, struct trans2_blobs
);
284 t2b
->params
= t2
->out
.params
;
285 t2b
->data
= t2
->out
.data
;
286 DLIST_ADD(alias_blobs
, t2b
);
287 torture_comment(tctx
,
288 "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n",
290 (int)t2
->in
.data
.length
, (int)t2
->in
.data
.length
);
294 torture_comment(tctx
, "Found %d valid levels\n", count
);
301 /* look for setfileinfo aliases */
302 static bool setfileinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
304 struct smb_trans2 t2
;
305 uint16_t setup
= TRANSACT2_SETFILEINFO
;
306 const char *fname
= "\\setfileinfo_aliases.txt";
314 t2
.in
.setup_count
= 1;
315 t2
.in
.setup
= &setup
;
316 t2
.in
.params
= data_blob_talloc_zero(tctx
, 6);
317 t2
.in
.data
= data_blob(NULL
, 0);
320 smbcli_unlink(cli
->tree
, fname
);
321 fnum
= create_complex_file(cli
, cli
, fname
);
322 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
323 "open of %s failed (%s)", fname
,
324 smbcli_errstr(cli
->tree
)));
326 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
328 SSVAL(t2
.in
.params
.data
, 0, fnum
);
329 SSVAL(t2
.in
.params
.data
, 4, 0);
331 gen_set_aliases(tctx
, cli
, &t2
, 2);
333 smbcli_close(cli
->tree
, fnum
);
334 smbcli_unlink(cli
->tree
, fname
);
339 /* look for setpathinfo aliases */
340 static bool setpathinfo_aliases(struct torture_context
*tctx
,
341 struct smbcli_state
*cli
)
343 struct smb_trans2 t2
;
344 uint16_t setup
= TRANSACT2_SETPATHINFO
;
345 const char *fname
= "\\setpathinfo_aliases.txt";
348 t2
.in
.max_param
= 32;
349 t2
.in
.max_data
= UINT16_MAX
;
353 t2
.in
.setup_count
= 1;
354 t2
.in
.setup
= &setup
;
355 t2
.in
.params
= data_blob_talloc_zero(tctx
, 4);
356 t2
.in
.data
= data_blob(NULL
, 0);
359 smbcli_unlink(cli
->tree
, fname
);
361 fnum
= create_complex_file(cli
, cli
, fname
);
362 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
363 "open of %s failed (%s)", fname
,
364 smbcli_errstr(cli
->tree
)));
366 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
367 smbcli_close(cli
->tree
, fnum
);
369 SSVAL(t2
.in
.params
.data
, 2, 0);
371 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
372 fname
, STR_TERMINATE
);
374 if (!gen_set_aliases(tctx
, cli
, &t2
, 0))
377 torture_assert_ntstatus_ok(tctx
, smbcli_unlink(cli
->tree
, fname
),
378 talloc_asprintf(tctx
, "unlink: %s", smbcli_errstr(cli
->tree
)));
384 /* look for aliased info levels in trans2 calls */
385 struct torture_suite
*torture_trans2_aliases(TALLOC_CTX
*mem_ctx
)
387 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "ALIASES");
389 torture_suite_add_1smb_test(suite
, "QFILEINFO aliases", qfsinfo_aliases
);
390 torture_suite_add_1smb_test(suite
, "QFSINFO aliases", qfileinfo_aliases
);
391 torture_suite_add_1smb_test(suite
, "QPATHINFO aliases", qpathinfo_aliases
);
392 torture_suite_add_1smb_test(suite
, "FINDFIRST aliases", findfirst_aliases
);
393 torture_suite_add_1smb_test(suite
, "setfileinfo_aliases", setfileinfo_aliases
);
394 torture_suite_add_1smb_test(suite
, "setpathinfo_aliases", setpathinfo_aliases
);