ctdb-scripts: Don't set arp_filter=1 by default in 10.interface
[samba4-gss.git] / source4 / libcli / raw / rawfileinfo.c
blobc8b0ec74c6fa02d030ec4aa5c4e032612db7e92b
1 /*
2 Unix SMB/CIFS implementation.
3 client trans2 operations
4 Copyright (C) James Myers 2003
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) James Peach 2007
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/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "librpc/gen_ndr/ndr_security.h"
27 /* local macros to make the code more readable */
28 #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \
29 DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \
30 (int)blob->length, parms->generic.level, (size))); \
31 return NT_STATUS_INFO_LENGTH_MISMATCH; \
33 #define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \
34 DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \
35 (int)blob->length, parms->generic.level, (size))); \
36 return NT_STATUS_INFO_LENGTH_MISMATCH; \
40 parse a stream information structure
42 NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
43 struct stream_information *io)
45 uint32_t ofs = 0;
46 io->num_streams = 0;
47 io->streams = NULL;
49 while (blob.length - ofs >= 24) {
50 unsigned int n = io->num_streams;
51 uint32_t nlen, len;
52 bool ret;
53 void *vstr;
54 size_t converted_size = 0;
56 io->streams =
57 talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1);
58 if (!io->streams) {
59 return NT_STATUS_NO_MEMORY;
61 nlen = IVAL(blob.data, ofs + 0x04);
62 io->streams[n].size = BVAL(blob.data, ofs + 0x08);
63 io->streams[n].alloc_size = BVAL(blob.data, ofs + 0x10);
64 if (nlen > blob.length - (ofs + 24)) {
65 return NT_STATUS_INFO_LENGTH_MISMATCH;
67 ret = convert_string_talloc(io->streams,
68 CH_UTF16, CH_UNIX,
69 blob.data+ofs+24, nlen, &vstr, &converted_size);
70 if (!ret) {
71 return NT_STATUS_ILLEGAL_CHARACTER;
73 io->streams[n].stream_name.s = (const char *)vstr;
74 io->streams[n].stream_name.private_length = nlen;
75 io->num_streams++;
76 len = IVAL(blob.data, ofs);
77 if (len > blob.length - ofs) {
78 return NT_STATUS_INFO_LENGTH_MISMATCH;
80 if (len == 0) break;
81 ofs += len;
84 return NT_STATUS_OK;
88 parse the fsinfo 'passthru' level replies
90 NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
91 enum smb_fileinfo_level level,
92 union smb_fileinfo *parms)
94 switch (level) {
95 case RAW_FILEINFO_BASIC_INFORMATION:
96 /* some servers return 40 bytes and some 36. w2k3 return 40, so that's
97 what we should do, but we need to accept 36 */
98 if (blob->length != 36) {
99 FINFO_CHECK_SIZE(40);
101 parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
102 parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
103 parms->basic_info.out.write_time = smbcli_pull_nttime(blob->data, 16);
104 parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
105 parms->basic_info.out.attrib = IVAL(blob->data, 32);
106 return NT_STATUS_OK;
108 case RAW_FILEINFO_STANDARD_INFORMATION:
109 FINFO_CHECK_SIZE(24);
110 parms->standard_info.out.alloc_size = BVAL(blob->data, 0);
111 parms->standard_info.out.size = BVAL(blob->data, 8);
112 parms->standard_info.out.nlink = IVAL(blob->data, 16);
113 parms->standard_info.out.delete_pending = CVAL(blob->data, 20);
114 parms->standard_info.out.directory = CVAL(blob->data, 21);
115 return NT_STATUS_OK;
117 case RAW_FILEINFO_EA_INFORMATION:
118 FINFO_CHECK_SIZE(4);
119 parms->ea_info.out.ea_size = IVAL(blob->data, 0);
120 return NT_STATUS_OK;
122 case RAW_FILEINFO_NAME_INFORMATION:
123 FINFO_CHECK_MIN_SIZE(4);
124 smbcli_blob_pull_string(NULL, mem_ctx, blob,
125 &parms->name_info.out.fname, 0, 4, STR_UNICODE);
126 return NT_STATUS_OK;
128 case RAW_FILEINFO_ALL_INFORMATION:
129 FINFO_CHECK_MIN_SIZE(72);
130 parms->all_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
131 parms->all_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
132 parms->all_info.out.write_time = smbcli_pull_nttime(blob->data, 16);
133 parms->all_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
134 parms->all_info.out.attrib = IVAL(blob->data, 32);
135 parms->all_info.out.alloc_size = BVAL(blob->data, 40);
136 parms->all_info.out.size = BVAL(blob->data, 48);
137 parms->all_info.out.nlink = IVAL(blob->data, 56);
138 parms->all_info.out.delete_pending = CVAL(blob->data, 60);
139 parms->all_info.out.directory = CVAL(blob->data, 61);
140 #if 1
141 parms->all_info.out.ea_size = IVAL(blob->data, 64);
142 smbcli_blob_pull_string(NULL, mem_ctx, blob,
143 &parms->all_info.out.fname, 68, 72, STR_UNICODE);
144 #else
145 /* this is what the CIFS spec says - and its totally
146 wrong, but its useful having it here so we can
147 quickly adapt to broken servers when running
148 tests */
149 parms->all_info.out.ea_size = IVAL(blob->data, 72);
150 /* access flags 4 bytes at 76
151 current_position 8 bytes at 80
152 mode 4 bytes at 88
153 alignment 4 bytes at 92
155 smbcli_blob_pull_string(NULL, mem_ctx, blob,
156 &parms->all_info.out.fname, 96, 100, STR_UNICODE);
157 #endif
158 return NT_STATUS_OK;
160 case RAW_FILEINFO_ALT_NAME_INFORMATION:
161 case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION:
162 FINFO_CHECK_MIN_SIZE(4);
163 smbcli_blob_pull_string(NULL, mem_ctx, blob,
164 &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE);
165 return NT_STATUS_OK;
167 case RAW_FILEINFO_STREAM_INFORMATION:
168 return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out);
170 case RAW_FILEINFO_INTERNAL_INFORMATION:
171 FINFO_CHECK_SIZE(8);
172 parms->internal_information.out.file_id = BVAL(blob->data, 0);
173 return NT_STATUS_OK;
175 case RAW_FILEINFO_ACCESS_INFORMATION:
176 FINFO_CHECK_SIZE(4);
177 parms->access_information.out.access_flags = IVAL(blob->data, 0);
178 return NT_STATUS_OK;
180 case RAW_FILEINFO_POSITION_INFORMATION:
181 FINFO_CHECK_SIZE(8);
182 parms->position_information.out.position = BVAL(blob->data, 0);
183 return NT_STATUS_OK;
185 case RAW_FILEINFO_MODE_INFORMATION:
186 FINFO_CHECK_SIZE(4);
187 parms->mode_information.out.mode = IVAL(blob->data, 0);
188 return NT_STATUS_OK;
190 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
191 FINFO_CHECK_SIZE(4);
192 parms->alignment_information.out.alignment_requirement
193 = IVAL(blob->data, 0);
194 return NT_STATUS_OK;
196 case RAW_FILEINFO_COMPRESSION_INFORMATION:
197 FINFO_CHECK_SIZE(16);
198 parms->compression_info.out.compressed_size = BVAL(blob->data, 0);
199 parms->compression_info.out.format = SVAL(blob->data, 8);
200 parms->compression_info.out.unit_shift = CVAL(blob->data, 10);
201 parms->compression_info.out.chunk_shift = CVAL(blob->data, 11);
202 parms->compression_info.out.cluster_shift = CVAL(blob->data, 12);
203 /* 3 bytes of padding */
204 return NT_STATUS_OK;
206 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
207 FINFO_CHECK_SIZE(56);
208 parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0);
209 parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8);
210 parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16);
211 parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24);
212 parms->network_open_information.out.alloc_size = BVAL(blob->data, 32);
213 parms->network_open_information.out.size = BVAL(blob->data, 40);
214 parms->network_open_information.out.attrib = IVAL(blob->data, 48);
215 return NT_STATUS_OK;
217 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
218 FINFO_CHECK_SIZE(8);
219 parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0);
220 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
221 return NT_STATUS_OK;
223 case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION:
224 FINFO_CHECK_MIN_SIZE(4);
225 smbcli_blob_pull_string(NULL, mem_ctx, blob,
226 &parms->normalized_name_info.out.fname,
227 0, 4, STR_UNICODE);
228 return NT_STATUS_OK;
230 case RAW_FILEINFO_SMB2_ALL_EAS:
231 FINFO_CHECK_MIN_SIZE(4);
232 return ea_pull_list_chained(blob, mem_ctx,
233 &parms->all_eas.out.num_eas,
234 &parms->all_eas.out.eas);
236 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
237 FINFO_CHECK_MIN_SIZE(0x64);
238 parms->all_info2.out.create_time = smbcli_pull_nttime(blob->data, 0x00);
239 parms->all_info2.out.access_time = smbcli_pull_nttime(blob->data, 0x08);
240 parms->all_info2.out.write_time = smbcli_pull_nttime(blob->data, 0x10);
241 parms->all_info2.out.change_time = smbcli_pull_nttime(blob->data, 0x18);
242 parms->all_info2.out.attrib = IVAL(blob->data, 0x20);
243 parms->all_info2.out.unknown1 = IVAL(blob->data, 0x24);
244 parms->all_info2.out.alloc_size = BVAL(blob->data, 0x28);
245 parms->all_info2.out.size = BVAL(blob->data, 0x30);
246 parms->all_info2.out.nlink = IVAL(blob->data, 0x38);
247 parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
248 parms->all_info2.out.directory = CVAL(blob->data, 0x3D);
249 /* 0x3E-0x3F padding */
250 parms->all_info2.out.file_id = BVAL(blob->data, 0x40);
251 parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
252 parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
253 parms->all_info2.out.position = BVAL(blob->data, 0x50);
254 parms->all_info2.out.mode = IVAL(blob->data, 0x58);
255 parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
256 smbcli_blob_pull_string(NULL, mem_ctx, blob,
257 &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
258 return NT_STATUS_OK;
260 case RAW_FILEINFO_SEC_DESC: {
261 enum ndr_err_code ndr_err;
263 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
264 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
266 ndr_err = ndr_pull_struct_blob(blob, mem_ctx,
267 parms->query_secdesc.out.sd,
268 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
269 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
270 return ndr_map_error2ntstatus(ndr_err);
273 return NT_STATUS_OK;
276 default:
277 break;
280 return NT_STATUS_INVALID_LEVEL;
284 /****************************************************************************
285 Handle qfileinfo/qpathinfo trans2 backend.
286 ****************************************************************************/
287 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
288 TALLOC_CTX *mem_ctx,
289 union smb_fileinfo *parms,
290 DATA_BLOB *blob)
292 switch (parms->generic.level) {
293 case RAW_FILEINFO_GENERIC:
294 case RAW_FILEINFO_GETATTR:
295 case RAW_FILEINFO_GETATTRE:
296 case RAW_FILEINFO_SEC_DESC:
297 /* not handled here */
298 return NT_STATUS_INVALID_LEVEL;
300 case RAW_FILEINFO_STANDARD:
301 if (session == NULL) {
302 return NT_STATUS_INVALID_PARAMETER;
305 FINFO_CHECK_SIZE(22);
306 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
307 blob->data + 0);
308 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
309 blob->data + 4);
310 parms->standard.out.write_time = raw_pull_dos_date2(session->transport,
311 blob->data + 8);
312 parms->standard.out.size = IVAL(blob->data, 12);
313 parms->standard.out.alloc_size = IVAL(blob->data, 16);
314 parms->standard.out.attrib = SVAL(blob->data, 20);
315 return NT_STATUS_OK;
317 case RAW_FILEINFO_EA_SIZE:
318 if (session == NULL) {
319 return NT_STATUS_INVALID_PARAMETER;
322 FINFO_CHECK_SIZE(26);
323 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
324 blob->data + 0);
325 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
326 blob->data + 4);
327 parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport,
328 blob->data + 8);
329 parms->ea_size.out.size = IVAL(blob->data, 12);
330 parms->ea_size.out.alloc_size = IVAL(blob->data, 16);
331 parms->ea_size.out.attrib = SVAL(blob->data, 20);
332 parms->ea_size.out.ea_size = IVAL(blob->data, 22);
333 return NT_STATUS_OK;
335 case RAW_FILEINFO_EA_LIST:
336 FINFO_CHECK_MIN_SIZE(4);
337 return ea_pull_list(blob, mem_ctx,
338 &parms->ea_list.out.num_eas,
339 &parms->ea_list.out.eas);
341 case RAW_FILEINFO_ALL_EAS:
342 FINFO_CHECK_MIN_SIZE(4);
343 return ea_pull_list(blob, mem_ctx,
344 &parms->all_eas.out.num_eas,
345 &parms->all_eas.out.eas);
347 case RAW_FILEINFO_IS_NAME_VALID:
348 /* no data! */
349 FINFO_CHECK_SIZE(0);
350 return NT_STATUS_OK;
352 case RAW_FILEINFO_BASIC_INFO:
353 case RAW_FILEINFO_BASIC_INFORMATION:
354 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
355 RAW_FILEINFO_BASIC_INFORMATION, parms);
357 case RAW_FILEINFO_STANDARD_INFO:
358 case RAW_FILEINFO_STANDARD_INFORMATION:
359 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
360 RAW_FILEINFO_STANDARD_INFORMATION, parms);
362 case RAW_FILEINFO_EA_INFO:
363 case RAW_FILEINFO_EA_INFORMATION:
364 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
365 RAW_FILEINFO_EA_INFORMATION, parms);
367 case RAW_FILEINFO_NAME_INFO:
368 case RAW_FILEINFO_NAME_INFORMATION:
369 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
370 RAW_FILEINFO_NAME_INFORMATION, parms);
372 case RAW_FILEINFO_ALL_INFO:
373 case RAW_FILEINFO_ALL_INFORMATION:
374 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
375 RAW_FILEINFO_ALL_INFORMATION, parms);
377 case RAW_FILEINFO_ALT_NAME_INFO:
378 case RAW_FILEINFO_ALT_NAME_INFORMATION:
379 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
380 RAW_FILEINFO_ALT_NAME_INFORMATION, parms);
382 case RAW_FILEINFO_STREAM_INFO:
383 case RAW_FILEINFO_STREAM_INFORMATION:
384 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
385 RAW_FILEINFO_STREAM_INFORMATION, parms);
387 case RAW_FILEINFO_INTERNAL_INFORMATION:
388 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
389 RAW_FILEINFO_INTERNAL_INFORMATION, parms);
391 case RAW_FILEINFO_ACCESS_INFORMATION:
392 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
393 RAW_FILEINFO_ACCESS_INFORMATION, parms);
395 case RAW_FILEINFO_POSITION_INFORMATION:
396 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
397 RAW_FILEINFO_POSITION_INFORMATION, parms);
399 case RAW_FILEINFO_MODE_INFORMATION:
400 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
401 RAW_FILEINFO_MODE_INFORMATION, parms);
403 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
404 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
405 RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
407 case RAW_FILEINFO_COMPRESSION_INFO:
408 case RAW_FILEINFO_COMPRESSION_INFORMATION:
409 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
410 RAW_FILEINFO_COMPRESSION_INFORMATION, parms);
412 case RAW_FILEINFO_UNIX_BASIC:
413 FINFO_CHECK_SIZE(100);
414 parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0);
415 parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8);
416 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
417 parms->unix_basic_info.out.access_time = smbcli_pull_nttime(blob->data, 24);
418 parms->unix_basic_info.out.change_time = smbcli_pull_nttime(blob->data, 32);
419 parms->unix_basic_info.out.uid = BVAL(blob->data, 40);
420 parms->unix_basic_info.out.gid = BVAL(blob->data, 48);
421 parms->unix_basic_info.out.file_type = IVAL(blob->data, 52);
422 parms->unix_basic_info.out.dev_major = BVAL(blob->data, 60);
423 parms->unix_basic_info.out.dev_minor = BVAL(blob->data, 68);
424 parms->unix_basic_info.out.unique_id = BVAL(blob->data, 76);
425 parms->unix_basic_info.out.permissions = BVAL(blob->data, 84);
426 parms->unix_basic_info.out.nlink = BVAL(blob->data, 92);
427 return NT_STATUS_OK;
429 case RAW_FILEINFO_UNIX_INFO2:
430 FINFO_CHECK_SIZE(116);
431 parms->unix_info2.out.end_of_file = BVAL(blob->data, 0);
432 parms->unix_info2.out.num_bytes = BVAL(blob->data, 8);
433 parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
434 parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24);
435 parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32);
436 parms->unix_info2.out.uid = BVAL(blob->data, 40);
437 parms->unix_info2.out.gid = BVAL(blob->data, 48);
438 parms->unix_info2.out.file_type = IVAL(blob->data, 52);
439 parms->unix_info2.out.dev_major = BVAL(blob->data, 60);
440 parms->unix_info2.out.dev_minor = BVAL(blob->data, 68);
441 parms->unix_info2.out.unique_id = BVAL(blob->data, 76);
442 parms->unix_info2.out.permissions = BVAL(blob->data, 84);
443 parms->unix_info2.out.nlink = BVAL(blob->data, 92);
444 parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100);
445 parms->unix_info2.out.file_flags = IVAL(blob->data, 108);
446 parms->unix_info2.out.flags_mask = IVAL(blob->data, 112);
447 return NT_STATUS_OK;
449 case RAW_FILEINFO_UNIX_LINK:
450 smbcli_blob_pull_string(session, mem_ctx, blob,
451 &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
452 return NT_STATUS_OK;
454 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
455 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
456 RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
458 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
459 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
460 RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
462 case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION:
463 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
464 RAW_FILEINFO_NORMALIZED_NAME_INFORMATION, parms);
466 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
467 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
468 RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
470 case RAW_FILEINFO_SMB2_ALL_EAS:
471 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
472 RAW_FILEINFO_SMB2_ALL_EAS, parms);
474 case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION:
475 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
476 RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION, parms);
480 return NT_STATUS_INVALID_LEVEL;
484 /****************************************************************************
485 Very raw query file info - returns param/data blobs - (async send)
486 ****************************************************************************/
487 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
488 uint16_t fnum,
489 uint16_t info_level,
490 DATA_BLOB data)
492 struct smb_trans2 tp;
493 uint16_t setup = TRANSACT2_QFILEINFO;
494 struct smbcli_request *req;
495 TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
497 tp.in.max_setup = 0;
498 tp.in.flags = 0;
499 tp.in.timeout = 0;
500 tp.in.setup_count = 1;
501 tp.in.data = data;
502 tp.in.max_param = 2;
503 tp.in.max_data = 0xFFFF;
504 tp.in.setup = &setup;
506 tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
507 if (!tp.in.params.data) {
508 talloc_free(mem_ctx);
509 return NULL;
512 SSVAL(tp.in.params.data, 0, fnum);
513 SSVAL(tp.in.params.data, 2, info_level);
515 req = smb_raw_trans2_send(tree, &tp);
517 talloc_free(mem_ctx);
519 return req;
523 /****************************************************************************
524 Very raw query file info - returns param/data blobs - (async recv)
525 ****************************************************************************/
526 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
527 TALLOC_CTX *mem_ctx,
528 DATA_BLOB *blob)
530 struct smb_trans2 tp;
531 NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
532 if (NT_STATUS_IS_OK(status)) {
533 *blob = tp.out.data;
535 return status;
538 /****************************************************************************
539 Very raw query path info - returns param/data blobs (async send)
540 ****************************************************************************/
541 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
542 const char *fname,
543 uint16_t info_level,
544 DATA_BLOB data)
546 struct smb_trans2 tp;
547 uint16_t setup = TRANSACT2_QPATHINFO;
548 struct smbcli_request *req;
549 TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
551 tp.in.max_setup = 0;
552 tp.in.flags = 0;
553 tp.in.timeout = 0;
554 tp.in.setup_count = 1;
555 tp.in.data = data;
556 tp.in.max_param = 2;
557 tp.in.max_data = 0xFFFF;
558 tp.in.setup = &setup;
560 tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
561 if (!tp.in.params.data) {
562 talloc_free(mem_ctx);
563 return NULL;
566 SSVAL(tp.in.params.data, 0, info_level);
567 SIVAL(tp.in.params.data, 2, 0);
568 smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
569 fname, STR_TERMINATE);
571 req = smb_raw_trans2_send(tree, &tp);
573 talloc_free(mem_ctx);
575 return req;
578 /****************************************************************************
579 send a SMBgetatr (async send)
580 ****************************************************************************/
581 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
582 union smb_fileinfo *parms)
584 struct smbcli_request *req;
586 req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
587 if (!req) return NULL;
589 smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
591 if (!smbcli_request_send(req)) {
592 smbcli_request_destroy(req);
593 return NULL;
596 return req;
599 /****************************************************************************
600 send a SMBgetatr (async recv)
601 ****************************************************************************/
602 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
603 union smb_fileinfo *parms)
605 if (req == NULL) {
606 goto failed;
609 if (!smbcli_request_receive(req) ||
610 smbcli_request_is_error(req)) {
611 return smbcli_request_destroy(req);
614 SMBCLI_CHECK_WCT(req, 10);
615 parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0));
616 parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
617 req->in.vwv + VWV(1));
618 parms->getattr.out.size = IVAL(req->in.vwv, VWV(3));
620 failed:
621 return smbcli_request_destroy(req);
625 /****************************************************************************
626 Handle SMBgetattrE (async send)
627 ****************************************************************************/
628 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
629 union smb_fileinfo *parms)
631 struct smbcli_request *req;
633 req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
634 if (!req) return NULL;
636 SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum);
637 if (!smbcli_request_send(req)) {
638 smbcli_request_destroy(req);
639 return NULL;
642 return req;
645 /****************************************************************************
646 Handle SMBgetattrE (async send)
647 ****************************************************************************/
648 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
649 union smb_fileinfo *parms)
651 if (req == NULL) {
652 goto failed;
655 if (!smbcli_request_receive(req) ||
656 smbcli_request_is_error(req)) {
657 return smbcli_request_destroy(req);
660 SMBCLI_CHECK_WCT(req, 11);
661 parms->getattre.out.create_time = raw_pull_dos_date2(req->transport,
662 req->in.vwv + VWV(0));
663 parms->getattre.out.access_time = raw_pull_dos_date2(req->transport,
664 req->in.vwv + VWV(2));
665 parms->getattre.out.write_time = raw_pull_dos_date2(req->transport,
666 req->in.vwv + VWV(4));
667 parms->getattre.out.size = IVAL(req->in.vwv, VWV(6));
668 parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8));
669 parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10));
671 failed:
672 return smbcli_request_destroy(req);
676 /****************************************************************************
677 Query file info (async send)
678 ****************************************************************************/
679 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
680 union smb_fileinfo *parms)
682 DATA_BLOB data;
683 struct smbcli_request *req;
685 /* pass off the non-trans2 level to specialised functions */
686 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
687 return smb_raw_getattrE_send(tree, parms);
689 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
690 return smb_raw_query_secdesc_send(tree, parms);
692 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
693 return NULL;
696 data = data_blob(NULL, 0);
698 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
699 if (!ea_push_name_list(tree,
700 &data,
701 parms->ea_list.in.num_names,
702 parms->ea_list.in.ea_names)) {
703 return NULL;
707 req = smb_raw_fileinfo_blob_send(tree,
708 parms->generic.in.file.fnum,
709 parms->generic.level, data);
711 data_blob_free(&data);
713 return req;
716 /****************************************************************************
717 Query file info (async recv)
718 ****************************************************************************/
719 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
720 TALLOC_CTX *mem_ctx,
721 union smb_fileinfo *parms)
723 DATA_BLOB blob;
724 NTSTATUS status;
725 struct smbcli_session *session = req?req->session:NULL;
727 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
728 return smb_raw_getattrE_recv(req, parms);
730 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
731 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
733 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
734 return smb_raw_getattr_recv(req, parms);
737 status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
738 if (!NT_STATUS_IS_OK(status)) {
739 return status;
742 return smb_raw_info_backend(session, mem_ctx, parms, &blob);
745 /****************************************************************************
746 Query file info (sync interface)
747 ****************************************************************************/
748 _PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
749 TALLOC_CTX *mem_ctx,
750 union smb_fileinfo *parms)
752 struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
753 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
756 /****************************************************************************
757 Query path info (async send)
758 ****************************************************************************/
759 _PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
760 union smb_fileinfo *parms)
762 DATA_BLOB data;
763 struct smbcli_request *req;
765 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
766 return smb_raw_getattr_send(tree, parms);
768 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
769 return NULL;
772 data = data_blob(NULL, 0);
774 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
775 if (!ea_push_name_list(tree,
776 &data,
777 parms->ea_list.in.num_names,
778 parms->ea_list.in.ea_names)) {
779 return NULL;
783 req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
784 parms->generic.level, data);
785 data_blob_free(&data);
787 return req;
790 /****************************************************************************
791 Query path info (async recv)
792 ****************************************************************************/
793 _PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
794 TALLOC_CTX *mem_ctx,
795 union smb_fileinfo *parms)
797 /* recv is identical to fileinfo */
798 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
801 /****************************************************************************
802 Query path info (sync interface)
803 ****************************************************************************/
804 _PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
805 TALLOC_CTX *mem_ctx,
806 union smb_fileinfo *parms)
808 struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
809 return smb_raw_pathinfo_recv(req, mem_ctx, parms);