2 Unix SMB/CIFS implementation.
4 SMB2 getinfo test suite
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "libcli/smb/smbXcli_base.h"
27 #include "torture/torture.h"
28 #include "torture/smb2/proto.h"
29 #include "torture/util.h"
36 union smb_fileinfo finfo
;
37 union smb_fileinfo dinfo
;
39 #define LEVEL(x) .name = #x, .level = x
40 { LEVEL(RAW_FILEINFO_BASIC_INFORMATION
) },
41 { LEVEL(RAW_FILEINFO_STANDARD_INFORMATION
) },
42 { LEVEL(RAW_FILEINFO_INTERNAL_INFORMATION
) },
43 { LEVEL(RAW_FILEINFO_EA_INFORMATION
) },
44 { LEVEL(RAW_FILEINFO_ACCESS_INFORMATION
) },
45 { LEVEL(RAW_FILEINFO_POSITION_INFORMATION
) },
46 { LEVEL(RAW_FILEINFO_MODE_INFORMATION
) },
47 { LEVEL(RAW_FILEINFO_ALIGNMENT_INFORMATION
) },
48 { LEVEL(RAW_FILEINFO_ALL_INFORMATION
) },
49 { LEVEL(RAW_FILEINFO_ALT_NAME_INFORMATION
) },
50 { LEVEL(RAW_FILEINFO_STREAM_INFORMATION
) },
51 { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION
) },
52 { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION
) },
53 { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION
) },
55 { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS
) },
57 { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION
) },
58 { LEVEL(RAW_FILEINFO_SEC_DESC
) }
65 union smb_fsinfo info
;
67 { LEVEL(RAW_QFS_VOLUME_INFORMATION
) },
68 { LEVEL(RAW_QFS_SIZE_INFORMATION
) },
69 { LEVEL(RAW_QFS_DEVICE_INFORMATION
) },
70 { LEVEL(RAW_QFS_ATTRIBUTE_INFORMATION
) },
71 { LEVEL(RAW_QFS_QUOTA_INFORMATION
) },
72 { LEVEL(RAW_QFS_FULL_SIZE_INFORMATION
) },
73 { LEVEL(RAW_QFS_OBJECTID_INFORMATION
) },
74 { LEVEL(RAW_QFS_SECTOR_SIZE_INFORMATION
) },
77 #define FNAME "testsmb2_file.dat"
78 #define DNAME "testsmb2_dir"
83 static bool torture_smb2_fileinfo(struct torture_context
*tctx
, struct smb2_tree
*tree
)
85 struct smb2_handle hfile
, hdir
;
89 status
= torture_smb2_testfile(tree
, FNAME
, &hfile
);
90 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create test file "
93 status
= torture_smb2_testdir(tree
, DNAME
, &hdir
);
94 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create test dir "
97 torture_comment(tctx
, "Testing file info levels\n");
98 torture_smb2_all_info(tctx
, tree
, hfile
);
99 torture_smb2_all_info(tctx
, tree
, hdir
);
101 for (i
=0;i
<ARRAY_SIZE(file_levels
);i
++) {
102 if (file_levels
[i
].level
== RAW_FILEINFO_SEC_DESC
) {
103 file_levels
[i
].finfo
.query_secdesc
.in
.secinfo_flags
= 0x7;
104 file_levels
[i
].dinfo
.query_secdesc
.in
.secinfo_flags
= 0x7;
106 if (file_levels
[i
].level
== RAW_FILEINFO_SMB2_ALL_EAS
) {
107 file_levels
[i
].finfo
.all_eas
.in
.continue_flags
=
108 SMB2_CONTINUE_FLAG_RESTART
;
109 file_levels
[i
].dinfo
.all_eas
.in
.continue_flags
=
110 SMB2_CONTINUE_FLAG_RESTART
;
112 file_levels
[i
].finfo
.generic
.level
= file_levels
[i
].level
;
113 file_levels
[i
].finfo
.generic
.in
.file
.handle
= hfile
;
114 file_levels
[i
].fstatus
= smb2_getinfo_file(tree
, tree
, &file_levels
[i
].finfo
);
115 torture_assert_ntstatus_ok(tctx
, file_levels
[i
].fstatus
,
116 talloc_asprintf(tctx
, "%s on file",
117 file_levels
[i
].name
));
118 file_levels
[i
].dinfo
.generic
.level
= file_levels
[i
].level
;
119 file_levels
[i
].dinfo
.generic
.in
.file
.handle
= hdir
;
120 file_levels
[i
].dstatus
= smb2_getinfo_file(tree
, tree
, &file_levels
[i
].dinfo
);
121 torture_assert_ntstatus_ok(tctx
, file_levels
[i
].dstatus
,
122 talloc_asprintf(tctx
, "%s on dir",
123 file_levels
[i
].name
));
130 test granted access when desired access includes
131 FILE_EXECUTE and does not include FILE_READ_DATA
133 static bool torture_smb2_fileinfo_grant_read(struct torture_context
*tctx
)
135 struct smb2_tree
*tree
;
137 struct smb2_handle hfile
, hdir
;
139 uint32_t file_granted_access
, dir_granted_access
;
141 ret
= torture_smb2_connection(tctx
, &tree
);
142 torture_assert(tctx
, ret
, "connection failed");
144 status
= torture_smb2_testfile_access(
145 tree
, FNAME
, &hfile
, SEC_FILE_EXECUTE
| SEC_FILE_READ_ATTRIBUTE
);
146 torture_assert_ntstatus_ok(tctx
, status
,
147 "Unable to create test file " FNAME
"\n");
149 torture_smb2_get_allinfo_access(tree
, hfile
, &file_granted_access
);
150 torture_assert_ntstatus_ok(tctx
, status
,
151 "Unable to query test file access ");
152 torture_assert_int_equal(tctx
, file_granted_access
,
153 SEC_FILE_EXECUTE
| SEC_FILE_READ_ATTRIBUTE
,
154 "granted file access ");
155 smb2_util_close(tree
, hfile
);
157 status
= torture_smb2_testdir_access(
158 tree
, DNAME
, &hdir
, SEC_FILE_EXECUTE
| SEC_FILE_READ_ATTRIBUTE
);
159 torture_assert_ntstatus_ok(tctx
, status
,
160 "Unable to create test dir " DNAME
"\n");
162 torture_smb2_get_allinfo_access(tree
, hdir
, &dir_granted_access
);
163 torture_assert_ntstatus_ok(tctx
, status
,
164 "Unable to query test dir access ");
165 torture_assert_int_equal(tctx
, dir_granted_access
,
166 SEC_FILE_EXECUTE
| SEC_FILE_READ_ATTRIBUTE
,
167 "granted dir access ");
168 smb2_util_close(tree
, hdir
);
173 static bool torture_smb2_fileinfo_normalized(struct torture_context
*tctx
)
175 struct smb2_tree
*tree
= NULL
;
177 struct smb2_handle hroot
;
178 const char *d1
= NULL
, *d1l
= NULL
, *d1u
= NULL
;
179 struct smb2_handle hd1
, hd1l
, hd1u
;
180 const char *d2
= NULL
, *d2l
= NULL
, *d2u
= NULL
;
181 struct smb2_handle hd2
, hd2l
, hd2u
;
182 const char *d3
= NULL
, *d3l
= NULL
, *d3u
= NULL
;
183 struct smb2_handle hd3
, hd3l
, hd3u
;
184 const char *d3s
= NULL
, *d3sl
= NULL
, *d3su
= NULL
, *d3sd
= NULL
;
185 struct smb2_handle hd3s
, hd3sl
, hd3su
, hd3sd
;
186 const char *f4
= NULL
, *f4l
= NULL
, *f4u
= NULL
, *f4d
= NULL
;
187 struct smb2_handle hf4
, hf4l
, hf4u
, hf4d
;
188 const char *f4s
= NULL
, *f4sl
= NULL
, *f4su
= NULL
, *f4sd
= NULL
;
189 struct smb2_handle hf4s
, hf4sl
, hf4su
, hf4sd
;
190 union smb_fileinfo info
= {
191 .normalized_name_info
= {
192 .level
= RAW_FILEINFO_NORMALIZED_NAME_INFORMATION
,
196 enum protocol_types protocol
;
197 struct smb2_tree
*tree_3_0
= NULL
;
198 struct smbcli_options options3_0
;
199 struct smb2_handle hroot_3_0
;
201 ret
= torture_smb2_connection(tctx
, &tree
);
202 torture_assert(tctx
, ret
, "connection failed");
204 protocol
= smbXcli_conn_protocol(tree
->session
->transport
->conn
);
206 d1
= talloc_asprintf(tctx
, "torture_dIr1N");
207 torture_assert_not_null(tctx
, d1
, "d1");
208 d1l
= strlower_talloc(tctx
, d1
);
209 torture_assert_not_null(tctx
, d1l
, "d1l");
210 d1u
= strupper_talloc(tctx
, d1
);
211 torture_assert_not_null(tctx
, d1u
, "d1u");
213 d2
= talloc_asprintf(tctx
, "%s\\dIr2Na", d1
);
214 torture_assert_not_null(tctx
, d2
, "d2");
215 d2l
= strlower_talloc(tctx
, d2
);
216 torture_assert_not_null(tctx
, d2l
, "d2l");
217 d2u
= strupper_talloc(tctx
, d2
);
218 torture_assert_not_null(tctx
, d2u
, "d2u");
220 d3
= talloc_asprintf(tctx
, "%s\\dIr3NaM", d2
);
221 torture_assert_not_null(tctx
, d3
, "d3");
222 d3l
= strlower_talloc(tctx
, d3
);
223 torture_assert_not_null(tctx
, d3l
, "d3l");
224 d3u
= strupper_talloc(tctx
, d3
);
225 torture_assert_not_null(tctx
, d3u
, "d3u");
227 d3s
= talloc_asprintf(tctx
, "%s:sTrEaM3", d3
);
228 torture_assert_not_null(tctx
, d3s
, "d3s");
229 d3sl
= strlower_talloc(tctx
, d3s
);
230 torture_assert_not_null(tctx
, d3sl
, "d3sl");
231 d3su
= strupper_talloc(tctx
, d3s
);
232 torture_assert_not_null(tctx
, d3su
, "d3su");
233 d3sd
= talloc_asprintf(tctx
, "%s:$DaTa", d3s
);
234 torture_assert_not_null(tctx
, d3sd
, "d3sd");
236 f4
= talloc_asprintf(tctx
, "%s\\fIlE4NaMe", d3
);
237 torture_assert_not_null(tctx
, f4
, "f4");
238 f4l
= strlower_talloc(tctx
, f4
);
239 torture_assert_not_null(tctx
, f4l
, "f4l");
240 f4u
= strupper_talloc(tctx
, f4
);
241 torture_assert_not_null(tctx
, f4u
, "f4u");
242 f4d
= talloc_asprintf(tctx
, "%s::$dAtA", f4
);
243 torture_assert_not_null(tctx
, f4d
, "f4d");
245 f4s
= talloc_asprintf(tctx
, "%s:StReAm4", f4
);
246 torture_assert_not_null(tctx
, f4s
, "f4s");
247 f4sl
= strlower_talloc(tctx
, f4s
);
248 torture_assert_not_null(tctx
, f4sl
, "f4sl");
249 f4su
= strupper_talloc(tctx
, f4s
);
250 torture_assert_not_null(tctx
, f4su
, "f4su");
251 f4sd
= talloc_asprintf(tctx
, "%s:$dAtA", f4s
);
252 torture_assert_not_null(tctx
, f4sd
, "f4sd");
254 status
= smb2_util_roothandle(tree
, &hroot
);
255 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create root handle");
257 info
.normalized_name_info
.in
.file
.handle
= hroot
;
258 ZERO_STRUCT(info
.normalized_name_info
.out
);
259 status
= smb2_getinfo_file(tree
, tree
, &info
);
260 if (protocol
< PROTOCOL_SMB3_11
) {
262 * Only SMB 3.1.1 and above should offer this.
264 torture_assert_ntstatus_equal(tctx
, status
,
265 NT_STATUS_NOT_SUPPORTED
,
267 torture_skip(tctx
, "SMB 3.1.1 not supported");
269 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_SUPPORTED
)) {
271 * Not all servers support this.
272 * (only Windows 10 1803 and higher)
274 torture_skip(tctx
, "NORMALIZED_NAME_INFORMATION not supported");
276 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hroot");
277 torture_assert(tctx
, info
.normalized_name_info
.out
.fname
.s
== NULL
,
278 "getinfo hroot should be empty");
280 smb2_deltree(tree
, d1
);
282 status
= torture_smb2_testdir(tree
, d1
, &hd1
);
283 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hd1");
284 status
= torture_smb2_open(tree
, d1l
, SEC_RIGHTS_FILE_ALL
, &hd1l
);
285 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd1l");
286 status
= torture_smb2_open(tree
, d1u
, SEC_RIGHTS_FILE_ALL
, &hd1u
);
287 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd1u");
289 status
= torture_smb2_testdir(tree
, d2
, &hd2
);
290 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hd2");
291 status
= torture_smb2_open(tree
, d2l
, SEC_RIGHTS_FILE_ALL
, &hd2l
);
292 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd2l");
293 status
= torture_smb2_open(tree
, d2u
, SEC_RIGHTS_FILE_ALL
, &hd2u
);
294 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd2u");
296 status
= torture_smb2_testdir(tree
, d3
, &hd3
);
297 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hd3");
298 status
= torture_smb2_open(tree
, d3l
, SEC_RIGHTS_FILE_ALL
, &hd3l
);
299 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd3l");
300 status
= torture_smb2_open(tree
, d3u
, SEC_RIGHTS_FILE_ALL
, &hd3u
);
301 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd3u");
303 status
= torture_smb2_testfile(tree
, d3s
, &hd3s
);
304 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hd3s");
305 status
= torture_smb2_open(tree
, d3sl
, SEC_RIGHTS_FILE_ALL
, &hd3sl
);
306 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd3sl");
307 status
= torture_smb2_open(tree
, d3su
, SEC_RIGHTS_FILE_ALL
, &hd3su
);
308 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd3su");
309 status
= torture_smb2_open(tree
, d3sd
, SEC_RIGHTS_FILE_ALL
, &hd3sd
);
310 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hd3sd");
312 status
= torture_smb2_testfile(tree
, f4
, &hf4
);
313 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hf4");
314 status
= torture_smb2_open(tree
, f4l
, SEC_RIGHTS_FILE_ALL
, &hf4l
);
315 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4l");
316 status
= torture_smb2_open(tree
, f4u
, SEC_RIGHTS_FILE_ALL
, &hf4u
);
317 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4u");
318 status
= torture_smb2_open(tree
, f4d
, SEC_RIGHTS_FILE_ALL
, &hf4d
);
319 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4d");
321 status
= torture_smb2_testfile(tree
, f4s
, &hf4s
);
322 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create hf4s");
323 status
= torture_smb2_open(tree
, f4sl
, SEC_RIGHTS_FILE_ALL
, &hf4sl
);
324 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4sl");
325 status
= torture_smb2_open(tree
, f4su
, SEC_RIGHTS_FILE_ALL
, &hf4su
);
326 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4su");
327 status
= torture_smb2_open(tree
, f4sd
, SEC_RIGHTS_FILE_ALL
, &hf4sd
);
328 torture_assert_ntstatus_ok(tctx
, status
, "Unable to open hf4sd");
330 info
.normalized_name_info
.in
.file
.handle
= hd1
;
331 ZERO_STRUCT(info
.normalized_name_info
.out
);
332 status
= smb2_getinfo_file(tree
, tree
, &info
);
333 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd1");
334 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
336 info
.normalized_name_info
.in
.file
.handle
= hd1l
;
337 ZERO_STRUCT(info
.normalized_name_info
.out
);
338 status
= smb2_getinfo_file(tree
, tree
, &info
);
339 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd1l");
340 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
342 info
.normalized_name_info
.in
.file
.handle
= hd1u
;
343 ZERO_STRUCT(info
.normalized_name_info
.out
);
344 status
= smb2_getinfo_file(tree
, tree
, &info
);
345 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd1u");
346 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
349 info
.normalized_name_info
.in
.file
.handle
= hd2
;
350 ZERO_STRUCT(info
.normalized_name_info
.out
);
351 status
= smb2_getinfo_file(tree
, tree
, &info
);
352 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd2");
353 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
355 info
.normalized_name_info
.in
.file
.handle
= hd2l
;
356 ZERO_STRUCT(info
.normalized_name_info
.out
);
357 status
= smb2_getinfo_file(tree
, tree
, &info
);
358 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd2l");
359 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
361 info
.normalized_name_info
.in
.file
.handle
= hd2u
;
362 ZERO_STRUCT(info
.normalized_name_info
.out
);
363 status
= smb2_getinfo_file(tree
, tree
, &info
);
364 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd2u");
365 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
368 info
.normalized_name_info
.in
.file
.handle
= hd3
;
369 ZERO_STRUCT(info
.normalized_name_info
.out
);
370 status
= smb2_getinfo_file(tree
, tree
, &info
);
371 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3");
372 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
374 info
.normalized_name_info
.in
.file
.handle
= hd3l
;
375 ZERO_STRUCT(info
.normalized_name_info
.out
);
376 status
= smb2_getinfo_file(tree
, tree
, &info
);
377 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3l");
378 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
380 info
.normalized_name_info
.in
.file
.handle
= hd3u
;
381 ZERO_STRUCT(info
.normalized_name_info
.out
);
382 status
= smb2_getinfo_file(tree
, tree
, &info
);
383 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3u");
384 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
387 info
.normalized_name_info
.in
.file
.handle
= hd3s
;
388 ZERO_STRUCT(info
.normalized_name_info
.out
);
389 status
= smb2_getinfo_file(tree
, tree
, &info
);
390 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3s");
391 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
392 d3s
, "getinfo hd3s");
393 info
.normalized_name_info
.in
.file
.handle
= hd3sl
;
394 ZERO_STRUCT(info
.normalized_name_info
.out
);
395 status
= smb2_getinfo_file(tree
, tree
, &info
);
396 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3sl");
397 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
398 d3s
, "getinfo hd3sl");
399 info
.normalized_name_info
.in
.file
.handle
= hd3su
;
400 ZERO_STRUCT(info
.normalized_name_info
.out
);
401 status
= smb2_getinfo_file(tree
, tree
, &info
);
402 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3su");
403 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
404 d3s
, "getinfo hd3su");
405 info
.normalized_name_info
.in
.file
.handle
= hd3sd
;
406 ZERO_STRUCT(info
.normalized_name_info
.out
);
407 status
= smb2_getinfo_file(tree
, tree
, &info
);
408 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hd3sd");
409 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
410 d3s
, "getinfo hd3sd");
412 info
.normalized_name_info
.in
.file
.handle
= hf4
;
413 ZERO_STRUCT(info
.normalized_name_info
.out
);
414 status
= smb2_getinfo_file(tree
, tree
, &info
);
415 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4");
416 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
418 info
.normalized_name_info
.in
.file
.handle
= hf4l
;
419 ZERO_STRUCT(info
.normalized_name_info
.out
);
420 status
= smb2_getinfo_file(tree
, tree
, &info
);
421 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4l");
422 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
424 info
.normalized_name_info
.in
.file
.handle
= hf4u
;
425 ZERO_STRUCT(info
.normalized_name_info
.out
);
426 status
= smb2_getinfo_file(tree
, tree
, &info
);
427 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4u");
428 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
430 info
.normalized_name_info
.in
.file
.handle
= hf4d
;
431 ZERO_STRUCT(info
.normalized_name_info
.out
);
432 status
= smb2_getinfo_file(tree
, tree
, &info
);
433 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4d");
434 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
437 info
.normalized_name_info
.in
.file
.handle
= hf4s
;
438 ZERO_STRUCT(info
.normalized_name_info
.out
);
439 status
= smb2_getinfo_file(tree
, tree
, &info
);
440 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4s");
441 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
442 f4s
, "getinfo hf4s");
443 info
.normalized_name_info
.in
.file
.handle
= hf4sl
;
444 ZERO_STRUCT(info
.normalized_name_info
.out
);
445 status
= smb2_getinfo_file(tree
, tree
, &info
);
446 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4sl");
447 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
448 f4s
, "getinfo hf4sl");
449 info
.normalized_name_info
.in
.file
.handle
= hf4su
;
450 ZERO_STRUCT(info
.normalized_name_info
.out
);
451 status
= smb2_getinfo_file(tree
, tree
, &info
);
452 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4su");
453 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
454 f4s
, "getinfo hf4su");
455 info
.normalized_name_info
.in
.file
.handle
= hf4sd
;
456 ZERO_STRUCT(info
.normalized_name_info
.out
);
457 status
= smb2_getinfo_file(tree
, tree
, &info
);
458 torture_assert_ntstatus_ok(tctx
, status
, "getinfo hf4sd");
459 torture_assert_str_equal(tctx
, info
.normalized_name_info
.out
.fname
.s
,
460 f4s
, "getinfo hf4sd");
462 /* Set max protocol to SMB 3.0.2 */
463 options3_0
= tree
->session
->transport
->options
;
464 options3_0
.max_protocol
= PROTOCOL_SMB3_02
;
465 options3_0
.client_guid
= GUID_zero();
466 ret
= torture_smb2_connection_ext(tctx
, 0, &options3_0
, &tree_3_0
);
467 torture_assert(tctx
, ret
, "connection with SMB < 3.1.1 failed");
469 status
= smb2_util_roothandle(tree_3_0
, &hroot_3_0
);
470 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create root handle 3_0");
472 info
.normalized_name_info
.in
.file
.handle
= hroot_3_0
;
473 ZERO_STRUCT(info
.normalized_name_info
.out
);
474 status
= smb2_getinfo_file(tree_3_0
, tree_3_0
, &info
);
475 torture_assert_ntstatus_equal(tctx
, status
,
476 NT_STATUS_NOT_SUPPORTED
,
485 static bool torture_smb2_fsinfo(struct torture_context
*tctx
)
488 struct smb2_tree
*tree
;
491 struct smb2_handle handle
;
493 torture_comment(tctx
, "Testing fsinfo levels\n");
495 ret
= torture_smb2_connection(tctx
, &tree
);
496 torture_assert(tctx
, ret
, "connection failed");
498 status
= smb2_util_roothandle(tree
, &handle
);
499 torture_assert_ntstatus_ok(tctx
, status
, "Unable to create root handle");
501 for (i
=0;i
<ARRAY_SIZE(fs_levels
);i
++) {
502 fs_levels
[i
].info
.generic
.level
= fs_levels
[i
].level
;
503 fs_levels
[i
].info
.generic
.handle
= handle
;
504 fs_levels
[i
].status
= smb2_getinfo_fs(tree
, tree
, &fs_levels
[i
].info
);
505 torture_assert_ntstatus_ok(tctx
, fs_levels
[i
].status
,
512 static bool torture_smb2_buffercheck_err(struct torture_context
*tctx
,
513 struct smb2_tree
*tree
,
514 struct smb2_getinfo
*b
,
520 for (i
=0; i
<=full
.length
; i
++) {
523 b
->in
.output_buffer_length
= i
;
525 status
= smb2_getinfo(tree
, tree
, b
);
528 torture_assert_ntstatus_equal(
529 tctx
, status
, NT_STATUS_INFO_LENGTH_MISMATCH
,
530 "Wrong error code small buffer");
535 torture_assert_ntstatus_equal(
536 tctx
, status
, STATUS_BUFFER_OVERFLOW
,
537 "Wrong error code for large buffer");
539 * TODO: compare the output buffer. That seems a bit
540 * difficult, because for level 5 for example the
541 * label length is adjusted to what is there. And some
542 * reserved fields seem to be not initialized to 0.
544 TALLOC_FREE(b
->out
.blob
.data
);
548 torture_assert_ntstatus_equal(
549 tctx
, status
, NT_STATUS_OK
,
550 "Wrong error code for right sized buffer");
556 struct level_buffersize
{
561 static bool torture_smb2_qfs_buffercheck(struct torture_context
*tctx
)
564 struct smb2_tree
*tree
;
566 struct smb2_handle handle
;
569 struct level_buffersize levels
[] = {
570 { 1, 24 }, /* We don't have proper defines here */
579 torture_comment(tctx
, "Testing SMB2_GETINFO_FS buffer sizes\n");
581 ret
= torture_smb2_connection(tctx
, &tree
);
582 torture_assert(tctx
, ret
, "connection failed");
584 status
= smb2_util_roothandle(tree
, &handle
);
585 torture_assert_ntstatus_ok(
586 tctx
, status
, "Unable to create root handle");
588 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
589 struct smb2_getinfo b
;
591 if (TARGET_IS_SAMBA3(tctx
) &&
592 ((levels
[i
].level
== 6) || (levels
[i
].level
== 11))) {
597 b
.in
.info_type
= SMB2_0_INFO_FILESYSTEM
;
598 b
.in
.info_class
= levels
[i
].level
;
599 b
.in
.file
.handle
= handle
;
600 b
.in
.output_buffer_length
= 65535;
602 status
= smb2_getinfo(tree
, tree
, &b
);
604 torture_assert_ntstatus_equal(
605 tctx
, status
, NT_STATUS_OK
,
606 "Wrong error code for large buffer");
608 ret
= torture_smb2_buffercheck_err(
609 tctx
, tree
, &b
, levels
[i
].fixed
, b
.out
.blob
);
618 static bool torture_smb2_qfile_buffercheck(struct torture_context
*tctx
)
621 struct smb2_tree
*tree
;
622 struct smb2_create c
;
624 struct smb2_handle handle
;
627 struct level_buffersize levels
[] = {
643 torture_comment(tctx
, "Testing SMB2_GETINFO_FILE buffer sizes\n");
645 ret
= torture_smb2_connection(tctx
, &tree
);
646 torture_assert(tctx
, ret
, "connection failed");
649 c
.in
.desired_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
650 c
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
651 c
.in
.create_disposition
= NTCREATEX_DISP_OVERWRITE_IF
;
653 NTCREATEX_SHARE_ACCESS_DELETE
|
654 NTCREATEX_SHARE_ACCESS_READ
|
655 NTCREATEX_SHARE_ACCESS_WRITE
;
656 c
.in
.create_options
= 0;
657 c
.in
.fname
= "bufsize.txt";
659 c
.in
.eas
.num_eas
= 2;
660 c
.in
.eas
.eas
= talloc_array(tree
, struct ea_struct
, 2);
661 c
.in
.eas
.eas
[0].flags
= 0;
662 c
.in
.eas
.eas
[0].name
.s
= "EAONE";
663 c
.in
.eas
.eas
[0].value
= data_blob_talloc(c
.in
.eas
.eas
, "VALUE1", 6);
664 c
.in
.eas
.eas
[1].flags
= 0;
665 c
.in
.eas
.eas
[1].name
.s
= "SECONDEA";
666 c
.in
.eas
.eas
[1].value
= data_blob_talloc(c
.in
.eas
.eas
, "ValueTwo", 8);
668 status
= smb2_create(tree
, tree
, &c
);
669 torture_assert_ntstatus_ok(
670 tctx
, status
, "Unable to create test file");
672 handle
= c
.out
.file
.handle
;
674 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
675 struct smb2_getinfo b
;
678 b
.in
.info_type
= SMB2_0_INFO_FILE
;
679 b
.in
.info_class
= levels
[i
].level
;
680 b
.in
.file
.handle
= handle
;
681 b
.in
.output_buffer_length
= 65535;
683 status
= smb2_getinfo(tree
, tree
, &b
);
684 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
687 torture_assert_ntstatus_equal(
688 tctx
, status
, NT_STATUS_OK
,
689 "Wrong error code for large buffer");
691 ret
= torture_smb2_buffercheck_err(
692 tctx
, tree
, &b
, levels
[i
].fixed
, b
.out
.blob
);
700 static bool torture_smb2_qsec_buffercheck(struct torture_context
*tctx
)
702 struct smb2_getinfo b
;
704 struct smb2_tree
*tree
;
705 struct smb2_create c
;
707 struct smb2_handle handle
;
709 torture_comment(tctx
, "Testing SMB2_GETINFO_SECURITY buffer sizes\n");
711 ret
= torture_smb2_connection(tctx
, &tree
);
712 torture_assert(tctx
, ret
, "connection failed");
715 c
.in
.oplock_level
= 0;
716 c
.in
.desired_access
= SEC_STD_SYNCHRONIZE
| SEC_DIR_READ_ATTRIBUTE
|
717 SEC_DIR_LIST
| SEC_STD_READ_CONTROL
;
718 c
.in
.file_attributes
= 0;
719 c
.in
.create_disposition
= NTCREATEX_DISP_OPEN
;
720 c
.in
.share_access
= NTCREATEX_SHARE_ACCESS_READ
|
721 NTCREATEX_SHARE_ACCESS_DELETE
;
722 c
.in
.create_options
= NTCREATEX_OPTIONS_ASYNC_ALERT
;
725 status
= smb2_create(tree
, tree
, &c
);
726 torture_assert_ntstatus_ok(
727 tctx
, status
, "Unable to create root handle");
729 handle
= c
.out
.file
.handle
;
732 b
.in
.info_type
= SMB2_0_INFO_SECURITY
;
734 b
.in
.file
.handle
= handle
;
735 b
.in
.output_buffer_length
= 0;
737 status
= smb2_getinfo(tree
, tree
, &b
);
738 torture_assert_ntstatus_equal(
739 tctx
, status
, NT_STATUS_BUFFER_TOO_SMALL
,
740 "Wrong error code for large buffer");
742 b
.in
.output_buffer_length
= 1;
743 status
= smb2_getinfo(tree
, tree
, &b
);
744 torture_assert_ntstatus_equal(
745 tctx
, status
, NT_STATUS_BUFFER_TOO_SMALL
,
746 "Wrong error code for large buffer");
751 /* basic testing of all SMB2 getinfo levels
753 static bool torture_smb2_getinfo(struct torture_context
*tctx
)
755 struct smb2_tree
*tree
;
759 ret
= torture_smb2_connection(tctx
, &tree
);
760 torture_assert(tctx
, ret
, "connection failed");
762 smb2_deltree(tree
, FNAME
);
763 smb2_deltree(tree
, DNAME
);
765 status
= torture_setup_complex_file(tctx
, tree
, FNAME
);
766 torture_assert_ntstatus_ok(tctx
, status
,
767 "setup complex file " FNAME
);
769 status
= torture_setup_complex_file(tctx
, tree
, FNAME
":streamtwo");
770 torture_assert_ntstatus_ok(tctx
, status
,
771 "setup complex file " FNAME
":streamtwo");
773 status
= torture_setup_complex_dir(tctx
, tree
, DNAME
);
774 torture_assert_ntstatus_ok(tctx
, status
,
775 "setup complex dir " DNAME
);
777 status
= torture_setup_complex_file(tctx
, tree
, DNAME
":streamtwo");
778 torture_assert_ntstatus_ok(tctx
, status
,
779 "setup complex dir " DNAME
":streamtwo");
781 ret
&= torture_smb2_fileinfo(tctx
, tree
);
787 #define LEVEL(l, u, ua, ra) \
791 .unrestricted_access = ua, \
792 .required_access = ra
798 uint32_t unrestricted_access
;
799 uint32_t required_access
;
800 } file_levels_access
[] = {
802 * The following info levels are not checked:
803 * - FileFullEaInformation and FileIdInformation:
804 * not implemented by the s4/libcli/raw
805 * - all pipe infolevels: that should be tested elsewhere by RPC tests
809 * The following allow unrestricted access, so requesting
810 * SEC_FILE_READ_ATTRIBUTE works, SEC_FILE_READ_ATTRIBUTE or
811 * SEC_FILE_READ_EA as well of course.
813 { LEVEL(RAW_FILEINFO_STANDARD_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
814 { LEVEL(RAW_FILEINFO_INTERNAL_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
815 { LEVEL(RAW_FILEINFO_ACCESS_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
816 { LEVEL(RAW_FILEINFO_POSITION_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
817 { LEVEL(RAW_FILEINFO_MODE_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
818 { LEVEL(RAW_FILEINFO_ALIGNMENT_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
819 { LEVEL(RAW_FILEINFO_ALT_NAME_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
820 { LEVEL(RAW_FILEINFO_STREAM_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
821 { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
822 { LEVEL(RAW_FILEINFO_NORMALIZED_NAME_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
823 { LEVEL(RAW_FILEINFO_EA_INFORMATION
, true, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_EA
) },
826 * The following require either SEC_FILE_READ_ATTRIBUTE or
829 { LEVEL(RAW_FILEINFO_BASIC_INFORMATION
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
830 { LEVEL(RAW_FILEINFO_ALL_INFORMATION
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
831 { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
832 { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
833 { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_ATTRIBUTE
) },
834 { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS
, false, SEC_STD_SYNCHRONIZE
, SEC_FILE_READ_EA
) },
835 /* Also try SEC_FILE_READ_ATTRIBUTE to show that it is the wrong one */
836 { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS
, false, SEC_FILE_READ_ATTRIBUTE
, SEC_FILE_READ_EA
) },
837 { LEVEL(RAW_FILEINFO_SEC_DESC
, false, SEC_STD_SYNCHRONIZE
, SEC_STD_READ_CONTROL
) },
838 /* Also try SEC_FILE_READ_ATTRIBUTE to show that it is the wrong one */
839 { LEVEL(RAW_FILEINFO_SEC_DESC
, false, SEC_FILE_READ_ATTRIBUTE
, SEC_STD_READ_CONTROL
) }
846 static bool torture_smb2_getfinfo_access(struct torture_context
*tctx
,
847 struct smb2_tree
*tree
)
849 const char *fname
= "torture_smb2_getfinfo_access";
850 struct smb2_handle hfile
;
855 smb2_deltree(tree
, fname
);
857 torture_setup_complex_file(tctx
, tree
, fname
);
859 for (i
= 0; i
< ARRAY_SIZE(file_levels_access
); i
++) {
860 union smb_fileinfo finfo
;
861 NTSTATUS expected_status
;
864 * First open with unrestricted_access, SEC_STD_SYNCHRONIZE for
865 * most tests, info levels with unrestricted=true should allow
868 status
= torture_smb2_testfile_access(
869 tree
, fname
, &hfile
, file_levels_access
[i
].unrestricted_access
);
870 torture_assert_ntstatus_ok_goto(tctx
, status
, ret
, done
,
871 "Unable to open test file\n");
873 if (file_levels_access
[i
].level
== RAW_FILEINFO_SEC_DESC
) {
874 finfo
.query_secdesc
.in
.secinfo_flags
= 0x7;
876 if (file_levels_access
[i
].level
== RAW_FILEINFO_SMB2_ALL_EAS
) {
877 finfo
.all_eas
.in
.continue_flags
=
878 SMB2_CONTINUE_FLAG_RESTART
;
881 finfo
.generic
.level
= file_levels_access
[i
].level
;
882 finfo
.generic
.in
.file
.handle
= hfile
;
884 if (file_levels_access
[i
].unrestricted
) {
885 expected_status
= NT_STATUS_OK
;
887 expected_status
= NT_STATUS_ACCESS_DENIED
;
890 status
= smb2_getinfo_file(tree
, tree
, &finfo
);
891 torture_assert_ntstatus_equal_goto(
892 tctx
, status
, expected_status
, ret
, done
,
893 talloc_asprintf(tctx
, "Level %s failed\n",
894 file_levels_access
[i
].name
));
896 smb2_util_close(tree
, hfile
);
899 * Now open with expected access, getinfo should work.
901 status
= torture_smb2_testfile_access(
902 tree
, fname
, &hfile
, file_levels_access
[i
].required_access
);
903 torture_assert_ntstatus_ok_goto(
904 tctx
, status
, ret
, done
,
905 "Unable to open test file\n");
907 if (file_levels_access
[i
].level
== RAW_FILEINFO_SEC_DESC
) {
908 finfo
.query_secdesc
.in
.secinfo_flags
= 0x7;
910 if (file_levels_access
[i
].level
== RAW_FILEINFO_SMB2_ALL_EAS
) {
911 finfo
.all_eas
.in
.continue_flags
=
912 SMB2_CONTINUE_FLAG_RESTART
;
914 finfo
.generic
.level
= file_levels_access
[i
].level
;
915 finfo
.generic
.in
.file
.handle
= hfile
;
917 status
= smb2_getinfo_file(tree
, tree
, &finfo
);
918 torture_assert_ntstatus_ok_goto(
919 tctx
, status
, ret
, done
,
920 talloc_asprintf(tctx
, "%s on file",
921 file_levels_access
[i
].name
));
923 smb2_util_close(tree
, hfile
);
927 smb2_deltree(tree
, fname
);
931 struct torture_suite
*torture_smb2_getinfo_init(TALLOC_CTX
*ctx
)
933 struct torture_suite
*suite
= torture_suite_create(
936 torture_suite_add_simple_test(suite
, "complex", torture_smb2_getinfo
);
937 torture_suite_add_simple_test(suite
, "fsinfo", torture_smb2_fsinfo
);
938 torture_suite_add_simple_test(suite
, "qfs_buffercheck",
939 torture_smb2_qfs_buffercheck
);
940 torture_suite_add_simple_test(suite
, "qfile_buffercheck",
941 torture_smb2_qfile_buffercheck
);
942 torture_suite_add_simple_test(suite
, "qsec_buffercheck",
943 torture_smb2_qsec_buffercheck
);
944 torture_suite_add_simple_test(suite
, "granted",
945 torture_smb2_fileinfo_grant_read
);
946 torture_suite_add_simple_test(suite
, "normalized",
947 torture_smb2_fileinfo_normalized
);
948 torture_suite_add_1smb2_test(suite
, "getinfo_access",
949 torture_smb2_getfinfo_access
);