s4/libcli/raw: clang: Fix 'Dereference of null pointer'
[Samba.git] / source4 / libcli / raw / rawfileinfo.c
blob235b3cd0fa2c76bb5b3266aead2726c50b202406
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 thats
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 FINFO_CHECK_MIN_SIZE(4);
162 smbcli_blob_pull_string(NULL, mem_ctx, blob,
163 &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE);
164 return NT_STATUS_OK;
166 case RAW_FILEINFO_STREAM_INFORMATION:
167 return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out);
169 case RAW_FILEINFO_INTERNAL_INFORMATION:
170 FINFO_CHECK_SIZE(8);
171 parms->internal_information.out.file_id = BVAL(blob->data, 0);
172 return NT_STATUS_OK;
174 case RAW_FILEINFO_ACCESS_INFORMATION:
175 FINFO_CHECK_SIZE(4);
176 parms->access_information.out.access_flags = IVAL(blob->data, 0);
177 return NT_STATUS_OK;
179 case RAW_FILEINFO_POSITION_INFORMATION:
180 FINFO_CHECK_SIZE(8);
181 parms->position_information.out.position = BVAL(blob->data, 0);
182 return NT_STATUS_OK;
184 case RAW_FILEINFO_MODE_INFORMATION:
185 FINFO_CHECK_SIZE(4);
186 parms->mode_information.out.mode = IVAL(blob->data, 0);
187 return NT_STATUS_OK;
189 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
190 FINFO_CHECK_SIZE(4);
191 parms->alignment_information.out.alignment_requirement
192 = IVAL(blob->data, 0);
193 return NT_STATUS_OK;
195 case RAW_FILEINFO_COMPRESSION_INFORMATION:
196 FINFO_CHECK_SIZE(16);
197 parms->compression_info.out.compressed_size = BVAL(blob->data, 0);
198 parms->compression_info.out.format = SVAL(blob->data, 8);
199 parms->compression_info.out.unit_shift = CVAL(blob->data, 10);
200 parms->compression_info.out.chunk_shift = CVAL(blob->data, 11);
201 parms->compression_info.out.cluster_shift = CVAL(blob->data, 12);
202 /* 3 bytes of padding */
203 return NT_STATUS_OK;
205 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
206 FINFO_CHECK_SIZE(56);
207 parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0);
208 parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8);
209 parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16);
210 parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24);
211 parms->network_open_information.out.alloc_size = BVAL(blob->data, 32);
212 parms->network_open_information.out.size = BVAL(blob->data, 40);
213 parms->network_open_information.out.attrib = IVAL(blob->data, 48);
214 return NT_STATUS_OK;
216 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
217 FINFO_CHECK_SIZE(8);
218 parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0);
219 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
220 return NT_STATUS_OK;
222 case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION:
223 FINFO_CHECK_MIN_SIZE(4);
224 smbcli_blob_pull_string(NULL, mem_ctx, blob,
225 &parms->normalized_name_info.out.fname,
226 0, 4, STR_UNICODE);
227 return NT_STATUS_OK;
229 case RAW_FILEINFO_SMB2_ALL_EAS:
230 FINFO_CHECK_MIN_SIZE(4);
231 return ea_pull_list_chained(blob, mem_ctx,
232 &parms->all_eas.out.num_eas,
233 &parms->all_eas.out.eas);
235 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
236 FINFO_CHECK_MIN_SIZE(0x64);
237 parms->all_info2.out.create_time = smbcli_pull_nttime(blob->data, 0x00);
238 parms->all_info2.out.access_time = smbcli_pull_nttime(blob->data, 0x08);
239 parms->all_info2.out.write_time = smbcli_pull_nttime(blob->data, 0x10);
240 parms->all_info2.out.change_time = smbcli_pull_nttime(blob->data, 0x18);
241 parms->all_info2.out.attrib = IVAL(blob->data, 0x20);
242 parms->all_info2.out.unknown1 = IVAL(blob->data, 0x24);
243 parms->all_info2.out.alloc_size = BVAL(blob->data, 0x28);
244 parms->all_info2.out.size = BVAL(blob->data, 0x30);
245 parms->all_info2.out.nlink = IVAL(blob->data, 0x38);
246 parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
247 parms->all_info2.out.directory = CVAL(blob->data, 0x3D);
248 /* 0x3E-0x3F padding */
249 parms->all_info2.out.file_id = BVAL(blob->data, 0x40);
250 parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
251 parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
252 parms->all_info2.out.position = BVAL(blob->data, 0x50);
253 parms->all_info2.out.mode = IVAL(blob->data, 0x58);
254 parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
255 smbcli_blob_pull_string(NULL, mem_ctx, blob,
256 &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
257 return NT_STATUS_OK;
259 case RAW_FILEINFO_SEC_DESC: {
260 enum ndr_err_code ndr_err;
262 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
263 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
265 ndr_err = ndr_pull_struct_blob(blob, mem_ctx,
266 parms->query_secdesc.out.sd,
267 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
268 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
269 return ndr_map_error2ntstatus(ndr_err);
272 return NT_STATUS_OK;
275 default:
276 break;
279 return NT_STATUS_INVALID_LEVEL;
283 /****************************************************************************
284 Handle qfileinfo/qpathinfo trans2 backend.
285 ****************************************************************************/
286 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
287 TALLOC_CTX *mem_ctx,
288 union smb_fileinfo *parms,
289 DATA_BLOB *blob)
291 switch (parms->generic.level) {
292 case RAW_FILEINFO_GENERIC:
293 case RAW_FILEINFO_GETATTR:
294 case RAW_FILEINFO_GETATTRE:
295 case RAW_FILEINFO_SEC_DESC:
296 /* not handled here */
297 return NT_STATUS_INVALID_LEVEL;
299 case RAW_FILEINFO_STANDARD:
300 if (session == NULL) {
301 return NT_STATUS_INVALID_PARAMETER;
304 FINFO_CHECK_SIZE(22);
305 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
306 blob->data + 0);
307 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
308 blob->data + 4);
309 parms->standard.out.write_time = raw_pull_dos_date2(session->transport,
310 blob->data + 8);
311 parms->standard.out.size = IVAL(blob->data, 12);
312 parms->standard.out.alloc_size = IVAL(blob->data, 16);
313 parms->standard.out.attrib = SVAL(blob->data, 20);
314 return NT_STATUS_OK;
316 case RAW_FILEINFO_EA_SIZE:
317 if (session == NULL) {
318 return NT_STATUS_INVALID_PARAMETER;
321 FINFO_CHECK_SIZE(26);
322 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
323 blob->data + 0);
324 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
325 blob->data + 4);
326 parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport,
327 blob->data + 8);
328 parms->ea_size.out.size = IVAL(blob->data, 12);
329 parms->ea_size.out.alloc_size = IVAL(blob->data, 16);
330 parms->ea_size.out.attrib = SVAL(blob->data, 20);
331 parms->ea_size.out.ea_size = IVAL(blob->data, 22);
332 return NT_STATUS_OK;
334 case RAW_FILEINFO_EA_LIST:
335 FINFO_CHECK_MIN_SIZE(4);
336 return ea_pull_list(blob, mem_ctx,
337 &parms->ea_list.out.num_eas,
338 &parms->ea_list.out.eas);
340 case RAW_FILEINFO_ALL_EAS:
341 FINFO_CHECK_MIN_SIZE(4);
342 return ea_pull_list(blob, mem_ctx,
343 &parms->all_eas.out.num_eas,
344 &parms->all_eas.out.eas);
346 case RAW_FILEINFO_IS_NAME_VALID:
347 /* no data! */
348 FINFO_CHECK_SIZE(0);
349 return NT_STATUS_OK;
351 case RAW_FILEINFO_BASIC_INFO:
352 case RAW_FILEINFO_BASIC_INFORMATION:
353 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
354 RAW_FILEINFO_BASIC_INFORMATION, parms);
356 case RAW_FILEINFO_STANDARD_INFO:
357 case RAW_FILEINFO_STANDARD_INFORMATION:
358 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
359 RAW_FILEINFO_STANDARD_INFORMATION, parms);
361 case RAW_FILEINFO_EA_INFO:
362 case RAW_FILEINFO_EA_INFORMATION:
363 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
364 RAW_FILEINFO_EA_INFORMATION, parms);
366 case RAW_FILEINFO_NAME_INFO:
367 case RAW_FILEINFO_NAME_INFORMATION:
368 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
369 RAW_FILEINFO_NAME_INFORMATION, parms);
371 case RAW_FILEINFO_ALL_INFO:
372 case RAW_FILEINFO_ALL_INFORMATION:
373 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
374 RAW_FILEINFO_ALL_INFORMATION, parms);
376 case RAW_FILEINFO_ALT_NAME_INFO:
377 case RAW_FILEINFO_ALT_NAME_INFORMATION:
378 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
379 RAW_FILEINFO_ALT_NAME_INFORMATION, parms);
381 case RAW_FILEINFO_STREAM_INFO:
382 case RAW_FILEINFO_STREAM_INFORMATION:
383 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
384 RAW_FILEINFO_STREAM_INFORMATION, parms);
386 case RAW_FILEINFO_INTERNAL_INFORMATION:
387 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
388 RAW_FILEINFO_INTERNAL_INFORMATION, parms);
390 case RAW_FILEINFO_ACCESS_INFORMATION:
391 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
392 RAW_FILEINFO_ACCESS_INFORMATION, parms);
394 case RAW_FILEINFO_POSITION_INFORMATION:
395 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
396 RAW_FILEINFO_POSITION_INFORMATION, parms);
398 case RAW_FILEINFO_MODE_INFORMATION:
399 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
400 RAW_FILEINFO_MODE_INFORMATION, parms);
402 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
403 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
404 RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
406 case RAW_FILEINFO_COMPRESSION_INFO:
407 case RAW_FILEINFO_COMPRESSION_INFORMATION:
408 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
409 RAW_FILEINFO_COMPRESSION_INFORMATION, parms);
411 case RAW_FILEINFO_UNIX_BASIC:
412 FINFO_CHECK_SIZE(100);
413 parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0);
414 parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8);
415 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
416 parms->unix_basic_info.out.access_time = smbcli_pull_nttime(blob->data, 24);
417 parms->unix_basic_info.out.change_time = smbcli_pull_nttime(blob->data, 32);
418 parms->unix_basic_info.out.uid = BVAL(blob->data, 40);
419 parms->unix_basic_info.out.gid = BVAL(blob->data, 48);
420 parms->unix_basic_info.out.file_type = IVAL(blob->data, 52);
421 parms->unix_basic_info.out.dev_major = BVAL(blob->data, 60);
422 parms->unix_basic_info.out.dev_minor = BVAL(blob->data, 68);
423 parms->unix_basic_info.out.unique_id = BVAL(blob->data, 76);
424 parms->unix_basic_info.out.permissions = BVAL(blob->data, 84);
425 parms->unix_basic_info.out.nlink = BVAL(blob->data, 92);
426 return NT_STATUS_OK;
428 case RAW_FILEINFO_UNIX_INFO2:
429 FINFO_CHECK_SIZE(116);
430 parms->unix_info2.out.end_of_file = BVAL(blob->data, 0);
431 parms->unix_info2.out.num_bytes = BVAL(blob->data, 8);
432 parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
433 parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24);
434 parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32);
435 parms->unix_info2.out.uid = BVAL(blob->data, 40);
436 parms->unix_info2.out.gid = BVAL(blob->data, 48);
437 parms->unix_info2.out.file_type = IVAL(blob->data, 52);
438 parms->unix_info2.out.dev_major = BVAL(blob->data, 60);
439 parms->unix_info2.out.dev_minor = BVAL(blob->data, 68);
440 parms->unix_info2.out.unique_id = BVAL(blob->data, 76);
441 parms->unix_info2.out.permissions = BVAL(blob->data, 84);
442 parms->unix_info2.out.nlink = BVAL(blob->data, 92);
443 parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100);
444 parms->unix_info2.out.file_flags = IVAL(blob->data, 108);
445 parms->unix_info2.out.flags_mask = IVAL(blob->data, 112);
446 return NT_STATUS_OK;
448 case RAW_FILEINFO_UNIX_LINK:
449 smbcli_blob_pull_string(session, mem_ctx, blob,
450 &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
451 return NT_STATUS_OK;
453 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
454 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
455 RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
457 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
458 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
459 RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
461 case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION:
462 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
463 RAW_FILEINFO_NORMALIZED_NAME_INFORMATION, parms);
465 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
466 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
467 RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
469 case RAW_FILEINFO_SMB2_ALL_EAS:
470 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
471 RAW_FILEINFO_SMB2_ALL_EAS, parms);
475 return NT_STATUS_INVALID_LEVEL;
479 /****************************************************************************
480 Very raw query file info - returns param/data blobs - (async send)
481 ****************************************************************************/
482 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
483 uint16_t fnum,
484 uint16_t info_level,
485 DATA_BLOB data)
487 struct smb_trans2 tp;
488 uint16_t setup = TRANSACT2_QFILEINFO;
489 struct smbcli_request *req;
490 TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
492 tp.in.max_setup = 0;
493 tp.in.flags = 0;
494 tp.in.timeout = 0;
495 tp.in.setup_count = 1;
496 tp.in.data = data;
497 tp.in.max_param = 2;
498 tp.in.max_data = 0xFFFF;
499 tp.in.setup = &setup;
501 tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
502 if (!tp.in.params.data) {
503 talloc_free(mem_ctx);
504 return NULL;
507 SSVAL(tp.in.params.data, 0, fnum);
508 SSVAL(tp.in.params.data, 2, info_level);
510 req = smb_raw_trans2_send(tree, &tp);
512 talloc_free(mem_ctx);
514 return req;
518 /****************************************************************************
519 Very raw query file info - returns param/data blobs - (async recv)
520 ****************************************************************************/
521 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
522 TALLOC_CTX *mem_ctx,
523 DATA_BLOB *blob)
525 struct smb_trans2 tp;
526 NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
527 if (NT_STATUS_IS_OK(status)) {
528 *blob = tp.out.data;
530 return status;
533 /****************************************************************************
534 Very raw query path info - returns param/data blobs (async send)
535 ****************************************************************************/
536 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
537 const char *fname,
538 uint16_t info_level,
539 DATA_BLOB data)
541 struct smb_trans2 tp;
542 uint16_t setup = TRANSACT2_QPATHINFO;
543 struct smbcli_request *req;
544 TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
546 tp.in.max_setup = 0;
547 tp.in.flags = 0;
548 tp.in.timeout = 0;
549 tp.in.setup_count = 1;
550 tp.in.data = data;
551 tp.in.max_param = 2;
552 tp.in.max_data = 0xFFFF;
553 tp.in.setup = &setup;
555 tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
556 if (!tp.in.params.data) {
557 talloc_free(mem_ctx);
558 return NULL;
561 SSVAL(tp.in.params.data, 0, info_level);
562 SIVAL(tp.in.params.data, 2, 0);
563 smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
564 fname, STR_TERMINATE);
566 req = smb_raw_trans2_send(tree, &tp);
568 talloc_free(mem_ctx);
570 return req;
573 /****************************************************************************
574 send a SMBgetatr (async send)
575 ****************************************************************************/
576 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
577 union smb_fileinfo *parms)
579 struct smbcli_request *req;
581 req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
582 if (!req) return NULL;
584 smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
586 if (!smbcli_request_send(req)) {
587 smbcli_request_destroy(req);
588 return NULL;
591 return req;
594 /****************************************************************************
595 send a SMBgetatr (async recv)
596 ****************************************************************************/
597 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
598 union smb_fileinfo *parms)
600 if (req == NULL) {
601 goto failed;
604 if (!smbcli_request_receive(req) ||
605 smbcli_request_is_error(req)) {
606 return smbcli_request_destroy(req);
609 SMBCLI_CHECK_WCT(req, 10);
610 parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0));
611 parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
612 req->in.vwv + VWV(1));
613 parms->getattr.out.size = IVAL(req->in.vwv, VWV(3));
615 failed:
616 return smbcli_request_destroy(req);
620 /****************************************************************************
621 Handle SMBgetattrE (async send)
622 ****************************************************************************/
623 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
624 union smb_fileinfo *parms)
626 struct smbcli_request *req;
628 req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
629 if (!req) return NULL;
631 SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum);
632 if (!smbcli_request_send(req)) {
633 smbcli_request_destroy(req);
634 return NULL;
637 return req;
640 /****************************************************************************
641 Handle SMBgetattrE (async send)
642 ****************************************************************************/
643 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
644 union smb_fileinfo *parms)
646 if (req == NULL) {
647 goto failed;
650 if (!smbcli_request_receive(req) ||
651 smbcli_request_is_error(req)) {
652 return smbcli_request_destroy(req);
655 SMBCLI_CHECK_WCT(req, 11);
656 parms->getattre.out.create_time = raw_pull_dos_date2(req->transport,
657 req->in.vwv + VWV(0));
658 parms->getattre.out.access_time = raw_pull_dos_date2(req->transport,
659 req->in.vwv + VWV(2));
660 parms->getattre.out.write_time = raw_pull_dos_date2(req->transport,
661 req->in.vwv + VWV(4));
662 parms->getattre.out.size = IVAL(req->in.vwv, VWV(6));
663 parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8));
664 parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10));
666 failed:
667 return smbcli_request_destroy(req);
671 /****************************************************************************
672 Query file info (async send)
673 ****************************************************************************/
674 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
675 union smb_fileinfo *parms)
677 DATA_BLOB data;
678 struct smbcli_request *req;
680 /* pass off the non-trans2 level to specialised functions */
681 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
682 return smb_raw_getattrE_send(tree, parms);
684 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
685 return smb_raw_query_secdesc_send(tree, parms);
687 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
688 return NULL;
691 data = data_blob(NULL, 0);
693 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
694 if (!ea_push_name_list(tree,
695 &data,
696 parms->ea_list.in.num_names,
697 parms->ea_list.in.ea_names)) {
698 return NULL;
702 req = smb_raw_fileinfo_blob_send(tree,
703 parms->generic.in.file.fnum,
704 parms->generic.level, data);
706 data_blob_free(&data);
708 return req;
711 /****************************************************************************
712 Query file info (async recv)
713 ****************************************************************************/
714 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
715 TALLOC_CTX *mem_ctx,
716 union smb_fileinfo *parms)
718 DATA_BLOB blob;
719 NTSTATUS status;
720 struct smbcli_session *session = req?req->session:NULL;
722 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
723 return smb_raw_getattrE_recv(req, parms);
725 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
726 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
728 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
729 return smb_raw_getattr_recv(req, parms);
732 status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
733 if (!NT_STATUS_IS_OK(status)) {
734 return status;
737 return smb_raw_info_backend(session, mem_ctx, parms, &blob);
740 /****************************************************************************
741 Query file info (sync interface)
742 ****************************************************************************/
743 _PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
744 TALLOC_CTX *mem_ctx,
745 union smb_fileinfo *parms)
747 struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
748 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
751 /****************************************************************************
752 Query path info (async send)
753 ****************************************************************************/
754 _PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
755 union smb_fileinfo *parms)
757 DATA_BLOB data;
758 struct smbcli_request *req;
760 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
761 return smb_raw_getattr_send(tree, parms);
763 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
764 return NULL;
767 data = data_blob(NULL, 0);
769 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
770 if (!ea_push_name_list(tree,
771 &data,
772 parms->ea_list.in.num_names,
773 parms->ea_list.in.ea_names)) {
774 return NULL;
778 req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
779 parms->generic.level, data);
780 data_blob_free(&data);
782 return req;
785 /****************************************************************************
786 Query path info (async recv)
787 ****************************************************************************/
788 _PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
789 TALLOC_CTX *mem_ctx,
790 union smb_fileinfo *parms)
792 /* recv is idential to fileinfo */
793 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
796 /****************************************************************************
797 Query path info (sync interface)
798 ****************************************************************************/
799 _PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
800 TALLOC_CTX *mem_ctx,
801 union smb_fileinfo *parms)
803 struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
804 return smb_raw_pathinfo_recv(req, mem_ctx, parms);