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 "libcli/libcli.h"
25 #include "torture/util.h"
27 int create_complex_file(struct smbcli_state
*cli
, TALLOC_CTX
*mem_ctx
, const char *fname
);
30 struct trans2_blobs
*next
, *prev
;
32 DATA_BLOB params
, data
;
35 /* look for aliases for a query */
36 static bool gen_aliases(struct torture_context
*tctx
,
37 struct smbcli_state
*cli
, struct smb_trans2
*t2
,
41 struct trans2_blobs
*alias_blobs
= NULL
;
42 struct trans2_blobs
*t2b
, *t2b2
;
43 int count
=0, alias_count
=0;
45 for (level
=0;level
<2000;level
++) {
48 SSVAL(t2
->in
.params
.data
, level_offset
, level
);
50 status
= smb_raw_trans2(cli
->tree
, tctx
, t2
);
51 if (!NT_STATUS_IS_OK(status
)) continue;
53 t2b
= talloc(tctx
, struct trans2_blobs
);
55 t2b
->params
= t2
->out
.params
;
56 t2b
->data
= t2
->out
.data
;
57 DLIST_ADD(alias_blobs
, t2b
);
59 "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n",
61 (int)t2b
->data
.length
, (int)t2b
->data
.length
);
65 torture_comment(tctx
, "Found %d levels with success status\n", count
);
67 for (t2b
=alias_blobs
; t2b
; t2b
=t2b
->next
) {
68 for (t2b2
=alias_blobs
; t2b2
; t2b2
=t2b2
->next
) {
69 if (t2b
->level
>= t2b2
->level
) continue;
70 if (data_blob_cmp(&t2b
->params
, &t2b2
->params
) == 0 &&
71 data_blob_cmp(&t2b
->data
, &t2b2
->data
) == 0) {
73 "\tLevel %u (0x%x) and level %u (0x%x) are possible aliases\n",
74 t2b
->level
, t2b
->level
, t2b2
->level
, t2b2
->level
);
80 torture_comment(tctx
, "Found %d aliased levels\n", alias_count
);
85 /* look for qfsinfo aliases */
86 static bool qfsinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
89 uint16_t setup
= TRANSACT2_QFSINFO
;
92 t2
.in
.max_data
= UINT16_MAX
;
96 t2
.in
.setup_count
= 1;
98 t2
.in
.params
= data_blob_talloc_zero(tctx
, 2);
99 t2
.in
.data
= data_blob(NULL
, 0);
102 return gen_aliases(tctx
, cli
, &t2
, 0);
105 /* look for qfileinfo aliases */
106 static bool qfileinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
108 struct smb_trans2 t2
;
109 uint16_t setup
= TRANSACT2_QFILEINFO
;
110 const char *fname
= "\\qfileinfo_aliases.txt";
114 t2
.in
.max_data
= UINT16_MAX
;
118 t2
.in
.setup_count
= 1;
119 t2
.in
.setup
= &setup
;
120 t2
.in
.params
= data_blob_talloc_zero(tctx
, 4);
121 t2
.in
.data
= data_blob(NULL
, 0);
124 smbcli_unlink(cli
->tree
, fname
);
125 fnum
= create_complex_file(cli
, cli
, fname
);
126 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
127 "open of %s failed (%s)", fname
,
128 smbcli_errstr(cli
->tree
)));
130 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
132 SSVAL(t2
.in
.params
.data
, 0, fnum
);
134 if (!gen_aliases(tctx
, cli
, &t2
, 2))
137 smbcli_close(cli
->tree
, fnum
);
138 smbcli_unlink(cli
->tree
, fname
);
144 /* look for qpathinfo aliases */
145 static bool qpathinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
147 struct smb_trans2 t2
;
148 uint16_t setup
= TRANSACT2_QPATHINFO
;
149 const char *fname
= "\\qpathinfo_aliases.txt";
153 t2
.in
.max_data
= UINT16_MAX
;
157 t2
.in
.setup_count
= 1;
158 t2
.in
.setup
= &setup
;
159 t2
.in
.params
= data_blob_talloc_zero(tctx
, 6);
160 t2
.in
.data
= data_blob(NULL
, 0);
163 smbcli_unlink(cli
->tree
, fname
);
164 fnum
= create_complex_file(cli
, cli
, fname
);
165 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
166 "open of %s failed (%s)", fname
,
167 smbcli_errstr(cli
->tree
)));
169 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
170 smbcli_close(cli
->tree
, fnum
);
172 SIVAL(t2
.in
.params
.data
, 2, 0);
174 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
175 fname
, STR_TERMINATE
);
177 if (!gen_aliases(tctx
, cli
, &t2
, 0))
180 smbcli_unlink(cli
->tree
, fname
);
186 /* look for trans2 findfirst aliases */
187 static bool findfirst_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
189 struct smb_trans2 t2
;
190 uint16_t setup
= TRANSACT2_FINDFIRST
;
191 const char *fname
= "\\findfirst_aliases.txt";
194 t2
.in
.max_param
= 16;
195 t2
.in
.max_data
= UINT16_MAX
;
199 t2
.in
.setup_count
= 1;
200 t2
.in
.setup
= &setup
;
201 t2
.in
.params
= data_blob_talloc_zero(tctx
, 12);
202 t2
.in
.data
= data_blob(NULL
, 0);
205 smbcli_unlink(cli
->tree
, fname
);
206 fnum
= create_complex_file(cli
, cli
, fname
);
207 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
208 "open of %s failed (%s)", fname
,
209 smbcli_errstr(cli
->tree
)));
211 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
212 smbcli_close(cli
->tree
, fnum
);
214 SSVAL(t2
.in
.params
.data
, 0, 0);
215 SSVAL(t2
.in
.params
.data
, 2, 1);
216 SSVAL(t2
.in
.params
.data
, 4, FLAG_TRANS2_FIND_CLOSE
);
217 SSVAL(t2
.in
.params
.data
, 6, 0);
218 SIVAL(t2
.in
.params
.data
, 8, 0);
220 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
221 fname
, STR_TERMINATE
);
223 if (!gen_aliases(tctx
, cli
, &t2
, 6))
226 smbcli_unlink(cli
->tree
, fname
);
233 /* look for aliases for a set function */
234 static bool gen_set_aliases(struct torture_context
*tctx
,
235 struct smbcli_state
*cli
,
236 struct smb_trans2
*t2
, int level_offset
)
239 struct trans2_blobs
*alias_blobs
= NULL
;
240 struct trans2_blobs
*t2b
;
243 for (level
=1;level
<1100;level
++) {
244 NTSTATUS status
, status1
;
245 SSVAL(t2
->in
.params
.data
, level_offset
, level
);
247 status1
= NT_STATUS_OK
;
249 for (dsize
=2; dsize
<1024; dsize
+= 2) {
250 data_blob_free(&t2
->in
.data
);
251 t2
->in
.data
= data_blob(NULL
, dsize
);
252 data_blob_clear(&t2
->in
.data
);
253 status
= smb_raw_trans2(cli
->tree
, tctx
, t2
);
254 /* some error codes mean that this whole level doesn't exist */
255 if (NT_STATUS_EQUAL(NT_STATUS_INVALID_LEVEL
, status
) ||
256 NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
) ||
257 NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED
, status
)) {
260 if (NT_STATUS_IS_OK(status
)) break;
262 /* invalid parameter means that the level exists at this
263 size, but the contents are wrong (not surprising with
265 if (NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) break;
267 /* this is the usual code for 'wrong size' */
268 if (NT_STATUS_EQUAL(status
, NT_STATUS_INFO_LENGTH_MISMATCH
)) {
272 if (!NT_STATUS_EQUAL(status
, status1
)) {
273 torture_comment(tctx
, "level=%d size=%d %s\n", level
, dsize
, nt_errstr(status
));
278 if (!NT_STATUS_IS_OK(status
) &&
279 !NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) continue;
281 t2b
= talloc(tctx
, struct trans2_blobs
);
283 t2b
->params
= t2
->out
.params
;
284 t2b
->data
= t2
->out
.data
;
285 DLIST_ADD(alias_blobs
, t2b
);
286 torture_comment(tctx
,
287 "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n",
289 (int)t2
->in
.data
.length
, (int)t2
->in
.data
.length
);
293 torture_comment(tctx
, "Found %d valid levels\n", count
);
300 /* look for setfileinfo aliases */
301 static bool setfileinfo_aliases(struct torture_context
*tctx
, struct smbcli_state
*cli
)
303 struct smb_trans2 t2
;
304 uint16_t setup
= TRANSACT2_SETFILEINFO
;
305 const char *fname
= "\\setfileinfo_aliases.txt";
313 t2
.in
.setup_count
= 1;
314 t2
.in
.setup
= &setup
;
315 t2
.in
.params
= data_blob_talloc_zero(tctx
, 6);
316 t2
.in
.data
= data_blob(NULL
, 0);
319 smbcli_unlink(cli
->tree
, fname
);
320 fnum
= create_complex_file(cli
, cli
, fname
);
321 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
322 "open of %s failed (%s)", fname
,
323 smbcli_errstr(cli
->tree
)));
325 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
327 SSVAL(t2
.in
.params
.data
, 0, fnum
);
328 SSVAL(t2
.in
.params
.data
, 4, 0);
330 gen_set_aliases(tctx
, cli
, &t2
, 2);
332 smbcli_close(cli
->tree
, fnum
);
333 smbcli_unlink(cli
->tree
, fname
);
338 /* look for setpathinfo aliases */
339 static bool setpathinfo_aliases(struct torture_context
*tctx
,
340 struct smbcli_state
*cli
)
342 struct smb_trans2 t2
;
343 uint16_t setup
= TRANSACT2_SETPATHINFO
;
344 const char *fname
= "\\setpathinfo_aliases.txt";
347 t2
.in
.max_param
= 32;
348 t2
.in
.max_data
= UINT16_MAX
;
352 t2
.in
.setup_count
= 1;
353 t2
.in
.setup
= &setup
;
354 t2
.in
.params
= data_blob_talloc_zero(tctx
, 4);
355 t2
.in
.data
= data_blob(NULL
, 0);
358 smbcli_unlink(cli
->tree
, fname
);
360 fnum
= create_complex_file(cli
, cli
, fname
);
361 torture_assert(tctx
, fnum
!= -1, talloc_asprintf(tctx
,
362 "open of %s failed (%s)", fname
,
363 smbcli_errstr(cli
->tree
)));
365 smbcli_write(cli
->tree
, fnum
, 0, &t2
, 0, sizeof(t2
));
366 smbcli_close(cli
->tree
, fnum
);
368 SSVAL(t2
.in
.params
.data
, 2, 0);
370 smbcli_blob_append_string(cli
->session
, tctx
, &t2
.in
.params
,
371 fname
, STR_TERMINATE
);
373 if (!gen_set_aliases(tctx
, cli
, &t2
, 0))
376 torture_assert_ntstatus_ok(tctx
, smbcli_unlink(cli
->tree
, fname
),
377 talloc_asprintf(tctx
, "unlink: %s", smbcli_errstr(cli
->tree
)));
383 /* look for aliased info levels in trans2 calls */
384 struct torture_suite
*torture_trans2_aliases(TALLOC_CTX
*mem_ctx
)
386 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "aliases");
388 torture_suite_add_1smb_test(suite
, "QFILEINFO aliases", qfsinfo_aliases
);
389 torture_suite_add_1smb_test(suite
, "QFSINFO aliases", qfileinfo_aliases
);
390 torture_suite_add_1smb_test(suite
, "QPATHINFO aliases", qpathinfo_aliases
);
391 torture_suite_add_1smb_test(suite
, "FINDFIRST aliases", findfirst_aliases
);
392 torture_suite_add_1smb_test(suite
, "setfileinfo_aliases", setfileinfo_aliases
);
393 torture_suite_add_1smb_test(suite
, "setpathinfo_aliases", setpathinfo_aliases
);