Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : SMB2 getinfo test suite
5 :
6 : Copyright (C) Andrew Tridgell 2005
7 :
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.
12 :
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.
17 :
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/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "libcli/smb2/smb2.h"
24 : #include "libcli/smb2/smb2_calls.h"
25 : #include "libcli/smb/smbXcli_base.h"
26 :
27 : #include "torture/torture.h"
28 : #include "torture/smb2/proto.h"
29 : #include "torture/util.h"
30 :
31 : static struct {
32 : const char *name;
33 : uint16_t level;
34 : NTSTATUS fstatus;
35 : NTSTATUS dstatus;
36 : union smb_fileinfo finfo;
37 : union smb_fileinfo dinfo;
38 : } file_levels[] = {
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) },
54 :
55 : { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
56 :
57 : { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
58 : { LEVEL(RAW_FILEINFO_SEC_DESC) }
59 : };
60 :
61 : static struct {
62 : const char *name;
63 : uint16_t level;
64 : NTSTATUS status;
65 : union smb_fsinfo info;
66 : } fs_levels[] = {
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) },
75 : };
76 :
77 : #define FNAME "testsmb2_file.dat"
78 : #define DNAME "testsmb2_dir"
79 :
80 : /*
81 : test fileinfo levels
82 : */
83 0 : static bool torture_smb2_fileinfo(struct torture_context *tctx, struct smb2_tree *tree)
84 : {
85 : struct smb2_handle hfile, hdir;
86 : NTSTATUS status;
87 : int i;
88 :
89 0 : status = torture_smb2_testfile(tree, FNAME, &hfile);
90 0 : torture_assert_ntstatus_ok(tctx, status, "Unable to create test file "
91 : FNAME "\n");
92 :
93 0 : status = torture_smb2_testdir(tree, DNAME, &hdir);
94 0 : torture_assert_ntstatus_ok(tctx, status, "Unable to create test dir "
95 : DNAME "\n");
96 :
97 0 : torture_comment(tctx, "Testing file info levels\n");
98 0 : torture_smb2_all_info(tctx, tree, hfile);
99 0 : torture_smb2_all_info(tctx, tree, hdir);
100 :
101 0 : for (i=0;i<ARRAY_SIZE(file_levels);i++) {
102 0 : if (file_levels[i].level == RAW_FILEINFO_SEC_DESC) {
103 0 : file_levels[i].finfo.query_secdesc.in.secinfo_flags = 0x7;
104 0 : file_levels[i].dinfo.query_secdesc.in.secinfo_flags = 0x7;
105 : }
106 0 : if (file_levels[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
107 0 : file_levels[i].finfo.all_eas.in.continue_flags =
108 : SMB2_CONTINUE_FLAG_RESTART;
109 0 : file_levels[i].dinfo.all_eas.in.continue_flags =
110 : SMB2_CONTINUE_FLAG_RESTART;
111 : }
112 0 : file_levels[i].finfo.generic.level = file_levels[i].level;
113 0 : file_levels[i].finfo.generic.in.file.handle = hfile;
114 0 : file_levels[i].fstatus = smb2_getinfo_file(tree, tree, &file_levels[i].finfo);
115 0 : torture_assert_ntstatus_ok(tctx, file_levels[i].fstatus,
116 : talloc_asprintf(tctx, "%s on file",
117 : file_levels[i].name));
118 0 : file_levels[i].dinfo.generic.level = file_levels[i].level;
119 0 : file_levels[i].dinfo.generic.in.file.handle = hdir;
120 0 : file_levels[i].dstatus = smb2_getinfo_file(tree, tree, &file_levels[i].dinfo);
121 0 : torture_assert_ntstatus_ok(tctx, file_levels[i].dstatus,
122 : talloc_asprintf(tctx, "%s on dir",
123 : file_levels[i].name));
124 : }
125 :
126 0 : return true;
127 : }
128 :
129 : /*
130 : test granted access when desired access includes
131 : FILE_EXECUTE and does not include FILE_READ_DATA
132 : */
133 5 : static bool torture_smb2_fileinfo_grant_read(struct torture_context *tctx)
134 : {
135 : struct smb2_tree *tree;
136 : bool ret;
137 : struct smb2_handle hfile, hdir;
138 : NTSTATUS status;
139 : uint32_t file_granted_access, dir_granted_access;
140 :
141 5 : ret = torture_smb2_connection(tctx, &tree);
142 5 : torture_assert(tctx, ret, "connection failed");
143 :
144 5 : status = torture_smb2_testfile_access(
145 : tree, FNAME, &hfile, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
146 5 : torture_assert_ntstatus_ok(tctx, status,
147 : "Unable to create test file " FNAME "\n");
148 4 : status =
149 5 : torture_smb2_get_allinfo_access(tree, hfile, &file_granted_access);
150 5 : torture_assert_ntstatus_ok(tctx, status,
151 : "Unable to query test file access ");
152 5 : torture_assert_int_equal(tctx, file_granted_access,
153 : SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
154 : "granted file access ");
155 5 : smb2_util_close(tree, hfile);
156 :
157 5 : status = torture_smb2_testdir_access(
158 : tree, DNAME, &hdir, SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE);
159 5 : torture_assert_ntstatus_ok(tctx, status,
160 : "Unable to create test dir " DNAME "\n");
161 4 : status =
162 5 : torture_smb2_get_allinfo_access(tree, hdir, &dir_granted_access);
163 5 : torture_assert_ntstatus_ok(tctx, status,
164 : "Unable to query test dir access ");
165 5 : torture_assert_int_equal(tctx, dir_granted_access,
166 : SEC_FILE_EXECUTE | SEC_FILE_READ_ATTRIBUTE,
167 : "granted dir access ");
168 5 : smb2_util_close(tree, hdir);
169 :
170 5 : return true;
171 : }
172 :
173 5 : static bool torture_smb2_fileinfo_normalized(struct torture_context *tctx)
174 : {
175 5 : struct smb2_tree *tree = NULL;
176 : bool ret;
177 : struct smb2_handle hroot;
178 5 : const char *d1 = NULL, *d1l = NULL, *d1u = NULL;
179 : struct smb2_handle hd1, hd1l, hd1u;
180 5 : const char *d2 = NULL, *d2l = NULL, *d2u = NULL;
181 : struct smb2_handle hd2, hd2l, hd2u;
182 5 : const char *d3 = NULL, *d3l = NULL, *d3u = NULL;
183 : struct smb2_handle hd3, hd3l, hd3u;
184 5 : const char *d3s = NULL, *d3sl = NULL, *d3su = NULL, *d3sd = NULL;
185 : struct smb2_handle hd3s, hd3sl, hd3su, hd3sd;
186 5 : const char *f4 = NULL, *f4l = NULL, *f4u = NULL, *f4d = NULL;
187 : struct smb2_handle hf4, hf4l, hf4u, hf4d;
188 5 : const char *f4s = NULL, *f4sl = NULL, *f4su = NULL, *f4sd = NULL;
189 : struct smb2_handle hf4s, hf4sl, hf4su, hf4sd;
190 5 : union smb_fileinfo info = {
191 : .normalized_name_info = {
192 : .level = RAW_FILEINFO_NORMALIZED_NAME_INFORMATION,
193 : },
194 : };
195 : NTSTATUS status;
196 : enum protocol_types protocol;
197 5 : struct smb2_tree *tree_3_0 = NULL;
198 : struct smbcli_options options3_0;
199 : struct smb2_handle hroot_3_0;
200 :
201 5 : ret = torture_smb2_connection(tctx, &tree);
202 5 : torture_assert(tctx, ret, "connection failed");
203 :
204 5 : protocol = smbXcli_conn_protocol(tree->session->transport->conn);
205 :
206 5 : d1 = talloc_asprintf(tctx, "torture_dIr1N");
207 5 : torture_assert_not_null(tctx, d1, "d1");
208 5 : d1l = strlower_talloc(tctx, d1);
209 5 : torture_assert_not_null(tctx, d1l, "d1l");
210 5 : d1u = strupper_talloc(tctx, d1);
211 5 : torture_assert_not_null(tctx, d1u, "d1u");
212 :
213 5 : d2 = talloc_asprintf(tctx, "%s\\dIr2Na", d1);
214 5 : torture_assert_not_null(tctx, d2, "d2");
215 5 : d2l = strlower_talloc(tctx, d2);
216 5 : torture_assert_not_null(tctx, d2l, "d2l");
217 5 : d2u = strupper_talloc(tctx, d2);
218 5 : torture_assert_not_null(tctx, d2u, "d2u");
219 :
220 5 : d3 = talloc_asprintf(tctx, "%s\\dIr3NaM", d2);
221 5 : torture_assert_not_null(tctx, d3, "d3");
222 5 : d3l = strlower_talloc(tctx, d3);
223 5 : torture_assert_not_null(tctx, d3l, "d3l");
224 5 : d3u = strupper_talloc(tctx, d3);
225 5 : torture_assert_not_null(tctx, d3u, "d3u");
226 :
227 5 : d3s = talloc_asprintf(tctx, "%s:sTrEaM3", d3);
228 5 : torture_assert_not_null(tctx, d3s, "d3s");
229 5 : d3sl = strlower_talloc(tctx, d3s);
230 5 : torture_assert_not_null(tctx, d3sl, "d3sl");
231 5 : d3su = strupper_talloc(tctx, d3s);
232 5 : torture_assert_not_null(tctx, d3su, "d3su");
233 5 : d3sd = talloc_asprintf(tctx, "%s:$DaTa", d3s);
234 5 : torture_assert_not_null(tctx, d3sd, "d3sd");
235 :
236 5 : f4 = talloc_asprintf(tctx, "%s\\fIlE4NaMe", d3);
237 5 : torture_assert_not_null(tctx, f4, "f4");
238 5 : f4l = strlower_talloc(tctx, f4);
239 5 : torture_assert_not_null(tctx, f4l, "f4l");
240 5 : f4u = strupper_talloc(tctx, f4);
241 5 : torture_assert_not_null(tctx, f4u, "f4u");
242 5 : f4d = talloc_asprintf(tctx, "%s::$dAtA", f4);
243 5 : torture_assert_not_null(tctx, f4d, "f4d");
244 :
245 5 : f4s = talloc_asprintf(tctx, "%s:StReAm4", f4);
246 5 : torture_assert_not_null(tctx, f4s, "f4s");
247 5 : f4sl = strlower_talloc(tctx, f4s);
248 5 : torture_assert_not_null(tctx, f4sl, "f4sl");
249 5 : f4su = strupper_talloc(tctx, f4s);
250 5 : torture_assert_not_null(tctx, f4su, "f4su");
251 5 : f4sd = talloc_asprintf(tctx, "%s:$dAtA", f4s);
252 5 : torture_assert_not_null(tctx, f4sd, "f4sd");
253 :
254 5 : status = smb2_util_roothandle(tree, &hroot);
255 5 : torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
256 :
257 5 : info.normalized_name_info.in.file.handle = hroot;
258 5 : ZERO_STRUCT(info.normalized_name_info.out);
259 5 : status = smb2_getinfo_file(tree, tree, &info);
260 5 : if (protocol < PROTOCOL_SMB3_11) {
261 : /*
262 : * Only SMB 3.1.1 and above should offer this.
263 : */
264 1 : torture_assert_ntstatus_equal(tctx, status,
265 : NT_STATUS_NOT_SUPPORTED,
266 : "getinfo hroot");
267 1 : torture_skip(tctx, "SMB 3.1.1 not supported");
268 : }
269 4 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
270 : /*
271 : * Not all servers support this.
272 : * (only Windows 10 1803 and higher)
273 : */
274 0 : torture_skip(tctx, "NORMALIZED_NAME_INFORMATION not supported");
275 : }
276 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hroot");
277 4 : torture_assert(tctx, info.normalized_name_info.out.fname.s == NULL,
278 : "getinfo hroot should be empty");
279 :
280 4 : smb2_deltree(tree, d1);
281 :
282 4 : status = torture_smb2_testdir(tree, d1, &hd1);
283 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hd1");
284 4 : status = torture_smb2_open(tree, d1l, SEC_RIGHTS_FILE_ALL, &hd1l);
285 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1l");
286 4 : status = torture_smb2_open(tree, d1u, SEC_RIGHTS_FILE_ALL, &hd1u);
287 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1u");
288 :
289 4 : status = torture_smb2_testdir(tree, d2, &hd2);
290 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hd2");
291 4 : status = torture_smb2_open(tree, d2l, SEC_RIGHTS_FILE_ALL, &hd2l);
292 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2l");
293 4 : status = torture_smb2_open(tree, d2u, SEC_RIGHTS_FILE_ALL, &hd2u);
294 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2u");
295 :
296 4 : status = torture_smb2_testdir(tree, d3, &hd3);
297 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3");
298 4 : status = torture_smb2_open(tree, d3l, SEC_RIGHTS_FILE_ALL, &hd3l);
299 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3l");
300 4 : status = torture_smb2_open(tree, d3u, SEC_RIGHTS_FILE_ALL, &hd3u);
301 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3u");
302 :
303 4 : status = torture_smb2_testfile(tree, d3s, &hd3s);
304 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3s");
305 4 : status = torture_smb2_open(tree, d3sl, SEC_RIGHTS_FILE_ALL, &hd3sl);
306 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sl");
307 4 : status = torture_smb2_open(tree, d3su, SEC_RIGHTS_FILE_ALL, &hd3su);
308 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3su");
309 4 : status = torture_smb2_open(tree, d3sd, SEC_RIGHTS_FILE_ALL, &hd3sd);
310 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sd");
311 :
312 4 : status = torture_smb2_testfile(tree, f4, &hf4);
313 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4");
314 4 : status = torture_smb2_open(tree, f4l, SEC_RIGHTS_FILE_ALL, &hf4l);
315 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4l");
316 4 : status = torture_smb2_open(tree, f4u, SEC_RIGHTS_FILE_ALL, &hf4u);
317 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4u");
318 4 : status = torture_smb2_open(tree, f4d, SEC_RIGHTS_FILE_ALL, &hf4d);
319 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4d");
320 :
321 4 : status = torture_smb2_testfile(tree, f4s, &hf4s);
322 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4s");
323 4 : status = torture_smb2_open(tree, f4sl, SEC_RIGHTS_FILE_ALL, &hf4sl);
324 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sl");
325 4 : status = torture_smb2_open(tree, f4su, SEC_RIGHTS_FILE_ALL, &hf4su);
326 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4su");
327 4 : status = torture_smb2_open(tree, f4sd, SEC_RIGHTS_FILE_ALL, &hf4sd);
328 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sd");
329 :
330 4 : info.normalized_name_info.in.file.handle = hd1;
331 4 : ZERO_STRUCT(info.normalized_name_info.out);
332 4 : status = smb2_getinfo_file(tree, tree, &info);
333 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd1");
334 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
335 : d1, "getinfo hd1");
336 4 : info.normalized_name_info.in.file.handle = hd1l;
337 4 : ZERO_STRUCT(info.normalized_name_info.out);
338 4 : status = smb2_getinfo_file(tree, tree, &info);
339 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd1l");
340 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
341 : d1, "getinfo hd1l");
342 4 : info.normalized_name_info.in.file.handle = hd1u;
343 4 : ZERO_STRUCT(info.normalized_name_info.out);
344 4 : status = smb2_getinfo_file(tree, tree, &info);
345 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd1u");
346 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
347 : d1, "getinfo hd1u");
348 :
349 4 : info.normalized_name_info.in.file.handle = hd2;
350 4 : ZERO_STRUCT(info.normalized_name_info.out);
351 4 : status = smb2_getinfo_file(tree, tree, &info);
352 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd2");
353 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
354 : d2, "getinfo hd2");
355 4 : info.normalized_name_info.in.file.handle = hd2l;
356 4 : ZERO_STRUCT(info.normalized_name_info.out);
357 4 : status = smb2_getinfo_file(tree, tree, &info);
358 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd2l");
359 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
360 : d2, "getinfo hd2l");
361 4 : info.normalized_name_info.in.file.handle = hd2u;
362 4 : ZERO_STRUCT(info.normalized_name_info.out);
363 4 : status = smb2_getinfo_file(tree, tree, &info);
364 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd2u");
365 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
366 : d2, "getinfo hd2u");
367 :
368 4 : info.normalized_name_info.in.file.handle = hd3;
369 4 : ZERO_STRUCT(info.normalized_name_info.out);
370 4 : status = smb2_getinfo_file(tree, tree, &info);
371 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3");
372 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
373 : d3, "getinfo hd3");
374 4 : info.normalized_name_info.in.file.handle = hd3l;
375 4 : ZERO_STRUCT(info.normalized_name_info.out);
376 4 : status = smb2_getinfo_file(tree, tree, &info);
377 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3l");
378 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
379 : d3, "getinfo hd3l");
380 4 : info.normalized_name_info.in.file.handle = hd3u;
381 4 : ZERO_STRUCT(info.normalized_name_info.out);
382 4 : status = smb2_getinfo_file(tree, tree, &info);
383 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3u");
384 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
385 : d3, "getinfo hd3u");
386 :
387 4 : info.normalized_name_info.in.file.handle = hd3s;
388 4 : ZERO_STRUCT(info.normalized_name_info.out);
389 4 : status = smb2_getinfo_file(tree, tree, &info);
390 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3s");
391 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
392 : d3s, "getinfo hd3s");
393 4 : info.normalized_name_info.in.file.handle = hd3sl;
394 4 : ZERO_STRUCT(info.normalized_name_info.out);
395 4 : status = smb2_getinfo_file(tree, tree, &info);
396 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sl");
397 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
398 : d3s, "getinfo hd3sl");
399 4 : info.normalized_name_info.in.file.handle = hd3su;
400 4 : ZERO_STRUCT(info.normalized_name_info.out);
401 4 : status = smb2_getinfo_file(tree, tree, &info);
402 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3su");
403 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
404 : d3s, "getinfo hd3su");
405 4 : info.normalized_name_info.in.file.handle = hd3sd;
406 4 : ZERO_STRUCT(info.normalized_name_info.out);
407 4 : status = smb2_getinfo_file(tree, tree, &info);
408 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hd3sd");
409 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
410 : d3s, "getinfo hd3sd");
411 :
412 4 : info.normalized_name_info.in.file.handle = hf4;
413 4 : ZERO_STRUCT(info.normalized_name_info.out);
414 4 : status = smb2_getinfo_file(tree, tree, &info);
415 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4");
416 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
417 : f4, "getinfo hf4");
418 4 : info.normalized_name_info.in.file.handle = hf4l;
419 4 : ZERO_STRUCT(info.normalized_name_info.out);
420 4 : status = smb2_getinfo_file(tree, tree, &info);
421 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4l");
422 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
423 : f4, "getinfo hf4l");
424 4 : info.normalized_name_info.in.file.handle = hf4u;
425 4 : ZERO_STRUCT(info.normalized_name_info.out);
426 4 : status = smb2_getinfo_file(tree, tree, &info);
427 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4u");
428 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
429 : f4, "getinfo hf4u");
430 4 : info.normalized_name_info.in.file.handle = hf4d;
431 4 : ZERO_STRUCT(info.normalized_name_info.out);
432 4 : status = smb2_getinfo_file(tree, tree, &info);
433 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4d");
434 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
435 : f4, "getinfo hf4d");
436 :
437 4 : info.normalized_name_info.in.file.handle = hf4s;
438 4 : ZERO_STRUCT(info.normalized_name_info.out);
439 4 : status = smb2_getinfo_file(tree, tree, &info);
440 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4s");
441 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
442 : f4s, "getinfo hf4s");
443 4 : info.normalized_name_info.in.file.handle = hf4sl;
444 4 : ZERO_STRUCT(info.normalized_name_info.out);
445 4 : status = smb2_getinfo_file(tree, tree, &info);
446 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sl");
447 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
448 : f4s, "getinfo hf4sl");
449 4 : info.normalized_name_info.in.file.handle = hf4su;
450 4 : ZERO_STRUCT(info.normalized_name_info.out);
451 4 : status = smb2_getinfo_file(tree, tree, &info);
452 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4su");
453 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
454 : f4s, "getinfo hf4su");
455 4 : info.normalized_name_info.in.file.handle = hf4sd;
456 4 : ZERO_STRUCT(info.normalized_name_info.out);
457 4 : status = smb2_getinfo_file(tree, tree, &info);
458 4 : torture_assert_ntstatus_ok(tctx, status, "getinfo hf4sd");
459 4 : torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s,
460 : f4s, "getinfo hf4sd");
461 :
462 : /* Set max protocol to SMB 3.0.2 */
463 4 : options3_0 = tree->session->transport->options;
464 4 : options3_0.max_protocol = PROTOCOL_SMB3_02;
465 4 : options3_0.client_guid = GUID_zero();
466 4 : ret = torture_smb2_connection_ext(tctx, 0, &options3_0, &tree_3_0);
467 4 : torture_assert(tctx, ret, "connection with SMB < 3.1.1 failed");
468 :
469 4 : status = smb2_util_roothandle(tree_3_0, &hroot_3_0);
470 4 : torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle 3_0");
471 :
472 4 : info.normalized_name_info.in.file.handle = hroot_3_0;
473 4 : ZERO_STRUCT(info.normalized_name_info.out);
474 4 : status = smb2_getinfo_file(tree_3_0, tree_3_0, &info);
475 4 : torture_assert_ntstatus_equal(tctx, status,
476 : NT_STATUS_NOT_SUPPORTED,
477 : "getinfo hroot");
478 :
479 4 : return true;
480 : }
481 :
482 : /*
483 : test fsinfo levels
484 : */
485 5 : static bool torture_smb2_fsinfo(struct torture_context *tctx)
486 : {
487 : bool ret;
488 : struct smb2_tree *tree;
489 : int i;
490 : NTSTATUS status;
491 : struct smb2_handle handle;
492 :
493 5 : torture_comment(tctx, "Testing fsinfo levels\n");
494 :
495 5 : ret = torture_smb2_connection(tctx, &tree);
496 5 : torture_assert(tctx, ret, "connection failed");
497 :
498 5 : status = smb2_util_roothandle(tree, &handle);
499 5 : torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle");
500 :
501 29 : for (i=0;i<ARRAY_SIZE(fs_levels);i++) {
502 28 : fs_levels[i].info.generic.level = fs_levels[i].level;
503 28 : fs_levels[i].info.generic.handle = handle;
504 28 : fs_levels[i].status = smb2_getinfo_fs(tree, tree, &fs_levels[i].info);
505 28 : torture_assert_ntstatus_ok(tctx, fs_levels[i].status,
506 : fs_levels[i].name);
507 : }
508 :
509 1 : return true;
510 : }
511 :
512 84 : static bool torture_smb2_buffercheck_err(struct torture_context *tctx,
513 : struct smb2_tree *tree,
514 : struct smb2_getinfo *b,
515 : size_t fixed,
516 : DATA_BLOB full)
517 : {
518 : size_t i;
519 :
520 2286 : for (i=0; i<=full.length; i++) {
521 : NTSTATUS status;
522 :
523 2204 : b->in.output_buffer_length = i;
524 :
525 2204 : status = smb2_getinfo(tree, tree, b);
526 :
527 2204 : if (i < fixed) {
528 1928 : torture_assert_ntstatus_equal(
529 : tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH,
530 : "Wrong error code small buffer");
531 3632 : continue;
532 : }
533 :
534 276 : if (i<full.length) {
535 194 : torture_assert_ntstatus_equal(
536 : tctx, status, STATUS_BUFFER_OVERFLOW,
537 : "Wrong error code for large buffer");
538 : /*
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.
543 : */
544 192 : TALLOC_FREE(b->out.blob.data);
545 192 : continue;
546 : }
547 :
548 82 : torture_assert_ntstatus_equal(
549 : tctx, status, NT_STATUS_OK,
550 : "Wrong error code for right sized buffer");
551 : }
552 :
553 82 : return true;
554 : }
555 :
556 : struct level_buffersize {
557 : int level;
558 : size_t fixed;
559 : };
560 :
561 5 : static bool torture_smb2_qfs_buffercheck(struct torture_context *tctx)
562 : {
563 : bool ret;
564 : struct smb2_tree *tree;
565 : NTSTATUS status;
566 : struct smb2_handle handle;
567 : int i;
568 :
569 5 : struct level_buffersize levels[] = {
570 : { 1, 24 }, /* We don't have proper defines here */
571 : { 3, 24 },
572 : { 4, 8 },
573 : { 5, 16 },
574 : { 6, 48 },
575 : { 7, 32 },
576 : { 11, 28 },
577 : };
578 :
579 5 : torture_comment(tctx, "Testing SMB2_GETINFO_FS buffer sizes\n");
580 :
581 5 : ret = torture_smb2_connection(tctx, &tree);
582 5 : torture_assert(tctx, ret, "connection failed");
583 :
584 5 : status = smb2_util_roothandle(tree, &handle);
585 5 : torture_assert_ntstatus_ok(
586 : tctx, status, "Unable to create root handle");
587 :
588 36 : for (i=0; i<ARRAY_SIZE(levels); i++) {
589 : struct smb2_getinfo b;
590 :
591 53 : if (TARGET_IS_SAMBA3(tctx) &&
592 46 : ((levels[i].level == 6) || (levels[i].level == 11))) {
593 8 : continue;
594 : }
595 :
596 24 : ZERO_STRUCT(b);
597 24 : b.in.info_type = SMB2_0_INFO_FILESYSTEM;
598 24 : b.in.info_class = levels[i].level;
599 24 : b.in.file.handle = handle;
600 24 : b.in.output_buffer_length = 65535;
601 :
602 24 : status = smb2_getinfo(tree, tree, &b);
603 :
604 24 : torture_assert_ntstatus_equal(
605 : tctx, status, NT_STATUS_OK,
606 : "Wrong error code for large buffer");
607 :
608 24 : ret = torture_smb2_buffercheck_err(
609 : tctx, tree, &b, levels[i].fixed, b.out.blob);
610 24 : if (!ret) {
611 1 : return ret;
612 : }
613 : }
614 :
615 4 : return true;
616 : }
617 :
618 5 : static bool torture_smb2_qfile_buffercheck(struct torture_context *tctx)
619 : {
620 : bool ret;
621 : struct smb2_tree *tree;
622 : struct smb2_create c;
623 : NTSTATUS status;
624 : struct smb2_handle handle;
625 : int i;
626 :
627 5 : struct level_buffersize levels[] = {
628 : { 4, 40 },
629 : { 5, 24 },
630 : { 6, 8 },
631 : { 7, 4 },
632 : { 8, 4 },
633 : { 16, 4 },
634 : { 17, 4 },
635 : { 18, 104 },
636 : { 21, 8 },
637 : { 22, 32 },
638 : { 28, 16 },
639 : { 34, 56 },
640 : { 35, 8 },
641 : };
642 :
643 5 : torture_comment(tctx, "Testing SMB2_GETINFO_FILE buffer sizes\n");
644 :
645 5 : ret = torture_smb2_connection(tctx, &tree);
646 5 : torture_assert(tctx, ret, "connection failed");
647 :
648 5 : ZERO_STRUCT(c);
649 5 : c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
650 5 : c.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
651 5 : c.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
652 5 : c.in.share_access =
653 : NTCREATEX_SHARE_ACCESS_DELETE|
654 : NTCREATEX_SHARE_ACCESS_READ|
655 : NTCREATEX_SHARE_ACCESS_WRITE;
656 5 : c.in.create_options = 0;
657 5 : c.in.fname = "bufsize.txt";
658 :
659 5 : c.in.eas.num_eas = 2;
660 5 : c.in.eas.eas = talloc_array(tree, struct ea_struct, 2);
661 5 : c.in.eas.eas[0].flags = 0;
662 5 : c.in.eas.eas[0].name.s = "EAONE";
663 5 : c.in.eas.eas[0].value = data_blob_talloc(c.in.eas.eas, "VALUE1", 6);
664 5 : c.in.eas.eas[1].flags = 0;
665 5 : c.in.eas.eas[1].name.s = "SECONDEA";
666 5 : c.in.eas.eas[1].value = data_blob_talloc(c.in.eas.eas, "ValueTwo", 8);
667 :
668 5 : status = smb2_create(tree, tree, &c);
669 5 : torture_assert_ntstatus_ok(
670 : tctx, status, "Unable to create test file");
671 :
672 5 : handle = c.out.file.handle;
673 :
674 64 : for (i=0; i<ARRAY_SIZE(levels); i++) {
675 : struct smb2_getinfo b;
676 :
677 60 : ZERO_STRUCT(b);
678 60 : b.in.info_type = SMB2_0_INFO_FILE;
679 60 : b.in.info_class = levels[i].level;
680 60 : b.in.file.handle = handle;
681 60 : b.in.output_buffer_length = 65535;
682 :
683 60 : status = smb2_getinfo(tree, tree, &b);
684 60 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
685 0 : continue;
686 : }
687 60 : torture_assert_ntstatus_equal(
688 : tctx, status, NT_STATUS_OK,
689 : "Wrong error code for large buffer");
690 :
691 60 : ret = torture_smb2_buffercheck_err(
692 : tctx, tree, &b, levels[i].fixed, b.out.blob);
693 60 : if (!ret) {
694 1 : return ret;
695 : }
696 : }
697 4 : return true;
698 : }
699 :
700 5 : static bool torture_smb2_qsec_buffercheck(struct torture_context *tctx)
701 : {
702 : struct smb2_getinfo b;
703 : bool ret;
704 : struct smb2_tree *tree;
705 : struct smb2_create c;
706 : NTSTATUS status;
707 : struct smb2_handle handle;
708 :
709 5 : torture_comment(tctx, "Testing SMB2_GETINFO_SECURITY buffer sizes\n");
710 :
711 5 : ret = torture_smb2_connection(tctx, &tree);
712 5 : torture_assert(tctx, ret, "connection failed");
713 :
714 5 : ZERO_STRUCT(c);
715 5 : c.in.oplock_level = 0;
716 5 : c.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE |
717 : SEC_DIR_LIST | SEC_STD_READ_CONTROL;
718 5 : c.in.file_attributes = 0;
719 5 : c.in.create_disposition = NTCREATEX_DISP_OPEN;
720 5 : c.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
721 : NTCREATEX_SHARE_ACCESS_DELETE;
722 5 : c.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
723 5 : c.in.fname = "";
724 :
725 5 : status = smb2_create(tree, tree, &c);
726 5 : torture_assert_ntstatus_ok(
727 : tctx, status, "Unable to create root handle");
728 :
729 5 : handle = c.out.file.handle;
730 :
731 5 : ZERO_STRUCT(b);
732 5 : b.in.info_type = SMB2_0_INFO_SECURITY;
733 5 : b.in.info_class = 0;
734 5 : b.in.file.handle = handle;
735 5 : b.in.output_buffer_length = 0;
736 :
737 5 : status = smb2_getinfo(tree, tree, &b);
738 5 : torture_assert_ntstatus_equal(
739 : tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
740 : "Wrong error code for large buffer");
741 :
742 4 : b.in.output_buffer_length = 1;
743 4 : status = smb2_getinfo(tree, tree, &b);
744 4 : torture_assert_ntstatus_equal(
745 : tctx, status, NT_STATUS_BUFFER_TOO_SMALL,
746 : "Wrong error code for large buffer");
747 :
748 4 : return true;
749 : }
750 :
751 : /* basic testing of all SMB2 getinfo levels
752 : */
753 5 : static bool torture_smb2_getinfo(struct torture_context *tctx)
754 : {
755 : struct smb2_tree *tree;
756 5 : bool ret = true;
757 : NTSTATUS status;
758 :
759 5 : ret = torture_smb2_connection(tctx, &tree);
760 5 : torture_assert(tctx, ret, "connection failed");
761 :
762 5 : smb2_deltree(tree, FNAME);
763 5 : smb2_deltree(tree, DNAME);
764 :
765 5 : status = torture_setup_complex_file(tctx, tree, FNAME);
766 5 : torture_assert_ntstatus_ok(tctx, status,
767 : "setup complex file " FNAME);
768 :
769 1 : status = torture_setup_complex_file(tctx, tree, FNAME ":streamtwo");
770 1 : torture_assert_ntstatus_ok(tctx, status,
771 : "setup complex file " FNAME ":streamtwo");
772 :
773 1 : status = torture_setup_complex_dir(tctx, tree, DNAME);
774 1 : torture_assert_ntstatus_ok(tctx, status,
775 : "setup complex dir " DNAME);
776 :
777 1 : status = torture_setup_complex_file(tctx, tree, DNAME ":streamtwo");
778 1 : torture_assert_ntstatus_ok(tctx, status,
779 : "setup complex dir " DNAME ":streamtwo");
780 :
781 0 : ret &= torture_smb2_fileinfo(tctx, tree);
782 :
783 0 : return ret;
784 : }
785 :
786 2355 : struct torture_suite *torture_smb2_getinfo_init(TALLOC_CTX *ctx)
787 : {
788 2355 : struct torture_suite *suite = torture_suite_create(
789 : ctx, "getinfo");
790 :
791 2355 : torture_suite_add_simple_test(suite, "complex", torture_smb2_getinfo);
792 2355 : torture_suite_add_simple_test(suite, "fsinfo", torture_smb2_fsinfo);
793 2355 : torture_suite_add_simple_test(suite, "qfs_buffercheck",
794 : torture_smb2_qfs_buffercheck);
795 2355 : torture_suite_add_simple_test(suite, "qfile_buffercheck",
796 : torture_smb2_qfile_buffercheck);
797 2355 : torture_suite_add_simple_test(suite, "qsec_buffercheck",
798 : torture_smb2_qsec_buffercheck);
799 2355 : torture_suite_add_simple_test(suite, "granted",
800 : torture_smb2_fileinfo_grant_read);
801 2355 : torture_suite_add_simple_test(suite, "normalized",
802 : torture_smb2_fileinfo_normalized);
803 2355 : return suite;
804 : }
|