ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / smb2 / getinfo.c
blob539090ac71abdc1a30e9477daa14b3353050f0b7
1 /*
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/>.
22 #include "includes.h"
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"
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) },
55 { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
57 { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
58 { LEVEL(RAW_FILEINFO_SEC_DESC) }
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) },
77 #define FNAME "testsmb2_file.dat"
78 #define DNAME "testsmb2_dir"
81 test fileinfo levels
83 static bool torture_smb2_fileinfo(struct torture_context *tctx, struct smb2_tree *tree)
85 struct smb2_handle hfile, hdir;
86 NTSTATUS status;
87 int i;
89 status = torture_smb2_testfile(tree, FNAME, &hfile);
90 torture_assert_ntstatus_ok(tctx, status, "Unable to create test file "
91 FNAME "\n");
93 status = torture_smb2_testdir(tree, DNAME, &hdir);
94 torture_assert_ntstatus_ok(tctx, status, "Unable to create test dir "
95 DNAME "\n");
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));
126 return true;
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;
136 bool ret;
137 struct smb2_handle hfile, hdir;
138 NTSTATUS status;
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");
148 status =
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");
161 status =
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);
170 return true;
173 static bool torture_smb2_fileinfo_normalized(struct torture_context *tctx)
175 struct smb2_tree *tree = NULL;
176 bool ret;
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,
195 NTSTATUS status;
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,
266 "getinfo hroot");
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,
335 d1, "getinfo hd1");
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,
341 d1, "getinfo hd1l");
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,
347 d1, "getinfo hd1u");
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,
354 d2, "getinfo hd2");
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,
360 d2, "getinfo hd2l");
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,
366 d2, "getinfo hd2u");
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,
373 d3, "getinfo hd3");
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,
379 d3, "getinfo hd3l");
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,
385 d3, "getinfo hd3u");
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,
417 f4, "getinfo hf4");
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,
423 f4, "getinfo hf4l");
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,
429 f4, "getinfo hf4u");
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,
435 f4, "getinfo hf4d");
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,
477 "getinfo hroot");
479 return true;
483 test fsinfo levels
485 static bool torture_smb2_fsinfo(struct torture_context *tctx)
487 bool ret;
488 struct smb2_tree *tree;
489 int i;
490 NTSTATUS status;
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,
506 fs_levels[i].name);
509 return true;
512 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)
518 size_t i;
520 for (i=0; i<=full.length; i++) {
521 NTSTATUS status;
523 b->in.output_buffer_length = i;
525 status = smb2_getinfo(tree, tree, b);
527 if (i < fixed) {
528 torture_assert_ntstatus_equal(
529 tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH,
530 "Wrong error code small buffer");
531 continue;
534 if (i<full.length) {
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);
545 continue;
548 torture_assert_ntstatus_equal(
549 tctx, status, NT_STATUS_OK,
550 "Wrong error code for right sized buffer");
553 return true;
556 struct level_buffersize {
557 int level;
558 size_t fixed;
561 static bool torture_smb2_qfs_buffercheck(struct torture_context *tctx)
563 bool ret;
564 struct smb2_tree *tree;
565 NTSTATUS status;
566 struct smb2_handle handle;
567 int i;
569 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 },
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))) {
593 continue;
596 ZERO_STRUCT(b);
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);
610 if (!ret) {
611 return ret;
615 return true;
618 static bool torture_smb2_qfile_buffercheck(struct torture_context *tctx)
620 bool ret;
621 struct smb2_tree *tree;
622 struct smb2_create c;
623 NTSTATUS status;
624 struct smb2_handle handle;
625 int i;
627 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 },
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");
648 ZERO_STRUCT(c);
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;
652 c.in.share_access =
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;
677 ZERO_STRUCT(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)) {
685 continue;
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);
693 if (!ret) {
694 return ret;
697 return true;
700 static bool torture_smb2_qsec_buffercheck(struct torture_context *tctx)
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;
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");
714 ZERO_STRUCT(c);
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;
723 c.in.fname = "";
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;
731 ZERO_STRUCT(b);
732 b.in.info_type = SMB2_0_INFO_SECURITY;
733 b.in.info_class = 0;
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");
748 return true;
751 /* basic testing of all SMB2 getinfo levels
753 static bool torture_smb2_getinfo(struct torture_context *tctx)
755 struct smb2_tree *tree;
756 bool ret = true;
757 NTSTATUS status;
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);
783 return ret;
786 #undef LEVEL
787 #define LEVEL(l, u, ua, ra) \
788 .name = #l, \
789 .level = l, \
790 .unrestricted = u, \
791 .unrestricted_access = ua, \
792 .required_access = ra
794 static struct {
795 const char *name;
796 uint16_t level;
797 bool unrestricted;
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
827 * SEC_FILE_READ_EA.
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) }
844 test fileinfo levels
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;
851 NTSTATUS status;
852 bool ret = true;
853 int i;
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
866 * this.
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;
886 } else {
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);
926 done:
927 smb2_deltree(tree, fname);
928 return ret;
931 struct torture_suite *torture_smb2_getinfo_init(TALLOC_CTX *ctx)
933 struct torture_suite *suite = torture_suite_create(
934 ctx, "getinfo");
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);
950 return suite;