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/>.
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "param/param.h"
28 /* local macros to make the code more readable */
29 #define FINFO_CHECK_MIN_SIZE(size) if (blob->length < (size)) { \
30 DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected min of %d\n", \
31 (int)blob->length, parms->generic.level, (size))); \
32 return NT_STATUS_INFO_LENGTH_MISMATCH; \
34 #define FINFO_CHECK_SIZE(size) if (blob->length != (size)) { \
35 DEBUG(1,("Unexpected FILEINFO reply size %d for level %u - expected %d\n", \
36 (int)blob->length, parms->generic.level, (size))); \
37 return NT_STATUS_INFO_LENGTH_MISMATCH; \
41 parse a stream information structure
43 NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
44 struct stream_information *io)
50 while (blob.length - ofs >= 24) {
51 uint_t n = io->num_streams;
56 talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1);
58 return NT_STATUS_NO_MEMORY;
60 nlen = IVAL(blob.data, ofs + 0x04);
61 io->streams[n].size = BVAL(blob.data, ofs + 0x08);
62 io->streams[n].alloc_size = BVAL(blob.data, ofs + 0x10);
63 if (nlen > blob.length - (ofs + 24)) {
64 return NT_STATUS_INFO_LENGTH_MISMATCH;
66 size = convert_string_talloc(io->streams,
67 lp_iconv_convenience(global_loadparm),
69 blob.data+ofs+24, nlen, &vstr);
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;
76 len = IVAL(blob.data, ofs);
77 if (len > blob.length - ofs) {
78 return NT_STATUS_INFO_LENGTH_MISMATCH;
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)
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) {
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);
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);
117 case RAW_FILEINFO_EA_INFORMATION:
119 parms->ea_info.out.ea_size = IVAL(blob->data, 0);
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);
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);
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);
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
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
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);
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);
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:
171 parms->internal_information.out.file_id = BVAL(blob->data, 0);
174 case RAW_FILEINFO_ACCESS_INFORMATION:
176 parms->access_information.out.access_flags = IVAL(blob->data, 0);
179 case RAW_FILEINFO_POSITION_INFORMATION:
181 parms->position_information.out.position = BVAL(blob->data, 0);
184 case RAW_FILEINFO_MODE_INFORMATION:
186 parms->mode_information.out.mode = IVAL(blob->data, 0);
189 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
191 parms->alignment_information.out.alignment_requirement
192 = IVAL(blob->data, 0);
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 */
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);
216 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
218 parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0);
219 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
222 case RAW_FILEINFO_SMB2_ALL_EAS:
223 FINFO_CHECK_MIN_SIZE(4);
224 return ea_pull_list_chained(blob, mem_ctx,
225 &parms->all_eas.out.num_eas,
226 &parms->all_eas.out.eas);
228 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
229 FINFO_CHECK_MIN_SIZE(0x64);
230 parms->all_info2.out.create_time = smbcli_pull_nttime(blob->data, 0x00);
231 parms->all_info2.out.access_time = smbcli_pull_nttime(blob->data, 0x08);
232 parms->all_info2.out.write_time = smbcli_pull_nttime(blob->data, 0x10);
233 parms->all_info2.out.change_time = smbcli_pull_nttime(blob->data, 0x18);
234 parms->all_info2.out.attrib = IVAL(blob->data, 0x20);
235 parms->all_info2.out.unknown1 = IVAL(blob->data, 0x24);
236 parms->all_info2.out.alloc_size = BVAL(blob->data, 0x28);
237 parms->all_info2.out.size = BVAL(blob->data, 0x30);
238 parms->all_info2.out.nlink = IVAL(blob->data, 0x38);
239 parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
240 parms->all_info2.out.directory = CVAL(blob->data, 0x3D);
241 /* 0x3E-0x3F padding */
242 parms->all_info2.out.file_id = BVAL(blob->data, 0x40);
243 parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
244 parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
245 parms->all_info2.out.position = BVAL(blob->data, 0x50);
246 parms->all_info2.out.mode = BVAL(blob->data, 0x58);
247 smbcli_blob_pull_string(NULL, mem_ctx, blob,
248 &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
251 case RAW_FILEINFO_SEC_DESC: {
252 enum ndr_err_code ndr_err;
254 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
255 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
257 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL,
258 parms->query_secdesc.out.sd,
259 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
260 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
261 return ndr_map_error2ntstatus(ndr_err);
271 return NT_STATUS_INVALID_LEVEL;
275 /****************************************************************************
276 Handle qfileinfo/qpathinfo trans2 backend.
277 ****************************************************************************/
278 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
280 union smb_fileinfo *parms,
283 switch (parms->generic.level) {
284 case RAW_FILEINFO_GENERIC:
285 case RAW_FILEINFO_GETATTR:
286 case RAW_FILEINFO_GETATTRE:
287 case RAW_FILEINFO_SEC_DESC:
288 /* not handled here */
289 return NT_STATUS_INVALID_LEVEL;
291 case RAW_FILEINFO_STANDARD:
292 FINFO_CHECK_SIZE(22);
293 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
295 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
297 parms->standard.out.write_time = raw_pull_dos_date2(session->transport,
299 parms->standard.out.size = IVAL(blob->data, 12);
300 parms->standard.out.alloc_size = IVAL(blob->data, 16);
301 parms->standard.out.attrib = SVAL(blob->data, 20);
304 case RAW_FILEINFO_EA_SIZE:
305 FINFO_CHECK_SIZE(26);
306 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
308 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
310 parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport,
312 parms->ea_size.out.size = IVAL(blob->data, 12);
313 parms->ea_size.out.alloc_size = IVAL(blob->data, 16);
314 parms->ea_size.out.attrib = SVAL(blob->data, 20);
315 parms->ea_size.out.ea_size = IVAL(blob->data, 22);
318 case RAW_FILEINFO_EA_LIST:
319 FINFO_CHECK_MIN_SIZE(4);
320 return ea_pull_list(blob, mem_ctx,
321 &parms->ea_list.out.num_eas,
322 &parms->ea_list.out.eas);
324 case RAW_FILEINFO_ALL_EAS:
325 FINFO_CHECK_MIN_SIZE(4);
326 return ea_pull_list(blob, mem_ctx,
327 &parms->all_eas.out.num_eas,
328 &parms->all_eas.out.eas);
330 case RAW_FILEINFO_IS_NAME_VALID:
335 case RAW_FILEINFO_BASIC_INFO:
336 case RAW_FILEINFO_BASIC_INFORMATION:
337 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
338 RAW_FILEINFO_BASIC_INFORMATION, parms);
340 case RAW_FILEINFO_STANDARD_INFO:
341 case RAW_FILEINFO_STANDARD_INFORMATION:
342 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
343 RAW_FILEINFO_STANDARD_INFORMATION, parms);
345 case RAW_FILEINFO_EA_INFO:
346 case RAW_FILEINFO_EA_INFORMATION:
347 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
348 RAW_FILEINFO_EA_INFORMATION, parms);
350 case RAW_FILEINFO_NAME_INFO:
351 case RAW_FILEINFO_NAME_INFORMATION:
352 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
353 RAW_FILEINFO_NAME_INFORMATION, parms);
355 case RAW_FILEINFO_ALL_INFO:
356 case RAW_FILEINFO_ALL_INFORMATION:
357 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
358 RAW_FILEINFO_ALL_INFORMATION, parms);
360 case RAW_FILEINFO_ALT_NAME_INFO:
361 case RAW_FILEINFO_ALT_NAME_INFORMATION:
362 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
363 RAW_FILEINFO_ALT_NAME_INFORMATION, parms);
365 case RAW_FILEINFO_STREAM_INFO:
366 case RAW_FILEINFO_STREAM_INFORMATION:
367 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
368 RAW_FILEINFO_STREAM_INFORMATION, parms);
370 case RAW_FILEINFO_INTERNAL_INFORMATION:
371 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
372 RAW_FILEINFO_INTERNAL_INFORMATION, parms);
374 case RAW_FILEINFO_ACCESS_INFORMATION:
375 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
376 RAW_FILEINFO_ACCESS_INFORMATION, parms);
378 case RAW_FILEINFO_POSITION_INFORMATION:
379 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
380 RAW_FILEINFO_POSITION_INFORMATION, parms);
382 case RAW_FILEINFO_MODE_INFORMATION:
383 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
384 RAW_FILEINFO_MODE_INFORMATION, parms);
386 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
387 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
388 RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
390 case RAW_FILEINFO_COMPRESSION_INFO:
391 case RAW_FILEINFO_COMPRESSION_INFORMATION:
392 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
393 RAW_FILEINFO_COMPRESSION_INFORMATION, parms);
395 case RAW_FILEINFO_UNIX_BASIC:
396 FINFO_CHECK_SIZE(100);
397 parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0);
398 parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8);
399 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
400 parms->unix_basic_info.out.access_time = smbcli_pull_nttime(blob->data, 24);
401 parms->unix_basic_info.out.change_time = smbcli_pull_nttime(blob->data, 32);
402 parms->unix_basic_info.out.uid = BVAL(blob->data, 40);
403 parms->unix_basic_info.out.gid = BVAL(blob->data, 48);
404 parms->unix_basic_info.out.file_type = IVAL(blob->data, 52);
405 parms->unix_basic_info.out.dev_major = BVAL(blob->data, 60);
406 parms->unix_basic_info.out.dev_minor = BVAL(blob->data, 68);
407 parms->unix_basic_info.out.unique_id = BVAL(blob->data, 76);
408 parms->unix_basic_info.out.permissions = BVAL(blob->data, 84);
409 parms->unix_basic_info.out.nlink = BVAL(blob->data, 92);
412 case RAW_FILEINFO_UNIX_INFO2:
413 FINFO_CHECK_SIZE(116);
414 parms->unix_info2.out.end_of_file = BVAL(blob->data, 0);
415 parms->unix_info2.out.num_bytes = BVAL(blob->data, 8);
416 parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
417 parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24);
418 parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32);
419 parms->unix_info2.out.uid = BVAL(blob->data, 40);
420 parms->unix_info2.out.gid = BVAL(blob->data, 48);
421 parms->unix_info2.out.file_type = IVAL(blob->data, 52);
422 parms->unix_info2.out.dev_major = BVAL(blob->data, 60);
423 parms->unix_info2.out.dev_minor = BVAL(blob->data, 68);
424 parms->unix_info2.out.unique_id = BVAL(blob->data, 76);
425 parms->unix_info2.out.permissions = BVAL(blob->data, 84);
426 parms->unix_info2.out.nlink = BVAL(blob->data, 92);
427 parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100);
428 parms->unix_info2.out.file_flags = IVAL(blob->data, 108);
429 parms->unix_info2.out.flags_mask = IVAL(blob->data, 112);
432 case RAW_FILEINFO_UNIX_LINK:
433 smbcli_blob_pull_string(session, mem_ctx, blob,
434 &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
437 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
438 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
439 RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
441 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
442 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
443 RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
445 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
446 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
447 RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
449 case RAW_FILEINFO_SMB2_ALL_EAS:
450 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
451 RAW_FILEINFO_SMB2_ALL_EAS, parms);
455 return NT_STATUS_INVALID_LEVEL;
459 /****************************************************************************
460 Very raw query file info - returns param/data blobs - (async send)
461 ****************************************************************************/
462 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
467 struct smb_trans2 tp;
468 uint16_t setup = TRANSACT2_QFILEINFO;
469 struct smbcli_request *req;
470 TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
475 tp.in.setup_count = 1;
478 tp.in.max_data = 0xFFFF;
479 tp.in.setup = &setup;
481 tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
482 if (!tp.in.params.data) {
483 talloc_free(mem_ctx);
487 SSVAL(tp.in.params.data, 0, fnum);
488 SSVAL(tp.in.params.data, 2, info_level);
490 req = smb_raw_trans2_send(tree, &tp);
492 talloc_free(mem_ctx);
498 /****************************************************************************
499 Very raw query file info - returns param/data blobs - (async recv)
500 ****************************************************************************/
501 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
505 struct smb_trans2 tp;
506 NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
507 if (NT_STATUS_IS_OK(status)) {
513 /****************************************************************************
514 Very raw query path info - returns param/data blobs (async send)
515 ****************************************************************************/
516 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
521 struct smb_trans2 tp;
522 uint16_t setup = TRANSACT2_QPATHINFO;
523 struct smbcli_request *req;
524 TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
529 tp.in.setup_count = 1;
532 tp.in.max_data = 0xFFFF;
533 tp.in.setup = &setup;
535 tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
536 if (!tp.in.params.data) {
537 talloc_free(mem_ctx);
541 SSVAL(tp.in.params.data, 0, info_level);
542 SIVAL(tp.in.params.data, 2, 0);
543 smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
544 fname, STR_TERMINATE);
546 req = smb_raw_trans2_send(tree, &tp);
548 talloc_free(mem_ctx);
553 /****************************************************************************
554 send a SMBgetatr (async send)
555 ****************************************************************************/
556 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
557 union smb_fileinfo *parms)
559 struct smbcli_request *req;
561 req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
562 if (!req) return NULL;
564 smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
566 if (!smbcli_request_send(req)) {
567 smbcli_request_destroy(req);
574 /****************************************************************************
575 send a SMBgetatr (async recv)
576 ****************************************************************************/
577 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
578 union smb_fileinfo *parms)
580 if (!smbcli_request_receive(req) ||
581 smbcli_request_is_error(req)) {
582 return smbcli_request_destroy(req);
585 SMBCLI_CHECK_WCT(req, 10);
586 parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0));
587 parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
588 req->in.vwv + VWV(1));
589 parms->getattr.out.size = IVAL(req->in.vwv, VWV(3));
592 return smbcli_request_destroy(req);
596 /****************************************************************************
597 Handle SMBgetattrE (async send)
598 ****************************************************************************/
599 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
600 union smb_fileinfo *parms)
602 struct smbcli_request *req;
604 req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
605 if (!req) return NULL;
607 SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum);
608 if (!smbcli_request_send(req)) {
609 smbcli_request_destroy(req);
616 /****************************************************************************
617 Handle SMBgetattrE (async send)
618 ****************************************************************************/
619 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
620 union smb_fileinfo *parms)
622 if (!smbcli_request_receive(req) ||
623 smbcli_request_is_error(req)) {
624 return smbcli_request_destroy(req);
627 SMBCLI_CHECK_WCT(req, 11);
628 parms->getattre.out.create_time = raw_pull_dos_date2(req->transport,
629 req->in.vwv + VWV(0));
630 parms->getattre.out.access_time = raw_pull_dos_date2(req->transport,
631 req->in.vwv + VWV(2));
632 parms->getattre.out.write_time = raw_pull_dos_date2(req->transport,
633 req->in.vwv + VWV(4));
634 parms->getattre.out.size = IVAL(req->in.vwv, VWV(6));
635 parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8));
636 parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10));
639 return smbcli_request_destroy(req);
643 /****************************************************************************
644 Query file info (async send)
645 ****************************************************************************/
646 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
647 union smb_fileinfo *parms)
650 struct smbcli_request *req;
652 /* pass off the non-trans2 level to specialised functions */
653 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
654 return smb_raw_getattrE_send(tree, parms);
656 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
657 return smb_raw_query_secdesc_send(tree, parms);
659 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
663 data = data_blob(NULL, 0);
665 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
666 if (!ea_push_name_list(tree,
668 parms->ea_list.in.num_names,
669 parms->ea_list.in.ea_names)) {
674 req = smb_raw_fileinfo_blob_send(tree,
675 parms->generic.in.file.fnum,
676 parms->generic.level, data);
678 data_blob_free(&data);
683 /****************************************************************************
684 Query file info (async recv)
685 ****************************************************************************/
686 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
688 union smb_fileinfo *parms)
692 struct smbcli_session *session = req?req->session:NULL;
694 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
695 return smb_raw_getattrE_recv(req, parms);
697 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
698 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
700 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
701 return smb_raw_getattr_recv(req, parms);
704 status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
705 if (!NT_STATUS_IS_OK(status)) {
709 return smb_raw_info_backend(session, mem_ctx, parms, &blob);
712 /****************************************************************************
713 Query file info (sync interface)
714 ****************************************************************************/
715 _PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
717 union smb_fileinfo *parms)
719 struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
720 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
723 /****************************************************************************
724 Query path info (async send)
725 ****************************************************************************/
726 _PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
727 union smb_fileinfo *parms)
730 struct smbcli_request *req;
732 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
733 return smb_raw_getattr_send(tree, parms);
735 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
739 data = data_blob(NULL, 0);
741 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
742 if (!ea_push_name_list(tree,
744 parms->ea_list.in.num_names,
745 parms->ea_list.in.ea_names)) {
750 req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
751 parms->generic.level, data);
752 data_blob_free(&data);
757 /****************************************************************************
758 Query path info (async recv)
759 ****************************************************************************/
760 _PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
762 union smb_fileinfo *parms)
764 /* recv is idential to fileinfo */
765 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
768 /****************************************************************************
769 Query path info (sync interface)
770 ****************************************************************************/
771 _PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
773 union smb_fileinfo *parms)
775 struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
776 return smb_raw_pathinfo_recv(req, mem_ctx, parms);